summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore2
-rwxr-xr-xBUILD/compile-pentium2
-rwxr-xr-xCMakeLists.txt15
-rw-r--r--Docs/INSTALL-BINARY20
-rw-r--r--INSTALL-SOURCE10213
-rw-r--r--INSTALL-WIN-SOURCE14
-rw-r--r--Makefile.am8
-rw-r--r--README71
-rw-r--r--client/mysql.cc33
-rw-r--r--client/mysql_upgrade.c28
-rw-r--r--client/mysqlbinlog.cc33
-rw-r--r--client/mysqlcheck.c19
-rw-r--r--client/mysqlimport.c4
-rw-r--r--client/mysqlslap.c20
-rw-r--r--client/mysqltest.cc207
-rw-r--r--cmd-line-utils/readline/config_readline.h7
-rw-r--r--cmd-line-utils/readline/display.c8
-rw-r--r--cmd-line-utils/readline/history.c4
-rw-r--r--cmd-line-utils/readline/rlmbutil.h4
-rw-r--r--cmd-line-utils/readline/text.c2
-rw-r--r--cmd-line-utils/readline/xmalloc.c2
-rw-r--r--configure.in41
-rw-r--r--extra/yassl/include/yassl_int.hpp2
-rw-r--r--extra/yassl/taocrypt/src/random.cpp1
-rw-r--r--include/ft_global.h2
-rw-r--r--include/m_ctype.h27
-rw-r--r--include/my_dbug.h88
-rw-r--r--include/my_sys.h12
-rw-r--r--include/my_tree.h4
-rw-r--r--include/myisamchk.h4
-rw-r--r--include/mysql.h10
-rw-r--r--include/mysql.h.pp10
-rw-r--r--include/mysql/plugin.h13
-rw-r--r--include/mysql/plugin.h.pp11
-rw-r--r--include/mysys_err.h5
-rw-r--r--include/violite.h8
-rw-r--r--libmysql/libmysql.c18
-rw-r--r--libmysql/libmysql.def1
-rw-r--r--libmysqld/CMakeLists.txt13
-rw-r--r--libmysqld/Makefile.am1
-rw-r--r--libmysqld/lib_sql.cc3
-rw-r--r--libmysqld/libmysqld.c1
-rw-r--r--libmysqld/libmysqld.def1
-rw-r--r--man/comp_err.128
-rw-r--r--man/innochecksum.119
-rw-r--r--man/make_win_bin_dist.14
-rw-r--r--man/msql2mysql.14
-rw-r--r--man/my_print_defaults.17
-rw-r--r--man/myisam_ftdump.14
-rw-r--r--man/myisamchk.11135
-rw-r--r--man/myisamlog.14
-rw-r--r--man/myisampack.110
-rw-r--r--man/mysql-stress-test.pl.14
-rw-r--r--man/mysql-test-run.pl.127
-rw-r--r--man/mysql.138
-rw-r--r--man/mysql.server.18
-rw-r--r--man/mysql_client_test.14
-rw-r--r--man/mysql_config.14
-rw-r--r--man/mysql_convert_table_format.14
-rw-r--r--man/mysql_find_rows.14
-rw-r--r--man/mysql_fix_extensions.14
-rw-r--r--man/mysql_fix_privilege_tables.14
-rw-r--r--man/mysql_install_db.16
-rw-r--r--man/mysql_secure_installation.14
-rw-r--r--man/mysql_setpermission.14
-rw-r--r--man/mysql_tzinfo_to_sql.14
-rw-r--r--man/mysql_upgrade.132
-rw-r--r--man/mysql_waitpid.14
-rw-r--r--man/mysql_zap.14
-rw-r--r--man/mysqlaccess.14
-rw-r--r--man/mysqladmin.14
-rw-r--r--man/mysqlbinlog.16
-rw-r--r--man/mysqlbug.14
-rw-r--r--man/mysqlcheck.115
-rw-r--r--man/mysqld.84
-rw-r--r--man/mysqld_multi.145
-rw-r--r--man/mysqld_safe.14
-rw-r--r--man/mysqldump.119
-rw-r--r--man/mysqldumpslow.14
-rw-r--r--man/mysqlhotcopy.14
-rw-r--r--man/mysqlimport.14
-rw-r--r--man/mysqlmanager.87
-rw-r--r--man/mysqlshow.14
-rw-r--r--man/mysqlslap.14
-rw-r--r--man/mysqltest.14
-rw-r--r--man/ndbd.8228
-rw-r--r--man/ndbd_redo_log_reader.1106
-rw-r--r--man/ndbmtd.832
-rw-r--r--man/perror.14
-rw-r--r--man/replace.14
-rw-r--r--man/resolve_stack_dump.14
-rw-r--r--man/resolveip.14
-rw-r--r--mysql-test/collections/README.experimental7
-rw-r--r--mysql-test/collections/default.experimental47
-rw-r--r--mysql-test/extra/binlog_tests/binlog.test39
-rw-r--r--mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test300
-rw-r--r--mysql-test/extra/binlog_tests/drop_temp_table.test67
-rw-r--r--mysql-test/extra/rpl_tests/rpl_auto_increment.test76
-rw-r--r--mysql-test/extra/rpl_tests/rpl_auto_increment_insert_view.test44
-rw-r--r--mysql-test/extra/rpl_tests/rpl_auto_increment_invoke_trigger.test82
-rw-r--r--mysql-test/extra/rpl_tests/rpl_autoinc_func_invokes_trigger.test57
-rw-r--r--mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_failed_optimize.test1
-rw-r--r--mysql-test/extra/rpl_tests/rpl_loaddata.test61
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_sp006.test41
-rw-r--r--mysql-test/extra/rpl_tests/rpl_stm_000001.test2
-rw-r--r--mysql-test/include/check-warnings.test2
-rw-r--r--mysql-test/include/concurrent.inc2
-rw-r--r--mysql-test/include/have_case_insensitive_fs.inc4
-rw-r--r--mysql-test/include/have_debug_sync.inc5
-rw-r--r--mysql-test/include/have_dynamic_loading.inc5
-rw-r--r--mysql-test/include/have_example_plugin.inc5
-rw-r--r--mysql-test/include/have_mysql_upgrade.inc4
-rw-r--r--mysql-test/include/have_not_innodb_plugin.inc4
-rw-r--r--mysql-test/include/have_simple_parser.inc5
-rw-r--r--mysql-test/include/have_udf.inc5
-rw-r--r--mysql-test/include/index_merge2.inc2
-rw-r--r--mysql-test/include/mix1.inc2
-rw-r--r--mysql-test/include/mtr_warnings.sql7
-rw-r--r--mysql-test/include/not_windows_embedded.inc11
-rw-r--r--mysql-test/lib/My/ConfigFactory.pm25
-rw-r--r--mysql-test/lib/My/Platform.pm9
-rwxr-xr-xmysql-test/lib/My/SafeProcess/safe_kill_win.cc28
-rwxr-xr-xmysql-test/lib/My/SafeProcess/safe_process_win.cc12
-rw-r--r--mysql-test/lib/mtr_cases.pm108
-rw-r--r--mysql-test/lib/mtr_report.pm5
-rw-r--r--mysql-test/lib/v1/incompatible.tests6
-rw-r--r--mysql-test/lib/v1/mtr_cases.pl25
-rwxr-xr-xmysql-test/mysql-stress-test.pl133
-rwxr-xr-xmysql-test/mysql-test-run.pl244
-rw-r--r--mysql-test/r/almost_full.result1
-rw-r--r--mysql-test/r/alter_table.result70
-rw-r--r--mysql-test/r/analyse.result112
-rw-r--r--mysql-test/r/archive.result22
-rw-r--r--mysql-test/r/bug40113.result29
-rw-r--r--mysql-test/r/bug46080.result2
-rw-r--r--mysql-test/r/bug46760.result43
-rw-r--r--mysql-test/r/case_insensitive_fs.require2
-rw-r--r--mysql-test/r/create.result13
-rw-r--r--mysql-test/r/ctype_ldml.result16
-rw-r--r--mysql-test/r/ctype_uca.result143
-rw-r--r--mysql-test/r/debug_sync.result277
-rw-r--r--mysql-test/r/delete.result45
-rw-r--r--mysql-test/r/distinct.result30
-rw-r--r--mysql-test/r/explain.result24
-rw-r--r--mysql-test/r/func_group.result44
-rw-r--r--mysql-test/r/func_in.result142
-rw-r--r--mysql-test/r/func_str.result9
-rw-r--r--mysql-test/r/gis-rtree.result39
-rw-r--r--mysql-test/r/gis.result12
-rw-r--r--mysql-test/r/grant.result4
-rw-r--r--mysql-test/r/grant3.result38
-rw-r--r--mysql-test/r/grant_lowercase_fs.result16
-rw-r--r--mysql-test/r/group_min_max.result6
-rw-r--r--mysql-test/r/have_debug_sync.require2
-rw-r--r--mysql-test/r/index_merge_innodb.result4
-rw-r--r--mysql-test/r/index_merge_myisam.result4
-rw-r--r--mysql-test/r/information_schema_db.result7
-rw-r--r--mysql-test/r/innodb-autoinc.result297
-rw-r--r--mysql-test/r/innodb-index.result37
-rw-r--r--mysql-test/r/innodb.result6
-rw-r--r--mysql-test/r/innodb_bug36169.result3
-rw-r--r--mysql-test/r/innodb_bug44032.result (renamed from mysql-test/suite/innodb/r/innodb_bug44032.result)0
-rw-r--r--mysql-test/r/innodb_bug44369.result14
-rw-r--r--mysql-test/r/innodb_bug46000.result18
-rw-r--r--mysql-test/r/innodb_bug47777.result13
-rw-r--r--mysql-test/r/innodb_file_format.result (renamed from mysql-test/suite/innodb/r/innodb_file_format.result)4
-rw-r--r--mysql-test/r/innodb_lock_wait_timeout_1.result357
-rw-r--r--mysql-test/r/innodb_mysql.result45
-rw-r--r--mysql-test/r/insert_select.result14
-rw-r--r--mysql-test/r/join.result64
-rw-r--r--mysql-test/r/locale.result29
-rw-r--r--mysql-test/r/lowercase_fs_off.result45
-rwxr-xr-xmysql-test/r/lowercase_mixed_tmpdir_innodb.result6
-rw-r--r--mysql-test/r/lowercase_table3.result2
-rw-r--r--mysql-test/r/myisam.result46
-rw-r--r--mysql-test/r/myisam_crash_before_flush_keys.result28
-rw-r--r--mysql-test/r/mysqlbinlog.result119
-rw-r--r--mysql-test/r/mysqltest.result20
-rw-r--r--mysql-test/r/not_true.require2
-rw-r--r--mysql-test/r/olap.result20
-rw-r--r--mysql-test/r/order_by.result31
-rw-r--r--mysql-test/r/partition.result15
-rw-r--r--mysql-test/r/partition_csv.result1
-rw-r--r--mysql-test/r/partition_innodb.result18
-rw-r--r--mysql-test/r/partition_innodb_builtin.result39
-rw-r--r--mysql-test/r/partition_innodb_plugin.result50
-rw-r--r--mysql-test/r/partition_open_files_limit.result22
-rw-r--r--mysql-test/r/partition_pruning.result3
-rw-r--r--mysql-test/r/ps_grant.result6
-rw-r--r--mysql-test/r/query_cache.result2
-rw-r--r--mysql-test/r/range.result385
-rw-r--r--mysql-test/r/select.result41
-rw-r--r--mysql-test/r/sp-bugs.result47
-rw-r--r--mysql-test/r/sp-error.result16
-rw-r--r--mysql-test/r/sp.result16
-rw-r--r--mysql-test/r/subselect.result19
-rw-r--r--mysql-test/r/subselect3.result69
-rw-r--r--mysql-test/r/subselect4.result61
-rw-r--r--mysql-test/r/system_mysql_db.result2
-rw-r--r--mysql-test/r/trigger_notembedded.result2
-rw-r--r--mysql-test/r/type_bit.result10
-rw-r--r--mysql-test/r/type_newdecimal.result220
-rw-r--r--mysql-test/r/udf.result16
-rw-r--r--mysql-test/r/update.result11
-rw-r--r--mysql-test/r/upgrade.result4
-rw-r--r--mysql-test/r/view_grant.result201
-rw-r--r--mysql-test/r/warnings.result5
-rw-r--r--mysql-test/r/windows.result7
-rw-r--r--mysql-test/r/xa.result25
-rw-r--r--mysql-test/std_data/Index.xml13
-rw-r--r--mysql-test/std_data/binlog_transaction.000001bin0 -> 1670 bytes
-rw-r--r--mysql-test/std_data/latin1.xml135
-rw-r--r--mysql-test/suite/binlog/r/binlog_delete_and_flush_index.result50
-rw-r--r--mysql-test/suite/binlog/r/binlog_killed_simulate.result2
-rw-r--r--mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result406
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_binlog.result24
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result41
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result440
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result20
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result161
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_binlog.result21
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_blackhole.result2
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_do_db.result42
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result55
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result4
-rw-r--r--mysql-test/suite/binlog/std_data/update-full-row.binlogbin0 -> 614 bytes
-rw-r--r--mysql-test/suite/binlog/std_data/update-partial-row.binlogbin0 -> 606 bytes
-rw-r--r--mysql-test/suite/binlog/std_data/write-full-row.binlogbin0 -> 571 bytes
-rw-r--r--mysql-test/suite/binlog/std_data/write-partial-row.binlogbin0 -> 596 bytes
-rw-r--r--mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test114
-rw-r--r--mysql-test/suite/binlog/t/binlog_mixed_failure_mixing_engines.test4
-rw-r--r--mysql-test/suite/binlog/t/binlog_row_failure_mixing_engines.test4
-rw-r--r--mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test25
-rw-r--r--mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test86
-rw-r--r--mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt1
-rw-r--r--mysql-test/suite/binlog/t/binlog_stm_do_db.test90
-rw-r--r--mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test15
-rw-r--r--mysql-test/suite/federated/federated_debug-master.opt1
-rw-r--r--mysql-test/suite/federated/federated_debug.result33
-rw-r--r--mysql-test/suite/federated/federated_debug.test39
-rw-r--r--mysql-test/suite/federated/my.cnf3
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_mysql.result4
-rw-r--r--mysql-test/suite/funcs_1/r/is_statistics.result4
-rw-r--r--mysql-test/suite/innodb/r/innodb-consistent.result35
-rw-r--r--mysql-test/suite/innodb/r/innodb-zip.result100
-rw-r--r--mysql-test/suite/innodb/r/innodb_bug44571.result9
-rw-r--r--mysql-test/suite/innodb/t/innodb-consistent-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb-consistent.test59
-rw-r--r--mysql-test/suite/innodb/t/innodb-zip.test48
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug44571.test18
-rw-r--r--mysql-test/suite/innodb/t/innodb_information_schema.test16
-rw-r--r--mysql-test/suite/parts/inc/partition_auto_increment.inc192
-rw-r--r--mysql-test/suite/parts/r/partition_auto_increment_innodb.result191
-rw-r--r--mysql-test/suite/parts/r/partition_auto_increment_maria.result191
-rw-r--r--mysql-test/suite/parts/r/partition_auto_increment_memory.result191
-rw-r--r--mysql-test/suite/parts/r/partition_auto_increment_myisam.result191
-rw-r--r--mysql-test/suite/parts/r/partition_auto_increment_ndb.result191
-rw-r--r--mysql-test/suite/parts/r/partition_recover_myisam.result2
-rw-r--r--mysql-test/suite/parts/t/partition_auto_increment_archive.test3
-rw-r--r--mysql-test/suite/parts/t/partition_auto_increment_blackhole.test3
-rw-r--r--mysql-test/suite/parts/t/partition_recover_myisam.test4
-rw-r--r--mysql-test/suite/pbxt/r/func_group.result2
-rw-r--r--mysql-test/suite/pbxt/r/grant.result8
-rw-r--r--mysql-test/suite/pbxt/r/group_min_max.result6
-rw-r--r--mysql-test/suite/pbxt/r/join_nested.result12
-rw-r--r--mysql-test/suite/pbxt/r/negation_elimination.result4
-rw-r--r--mysql-test/suite/pbxt/r/ps_grant.result6
-rw-r--r--mysql-test/suite/pbxt/r/skip_grants.result2
-rw-r--r--mysql-test/suite/pbxt/r/subselect.result2
-rw-r--r--mysql-test/suite/pbxt/r/view_grant.result8
-rw-r--r--mysql-test/suite/pbxt/t/grant.test2
-rw-r--r--mysql-test/suite/pbxt/t/ps_grant.test3
-rw-r--r--mysql-test/suite/pbxt/t/subselect.test4
-rw-r--r--mysql-test/suite/rpl/r/rpl_auto_increment.result68
-rw-r--r--mysql-test/suite/rpl/r/rpl_auto_increment_update_failure.result1041
-rw-r--r--mysql-test/suite/rpl/r/rpl_bug33931.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_do_grant.result3
-rw-r--r--mysql-test/suite/rpl/r/rpl_extraCol_innodb.result1
-rw-r--r--mysql-test/suite/rpl/r/rpl_extraCol_myisam.result1
-rw-r--r--mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result4
-rw-r--r--mysql-test/suite/rpl/r/rpl_idempotency.result3
-rw-r--r--mysql-test/suite/rpl/r/rpl_init_slave_errors.result1
-rw-r--r--mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_loaddata.result33
-rw-r--r--mysql-test/suite/rpl/r/rpl_loaddata_fatal.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_loaddata_map.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_loaddatalocal.result28
-rw-r--r--mysql-test/suite/rpl/r/rpl_log_pos.result1
-rw-r--r--mysql-test/suite/rpl/r/rpl_mysql_upgrade.result13
-rw-r--r--mysql-test/suite/rpl/r/rpl_packet.result17
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_create_table.result4
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_disabled_slave_key.result26
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result36
-rw-r--r--mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result1
-rw-r--r--mysql-test/suite/rpl/r/rpl_stm_log.result6
-rw-r--r--mysql-test/suite/rpl/r/rpl_temporary_errors.result1
-rw-r--r--mysql-test/suite/rpl/t/disabled.def3
-rw-r--r--mysql-test/suite/rpl/t/rpl_auto_increment_update_failure.test214
-rw-r--r--mysql-test/suite/rpl/t/rpl_bug33931.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_do_grant.test7
-rw-r--r--mysql-test/suite/rpl/t/rpl_drop_temp.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_err_ignoredtable.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_get_master_version_and_clock-slave.opt1
-rw-r--r--mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test4
-rw-r--r--mysql-test/suite/rpl/t/rpl_idempotency.test3
-rw-r--r--mysql-test/suite/rpl/t/rpl_init_slave_errors.test1
-rw-r--r--mysql-test/suite/rpl/t/rpl_loaddatalocal.test70
-rw-r--r--mysql-test/suite/rpl/t/rpl_log_pos.test1
-rw-r--r--mysql-test/suite/rpl/t/rpl_mysql_upgrade.test56
-rw-r--r--mysql-test/suite/rpl/t/rpl_packet.test32
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_disabled_slave_key.test73
-rw-r--r--mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test3
-rw-r--r--mysql-test/suite/rpl/t/rpl_temporary_errors.test9
-rw-r--r--mysql-test/suite/rpl_ndb/r/rpl_ndb_circular_simplex.result1
-rw-r--r--mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result1
-rw-r--r--mysql-test/suite/rpl_ndb/r/rpl_ndb_sp006.result36
-rw-r--r--mysql-test/suite/rpl_ndb/t/rpl_ndb_circular.test1
-rw-r--r--mysql-test/suite/rpl_ndb/t/rpl_ndb_circular_simplex.test4
-rw-r--r--mysql-test/t/almost_full.test2
-rw-r--r--mysql-test/t/alter_table.test60
-rw-r--r--mysql-test/t/analyse.test70
-rw-r--r--mysql-test/t/archive.test24
-rw-r--r--mysql-test/t/bug40113.test46
-rw-r--r--mysql-test/t/bug46080.test3
-rw-r--r--mysql-test/t/bug46760-master.opt2
-rw-r--r--mysql-test/t/bug46760.test38
-rw-r--r--mysql-test/t/create.test17
-rw-r--r--mysql-test/t/ctype_ldml.test13
-rw-r--r--mysql-test/t/ctype_uca.test2
-rw-r--r--mysql-test/t/debug_sync.test420
-rw-r--r--mysql-test/t/delete.test44
-rw-r--r--mysql-test/t/disabled.def7
-rw-r--r--mysql-test/t/distinct.test40
-rw-r--r--mysql-test/t/explain.test31
-rw-r--r--mysql-test/t/flush_read_lock_kill.test2
-rw-r--r--mysql-test/t/func_group.test48
-rw-r--r--mysql-test/t/func_in.test85
-rw-r--r--mysql-test/t/func_str.test13
-rw-r--r--mysql-test/t/gis-rtree.test21
-rw-r--r--mysql-test/t/gis.test16
-rw-r--r--mysql-test/t/grant3.test35
-rw-r--r--mysql-test/t/grant_lowercase_fs.test30
-rw-r--r--mysql-test/t/information_schema.test3
-rw-r--r--mysql-test/t/information_schema_db.test1
-rw-r--r--mysql-test/t/innodb-autoinc.test180
-rw-r--r--mysql-test/t/innodb-index.test26
-rw-r--r--mysql-test/t/innodb.test6
-rw-r--r--mysql-test/t/innodb_bug36169.test7
-rw-r--r--mysql-test/t/innodb_bug36172.test4
-rw-r--r--mysql-test/t/innodb_bug39438.test4
-rw-r--r--mysql-test/t/innodb_bug44032.test (renamed from mysql-test/suite/innodb/t/innodb_bug44032.test)0
-rw-r--r--mysql-test/t/innodb_bug44369.test21
-rw-r--r--mysql-test/t/innodb_bug46000.test34
-rw-r--r--mysql-test/t/innodb_bug47777.test24
-rw-r--r--mysql-test/t/innodb_file_format.test (renamed from mysql-test/suite/innodb/t/innodb_file_format.test)15
-rw-r--r--mysql-test/t/innodb_lock_wait_timeout_1-master.opt (renamed from mysql-test/t/bug40113-master.opt)0
-rw-r--r--mysql-test/t/innodb_lock_wait_timeout_1.test230
-rw-r--r--mysql-test/t/innodb_mysql.test29
-rw-r--r--mysql-test/t/insert_select.test28
-rw-r--r--mysql-test/t/join.test74
-rw-r--r--mysql-test/t/kill.test2
-rw-r--r--mysql-test/t/locale.test18
-rw-r--r--mysql-test/t/lowercase_fs_off.test62
-rw-r--r--mysql-test/t/lowercase_mixed_tmpdir_innodb-master.opt2
-rw-r--r--mysql-test/t/lowercase_mixed_tmpdir_innodb-master.sh6
-rw-r--r--mysql-test/t/lowercase_mixed_tmpdir_innodb.test12
-rw-r--r--mysql-test/t/lowercase_table3.test2
-rw-r--r--mysql-test/t/myisam-system.test6
-rw-r--r--mysql-test/t/myisam.test46
-rw-r--r--mysql-test/t/myisam_crash_before_flush_keys.test12
-rw-r--r--mysql-test/t/mysqlbinlog.test67
-rw-r--r--mysql-test/t/mysqltest.test41
-rw-r--r--mysql-test/t/named_pipe.test5
-rw-r--r--mysql-test/t/not_partition.test2
-rw-r--r--mysql-test/t/olap.test15
-rw-r--r--mysql-test/t/order_by.test32
-rw-r--r--mysql-test/t/partition.test13
-rw-r--r--mysql-test/t/partition_csv.test2
-rw-r--r--mysql-test/t/partition_innodb.test29
-rw-r--r--mysql-test/t/partition_innodb_builtin.test67
-rw-r--r--mysql-test/t/partition_innodb_plugin.test75
-rw-r--r--mysql-test/t/partition_open_files_limit-master.opt1
-rw-r--r--mysql-test/t/partition_open_files_limit.test26
-rw-r--r--mysql-test/t/plugin.test1
-rw-r--r--mysql-test/t/plugin_load.test1
-rw-r--r--mysql-test/t/ps_not_windows.test2
-rw-r--r--mysql-test/t/query_cache.test3
-rw-r--r--mysql-test/t/range.test215
-rw-r--r--mysql-test/t/select.test33
-rw-r--r--mysql-test/t/sp-bugs.test61
-rw-r--r--mysql-test/t/sp-error.test24
-rw-r--r--mysql-test/t/sp.test22
-rw-r--r--mysql-test/t/status-master.opt1
-rw-r--r--mysql-test/t/subselect.test17
-rw-r--r--mysql-test/t/subselect3.test66
-rw-r--r--mysql-test/t/subselect4.test64
-rw-r--r--mysql-test/t/type_bit.test11
-rw-r--r--mysql-test/t/type_newdecimal.test134
-rw-r--r--mysql-test/t/udf.test12
-rw-r--r--mysql-test/t/update.test15
-rw-r--r--mysql-test/t/upgrade.test2
-rw-r--r--mysql-test/t/view_grant.test147
-rw-r--r--mysql-test/t/warnings.test7
-rwxr-xr-xmysql-test/t/windows.test6
-rw-r--r--mysql-test/t/xa.test62
-rw-r--r--mysql-test/valgrind.supp99
-rw-r--r--mysys/CMakeLists.txt2
-rw-r--r--mysys/Makefile.am35
-rw-r--r--mysys/charset-def.c4
-rw-r--r--mysys/errors.c2
-rw-r--r--mysys/hash.c9
-rw-r--r--mysys/lf_hash.c15
-rw-r--r--mysys/mf_keycache.c146
-rw-r--r--mysys/mf_strip.c45
-rw-r--r--mysys/my_copy.c7
-rw-r--r--mysys/my_getopt.c6
-rw-r--r--mysys/my_largepage.c2
-rw-r--r--mysys/my_redel.c3
-rw-r--r--mysys/my_seek.c16
-rw-r--r--mysys/my_static.c7
-rw-r--r--mysys/my_thr_init.c7
-rw-r--r--mysys/my_wincond.c1
-rw-r--r--mysys/thr_lock.c22
-rw-r--r--mysys/thr_mutex.c31
-rw-r--r--mysys/tree.c8
-rw-r--r--mysys/typelib.c5
-rw-r--r--plugin/fulltext/plugin_example.c4
-rwxr-xr-xregex/CMakeLists.txt2
-rw-r--r--regex/engine.c76
-rw-r--r--regex/engine.ih10
-rw-r--r--scripts/fill_help_tables.sql32
-rwxr-xr-xscripts/make_win_bin_dist1
-rw-r--r--scripts/mysql_system_tables.sql2
-rw-r--r--scripts/mysql_system_tables_fix.sql4
-rw-r--r--sql-common/client.c6
-rw-r--r--sql-common/my_time.c3
-rwxr-xr-xsql/CMakeLists.txt1
-rw-r--r--sql/Makefile.am2
-rw-r--r--sql/debug_sync.cc1906
-rw-r--r--sql/debug_sync.h60
-rw-r--r--sql/event_data_objects.cc2
-rw-r--r--sql/events.cc10
-rw-r--r--sql/field.cc199
-rw-r--r--sql/field.h39
-rw-r--r--sql/ha_ndbcluster.cc17
-rw-r--r--sql/ha_ndbcluster_binlog.cc17
-rw-r--r--sql/ha_partition.cc182
-rw-r--r--sql/ha_partition.h23
-rw-r--r--sql/handler.cc45
-rw-r--r--sql/handler.h10
-rw-r--r--sql/item.cc109
-rw-r--r--sql/item.h5
-rw-r--r--sql/item_cmpfunc.cc219
-rw-r--r--sql/item_cmpfunc.h3
-rw-r--r--sql/item_func.cc58
-rw-r--r--sql/item_func.h1
-rw-r--r--sql/item_geofunc.cc9
-rw-r--r--sql/item_strfunc.cc7
-rw-r--r--sql/item_subselect.cc37
-rw-r--r--sql/item_sum.cc3
-rw-r--r--sql/item_timefunc.cc16
-rw-r--r--sql/item_xmlfunc.cc9
-rw-r--r--sql/log.cc71
-rw-r--r--sql/log_event.cc141
-rw-r--r--sql/log_event.h6
-rw-r--r--sql/log_event_old.cc104
-rw-r--r--sql/my_decimal.h14
-rw-r--r--sql/mysql_priv.h6
-rw-r--r--sql/mysqld.cc105
-rw-r--r--sql/opt_range.cc118
-rw-r--r--sql/opt_sum.cc3
-rw-r--r--sql/partition_info.cc6
-rw-r--r--sql/records.cc23
-rw-r--r--sql/repl_failsafe.cc4
-rw-r--r--sql/rpl_filter.cc8
-rw-r--r--sql/scheduler.cc4
-rw-r--r--sql/set_var.cc16
-rw-r--r--sql/set_var.h18
-rw-r--r--sql/share/errmsg.txt9
-rw-r--r--sql/slave.cc83
-rw-r--r--sql/slave.h3
-rw-r--r--sql/sp.cc4
-rw-r--r--sql/sp_head.cc43
-rw-r--r--sql/sql_acl.cc94
-rw-r--r--sql/sql_base.cc75
-rw-r--r--sql/sql_binlog.cc51
-rw-r--r--sql/sql_builtin.cc.in1
-rw-r--r--sql/sql_cache.cc15
-rw-r--r--sql/sql_class.cc123
-rw-r--r--sql/sql_class.h74
-rw-r--r--sql/sql_db.cc24
-rw-r--r--sql/sql_delete.cc160
-rw-r--r--sql/sql_handler.cc7
-rw-r--r--sql/sql_insert.cc108
-rw-r--r--sql/sql_lex.h7
-rw-r--r--sql/sql_load.cc135
-rw-r--r--sql/sql_locale.cc4
-rw-r--r--sql/sql_parse.cc122
-rw-r--r--sql/sql_partition.cc9
-rw-r--r--sql/sql_plugin.cc26
-rw-r--r--sql/sql_prepare.cc28
-rw-r--r--sql/sql_rename.cc2
-rw-r--r--sql/sql_repl.cc14
-rw-r--r--sql/sql_select.cc307
-rw-r--r--sql/sql_select.h25
-rw-r--r--sql/sql_show.cc166
-rw-r--r--sql/sql_table.cc135
-rw-r--r--sql/sql_tablespace.cc2
-rw-r--r--sql/sql_trigger.cc4
-rw-r--r--sql/sql_udf.cc4
-rw-r--r--sql/sql_update.cc11
-rw-r--r--sql/sql_view.cc2
-rw-r--r--sql/sql_yacc.yy25
-rw-r--r--sql/structs.h14
-rw-r--r--sql/table.cc37
-rw-r--r--sql/table.h12
-rw-r--r--sql/time.cc16
-rw-r--r--sql/udf_example.c4
-rw-r--r--sql/unireg.cc8
-rw-r--r--storage/archive/ha_archive.cc17
-rw-r--r--storage/blackhole/ha_blackhole.cc12
-rw-r--r--storage/csv/ha_tina.cc4
-rw-r--r--storage/federatedx/Makefile.am1
-rw-r--r--storage/federatedx/ha_federatedx.cc22
-rw-r--r--storage/heap/hp_write.c7
-rw-r--r--storage/innobase/dict/dict0dict.c2
-rw-r--r--storage/innobase/handler/ha_innodb.cc216
-rw-r--r--storage/innobase/handler/ha_innodb.h7
-rw-r--r--storage/innobase/os/os0proc.c1
-rw-r--r--storage/innobase/row/row0mysql.c15
-rw-r--r--storage/innodb_plugin/CMakeLists.txt16
-rw-r--r--storage/innodb_plugin/ChangeLog226
-rw-r--r--storage/innodb_plugin/Makefile.am1
-rw-r--r--storage/innodb_plugin/README29
-rw-r--r--storage/innodb_plugin/btr/btr0btr.c25
-rw-r--r--storage/innodb_plugin/btr/btr0sea.c2
-rw-r--r--storage/innodb_plugin/buf/buf0buf.c292
-rw-r--r--storage/innodb_plugin/buf/buf0flu.c42
-rw-r--r--storage/innodb_plugin/buf/buf0lru.c298
-rw-r--r--storage/innodb_plugin/buf/buf0rea.c209
-rw-r--r--storage/innodb_plugin/dict/dict0crea.c2
-rw-r--r--storage/innodb_plugin/dict/dict0dict.c25
-rw-r--r--storage/innodb_plugin/fil/fil0fil.c44
-rw-r--r--storage/innodb_plugin/fsp/fsp0fsp.c80
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.cc307
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.h25
-rw-r--r--storage/innodb_plugin/handler/handler0alter.cc17
-rw-r--r--storage/innodb_plugin/handler/handler0vars.h69
-rw-r--r--storage/innodb_plugin/handler/win_delay_loader.cc1024
-rw-r--r--storage/innodb_plugin/include/buf0buf.h132
-rw-r--r--storage/innodb_plugin/include/buf0buf.ic92
-rw-r--r--storage/innodb_plugin/include/buf0lru.h52
-rw-r--r--storage/innodb_plugin/include/buf0rea.h10
-rw-r--r--storage/innodb_plugin/include/buf0types.h2
-rw-r--r--storage/innodb_plugin/include/dict0crea.h2
-rw-r--r--storage/innodb_plugin/include/dict0dict.h2
-rw-r--r--storage/innodb_plugin/include/dict0mem.h2
-rw-r--r--storage/innodb_plugin/include/fsp0fsp.h2
-rw-r--r--storage/innodb_plugin/include/lock0lock.h8
-rw-r--r--storage/innodb_plugin/include/log0log.h7
-rw-r--r--storage/innodb_plugin/include/log0log.ic73
-rw-r--r--storage/innodb_plugin/include/log0recv.h5
-rw-r--r--storage/innodb_plugin/include/mtr0mtr.h5
-rw-r--r--storage/innodb_plugin/include/os0file.h1
-rw-r--r--storage/innodb_plugin/include/os0sync.h81
-rw-r--r--storage/innodb_plugin/include/page0page.h7
-rw-r--r--storage/innodb_plugin/include/page0page.ic2
-rw-r--r--storage/innodb_plugin/include/page0zip.h12
-rw-r--r--storage/innodb_plugin/include/rem0cmp.h2
-rw-r--r--storage/innodb_plugin/include/rem0rec.ic2
-rw-r--r--storage/innodb_plugin/include/row0ins.h2
-rw-r--r--storage/innodb_plugin/include/row0mysql.h6
-rw-r--r--storage/innodb_plugin/include/srv0srv.h16
-rw-r--r--storage/innodb_plugin/include/trx0rec.h4
-rw-r--r--storage/innodb_plugin/include/trx0rec.ic4
-rw-r--r--storage/innodb_plugin/include/trx0roll.h15
-rw-r--r--storage/innodb_plugin/include/trx0sys.ic4
-rw-r--r--storage/innodb_plugin/include/trx0trx.h4
-rw-r--r--storage/innodb_plugin/include/univ.i67
-rw-r--r--storage/innodb_plugin/include/ut0auxconf.h12
-rw-r--r--storage/innodb_plugin/include/ut0byte.h4
-rw-r--r--storage/innodb_plugin/include/ut0byte.ic4
-rw-r--r--storage/innodb_plugin/include/ut0ut.h20
-rw-r--r--storage/innodb_plugin/lock/lock0lock.c49
-rw-r--r--storage/innodb_plugin/log/log0log.c22
-rw-r--r--storage/innodb_plugin/log/log0recv.c82
-rw-r--r--storage/innodb_plugin/mem/mem0mem.c20
-rw-r--r--storage/innodb_plugin/mtr/mtr0mtr.c8
-rw-r--r--storage/innodb_plugin/mysql-test/innodb-analyze.test2
-rw-r--r--storage/innodb_plugin/mysql-test/innodb-consistent-master.opt1
-rw-r--r--storage/innodb_plugin/mysql-test/innodb-consistent.result35
-rw-r--r--storage/innodb_plugin/mysql-test/innodb-consistent.test58
-rw-r--r--storage/innodb_plugin/mysql-test/innodb-zip.result2
-rw-r--r--storage/innodb_plugin/mysql-test/innodb-zip.test2
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug34300.test2
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug36169.test4
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug36172.test6
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug44369.result14
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug44369.test21
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug44571.result9
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug44571.test17
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug46000.result17
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_bug46000.test34
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_file_format.result1
-rw-r--r--storage/innodb_plugin/mysql-test/innodb_file_format.test1
-rw-r--r--storage/innodb_plugin/os/os0file.c109
-rw-r--r--storage/innodb_plugin/os/os0proc.c1
-rw-r--r--storage/innodb_plugin/page/page0cur.c2
-rw-r--r--storage/innodb_plugin/page/page0page.c6
-rw-r--r--storage/innodb_plugin/page/page0zip.c65
-rw-r--r--storage/innodb_plugin/plug.in.disabled162
-rw-r--r--storage/innodb_plugin/rem/rem0cmp.c6
-rwxr-xr-xstorage/innodb_plugin/revert_gen.sh8
-rw-r--r--storage/innodb_plugin/row/row0ins.c8
-rw-r--r--storage/innodb_plugin/row/row0merge.c225
-rw-r--r--storage/innodb_plugin/row/row0mysql.c50
-rwxr-xr-xstorage/innodb_plugin/scripts/export.sh74
-rw-r--r--storage/innodb_plugin/srv/srv0srv.c56
-rw-r--r--storage/innodb_plugin/srv/srv0start.c38
-rw-r--r--storage/innodb_plugin/sync/sync0rw.c1
-rw-r--r--storage/innodb_plugin/sync/sync0sync.c71
-rw-r--r--storage/innodb_plugin/thr/thr0loc.c2
-rw-r--r--storage/innodb_plugin/trx/trx0rec.c4
-rw-r--r--storage/innodb_plugin/trx/trx0roll.c74
-rw-r--r--storage/innodb_plugin/trx/trx0trx.c4
-rw-r--r--storage/innodb_plugin/ut/ut0auxconf_atomic_pthread_t_solaris.c26
-rw-r--r--storage/innodb_plugin/ut/ut0auxconf_have_gcc_atomics.c61
-rw-r--r--storage/innodb_plugin/ut/ut0ut.c19
-rw-r--r--storage/innodb_plugin/win-plugin/README22
-rw-r--r--storage/innodb_plugin/win-plugin/win-plugin.diff279
-rw-r--r--storage/maria/ha_maria.cc33
-rw-r--r--storage/maria/lockman.c13
-rw-r--r--storage/maria/ma_check.c18
-rw-r--r--storage/maria/ma_check_standalone.h6
-rw-r--r--storage/maria/ma_ft_boolean_search.c54
-rw-r--r--storage/maria/ma_ft_nlq_search.c23
-rw-r--r--storage/maria/ma_ft_parser.c35
-rw-r--r--storage/maria/ma_ftdefs.h16
-rw-r--r--storage/maria/ma_sort.c11
-rw-r--r--storage/maria/ma_state.c2
-rw-r--r--storage/maria/maria_def.h2
-rw-r--r--storage/maria/maria_ftdump.c16
-rw-r--r--storage/maria/trnman.c6
-rw-r--r--storage/myisam/ft_boolean_search.c40
-rw-r--r--storage/myisam/ft_nlq_search.c12
-rw-r--r--storage/myisam/ft_parser.c34
-rw-r--r--storage/myisam/ft_stopwords.c5
-rw-r--r--storage/myisam/ftdefs.h10
-rw-r--r--storage/myisam/ha_myisam.cc33
-rw-r--r--storage/myisam/mi_check.c29
-rw-r--r--storage/myisam/mi_search.c6
-rw-r--r--storage/myisam/mi_write.c14
-rw-r--r--storage/myisam/myisam_ftdump.c15
-rw-r--r--storage/myisam/myisamchk.c14
-rw-r--r--storage/myisam/myisamdef.h2
-rw-r--r--storage/myisam/myisamlog.c2
-rw-r--r--storage/myisam/sort.c22
-rw-r--r--storage/myisammrg/myrg_open.c3
-rw-r--r--storage/mysql_storage_engine.cmake8
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp2
-rw-r--r--storage/ndb/src/kernel/blocks/suma/Suma.cpp18
-rw-r--r--storage/pbxt/src/discover_xt.cc2
-rw-r--r--storage/xtradb/CMakeLists.txt100
-rw-r--r--storage/xtradb/COPYING.Percona30
-rw-r--r--storage/xtradb/COPYING.Sun_Microsystems31
-rw-r--r--storage/xtradb/ChangeLog374
-rw-r--r--storage/xtradb/Doxyfile1419
-rw-r--r--storage/xtradb/Makefile.am438
-rw-r--r--storage/xtradb/btr/btr0btr.c651
-rw-r--r--storage/xtradb/btr/btr0cur.c949
-rw-r--r--storage/xtradb/btr/btr0pcur.c86
-rw-r--r--storage/xtradb/btr/btr0sea.c300
-rw-r--r--storage/xtradb/buf/buf0buddy.c163
-rw-r--r--storage/xtradb/buf/buf0buf.c650
-rw-r--r--storage/xtradb/buf/buf0flu.c328
-rw-r--r--storage/xtradb/buf/buf0lru.c269
-rw-r--r--storage/xtradb/buf/buf0rea.c167
-rw-r--r--storage/xtradb/data/data0data.c134
-rw-r--r--storage/xtradb/data/data0type.c105
-rw-r--r--storage/xtradb/dict/dict0boot.c46
-rw-r--r--storage/xtradb/dict/dict0crea.c226
-rw-r--r--storage/xtradb/dict/dict0dict.c997
-rw-r--r--storage/xtradb/dict/dict0load.c134
-rw-r--r--storage/xtradb/dict/dict0mem.c103
-rw-r--r--storage/xtradb/dyn/dyn0dyn.c11
-rw-r--r--storage/xtradb/eval/eval0eval.c83
-rw-r--r--storage/xtradb/eval/eval0proc.c51
-rw-r--r--storage/xtradb/fil/fil0fil.c1448
-rw-r--r--storage/xtradb/fsp/fsp0fsp.c1026
-rw-r--r--storage/xtradb/fut/fut0fut.c3
-rw-r--r--storage/xtradb/fut/fut0lst.c91
-rw-r--r--storage/xtradb/ha/ha0ha.c129
-rw-r--r--storage/xtradb/ha/ha0storage.c21
-rw-r--r--storage/xtradb/ha/hash0hash.c57
-rw-r--r--storage/xtradb/handler/ha_innodb.cc2492
-rw-r--r--storage/xtradb/handler/ha_innodb.h86
-rw-r--r--storage/xtradb/handler/handler0alter.cc163
-rw-r--r--storage/xtradb/handler/handler0vars.h5
-rw-r--r--storage/xtradb/handler/i_s.cc243
-rw-r--r--storage/xtradb/handler/i_s.h3
-rw-r--r--storage/xtradb/handler/innodb_patch_info.h2
-rw-r--r--storage/xtradb/handler/mysql_addons.cc3
-rw-r--r--storage/xtradb/handler/win_delay_loader.cc222
-rw-r--r--storage/xtradb/ibuf/ibuf0ibuf.c658
-rw-r--r--storage/xtradb/include/btr0btr.h455
-rw-r--r--storage/xtradb/include/btr0btr.ic141
-rw-r--r--storage/xtradb/include/btr0cur.h617
-rw-r--r--storage/xtradb/include/btr0cur.ic92
-rw-r--r--storage/xtradb/include/btr0pcur.h338
-rw-r--r--storage/xtradb/include/btr0pcur.ic233
-rw-r--r--storage/xtradb/include/btr0sea.h187
-rw-r--r--storage/xtradb/include/btr0sea.ic23
-rw-r--r--storage/xtradb/include/btr0types.h10
-rw-r--r--storage/xtradb/include/buf0buddy.h21
-rw-r--r--storage/xtradb/include/buf0buddy.ic46
-rw-r--r--storage/xtradb/include/buf0buf.h1251
-rw-r--r--storage/xtradb/include/buf0buf.ic487
-rw-r--r--storage/xtradb/include/buf0flu.h117
-rw-r--r--storage/xtradb/include/buf0flu.ic27
-rw-r--r--storage/xtradb/include/buf0lru.h112
-rw-r--r--storage/xtradb/include/buf0lru.ic3
-rw-r--r--storage/xtradb/include/buf0rea.h61
-rw-r--r--storage/xtradb/include/buf0types.h34
-rw-r--r--storage/xtradb/include/data0data.h385
-rw-r--r--storage/xtradb/include/data0data.ic240
-rw-r--r--storage/xtradb/include/data0type.h269
-rw-r--r--storage/xtradb/include/data0type.ic216
-rw-r--r--storage/xtradb/include/data0types.h3
-rw-r--r--storage/xtradb/include/db0err.h3
-rw-r--r--storage/xtradb/include/dict0boot.h44
-rw-r--r--storage/xtradb/include/dict0boot.ic25
-rw-r--r--storage/xtradb/include/dict0crea.h100
-rw-r--r--storage/xtradb/include/dict0crea.ic3
-rw-r--r--storage/xtradb/include/dict0dict.h979
-rw-r--r--storage/xtradb/include/dict0dict.ic399
-rw-r--r--storage/xtradb/include/dict0load.h58
-rw-r--r--storage/xtradb/include/dict0load.ic3
-rw-r--r--storage/xtradb/include/dict0mem.h396
-rw-r--r--storage/xtradb/include/dict0mem.ic3
-rw-r--r--storage/xtradb/include/dict0types.h9
-rw-r--r--storage/xtradb/include/dyn0dyn.h128
-rw-r--r--storage/xtradb/include/dyn0dyn.ic111
-rw-r--r--storage/xtradb/include/eval0eval.h59
-rw-r--r--storage/xtradb/include/eval0eval.ic77
-rw-r--r--storage/xtradb/include/eval0proc.h67
-rw-r--r--storage/xtradb/include/eval0proc.ic19
-rw-r--r--storage/xtradb/include/fil0fil.h545
-rw-r--r--storage/xtradb/include/fsp0fsp.h334
-rw-r--r--storage/xtradb/include/fsp0fsp.ic13
-rw-r--r--storage/xtradb/include/fsp0types.h110
-rw-r--r--storage/xtradb/include/fut0fut.h21
-rw-r--r--storage/xtradb/include/fut0fut.ic21
-rw-r--r--storage/xtradb/include/fut0lst.h161
-rw-r--r--storage/xtradb/include/fut0lst.ic77
-rw-r--r--storage/xtradb/include/ha0ha.h187
-rw-r--r--storage/xtradb/include/ha0ha.ic110
-rw-r--r--storage/xtradb/include/ha0storage.h83
-rw-r--r--storage/xtradb/include/ha0storage.ic46
-rw-r--r--storage/xtradb/include/ha_prototypes.h226
-rw-r--r--storage/xtradb/include/handler0alter.h17
-rw-r--r--storage/xtradb/include/hash0hash.h175
-rw-r--r--storage/xtradb/include/hash0hash.ic87
-rw-r--r--storage/xtradb/include/ibuf0ibuf.h198
-rw-r--r--storage/xtradb/include/ibuf0ibuf.ic112
-rw-r--r--storage/xtradb/include/ibuf0types.h3
-rw-r--r--storage/xtradb/include/lock0iter.h19
-rw-r--r--storage/xtradb/include/lock0lock.h659
-rw-r--r--storage/xtradb/include/lock0lock.ic48
-rw-r--r--storage/xtradb/include/lock0priv.h58
-rw-r--r--storage/xtradb/include/lock0priv.ic11
-rw-r--r--storage/xtradb/include/lock0types.h3
-rw-r--r--storage/xtradb/include/log0log.h632
-rw-r--r--storage/xtradb/include/log0log.ic168
-rw-r--r--storage/xtradb/include/log0recv.h334
-rw-r--r--storage/xtradb/include/log0recv.ic21
-rw-r--r--storage/xtradb/include/mach0data.h310
-rw-r--r--storage/xtradb/include/mach0data.ic284
-rw-r--r--storage/xtradb/include/mem0dbg.h61
-rw-r--r--storage/xtradb/include/mem0dbg.ic47
-rw-r--r--storage/xtradb/include/mem0mem.h236
-rw-r--r--storage/xtradb/include/mem0mem.ic202
-rw-r--r--storage/xtradb/include/mem0pool.h65
-rw-r--r--storage/xtradb/include/mem0pool.ic3
-rw-r--r--storage/xtradb/include/mtr0log.h213
-rw-r--r--storage/xtradb/include/mtr0log.ic95
-rw-r--r--storage/xtradb/include/mtr0mtr.h336
-rw-r--r--storage/xtradb/include/mtr0mtr.ic108
-rw-r--r--storage/xtradb/include/mtr0types.h3
-rw-r--r--storage/xtradb/include/mysql_addons.h3
-rw-r--r--storage/xtradb/include/os0file.h548
-rw-r--r--storage/xtradb/include/os0proc.h31
-rw-r--r--storage/xtradb/include/os0proc.ic3
-rw-r--r--storage/xtradb/include/os0sync.h241
-rw-r--r--storage/xtradb/include/os0sync.ic21
-rw-r--r--storage/xtradb/include/os0thread.h76
-rw-r--r--storage/xtradb/include/os0thread.ic3
-rw-r--r--storage/xtradb/include/page0cur.h276
-rw-r--r--storage/xtradb/include/page0cur.ic137
-rw-r--r--storage/xtradb/include/page0page.h771
-rw-r--r--storage/xtradb/include/page0page.ic453
-rw-r--r--storage/xtradb/include/page0types.h68
-rw-r--r--storage/xtradb/include/page0zip.h366
-rw-r--r--storage/xtradb/include/page0zip.ic123
-rw-r--r--storage/xtradb/include/pars0opt.h23
-rw-r--r--storage/xtradb/include/pars0opt.ic3
-rw-r--r--storage/xtradb/include/pars0pars.h641
-rw-r--r--storage/xtradb/include/pars0pars.ic3
-rw-r--r--storage/xtradb/include/pars0sym.h165
-rw-r--r--storage/xtradb/include/pars0sym.ic3
-rw-r--r--storage/xtradb/include/pars0types.h3
-rw-r--r--storage/xtradb/include/que0que.h295
-rw-r--r--storage/xtradb/include/que0que.ic104
-rw-r--r--storage/xtradb/include/que0types.h9
-rw-r--r--storage/xtradb/include/read0read.h123
-rw-r--r--storage/xtradb/include/read0read.ic33
-rw-r--r--storage/xtradb/include/read0types.h3
-rw-r--r--storage/xtradb/include/rem0cmp.h175
-rw-r--r--storage/xtradb/include/rem0cmp.ic53
-rw-r--r--storage/xtradb/include/rem0rec.h648
-rw-r--r--storage/xtradb/include/rem0rec.ic623
-rw-r--r--storage/xtradb/include/rem0types.h3
-rw-r--r--storage/xtradb/include/row0ext.h61
-rw-r--r--storage/xtradb/include/row0ext.ic35
-rw-r--r--storage/xtradb/include/row0ins.h85
-rw-r--r--storage/xtradb/include/row0ins.ic3
-rw-r--r--storage/xtradb/include/row0merge.h151
-rw-r--r--storage/xtradb/include/row0mysql.h512
-rw-r--r--storage/xtradb/include/row0mysql.ic3
-rw-r--r--storage/xtradb/include/row0purge.h41
-rw-r--r--storage/xtradb/include/row0purge.ic3
-rw-r--r--storage/xtradb/include/row0row.h241
-rw-r--r--storage/xtradb/include/row0row.ic41
-rw-r--r--storage/xtradb/include/row0sel.h328
-rw-r--r--storage/xtradb/include/row0sel.ic25
-rw-r--r--storage/xtradb/include/row0types.h3
-rw-r--r--storage/xtradb/include/row0uins.h11
-rw-r--r--storage/xtradb/include/row0uins.ic3
-rw-r--r--storage/xtradb/include/row0umod.h13
-rw-r--r--storage/xtradb/include/row0umod.ic3
-rw-r--r--storage/xtradb/include/row0undo.h100
-rw-r--r--storage/xtradb/include/row0undo.ic3
-rw-r--r--storage/xtradb/include/row0upd.h338
-rw-r--r--storage/xtradb/include/row0upd.ic77
-rw-r--r--storage/xtradb/include/row0vers.h88
-rw-r--r--storage/xtradb/include/row0vers.ic3
-rw-r--r--storage/xtradb/include/srv0que.h38
-rw-r--r--storage/xtradb/include/srv0srv.h383
-rw-r--r--storage/xtradb/include/srv0srv.ic3
-rw-r--r--storage/xtradb/include/srv0start.h78
-rw-r--r--storage/xtradb/include/sync0arr.h74
-rw-r--r--storage/xtradb/include/sync0arr.ic3
-rw-r--r--storage/xtradb/include/sync0rw.h336
-rw-r--r--storage/xtradb/include/sync0rw.ic209
-rw-r--r--storage/xtradb/include/sync0sync.h243
-rw-r--r--storage/xtradb/include/sync0sync.ic130
-rw-r--r--storage/xtradb/include/sync0types.h5
-rw-r--r--storage/xtradb/include/thr0loc.h31
-rw-r--r--storage/xtradb/include/thr0loc.ic3
-rw-r--r--storage/xtradb/include/trx0i_s.h184
-rw-r--r--storage/xtradb/include/trx0purge.h106
-rw-r--r--storage/xtradb/include/trx0purge.ic11
-rw-r--r--storage/xtradb/include/trx0rec.h297
-rw-r--r--storage/xtradb/include/trx0rec.ic76
-rw-r--r--storage/xtradb/include/trx0roll.h261
-rw-r--r--storage/xtradb/include/trx0roll.ic13
-rw-r--r--storage/xtradb/include/trx0rseg.h128
-rw-r--r--storage/xtradb/include/trx0rseg.ic67
-rw-r--r--storage/xtradb/include/trx0sys.h506
-rw-r--r--storage/xtradb/include/trx0sys.ic154
-rw-r--r--storage/xtradb/include/trx0trx.h407
-rw-r--r--storage/xtradb/include/trx0trx.ic49
-rw-r--r--storage/xtradb/include/trx0types.h58
-rw-r--r--storage/xtradb/include/trx0undo.h456
-rw-r--r--storage/xtradb/include/trx0undo.ic163
-rw-r--r--storage/xtradb/include/trx0xa.h45
-rw-r--r--storage/xtradb/include/univ.i82
-rw-r--r--storage/xtradb/include/usr0sess.h23
-rw-r--r--storage/xtradb/include/usr0sess.ic3
-rw-r--r--storage/xtradb/include/usr0types.h3
-rw-r--r--storage/xtradb/include/ut0auxconf.h7
-rw-r--r--storage/xtradb/include/ut0byte.h228
-rw-r--r--storage/xtradb/include/ut0byte.ic200
-rw-r--r--storage/xtradb/include/ut0dbg.h67
-rw-r--r--storage/xtradb/include/ut0list.h103
-rw-r--r--storage/xtradb/include/ut0list.ic23
-rw-r--r--storage/xtradb/include/ut0lst.h186
-rw-r--r--storage/xtradb/include/ut0mem.h211
-rw-r--r--storage/xtradb/include/ut0mem.ic76
-rw-r--r--storage/xtradb/include/ut0rnd.h93
-rw-r--r--storage/xtradb/include/ut0rnd.ic84
-rw-r--r--storage/xtradb/include/ut0sort.h5
-rw-r--r--storage/xtradb/include/ut0ut.h309
-rw-r--r--storage/xtradb/include/ut0ut.ic77
-rw-r--r--storage/xtradb/include/ut0vec.h68
-rw-r--r--storage/xtradb/include/ut0vec.ic46
-rw-r--r--storage/xtradb/include/ut0wqueue.h42
-rw-r--r--storage/xtradb/lock/lock0iter.c19
-rw-r--r--storage/xtradb/lock/lock0lock.c1287
-rw-r--r--storage/xtradb/log/log0log.c444
-rw-r--r--storage/xtradb/log/log0recv.c717
-rw-r--r--storage/xtradb/mach/mach0data.c29
-rw-r--r--storage/xtradb/mem/mem0dbg.c136
-rw-r--r--storage/xtradb/mem/mem0mem.c148
-rw-r--r--storage/xtradb/mem/mem0pool.c125
-rw-r--r--storage/xtradb/mtr/mtr0log.c147
-rw-r--r--storage/xtradb/mtr/mtr0mtr.c84
-rw-r--r--storage/xtradb/os/os0file.c870
-rw-r--r--storage/xtradb/os/os0proc.c56
-rw-r--r--storage/xtradb/os/os0sync.c168
-rw-r--r--storage/xtradb/os/os0thread.c81
-rw-r--r--storage/xtradb/page/page0cur.c325
-rw-r--r--storage/xtradb/page/page0page.c480
-rw-r--r--storage/xtradb/page/page0zip.c847
-rw-r--r--storage/xtradb/pars/lexyy.c8
-rw-r--r--storage/xtradb/pars/pars0lex.l6
-rw-r--r--storage/xtradb/pars/pars0opt.c200
-rw-r--r--storage/xtradb/pars/pars0pars.c583
-rw-r--r--storage/xtradb/pars/pars0sym.c79
-rw-r--r--storage/xtradb/plug.in74
-rw-r--r--storage/xtradb/que/que0que.c215
-rw-r--r--storage/xtradb/read/read0read.c70
-rw-r--r--storage/xtradb/rem/rem0cmp.c246
-rw-r--r--storage/xtradb/rem/rem0rec.c282
-rw-r--r--storage/xtradb/row/row0ext.c29
-rw-r--r--storage/xtradb/row/row0ins.c412
-rw-r--r--storage/xtradb/row/row0merge.c696
-rw-r--r--storage/xtradb/row/row0mysql.c602
-rw-r--r--storage/xtradb/row/row0purge.c119
-rw-r--r--storage/xtradb/row/row0row.c291
-rw-r--r--storage/xtradb/row/row0sel.c523
-rw-r--r--storage/xtradb/row/row0uins.c48
-rw-r--r--storage/xtradb/row/row0umod.c155
-rw-r--r--storage/xtradb/row/row0undo.c53
-rw-r--r--storage/xtradb/row/row0upd.c459
-rw-r--r--storage/xtradb/row/row0vers.c102
-rw-r--r--storage/xtradb/srv/srv0que.c85
-rw-r--r--storage/xtradb/srv/srv0srv.c647
-rw-r--r--storage/xtradb/srv/srv0start.c320
-rw-r--r--storage/xtradb/sync/sync0arr.c205
-rw-r--r--storage/xtradb/sync/sync0rw.c188
-rw-r--r--storage/xtradb/sync/sync0sync.c292
-rw-r--r--storage/xtradb/thr/thr0loc.c64
-rw-r--r--storage/xtradb/trx/trx0i_s.c369
-rw-r--r--storage/xtradb/trx/trx0purge.c138
-rw-r--r--storage/xtradb/trx/trx0rec.c394
-rw-r--r--storage/xtradb/trx/trx0roll.c279
-rw-r--r--storage/xtradb/trx/trx0rseg.c65
-rw-r--r--storage/xtradb/trx/trx0sys.c471
-rw-r--r--storage/xtradb/trx/trx0trx.c260
-rw-r--r--storage/xtradb/trx/trx0undo.c584
-rw-r--r--storage/xtradb/usr/usr0sess.c25
-rw-r--r--storage/xtradb/ut/ut0auxconf.c13
-rw-r--r--storage/xtradb/ut/ut0auxconf_atomic_pthread_t_gcc.c43
-rw-r--r--storage/xtradb/ut/ut0auxconf_atomic_pthread_t_solaris.c34
-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
-rw-r--r--storage/xtradb/ut/ut0byte.c17
-rw-r--r--storage/xtradb/ut/ut0dbg.c47
-rw-r--r--storage/xtradb/ut/ut0list.c69
-rw-r--r--storage/xtradb/ut/ut0mem.c177
-rw-r--r--storage/xtradb/ut/ut0rnd.c17
-rw-r--r--storage/xtradb/ut/ut0ut.c190
-rw-r--r--storage/xtradb/ut/ut0vec.c23
-rw-r--r--storage/xtradb/ut/ut0wqueue.c34
-rw-r--r--storage/xtradb/win-plugin/README3
-rw-r--r--storage/xtradb/win-plugin/win-plugin.diff88
-rw-r--r--strings/ctype-mb.c11
-rw-r--r--strings/ctype-simple.c4
-rw-r--r--strings/ctype-uca.c351
-rw-r--r--strings/ctype-ucs2.c13
-rw-r--r--support-files/MacOSX/ReadMe.txt451
-rw-r--r--support-files/binary-configure.sh24
-rw-r--r--tests/mysql_client_test.c94
-rw-r--r--unittest/mysys/Makefile.am12
-rw-r--r--vio/vio.c27
-rw-r--r--vio/vio_priv.h5
-rw-r--r--vio/viosocket.c120
-rw-r--r--vio/viosslfactories.c62
980 files changed, 60027 insertions, 39706 deletions
diff --git a/.bzrignore b/.bzrignore
index d2a1ce94f70..e3cb25a09c9 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -1922,3 +1922,5 @@ libmysqld/examples/mysqltest.cc
extra/libevent/event-config.h
libmysqld/opt_table_elimination.cc
libmysqld/ha_federatedx.cc
+tmp
+libmysqld/debug_sync.cc
diff --git a/BUILD/compile-pentium b/BUILD/compile-pentium
index b8f8d028e1f..cdbc7e773eb 100755
--- a/BUILD/compile-pentium
+++ b/BUILD/compile-pentium
@@ -4,7 +4,7 @@ path=`dirname $0`
. "$path/SETUP.sh"
extra_flags="$pentium_cflags $fast_cflags"
-extra_configs="$pentium_configs $static_link"
+extra_configs="$pentium_configs"
strip=yes
. "$path/FINISH.sh"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cccd42205b1..0d7380c8f75 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -66,6 +66,12 @@ IF(EXTRA_DEBUG)
ADD_DEFINITIONS(-D EXTRA_DEBUG)
ENDIF(EXTRA_DEBUG)
+IF(ENABLED_DEBUG_SYNC)
+ ADD_DEFINITIONS(-D ENABLED_DEBUG_SYNC)
+ENDIF(ENABLED_DEBUG_SYNC)
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DENABLED_DEBUG_SYNC")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DENABLED_DEBUG_SYNC")
+
# in some places we use DBUG_OFF
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDBUG_OFF")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDBUG_OFF")
@@ -211,12 +217,16 @@ ENDIF(WITHOUT_DYNAMIC_PLUGINS)
FILE(GLOB STORAGE_SUBDIRS storage/*)
FOREACH(SUBDIR ${STORAGE_SUBDIRS})
FILE(RELATIVE_PATH DIRNAME ${PROJECT_SOURCE_DIR}/storage ${SUBDIR})
- STRING(TOUPPER ${DIRNAME} ENGINE)
- STRING(TOLOWER ${DIRNAME} ENGINE_LOWER)
IF (EXISTS ${SUBDIR}/CMakeLists.txt)
# Check MYSQL_STORAGE_ENGINE macro is present
FILE(STRINGS ${SUBDIR}/CMakeLists.txt HAVE_STORAGE_ENGINE REGEX MYSQL_STORAGE_ENGINE)
IF(HAVE_STORAGE_ENGINE)
+ # Extract name of engine from HAVE_STORAGE_ENGINE
+ STRING(REGEX REPLACE ".*MYSQL_STORAGE_ENGINE\\((.*\)\\).*"
+ "\\1" ENGINE_NAME ${HAVE_STORAGE_ENGINE})
+ STRING(TOUPPER ${ENGINE_NAME} ENGINE)
+ STRING(TOLOWER ${ENGINE_NAME} ENGINE_LOWER)
+
SET(ENGINE_BUILD_TYPE "DYNAMIC")
# Read plug.in to find out if a plugin is mandatory and whether it supports
# build as shared library (dynamic).
@@ -254,6 +264,7 @@ FOREACH(SUBDIR ${STORAGE_SUBDIRS})
SET (MYSQLD_STATIC_ENGINE_LIBS ${MYSQLD_STATIC_ENGINE_LIBS} ${PLUGIN_NAME})
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_${ENGINE}_STORAGE_ENGINE")
SET (WITH_${ENGINE}_STORAGE_ENGINE TRUE)
+ SET (${ENGINE}_DIR ${DIRNAME})
ENDIF (ENGINE_BUILD_TYPE STREQUAL "STATIC")
ENDIF(EXISTS ${SUBDIR}/plug.in)
diff --git a/Docs/INSTALL-BINARY b/Docs/INSTALL-BINARY
index 499a8adf411..01ac65950a9 100644
--- a/Docs/INSTALL-BINARY
+++ b/Docs/INSTALL-BINARY
@@ -3,7 +3,7 @@ describe how to install MariaDB; However all documentation at www.mysql.com
also applies.
-2.9. Installing MariaDB from tar.gz Packages on Other Unix-Like Systems
+2.2. Installing MariaDB from Generic Binaries on Unix/Linux
This section covers the installation of MariaDB binary distributions
that are provided for various platforms in the form of compressed
@@ -22,11 +22,13 @@ also applies.
* A reasonable tar to unpack the distribution. GNU tar is known
to work. Some operating systems come with a preinstalled
version of tar that is known to have problems. For example,
- the tar provided with early versions of Mac OS X, SunOS 4.x
- and Solaris 8 and earlier are known to have problems with long
- file names. On Mac OS X, you can use the preinstalled gnutar
- program. On other systems with a deficient tar, you should
- install GNU tar first.
+ the tar provided with early versions of Mac OS X, SunOS 4.x,
+ Solaris 8, Solaris 9, Solaris 10 and OpenSolaris, and HP-UX
+ are known to have problems with long file names. On Mac OS X,
+ you can use the preinstalled gnutar program. On Solaris 10 and
+ OpenSolaris you can use the preinstalled gtar. On other
+ systems with a deficient tar, you should install GNU tar
+ first.
If you run into problems and need to file a bug report,
please report them to: http://bugs.launchpad.net/maria
@@ -52,7 +54,7 @@ shell> bin/mysqld_safe --user=mysql &
Note
This procedure does not set up any passwords for MariaDB accounts.
- After following the procedure, proceed to Section 2.11,
+ After following the procedure, proceed to Section 2.13,
"Post-Installation Setup and Testing."
A more detailed version of the preceding description for
@@ -147,7 +149,7 @@ shell> chown -R mysql data
machine, you can copy support-files/mysql.server to the
location where your system has its startup files. More
information can be found in the support-files/mysql.server
- script itself and in Section 2.11.2.2, "Starting and Stopping
+ script itself and in Section 2.13.1.2, "Starting and Stopping
MariaDB Automatically."
10. You can set up new accounts using the bin/mysql_setpermission
script if you install the DBI and DBD::mysql Perl modules. See
@@ -186,5 +188,5 @@ Note
The accounts that are listed in the MariaDB grant tables initially
have no passwords. After starting the server, you should set up
- passwords for them using the instructions in Section 2.11,
+ passwords for them using the instructions in Section 2.13,
"Post-Installation Setup and Testing."
diff --git a/INSTALL-SOURCE b/INSTALL-SOURCE
index b38f884d98c..4e91825917b 100644
--- a/INSTALL-SOURCE
+++ b/INSTALL-SOURCE
@@ -5,9 +5,8 @@ Chapter 2. Installing and Upgrading MySQL
of the procedure follows and later sections provide the details.
If you plan to upgrade an existing version of MySQL to a newer
version rather than install MySQL for the first time, see Section
- 2.12.1, "Upgrading MySQL," for information about upgrade
- procedures and about issues that you should consider before
- upgrading.
+ 2.4.1, "Upgrading MySQL," for information about upgrade procedures
+ and about issues that you should consider before upgrading.
If you are interested in migrating to MySQL from another database
system, you may wish to read Section A.8, "MySQL 5.1 FAQ ---
@@ -15,96 +14,61 @@ Chapter 2. Installing and Upgrading MySQL
concerning migration issues.
1. Determine whether MySQL runs and is supported on your
- platform. Please note that not all platforms are equally
- suitable for running MySQL, and that not all platforms on
- which MySQL is known to run are officially supported by Sun
- Microsystems, Inc.:
-
- + For MySQL Enterprise Server, the officially supported
- platforms are listed at
- http://www.mysql.com/support/supportedplatforms.html.
-
- + MySQL Community Server runs on the platforms listed at
- Section 2.1.1, "Operating Systems Supported by MySQL
- Community Server."
-
- 2. Choose which distribution to install. Several versions of
- MySQL are available, and most are available in several
- distribution formats. You can choose from pre-packaged
- distributions containing binary (precompiled) programs or
- source code. When in doubt, use a binary distribution. We also
- provide public access to our current source tree for those who
- want to see our most recent developments and help us test new
- code. To determine which version and type of distribution you
- should use, see Section 2.1.2, "Choosing Which MySQL
- Distribution to Install."
-
- 3. Download the distribution that you want to install. For
- instructions, see Section 2.1.3, "How to Get MySQL." To verify
- the integrity of the distribution, use the instructions in
- Section 2.1.4, "Verifying Package Integrity Using MD5
+ platform.
+ Please note that not all platforms are equally suitable for
+ running MySQL, and that not all platforms on which MySQL is
+ known to run are officially supported by Sun Microsystems,
+ Inc.:
+
+ 2. Choose which distribution to install.
+ Several versions of MySQL are available, and most are
+ available in several distribution formats. You can choose from
+ pre-packaged distributions containing binary (precompiled)
+ programs or source code. When in doubt, use a binary
+ distribution. We also provide public access to our current
+ source tree for those who want to see our most recent
+ developments and help us test new code. To determine which
+ version and type of distribution you should use, see Section
+ 2.1.2, "Choosing Which MySQL Distribution to Install."
+
+ 3. Download the distribution that you want to install.
+ For instructions, see Section 2.1.3, "How to Get MySQL." To
+ verify the integrity of the distribution, use the instructions
+ in Section 2.1.4, "Verifying Package Integrity Using MD5
Checksums or GnuPG."
- 4. Install the distribution. To install MySQL from a binary
- distribution, use the instructions in Section 2.2, "Standard
- MySQL Installation Using a Binary Distribution." To install
- MySQL from a source distribution or from the current
- development source tree, use the instructions in Section 2.10,
- "MySQL Installation Using a Source Distribution."
- If you encounter installation difficulties, see Section 2.13,
- "Operating System-Specific Notes," for information on solving
- problems for particular platforms.
-
- 5. Perform any necessary post-installation setup. After
- installing MySQL, read Section 2.11, "Post-Installation Setup
- and Testing." This section contains important information
- about making sure the MySQL server is working properly. It
- also describes how to secure the initial MySQL user accounts,
- which have no passwords until you assign passwords. The
- section applies whether you install MySQL using a binary or
- source distribution.
+ 4. Install the distribution.
+ To install MySQL from a binary distribution, use the
+ instructions in Section 2.2, "Installing MySQL from Generic
+ Binaries on Unix/Linux."
+ To install MySQL from a source distribution or from the
+ current development source tree, use the instructions in
+ Section 2.3, "MySQL Installation Using a Source Distribution."
+
+ 5. Perform any necessary post-installation setup.
+ After installing MySQL, read Section 2.13, "Post-Installation
+ Setup and Testing." This section contains important
+ information about making sure the MySQL server is working
+ properly. It also describes how to secure the initial MySQL
+ user accounts, which have no passwords until you assign
+ passwords. The section applies whether you install MySQL using
+ a binary or source distribution.
6. If you want to run the MySQL benchmark scripts, Perl support
for MySQL must be available. See Section 2.15, "Perl
Installation Notes."
-2.1. General Installation Issues
-
- The MySQL installation procedure depends on whether you will
- install MySQL Enterprise Server or MySQL Community Server. The set
- of applicable platforms depends on which distribution you will
- install:
-
- * For MySQL Enterprise Server, the officially supported
- platforms are listed at
- http://www.mysql.com/support/supportedplatforms.html.
-
- * MySQL Community Server runs on the platforms listed at Section
- 2.1.1, "Operating Systems Supported by MySQL Community
- Server."
-
- For MySQL Enterprise Server, install the main distribution plus
- any service packs or hotfixes that you wish to apply using the
- Enterprise Installer. For platforms that do not yet have an
- Enterprise Installer, use the Community Server instructions.
-
- For MySQL Community Server, install the main distribution plus any
- hotfixes and updates:
-
- * Download a binary release, or download a source release and
- build MySQL yourself from the source code.
-
- * Retrieve MySQL from the Bazaar tree and build it from source.
- The Bazaar tree contains the latest developer code.
+2.1. General Installation Guidance
The immediately following sections contain the information
necessary to choose, download, and verify your distribution. The
instructions in later sections of the chapter describe how to
install the distribution that you choose. For binary
- distributions, see the instructions at Section 2.2, "Standard
- MySQL Installation Using a Binary Distribution." To build MySQL
- from source, use the instructions at Section 2.10, "MySQL
- Installation Using a Source Distribution."
+ distributions, see the instructions at Section 2.2, "Installing
+ MySQL from Generic Binaries on Unix/Linux" or the corresponding
+ section for your platform if available. To build MySQL from
+ source, use the instructions in Section 2.3, "MySQL Installation
+ Using a Source Distribution."
2.1.1. Operating Systems Supported by MySQL Community Server
@@ -129,58 +93,31 @@ Important
MySQL has been reported to compile successfully on the following
combinations of operating system and thread package.
- * AIX 4.x, 5.x with native threads. See Section 2.13.5.3,
- "IBM-AIX notes."
-
- * Amiga.
+ * AIX 4.x, 5.x with native threads. See Section 2.12,
+ "Installing MySQL on AIX." AIX 5.3 should be upgraded to
+ technology level 7 (5300-07).
- * FreeBSD 5.x and up with native threads.
+ * FreeBSD 5.x and up with native threads. See Section 2.10,
+ "Installing MySQL on FreeBSD."
- * HP-UX 11.x with the native threads. See Section 2.13.5.2,
- "HP-UX Version 11.x Notes."
+ * HP-UX 11.x with the native threads. See Section 2.11,
+ "Installing MySQL on HP-UX."
* Linux, builds on all fairly recent Linux distributions with
- glibc 2.3. See Section 2.13.1, "Linux Notes."
-
- * Mac OS X. See Section 2.13.2, "Mac OS X Notes."
-
- * NetBSD 1.3/1.4 Intel and NetBSD 1.3 Alpha. See Section
- 2.13.4.2, "NetBSD Notes."
-
- * Novell NetWare 6.0 and 6.5. See Section 2.8, "Installing MySQL
- on NetWare."
-
- * OpenBSD 2.5 and with native threads. OpenBSD earlier than 2.5
- with the MIT-pthreads package. See Section 2.13.4.3, "OpenBSD
- 2.5 Notes."
+ glibc 2.3. See Section 2.6, "Installing MySQL on Linux."
- * SCO OpenServer 5.0.X with a recent port of the FSU Pthreads
- package. See Section 2.13.5.8, "SCO UNIX and OpenServer 5.0.x
- Notes."
+ * Mac OS X. See Section 2.7, "Installing MySQL on Mac OS X."
- * SCO Openserver 6.0.x. See Section 2.13.5.9, "SCO OpenServer
- 6.0.x Notes."
-
- * SCO UnixWare 7.1.x. See Section 2.13.5.10, "SCO UnixWare 7.1.x
- and OpenUNIX 8.0.0 Notes."
-
- * SGI Irix 6.x with native threads. See Section 2.13.5.7, "SGI
- Irix Notes."
-
- * Solaris 2.5 and above with native threads on SPARC and x86.
- See Section 2.13.3, "Solaris Notes."
-
- * Tru64 Unix. See Section 2.13.5.5, "Alpha-DEC-UNIX Notes
- (Tru64)."
+ * Solaris 2.8 on SPARC and x86, including support for native
+ threads. See Section 2.8.1, "Solaris Notes."
* Windows 2000, Windows XP, Windows Vista, Windows Server 2003,
- and Windows Server 2008. See Section 2.3, "Installing MySQL on
+ and Windows Server 2008. See Section 2.5, "Installing MySQL on
Windows."
MySQL has also been known to run on other systems in the past. See
- Section 2.13, "Operating System-Specific Notes." Some porting
- effort might be required for current versions of MySQL on these
- systems.
+ Section 2.1, "General Installation Guidance." Some porting effort
+ might be required for current versions of MySQL on these systems.
Not all platforms are equally well-suited for running MySQL. How
well a certain platform is suited for a high-load mission-critical
@@ -208,8 +145,8 @@ Important
* General file system stability and performance.
* Table size. If your tables are large, performance is affected
- by the ability of the file system to deal with large files at
- all and to deal with them efficiently.
+ by the ability of the file system to deal with large files and
+ dealing with them efficiently.
* Our level of expertise here at Sun Microsystems, Inc. with the
platform. If we know a platform well, we enable
@@ -240,7 +177,7 @@ Important
development process, multiple release series co-exist, each at a
different stage of maturity:
- * MySQL 5.4 and 6.0 are the current development release series.
+ * MySQL 5.5 is the current development release series.
* MySQL 5.1 is the current General Availability (Production)
release series. New releases are issued for bugfixes only; no
@@ -255,9 +192,9 @@ Important
has ended.
Extended support for MySQL 4.1 remains available. According to
the MySQL Lifecycle Policy
- (http://www.mysql.com/company/legal/lifecycle/#policy), only
- Security and Severity Level 1 issues are still being fixed for
- MySQL 4.1.
+ (http://www.mysql.com/about/legal/lifecycle/), only Security
+ and Severity Level 1 issues are still being fixed for MySQL
+ 4.1.
We do not believe in a complete code freeze because this prevents
us from making bugfixes and other fixes that must be done. By
@@ -367,13 +304,13 @@ Important
* The MySQL benchmark suite
This suite runs a range of common queries. It is also a test
to determine whether the latest batch of optimizations
- actually made the code faster. See Section 7.1.4, "The MySQL
+ actually made the code faster. See Section 7.1.3, "The MySQL
Benchmark Suite."
* The crash-me test
This test tries to determine what features the database
supports and what its capabilities and limitations are. See
- Section 7.1.4, "The MySQL Benchmark Suite."
+ Section 7.1.3, "The MySQL Benchmark Suite."
We also test the newest MySQL version in our internal production
environment, on at least one machine. We have more than 100GB of
@@ -492,21 +429,6 @@ Important
as soon as possible. (We would like other companies to do
this, too!)
-2.1.2.4. MySQL Binaries Compiled by Sun Microsystems, Inc.
-
- Sun Microsystems, Inc. provides a set of binary distributions of
- MySQL. In addition to binaries provided in platform-specific
- package formats, we offer binary distributions for a number of
- platforms in the form of compressed tar files (.tar.gz files). See
- Section 2.2, "Standard MySQL Installation Using a Binary
- Distribution." For Windows distributions, see Section 2.3,
- "Installing MySQL on Windows."
-
- If you want to compile a debug version of MySQL from a source
- distribution, you should add --with-debug or --with-debug=full to
- the configure command used to configure the distribution and
- remove any -fomit-frame-pointer options.
-
2.1.3. How to Get MySQL
Check our downloads page at http://dev.mysql.com/downloads/ for
@@ -553,8 +475,8 @@ Important
shell> md5sum package_name
Example:
-shell> md5sum mysql-standard-5.1.39-linux-i686.tar.gz
-aaab65abbec64d5e907dcd41b8699945 mysql-standard-5.1.39-linux-i686.ta
+shell> md5sum mysql-standard-5.1.41-linux-i686.tar.gz
+aaab65abbec64d5e907dcd41b8699945 mysql-standard-5.1.41-linux-i686.ta
r.gz
You should verify that the resulting checksum (the string of
@@ -728,8 +650,8 @@ pg-signature.html
signature, which also is available from the download page. The
signature file has the same name as the distribution file with an
.asc extension, as shown by the examples in the following table.
- Distribution file mysql-standard-5.1.39-linux-i686.tar.gz
- Signature file mysql-standard-5.1.39-linux-i686.tar.gz.asc
+ Distribution file mysql-standard-5.1.41-linux-i686.tar.gz
+ Signature file mysql-standard-5.1.41-linux-i686.tar.gz.asc
Make sure that both files are stored in the same directory and
then run the following command to verify the signature for the
@@ -737,7 +659,7 @@ pg-signature.html
shell> gpg --verify package_name.asc
Example:
-shell> gpg --verify mysql-standard-5.1.39-linux-i686.tar.gz.asc
+shell> gpg --verify mysql-standard-5.1.41-linux-i686.tar.gz.asc
gpg: Signature made Tue 12 Jul 2005 23:35:41 EST using DSA key ID 507
2E1F5
gpg: Good signature from "MySQL Package signing key (www.mysql.com) <
@@ -757,8 +679,8 @@ build@mysql.com>"
shell> rpm --checksig package_name.rpm
Example:
-shell> rpm --checksig MySQL-server-5.1.39-0.glibc23.i386.rpm
-MySQL-server-5.1.39-0.glibc23.i386.rpm: md5 gpg OK
+shell> rpm --checksig MySQL-server-5.1.41-0.glibc23.i386.rpm
+MySQL-server-5.1.41-0.glibc23.i386.rpm: md5 gpg OK
Note
@@ -786,22 +708,6 @@ shell> rpm --import mysql_pubkey.asc
Sun Microsystems, Inc. A distribution provided by another vendor
might use a layout different from those shown here.
- For MySQL 5.1 on Windows, the default installation directory is
- C:\Program Files\MySQL\MySQL Server 5.1. (Some Windows users
- prefer to install in C:\mysql, the directory that formerly was
- used as the default. However, the layout of the subdirectories
- remains the same.) The installation directory has the following
- subdirectories.
- Directory Contents of Directory
- bin Client programs and the mysqld server
- data Log files, databases
- Docs Manual in CHM format
- examples Example programs and scripts
- include Include (header) files
- lib Libraries
- scripts Utility scripts
- share Error message files
-
Installations created from our Linux RPM distributions result in
files under the following system directories.
Directory Contents of Directory
@@ -863,2399 +769,37 @@ shell> rpm --import mysql_pubkey.asc
distribution by executing the scripts/make_binary_distribution
script from the top directory of the source distribution.
-2.2. Standard MySQL Installation Using a Binary Distribution
-
- The next several sections cover the installation of MySQL on
- platforms where we offer packages using the native packaging
- format of the respective platform. (This is also known as
- performing a "binary install.") However, binary distributions of
- MySQL are available for many other platforms as well. See Section
- 2.9, "Installing MySQL from tar.gz Packages on Other Unix-Like
- Systems," for generic installation instructions for these packages
- that apply to all platforms.
-
- See Section 2.1, "General Installation Issues," for more
- information on what other binary distributions are available and
- how to obtain them.
-
-2.3. Installing MySQL on Windows
-
- A native Windows distribution of MySQL has been available since
- version 3.21 and represents a sizable percentage of the daily
- downloads of MySQL. This section describes the process for
- installing MySQL on Windows.
-
-Note
-
- If you are upgrading MySQL from an existing installation older
- than MySQL 4.1.5, you must first perform the procedure described
- in Section 2.3.14, "Upgrading MySQL on Windows."
-
- To run MySQL on Windows, you need the following:
-
- * A Windows operating system such as Windows 2000, Windows XP,
- Windows Vista, Windows Server 2003, or Windows Server 2008.
- Both 32-bit and 64-bit versions are supported.
- A Windows operating system permits you to run the MySQL server
- as a service. See Section 2.3.11, "Starting MySQL as a Windows
- Service."
- Generally, you should install MySQL on Windows using an
- account that has administrator rights. Otherwise, you may
- encounter problems with certain operations such as editing the
- PATH environment variable or accessing the Service Control
- Manager. Once installed, MySQL does not need to be executed
- using a user with Administrator privileges.
-
- * TCP/IP protocol support.
-
- * Enough space on the hard drive to unpack, install, and create
- the databases in accordance with your requirements (generally
- a minimum of 200 megabytes is recommended.)
-
- For a list of limitations within the Windows version of MySQL, see
- Section D.7.3, "Windows Platform Limitations."
-
- There may also be other requirements, depending on how you plan to
- use MySQL:
-
- * If you plan to connect to the MySQL server via ODBC, you need
- a Connector/ODBC driver. See Section 21.1, "MySQL
- Connector/ODBC."
-
- * If you plan to use MySQL server with ADO.NET applications, you
- need the Connector/NET driver. See Section 21.2, "MySQL
- Connector/NET."
-
- * If you need tables with a size larger than 4GB, install MySQL
- on an NTFS or newer file system. Don't forget to use MAX_ROWS
- and AVG_ROW_LENGTH when you create tables. See Section
- 12.1.17, "CREATE TABLE Syntax."
-
- MySQL for Windows is available in several distribution formats:
-
- * Binary distributions are available that contain a setup
- program that installs everything you need so that you can
- start the server immediately. Another binary distribution
- format contains an archive that you simply unpack in the
- installation location and then configure yourself. For
- details, see Section 2.3.1, "Choosing An Installation
- Package."
-
- * The source distribution contains all the code and support
- files for building the executables using the Visual Studio
- compiler system.
-
- Generally speaking, you should use a binary distribution that
- includes an installer. It is simpler to use than the others, and
- you need no additional tools to get MySQL up and running. The
- installer for the Windows version of MySQL, combined with a GUI
- Configuration Wizard, automatically installs MySQL, creates an
- option file, starts the server, and secures the default user
- accounts.
-
-Caution
-
- Using virus scanning software such as Norton/Symantec Anti-Virus
- on directories containing MySQL data and temporary tables can
- cause issues, both in terms of the performance of MySQL and the
- virus-scanning software mis-identifying the contents of the files
- as containing spam. This is because of the fingerprinting
- mechanism used by the virus scanning software, and the way in
- which MySQL rapidly updates different files, which may be
- identified as a potential security risk.
-
- After installing MySQL Server, it is recommended that you disable
- virus scanning on the main directory (datadir) being used to store
- your MySQL table data. There is usually a system built into the
- virus scanning software to allow certain directories to be
- specifically ignored during virus scanning.
-
- In addition, by default, MySQL creates temporary files in the
- standard Windows temporary directory. To prevent the temporary
- files also being scanned, you should configure a separate
- temporary directory for MySQL temporary files and add this to the
- virus scanning exclusion list. To do this, add a configuration
- option for the tmpdir parameter to your my.ini configuration file.
- For more information, see Section 2.3.7, "Creating an Option
- File."
-
- The following section describes how to install MySQL on Windows
- using a binary distribution. To use an installation package that
- does not include an installer, follow the procedure described in
- Section 2.3.5, "Installing MySQL from a Noinstall Zip Archive." To
- install using a source distribution, see Section 2.10.6,
- "Installing MySQL from Source on Windows."
-
- MySQL distributions for Windows can be downloaded from
- http://dev.mysql.com/downloads/. See Section 2.1.3, "How to Get
- MySQL."
-
-2.3.1. Choosing An Installation Package
-
- For MySQL 5.1, there are three installation packages to choose
- from when installing MySQL on Windows:
-
- * The Essentials Package: This package has a file name similar
- to mysql-essential-5.1.39-win32.msi and contains the minimum
- set of files needed to install MySQL on Windows, including the
- Configuration Wizard. This package does not include optional
- components such as the embedded server and benchmark suite.
-
- * The Complete Package: This package has a file name similar to
- mysql-5.1.39-win32.zip and contains all files needed for a
- complete Windows installation, including the Configuration
- Wizard. This package includes optional components such as the
- embedded server and benchmark suite.
-
- * The Noinstall Archive: This package has a file name similar to
- mysql-noinstall-5.1.39-win32.zip and contains all the files
- found in the Complete install package, with the exception of
- the Configuration Wizard. This package does not include an
- automated installer, and must be manually installed and
- configured.
-
- The Essentials package is recommended for most users. It is
- provided as an .msi file for use with the Windows Installer. The
- Complete and Noinstall distributions are packaged as Zip archives.
- To use them, you must have a tool that can unpack .zip files.
-
- Your choice of install package affects the installation process
- you must follow. If you choose to install either the Essentials or
- Complete install packages, see Section 2.3.2, "Installing MySQL
- with the Automated Installer." If you choose to install MySQL from
- the Noinstall archive, see Section 2.3.5, "Installing MySQL from a
- Noinstall Zip Archive."
-
-2.3.2. Installing MySQL with the Automated Installer
-
- New MySQL users can use the MySQL Installation Wizard and MySQL
- Configuration Wizard to install MySQL on Windows. These are
- designed to install and configure MySQL in such a way that new
- users can immediately get started using MySQL.
-
- The MySQL Installation Wizard and MySQL Configuration Wizard are
- available in the Essentials and Complete install packages. They
- are recommended for most standard MySQL installations. Exceptions
- include users who need to install multiple instances of MySQL on a
- single server host and advanced users who want complete control of
- server configuration.
-
-2.3.3. Using the MySQL Installation Wizard
-
- MySQL Installation Wizard is an installer for the MySQL server
- that uses the latest installer technologies for Microsoft Windows.
- The MySQL Installation Wizard, in combination with the MySQL
- Configuration Wizard, allows a user to install and configure a
- MySQL server that is ready for use immediately after installation.
-
- The MySQL Installation Wizard is the standard installer for all
- MySQL server distributions, version 4.1.5 and higher. Users of
- previous versions of MySQL need to shut down and remove their
- existing MySQL installations manually before installing MySQL with
- the MySQL Installation Wizard. See Section 2.3.3.6, "Upgrading
- MySQL with the Installation Wizard," for more information on
- upgrading from a previous version.
-
- Microsoft has included an improved version of their Microsoft
- Windows Installer (MSI) in the recent versions of Windows. MSI has
- become the de-facto standard for application installations on
- Windows 2000, Windows XP, and Windows Server 2003. The MySQL
- Installation Wizard makes use of this technology to provide a
- smoother and more flexible installation process.
-
- The Microsoft Windows Installer Engine was updated with the
- release of Windows XP; those using a previous version of Windows
- can reference this Microsoft Knowledge Base article
- (http://support.microsoft.com/default.aspx?scid=kb;EN-US;292539)
- for information on upgrading to the latest version of the Windows
- Installer Engine.
-
- In addition, Microsoft has introduced the WiX (Windows Installer
- XML) toolkit recently. This is the first highly acknowledged Open
- Source project from Microsoft. We have switched to WiX because it
- is an Open Source project and it allows us to handle the complete
- Windows installation process in a flexible manner using scripts.
-
- Improving the MySQL Installation Wizard depends on the support and
- feedback of users like you. If you find that the MySQL
- Installation Wizard is lacking some feature important to you, or
- if you discover a bug, please report it in our bugs database using
- the instructions given in Section 1.6, "How to Report Bugs or
- Problems."
-
-2.3.3.1. Downloading and Starting the MySQL Installation Wizard
-
- The MySQL installation packages can be downloaded from
- http://dev.mysql.com/downloads/. If the package you download is
- contained within a Zip archive, you need to extract the archive
- first.
-
-Note
-
- If you are installing on Windows Vista it is best to open a
- network port before beginning the installation. To do this, first
- ensure that you are logged in as an Administrator, go to the
- Control Panel, and double click the Windows Firewall icon. Choose
- the Allow a program through Windows Firewall option and click the
- Add port button. Enter MySQL into the Name text box and 3306 (or
- the port of your choice) into the Port number text box. Also
- ensure that the TCP protocol radio button is selected. If you
- wish, you can also limit access to the MySQL server by choosing
- the Change scope button. Confirm your choices by clicking the OK
- button. If you do not open a port prior to installation, you
- cannot configure the MySQL server immediately after installation.
- Additionally, when running the MySQL Installation Wizard on
- Windows Vista, ensure that you are logged in as a user with
- administrative rights.
-
- The process for starting the wizard depends on the contents of the
- installation package you download. If there is a setup.exe file
- present, double-click it to start the installation process. If
- there is an .msi file present, double-click it to start the
- installation process.
-
-2.3.3.2. Choosing an Install Type
-
- There are three installation types available: Typical, Complete,
- and Custom.
-
- The Typical installation type installs the MySQL server, the mysql
- command-line client, and the command-line utilities. The
- command-line clients and utilities include mysqldump, myisamchk,
- and several other tools to help you manage the MySQL server.
-
- The Complete installation type installs all components included in
- the installation package. The full installation package includes
- components such as the embedded server library, the benchmark
- suite, support scripts, and documentation.
-
- The Custom installation type gives you complete control over which
- packages you wish to install and the installation path that is
- used. See Section 2.3.3.3, "The Custom Install Dialog," for more
- information on performing a custom install.
-
- If you choose the Typical or Complete installation types and click
- the Next button, you advance to the confirmation screen to verify
- your choices and begin the installation. If you choose the Custom
- installation type and click the Next button, you advance to the
- custom installation dialog, described in Section 2.3.3.3, "The
- Custom Install Dialog."
-
-2.3.3.3. The Custom Install Dialog
-
- If you wish to change the installation path or the specific
- components that are installed by the MySQL Installation Wizard,
- choose the Custom installation type.
-
- A tree view on the left side of the custom install dialog lists
- all available components. Components that are not installed have a
- red X icon; components that are installed have a gray icon. To
- change whether a component is installed, click on that component's
- icon and choose a new option from the drop-down list that appears.
-
- You can change the default installation path by clicking the
- Change... button to the right of the displayed installation path.
-
- After choosing your installation components and installation path,
- click the Next button to advance to the confirmation dialog.
-
-2.3.3.4. The Confirmation Dialog
-
- Once you choose an installation type and optionally choose your
- installation components, you advance to the confirmation dialog.
- Your installation type and installation path are displayed for you
- to review.
-
- To install MySQL if you are satisfied with your settings, click
- the Install button. To change your settings, click the Back
- button. To exit the MySQL Installation Wizard without installing
- MySQL, click the Cancel button.
-
- After installation is complete, you have the option of registering
- with the MySQL web site. Registration gives you access to post in
- the MySQL forums at forums.mysql.com (http://forums.mysql.com),
- along with the ability to report bugs at bugs.mysql.com
- (http://bugs.mysql.com) and to subscribe to our newsletter. The
- final screen of the installer provides a summary of the
- installation and gives you the option to launch the MySQL
- Configuration Wizard, which you can use to create a configuration
- file, install the MySQL service, and configure security settings.
-
-2.3.3.5. Changes Made by MySQL Installation Wizard
-
- Once you click the Install button, the MySQL Installation Wizard
- begins the installation process and makes certain changes to your
- system which are described in the sections that follow.
-
- Changes to the Registry
-
- The MySQL Installation Wizard creates one Windows registry key in
- a typical install situation, located in
- HKEY_LOCAL_MACHINE\SOFTWARE\MySQL AB.
-
- The MySQL Installation Wizard creates a key named after the major
- version of the server that is being installed, such as MySQL
- Server 5.1. It contains two string values, Location and Version.
- The Location string contains the path to the installation
- directory. In a default installation it contains C:\Program
- Files\MySQL\MySQL Server 5.1\. The Version string contains the
- release number. For example, for an installation of MySQL Server
- 5.1.39, the key contains a value of 5.1.39.
-
- These registry keys are used to help external tools identify the
- installed location of the MySQL server, preventing a complete scan
- of the hard-disk to determine the installation path of the MySQL
- server. The registry keys are not required to run the server, and
- if you install MySQL using the noinstall Zip archive, the registry
- keys are not created.
-
- Changes to the Start Menu
-
- The MySQL Installation Wizard creates a new entry in the Windows
- Start menu under a common MySQL menu heading named after the major
- version of MySQL that you have installed. For example, if you
- install MySQL 5.1, the MySQL Installation Wizard creates a MySQL
- Server 5.1 section in the Start menu.
-
- The following entries are created within the new Start menu
- section:
-
- * MySQL Command Line Client: This is a shortcut to the mysql
- command-line client and is configured to connect as the root
- user. The shortcut prompts for a root user password when you
- connect.
-
- * MySQL Server Instance Config Wizard: This is a shortcut to the
- MySQL Configuration Wizard. Use this shortcut to configure a
- newly installed server, or to reconfigure an existing server.
-
- * MySQL Documentation: This is a link to the MySQL server
- documentation that is stored locally in the MySQL server
- installation directory. This option is not available when the
- MySQL server is installed using the Essentials installation
- package.
-
- Changes to the File System
-
- The MySQL Installation Wizard by default installs the MySQL 5.1
- server to C:\Program Files\MySQL\MySQL Server 5.1, where Program
- Files is the default location for applications in your system, and
- 5.1 is the major version of your MySQL server. This is the
- recommended location for the MySQL server, replacing the former
- default location C:\mysql.
-
- By default, all MySQL applications are stored in a common
- directory at C:\Program Files\MySQL, where Program Files is the
- default location for applications in your Windows installation. A
- typical MySQL installation on a developer machine might look like
- this:
-C:\Program Files\MySQL\MySQL Server 5.1
-C:\Program Files\MySQL\MySQL Workbench 5.1 OSS
-
- This approach makes it easier to manage and maintain all MySQL
- applications installed on a particular system.
-
- In MySQL 5.1.23 and earlier, the default location for the data
- files used by MySQL is located within the corresponding MySQL
- Server installation directory. For MySQL 5.1.24 and later, the
- default location of the data directory is the AppData directory
- configured for the user that installed the MySQL application.
-
-2.3.3.6. Upgrading MySQL with the Installation Wizard
-
- The MySQL Installation Wizard can perform server upgrades
- automatically using the upgrade capabilities of MSI. That means
- you do not need to remove a previous installation manually before
- installing a new release. The installer automatically shuts down
- and removes the previous MySQL service before installing the new
- version.
-
- Automatic upgrades are available only when upgrading between
- installations that have the same major and minor version numbers.
- For example, you can upgrade automatically from MySQL 4.1.5 to
- MySQL 4.1.6, but not from MySQL 5.0 to MySQL 5.1.
-
- See Section 2.3.14, "Upgrading MySQL on Windows."
-
-2.3.4. MySQL Server Instance Configuration Wizard
-
- The MySQL Server Instance Configuration Wizard helps automate the
- process of configuring your server. It creates a custom MySQL
- configuration file (my.ini or my.cnf) by asking you a series of
- questions and then applying your responses to a template to
- generate the configuration file that is tuned to your
- installation.
-
- The MySQL Server Instance Configuration Wizard is included with
- the MySQL 5.1 server. The MySQL Server Instance Configuration
- Wizard is only available for Windows.
-
-2.3.4.1. Starting the MySQL Server Instance Configuration Wizard
-
- The MySQL Server Instance Configuration Wizard is normally started
- as part of the installation process. You should only need to run
- the MySQL Server Instance Configuration Wizard again when you need
- to change the configuration parameters of your server.
-
- If you chose not to open a port prior to installing MySQL on
- Windows Vista, you can choose to use the MySQL Server
- Configuration Wizard after installation. However, you must open a
- port in the Windows Firewall. To do this see the instructions
- given in Section 2.3.3.1, "Downloading and Starting the MySQL
- Installation Wizard." Rather than opening a port, you also have
- the option of adding MySQL as a program that bypasses the Windows
- Firewall. One or the other option is sufficient --- you need not
- do both. Additionally, when running the MySQL Server Configuration
- Wizard on Windows Vista ensure that you are logged in as a user
- with administrative rights.
- MySQL Server Instance Configuration Wizard
-
- You can launch the MySQL Configuration Wizard by clicking the
- MySQL Server Instance Config Wizard entry in the MySQL section of
- the Windows Start menu.
-
- Alternatively, you can navigate to the bin directory of your MySQL
- installation and launch the MySQLInstanceConfig.exe file directly.
-
- The MySQL Server Instance Configuration Wizard places the my.ini
- file in the installation directory for the MySQL server. This
- helps associate configuration files with particular server
- instances.
-
- To ensure that the MySQL server knows where to look for the my.ini
- file, an argument similar to this is passed to the MySQL server as
- part of the service installation:
---defaults-file="C:\Program Files\MySQL\MySQL Server 5.1\my.ini"
-
- Here, C:\Program Files\MySQL\MySQL Server 5.1 is replaced with the
- installation path to the MySQL Server. The --defaults-file option
- instructs the MySQL server to read the specified file for
- configuration options when it starts.
-
- Apart from making changes to the my.ini file by running the MySQL
- Server Instance Configuration Wizard again, you can modify it by
- opening it with a text editor and making any necessary changes.
- You can also modify the server configuration with the MySQL
- Administrator (http://www.mysql.com/products/administrator/)
- utility. For more information about server configuration, see
- Section 5.1.2, "Server Command Options."
-
- MySQL clients and utilities such as the mysql and mysqldump
- command-line clients are not able to locate the my.ini file
- located in the server installation directory. To configure the
- client and utility applications, create a new my.ini file in the
- Windows installation directory (for example, C:\WINDOWS).
-
- Under Windows Server 2003, Windows Server 2000, Windows XP, and
- Windows Vista MySQL Server Instance Configuration Wizard will
- configure MySQL to work as a Windows service. To start and stop
- MySQL you use the Services application that is supplied as part of
- the Windows Administrator Tools.
-
-2.3.4.2. Choosing a Maintenance Option
-
- If the MySQL Server Instance Configuration Wizard detects an
- existing configuration file, you have the option of either
- reconfiguring your existing server, or removing the server
- instance by deleting the configuration file and stopping and
- removing the MySQL service.
-
- To reconfigure an existing server, choose the Re-configure
- Instance option and click the Next button. Any existing
- configuration file is not overwritten, but renamed (within the
- same directory) using a timestamp (Windows) or sequential number
- (Linux). To remove the existing server instance, choose the Remove
- Instance option and click the Next button.
-
- If you choose the Remove Instance option, you advance to a
- confirmation window. Click the Execute button. The MySQL Server
- Configuration Wizard stops and removes the MySQL service, and then
- deletes the configuration file. The server installation and its
- data folder are not removed.
-
- If you choose the Re-configure Instance option, you advance to the
- Configuration Type dialog where you can choose the type of
- installation that you wish to configure.
-
-2.3.4.3. Choosing a Configuration Type
-
- When you start the MySQL Server Instance Configuration Wizard for
- a new MySQL installation, or choose the Re-configure Instance
- option for an existing installation, you advance to the
- Configuration Type dialog.
- MySQL Server Instance Configuration Wizard: Configuration Type
-
- There are two configuration types available: Detailed
- Configuration and Standard Configuration. The Standard
- Configuration option is intended for new users who want to get
- started with MySQL quickly without having to make many decisions
- about server configuration. The Detailed Configuration option is
- intended for advanced users who want more fine-grained control
- over server configuration.
-
- If you are new to MySQL and need a server configured as a
- single-user developer machine, the Standard Configuration should
- suit your needs. Choosing the Standard Configuration option causes
- the MySQL Configuration Wizard to set all configuration options
- automatically with the exception of Service Options and Security
- Options.
-
- The Standard Configuration sets options that may be incompatible
- with systems where there are existing MySQL installations. If you
- have an existing MySQL installation on your system in addition to
- the installation you wish to configure, the Detailed Configuration
- option is recommended.
-
- To complete the Standard Configuration, please refer to the
- sections on Service Options and Security Options in Section
- 2.3.4.10, "The Service Options Dialog," and Section 2.3.4.11, "The
- Security Options Dialog," respectively.
-
-2.3.4.4. The Server Type Dialog
-
- There are three different server types available to choose from.
- The server type that you choose affects the decisions that the
- MySQL Server Instance Configuration Wizard makes with regard to
- memory, disk, and processor usage.
- MySQL Server Instance Configuration Wizard: Server Type
-
- * Developer Machine: Choose this option for a typical desktop
- workstation where MySQL is intended only for personal use. It
- is assumed that many other desktop applications are running.
- The MySQL server is configured to use minimal system
- resources.
-
- * Server Machine: Choose this option for a server machine where
- the MySQL server is running alongside other server
- applications such as FTP, email, and Web servers. The MySQL
- server is configured to use a moderate portion of the system
- resources.
-
- * Dedicated MySQL Server Machine: Choose this option for a
- server machine that is intended to run only the MySQL server.
- It is assumed that no other applications are running. The
- MySQL server is configured to use all available system
- resources.
-
-Note
-
- By selecting one of the preconfigured configurations, the values
- and settings of various options in your my.cnf or my.ini will be
- altered accordingly. The default values and options as described
- in the reference manual may therefore be different to the options
- and values that were created during the execution of the
- configuration wizard.
-
-2.3.4.5. The Database Usage Dialog
-
- The Database Usage dialog allows you to indicate the storage
- engines that you expect to use when creating MySQL tables. The
- option you choose determines whether the InnoDB storage engine is
- available and what percentage of the server resources are
- available to InnoDB.
- MySQL Server Instance Configuration Wizard: Usage Dialog
-
- * Multifunctional Database: This option enables both the InnoDB
- and MyISAM storage engines and divides resources evenly
- between the two. This option is recommended for users who use
- both storage engines on a regular basis.
-
- * Transactional Database Only: This option enables both the
- InnoDB and MyISAM storage engines, but dedicates most server
- resources to the InnoDB storage engine. This option is
- recommended for users who use InnoDB almost exclusively and
- make only minimal use of MyISAM.
-
- * Non-Transactional Database Only: This option disables the
- InnoDB storage engine completely and dedicates all server
- resources to the MyISAM storage engine. This option is
- recommended for users who do not use InnoDB.
-
- The Configuration Wizard uses a template to generate the server
- configuration file. The Database Usage dialog sets one of the
- following option strings:
-Multifunctional Database: MIXED
-Transactional Database Only: INNODB
-Non-Transactional Database Only: MYISAM
-
- When these options are processed through the default template
- (my-template.ini) the result is:
-Multifunctional Database:
-default-storage-engine=InnoDB
-_myisam_pct=50
-
-Transactional Database Only:
-default-storage-engine=InnoDB
-_myisam_pct=5
-
-Non-Transactional Database Only:
-default-storage-engine=MyISAM
-_myisam_pct=100
-skip-innodb
-
- The _myisam_pct value is used to calculate the percentage of
- resources dedicated to MyISAM. The remaining resources are
- allocated to InnoDB.
-
-2.3.4.6. The InnoDB Tablespace Dialog
-
- Some users may want to locate the InnoDB tablespace files in a
- different location than the MySQL server data directory. Placing
- the tablespace files in a separate location can be desirable if
- your system has a higher capacity or higher performance storage
- device available, such as a RAID storage system.
- MySQL Server Instance Configuration Wizard: InnoDB Data Tablespace
-
- To change the default location for the InnoDB tablespace files,
- choose a new drive from the drop-down list of drive letters and
- choose a new path from the drop-down list of paths. To create a
- custom path, click the ... button.
-
- If you are modifying the configuration of an existing server, you
- must click the Modify button before you change the path. In this
- situation you must move the existing tablespace files to the new
- location manually before starting the server.
-
-2.3.4.7. The Concurrent Connections Dialog
-
- To prevent the server from running out of resources, it is
- important to limit the number of concurrent connections to the
- MySQL server that can be established. The Concurrent Connections
- dialog allows you to choose the expected usage of your server, and
- sets the limit for concurrent connections accordingly. It is also
- possible to set the concurrent connection limit manually.
- MySQL Server Instance Configuration Wizard: Connections
-
- * Decision Support (DSS)/OLAP: Choose this option if your server
- does not require a large number of concurrent connections. The
- maximum number of connections is set at 100, with an average
- of 20 concurrent connections assumed.
-
- * Online Transaction Processing (OLTP): Choose this option if
- your server requires a large number of concurrent connections.
- The maximum number of connections is set at 500.
-
- * Manual Setting: Choose this option to set the maximum number
- of concurrent connections to the server manually. Choose the
- number of concurrent connections from the drop-down box
- provided, or enter the maximum number of connections into the
- drop-down box if the number you desire is not listed.
-
-2.3.4.8. The Networking and Strict Mode Options Dialog
-
- Use the Networking Options dialog to enable or disable TCP/IP
- networking and to configure the port number that is used to
- connect to the MySQL server.
- MySQL Server Instance Configuration Wizard: Network Configuration
-
- TCP/IP networking is enabled by default. To disable TCP/IP
- networking, uncheck the box next to the Enable TCP/IP Networking
- option.
-
- Port 3306 is used by default. To change the port used to access
- MySQL, choose a new port number from the drop-down box or type a
- new port number directly into the drop-down box. If the port
- number you choose is in use, you are prompted to confirm your
- choice of port number.
-
- Set the Server SQL Mode to either enable or disable strict mode.
- Enabling strict mode (default) makes MySQL behave more like other
- database management systems. If you run applications that rely on
- MySQL's old "forgiving" behavior, make sure to either adapt those
- applications or to disable strict mode. For more information about
- strict mode, see Section 5.1.8, "Server SQL Modes."
-
-2.3.4.9. The Character Set Dialog
-
- The MySQL server supports multiple character sets and it is
- possible to set a default server character set that is applied to
- all tables, columns, and databases unless overridden. Use the
- Character Set dialog to change the default character set of the
- MySQL server.
- MySQL Server Instance Configuration Wizard: Character Set
-
- * Standard Character Set: Choose this option if you want to use
- latin1 as the default server character set. latin1 is used for
- English and many Western European languages.
-
- * Best Support For Multilingualism: Choose this option if you
- want to use utf8 as the default server character set. This is
- a Unicode character set that can store characters from many
- different languages.
-
- * Manual Selected Default Character Set / Collation: Choose this
- option if you want to pick the server's default character set
- manually. Choose the desired character set from the provided
- drop-down list.
-
-2.3.4.10. The Service Options Dialog
-
- On Windows platforms, the MySQL server can be installed as a
- Windows service. When installed this way, the MySQL server can be
- started automatically during system startup, and even restarted
- automatically by Windows in the event of a service failure.
-
- The MySQL Server Instance Configuration Wizard installs the MySQL
- server as a service by default, using the service name MySQL. If
- you do not wish to install the service, uncheck the box next to
- the Install As Windows Service option. You can change the service
- name by picking a new service name from the drop-down box provided
- or by entering a new service name into the drop-down box.
-
-Note
-
- Service names can include any legal character except forward (/)
- or backward (\) slashes, and must be less than 256 characters
- long.
-
-Warning
-
- If you are installing multiple versions of MySQL onto the same
- machine, you must choose a different service name for each version
- that you install. If you do not choose a different service for
- each installed version then the service manager information will
- be inconsistent and this will cause problems when you try to
- uninstall a previous version.
-
- If you have already installed multiple versions using the same
- service name, you must manually edit the contents of the
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services parameters
- within the Windows registry to update the association of the
- service name with the correct server version.
-
- Typically, when installing multiple versions you create a service
- name based on the version information. For example, you might
- install MySQL 5.x as mysql5, or specific versions such as MySQL
- 5.1.30 as mysql50130.
-
- To install the MySQL server as a service but not have it started
- automatically at startup, uncheck the box next to the Launch the
- MySQL Server Automatically option.
-
-2.3.4.11. The Security Options Dialog
-
- It is strongly recommended that you set a root password for your
- MySQL server, and the MySQL Server Instance Configuration Wizard
- requires by default that you do so. If you do not wish to set a
- root password, uncheck the box next to the Modify Security
- Settings option.
- MySQL Server Instance Configuration Wizard: Security
-
- To set the root password, enter the desired password into both the
- New root password and Confirm boxes. If you are reconfiguring an
- existing server, you need to enter the existing root password into
- the Current root password box.
-
- To prevent root logins from across the network, check the box next
- to the Root may only connect from localhost option. This increases
- the security of your root account.
-
- To create an anonymous user account, check the box next to the
- Create An Anonymous Account option. Creating an anonymous account
- can decrease server security and cause login and permission
- difficulties. For this reason, it is not recommended.
-
-2.3.4.12. The Confirmation Dialog
-
- The final dialog in the MySQL Server Instance Configuration Wizard
- is the Confirmation Dialog. To start the configuration process,
- click the Execute button. To return to a previous dialog, click
- the Back button. To exit the MySQL Server Instance Configuration
- Wizard without configuring the server, click the Cancel button.
- MySQL Server Instance Configuration Wizard: Confirmation
-
- After you click the Execute button, the MySQL Server Instance
- Configuration Wizard performs a series of tasks and displays the
- progress onscreen as the tasks are performed.
-
- The MySQL Server Instance Configuration Wizard first determines
- configuration file options based on your choices using a template
- prepared by MySQL developers and engineers. This template is named
- my-template.ini and is located in your server installation
- directory.
-
- The MySQL Configuration Wizard then writes these options to the
- corresponding configuration file.
-
- If you chose to create a service for the MySQL server, the MySQL
- Server Instance Configuration Wizard creates and starts the
- service. If you are reconfiguring an existing service, the MySQL
- Server Instance Configuration Wizard restarts the service to apply
- your configuration changes.
-
- If you chose to set a root password, the MySQL Configuration
- Wizard connects to the server, sets your new root password, and
- applies any other security settings you may have selected.
-
- After the MySQL Server Instance Configuration Wizard has completed
- its tasks, it displays a summary. Click the Finish button to exit
- the MySQL Server Configuration Wizard.
-
-2.3.5. Installing MySQL from a Noinstall Zip Archive
-
- Users who are installing from the Noinstall package can use the
- instructions in this section to manually install MySQL. The
- process for installing MySQL from a Zip archive is as follows:
-
- 1. Extract the archive to the desired install directory
-
- 2. Create an option file
-
- 3. Choose a MySQL server type
-
- 4. Start the MySQL server
-
- 5. Secure the default user accounts
-
- This process is described in the sections that follow.
-
-2.3.6. Extracting the Install Archive
-
- To install MySQL manually, do the following:
-
- 1. If you are upgrading from a previous version please refer to
- Section 2.3.14, "Upgrading MySQL on Windows," before beginning
- the upgrade process.
-
- 2. Make sure that you are logged in as a user with administrator
- privileges.
-
- 3. Choose an installation location. Traditionally, the MySQL
- server is installed in C:\mysql. The MySQL Installation Wizard
- installs MySQL under C:\Program Files\MySQL. If you do not
- install MySQL at C:\mysql, you must specify the path to the
- install directory during startup or in an option file. See
- Section 2.3.7, "Creating an Option File."
-
- 4. Extract the install archive to the chosen installation
- location using your preferred Zip archive tool. Some tools may
- extract the archive to a folder within your chosen
- installation location. If this occurs, you can move the
- contents of the subfolder into the chosen installation
- location.
-
-2.3.7. Creating an Option File
-
- If you need to specify startup options when you run the server,
- you can indicate them on the command line or place them in an
- option file. For options that are used every time the server
- starts, you may find it most convenient to use an option file to
- specify your MySQL configuration. This is particularly true under
- the following circumstances:
-
- * The installation or data directory locations are different
- from the default locations (C:\Program Files\MySQL\MySQL
- Server 5.1 and C:\Program Files\MySQL\MySQL Server 5.1\data).
-
- * You need to tune the server settings, such as memory, cache,
- or InnoDB configuration information.
-
- When the MySQL server starts on Windows, it looks for options in
- two files: the my.ini file in the Windows directory, and the
- C:\my.cnf file. The Windows directory typically is named something
- like C:\WINDOWS. You can determine its exact location from the
- value of the WINDIR environment variable using the following
- command:
-C:\> echo %WINDIR%
-
- MySQL looks for options first in the my.ini file, and then in the
- my.cnf file. However, to avoid confusion, it is best if you use
- only one file. If your PC uses a boot loader where C: is not the
- boot drive, your only option is to use the my.ini file. Whichever
- option file you use, it must be a plain text file.
-
- You can also make use of the example option files included with
- your MySQL distribution; see Section 4.2.3.3.2, "Preconfigured
- Option Files."
-
- An option file can be created and modified with any text editor,
- such as Notepad. For example, if MySQL is installed in E:\mysql
- and the data directory is in E:\mydata\data, you can create an
- option file containing a [mysqld] section to specify values for
- the basedir and datadir options:
-[mysqld]
-# set basedir to your installation path
-basedir=E:/mysql
-# set datadir to the location of your data directory
-datadir=E:/mydata/data
-
- Note that Windows path names are specified in option files using
- (forward) slashes rather than backslashes. If you do use
- backslashes, you must double them:
-[mysqld]
-# set basedir to your installation path
-basedir=E:\\mysql
-# set datadir to the location of your data directory
-datadir=E:\\mydata\\data
-
- MySQL Enterprise For expert advice on the start-up options
- appropriate to your circumstances, subscribe to the MySQL
- Enterprise Monitor. For more information, see
- http://www.mysql.com/products/enterprise/advisors.html.
-
- In MySQL 5.1.23 and earlier, the MySQL installer places the data
- directory directly under the directory where you install MySQL. On
- MySQL 5.1.24 and later, the data directory is located within the
- AppData directory for the user running MySQL.
-
- If you would like to use a data directory in a different location,
- you should copy the entire contents of the data directory to the
- new location. For example, if you want to use E:\mydata as the
- data directory instead, you must do two things:
-
- 1. Move the entire data directory and all of its contents from
- the default location (for example C:\Program Files\MySQL\MySQL
- Server 5.1\data) to E:\mydata.
-
- 2. Use a --datadir option to specify the new data directory
- location each time you start the server.
-
-2.3.8. Selecting a MySQL Server Type
-
- The following table shows the available servers for Windows in
- MySQL 5.1.20 and earlier.
- Binary Description
- mysqld-nt Optimized binary with named-pipe support
- mysqld Optimized binary without named-pipe support
- mysqld-debug Like mysqld-nt, but compiled with full debugging and
- automatic memory allocation checking
-
- The following table shows the available servers for Windows in
- MySQL 5.1.21 and later.
- Binary Description
- mysqld Optimized binary with named-pipe support
- mysqld-debug Like mysqld, but compiled with full debugging and
- automatic memory allocation checking
-
- All of the preceding binaries are optimized for modern Intel
- processors, but should work on any Intel i386-class or higher
- processor.
-
- Each of the servers in a distribution support the same set of
- storage engines. The SHOW ENGINES statement displays which engines
- a given server supports.
-
- All Windows MySQL 5.1 servers have support for symbolic linking of
- database directories.
-
- MySQL supports TCP/IP on all Windows platforms. MySQL servers on
- Windows support named pipes as indicated in the following list.
- However, the default is to use TCP/IP regardless of platform.
- (Named pipes are slower than TCP/IP in many Windows
- configurations.)
-
- Use of named pipes is subject to these conditions:
-
- * Named pipes are enabled only if you start the server with the
- --enable-named-pipe option. It is necessary to use this option
- explicitly because some users have experienced problems with
- shutting down the MySQL server when named pipes were used.
-
- * For MySQL 5.1.20 and earlier, named-pipe connections are
- allowed only by the mysqld-nt and mysqld-debug servers. For
- MySQL 5.1.21 and later, the mysqld and mysqld-debug servers
- both contain support for named-pipe connections.
-
-Note
-
- Most of the examples in this manual use mysqld as the server name.
- If you choose to use a different server, such as mysqld-nt or
- mysqld-debug, make the appropriate substitutions in the commands
- that are shown in the examples.
-
-2.3.9. Starting the Server for the First Time
-
- This section gives a general overview of starting the MySQL
- server. The following sections provide more specific information
- for starting the MySQL server from the command line or as a
- Windows service.
-
- The information here applies primarily if you installed MySQL
- using the Noinstall version, or if you wish to configure and test
- MySQL manually rather than with the GUI tools.
-
- The examples in these sections assume that MySQL is installed
- under the default location of C:\Program Files\MySQL\MySQL Server
- 5.1. Adjust the path names shown in the examples if you have MySQL
- installed in a different location.
-
- Clients have two options. They can use TCP/IP, or they can use a
- named pipe if the server supports named-pipe connections.
-
- MySQL for Windows also supports shared-memory connections if the
- server is started with the --shared-memory option. Clients can
- connect through shared memory by using the --protocol=MEMORY
- option.
-
- For information about which server binary to run, see Section
- 2.3.8, "Selecting a MySQL Server Type."
-
- Testing is best done from a command prompt in a console window (or
- "DOS window"). In this way you can have the server display status
- messages in the window where they are easy to see. If something is
- wrong with your configuration, these messages make it easier for
- you to identify and fix any problems.
-
- To start the server, enter this command:
-C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld" --console
-
- For a server that includes InnoDB support, you should see the
- messages similar to those following as it starts (the path names
- and sizes may differ):
-InnoDB: The first specified datafile c:\ibdata\ibdata1 did not exist:
-InnoDB: a new database to be created!
-InnoDB: Setting file c:\ibdata\ibdata1 size to 209715200
-InnoDB: Database physically writes the file full: wait...
-InnoDB: Log file c:\iblogs\ib_logfile0 did not exist: new to be creat
-ed
-InnoDB: Setting log file c:\iblogs\ib_logfile0 size to 31457280
-InnoDB: Log file c:\iblogs\ib_logfile1 did not exist: new to be creat
-ed
-InnoDB: Setting log file c:\iblogs\ib_logfile1 size to 31457280
-InnoDB: Log file c:\iblogs\ib_logfile2 did not exist: new to be creat
-ed
-InnoDB: Setting log file c:\iblogs\ib_logfile2 size to 31457280
-InnoDB: Doublewrite buffer not found: creating new
-InnoDB: Doublewrite buffer created
-InnoDB: creating foreign key constraint system tables
-InnoDB: foreign key constraint system tables created
-011024 10:58:25 InnoDB: Started
-
- When the server finishes its startup sequence, you should see
- something like this, which indicates that the server is ready to
- service client connections:
-mysqld: ready for connections
-Version: '5.1.39' socket: '' port: 3306
-
- The server continues to write to the console any further
- diagnostic output it produces. You can open a new console window
- in which to run client programs.
-
- If you omit the --console option, the server writes diagnostic
- output to the error log in the data directory (C:\Program
- Files\MySQL\MySQL Server 5.1\data by default). The error log is
- the file with the .err extension.
-
-Note
-
- The accounts that are listed in the MySQL grant tables initially
- have no passwords. After starting the server, you should set up
- passwords for them using the instructions in Section 2.11,
- "Post-Installation Setup and Testing."
-
-2.3.10. Starting MySQL from the Windows Command Line
-
- The MySQL server can be started manually from the command line.
- This can be done on any version of Windows.
-
- To start the mysqld server from the command line, you should start
- a console window (or "DOS window") and enter this command:
-C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld"
-
- The path to mysqld may vary depending on the install location of
- MySQL on your system.
-
- You can stop the MySQL server by executing this command:
-C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqladmin" -u root
- shutdown
-
-Note
-
- If the MySQL root user account has a password, you need to invoke
- mysqladmin with the -p option and supply the password when
- prompted.
-
- This command invokes the MySQL administrative utility mysqladmin
- to connect to the server and tell it to shut down. The command
- connects as the MySQL root user, which is the default
- administrative account in the MySQL grant system. Note that users
- in the MySQL grant system are wholly independent from any login
- users under Windows.
-
- If mysqld doesn't start, check the error log to see whether the
- server wrote any messages there to indicate the cause of the
- problem. The error log is located in the C:\Program
- Files\MySQL\MySQL Server 5.1\data directory. It is the file with a
- suffix of .err. You can also try to start the server as mysqld
- --console; in this case, you may get some useful information on
- the screen that may help solve the problem.
-
- The last option is to start mysqld with the --standalone and
- --debug options. In this case, mysqld writes a log file
- C:\mysqld.trace that should contain the reason why mysqld doesn't
- start. See MySQL Internals: Porting
- (http://forge.mysql.com/wiki/MySQL_Internals_Porting).
-
- Use mysqld --verbose --help to display all the options that mysqld
- supports.
-
-2.3.11. Starting MySQL as a Windows Service
-
- On Windows, the recommended way to run MySQL is to install it as a
- Windows service, whereby MySQL starts and stops automatically when
- Windows starts and stops. A MySQL server installed as a service
- can also be controlled from the command line using NET commands,
- or with the graphical Services utility. Generally, to install
- MySQL as a Windows service you should be logged in using an
- account that has administrator rights.
-
- The Services utility (the Windows Service Control Manager) can be
- found in the Windows Control Panel (under Administrative Tools on
- Windows 2000, XP, Vista and Server 2003). To avoid conflicts, it
- is advisable to close the Services utility while performing server
- installation or removal operations from the command line.
-
- Before installing MySQL as a Windows service, you should first
- stop the current server if it is running by using the following
- command:
-C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqladmin"
- -u root shutdown
-
-Note
-
- If the MySQL root user account has a password, you need to invoke
- mysqladmin with the -p option and supply the password when
- prompted.
-
- This command invokes the MySQL administrative utility mysqladmin
- to connect to the server and tell it to shut down. The command
- connects as the MySQL root user, which is the default
- administrative account in the MySQL grant system. Note that users
- in the MySQL grant system are wholly independent from any login
- users under Windows.
-
- Install the server as a service using this command:
-C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld" --install
-
- The service-installation command does not start the server.
- Instructions for that are given later in this section.
-
- To make it easier to invoke MySQL programs, you can add the path
- name of the MySQL bin directory to your Windows system PATH
- environment variable:
-
- * On the Windows desktop, right-click on the My Computer icon,
- and select Properties.
-
- * Next select the Advanced tab from the System Properties menu
- that appears, and click the Environment Variables button.
-
- * Under System Variables, select Path, and then click the Edit
- button. The Edit System Variable dialogue should appear.
-
- * Place your cursor at the end of the text appearing in the
- space marked Variable Value. (Use the End key to ensure that
- your cursor is positioned at the very end of the text in this
- space.) Then enter the complete path name of your MySQL bin
- directory (for example, C:\Program Files\MySQL\MySQL Server
- 5.1\bin), Note that there should be a semicolon separating
- this path from any values present in this field. Dismiss this
- dialogue, and each dialogue in turn, by clicking OK until all
- of the dialogues that were opened have been dismissed. You
- should now be able to invoke any MySQL executable program by
- typing its name at the DOS prompt from any directory on the
- system, without having to supply the path. This includes the
- servers, the mysql client, and all MySQL command-line
- utilities such as mysqladmin and mysqldump.
- You should not add the MySQL bin directory to your Windows
- PATH if you are running multiple MySQL servers on the same
- machine.
-
-Warning
-
- You must exercise great care when editing your system PATH by
- hand; accidental deletion or modification of any portion of the
- existing PATH value can leave you with a malfunctioning or even
- unusable system.
-
- The following additional arguments can be used in MySQL 5.1 when
- installing the service:
-
- * You can specify a service name immediately following the
- --install option. The default service name is MySQL.
-
- * If a service name is given, it can be followed by a single
- option. By convention, this should be
- --defaults-file=file_name to specify the name of an option
- file from which the server should read options when it starts.
- The use of a single option other than --defaults-file is
- possible but discouraged. --defaults-file is more flexible
- because it enables you to specify multiple startup options for
- the server by placing them in the named option file.
-
- * You can also specify a --local-service option following the
- service name. This causes the server to run using the
- LocalService Windows account that has limited system
- privileges. This account is available only for Windows XP or
- newer. If both --defaults-file and --local-service are given
- following the service name, they can be in any order.
-
- For a MySQL server that is installed as a Windows service, the
- following rules determine the service name and option files that
- the server uses:
-
- * If the service-installation command specifies no service name
- or the default service name (MySQL) following the --install
- option, the server uses the a service name of MySQL and reads
- options from the [mysqld] group in the standard option files.
-
- * If the service-installation command specifies a service name
- other than MySQL following the --install option, the server
- uses that service name. It reads options from the [mysqld]
- group and the group that has the same name as the service in
- the standard option files. This allows you to use the [mysqld]
- group for options that should be used by all MySQL services,
- and an option group with the service name for use by the
- server installed with that service name.
-
- * If the service-installation command specifies a
- --defaults-file option after the service name, the server
- reads options only from the [mysqld] group of the named file
- and ignores the standard option files.
-
- As a more complex example, consider the following command:
-C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld"
- --install MySQL --defaults-file=C:\my-opts.cnf
-
- Here, the default service name (MySQL) is given after the
- --install option. If no --defaults-file option had been given,
- this command would have the effect of causing the server to read
- the [mysqld] group from the standard option files. However,
- because the --defaults-file option is present, the server reads
- options from the [mysqld] option group, and only from the named
- file.
-
- You can also specify options as Start parameters in the Windows
- Services utility before you start the MySQL service.
-
- Once a MySQL server has been installed as a service, Windows
- starts the service automatically whenever Windows starts. The
- service also can be started immediately from the Services utility,
- or by using a NET START MySQL command. The NET command is not case
- sensitive.
-
- When run as a service, mysqld has no access to a console window,
- so no messages can be seen there. If mysqld does not start, check
- the error log to see whether the server wrote any messages there
- to indicate the cause of the problem. The error log is located in
- the MySQL data directory (for example, C:\Program
- Files\MySQL\MySQL Server 5.1\data). It is the file with a suffix
- of .err.
-
- When a MySQL server has been installed as a service, and the
- service is running, Windows stops the service automatically when
- Windows shuts down. The server also can be stopped manually by
- using the Services utility, the NET STOP MySQL command, or the
- mysqladmin shutdown command.
-
- You also have the choice of installing the server as a manual
- service if you do not wish for the service to be started
- automatically during the boot process. To do this, use the
- --install-manual option rather than the --install option:
-C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld" --install-m
-anual
-
- To remove a server that is installed as a service, first stop it
- if it is running by executing NET STOP MySQL. Then use the
- --remove option to remove it:
-C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld" --remove
-
- If mysqld is not running as a service, you can start it from the
- command line. For instructions, see Section 2.3.10, "Starting
- MySQL from the Windows Command Line."
-
- Please see Section 2.3.13, "Troubleshooting a MySQL Installation
- Under Windows," if you encounter difficulties during installation.
-
-2.3.12. Testing The MySQL Installation
-
- You can test whether the MySQL server is working by executing any
- of the following commands:
-C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqlshow"
-C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqlshow" -u root
-mysql
-C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqladmin" version
- status proc
-C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysql" test
-
- If mysqld is slow to respond to TCP/IP connections from client
- programs, there is probably a problem with your DNS. In this case,
- start mysqld with the --skip-name-resolve option and use only
- localhost and IP numbers in the Host column of the MySQL grant
- tables.
-
- You can force a MySQL client to use a named-pipe connection rather
- than TCP/IP by specifying the --pipe or --protocol=PIPE option, or
- by specifying . (period) as the host name. Use the --socket option
- to specify the name of the pipe if you do not want to use the
- default pipe name.
-
- Note that if you have set a password for the root account, deleted
- the anonymous account, or created a new user account, then you
- must use the appropriate -u and -p options with the commands shown
- above in order to connect with the MySQL Server. See Section
- 4.2.2, "Connecting to the MySQL Server."
-
- For more information about mysqlshow, see Section 4.5.6,
- "mysqlshow --- Display Database, Table, and Column Information."
-
-2.3.13. Troubleshooting a MySQL Installation Under Windows
-
- When installing and running MySQL for the first time, you may
- encounter certain errors that prevent the MySQL server from
- starting. The purpose of this section is to help you diagnose and
- correct some of these errors.
-
- Your first resource when troubleshooting server issues is the
- error log. The MySQL server uses the error log to record
- information relevant to the error that prevents the server from
- starting. The error log is located in the data directory specified
- in your my.ini file. The default data directory location is
- C:\Program Files\MySQL\MySQL Server 5.1\data. See Section 5.2.2,
- "The Error Log."
-
- Another source of information regarding possible errors is the
- console messages displayed when the MySQL service is starting. Use
- the NET START MySQL command from the command line after installing
- mysqld as a service to see any error messages regarding the
- starting of the MySQL server as a service. See Section 2.3.11,
- "Starting MySQL as a Windows Service."
-
- The following examples show other common error messages you may
- encounter when installing MySQL and starting the server for the
- first time:
-
- * If the MySQL server cannot find the mysql privileges database
- or other critical files, you may see these messages:
-System error 1067 has occurred.
-Fatal error: Can't open privilege tables: Table 'mysql.host' doesn't
-exist
- These messages often occur when the MySQL base or data
- directories are installed in different locations than the
- default locations (C:\Program Files\MySQL\MySQL Server 5.1 and
- C:\Program Files\MySQL\MySQL Server 5.1\data, respectively).
- This situation may occur when MySQL is upgraded and installed
- to a new location, but the configuration file is not updated
- to reflect the new location. In addition, there may be old and
- new configuration files that conflict. Be sure to delete or
- rename any old configuration files when upgrading MySQL.
- If you have installed MySQL to a directory other than
- C:\Program Files\MySQL\MySQL Server 5.1, you need to ensure
- that the MySQL server is aware of this through the use of a
- configuration (my.ini) file. The my.ini file needs to be
- located in your Windows directory, typically C:\WINDOWS. You
- can determine its exact location from the value of the WINDIR
- environment variable by issuing the following command from the
- command prompt:
-C:\> echo %WINDIR%
- An option file can be created and modified with any text
- editor, such as Notepad. For example, if MySQL is installed in
- E:\mysql and the data directory is D:\MySQLdata, you can
- create the option file and set up a [mysqld] section to
- specify values for the basedir and datadir options:
-[mysqld]
-# set basedir to your installation path
-basedir=E:/mysql
-# set datadir to the location of your data directory
-datadir=D:/MySQLdata
- Note that Windows path names are specified in option files
- using (forward) slashes rather than backslashes. If you do use
- backslashes, you must double them:
-[mysqld]
-# set basedir to your installation path
-basedir=C:\\Program Files\\MySQL\\MySQL Server 5.1
-# set datadir to the location of your data directory
-datadir=D:\\MySQLdata
- If you change the datadir value in your MySQL configuration
- file, you must move the contents of the existing MySQL data
- directory before restarting the MySQL server.
- See Section 2.3.7, "Creating an Option File."
-
- * If you reinstall or upgrade MySQL without first stopping and
- removing the existing MySQL service and install MySQL using
- the MySQL Configuration Wizard, you may see this error:
-Error: Cannot create Windows service for MySql. Error: 0
- This occurs when the Configuration Wizard tries to install the
- service and finds an existing service with the same name.
- One solution to this problem is to choose a service name other
- than mysql when using the configuration wizard. This allows
- the new service to be installed correctly, but leaves the
- outdated service in place. Although this is harmless, it is
- best to remove old services that are no longer in use.
- To permanently remove the old mysql service, execute the
- following command as a user with administrative privileges, on
- the command-line:
-C:\> sc delete mysql
-[SC] DeleteService SUCCESS
- If the sc utility is not available for your version of
- Windows, download the delsrv utility from
- http://www.microsoft.com/windows2000/techinfo/reskit/tools/exi
- sting/delsrv-o.asp and use the delsrv mysql syntax.
-
-2.3.14. Upgrading MySQL on Windows
-
- This section lists some of the steps you should take when
- upgrading MySQL on Windows.
-
- 1. Review Section 2.12.1, "Upgrading MySQL," for additional
- information on upgrading MySQL that is not specific to
- Windows.
-
- 2. You should always back up your current MySQL installation
- before performing an upgrade. See Section 6.1, "Database
- Backups."
-
- 3. Download the latest Windows distribution of MySQL from
- http://dev.mysql.com/downloads/.
-
- 4. Before upgrading MySQL, you must stop the server. If the
- server is installed as a service, stop the service with the
- following command from the command prompt:
-C:\> NET STOP MySQL
- If you are not running the MySQL server as a service, use the
- following command to stop it:
-C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqladmin" -u root
- shutdown
-
-Note
- If the MySQL root user account has a password, you need to
- invoke mysqladmin with the -p option and supply the password
- when prompted.
-
- 5. When upgrading to MySQL 5.1 from a version previous to 4.1.5,
- or when upgrading from a version of MySQL installed from a Zip
- archive to a version of MySQL installed with the MySQL
- Installation Wizard, you must manually remove the previous
- installation and MySQL service (if the server is installed as
- a service).
- To remove the MySQL service, use the following command:
-C:\> C:\mysql\bin\mysqld --remove
- If you do not remove the existing service, the MySQL
- Installation Wizard may fail to properly install the new MySQL
- service.
-
- 6. When upgrading from MySQL 5.1.23 to MySQL 5.1.24, the change
- in the default location of the data directory from a directory
- within the MySQL installation to the AppData folder means that
- you must manually copy the data files from your old
- installation to the new location.
-
- 7. If you are using the MySQL Installation Wizard, start the
- wizard as described in Section 2.3.3, "Using the MySQL
- Installation Wizard."
-
- 8. If you are installing MySQL from a Zip archive, extract the
- archive. You may either overwrite your existing MySQL
- installation (usually located at C:\mysql), or install it into
- a different directory, such as C:\mysql5. Overwriting the
- existing installation is recommended.
-
- 9. If you were running MySQL as a Windows service and you had to
- remove the service earlier in this procedure, reinstall the
- service. (See Section 2.3.11, "Starting MySQL as a Windows
- Service.")
- 10. Restart the server. For example, use NET START MySQL if you
- run MySQL as a service, or invoke mysqld directly otherwise.
- 11. If you encounter errors, see Section 2.3.13, "Troubleshooting
- a MySQL Installation Under Windows."
-
-2.3.15. MySQL on Windows Compared to MySQL on Unix
-
- MySQL for Windows has proven itself to be very stable. The Windows
- version of MySQL has the same features as the corresponding Unix
- version, with the following exceptions:
-
- * Limited number of ports
- Windows systems have about 4,000 ports available for client
- connections, and after a connection on a port closes, it takes
- two to four minutes before the port can be reused. In
- situations where clients connect to and disconnect from the
- server at a high rate, it is possible for all available ports
- to be used up before closed ports become available again. If
- this happens, the MySQL server appears to be unresponsive even
- though it is running. Note that ports may be used by other
- applications running on the machine as well, in which case the
- number of ports available to MySQL is lower.
- For more information about this problem, see
- http://support.microsoft.com/default.aspx?scid=kb;en-us;196271
- .
-
- * Concurrent reads
- MySQL depends on the pread() and pwrite() system calls to be
- able to mix INSERT and SELECT. Currently, we use mutexes to
- emulate pread() and pwrite(). We intend to replace the file
- level interface with a virtual interface in the future so that
- we can use the readfile()/writefile() interface to get more
- speed. The current implementation limits the number of open
- files that MySQL 5.1 can use to 2,048, which means that you
- cannot run as many concurrent threads on Windows as on Unix.
-
- * Blocking read
- MySQL uses a blocking read for each connection. That has the
- following implications if named-pipe connections are enabled:
-
- + A connection is not disconnected automatically after
- eight hours, as happens with the Unix version of MySQL.
-
- + If a connection hangs, it is not possible to break it
- without killing MySQL.
-
- + mysqladmin kill does not work on a sleeping connection.
-
- + mysqladmin shutdown cannot abort as long as there are
- sleeping connections.
- We plan to fix this problem in the future.
-
- * ALTER TABLE
- While you are executing an ALTER TABLE statement, the table is
- locked from being used by other threads. This has to do with
- the fact that on Windows, you can't delete a file that is in
- use by another thread. In the future, we may find some way to
- work around this problem.
-
- * DROP TABLE
- DROP TABLE on a table that is in use by a MERGE table does not
- work on Windows because the MERGE handler does the table
- mapping hidden from the upper layer of MySQL. Because Windows
- does not allow dropping files that are open, you first must
- flush all MERGE tables (with FLUSH TABLES) or drop the MERGE
- table before dropping the table.
-
- * DATA DIRECTORY and INDEX DIRECTORY
- The DATA DIRECTORY and INDEX DIRECTORY options for CREATE
- TABLE are ignored on Windows, because Windows doesn't support
- symbolic links. These options also are ignored on systems that
- have a nonfunctional realpath() call.
-
- * DROP DATABASE
- You cannot drop a database that is in use by some thread.
-
- * Case-insensitive names
- File names are not case sensitive on Windows, so MySQL
- database and table names are also not case sensitive on
- Windows. The only restriction is that database and table names
- must be specified using the same case throughout a given
- statement. See Section 8.2.2, "Identifier Case Sensitivity."
-
- * Directory and file names
- On Windows, MySQL Server supports only directory and file
- names that are compatible with the current ANSI code pages.
- For example, the following Japanese directory name will not
- work in the Western locale (code page 1252):
-datadir="C:/维基百科关于中文维基百科"
- The same limitation applies to directory and file names
- referred to in SQL statements, such as the data file path name
- in LOAD DATA INFILE.
-
- * The "\" path name separator character
- Path name components in Windows are separated by the "\"
- character, which is also the escape character in MySQL. If you
- are using LOAD DATA INFILE or SELECT ... INTO OUTFILE, use
- Unix-style file names with "/" characters:
-mysql> LOAD DATA INFILE 'C:/tmp/skr.txt' INTO TABLE skr;
-mysql> SELECT * INTO OUTFILE 'C:/tmp/skr.txt' FROM skr;
- Alternatively, you must double the "\" character:
-mysql> LOAD DATA INFILE 'C:\\tmp\\skr.txt' INTO TABLE skr;
-mysql> SELECT * INTO OUTFILE 'C:\\tmp\\skr.txt' FROM skr;
-
- * Problems with pipes
- Pipes do not work reliably from the Windows command-line
- prompt. If the pipe includes the character ^Z / CHAR(24),
- Windows thinks that it has encountered end-of-file and aborts
- the program.
- This is mainly a problem when you try to apply a binary log as
- follows:
-C:\> mysqlbinlog binary_log_file | mysql --user=root
- If you have a problem applying the log and suspect that it is
- because of a ^Z / CHAR(24) character, you can use the
- following workaround:
-C:\> mysqlbinlog binary_log_file --result-file=/tmp/bin.sql
-C:\> mysql --user=root --execute "source /tmp/bin.sql"
- The latter command also can be used to reliably read in any
- SQL file that may contain binary data.
-
- * Access denied for user error
- If MySQL cannot resolve your host name properly, you may get
- the following error when you attempt to run a MySQL client
- program to connect to a server running on the same machine:
-Access denied for user 'some_user'@'unknown'
-to database 'mysql'
- To fix this problem, you should create a file named
- \windows\hosts containing the following information:
-127.0.0.1 localhost
-
- Here are some open issues for anyone who might want to help us
- improve MySQL on Windows:
-
- * Add macros to use the faster thread-safe increment/decrement
- methods provided by Windows.
-
-2.4. Installing MySQL from RPM Packages on Linux
-
- The recommended way to install MySQL on RPM-based Linux
- distributions is by using the RPM packages. The RPMs that we
- provide to the community should work on all versions of Linux that
- support RPM packages and use glibc 2.3. To obtain RPM packages,
- see Section 2.1.3, "How to Get MySQL."
-
- For non-RPM Linux distributions, you can install MySQL using a
- .tar.gz package. See Section 2.9, "Installing MySQL from tar.gz
- Packages on Other Unix-Like Systems."
-
- We do provide some platform-specific RPMs; the difference between
- a platform-specific RPM and a generic RPM is that a
- platform-specific RPM is built on the targeted platform and is
- linked dynamically whereas a generic RPM is linked statically with
- LinuxThreads.
-
-Note
-
- RPM distributions of MySQL often are provided by other vendors. Be
- aware that they may differ in features and capabilities from those
- built by us, and that the instructions in this manual do not
- necessarily apply to installing them. The vendor's instructions
- should be consulted instead.
-
- If you have problems with an RPM file (for example, if you receive
- the error Sorry, the host 'xxxx' could not be looked up), see
- Section 2.13.1.2, "Linux Binary Distribution Notes."
-
- In most cases, you need to install only the MySQL-server and
- MySQL-client packages to get a functional MySQL installation. The
- other packages are not required for a standard installation.
-
- RPMs for MySQL Cluster. Beginning with MySQL 5.1.24, standard
- MySQL server RPMs built by MySQL no longer provide support for the
- NDBCLUSTER storage engine. MySQL Cluster users wanting to upgrade
- MySQL 5.1.23 or earlier installations from RPMs built by MySQL
- should upgrade to MySQL Cluster NDB 6.2 or MySQL Cluster NDB 6.3;
- RPMs that should work with most Linux distributions are available
- for both of these release series.
-
-Important
-
- When upgrading a MySQL Cluster RPM installation, you must upgrade
- all installed RPMs, including the Server and Client RPMs.
-
- For more information about installing MySQL Cluster from RPMs, see
- Section 17.2.2, "MySQL Cluster Multi-Computer Installation."
-
- For upgrades, if your installation was originally produced by
- installing multiple RPM packages, it is best to upgrade all the
- packages, not just some. For example, if you previously installed
- the server and client RPMs, do not upgrade just the server RPM.
-
- If you get a dependency failure when trying to install MySQL
- packages (for example, error: removing these packages would break
- dependencies: libmysqlclient.so.10 is needed by ...), you should
- also install the MySQL-shared-compat package, which includes both
- the shared libraries for backward compatibility
- (libmysqlclient.so.12 for MySQL 4.0 and libmysqlclient.so.10 for
- MySQL 3.23).
-
- Some Linux distributions still ship with MySQL 3.23 and they
- usually link applications dynamically to save disk space. If these
- shared libraries are in a separate package (for example,
- MySQL-shared), it is sufficient to simply leave this package
- installed and just upgrade the MySQL server and client packages
- (which are statically linked and do not depend on the shared
- libraries). For distributions that include the shared libraries in
- the same package as the MySQL server (for example, Red Hat Linux),
- you could either install our 3.23 MySQL-shared RPM, or use the
- MySQL-shared-compat package instead. (Do not install both.)
-
- The RPM packages shown in the following list are available. The
- names shown here use a suffix of .glibc23.i386.rpm, but particular
- packages can have different suffixes, as described later.
-
- * MySQL-server-VERSION.glibc23.i386.rpm
- The MySQL server. You need this unless you only want to
- connect to a MySQL server running on another machine.
-
- * MySQL-client-VERSION.glibc23.i386.rpm
- The standard MySQL client programs. You probably always want
- to install this package.
-
- * MySQL-devel-VERSION.glibc23.i386.rpm
- The libraries and include files that are needed if you want to
- compile other MySQL clients, such as the Perl modules.
-
- * MySQL-debuginfo-VERSION.glibc23.i386.rpm
- This package contains debugging information. debuginfo RPMs
- are never needed to use MySQL software; this is true both for
- the server and for client programs. However, they contain
- additional information that might be needed by a debugger to
- analyze a crash.
-
- * MySQL-shared-VERSION.glibc23.i386.rpm
- This package contains the shared libraries
- (libmysqlclient.so*) that certain languages and applications
- need to dynamically load and use MySQL. It contains
- single-threaded and thread-safe libraries. If you install this
- package, do not install the MySQL-shared-compat package.
-
- * MySQL-shared-compat-VERSION.glibc23.i386.rpm
- This package includes the shared libraries for MySQL 3.23,
- 4.0, and so on, up to the current release. It contains
- single-threaded and thread-safe libraries. Install this
- package instead of MySQL-shared if you have applications
- installed that are dynamically linked against older versions
- of MySQL but you want to upgrade to the current version
- without breaking the library dependencies.
-
- * MySQL-embedded-VERSION.glibc23.i386.rpm
- The embedded MySQL server library.
-
- * MySQL-ndb-management-VERSION.glibc23.i386.rpm,
- MySQL-ndb-storage-VERSION.glibc23.i386.rpm,
- MySQL-ndb-tools-VERSION.glibc23.i386.rpm,
- MySQL-ndb-extra-VERSION.glibc23.i386.rpm
- Packages that contain additional files for MySQL Cluster
- installations.
-
-Note
- The MySQL-ndb-tools RPM requires a working installation of
- perl. Prior to MySQL 5.1.18, the DBI and HTML::Template
- packages were also required. See Section 2.15, "Perl
- Installation Notes," and Section 17.6.21, "ndb_size.pl ---
- NDBCLUSTER Size Requirement Estimator," for more information.
-
- * MySQL-test-VERSION.glibc23.i386.rpm
- This package includes the MySQL test suite.
-
- * MySQL-VERSION.src.rpm
- This contains the source code for all of the previous
- packages. It can also be used to rebuild the RPMs on other
- architectures (for example, Alpha or SPARC).
-
- The suffix of RPM package names (following the VERSION value) has
- the following syntax:
-.PLATFORM.CPU.rpm
-
- The PLATFORM and CPU values indicate the type of system for which
- the package is built. PLATFORM indicates the platform and CPU
- indicates the processor type or family.
-
- All packages are dynamically linked against glibc 2.3. The
- PLATFORM value indicates whether the package is platform
- independent or intended for a specific platform, as shown in the
- following table.
- glibc23 Platform independent, should run on any Linux distribution
- that supports glibc 2.3
- rhel3, rhel4 Red Hat Enterprise Linux 3 or 4
- sles9, sles10 SuSE Linux Enterprise Server 9 or 10
-
- In MySQL 5.1, only glibc23 packages are available currently.
-
- The CPU value indicates the processor type or family for which the
- package is built.
- i386 x86 processor, 386 and up
- i586 x86 processor, Pentium and up
- x86_64 64-bit x86 processor
- ia64 Itanium (IA-64) processor
-
- To see all files in an RPM package (for example, a MySQL-server
- RPM), run a command like this:
-shell> rpm -qpl MySQL-server-VERSION.glibc23.i386.rpm
-
- To perform a standard minimal installation, install the server and
- client RPMs:
-shell> rpm -i MySQL-server-VERSION.glibc23.i386.rpm
-shell> rpm -i MySQL-client-VERSION.glibc23.i386.rpm
-
- To install only the client programs, install just the client RPM:
-shell> rpm -i MySQL-client-VERSION.glibc23.i386.rpm
-
- RPM provides a feature to verify the integrity and authenticity of
- packages before installing them. If you would like to learn more
- about this feature, see Section 2.1.4, "Verifying Package
- Integrity Using MD5 Checksums or GnuPG."
-
- The server RPM places data under the /var/lib/mysql directory. The
- RPM also creates a login account for a user named mysql (if one
- does not exist) to use for running the MySQL server, and creates
- the appropriate entries in /etc/init.d/ to start the server
- automatically at boot time. (This means that if you have performed
- a previous installation and have made changes to its startup
- script, you may want to make a copy of the script so that you
- don't lose it when you install a newer RPM.) See Section 2.11.2.2,
- "Starting and Stopping MySQL Automatically," for more information
- on how MySQL can be started automatically on system startup.
-
- If you want to install the MySQL RPM on older Linux distributions
- that do not support initialization scripts in /etc/init.d
- (directly or via a symlink), you should create a symbolic link
- that points to the location where your initialization scripts
- actually are installed. For example, if that location is
- /etc/rc.d/init.d, use these commands before installing the RPM to
- create /etc/init.d as a symbolic link that points there:
-shell> cd /etc
-shell> ln -s rc.d/init.d .
-
- However, all current major Linux distributions should support the
- new directory layout that uses /etc/init.d, because it is required
- for LSB (Linux Standard Base) compliance.
-
- If the RPM files that you install include MySQL-server, the mysqld
- server should be up and running after installation. You should be
- able to start using MySQL.
-
- If something goes wrong, you can find more information in the
- binary installation section. See Section 2.9, "Installing MySQL
- from tar.gz Packages on Other Unix-Like Systems."
-
-Note
-
- The accounts that are listed in the MySQL grant tables initially
- have no passwords. After starting the server, you should set up
- passwords for them using the instructions in Section 2.11,
- "Post-Installation Setup and Testing."
-
- During RPM installation, a user named mysql and a group named
- mysql are created on the system. This is done using the useradd,
- groupadd, and usermod commands. Those commands require appropriate
- administrative privileges, which is ensured for locally managed
- users and groups (as listed in the /etc/passwd and /etc/group
- files) by the RPM installation process being run by root.
-
- For nonlocal user management (LDAP, NIS, and so forth), the
- administrative tools may require additional authentication (such
- as a password), and will fail if the installing user does not
- provide this authentication. Even if they fail, the RPM
- installation will not abort but succeed, and this is intentional.
- If they failed, some of the intended transfer of ownership may be
- missing, and it is recommended that the system administrator then
- manually ensures some appropriate user andgroup exists and
- manually transfers ownership following the actions in the RPM spec
- file.
-
-2.5. Installing MySQL on Mac OS X
-
- You can install MySQL on Mac OS X 10.3.x ("Panther") or newer
- using a Mac OS X binary package in PKG format instead of the
- binary tarball distribution. Please note that older versions of
- Mac OS X (for example, 10.1.x or 10.2.x) are not supported by this
- package.
-
- The package is located inside a disk image (.dmg) file that you
- first need to mount by double-clicking its icon in the Finder. It
- should then mount the image and display its contents.
-
- To obtain MySQL, see Section 2.1.3, "How to Get MySQL."
-
-Note
-
- Before proceeding with the installation, be sure to shut down all
- running MySQL server instances by either using the MySQL Manager
- Application (on Mac OS X Server) or via mysqladmin shutdown on the
- command line.
-
- To actually install the MySQL PKG file, double-click on the
- package icon. This launches the Mac OS X Package Installer, which
- guides you through the installation of MySQL.
-
- Due to a bug in the Mac OS X package installer, you may see this
- error message in the destination disk selection dialog:
-You cannot install this software on this disk. (null)
-
- If this error occurs, simply click the Go Back button once to
- return to the previous screen. Then click Continue to advance to
- the destination disk selection again, and you should be able to
- choose the destination disk correctly. We have reported this bug
- to Apple and it is investigating this problem.
-
- The Mac OS X PKG of MySQL installs itself into
- /usr/local/mysql-VERSION and also installs a symbolic link,
- /usr/local/mysql, that points to the new location. If a directory
- named /usr/local/mysql exists, it is renamed to
- /usr/local/mysql.bak first. Additionally, the installer creates
- the grant tables in the mysql database by executing
- mysql_install_db.
-
- The installation layout is similar to that of a tar file binary
- distribution; all MySQL binaries are located in the directory
- /usr/local/mysql/bin. The MySQL socket file is created as
- /tmp/mysql.sock by default. See Section 2.1.5, "Installation
- Layouts."
-
- MySQL installation requires a Mac OS X user account named mysql. A
- user account with this name should exist by default on Mac OS X
- 10.2 and up.
-
- If you are running Mac OS X Server, a version of MySQL should
- already be installed. The following table shows the versions of
- MySQL that ship with Mac OS X Server versions.
- Mac OS X Server Version MySQL Version
- 10.2-10.2.2 3.23.51
- 10.2.3-10.2.6 3.23.53
- 10.3 4.0.14
- 10.3.2 4.0.16
- 10.4.0 4.1.10a
-
- This manual section covers the installation of the official MySQL
- Mac OS X PKG only. Make sure to read Apple's help information
- about installing MySQL: Run the "Help View" application, select
- "Mac OS X Server" help, do a search for "MySQL," and read the item
- entitled "Installing MySQL."
-
- If you previously used Marc Liyanage's MySQL packages for Mac OS X
- from http://www.entropy.ch, you can simply follow the update
- instructions for packages using the binary installation layout as
- given on his pages.
-
- If you are upgrading from Marc's 3.23.x versions or from the Mac
- OS X Server version of MySQL to the official MySQL PKG, you also
- need to convert the existing MySQL privilege tables to the current
- format, because some new security privileges have been added. See
- Section 4.4.8, "mysql_upgrade --- Check Tables for MySQL Upgrade."
-
- If you want MySQL to start automatically during system startup,
- you also need to install the MySQL Startup Item. It is part of the
- Mac OS X installation disk images as a separate installation
- package. Simply double-click the MySQLStartupItem.pkg icon and
- follow the instructions to install it. The Startup Item need be
- installed only once. There is no need to install it each time you
- upgrade the MySQL package later.
-
- The Startup Item for MySQL is installed into
- /Library/StartupItems/MySQLCOM. (Before MySQL 4.1.2, the location
- was /Library/StartupItems/MySQL, but that collided with the MySQL
- Startup Item installed by Mac OS X Server.) Startup Item
- installation adds a variable MYSQLCOM=-YES- to the system
- configuration file /etc/hostconfig. If you want to disable the
- automatic startup of MySQL, simply change this variable to
- MYSQLCOM=-NO-.
-
- On Mac OS X Server, the default MySQL installation uses the
- variable MYSQL in the /etc/hostconfig file. The MySQL Startup Item
- installer disables this variable by setting it to MYSQL=-NO-. This
- avoids boot time conflicts with the MYSQLCOM variable used by the
- MySQL Startup Item. However, it does not shut down a running MySQL
- server. You should do that yourself.
-
- After the installation, you can start up MySQL by running the
- following commands in a terminal window. You must have
- administrator privileges to perform this task.
-
- If you have installed the Startup Item, use this command:
-shell> sudo /Library/StartupItems/MySQLCOM/MySQLCOM start
-(Enter your password, if necessary)
-(Press Control-D or enter "exit" to exit the shell)
-
- If you don't use the Startup Item, enter the following command
- sequence:
-shell> cd /usr/local/mysql
-shell> sudo ./bin/mysqld_safe
-(Enter your password, if necessary)
-(Press Control-Z)
-shell> bg
-(Press Control-D or enter "exit" to exit the shell)
-
- You should be able to connect to the MySQL server, for example, by
- running /usr/local/mysql/bin/mysql.
-
-Note
-
- The accounts that are listed in the MySQL grant tables initially
- have no passwords. After starting the server, you should set up
- passwords for them using the instructions in Section 2.11,
- "Post-Installation Setup and Testing."
-
- You might want to add aliases to your shell's resource file to
- make it easier to access commonly used programs such as mysql and
- mysqladmin from the command line. The syntax for bash is:
-alias mysql=/usr/local/mysql/bin/mysql
-alias mysqladmin=/usr/local/mysql/bin/mysqladmin
-
- For tcsh, use:
-alias mysql /usr/local/mysql/bin/mysql
-alias mysqladmin /usr/local/mysql/bin/mysqladmin
-
- Even better, add /usr/local/mysql/bin to your PATH environment
- variable. You can do this by modifying the appropriate startup
- file for your shell. For more information, see Section 4.2.1,
- "Invoking MySQL Programs."
-
- If you are upgrading an existing installation, note that
- installing a new MySQL PKG does not remove the directory of an
- older installation. Unfortunately, the Mac OS X Installer does not
- yet offer the functionality required to properly upgrade
- previously installed packages.
-
- To use your existing databases with the new installation, you'll
- need to copy the contents of the old data directory to the new
- data directory. Make sure that neither the old server nor the new
- one is running when you do this. After you have copied over the
- MySQL database files from the previous installation and have
- successfully started the new server, you should consider removing
- the old installation files to save disk space. Additionally, you
- should also remove older versions of the Package Receipt
- directories located in /Library/Receipts/mysql-VERSION.pkg.
-
-2.6. Installing MySQL on Solaris
-
- To obtain a binary MySQL distribution for Solaris in tarball or
- PKG format, http://dev.mysql.com/downloads/mysql/5.1.html.
-
- If you install MySQL using a binary tarball distribution on
- Solaris, you may run into trouble even before you get the MySQL
- distribution unpacked, as the Solaris tar cannot handle long file
- names. This means that you may see errors when you try to unpack
- MySQL.
-
- If this occurs, you must use GNU tar (gtar) to unpack the
- distribution.
-
- You can install MySQL on Solaris using a binary package in PKG
- format instead of the binary tarball distribution. Before
- installing using the binary PKG format, you should create the
- mysql user and group, for example:
-groupadd mysql
-useradd -g mysql mysql
-
- Some basic PKG-handling commands follow:
-
- * To add a package:
-pkgadd -d package_name.pkg
-
- * To remove a package:
-pkgrm package_name
-
- * To get a full list of installed packages:
-pkginfo
-
- * To get detailed information for a package:
-pkginfo -l package_name
-
- * To list the files belonging to a package:
-pkgchk -v package_name
-
- * To get packaging information for an arbitrary file:
-pkgchk -l -p file_name
-
- For additional information about installing MySQL on Solaris, see
- Section 2.13.3, "Solaris Notes."
-
-2.7. Installing MySQL on i5/OS
-
- The i5/OS POWER MySQL package was created in cooperation with IBM.
- MySQL works within the Portable Application Solution Environment
- (PASE) on the System i series of hardware and will also provide
- database services for the Zend Core for i5/OS.
-
- MySQL for i5/OS is provided as a save file (.savf) package that
- can be downloaded and installed directly without any additional
- installation steps required.
-
- MySQL is only supported on i5/OS V5R4 or later releases. The i5/OS
- PASE must be installed for MySQL to operate. You must be able to
- login as a user in *SECOFR class.
-
- You should the installation notes and tips for i5/OS before
- starting installation. See i5/OS Installation Notes.
-
-Note
-
- The installation package will use an existing configuration if you
- have previously installed MySQL (which is identified by looking
- for the file /etc/my.cnf). The values for the data directory
- (DATADIR) and owner of the MySQL files (USRPRF) specified during
- the installation will be ignored, and the values determined from
- the /etc/my.cnf will be used instead.
-
- If you want to change these parameters during a new install, you
- should temporarily rename /etc/my.cnf, install MySQL using the new
- parameters you want to use, and then merge your previous
- /etc/my.cnf configuration settings with the new /etc/my.cnf file
- that is created during installation.
-
- To install MySQL on i5/OS, follow these steps:
-
- 1. Create a user profile MYSQL. The MYSQL user profile will own
- all the MySQL files and databases and be the active user used
- when the MySQL server is running. The profile should be
- disabled so that you cannot log in as the MySQL user. To
- create a user profile, use CRTUSRPRF:
-CRTUSRPRF USRPRF(MYSQL) STATUS(*DISABLED) TEXT('MySQL user id')
-
- 2. On the System i machine, create a save file that will be used
- to receive the downloaded installation save file. The file
- should be located within the General Purpose Library (QGPL):
-CRTSAVF FILE(QGPL/MYSQLINST)
-
- 3. Download the MySQL installation save file in 32-bit
- (mysql-5.0.42-i5os-power-32bit.savf) or 64-bit
- (mysql-5.0.42-i5os-power-64bit.savf) from MySQL Downloads
- (http://dev.mysql.com/downloads).
-
- 4. You need to FTP the downloaded .savf file directly into the
- QGPL/MYSQLINST file on the System i server. You can do this
- through FTP using the following steps after logging in to the
- System i machine:
-ftp> bin
-ftp> cd qgpl
-ftp> put mysql-5.0.42-i5os-power.savf mysqlinst
-
- 5. Log into the System i server using a user in the *SECOFR
- class, such as the QSECOFR user ID.
-
- 6. You need to restore the installation library stored in the
- .savf save file:
-RSTLIB MYSQLINST DEV(*SAVF) SAVF(QGPL/MYSQLINST)
-
- 7. You need to execute the installation command,
- MYSQLINST/INSMYSQL. You can specify three parameter settings
- during installation:
-
- + DIR('/opt/mysql') sets the installation location for the
- MySQL files. The directory will be created if it does not
- already exist.
-
- + DATADIR('/QOpenSys/mysal/data') sets the location of the
- directory that will be used to store the database files
- and binary logs. The default setting is
- /QOpenSys/mysql/data. Note that if the installer detects
- an existing installation (due to the existence of
- /etc/my.cnf), then this parameter will be ignored.
-
- + USRPRF(MYSQL) sets the user profile that will own the
- files that are installed. The profile will be created if
- it does not already exist.
- MySQL can be installed anywhere, for this example we will
- assume MySQL has been installed into /opt/mysql. The MYSQL
- user profile that was created earlier in this sequence should
- be used for the profile:
-MYSQLINST/INSMYSQL DIR('/opt/mysql') DATADIR('/opt/mysqldata') USRPRF
-(MYSQL)
- If you are updating an installation over an existing MySQL
- installation, you should use the same parameter values that
- were used when MySQL was originally installed.
- The installation copies all the necessary files into a
- directory matching the package version (for example
- mysql-5.0.42-i5os-power-32bit), sets the ownership on those
- files, sets up the MySQL environment and creates the MySQL
- configuration file (in /etc/my.cnf) completing all the steps
- in a typical binary installation process automatically. If
- this is a new installation of MySQL, or if the installer
- detects that this is a new version (because the /etc/my.cnf
- file does not exist), then the initial core MySQL databases
- will also be created during installation.
-
- 8. Once the installation has completed, you can delete the
- installation file:
-DLTLIB LIB(MYSQLINST)
-
- To start MySQL:
-
- 1. Log into the System i server using a user within the *SECOFR
- class, such as the QSECOFR user ID.
-
-Note
- You should start mysqld_safe using a user that in the PASE
- environment has the id=0 (the equivalent of the standard Unix
- root user). If you do not use a user with this ID then the
- system will be unable to change the user when executing mysqld
- as set using --user option. If this happens, mysqld may be
- unable to read the files located within the MySQL data
- directory and the execution will fail.
-
- 2. Enter the PASE environment using call qp2term.
-
- 3. Start the MySQL server by changing to the installation
- directory and running mysqld_safe, specifying the user name
- used to install the server. The installer conveniently
- installs a symbolic link to the installation directory
- (mysql-5.0.42-i5os-power-32bit) as /opt/mysql/mysql:
-> cd /opt/mysql/mysql
-> bin/mysqld_safe --user=mysql &
- You should see a message similar to the following:
-Starting mysqld daemon with databases »
- from /opt/mysql/mysql-enterprise-5.0.42-i5os-power-32bit/data
-
- If you are having problems starting MySQL server, see Section
- 2.11.2.3, "Starting and Troubleshooting the MySQL Server."
-
- To stop MySQL:
-
- 1. Log into the System i server using the *SECOFR class, such as
- the QSECOFR user ID.
-
- 2. Enter the PASE environment using call qp2term.
-
- 3. Stop the MySQL server by changing into the installation
- directory and running mysqladmin, specifying the user name
- used to install the server:
-> cd /opt/mysql/mysql
-> bin/mysqladmin -u root shutdown
- If the session that you started and stopped MySQL are the
- same, you may get the log output from mysqld:
- STOPPING server from pid file »
- /opt/mysql/mysql-enterprise-5.0.42-i5os-power-32bit/data/I5DBX.R
-CHLAND.IBM.COM.pid
- 070718 10:34:20 mysqld ended
- If the sessions used to start and stop MySQL are different,
- you will not receive any confirmation of the shutdown.
-
- Note and tips
-
- * A problem has been identified with the installation process on
- DBCS systems. If you are having problems install MySQL on a
- DBCS system, you need to change your job's coded character set
- identifier (CSSID) to 37 (EBCDIC) before executing the install
- command, INSMYSQL. To do this, determine your existing CSSID
- (using DSPJOB and selecting option 2), execute CHGJOB
- CSSID(37), run INSMYSQL to install MySQL and then execute
- CHGJOB again with your original CSSID.
-
- * If you want to use the Perl scripts that are included with
- MySQL, you need to download the iSeries Tools for Developers
- (5799-PTL). See
- http://www-03.ibm.com/servers/enable/site/porting/tools/.
-
-2.8. Installing MySQL on NetWare
-
- Porting MySQL to NetWare was an effort spearheaded by Novell.
- Novell customers should be pleased to note that NetWare 6.5 ships
- with bundled MySQL binaries, complete with an automatic commercial
- use license for all servers running that version of NetWare.
-
- MySQL for NetWare is compiled using a combination of Metrowerks
- CodeWarrior for NetWare and special cross-compilation versions of
- the GNU autotools.
-
- The latest binary packages for NetWare can be obtained at
- http://dev.mysql.com/downloads/. See Section 2.1.3, "How to Get
- MySQL."
-
- To host MySQL, the NetWare server must meet these requirements:
-
- * The latest Support Pack of NetWare 6.5
- (http://support.novell.com/filefinder/18197/index.html) must
- be installed.
-
- * The system must meet Novell's minimum requirements to run the
- respective version of NetWare.
-
- * MySQL data and the program binaries must be installed on an
- NSS volume; traditional volumes are not supported.
-
- To install MySQL for NetWare, use the following procedure:
-
- 1. If you are upgrading from a prior installation, stop the MySQL
- server. This is done from the server console, using the
- following command:
-SERVER: mysqladmin -u root shutdown
-
-Note
- If the MySQL root user account has a password, you need to
- invoke mysqladmin with the -p option and supply the password
- when prompted.
-
- 2. Log on to the target server from a client machine with access
- to the location where you are installing MySQL.
-
- 3. Extract the binary package Zip file onto the server. Be sure
- to allow the paths in the Zip file to be used. It is safe to
- simply extract the file to SYS:\.
- If you are upgrading from a prior installation, you may need
- to copy the data directory (for example, SYS:MYSQL\DATA), as
- well as my.cnf, if you have customized it. You can then delete
- the old copy of MySQL.
-
- 4. You might want to rename the directory to something more
- consistent and easy to use. The examples in this manual use
- SYS:MYSQL to refer to the installation directory.
- Note that MySQL installation on NetWare does not detect if a
- version of MySQL is already installed outside the NetWare
- release. Therefore, if you have installed the latest MySQL
- version from the Web (for example, MySQL 4.1 or later) in
- SYS:\MYSQL, you must rename the folder before upgrading the
- NetWare server; otherwise, files in SYS:\MySQL are overwritten
- by the MySQL version present in NetWare Support Pack.
-
- 5. At the server console, add a search path for the directory
- containing the MySQL NLMs. For example:
-SERVER: SEARCH ADD SYS:MYSQL\BIN
-
- 6. Initialize the data directory and the grant tables, if
- necessary, by executing mysql_install_db at the server
- console.
-
- 7. Start the MySQL server using mysqld_safe at the server
- console.
-
- 8. To finish the installation, you should also add the following
- commands to autoexec.ncf. For example, if your MySQL
- installation is in SYS:MYSQL and you want MySQL to start
- automatically, you could add these lines:
-#Starts the MySQL 5.1.x database server
-SEARCH ADD SYS:MYSQL\BIN
-MYSQLD_SAFE
- If you are running MySQL on NetWare 6.0, we strongly suggest
- that you use the --skip-external-locking option on the command
- line:
-#Starts the MySQL 5.1.x database server
-SEARCH ADD SYS:MYSQL\BIN
-MYSQLD_SAFE --skip-external-locking
- It is also necessary to use CHECK TABLE and REPAIR TABLE
- instead of myisamchk, because myisamchk makes use of external
- locking. External locking is known to have problems on NetWare
- 6.0; the problem has been eliminated in NetWare 6.5. Note that
- the use of MySQL on Netware 6.0 is not officially supported.
- mysqld_safe on NetWare provides a screen presence. When you
- unload (shut down) the mysqld_safe NLM, the screen does not go
- away by default. Instead, it prompts for user input:
-*<NLM has terminated; Press any key to close the screen>*
- If you want NetWare to close the screen automatically instead,
- use the --autoclose option to mysqld_safe. For example:
-#Starts the MySQL 5.1.x database server
-SEARCH ADD SYS:MYSQL\BIN
-MYSQLD_SAFE --autoclose
- The behavior of mysqld_safe on NetWare is described further in
- Section 4.3.2, "mysqld_safe --- MySQL Server Startup Script."
-
- 9. When installing MySQL, either for the first time or upgrading
- from a previous version, download and install the latest and
- appropriate Perl module and PHP extensions for NetWare:
-
- + Perl:
- http://forge.novell.com/modules/xfcontent/downloads.php/p
- erl/Modules/
-
- + PHP:
- http://forge.novell.com/modules/xfcontent/downloads.php/p
- hp/Modules/
-
- If there was an existing installation of MySQL on the NetWare
- server, be sure to check for existing MySQL startup commands in
- autoexec.ncf, and edit or delete them as necessary.
-
-Note
-
- The accounts that are listed in the MySQL grant tables initially
- have no passwords. After starting the server, you should set up
- passwords for them using the instructions in Section 2.11,
- "Post-Installation Setup and Testing."
-
-2.9. Installing MySQL from tar.gz Packages on Other Unix-Like Systems
+2.2. Installing MySQL from Generic Binaries on Unix/Linux
This section covers the installation of MySQL binary distributions
that are provided for various platforms in the form of compressed
- tar files (files with a .tar.gz extension). See Section 2.1.2.4,
- "MySQL Binaries Compiled by Sun Microsystems, Inc.," for a
+ tar files (files with a .tar.gz extension). See Section 2.2,
+ "Installing MySQL from Generic Binaries on Unix/Linux," for a
detailed list.
To obtain MySQL, see Section 2.1.3, "How to Get MySQL."
+ Sun Microsystems, Inc. provides a set of binary distributions of
+ MySQL. In addition to binaries provided in platform-specific
+ package formats, we offer binary distributions for a number of
+ platforms in the form of compressed tar files (.tar.gz files). For
+ Windows distributions, see Section 2.5, "Installing MySQL on
+ Windows."
+
+ If you want to compile a debug version of MySQL from a source
+ distribution, you should add --with-debug or --with-debug=full to
+ the configure command used to configure the distribution and
+ remove any -fomit-frame-pointer options.
+
MySQL tar file binary distributions have names of the form
mysql-VERSION-OS.tar.gz, where VERSION is a number (for example,
- 5.1.39), and OS indicates the type of operating system for which
+ 5.1.41), and OS indicates the type of operating system for which
the distribution is intended (for example, pc-linux-i686).
In addition to these generic packages, we also offer binaries in
- platform-specific package formats for selected platforms. See
- Section 2.2, "Standard MySQL Installation Using a Binary
- Distribution," for more information on how to install these.
+ platform-specific package formats for selected platforms. See the
+ platform specific sections for more information, for more
+ information on how to install these.
You need the following tools to install a MySQL tar file binary
distribution:
@@ -3265,11 +809,13 @@ Note
* A reasonable tar to unpack the distribution. GNU tar is known
to work. Some operating systems come with a preinstalled
version of tar that is known to have problems. For example,
- the tar provided with early versions of Mac OS X, SunOS 4.x
- and Solaris 8 and earlier are known to have problems with long
- file names. On Mac OS X, you can use the preinstalled gnutar
- program. On other systems with a deficient tar, you should
- install GNU tar first.
+ the tar provided with early versions of Mac OS X, SunOS 4.x,
+ Solaris 8, Solaris 9, Solaris 10 and OpenSolaris, and HP-UX
+ are known to have problems with long file names. On Mac OS X,
+ you can use the preinstalled gnutar program. On Solaris 10 and
+ OpenSolaris you can use the preinstalled gtar. On other
+ systems with a deficient tar, you should install GNU tar
+ first.
If you run into problems and need to file a bug report, please use
the instructions in Section 1.6, "How to Report Bugs or Problems."
@@ -3292,7 +838,7 @@ shell> bin/mysqld_safe --user=mysql &
Note
This procedure does not set up any passwords for MySQL accounts.
- After following the procedure, proceed to Section 2.11,
+ After following the procedure, proceed to Section 2.13,
"Post-Installation Setup and Testing."
A more detailed version of the preceding description for
@@ -3386,7 +932,7 @@ shell> chown -R mysql data
machine, you can copy support-files/mysql.server to the
location where your system has its startup files. More
information can be found in the support-files/mysql.server
- script itself and in Section 2.11.2.2, "Starting and Stopping
+ script itself and in Section 2.13.1.2, "Starting and Stopping
MySQL Automatically."
10. You can set up new accounts using the bin/mysql_setpermission
script if you install the DBI and DBD::mysql Perl modules. See
@@ -3425,10 +971,10 @@ Note
The accounts that are listed in the MySQL grant tables initially
have no passwords. After starting the server, you should set up
- passwords for them using the instructions in Section 2.11,
+ passwords for them using the instructions in Section 2.13,
"Post-Installation Setup and Testing."
-2.10. MySQL Installation Using a Source Distribution
+2.3. MySQL Installation Using a Source Distribution
Before you proceed with an installation from source, first check
whether our binary is available for your platform and whether it
@@ -3437,11 +983,11 @@ Note
To obtain a source distribution for MySQL, Section 2.1.3, "How to
Get MySQL." If you want to build MySQL from source on Windows, see
- Section 2.10.6, "Installing MySQL from Source on Windows."
+ Section 2.5.10, "Installing MySQL from Source on Windows."
MySQL source distributions are provided as compressed tar archives
and have names of the form mysql-VERSION.tar.gz, where VERSION is
- a number like 5.1.39.
+ a number like 5.1.41.
You need the following tools to build and install MySQL from
source:
@@ -3451,11 +997,13 @@ Note
* A reasonable tar to unpack the distribution. GNU tar is known
to work. Some operating systems come with a preinstalled
version of tar that is known to have problems. For example,
- the tar provided with early versions of Mac OS X, SunOS 4.x
- and Solaris 8 and earlier are known to have problems with long
- file names. On Mac OS X, you can use the preinstalled gnutar
- program. On other systems with a deficient tar, you should
- install GNU tar first.
+ the tar provided with early versions of Mac OS X, SunOS 4.x,
+ Solaris 8, Solaris 9, Solaris 10 and OpenSolaris, and HP-UX
+ are known to have problems with long file names. On Mac OS X,
+ you can use the preinstalled gnutar program. On Solaris 10 and
+ OpenSolaris you can use the preinstalled gtar. On other
+ systems with a deficient tar, you should install GNU tar
+ first.
* A working ANSI C++ compiler. gcc 2.95.2 or later, SGI C++, and
SunPro C++ are some of the compilers that are known to work.
@@ -3489,7 +1037,7 @@ CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors \
If you run into problems and need to file a bug report, please use
the instructions in Section 1.6, "How to Report Bugs or Problems."
-2.10.1. Source Installation Overview
+2.3.1. Source Installation Overview
The basic commands that you must execute to install a MySQL source
distribution are:
@@ -3519,7 +1067,7 @@ shell> rpmbuild --rebuild --clean MySQL-VERSION.src.rpm
Note
This procedure does not set up any passwords for MySQL accounts.
- After following the procedure, proceed to Section 2.11,
+ After following the procedure, proceed to Section 2.13,
"Post-Installation Setup and Testing," for post-installation setup
and testing.
@@ -3566,15 +1114,15 @@ shell> ./configure --prefix=/usr/local/mysql
shell> make
When you run configure, you might want to specify other
options. Run ./configure --help for a list of options. Section
- 2.10.2, "Typical configure Options," discusses some of the
- more useful options.
+ 2.3.2, "Typical configure Options," discusses some of the more
+ useful options.
If configure fails and you are going to send mail to a MySQL
mailing list to ask for assistance, please include any lines
from config.log that you think can help solve the problem.
Also include the last couple of lines of output from
configure. To file a bug report, please use the instructions
in Section 1.6, "How to Report Bugs or Problems."
- If the compile fails, see Section 2.10.4, "Dealing with
+ If the compile fails, see Section 2.3.4, "Dealing with
Problems Compiling MySQL," for help.
8. Install the distribution:
@@ -3622,7 +1170,7 @@ shell> chown -R mysql var
machine, you can copy support-files/mysql.server to the
location where your system has its startup files. More
information can be found in the support-files/mysql.server
- script itself; see also Section 2.11.2.2, "Starting and
+ script itself; see also Section 2.13.1.2, "Starting and
Stopping MySQL Automatically."
14. You can set up new accounts using the bin/mysql_setpermission
script if you install the DBI and DBD::mysql Perl modules. See
@@ -3652,10 +1200,10 @@ Note
The accounts that are listed in the MySQL grant tables initially
have no passwords. After starting the server, you should set up
- passwords for them using the instructions in Section 2.11,
+ passwords for them using the instructions in Section 2.13,
"Post-Installation Setup and Testing."
-2.10.2. Typical configure Options
+2.3.2. Typical configure Options
The configure script gives you a great deal of control over how
you configure a MySQL source distribution. Typically you do this
@@ -3687,6 +1235,7 @@ shell> ./configure --help
--enable-FEATURE Enable FEATURE
--enable-assembler Use assembler versions of some string functions
if available
+ --enable-debug-sync Compile in Debug Sync facility 5.1.41
--enable-dependency-tracking Do not reject slow dependency
extractors
--enable-fast-install Optimize for fast installation yes
@@ -3833,8 +1382,7 @@ shell> ./configure --help
Some of the configure options available are described here. For
options that may be of use if you have difficulties building
- MySQL, see Section 2.10.4, "Dealing with Problems Compiling
- MySQL."
+ MySQL, see Section 2.3.4, "Dealing with Problems Compiling MySQL."
* To compile just the MySQL client libraries and client programs
and not the server, use the --without-server option:
@@ -3870,6 +1418,11 @@ shell> ./configure --prefix=/usr/local \
common to use an option file. See Section 4.2.3.3, "Using
Option Files."
+ * This option specifies the port number on which the server
+ listens for TCP/IP connections. The default is port 3306. To
+ listen on a different port, use a configure command like this:
+shell> ./configure --with-tcp-port=3307
+
* If you are using Unix and you want the MySQL socket file
location to be somewhere other than the default location
(normally in the directory /tmp or /var/run), use a configure
@@ -3878,7 +1431,7 @@ shell> ./configure \
--with-unix-socket-path=/usr/local/mysql/tmp/mysql.sock
The socket file name must be an absolute path name. You can
also change the location of mysql.sock at server startup by
- using a MySQL option file. See Section B.1.4.5, "How to
+ using a MySQL option file. See Section B.5.4.5, "How to
Protect or Change the MySQL Unix Socket File."
* If you want to compile statically linked programs (for
@@ -3924,7 +1477,7 @@ CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro \
The binaries we provide on the MySQL Web site at
http://dev.mysql.com/downloads/ are all compiled with full
optimization and should be perfect for most users. See Section
- 2.1.2.4, "MySQL Binaries Compiled by Sun Microsystems, Inc.."
+ 2.2, "Installing MySQL from Generic Binaries on Unix/Linux."
There are some configuration settings you can tweak to build
an even faster binary, but these are only for advanced users.
See Section 7.5.1, "How Compiling and Linking Affects the
@@ -3987,22 +1540,41 @@ shell> ./configure --with-debug
error output. Typically, this output is written to the error
log.
+ * To cause the Debug Sync facility to be compiled into the
+ server, use the --enable-debug-sync option. This facility is
+ used for testing and debugging. When compiled in, Debug Sync
+ is disabled by default. To enable it, start mysqld with the
+ --debug-sync-timeout=N option, where N is a timeout value
+ greater than 0. (The default value is 0, which disables Debug
+ Sync.) N becomes the default timeout for individual
+ synchronization points.
+ Debug Sync is also compiled in if you configure with the
+ --with-debug option (which implies --enable-debug-sync),
+ unless you also use the --disable-debug-sync option.
+ For a description of the Debug Sync facility and how to use
+ synchronization points, see MySQL Internals: Test
+ Synchronization
+ (http://forge.mysql.com/wiki/MySQL_Internals_Test_Synchronizat
+ ion).
+ The --enable-debug-sync and --disable-debug-sync options were
+ added in MySQL 5.1.41.
+
* If your client programs are using threads, you must compile a
thread-safe version of the MySQL client library with the
--enable-thread-safe-client configure option. This creates a
libmysqlclient_r library with which you should link your
- threaded applications. See Section 21.10.17, "How to Make a
+ threaded applications. See Section 21.9.16.2, "How to Make a
Threaded Client."
* Some features require that the server be built with
compression library support, such as the COMPRESS() and
UNCOMPRESS() functions, and compression of the client/server
protocol. The --with-zlib-dir=no|bundled|DIR option provides
- control for compression library support. The value no
+ control over compression library support. The value no
explicitly disables compression support. bundled causes the
zlib library bundled in the MySQL sources to be used. A DIR
- path name specifies where to find the compression library
- sources.
+ path name specifies the directory in which to find the
+ compression library sources.
* It is possible to build MySQL with large table support using
the --with-big-tables option.
@@ -4035,8 +1607,8 @@ shell> ./configure --with-debug
default as of MySQL 5.1.28; to disable it, use
--disable-profiling.
- * See Section 2.13, "Operating System-Specific Notes," for
- options that pertain to particular operating systems.
+ * See Section 2.1, "General Installation Guidance," for options
+ that pertain to particular operating systems.
* See Section 5.5.7.2, "Using SSL Connections," for options that
pertain to configuring MySQL to support secure (encrypted)
@@ -4082,7 +1654,7 @@ shell> ./configure --with-debug
dynamic plugins. Plugins that do not support dynamic build are
not built.)
-2.10.3. Installing from the Development Source Tree
+2.3.3. Installing from the Development Source Tree
Caution
@@ -4091,17 +1663,17 @@ Caution
on your system, you should use a standard release distribution
(either a binary or source distribution).
- To obtain the most recent development source tree, you first need
- to download and install Bazaar. You can obtain Bazaar from the
- Bazaar VCS Website (http://bazaar-vcs.org). Bazaar is supported by
- any platform that supports Python, and is therefore compatible
- with any Linux, Unix, Windows or Mac OS X host. Instructions for
+ To obtain the most recent development source tree, you must have
+ Bazaar installed. You can obtain Bazaar from the Bazaar VCS
+ Website (http://bazaar-vcs.org). Bazaar is supported by any
+ platform that supports Python, and is therefore compatible with
+ any Linux, Unix, Windows or Mac OS X host. Instructions for
downloading and installing Bazaar on the different platforms are
available on the Bazaar website.
All MySQL projects are hosted on Launchpad
(http://launchpad.net/). MySQL projects, including MySQL server,
- MySQL Workbench and others are available from the Sun/MySQL
+ MySQL Workbench, and others are available from the Sun/MySQL
Engineering (http://launchpad.net/~mysql) page. For the
repositories related only to MySQL server, see the MySQL Server
(http://launchpad.net/mysql-server) page.
@@ -4135,12 +1707,12 @@ sql_yacc.yy:#####: fatal error: maximum table size (32767) exceeded
The maximum table size is not actually exceeded; the error is
caused by bugs in older versions of bison.
- To build under Windows you will need a copy of Microsoft Visual
- C++ 2005 Express Edition, Visual Studio .Net 2003 (7.1), or Visual
- Studio 2005 (8.0) compiler system.
+ To build under Windows you must have Microsoft Visual C++ 2005
+ Express Edition, Visual Studio .Net 2003 (7.1), or Visual Studio
+ 2005 (8.0) compiler system.
- Once you have the necessary tools installed, you first need to
- create a local branch of the MySQL source code on your machine:
+ Once the necessary tools are installed, you must create a local
+ branch of the MySQL source code on your machine:
1. To obtain a copy of the MySQL source code, you must create a
new Bazaar branch. If you do not already have a Bazaar
@@ -4150,8 +1722,8 @@ shell> mkdir mysql-server
shell> bzr init-repo --trees mysql-server
2. Once you have an initialized directory, you can branch from
- the public MySQL server repositories. To create a branch of a
- specific version:
+ the public MySQL server repositories to create a local source
+ tree. To create a branch of a specific version:
shell> cd mysql-server
shell> bzr branch lp:mysql-server/5.1 mysql-5.1
@@ -4167,46 +1739,60 @@ shell> bzr branch lp:mysql-server/5.1 mysql-5.1
branch:
shell> bzr branch mysql-5.1 mysql-5.1-build
- Once you have the local branch, you can start to build MySQL
- server from the source code. On Windows, the build process is
- different from Unix/Linux. To continue building MySQL on Windows,
- see Section 2.10.6, "Installing MySQL from Source on Windows."
+ 5. To obtain changes made after you have set up the branch
+ initially, update it using the pull option periodically. Use
+ this command in the top-level directory of the local copy:
+shell> bzr pull
+ You can examine the changeset comments for the tree by using
+ the log option to bzr:
+shell> bzr log
+ You can also browse changesets, comments, and source code
+ online. To browse this information for MySQL 5.1, go to the
+ Launchpad MySQL Server (http://launchpad.net/mysql-server)
+ page.
+ If you see diffs (changes) or code that you have a question
+ about, do not hesitate to send email to the MySQL internals
+ mailing list. See Section 1.5.1, "MySQL Mailing Lists." Also,
+ if you think you have a better idea on how to do something,
+ send an email message to the list with a patch.
+
+ After you have the local branch, you can build MySQL server from
+ the source code. On Windows, the build process is different from
+ Unix/Linux: see Section 2.5.10, "Installing MySQL from Source on
+ Windows."
- On Unix/Linux you need to use the autoconf system to create the
- configure script so that you can configure the build environment
- before building.
+ On Unix/Linux, use the autoconf system to create the configure
+ script so that you can configure the build environment before
+ building. The following example shows the typical commands
+ required to build MySQL from a source tree.
- 1. The following example shows the typical commands required to
- configure a source tree. The first cd command changes location
- into the top-level directory of the tree; replace mysql-5.1
- with the appropriate directory name.
+ 1. Change location to the top-level directory of the source tree;
+ replace mysql-5.1 with the appropriate directory name.
+shell> cd mysql-5.1
-Note
- For MySQL 5.1.12 and earlier, you must separately configure
- the INNODB storage engine. You can do this by running the
- following command from the main source directory:
+ 2. Prepare the source tree for configuration.
+ Prior to MySQL 5.1.12, you must separately configure the
+ InnoDB storage engine. Run the following command from the main
+ source directory:
shell> (cd storage/innobase; autoreconf --force --install)
-shell> cd mysql-5.1
+ You can omit the previous command for MySQL 5.1.12 and later,
+ or if you do not require InnoDB support.
+ Prepare the remainder of the source tree:
shell> autoreconf --force --install
-shell> ./configure # Add your favorite options here
-shell> make
- Or you can use BUILD/autorun.sh as a shortcut for the
+ As an alternative to the preceding autoreconf command, you can
+ use BUILD/autorun.sh, which acts as a shortcut for the
following sequence of commands:
shell> aclocal; autoheader
shell> libtoolize --automake --force
shell> automake --force --add-missing; autoconf
- The command line that changes directory into the
- storage/innobase directory is used to configure the InnoDB
- storage engine. You can omit this lines if you do not require
- InnoDB support.
-
-Note
- Beginning with MySQL 5.1, code specific to storage engines has
- been moved under a storage directory. For example, InnoDB code
- is now found in storage/innobase and NDBCLUSTER code is in
- storage/ndb.
If you get some strange errors during this stage, verify that
- you have the correct version of the libtool installed.
+ you have the correct version of libtool installed.
+
+ 3. Configure the source tree and compile MySQL:
+shell> ./configure # Add your favorite options here
+shell> make
+ For a description of some configure options, see Section
+ 2.3.2, "Typical configure Options."
A collection of our standard configuration scripts is located
in the BUILD/ subdirectory. For example, you may find it more
convenient to use the BUILD/compile-pentium-debug script than
@@ -4217,52 +1803,34 @@ Note
They are not officially maintained and their contents may
change from release to release.
- 2. When the build is done, run make install. Be careful with this
+ 4. When the build is done, run make install. Be careful with this
on a production machine; the command may overwrite your live
- release installation. If you have another installation of
- MySQL, run ./configure with different values for the --prefix,
- --with-tcp-port, and --with-unix-socket-path options than
- those used for your production server.
+ release installation. If you already have MySQL installed and
+ do not want to overwrite it, run ./configure with values for
+ the --prefix, --with-tcp-port, and --with-unix-socket-path
+ options different from those used for your production server.
- 3. Play hard with your new installation and try to make the new
+ 5. Play hard with your new installation and try to make the new
features crash. Start by running make test. See Section
22.1.2, "MySQL Test Suite."
- 4. If you have gotten to the make stage, but the distribution
+ 6. If you have gotten to the make stage, but the distribution
does not compile, please enter the problem into our bugs
database using the instructions given in Section 1.6, "How to
Report Bugs or Problems." If you have installed the latest
versions of the required GNU tools, and they crash trying to
process our configuration files, please report that also.
- However, if you execute aclocal and get a command not found
- error or a similar problem, do not report it. Instead, make
- sure that all the necessary tools are installed and that your
- PATH variable is set correctly so that your shell can find
- them.
-
- 5. After initially copying the repository with bzr to obtain the
- source tree, you should use pull option to periodically update
- your local copy. To do this any time after you have set up the
- repository, use this command:
-shell> bzr pull
-
- 6. You can examine the changeset comments for the tree by using
- the log option to bzr:
-shell> bzr log
- You can also browse changesets, comments, and source code
- online. To browse this information for MySQL 5.1, go to
- http://launchpad.net/mysql-server/.
- If you see diffs or code that you have a question about, do
- not hesitate to send email to the MySQL internals mailing
- list. See Section 1.5.1, "MySQL Mailing Lists." Also, if you
- think you have a better idea on how to do something, send an
- email message to the list with a patch.
+ However, if you get a command not found error or a similar
+ problem for aclocal, configure, or other required tools, do
+ not report it. Instead, make sure that all the required tools
+ are installed and that your PATH variable is set correctly so
+ that your shell can find them.
-2.10.4. Dealing with Problems Compiling MySQL
+2.3.4. Dealing with Problems Compiling MySQL
All MySQL programs compile cleanly for us with no warnings on
Solaris or Linux using gcc. On other systems, warnings may occur
- due to differences in system include files. See Section 2.10.5,
+ due to differences in system include files. See Section 2.3.5,
"MIT-pthreads Notes," for warnings that may occur when using
MIT-pthreads. For other problems, check the following list.
@@ -4355,9 +1923,9 @@ shell> CFLAGS=-O3
shell> CXX=gcc
shell> CXXFLAGS=-O3
shell> export CC CFLAGS CXX CXXFLAGS
- See Section 2.1.2.4, "MySQL Binaries Compiled by Sun
- Microsystems, Inc.," for a list of flag definitions that have
- been found to be useful on various systems.
+ See Section 2.2, "Installing MySQL from Generic Binaries on
+ Unix/Linux," for a list of flag definitions that have been
+ found to be useful on various systems.
* If you get errors such as those shown here when compiling
mysqld, configure did not correctly detect the type of the
@@ -4415,20 +1983,19 @@ export CXX="gcc"
You must run configure again after making either of those
changes.
-2.10.5. MIT-pthreads Notes
+2.3.5. MIT-pthreads Notes
This section describes some of the issues involved in using
MIT-pthreads.
On Linux, you should not use MIT-pthreads. Use the installed
- LinuxThreads implementation instead. See Section 2.13.1, "Linux
- Notes."
+ LinuxThreads implementation instead. See Section 2.6, "Installing
+ MySQL on Linux."
If your system does not provide native thread support, you should
build MySQL using the MIT-pthreads package. This includes older
FreeBSD systems, SunOS 4.x, Solaris 2.4 and earlier, and some
- others. See Section 2.1.1, "Operating Systems Supported by MySQL
- Community Server."
+ others. See Section 2.1, "General Installation Guidance."
MIT-pthreads is not part of the MySQL 5.1 source distribution. If
you require this package, you need to download it separately from
@@ -4497,1322 +2064,9 @@ implicit declaration of function `int strtoul(...)'
* We have not been able to make readline work with MIT-pthreads.
(This is not necessary, but may be of interest to some.)
-2.10.6. Installing MySQL from Source on Windows
-
- These instructions describe how to build binaries from source for
- MySQL 5.1 on Windows. Instructions are provided for building
- binaries from a standard source distribution or from the Bazaar
- tree that contains the latest development source.
-
-Note
-
- The instructions here are strictly for users who want to test
- MySQL on Microsoft Windows from the latest source distribution or
- from the Bazaar tree. For production use, we do not advise using a
- MySQL server built by yourself from source. Normally, it is best
- to use precompiled binary distributions of MySQL that are built
- specifically for optimal performance on Windows by Sun
- Microsystems, Inc. Instructions for installing binary
- distributions are available in Section 2.3, "Installing MySQL on
- Windows."
-
- To build MySQL on Windows from source, you must satisfy the
- following system, compiler, and resource requirements:
-
- * Windows 2000, Windows XP, or newer version.
- Windows Vista is supported when using Visual Studio 2005
- provided you have installed the following updates:
-
- + Microsoft Visual Studio 2005 Professional Edition - ENU
- Service Pack 1 (KB926601)
- (http://support.microsoft.com/?kbid=926601)
-
- + Security Update for Microsoft Visual Studio 2005
- Professional Edition - ENU (KB937061)
- (http://support.microsoft.com/?kbid=937061)
-
- + Update for Microsoft Visual Studio 2005 Professional
- Edition - ENU (KB932232)
- (http://support.microsoft.com/?kbid=932232)
-
- * CMake, which can be downloaded from http://www.cmake.org.
- After installing, modify your path to include the cmake
- binary.
-
- * Microsoft Visual C++ 2005 Express Edition, Visual Studio .Net
- 2003 (7.1), or Visual Studio 2005 (8.0) compiler system.
-
- * If you are using Visual C++ 2005 Express Edition, you must
- also install an appropriate Platform SDK. More information and
- links to downloads for various Windows platforms is available
- from
- http://www.microsoft.com/downloads/details.aspx?familyid=0baf2
- b35-c656-4969-ace8-e4c0c0716adb.
-
- * If you are compiling from a Bazaar tree or making changes to
- the parser, you need bison for Windows, which can be
- downloaded from
- http://gnuwin32.sourceforge.net/packages/bison.htm. Download
- the package labeled "Complete package, excluding sources".
- After installing the package, modify your path to include the
- bison binary and ensure that this binary is accessible from
- Visual Studio.
-
- * Cygwin might be necessary if you want to run the test script
- or package the compiled binaries and support files into a Zip
- archive. (Cygwin is needed only to test or package the
- distribution, not to build it.) Cygwin is available from
- http://cygwin.com.
-
- * 3GB to 5GB of disk space.
-
- The exact system requirements can be found here:
- http://msdn.microsoft.com/vstudio/Previous/2003/sysreqs/default.as
- px and
- http://msdn.microsoft.com/vstudio/products/sysreqs/default.aspx
-
- You also need a MySQL source distribution for Windows, which can
- be obtained two ways:
-
- * Obtain a source distribution packaged by Sun Microsystems,
- Inc. These are available from http://dev.mysql.com/downloads/.
-
- * Package a source distribution yourself from the latest Bazaar
- developer source tree. For instructions on pulling the latest
- source files, see Section 2.10.3, "Installing from the
- Development Source Tree."
-
- If you find something not working as expected, or you have
- suggestions about ways to improve the current build process on
- Windows, please send a message to the win32 mailing list. See
- Section 1.5.1, "MySQL Mailing Lists."
-
-2.10.6.1. Building MySQL from Source Using CMake and Visual Studio
-
- You can build MySQL on Windows by using a combination of cmake and
- Microsoft Visual Studio .NET 2003 (7.1), Microsoft Visual Studio
- 2005 (8.0) or Microsoft Visual C++ 2005 Express Edition. You must
- have the appropriate Microsoft Platform SDK installed.
-
-Note
-
- To compile from the source code on Windows you must use the
- standard source distribution (for example, mysql-5.0.45.tar.gz).
- You build from the same distribution as used to build MySQL on
- Unix, Linux and other platforms. Do not use the Windows Source
- distributions as they do not contain the necessary configuration
- script and other files.
-
- Follow this procedure to build MySQL:
-
- 1. If you are installing from a packaged source distribution,
- create a work directory (for example, C:\workdir), and unpack
- the source distribution there using WinZip or another Windows
- tool that can read .zip files. This directory is the work
- directory in the following instructions.
-
- 2. Using a command shell, navigate to the work directory and run
- the following command:
-C:\workdir>win\configure.js options
- If you have associated the .js file extension with an
- application such as a text editor, then you may need to use
- the following command to force configure.js to be executed as
- a script:
-C:\workdir>cscript win\configure.js options
- These options are available for configure.js:
-
- + WITH_INNOBASE_STORAGE_ENGINE: Enable the InnoDB storage
- engine.
-
- + WITH_PARTITION_STORAGE_ENGINE: Enable user-defined
- partitioning.
-
- + WITH_ARCHIVE_STORAGE_ENGINE: Enable the ARCHIVE storage
- engine.
-
- + WITH_BLACKHOLE_STORAGE_ENGINE: Enable the BLACKHOLE
- storage engine.
-
- + WITH_EXAMPLE_STORAGE_ENGINE: Enable the EXAMPLE storage
- engine.
-
- + WITH_FEDERATED_STORAGE_ENGINE: Enable the FEDERATED
- storage engine.
-
- + WITH_NDBCLUSTER_STORAGE_ENGINE (experimental): Enable the
- NDBCLUSTER storage engine in the MySQL server; cause
- binaries for the MySQL Cluster management and data node,
- management client, and other programs to be built.
- This option is supported only in MySQL Cluster NDB 7.0
- (NDBCLUSTER storage engine versions 6.4.0 and later)
- using the MySQL Cluster sources. It cannot be used to
- enable clustering support in other MySQL source trees or
- distributions.
+2.4. Upgrading or Downgrading MySQL
- + MYSQL_SERVER_SUFFIX=suffix: Server suffix, default none.
-
- + COMPILATION_COMMENT=comment: Server comment, default
- "Source distribution".
-
- + MYSQL_TCP_PORT=port: Server port, default 3306.
-
- + DISABLE_GRANT_OPTIONS: Disables the --bootstrap,
- --skip-grant-tables, and --init-file options for mysqld.
- This option is available as of MySQL 5.1.15.
- For example (type the command on one line):
-C:\workdir>win\configure.js WITH_INNOBASE_STORAGE_ENGINE
- WITH_PARTITION_STORAGE_ENGINE MYSQL_SERVER_SUFFIX=-pro
-
- 3. From the work directory, execute the win\build-vs8.bat or
- win\build-vs71.bat file, depending on the version of Visual
- Studio you have installed. The script invokes CMake, which
- generates the mysql.sln solution file.
- You can also use win\build-vs8_x64.bat to build the 64-bit
- version of MySQL. However, you cannot build the 64-bit version
- with Visual Studio Express Edition. You must use Visual Studio
- 2005 (8.0) or higher.
-
- 4. From the work directory, open the generated mysql.sln file
- with Visual Studio and select the proper configuration using
- the Configuration menu. The menu provides Debug, Release,
- RelwithDebInfo, MinRelInfo options. Then select Solution >
- Build to build the solution.
- Remember the configuration that you use in this step. It is
- important later when you run the test script because that
- script needs to know which configuration you used.
-
- 5. Test the server. The server built using the preceding
- instructions expects that the MySQL base directory and data
- directory are C:\mysql and C:\mysql\data by default. If you
- want to test your server using the source tree root directory
- and its data directory as the base directory and data
- directory, you need to tell the server their path names. You
- can either do this on the command line with the --basedir and
- --datadir options, or by placing appropriate options in an
- option file. (See Section 4.2.3.3, "Using Option Files.") If
- you have an existing data directory elsewhere that you want to
- use, you can specify its path name instead.
- When the server is running in standalone fashion or as a
- service based on your configuration, try to connect to it from
- the mysql interactive command-line utility.
- You can also run the standard test script, mysql-test-run.pl.
- This script is written in Perl, so you'll need either Cygwin
- or ActiveState Perl to run it. You may also need to install
- the modules required by the script. To run the test script,
- change location into the mysql-test directory under the work
- directory, set the MTR_VS_CONFIG environment variable to the
- configuration you selected earlier (or use the --vs-config
- option), and invoke mysql-test-run.pl. For example (using
- Cygwin and the bash shell):
-shell> cd mysql-test
-shell> export MTR_VS_CONFIG=debug
-shell> ./mysql-test-run.pl --force --timer
-shell> ./mysql-test-run.pl --force --timer --ps-protocol
-
- When you are satisfied that the programs you have built are
- working correctly, stop the server. Now you can install the
- distribution. One way to do this is to use the make_win_bin_dist
- script in the scripts directory of the MySQL source distribution
- (see Section 4.4.2, "make_win_bin_dist --- Package MySQL
- Distribution as ZIP Archive"). This is a shell script, so you must
- have Cygwin installed if you want to use it. It creates a Zip
- archive of the built executables and support files that you can
- unpack in the location at which you want to install MySQL.
-
- It is also possible to install MySQL by copying directories and
- files directly:
-
- 1. Create the directories where you want to install MySQL. For
- example, to install into C:\mysql, use these commands:
-C:\> mkdir C:\mysql
-C:\> mkdir C:\mysql\bin
-C:\> mkdir C:\mysql\data
-C:\> mkdir C:\mysql\share
-C:\> mkdir C:\mysql\scripts
- If you want to compile other clients and link them to MySQL,
- you should also create several additional directories:
-C:\> mkdir C:\mysql\include
-C:\> mkdir C:\mysql\lib
-C:\> mkdir C:\mysql\lib\debug
-C:\> mkdir C:\mysql\lib\opt
- If you want to benchmark MySQL, create this directory:
-C:\> mkdir C:\mysql\sql-bench
- Benchmarking requires Perl support. See Section 2.15, "Perl
- Installation Notes."
-
- 2. From the work directory, copy into the C:\mysql directory the
- following directories:
-C:\> cd \workdir
-C:\workdir> copy client_release\*.exe C:\mysql\bin
-C:\workdir> copy client_debug\mysqld.exe C:\mysql\bin\mysqld-debug.ex
-e
-C:\workdir> xcopy scripts\*.* C:\mysql\scripts /E
-C:\workdir> xcopy share\*.* C:\mysql\share /E
- If you want to compile other clients and link them to MySQL,
- you should also copy several libraries and header files:
-C:\workdir> copy lib_debug\mysqlclient.lib C:\mysql\lib\debug
-C:\workdir> copy lib_debug\libmysql.* C:\mysql\lib\debug
-C:\workdir> copy lib_debug\zlib.* C:\mysql\lib\debug
-C:\workdir> copy lib_release\mysqlclient.lib C:\mysql\lib\opt
-C:\workdir> copy lib_release\libmysql.* C:\mysql\lib\opt
-C:\workdir> copy lib_release\zlib.* C:\mysql\lib\opt
-C:\workdir> copy include\*.h C:\mysql\include
-C:\workdir> copy libmysql\libmysql.def C:\mysql\include
- If you want to benchmark MySQL, you should also do this:
-C:\workdir> xcopy sql-bench\*.* C:\mysql\bench /E
-
- After installation, set up and start the server in the same way as
- for binary Windows distributions. See Section 2.3, "Installing
- MySQL on Windows."
-
-2.10.7. Compiling MySQL Clients on Windows
-
- In your source files, you should include my_global.h before
- mysql.h:
-#include <my_global.h>
-#include <mysql.h>
-
- my_global.h includes any other files needed for Windows
- compatibility (such as windows.h) if you compile your program on
- Windows.
-
- You can either link your code with the dynamic libmysql.lib
- library, which is just a wrapper to load in libmysql.dll on
- demand, or link with the static mysqlclient.lib library.
-
- The MySQL client libraries are compiled as threaded libraries, so
- you should also compile your code to be multi-threaded.
-
-2.11. Post-Installation Setup and Testing
-
- After installing MySQL, there are some issues that you should
- address. For example, on Unix, you should initialize the data
- directory and create the MySQL grant tables. On all platforms, an
- important security concern is that the initial accounts in the
- grant tables have no passwords. You should assign passwords to
- prevent unauthorized access to the MySQL server. Optionally, you
- can create time zone tables to enable recognition of named time
- zones.
-
- The following sections include post-installation procedures that
- are specific to Windows systems and to Unix systems. Another
- section, Section 2.11.2.3, "Starting and Troubleshooting the MySQL
- Server," applies to all platforms; it describes what to do if you
- have trouble getting the server to start. Section 2.11.3,
- "Securing the Initial MySQL Accounts," also applies to all
- platforms. You should follow its instructions to make sure that
- you have properly protected your MySQL accounts by assigning
- passwords to them.
-
- When you are ready to create additional user accounts, you can
- find information on the MySQL access control system and account
- management in Section 5.4, "The MySQL Access Privilege System,"
- and Section 5.5, "MySQL User Account Management."
-
-2.11.1. Windows Post-Installation Procedures
-
- On Windows, the data directory and the grant tables do not have to
- be created. MySQL Windows distributions include the grant tables
- with a set of preinitialized accounts in the mysql database under
- the data directory. It is unnecessary to run the mysql_install_db
- script that is used on Unix. Regarding passwords, if you installed
- MySQL using the Windows Installation Wizard, you may have already
- assigned passwords to the accounts. (See Section 2.3.3, "Using the
- MySQL Installation Wizard.") Otherwise, use the
- password-assignment procedure given in Section 2.11.3, "Securing
- the Initial MySQL Accounts."
-
- Before setting up passwords, you might want to try running some
- client programs to make sure that you can connect to the server
- and that it is operating properly. Make sure that the server is
- running (see Section 2.3.9, "Starting the Server for the First
- Time"), and then issue the following commands to verify that you
- can retrieve information from the server. The output should be
- similar to what is shown here:
-C:\> C:\mysql\bin\mysqlshow
-+--------------------+
-| Databases |
-+--------------------+
-| information_schema |
-| mysql |
-| test |
-+--------------------+
-
-C:\> C:\mysql\bin\mysqlshow mysql
-Database: mysql
-+---------------------------+
-| Tables |
-+---------------------------+
-| columns_priv |
-| db |
-| event |
-| func |
-| general_log |
-| help_category |
-| help_keyword |
-| help_relation |
-| help_topic |
-| host |
-| plugin |
-| proc |
-| procs_priv |
-| servers |
-| slow_log |
-| tables_priv |
-| time_zone |
-| time_zone_leap_second |
-| time_zone_name |
-| time_zone_transition |
-| time_zone_transition_type |
-| user |
-+---------------------------+
-
-
-C:\> C:\mysql\bin\mysql -e "SELECT Host,Db,User FROM db" mysql
-+------+-------+------+
-| host | db | user |
-+------+-------+------+
-| % | test% | |
-+------+-------+------+
-
- You may need to specify a different directory from the one shown;
- if you used the Windows Installation Wizard, then the default
- directory is C:\Program Files\MySQL\MySQL Server 5.1, and the
- mysql and mysqlshow client programs are in C:\Program
- Files\MySQL\MySQL Server 5.1\bin. See Section 2.3.3, "Using the
- MySQL Installation Wizard," for more information.
-
- If you have already secured the initial MySQL accounts, you may
- need to use the -u and -p options to supply a user name and
- password to the mysqlshow and mysql client programs; otherwise the
- programs may fail with an error, or you may not be able to view
- all databases. For example, if you have assigned the password
- "secretpass" to the MySQL root account, then you can invoke
- mysqlshow and mysql as shown here:
-C:\> C:\mysql\bin\mysqlshow -uroot -psecretpass
-+--------------------+
-| Databases |
-+--------------------+
-| information_schema |
-| mysql |
-| test |
-+--------------------+
-
-C:\> C:\mysql\bin\mysqlshow -uroot -psecretpass mysql
-Database: mysql
-+---------------------------+
-| Tables |
-+---------------------------+
-| columns_priv |
-| db |
-| event |
-| func |
-| general_log |
-| help_category |
-| help_keyword |
-| help_relation |
-| help_topic |
-| host |
-| plugin |
-| proc |
-| procs_priv |
-| servers |
-| slow_log |
-| tables_priv |
-| time_zone |
-| time_zone_leap_second |
-| time_zone_name |
-| time_zone_transition |
-| time_zone_transition_type |
-| user |
-+---------------------------+
-
-
-C:\> C:\mysql\bin\mysql -uroot -psecretpass -e "SELECT Host,Db,User F
-ROM db" mysql
-+------+-------+------+
-| host | db | user |
-+------+-------+------+
-| % | test% | |
-+------+-------+------+
-
- For more information about these programs, see Section 4.5.6,
- "mysqlshow --- Display Database, Table, and Column Information,"
- and Section 4.5.1, "mysql --- The MySQL Command-Line Tool."
-
- If you are running a version of Windows that supports services and
- you want the MySQL server to run automatically when Windows
- starts, see Section 2.3.11, "Starting MySQL as a Windows Service."
-
-2.11.2. Unix Post-Installation Procedures
-
- After installing MySQL on Unix, you need to initialize the grant
- tables, start the server, and make sure that the server works
- satisfactorily. You may also wish to arrange for the server to be
- started and stopped automatically when your system starts and
- stops. You should also assign passwords to the accounts in the
- grant tables.
-
- On Unix, the grant tables are set up by the mysql_install_db
- program. For some installation methods, this program is run for
- you automatically:
-
- * If you install MySQL on Linux using RPM distributions, the
- server RPM runs mysql_install_db.
-
- * If you install MySQL on Mac OS X using a PKG distribution, the
- installer runs mysql_install_db.
-
- Otherwise, you'll need to run mysql_install_db yourself.
-
- The following procedure describes how to initialize the grant
- tables (if that has not previously been done) and then start the
- server. It also suggests some commands that you can use to test
- whether the server is accessible and working properly. For
- information about starting and stopping the server automatically,
- see Section 2.11.2.2, "Starting and Stopping MySQL Automatically."
-
- After you complete the procedure and have the server running, you
- should assign passwords to the accounts created by
- mysql_install_db. Instructions for doing so are given in Section
- 2.11.3, "Securing the Initial MySQL Accounts."
-
- In the examples shown here, the server runs under the user ID of
- the mysql login account. This assumes that such an account exists.
- Either create the account if it does not exist, or substitute the
- name of a different existing login account that you plan to use
- for running the server.
-
- 1. Change location into the top-level directory of your MySQL
- installation, represented here by BASEDIR:
-shell> cd BASEDIR
- BASEDIR is likely to be something like /usr/local/mysql or
- /usr/local. The following steps assume that you are located in
- this directory.
-
- 2. If necessary, run the mysql_install_db program to set up the
- initial MySQL grant tables containing the privileges that
- determine how users are allowed to connect to the server.
- You'll need to do this if you used a distribution type for
- which the installation procedure doesn't run the program for
- you.
- Typically, mysql_install_db needs to be run only the first
- time you install MySQL, so you can skip this step if you are
- upgrading an existing installation, However, mysql_install_db
- does not overwrite any existing privilege tables, so it should
- be safe to run in any circumstances.
- To initialize the grant tables, use one of the following
- commands, depending on whether mysql_install_db is located in
- the bin or scripts directory:
-shell> bin/mysql_install_db --user=mysql
-shell> scripts/mysql_install_db --user=mysql
- It might be necessary to specify other options such as
- --basedir or --datadir if mysql_install_db does not use the
- correct locations for the installation directory or data
- directory. For example:
-shell> bin/mysql_install_db --user=mysql \
- --basedir=/opt/mysql/mysql \
- --datadir=/opt/mysql/mysql/data
- The mysql_install_db script creates the server's data
- directory. Under the data directory, it creates directories
- for the mysql database that holds all database privileges and
- the test database that you can use to test MySQL. The script
- also creates privilege table entries for root and
- anonymous-user accounts. The accounts have no passwords
- initially. A description of their initial privileges is given
- in Section 2.11.3, "Securing the Initial MySQL Accounts."
- Briefly, these privileges allow the MySQL root user to do
- anything, and allow anybody to create or use databases with a
- name of test or starting with test_.
- It is important to make sure that the database directories and
- files are owned by the mysql login account so that the server
- has read and write access to them when you run it later. To
- ensure this, the --user option should be used as shown if you
- run mysql_install_db as root. Otherwise, you should execute
- the script while logged in as mysql, in which case you can
- omit the --user option from the command.
- mysql_install_db creates several tables in the mysql database,
- including user, db, host, tables_priv, columns_priv, func, and
- others. See Section 5.4, "The MySQL Access Privilege System,"
- for a complete listing and description of these tables.
- If you don't want to have the test database, you can remove it
- with mysqladmin -u root drop test after starting the server.
- If you have trouble with mysql_install_db at this point, see
- Section 2.11.2.1, "Problems Running mysql_install_db."
-
- 3. Start the MySQL server:
-shell> bin/mysqld_safe --user=mysql &
- It is important that the MySQL server be run using an
- unprivileged (non-root) login account. To ensure this, the
- --user option should be used as shown if you run mysqld_safe
- as system root. Otherwise, you should execute the script while
- logged in to the system as mysql, in which case you can omit
- the --user option from the command.
- Further instructions for running MySQL as an unprivileged user
- are given in Section 5.3.5, "How to Run MySQL as a Normal
- User."
- If you neglected to create the grant tables before proceeding
- to this step, the following message appears in the error log
- file when you start the server:
-mysqld: Can't find file: 'host.frm'
- If you have other problems starting the server, see Section
- 2.11.2.3, "Starting and Troubleshooting the MySQL Server."
-
- 4. Use mysqladmin to verify that the server is running. The
- following commands provide simple tests to check whether the
- server is up and responding to connections:
-shell> bin/mysqladmin version
-shell> bin/mysqladmin variables
- The output from mysqladmin version varies slightly depending
- on your platform and version of MySQL, but should be similar
- to that shown here:
-shell> bin/mysqladmin version
-mysqladmin Ver 14.12 Distrib 5.1.39, for pc-linux-gnu on i686
-...
-
-Server version 5.1.39
-Protocol version 10
-Connection Localhost via UNIX socket
-UNIX socket /var/lib/mysql/mysql.sock
-Uptime: 14 days 5 hours 5 min 21 sec
-
-Threads: 1 Questions: 366 Slow queries: 0
-Opens: 0 Flush tables: 1 Open tables: 19
-Queries per second avg: 0.000
- To see what else you can do with mysqladmin, invoke it with
- the --help option.
-
- 5. Verify that you can shut down the server:
-shell> bin/mysqladmin -u root shutdown
-
- 6. Verify that you can start the server again. Do this by using
- mysqld_safe or by invoking mysqld directly. For example:
-shell> bin/mysqld_safe --user=mysql --log &
- If mysqld_safe fails, see Section 2.11.2.3, "Starting and
- Troubleshooting the MySQL Server."
-
- 7. Run some simple tests to verify that you can retrieve
- information from the server. The output should be similar to
- what is shown here:
-shell> bin/mysqlshow
-+-----------+
-| Databases |
-+-----------+
-| mysql |
-| test |
-+-----------+
-
-shell> bin/mysqlshow mysql
-Database: mysql
-+---------------------------+
-| Tables |
-+---------------------------+
-| columns_priv |
-| db |
-| func |
-| help_category |
-| help_keyword |
-| help_relation |
-| help_topic |
-| host |
-| proc |
-| procs_priv |
-| tables_priv |
-| time_zone |
-| time_zone_leap_second |
-| time_zone_name |
-| time_zone_transition |
-| time_zone_transition_type |
-| user |
-+---------------------------+
-
-shell> bin/mysql -e "SELECT Host,Db,User FROM db" mysql
-+------+--------+------+
-| host | db | user |
-+------+--------+------+
-| % | test | |
-| % | test_% | |
-+------+--------+------+
-
- 8. There is a benchmark suite in the sql-bench directory (under
- the MySQL installation directory) that you can use to compare
- how MySQL performs on different platforms. The benchmark suite
- is written in Perl. It requires the Perl DBI module that
- provides a database-independent interface to the various
- databases, and some other additional Perl modules:
-DBI
-DBD::mysql
-Data::Dumper
-Data::ShowTable
- These modules can be obtained from CPAN
- (http://www.cpan.org/). See also Section 2.15.1, "Installing
- Perl on Unix."
- The sql-bench/Results directory contains the results from many
- runs against different databases and platforms. To run all
- tests, execute these commands:
-shell> cd sql-bench
-shell> perl run-all-tests
- If you don't have the sql-bench directory, you probably
- installed MySQL using RPM files other than the source RPM.
- (The source RPM includes the sql-bench benchmark directory.)
- In this case, you must first install the benchmark suite
- before you can use it. There are separate benchmark RPM files
- named mysql-bench-VERSION.i386.rpm that contain benchmark code
- and data.
- If you have a source distribution, there are also tests in its
- tests subdirectory that you can run. For example, to run
- auto_increment.tst, execute this command from the top-level
- directory of your source distribution:
-shell> mysql -vvf test < ./tests/auto_increment.tst
- The expected result of the test can be found in the
- ./tests/auto_increment.res file.
-
- 9. At this point, you should have the server running. However,
- none of the initial MySQL accounts have a password, so you
- should assign passwords using the instructions found in
- Section 2.11.3, "Securing the Initial MySQL Accounts."
-
- The MySQL 5.1 installation procedure creates time zone tables in
- the mysql database. However, you must populate the tables manually
- using the instructions in Section 9.7, "MySQL Server Time Zone
- Support."
-
-2.11.2.1. Problems Running mysql_install_db
-
- The purpose of the mysql_install_db script is to generate new
- MySQL privilege tables. It does not overwrite existing MySQL
- privilege tables, and it does not affect any other data.
-
- If you want to re-create your privilege tables, first stop the
- mysqld server if it is running. Then rename the mysql directory
- under the data directory to save it, and then run
- mysql_install_db. Suppose that your current directory is the MySQL
- installation directory and that mysql_install_db is located in the
- bin directory and the data directory is named data. To rename the
- mysql database and re-run mysql_install_db, use these commands.
-shell> mv data/mysql data/mysql.old
-shell> bin/mysql_install_db --user=mysql
-
- When you run mysql_install_db, you might encounter the following
- problems:
-
- * mysql_install_db fails to install the grant tables
- You may find that mysql_install_db fails to install the grant
- tables and terminates after displaying the following messages:
-Starting mysqld daemon with databases from XXXXXX
-mysqld ended
- In this case, you should examine the error log file very
- carefully. The log should be located in the directory XXXXXX
- named by the error message and should indicate why mysqld
- didn't start. If you do not understand what happened, include
- the log when you post a bug report. See Section 1.6, "How to
- Report Bugs or Problems."
-
- * There is a mysqld process running
- This indicates that the server is running, in which case the
- grant tables have probably been created already. If so, there
- is no need to run mysql_install_db at all because it needs to
- be run only once (when you install MySQL the first time).
-
- * Installing a second mysqld server does not work when one
- server is running
- This can happen when you have an existing MySQL installation,
- but want to put a new installation in a different location.
- For example, you might have a production installation, but you
- want to create a second installation for testing purposes.
- Generally the problem that occurs when you try to run a second
- server is that it tries to use a network interface that is in
- use by the first server. In this case, you should see one of
- the following error messages:
-Can't start server: Bind on TCP/IP port:
-Address already in use
-Can't start server: Bind on unix socket...
- For instructions on setting up multiple servers, see Section
- 5.6, "Running Multiple MySQL Servers on the Same Machine."
-
- * You do not have write access to the /tmp directory
- If you do not have write access to create temporary files or a
- Unix socket file in the default location (the /tmp directory),
- an error occurs when you run mysql_install_db or the mysqld
- server.
- You can specify different locations for the temporary
- directory and Unix socket file by executing these commands
- prior to starting mysql_install_db or mysqld, where
- some_tmp_dir is the full path name to some directory for which
- you have write permission:
-shell> TMPDIR=/some_tmp_dir/
-shell> MYSQL_UNIX_PORT=/some_tmp_dir/mysql.sock
-shell> export TMPDIR MYSQL_UNIX_PORT
- Then you should be able to run mysql_install_db and start the
- server with these commands:
-shell> bin/mysql_install_db --user=mysql
-shell> bin/mysqld_safe --user=mysql &
- If mysql_install_db is located in the scripts directory,
- modify the first command to scripts/mysql_install_db.
- See Section B.1.4.5, "How to Protect or Change the MySQL Unix
- Socket File," and Section 2.14, "Environment Variables."
-
- There are some alternatives to running the mysql_install_db script
- provided in the MySQL distribution:
-
- * If you want the initial privileges to be different from the
- standard defaults, you can modify mysql_install_db before you
- run it. However, it is preferable to use GRANT and REVOKE to
- change the privileges after the grant tables have been set up.
- In other words, you can run mysql_install_db, and then use
- mysql -u root mysql to connect to the server as the MySQL root
- user so that you can issue the necessary GRANT and REVOKE
- statements.
- If you want to install MySQL on several machines with the same
- privileges, you can put the GRANT and REVOKE statements in a
- file and execute the file as a script using mysql after
- running mysql_install_db. For example:
-shell> bin/mysql_install_db --user=mysql
-shell> bin/mysql -u root < your_script_file
- By doing this, you can avoid having to issue the statements
- manually on each machine.
-
- * It is possible to re-create the grant tables completely after
- they have previously been created. You might want to do this
- if you're just learning how to use GRANT and REVOKE and have
- made so many modifications after running mysql_install_db that
- you want to wipe out the tables and start over.
- To re-create the grant tables, remove all the .frm, .MYI, and
- .MYD files in the mysql database directory. Then run the
- mysql_install_db script again.
-
- * You can start mysqld manually using the --skip-grant-tables
- option and add the privilege information yourself using mysql:
-shell> bin/mysqld_safe --user=mysql --skip-grant-tables &
-shell> bin/mysql mysql
- From mysql, manually execute the SQL commands contained in
- mysql_install_db. Make sure that you run mysqladmin
- flush-privileges or mysqladmin reload afterward to tell the
- server to reload the grant tables.
- Note that by not using mysql_install_db, you not only have to
- populate the grant tables manually, you also have to create
- them first.
-
-2.11.2.2. Starting and Stopping MySQL Automatically
-
- Generally, you start the mysqld server in one of these ways:
-
- * Invoke mysqld directly. This works on any platform.
-
- * Run the MySQL server as a Windows service. The service can be
- set to start the server automatically when Windows starts, or
- as a manual service that you start on request. For
- instructions, see Section 2.3.11, "Starting MySQL as a Windows
- Service."
-
- * Invoke mysqld_safe, which tries to determine the proper
- options for mysqld and then runs it with those options. This
- script is used on Unix and Unix-like systems. See Section
- 4.3.2, "mysqld_safe --- MySQL Server Startup Script."
-
- * Invoke mysql.server. This script is used primarily at system
- startup and shutdown on systems that use System V-style run
- directories, where it usually is installed under the name
- mysql. The mysql.server script starts the server by invoking
- mysqld_safe. See Section 4.3.3, "mysql.server --- MySQL Server
- Startup Script."
-
- * On Mac OS X, install a separate MySQL Startup Item package to
- enable the automatic startup of MySQL on system startup. The
- Startup Item starts the server by invoking mysql.server. See
- Section 2.5, "Installing MySQL on Mac OS X," for details.
-
- The mysqld_safe and mysql.server scripts and the Mac OS X Startup
- Item can be used to start the server manually, or automatically at
- system startup time. mysql.server and the Startup Item also can be
- used to stop the server.
-
- To start or stop the server manually using the mysql.server
- script, invoke it with start or stop arguments:
-shell> mysql.server start
-shell> mysql.server stop
-
- Before mysql.server starts the server, it changes location to the
- MySQL installation directory, and then invokes mysqld_safe. If you
- want the server to run as some specific user, add an appropriate
- user option to the [mysqld] group of the /etc/my.cnf option file,
- as shown later in this section. (It is possible that you will need
- to edit mysql.server if you've installed a binary distribution of
- MySQL in a nonstandard location. Modify it to change location into
- the proper directory before it runs mysqld_safe. If you do this,
- your modified version of mysql.server may be overwritten if you
- upgrade MySQL in the future, so you should make a copy of your
- edited version that you can reinstall.)
-
- mysql.server stop stops the server by sending a signal to it. You
- can also stop the server manually by executing mysqladmin
- shutdown.
-
- To start and stop MySQL automatically on your server, you need to
- add start and stop commands to the appropriate places in your
- /etc/rc* files.
-
- If you use the Linux server RPM package
- (MySQL-server-VERSION.rpm), the mysql.server script is installed
- in the /etc/init.d directory with the name mysql. You need not
- install it manually. See Section 2.4, "Installing MySQL from RPM
- Packages on Linux," for more information on the Linux RPM
- packages.
-
- Some vendors provide RPM packages that install a startup script
- under a different name such as mysqld.
-
- If you install MySQL from a source distribution or using a binary
- distribution format that does not install mysql.server
- automatically, you can install it manually. The script can be
- found in the support-files directory under the MySQL installation
- directory or in a MySQL source tree.
-
- To install mysql.server manually, copy it to the /etc/init.d
- directory with the name mysql, and then make it executable. Do
- this by changing location into the appropriate directory where
- mysql.server is located and executing these commands:
-shell> cp mysql.server /etc/init.d/mysql
-shell> chmod +x /etc/init.d/mysql
-
- Older Red Hat systems use the /etc/rc.d/init.d directory rather
- than /etc/init.d. Adjust the preceding commands accordingly.
- Alternatively, first create /etc/init.d as a symbolic link that
- points to /etc/rc.d/init.d:
-shell> cd /etc
-shell> ln -s rc.d/init.d .
-
- After installing the script, the commands needed to activate it to
- run at system startup depend on your operating system. On Linux,
- you can use chkconfig:
-shell> chkconfig --add mysql
-
- On some Linux systems, the following command also seems to be
- necessary to fully enable the mysql script:
-shell> chkconfig --level 345 mysql on
-
- On FreeBSD, startup scripts generally should go in
- /usr/local/etc/rc.d/. The rc(8) manual page states that scripts in
- this directory are executed only if their basename matches the
- *.sh shell file name pattern. Any other files or directories
- present within the directory are silently ignored. In other words,
- on FreeBSD, you should install the mysql.server script as
- /usr/local/etc/rc.d/mysql.server.sh to enable automatic startup.
-
- As an alternative to the preceding setup, some operating systems
- also use /etc/rc.local or /etc/init.d/boot.local to start
- additional services on startup. To start up MySQL using this
- method, you could append a command like the one following to the
- appropriate startup file:
-/bin/sh -c 'cd /usr/local/mysql; ./bin/mysqld_safe --user=mysql &'
-
- For other systems, consult your operating system documentation to
- see how to install startup scripts.
-
- You can add options for mysql.server in a global /etc/my.cnf file.
- A typical /etc/my.cnf file might look like this:
-[mysqld]
-datadir=/usr/local/mysql/var
-socket=/var/tmp/mysql.sock
-port=3306
-user=mysql
-
-[mysql.server]
-basedir=/usr/local/mysql
-
- The mysql.server script supports the following options: basedir,
- datadir, and pid-file. If specified, they must be placed in an
- option file, not on the command line. mysql.server supports only
- start and stop as command-line arguments.
-
- The following table shows which option groups the server and each
- startup script read from option files.
- Script Option Groups
- mysqld [mysqld], [server], [mysqld-major_version]
- mysqld_safe [mysqld], [server], [mysqld_safe]
- mysql.server [mysqld], [mysql.server], [server]
-
- [mysqld-major_version] means that groups with names like
- [mysqld-5.0] and [mysqld-5.1] are read by servers having versions
- 5.0.x, 5.1.x, and so forth. This feature can be used to specify
- options that can be read only by servers within a given release
- series.
-
- For backward compatibility, mysql.server also reads the
- [mysql_server] group and mysqld_safe also reads the [safe_mysqld]
- group. However, you should update your option files to use the
- [mysql.server] and [mysqld_safe] groups instead when using MySQL
- 5.1.
-
- See Section 4.2.3.3, "Using Option Files."
-
-2.11.2.3. Starting and Troubleshooting the MySQL Server
-
- This section provides troubleshooting suggestions for problems
- starting the server on Unix. If you are using Windows, see Section
- 2.3.13, "Troubleshooting a MySQL Installation Under Windows."
-
- If you have problems starting the server, here are some things to
- try:
-
- * Check the error log to see why the server does not start.
-
- * Specify any special options needed by the storage engines you
- are using.
-
- * Make sure that the server knows where to find the data
- directory.
-
- * Make sure that the server can access the data directory. The
- ownership and permissions of the data directory and its
- contents must be set such that the server can read and modify
- them.
-
- * Verify that the network interfaces the server wants to use are
- available.
-
- Some storage engines have options that control their behavior. You
- can create a my.cnf file and specify startup options for the
- engines that you plan to use. If you are going to use storage
- engines that support transactional tables (InnoDB, NDB), be sure
- that you have them configured the way you want before starting the
- server:
-
- * If you are using InnoDB tables, see Section 13.6.2, "InnoDB
- Configuration."
-
- * If you are using MySQL Cluster, see Section 17.3, "MySQL
- Cluster Configuration."
-
- MySQL Enterprise For expert advice on start-up options appropriate
- to your circumstances, subscribe to The MySQL Enterprise Monitor.
- For more information, see
- http://www.mysql.com/products/enterprise/advisors.html.
-
- Storage engines will use default option values if you specify
- none, but it is recommended that you review the available options
- and specify explicit values for those for which the defaults are
- not appropriate for your installation.
-
- When the mysqld server starts, it changes location to the data
- directory. This is where it expects to find databases and where it
- expects to write log files. The server also writes the pid
- (process ID) file in the data directory.
-
- The data directory location is hardwired in when the server is
- compiled. This is where the server looks for the data directory by
- default. If the data directory is located somewhere else on your
- system, the server will not work properly. You can determine what
- the default path settings are by invoking mysqld with the
- --verbose and --help options.
-
- If the default locations don't match the MySQL installation layout
- on your system, you can override them by specifying options to
- mysqld or mysqld_safe on the command line or in an option file.
-
- To specify the location of the data directory explicitly, use the
- --datadir option. However, normally you can tell mysqld the
- location of the base directory under which MySQL is installed and
- it looks for the data directory there. You can do this with the
- --basedir option.
-
- To check the effect of specifying path options, invoke mysqld with
- those options followed by the --verbose and --help options. For
- example, if you change location into the directory where mysqld is
- installed and then run the following command, it shows the effect
- of starting the server with a base directory of /usr/local:
-shell> ./mysqld --basedir=/usr/local --verbose --help
-
- You can specify other options such as --datadir as well, but
- --verbose and --help must be the last options.
-
- Once you determine the path settings you want, start the server
- without --verbose and --help.
-
- If mysqld is currently running, you can find out what path
- settings it is using by executing this command:
-shell> mysqladmin variables
-
- Or:
-shell> mysqladmin -h host_name variables
-
- host_name is the name of the MySQL server host.
-
- If you get Errcode 13 (which means Permission denied) when
- starting mysqld, this means that the privileges of the data
- directory or its contents do not allow the server access. In this
- case, you change the permissions for the involved files and
- directories so that the server has the right to use them. You can
- also start the server as root, but this raises security issues and
- should be avoided.
-
- On Unix, change location into the data directory and check the
- ownership of the data directory and its contents to make sure the
- server has access. For example, if the data directory is
- /usr/local/mysql/var, use this command:
-shell> ls -la /usr/local/mysql/var
-
- If the data directory or its files or subdirectories are not owned
- by the login account that you use for running the server, change
- their ownership to that account. If the account is named mysql,
- use these commands:
-shell> chown -R mysql /usr/local/mysql/var
-shell> chgrp -R mysql /usr/local/mysql/var
-
- If the server fails to start up correctly, check the error log.
- Log files are located in the data directory (typically C:\Program
- Files\MySQL\MySQL Server 5.1\data on Windows,
- /usr/local/mysql/data for a Unix binary distribution, and
- /usr/local/var for a Unix source distribution). Look in the data
- directory for files with names of the form host_name.err and
- host_name.log, where host_name is the name of your server host.
- Then examine the last few lines of these files. On Unix, you can
- use tail to display them:
-shell> tail host_name.err
-shell> tail host_name.log
-
- The error log should contain information that indicates why the
- server couldn't start.
-
- If either of the following errors occur, it means that some other
- program (perhaps another mysqld server) is using the TCP/IP port
- or Unix socket file that mysqld is trying to use:
-Can't start server: Bind on TCP/IP port: Address already in use
-Can't start server: Bind on unix socket...
-
- Use ps to determine whether you have another mysqld server
- running. If so, shut down the server before starting mysqld again.
- (If another server is running, and you really want to run multiple
- servers, you can find information about how to do so in Section
- 5.6, "Running Multiple MySQL Servers on the Same Machine.")
-
- If no other server is running, try to execute the command telnet
- your_host_name tcp_ip_port_number. (The default MySQL port number
- is 3306.) Then press Enter a couple of times. If you don't get an
- error message like telnet: Unable to connect to remote host:
- Connection refused, some other program is using the TCP/IP port
- that mysqld is trying to use. You'll need to track down what
- program this is and disable it, or else tell mysqld to listen to a
- different port with the --port option. In this case, you'll also
- need to specify the port number for client programs when
- connecting to the server via TCP/IP.
-
- Another reason the port might be inaccessible is that you have a
- firewall running that blocks connections to it. If so, modify the
- firewall settings to allow access to the port.
-
- If the server starts but you can't connect to it, you should make
- sure that you have an entry in /etc/hosts that looks like this:
-127.0.0.1 localhost
-
- This problem occurs only on systems that do not have a working
- thread library and for which MySQL must be configured to use
- MIT-pthreads.
-
- If you cannot get mysqld to start, you can try to make a trace
- file to find the problem by using the --debug option. See MySQL
- Internals: Porting
- (http://forge.mysql.com/wiki/MySQL_Internals_Porting).
-
-2.11.3. Securing the Initial MySQL Accounts
-
- Part of the MySQL installation process is to set up the mysql
- database that contains the grant tables:
-
- * Windows distributions contain preinitialized grant tables that
- are installed automatically.
-
- * On Unix, the grant tables are populated by the
- mysql_install_db program. Some installation methods run this
- program for you. Others require that you execute it manually.
- For details, see Section 2.11.2, "Unix Post-Installation
- Procedures."
-
- The grant tables define the initial MySQL user accounts and their
- access privileges. These accounts are set up as follows:
-
- * Accounts with the user name root are created. These are
- superuser accounts that can do anything. The initial root
- account passwords are empty, so anyone can connect to the
- MySQL server as root --- without a password --- and be granted
- all privileges.
-
- + On Windows, one root account is created; this account
- allows connecting from the local host only. The Windows
- installer will optionally create an account allowing for
- connections from any host only if the user selects the
- Enable root access from remote machines option during
- installation.
-
- + On Unix, both root accounts are for connections from the
- local host. Connections must be made from the local host
- by specifying a host name of localhost for one of the
- accounts, or the actual host name or IP number for the
- other.
-
- * Two anonymous-user accounts are created, each with an empty
- user name. The anonymous accounts have no password, so anyone
- can use them to connect to the MySQL server.
-
- + On Windows, one anonymous account is for connections from
- the local host. It has no global privileges. (Before
- MySQL 5.1.16, it has all global privileges, just like the
- root accounts.) The other is for connections from any
- host and has all privileges for the test database and for
- other databases with names that start with test.
-
- + On Unix, both anonymous accounts are for connections from
- the local host. Connections must be made from the local
- host by specifying a host name of localhost for one of
- the accounts, or the actual host name or IP number for
- the other. These accounts have all privileges for the
- test database and for other databases with names that
- start with test_.
-
- As noted, none of the initial accounts have passwords. This means
- that your MySQL installation is unprotected until you do something
- about it:
-
- * If you want to prevent clients from connecting as anonymous
- users without a password, you should either assign a password
- to each anonymous account or else remove the accounts.
-
- * You should assign a password to each MySQL root account.
-
- The following instructions describe how to set up passwords for
- the initial MySQL accounts, first for the anonymous accounts and
- then for the root accounts. Replace "newpwd" in the examples with
- the actual password that you want to use. The instructions also
- cover how to remove the anonymous accounts, should you prefer not
- to allow anonymous access at all.
-
- You might want to defer setting the passwords until later, so that
- you don't need to specify them while you perform additional setup
- or testing. However, be sure to set them before using your
- installation for production purposes.
-
- Anonymous Account Password Assignment
-
- To assign passwords to the anonymous accounts, connect to the
- server as root and then use either SET PASSWORD or UPDATE. In
- either case, be sure to encrypt the password using the PASSWORD()
- function.
-
- To use SET PASSWORD on Windows, do this:
-shell> mysql -u root
-mysql> SET PASSWORD FOR ''@'localhost' = PASSWORD('newpwd');
-mysql> SET PASSWORD FOR ''@'%' = PASSWORD('newpwd');
-
- To use SET PASSWORD on Unix, do this:
-shell> mysql -u root
-mysql> SET PASSWORD FOR ''@'localhost' = PASSWORD('newpwd');
-mysql> SET PASSWORD FOR ''@'host_name' = PASSWORD('newpwd');
-
- In the second SET PASSWORD statement, replace host_name with the
- name of the server host. This is the name that is specified in the
- Host column of the non-localhost record for root in the user
- table. If you don't know what host name this is, issue the
- following statement before using SET PASSWORD:
-mysql> SELECT Host, User FROM mysql.user;
-
- Look for the record that has root in the User column and something
- other than localhost in the Host column. Then use that Host value
- in the second SET PASSWORD statement.
-
- Anonymous Account Removal
-
- If you prefer to remove the anonymous accounts instead, do so as
- follows:
-shell> mysql -u root
-mysql> DROP USER '';
-
- The DROP statement applies both to Windows and to Unix. On
- Windows, if you want to remove only the anonymous account that has
- the same privileges as root, do this instead:
-shell> mysql -u root
-mysql> DROP USER ''@'localhost';
-
- That account allows anonymous access but has full privileges, so
- removing it improves security.
-
- root Account Password Assignment
-
- You can assign passwords to the root accounts in several ways. The
- following discussion demonstrates three methods:
-
- * Use the SET PASSWORD statement
-
- * Use the mysqladmin command-line client program
-
- * Use the UPDATE statement
-
- To assign passwords using SET PASSWORD, connect to the server as
- root and issue SET PASSWORD statements. Be sure to encrypt the
- password using the PASSWORD() function.
-
- For Windows, do this:
-shell> mysql -u root
-mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpwd');
-mysql> SET PASSWORD FOR 'root'@'%' = PASSWORD('newpwd');
-
- For Unix, do this:
-shell> mysql -u root
-mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpwd');
-mysql> SET PASSWORD FOR 'root'@'host_name' = PASSWORD('newpwd');
-
- In the second SET PASSWORD statement, replace host_name with the
- name of the server host. This is the same host name that you used
- when you assigned the anonymous account passwords.
-
- If the user table contains an account with User and Host values of
- 'root' and '127.0.0.1', use an additional SET PASSWORD statement
- to set that account's password:
-mysql> SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('newpwd');
-
- To assign passwords to the root accounts using mysqladmin, execute
- the following commands:
-shell> mysqladmin -u root password "newpwd"
-shell> mysqladmin -u root -h host_name password "newpwd"
-
- These commands apply both to Windows and to Unix. In the second
- command, replace host_name with the name of the server host. The
- double quotes around the password are not always necessary, but
- you should use them if the password contains spaces or other
- characters that are special to your command interpreter.
-
- The mysqladmin method of setting the root account passwords does
- not set the password for the 'root'@'127.0.0.1' account. To do so,
- use SET PASSWORD as shown earlier.
-
- You can also use UPDATE to modify the user table directly. The
- following UPDATE statement assigns a password to all root
- accounts:
-shell> mysql -u root
-mysql> UPDATE mysql.user SET Password = PASSWORD('newpwd')
- -> WHERE User = 'root';
-mysql> FLUSH PRIVILEGES;
-
- The UPDATE statement applies both to Windows and to Unix.
-
- After the passwords have been set, you must supply the appropriate
- password whenever you connect to the server. For example, if you
- want to use mysqladmin to shut down the server, you can do so
- using this command:
-shell> mysqladmin -u root -p shutdown
-Enter password: (enter root password here)
-
-Note
-
- If you forget your root password after setting it up, Section
- B.1.4.1, "How to Reset the Root Password," covers the procedure
- for resetting it.
-
- To set up additional accounts, you can use the GRANT statement.
- For instructions, see Section 5.5.2, "Adding User Accounts."
-
-2.12. Upgrading or Downgrading MySQL
-
-2.12.1. Upgrading MySQL
+2.4.1. Upgrading MySQL
As a general rule, to upgrade from one release series to another,
you should go to the next series rather than skipping a series. To
@@ -5825,14 +2079,22 @@ Note
MySQL 5.0, see the MySQL 5.0 Reference Manual; for earlier
releases, see the MySQL 3.23, 4.0, 4.1 Reference Manual.
+ If you perform a binary (in-place) upgrade without dumping and
+ reloading tables, you cannot upgrade directly from MySQL 4.1 to
+ 5.1. This occurs due to an incompatible change in the MyISAM table
+ index format in MySQL 5.0. Upgrade from MySQL 4.1 to 5.0 and
+ repair all MyISAM tables (see Section 2.4.4, "Rebuilding or
+ Repairing Tables or Indexes"). Then upgrade from MySQL 5.0 to 5.1
+ and check and repair your tables.
+
To upgrade from MySQL 5.0 to 5.1, use the items in the following
checklist as a guide:
* Before any upgrade, back up your databases, including the
mysql database that contains the grant tables. See Section
- 6.1, "Database Backups."
+ 6.1, "Database Backup Methods."
- * Read all the notes in Section 2.12.1.1, "Upgrading from MySQL
+ * Read all the notes in Section 2.4.1.1, "Upgrading from MySQL
5.0 to 5.1." These notes enable you to identify upgrade issues
that apply to your current MySQL installation. Some
incompatibilities discussed in that section require your
@@ -5852,8 +2114,8 @@ Note
MySQL introduce changes to the structure of the grant tables
to add new privileges or features.)
- * If you are running MySQL Server on Windows, see Section
- 2.3.14, "Upgrading MySQL on Windows."
+ * If you are running MySQL Server on Windows, see Section 2.5.7,
+ "Upgrading MySQL on Windows."
* If you are using replication, see Section 16.3.3, "Upgrading a
Replication Setup," for information on upgrading your
@@ -5926,7 +2188,7 @@ Note
applies to other MySQL interfaces as well, such as PHP mysql
extensions and the Python MySQLdb module.
-2.12.1.1. Upgrading from MySQL 5.0 to 5.1
+2.4.1.1. Upgrading from MySQL 5.0 to 5.1
After upgrading a 5.0 installation to 5.0.10 or above, it is
necessary to upgrade your grant tables. Otherwise, creating stored
@@ -5944,13 +2206,21 @@ Note
you dump your tables with mysqldump before upgrading and reload
the dump file after upgrading.
+ If you perform a binary (in-place) upgrade without dumping and
+ reloading tables, you cannot upgrade directly from MySQL 4.1 to
+ 5.1. This occurs due to an incompatible change in the MyISAM table
+ index format in MySQL 5.0. Upgrade from MySQL 4.1 to 5.0 and
+ repair all MyISAM tables (see Section 2.4.4, "Rebuilding or
+ Repairing Tables or Indexes"). Then upgrade from MySQL 5.0 to 5.1
+ and check and repair your tables.
+
In general, you should do the following when upgrading from MySQL
5.0 to 5.1:
* Read all the items in the following sections to see whether
any of them might affect your applications:
- + Section 2.12.1, "Upgrading MySQL," has general update
+ + Section 2.4.1, "Upgrading MySQL," has general update
information.
+ The items in the change lists found later in this section
@@ -5975,7 +2245,7 @@ Note
in the incompatibility description. Often this will involve a
dump and reload, or use of a statement such as CHECK TABLE or
REPAIR TABLE.
- For dump and reload instructions, see Section 2.12.4,
+ For dump and reload instructions, see Section 2.4.4,
"Rebuilding or Repairing Tables or Indexes." Any procedure
that involves REPAIR TABLE with the USE_FRM option must be
done before upgrading. Use of this statement with a version of
@@ -5992,15 +2262,17 @@ Note
MySQL introduce changes to the structure of the grant tables
to add new privileges or features.)
- * Check Section 2.12.3, "Checking Whether Table Indexes Must Be
- Rebuilt," to see whether changes to character sets or
- collations were made that affect your table indexes. If so,
- you will need to rebuild the affected indexes using the
- instructions in Section 2.12.4, "Rebuilding or Repairing
- Tables or Indexes."
+ * Check Section 2.4.3, "Checking Whether Tables or Indexes Must
+ Be Rebuilt," to see whether changes to table formats or to
+ character sets or collations were made between your current
+ version of MySQL and the version to which you are upgrading.
+ If so and these changes result in an incompatibility between
+ MySQL versions, you will need to upgrade the affected tables
+ using the instructions in Section 2.4.4, "Rebuilding or
+ Repairing Tables or Indexes."
- * If you are running MySQL Server on Windows, see Section
- 2.3.14, "Upgrading MySQL on Windows."
+ * If you are running MySQL Server on Windows, see Section 2.5.7,
+ "Upgrading MySQL on Windows."
* If you are using replication, see Section 16.3.3, "Upgrading a
Replication Setup," for information on upgrading your
@@ -6042,6 +2314,22 @@ Note
Server Changes:
+ * Known issue: After a binary upgrade to MySQL 5.1 from a MySQL
+ 5.0 installation that contains ARCHIVE tables, accessing those
+ tables will cause the server to crash, even if you have run
+ mysql_upgrade or CHECK TABLE ... FOR UPGRADE. To work around
+ this problem, use mysqldump to dump all ARCHIVE tables before
+ upgrading, and reload them into MySQL 5.1 after upgrading.
+
+ * Known issue: The fix for
+ Bug#23491: http://bugs.mysql.com/23491 introduced a problem
+ with SHOW CREATE VIEW, which is used by mysqldump. This causes
+ an incompatibility when upgrading from versions affected by
+ that bug fix (MySQL 5.0.40 through 5.0.43, MySQL 5.1.18
+ through 5.1.19): If you use mysqldump before upgrading from an
+ affected version and reload the data after upgrading to a
+ higher version, you must drop and recreate your views.
+
* Known issue: Dumps performed by using mysqldump to generate a
dump file before the upgrade and reloading the file after
upgrading are subject to the following problem:
@@ -6162,8 +2450,28 @@ RENAME TABLE table_b TO `table b`;
* Incompatible change: Character set or collation changes were
made in MySQL 5.1.21, 5.1.23, and 5.1.24 that may require
- table indexes to be rebuilt. For details, see Section 2.12.3,
- "Checking Whether Table Indexes Must Be Rebuilt."
+ table indexes to be rebuilt. For details, see Section 2.4.3,
+ "Checking Whether Tables or Indexes Must Be Rebuilt."
+
+ * Incompatible change: MySQL 5.1 implements support for a plugin
+ API that allows the loading and unloading of components at
+ runtime, without restarting the server. Section 22.2, "The
+ MySQL Plugin Interface." The plugin API requires the
+ mysql.plugin table. After upgrading from an older version of
+ MySQL, you should run the mysql_upgrade command to create this
+ table. See Section 4.4.8, "mysql_upgrade --- Check Tables for
+ MySQL Upgrade."
+ Plugins are installed in the directory named by the plugin_dir
+ system variable. This variable also controls the location from
+ which the server loads user-defined functions (UDFs), which is
+ a change from earlier versions of MySQL. That is, all UDF
+ library files now must be installed in the plugin directory.
+ When upgrading from an older version of MySQL, you must
+ migrate your UDF files to the plugin directory.
+
+ * Incompatible change: The table_cache system variable has been
+ renamed to table_open_cache. Any scripts that refer to
+ table_cache must be updated to use the new name.
* Incompatible change: In MySQL 5.1.36, options for loading
plugins such as pluggable storage engines were changed from
@@ -6262,26 +2570,6 @@ RENAME TABLE table_b TO `table b`;
information and workarounds, see Section D.4, "Restrictions on
Views."
- * Incompatible change: MySQL 5.1 implements support for a plugin
- API that allows the loading and unloading of components at
- runtime, without restarting the server. Section 22.2, "The
- MySQL Plugin Interface." The plugin API requires the
- mysql.plugin table. After upgrading from an older version of
- MySQL, you should run the mysql_upgrade command to create this
- table. See Section 4.4.8, "mysql_upgrade --- Check Tables for
- MySQL Upgrade."
- Plugins are installed in the directory named by the plugin_dir
- system variable. This variable also controls the location from
- which the server loads user-defined functions (UDFs), which is
- a change from earlier versions of MySQL. That is, all UDF
- library files now must be installed in the plugin directory.
- When upgrading from an older version of MySQL, you must
- migrate your UDF files to the plugin directory.
-
- * Incompatible change: The table_cache system variable has been
- renamed to table_open_cache. Any scripts that refer to
- table_cache must be updated to use the new name.
-
* Incompatible change: Several issues were identified for stored
programs (stored procedures and functions, triggers, and
events) and views containing non-ASCII symbols. These issues
@@ -6314,6 +2602,19 @@ RENAME TABLE table_b TO `table b`;
to 5.1.20. 2) Logging to syslog may fail to operate correctly
in some cases. For these reasons, avoid using MySQL 5.1.20.
+ * Incompatible change: As of MySQL 5.1.18, the plugin interface
+ and its handling of system variables was changed. Command-line
+ options such as --skip-innodb now cause an error if InnoDB is
+ not built-in or plugin-loaded. You should use
+ --loose-skip-innodb if you do not want any error even if
+ InnoDB is not available. The --loose prefix modifier should be
+ used for all command-line options where you are uncertain
+ whether the plugin exists and when you want the operation to
+ proceed even if the option is necessarily ignored due to the
+ absence of the plugin. (For a desecription of how --loose
+ works, see Section 4.2.3.1, "Using Options on the Command
+ Line.")
+
* Incompatible change: As of MySQL 5.1.15, InnoDB rolls back
only the last statement on a transaction timeout. A new
option, --innodb_rollback_on_timeout, causes InnoDB to abort
@@ -6479,7 +2780,7 @@ DELETE FROM t1 AS a2 USING t1 AS a1 INNER JOIN t2 AS a2;
still accepted as a synonym for the ENGINE = engine_name table
option but generates a warning. You should note that this
option is not available in MySQL 5.1.7, and is removed
- altogether as of MySQL 6.0 and produces a syntax error.
+ altogether as of MySQL 5.4 and produces a syntax error.
TYPE has been deprecated since MySQL 4.0.
* Incompatible change: The namespace for triggers changed in
@@ -6543,8 +2844,11 @@ mysql> source /tmp/triggers.sql //
SUPER privilege from those accounts that no longer otherwise
require it.
- * Some keywords are reserved in MySQL 5.1 that were not reserved
- in MySQL 5.0. See Section 8.3, "Reserved Words."
+ * Some keywords may be reserved in MySQL 5.1 that were not
+ reserved in MySQL 5.0. See Section 8.3, "Reserved Words."
+
+ * The BACKUP TABLE, and RESTORE TABLE statements are deprecated.
+ mysqldump or mysqlhotcopy can be used as alternatives.
* The LOAD DATA FROM MASTER and LOAD TABLE FROM MASTER
statements are deprecated. See Section 12.6.2.2, "LOAD DATA
@@ -6563,7 +2867,7 @@ mysql> source /tmp/triggers.sql //
than an unsigned int for STMT_ATTR_UPDATE_MAX_LENGTH.
(Bug#16144: http://bugs.mysql.com/16144)
-2.12.2. Downgrading MySQL
+2.4.2. Downgrading MySQL
This section describes what you should do to downgrade to an older
MySQL version in the unlikely case that the previous version
@@ -6580,7 +2884,7 @@ mysql> source /tmp/triggers.sql //
* Read the upgrading section for the release series from which
you are downgrading to be sure that it does not have any
- features you really need. See Section 2.12.1, "Upgrading
+ features you really need. See Section 2.4.1, "Upgrading
MySQL."
* If there is a downgrading section for that version, you should
@@ -6590,13 +2894,14 @@ mysql> source /tmp/triggers.sql //
which you are downgrading and your current version, see the
change logs (Appendix C, "MySQL Change History").
- * Check Section 2.12.3, "Checking Whether Table Indexes Must Be
- Rebuilt," to see whether changes to character sets or
- collations were made between your current version of MySQL and
- the version to which you are downgrading. If so and these
- changes affect your table indexes, you will need to rebuild
- the affected indexes using the instructions in Section 2.12.4,
- "Rebuilding or Repairing Tables or Indexes."
+ * Check Section 2.4.3, "Checking Whether Tables or Indexes Must
+ Be Rebuilt," to see whether changes to table formats or to
+ character sets or collations were made between your current
+ version of MySQL and the version to which you are downgrading.
+ If so and these changes result in an incompatibility between
+ MySQL versions, you will need to downgrade the affected tables
+ using the instructions in Section 2.4.4, "Rebuilding or
+ Repairing Tables or Indexes."
In most cases, you can move the MySQL format files and data files
between different versions on the same architecture as long as you
@@ -6606,7 +2911,7 @@ mysql> source /tmp/triggers.sql //
incompatibilities in table storage formats. In this case, use
mysqldump to dump your tables before downgrading. After
downgrading, reload the dump file using mysql or mysqlimport to
- re-create your tables. For examples, see Section 2.12.5, "Copying
+ re-create your tables. For examples, see Section 2.4.5, "Copying
MySQL Databases to Another Machine."
A typical symptom of a downward-incompatible table format change
@@ -6639,11 +2944,11 @@ mysql> source /tmp/triggers.sql //
* Triggers were added in MySQL 5.0, so if you downgrade from 5.0
to 4.1, you cannot use triggers at all.
-2.12.2.1. Downgrading to MySQL 5.0
+2.4.2.1. Downgrading to MySQL 5.0
- When downgrading to MySQL 5.0 from MySQL 5.1 or a later version,
- you should keep in mind the following issues relating to features
- found in MySQL 5.1 and later, but not in MySQL 5.0:
+ When downgrading to MySQL 5.0 from MySQL 5.1, you should keep in
+ mind the following issues relating to features found in MySQL 5.1,
+ but not in MySQL 5.0:
* Partitioning. MySQL 5.0 does not support user-defined
partitioning. If a table was created as a partitioned table in
@@ -6684,7 +2989,7 @@ mysql> source /tmp/triggers.sql //
5.0, you will need to give the SUPER privilege to those
accounts that had the TRIGGER privilege in 5.1.
-2.12.3. Checking Whether Table Indexes Must Be Rebuilt
+2.4.3. Checking Whether Tables or Indexes Must Be Rebuilt
A binary upgrade or downgrade is one that installs one version of
MySQL "in place" over an existing version, without dumping and
@@ -6699,12 +3004,37 @@ mysql> source /tmp/triggers.sql //
3. Start the server for the new version.
In many cases, the tables from the previous version of MySQL can
- be used without change by the new version. However, sometimes
- modifications are made to the handling of character sets or
- collations that change the character sort order, which causes the
- ordering of entries in any index that uses an affected character
- set or collation to be incorrect. Such changes result in several
- possible problems:
+ be used without problem by the new version. However, sometimes
+ changes occur that require tables or table indexes to be rebuilt,
+ as described in this section. If you have tables that are affected
+ by any of the issues described here, rebuild the tables or indexes
+ as necessary using the instructions given in Section 2.4.4,
+ "Rebuilding or Repairing Tables or Indexes."
+
+ Table Incompatibilities
+
+ After a binary upgrade to MySQL 5.1 from a MySQL 5.0 installation
+ that contains ARCHIVE tables, accessing those tables causes the
+ server to crash, even if you have run mysql_upgrade or CHECK TABLE
+ ... FOR UPGRADE. To work around this problem, use mysqldump to
+ dump all ARCHIVE tables before upgrading, and reload them into
+ MySQL 5.1 after upgrading. The same problem occurs for binary
+ downgrades from MySQL 5.1 to 5.0.
+
+ Index Incompatibilities
+
+ If you perform a binary upgrade without dumping and reloading
+ tables, you cannot upgrade directly from MySQL 4.1 to 5.1 or
+ higher. This occurs due to an incompatible change in the MyISAM
+ table index format in MySQL 5.0. Upgrade from MySQL 4.1 to 5.0 and
+ repair all MyISAM tables. Then upgrade from MySQL 5.0 to 5.1 and
+ check and repair your tables.
+
+ Modifications to the handling of character sets or collations
+ might change the character sort order, which causes the ordering
+ of entries in any index that uses an affected character set or
+ collation to be incorrect. Such changes result in several possible
+ problems:
* Comparison results that differ from previous results
@@ -6719,7 +3049,7 @@ mysql> source /tmp/triggers.sql //
an affected character set or collation, either by dropping and
re-creating the indexes, or by dumping and reloading the entire
table. For information about rebuilding indexes, see Section
- 2.12.4, "Rebuilding or Repairing Tables or Indexes."
+ 2.4.4, "Rebuilding or Repairing Tables or Indexes."
To check whether a table has indexes that must be rebuilt, consult
the following list. It indicates which versions of MySQL
@@ -6730,14 +3060,10 @@ mysql> source /tmp/triggers.sql //
report, the bug number is given.
The list applies both for binary upgrades and downgrades. For
- example, Bug#29461: http://bugs.mysql.com/29461 was fixed in MySQL
- 5.0.48, so it applies to upgrades from versions older than 5.0.48
- to 5.0.48 or newer, and also to downgrades from 5.0.48 or newer to
- versions older than 5.0.48.
-
- If you have tables with indexes that are affected, rebuild the
- indexes using the instructions given in Section 2.12.4,
- "Rebuilding or Repairing Tables or Indexes."
+ example, Bug#27877: http://bugs.mysql.com/27877 was fixed in MySQL
+ 5.1.24 and 5.4.0, so it applies to upgrades from versions older
+ than 5.1.24 to 5.1.24 or newer, and to downgrades from 5.1.24 or
+ newer to versions older than 5.1.24.
In many cases, you can use CHECK TABLE ... FOR UPGRADE to identify
tables for which index rebuilding is required. (It will report:
@@ -6751,76 +3077,31 @@ mysql> source /tmp/triggers.sql //
Changes that cause index rebuilding to be necessary:
- * MySQL 5.0.48 (Bug#29461: http://bugs.mysql.com/29461)
+ * MySQL 5.0.48, 5.1.21 (Bug#29461: http://bugs.mysql.com/29461)
Affects indexes for columns that use any of these character
sets: eucjpms, euc_kr, gb2312, latin7, macce, ujis
Affected tables can be detected by CHECK TABLE ... FOR UPGRADE
- as of MySQL 5.1.29, 6.0.8 (see
+ as of MySQL 5.1.29, 5.4.0 (see
Bug#39585: http://bugs.mysql.com/39585).
- * MySQL 5.0.48 (Bug#27562: http://bugs.mysql.com/27562)
+ * MySQL 5.0.48, 5.1.23 (Bug#27562: http://bugs.mysql.com/27562)
Affects indexes that use the ascii_general_ci collation for
columns that contain any of these characters: '`' GRAVE
ACCENT, '[' LEFT SQUARE BRACKET, '\' REVERSE SOLIDUS, ']'
RIGHT SQUARE BRACKET, '~' TILDE
Affected tables can be detected by CHECK TABLE ... FOR UPGRADE
- as of MySQL 5.1.29, 6.0.8 (see
+ as of MySQL 5.1.29, 5.4.0 (see
Bug#39585: http://bugs.mysql.com/39585).
- * MySQL 5.1.21 (Bug#29461: http://bugs.mysql.com/29461)
- Affects indexes for columns that use any of these character
- sets: eucjpms, euc_kr, gb2312, latin7, macce, ujis
- Affected tables can be detected by CHECK TABLE ... FOR UPGRADE
- as of MySQL 5.1.29, 6.0.8 (see
- Bug#39585: http://bugs.mysql.com/39585).
-
- * MySQL 5.1.23 (Bug#27562: http://bugs.mysql.com/27562)
- Affects indexes that use the ascii_general_ci collation for
- columns that contain any of these characters: '`' GRAVE
- ACCENT, '[' LEFT SQUARE BRACKET, '\' REVERSE SOLIDUS, ']'
- RIGHT SQUARE BRACKET, '~' TILDE
- Affected tables can be detected by CHECK TABLE ... FOR UPGRADE
- as of MySQL 5.1.29, 6.0.8 (see
- Bug#39585: http://bugs.mysql.com/39585).
-
- * MySQL 5.1.24 (Bug#27877: http://bugs.mysql.com/27877)
+ * MySQL 5.1.24, 5.4.0 (Bug#27877: http://bugs.mysql.com/27877)
Affects indexes that use the utf8_general_ci or
ucs2_general_ci collation for columns that contain 'ß' LATIN
SMALL LETTER SHARP S (German).
Affected tables can be detected by CHECK TABLE ... FOR UPGRADE
- as of MySQL 5.1.30, 6.0.8 (see
+ as of MySQL 5.1.30, 5.4.0 (see
Bug#40053: http://bugs.mysql.com/40053).
- * * MySQL 6.0.1 (WL#3664)
- Affects indexes that use the latin2_czech_cs collation.
- Affected tables can be detected by CHECK TABLE ... FOR UPGRADE
- as of MySQL 5.4.4, 6.0.9 (see
- Bug#40054: http://bugs.mysql.com/40054).
- MySQL 6.0.5 (Bug#33452: http://bugs.mysql.com/33452)
- Affects indexes that use the latin2_czech_cs collation.
- Affected tables can be detected by CHECK TABLE ... FOR UPGRADE
- as of MySQL 5.4.4, 6.0.9 (see
- Bug#40054: http://bugs.mysql.com/40054).
-
- * MySQL 6.0.5 (Bug#27877: http://bugs.mysql.com/27877)
- Affects indexes that use the utf8_general_ci or
- ucs2_general_ci collation for columns that contain 'ß' LATIN
- SMALL LETTER SHARP S (German).
- Affected tables can be detected by CHECK TABLE ... FOR UPGRADE
- as of MySQL 6.0.8 (see
- Bug#40053: http://bugs.mysql.com/40053).
-
- * MySQL 6.0.6 (Bug#25420: http://bugs.mysql.com/25420)
- Affects indexes for columns that use the following collations,
- if the columns contain the indicated characters:
- big5_chinese_ci: '~' TILDE or '`' GRAVE ACCENT;
- cp866_general_ci: j LATIN SMALL LETTER J; gb2312_chinese_ci:
- '~' TILDE; gbk_chinese_ci: '~' TILDE
- Affected tables can be detected by CHECK TABLE ... FOR UPGRADE
- as of MySQL 5.4.4, 6.0.9 (see
- Bug#40054: http://bugs.mysql.com/40054).
-
-2.12.4. Rebuilding or Repairing Tables or Indexes
+2.4.4. Rebuilding or Repairing Tables or Indexes
This section describes how to rebuild a table. This can be
necessitated by changes to MySQL such as how data types are
@@ -6837,11 +3118,11 @@ mysql> source /tmp/triggers.sql //
Note
If you are rebuilding tables because a different version of MySQL
- will not handle them after a binary upgrade or downgrade, you must
- use the dump-and-reload method. Dump the tables before upgrading
- or downgrading (using your original version of MySQL), and reload
- the tables after upgrading or downgrading (after installing the
- new version).
+ will not handle them after a binary (in-place) upgrade or
+ downgrade, you must use the dump-and-reload method. Dump the
+ tables before upgrading or downgrading (using your original
+ version of MySQL), and reload the tables after upgrading or
+ downgrading (after installing the new version).
If you use the dump-and-reload method of rebuilding tables only
for the purpose of rebuilding indexes, you can perform the dump
@@ -6863,9 +3144,10 @@ shell> mysql db_name < dump.sql
shell> mysqldump --all-databases > dump.sql
shell> mysql < dump.sql
- To rebuild a table with ALTER TABLE, use a statement that
- "changes" the table to use the storage engine that it already has.
- For example, if t1 is a MyISAM table, use this statement:
+ To rebuild a table with ALTER TABLE, use a "null" alteration; that
+ is, an ALTER TABLE statement that "changes" the table to use the
+ storage engine that it already has. For example, if t1 is a MyISAM
+ table, use this statement:
mysql> ALTER TABLE t1 ENGINE = MyISAM;
If you are not sure which storage engine to specify in the ALTER
@@ -6885,7 +3167,15 @@ mysql> REPAIR TABLE t1;
For specifics about which storage engines REPAIR TABLE supports,
see Section 12.5.2.6, "REPAIR TABLE Syntax."
-2.12.5. Copying MySQL Databases to Another Machine
+ mysqlcheck --repair provides command-line access to the REPAIR
+ TABLE statement. This can be a more convenient means of repairing
+ tables because you can use the --databases or --all-databases
+ option to repair all tables in specific databases or all
+ databases, respectively:
+shell> mysqlcheck --repair --databases db_name ...
+shell> mysqlcheck --repair --all-databases
+
+2.4.5. Copying MySQL Databases to Another Machine
You can copy the .frm, .MYI, and .MYD files for MyISAM tables
between different architectures that support the same
@@ -6950,553 +3240,3112 @@ shell> mysqlimport db_name DUMPDIR/*.txt # load data into tables
mysqladmin flush-privileges so that the server reloads the grant
table information.
-2.13. Operating System-Specific Notes
+2.5. Installing MySQL on Windows
+
+ This section describes the process for installing MySQL on
+ Windows.
+
+ To run MySQL on Windows, you need the following:
+
+ * A Windows operating system such as Windows 2000, Windows XP,
+ Windows Vista, Windows Server 2003, or Windows Server 2008.
+ Both 32-bit and 64-bit versions are supported.
+ In addition to running MySQL as a standard application, you
+ can also run the MySQL server as a Windows service. By using a
+ service you can monitor and control the operation of the
+ server through the standard Windows service management tools.
+ For more information, see Section 2.5.5.6, "Starting MySQL as
+ a Windows Service."
+ Generally, you should install MySQL on Windows using an
+ account that has administrator rights. Otherwise, you may
+ encounter problems with certain operations such as editing the
+ PATH environment variable or accessing the Service Control
+ Manager. Once installed, MySQL does not need to be executed
+ using a user with Administrator privileges.
+
+ * TCP/IP protocol support.
+
+ * Enough space on the hard drive to unpack, install, and create
+ the databases in accordance with your requirements (generally
+ a minimum of 200 megabytes is recommended.)
+
+ For a list of limitations within the Windows version of MySQL, see
+ Section D.7.3, "Windows Platform Limitations."
+
+ In addition to the MySQL Server package, you may need or want
+ additional components to use MySQL with your application or
+ development environment. These include, but are not limited to:
+
+ * If you plan to connect to the MySQL server via ODBC, you need
+ a Connector/ODBC driver. For more information, including
+ installation and configuration instructions, see Section 21.1,
+ "MySQL Connector/ODBC."
+
+ * If you plan to use MySQL server with .NET applications, you
+ need the Connector/NET driver. For more information, including
+ installation and configuration instructions, see Section 21.2,
+ "MySQL Connector/NET."
+
+ MySQL distributions for Windows can be downloaded from
+ http://dev.mysql.com/downloads/. See Section 2.1.3, "How to Get
+ MySQL."
+
+ MySQL for Windows is available in several distribution formats,
+ detailed below. Generally speaking, you should use a binary
+ distribution that includes an installer. It is simpler to use than
+ the others, and you need no additional tools to get MySQL up and
+ running. The installer for the Windows version of MySQL, combined
+ with a GUI Config Wizard, automatically installs MySQL, creates an
+ option file, starts the server, and secures the default user
+ accounts.
+
+ * Binary installer distribution. The installable distribution
+ comes packaged as a Microsoft Windows Installer (MSI) package
+ that you can install manually or automatically on your
+ systems. Two formats are available, an essentials package that
+ contains all the files you need to install and configure
+ MySQL, but no additional components, and a complete package
+ that includes MySQL, configuration tools, benchmarks and other
+ components. For more information on the specific differences,
+ see Section 2.5.2, "Choosing An Installation Package"
+ For instructions on installing MySQL using one of the MSI
+ installation packages, see Section 2.5.3, "Installing MySQL
+ with the MSI Package."
+
+ * Standard binary distribution format packaged as a Zip file
+ containing all of the necessary files that you unpack into
+ your chosen location. This package contains all of the files
+ in the full Windows MSI Installer package, but does not
+ including an installation program.
+ For instructions on installing MySQL using the Zip file, see
+ Section 2.5.5, "Installing MySQL from a noinstall Zip
+ Archive."
+
+ * The source distribution contains all the code and support
+ files for building the executables using the Visual Studio
+ compiler system.
+ For instructions on building MySQL from source on Windows, see
+ Section 2.5.10, "Installing MySQL from Source on Windows."
+
+ MySQL on Windows considerations:
+
+ * Large Table Support
+ If you need tables with a size larger than 4GB, install MySQL
+ on an NTFS or newer file system. Don't forget to use MAX_ROWS
+ and AVG_ROW_LENGTH when you create tables. See Section
+ 12.1.17, "CREATE TABLE Syntax."
+
+ * MySQL and Virus Checking Software
+ Using virus scanning software such as Norton/Symantec
+ Anti-Virus on directories containing MySQL data and temporary
+ tables can cause issues, both in terms of the performance of
+ MySQL and the virus-scanning software mis-identifying the
+ contents of the files as containing spam. This is because of
+ the fingerprinting mechanism used by the virus scanning
+ software, and the way in which MySQL rapidly updates different
+ files, which may be identified as a potential security risk.
+ After installing MySQL Server, it is recommended that you
+ disable virus scanning on the main directory (datadir) being
+ used to store your MySQL table data. There is usually a system
+ built into the virus scanning software to allow certain
+ directories to be specifically ignored during virus scanning.
+ In addition, by default, MySQL creates temporary files in the
+ standard Windows temporary directory. To prevent the temporary
+ files also being scanned, you should configure a separate
+ temporary directory for MySQL temporary files and add this to
+ the virus scanning exclusion list. To do this, add a
+ configuration option for the tmpdir parameter to your my.ini
+ configuration file. For more information, see Section 2.5.5.2,
+ "Creating an Option File."
+
+2.5.1. Windows Installation Layout
+
+ For MySQL 5.1 on Windows, the default installation directory is
+ C:\Program Files\MySQL\MySQL Server 5.1. Some Windows users prefer
+ to install in C:\mysql, the directory that formerly was used as
+ the default. However, the layout of the subdirectories remains the
+ same.
+
+ For MySQL 5.1.23 and earlier, all of the files are located within
+ this parent directory, using the following structure:
+
+ Table 2.2. Installation Layout for Windows using MySQL 5.1.23 and
+ earlier
+ Directory Contents of Directory
+ bin Client programs and the mysqld server
+ data Log files, databases
+ Docs Manual in CHM format
+ examples Example programs and scripts
+ include Include (header) files
+ lib Libraries
+ scripts Utility scripts
+ share Error message files
+
+ For MySQL 5.1.24 and later, the default location of data directory
+ was changed. The remainder of the directory structure remains the
+ same:
+
+ Table 2.3. Installation Layout for Windows using MySQL 5.1.24 and
+ later
+ Directory Contents of Directory
+ bin Client programs and the mysqld server
+ C:\Documents and Settings\All Users\Application Data\MySQL Log
+ files, databases
+ Docs Manual in CHM format
+ examples Example programs and scripts
+ include Include (header) files
+ lib Libraries
+ scripts Utility scripts
+ share Error message files
+
+2.5.2. Choosing An Installation Package
+
+ For MySQL 5.1, there are three installation packages to choose
+ from when installing MySQL on Windows:
+ Packaging
+ Feature Essentials Complete Zip (No-install)
+ Installer Yes Yes No
+ Directory-only
+ MySQL Server Instance Config Wizard Yes Yes No
+ Test Suite No Yes Yes
+ MySQL Server Yes Yes Yes
+ MySQL Client Programs Yes Yes Yes
+ C Headers/Libraries Yes Yes Yes
+ Embedded Server No Optional Yes
+ Scripts and Examples No Optional Yes
+
+ In the above table:
+
+ * Yes indiciates that the component is installed by default.
+
+ * No indicates that the component is not installed or included.
+
+ * Optional indicates that the component is included with the
+ package, but not installed unless explicitly requested using
+ the Custom installation mode.
+
+ The workflow for installing using the MSI installer is shown
+ below:
+
+ Figure 2.1. Installation Workflow for Windows using MSI
+ Installation Workflow for Windows using MSI
+
+ The workflow for installing using the MSI installer is shown
+ below:
+
+ Figure 2.2. Installation Workflow for Windows using Zip
+ Installation Workflow for Windows using Zip
+
+Note
+
+ For the Essentials and Complete packages in the MSI installer, you
+ can select individual components to be installed by using the
+ Custom mode, including disable the components confiurated for
+ installation by default.
+
+ Full details on the components are suggested uses are provided
+ below for reference:
+
+ * Windows Essentials --- this package has a file name similar to
+ mysql-essential-5.1.41-win32.msi and is supplied as a
+ Microsoft Installer (MSI) package. The package includes the
+ minimum set of files needed to install MySQL on Windows,
+ including the MySQL Server Instance Config Wizard. This
+ package does not include optional components such as the
+ embedded server, developer headers and libraries or benchmark
+ suite.
+ To install using this package, see Section 2.5.3, "Installing
+ MySQL with the MSI Package."
+
+ * Windows MSI Installer (Complete) --- this package has a file
+ name similar to mysql-5.1.41-win32.zip and contains all files
+ needed for a complete Windows installation, including the
+ MySQL Server Instance Config Wizard. This package includes
+ optional components such as the embedded server and benchmark
+ suite.
+ To install using this package, see Section 2.5.3, "Installing
+ MySQL with the MSI Package."
+
+ * Without installer --- this package has a file name similar to
+ mysql-noinstall-5.1.41-win32.zip and contains all the files
+ found in the Complete install package, with the exception of
+ the MySQL Server Instance Config Wizard. This package does not
+ include an automated installer, and must be manually installed
+ and configured.
+
+ The Essentials package is recommended for most users. Both the
+ Essentials and Complete distributions are available as an .msi
+ file for use with the Windows Installer. The Noinstall
+ distribution is packaged as Zip archives. To use Zip archives, you
+ must have a tool that can unpack .zip files.
+
+ When using the MSI installers you can automate the installation
+ process. For more information, see Section 2.5.3.2, "Installing
+ MySQL Automatically using MSI." To automate the creation of a
+ MySQL instance, see Section 2.5.4.13, "Creating an Instance from
+ the Command Line."
+
+ Your choice of install package affects the installation process
+ you must follow. If you choose to install either the Essentials or
+ Complete install packages, see Section 2.5.3, "Installing MySQL
+ with the MSI Package." If you choose to install MySQL from the
+ Noinstall archive, see Section 2.5.5, "Installing MySQL from a
+ noinstall Zip Archive."
+
+2.5.3. Installing MySQL with the MSI Package
+
+ The MSI package are designed to install and configure MySQL in
+ such a way that you can immediately get started using MySQL.
+
+ The MySQL Installation Wizard and MySQL Config Wizard are
+ available in the Essentials and Complete install packages. They
+ are recommended for most standard MySQL installations. Exceptions
+ include users who need to install multiple instances of MySQL on a
+ single server host and advanced users who want complete control of
+ server configuration.
+
+ * For information on installing using the GUI MSI installer
+ process, see Section 2.5.3, "Installing MySQL with the MSI
+ Package."
+
+ * For information on installing using the command line using the
+ MSI package, see Section 2.5.3.2, "Installing MySQL
+ Automatically using MSI."
+
+ * If you have previously installed MySQL using the MSI package
+ and want to remove MySQL, see Section 2.5.3.3, "Removing MySQL
+ Installed from the MSI Package."
+
+ The workflow sequence for using the installer is shown in the
+ figure below:
+
+ Figure 2.3. Installation Workflow for Windows using MSI Installer
+ Installation Workflow for Windows using MSI Installer
+
+Note
+
+ Microsoft Windows XP and later include a firewall which
+ specifically blocks ports. If you plan on using MySQL through a
+ network port then you should open and create an exception for this
+ port before performing the installation. To check and if necessary
+ add an exception to the firewall settings:
+
+ 1. First ensure that you are logged in as an Administrator or a
+ user with Administrator privileges.
+
+ 2. Go to the Control Panel, and double click the Windows Firewall
+ icon.
+
+ 3. Choose the Allow a program through Windows Firewall option and
+ click the Add port button.
+
+ 4. Enter MySQL into the Name text box and 3306 (or the port of
+ your choice) into the Port number text box.
+
+ 5. Also ensure that the TCP protocol radio button is selected.
+
+ 6. If you wish, you can also limit access to the MySQL server by
+ choosing the Change scope button.
+
+ 7. Confirm your choices by clicking the OK button.
+
+ Additionally, when running the MySQL Installation Wizard on
+ Windows Vista, ensure that you are logged in as a user with
+ administrative rights.
+
+Note
+
+ When using Windows Vista, you may want to disable User Account
+ Control (UAC) before performing the installation. If you do not do
+ so, then MySQL may be identified as a security risk, which will
+ mean that you need to enable MySQL. You can disable the security
+ checking by following these instructions:
+
+ 1. Open Control Panel.
+
+ 2. Under the User Accounts and Family Safety, select Add or
+ remove user accounts.
+
+ 3. Click on the Got to the main User Accounts page link.
+
+ 4. Click on Turn User Account Control on or off. You may be
+ prompted to provide permission to change this setting. Click
+ Continue.
+
+ 5. Deselect or unceck the checkbox next to Use User Account
+ Control (UAC) to help protect your computer. Click OK to save
+ the setting.
+
+ You will need to restart to complete the process. Click Restart
+ Now to reboot the machine and apply the changes. You can then
+ follow the instructions below for installing Windows.
+
+2.5.3.1. Using the MySQL Installation Wizard
+
+ MySQL Installation Wizard is an installer for the MySQL server
+ that uses the latest installer technologies for Microsoft Windows.
+ The MySQL Installation Wizard, in combination with the MySQL
+ Config Wizard, allows a user to install and configure a MySQL
+ server that is ready for use immediately after installation.
+
+ The MySQL Installation Wizard uses the standard Microsoft
+ Installer Engine (MSI) system is the standard installer for all
+ MySQL server distributions, version 4.1.5 and higher. Users of
+ previous versions of MySQL need to shut down and remove their
+ existing MySQL installations manually before installing MySQL with
+ the MySQL Installation Wizard. See Section 2.5.3.1.6, "Upgrading
+ MySQL with the Installation Wizard," for more information on
+ upgrading from a previous version.
+
+ If you are upgrading an installation from MySQL 5.1.31 or earlier
+ to MySQL 5.1.32 or later, read the notes provided in Section
+ 2.5.3.1.6, "Upgrading MySQL with the Installation Wizard."
+
+ The Microsoft Windows Installer Engine was updated with the
+ release of Windows XP; those using a previous version of Windows
+ can reference this Microsoft Knowledge Base article
+ (http://support.microsoft.com/default.aspx?scid=kb;EN-US;292539)
+ for information on upgrading to the latest version of the Windows
+ Installer Engine.
+
+ In addition, Microsoft has introduced the WiX (Windows Installer
+ XML) toolkit. This is the first highly acknowledged Open Source
+ project from Microsoft. We have switched to WiX because it is an
+ Open Source project and it allows us to handle the complete
+ Windows installation process in a flexible manner using scripts.
+
+ Improving the MySQL Installation Wizard depends on the support and
+ feedback of users like you. If you find that the MySQL
+ Installation Wizard is lacking some feature important to you, or
+ if you discover a bug, please report it in our bugs database using
+ the instructions given in Section 1.6, "How to Report Bugs or
+ Problems."
+
+2.5.3.1.1. Downloading and Starting the MySQL Installation Wizard
+
+ The MySQL installation packages can be downloaded from
+ http://dev.mysql.com/downloads/. If the package you download is
+ contained within a Zip archive, you need to extract the archive
+ first.
+
+ The process for starting the wizard depends on the contents of the
+ installation package you download. If there is a setup.exe file
+ present, double-click it to start the installation process. If
+ there is an .msi file present, double-click it to start the
+ installation process.
+
+2.5.3.1.2. Choosing an Install Type
+
+ There are three installation types available: Typical, Complete,
+ and Custom.
+
+ The Typical installation type installs the MySQL server, the mysql
+ command-line client, and the command-line utilities. The
+ command-line clients and utilities include mysqldump, myisamchk,
+ and several other tools to help you manage the MySQL server.
+
+ The Complete installation type installs all components included in
+ the installation package. The full installation package includes
+ components such as the embedded server library, the benchmark
+ suite, support scripts, and documentation.
+
+ The Custom installation type gives you complete control over which
+ packages you wish to install and the installation path that is
+ used. See Section 2.5.3.1.3, "The Custom Install Dialog," for more
+ information on performing a custom install.
+
+ If you choose the Typical or Complete installation types and click
+ the Next button, you advance to the confirmation screen to verify
+ your choices and begin the installation. If you choose the Custom
+ installation type and click the Next button, you advance to the
+ custom installation dialog, described in Section 2.5.3.1.3, "The
+ Custom Install Dialog."
+
+2.5.3.1.3. The Custom Install Dialog
+
+ If you wish to change the installation path or the specific
+ components that are installed by the MySQL Installation Wizard,
+ choose the Custom installation type.
+
+ A tree view on the left side of the custom install dialog lists
+ all available components. Components that are not installed have a
+ red X icon; components that are installed have a gray icon. To
+ change whether a component is installed, click on that component's
+ icon and choose a new option from the drop-down list that appears.
+
+ You can change the default installation path by clicking the
+ Change... button to the right of the displayed installation path.
+
+ After choosing your installation components and installation path,
+ click the Next button to advance to the confirmation dialog.
+
+2.5.3.1.4. The Confirmation Dialog
+
+ Once you choose an installation type and optionally choose your
+ installation components, you advance to the confirmation dialog.
+ Your installation type and installation path are displayed for you
+ to review.
+
+ To install MySQL if you are satisfied with your settings, click
+ the Install button. To change your settings, click the Back
+ button. To exit the MySQL Installation Wizard without installing
+ MySQL, click the Cancel button.
+
+ After installation is complete, you have the option of registering
+ with the MySQL web site. Registration gives you access to post in
+ the MySQL forums at forums.mysql.com (http://forums.mysql.com),
+ along with the ability to report bugs at bugs.mysql.com
+ (http://bugs.mysql.com) and to subscribe to our newsletter. The
+ final screen of the installer provides a summary of the
+ installation and gives you the option to launch the MySQL Config
+ Wizard, which you can use to create a configuration file, install
+ the MySQL service, and configure security settings.
+
+2.5.3.1.5. Changes Made by MySQL Installation Wizard
+
+ Once you click the Install button, the MySQL Installation Wizard
+ begins the installation process and makes certain changes to your
+ system which are described in the sections that follow.
+
+ Changes to the Registry
+
+ The MySQL Installation Wizard creates one Windows registry key in
+ a typical install situation, located in
+ HKEY_LOCAL_MACHINE\SOFTWARE\MySQL AB.
+
+ The MySQL Installation Wizard creates a key named after the major
+ version of the server that is being installed, such as MySQL
+ Server 5.1. It contains two string values, Location and Version.
+ The Location string contains the path to the installation
+ directory. In a default installation it contains C:\Program
+ Files\MySQL\MySQL Server 5.1\. The Version string contains the
+ release number. For example, for an installation of MySQL Server
+ 5.1.41, the key contains a value of 5.1.41.
+
+ These registry keys are used to help external tools identify the
+ installed location of the MySQL server, preventing a complete scan
+ of the hard-disk to determine the installation path of the MySQL
+ server. The registry keys are not required to run the server, and
+ if you install MySQL using the noinstall Zip archive, the registry
+ keys are not created.
+
+ Changes to the Start Menu
+
+ The MySQL Installation Wizard creates a new entry in the Windows
+ Start menu under a common MySQL menu heading named after the major
+ version of MySQL that you have installed. For example, if you
+ install MySQL 5.1, the MySQL Installation Wizard creates a MySQL
+ Server 5.1 section in the Start menu.
+
+ The following entries are created within the new Start menu
+ section:
+
+ * MySQL Command Line Client: This is a shortcut to the mysql
+ command-line client and is configured to connect as the root
+ user. The shortcut prompts for a root user password when you
+ connect.
+
+ * MySQL Server Instance Config Wizard: This is a shortcut to the
+ MySQL Config Wizard. Use this shortcut to configure a newly
+ installed server, or to reconfigure an existing server.
+
+ * MySQL Documentation: This is a link to the MySQL server
+ documentation that is stored locally in the MySQL server
+ installation directory. This option is not available when the
+ MySQL server is installed using the Essentials installation
+ package.
+
+ Changes to the File System
+
+ The MySQL Installation Wizard by default installs the MySQL 5.1
+ server to C:\Program Files\MySQL\MySQL Server 5.1, where Program
+ Files is the default location for applications in your system, and
+ 5.1 is the major version of your MySQL server. This is the
+ recommended location for the MySQL server, replacing the former
+ default location C:\mysql.
+
+ By default, all MySQL applications are stored in a common
+ directory at C:\Program Files\MySQL, where Program Files is the
+ default location for applications in your Windows installation. A
+ typical MySQL installation on a developer machine might look like
+ this:
+C:\Program Files\MySQL\MySQL Server 5.1
+C:\Program Files\MySQL\MySQL Workbench 5.1 OSS
+
+ This approach makes it easier to manage and maintain all MySQL
+ applications installed on a particular system.
+
+ In MySQL 5.1.23 and earlier, the default location for the data
+ files used by MySQL is located within the corresponding MySQL
+ Server installation directory. For MySQL 5.1.24 and later, the
+ default location of the data directory is the AppData directory
+ configured for the user that installed the MySQL application.
+
+2.5.3.1.6. Upgrading MySQL with the Installation Wizard
+
+ The MySQL Installation Wizard can perform server upgrades
+ automatically using the upgrade capabilities of MSI. That means
+ you do not need to remove a previous installation manually before
+ installing a new release. The installer automatically shuts down
+ and removes the previous MySQL service before installing the new
+ version.
+
+ Automatic upgrades are available only when upgrading between
+ installations that have the same major and minor version numbers.
+ For example, you can upgrade automatically from MySQL 5.1.34 to
+ MySQL 5.1.37, but not from MySQL 5.0 to MySQL 5.1.
+
+ In MySQL 5.1.32 and later, the EXE version of the MSI installer
+ packages were removed. When upgrading an existing MySQL
+ installation from the old EXE based installer to the MSI based
+ installer, please keep the following notes in mind:
+
+ * The MSI installer will not identify an existing installation
+ that was installed using the old EXE installer. This means
+ that the installer will not stop the existing server, or
+ detect that the existing password is required before
+ installing the new version. To work around this:
+
+ 1. Stop the current server manually using net stop or
+ mysqladmin shutdown.
+
+ 2. Remove the existing installation manually by using the
+ Add/Remove Programs control panel. This will keep the
+ existing configuration and data files, as these are not
+ removed automatically.
+
+ 3. Install the new version of MySQL using the MSI installer.
+ When running the installation, skip updating the security
+ by deselecting the checkbox on the security screen.
+
+ 4. Complete the installation, and then start the server
+ again. You should be able to login with your existing
+ user and password credentials.
+
+ * You can only upgrade the version and release using the MSI
+ installer. For example, you can upgrade an open source
+ installation with an open source installer. You cannot upgrade
+ an open source installation using the enterprise installer.
+
+ See Section 2.5.7, "Upgrading MySQL on Windows."
+
+2.5.3.2. Installing MySQL Automatically using MSI
+
+ The Microsoft Installer (MSI) supports a both a quiet and a
+ passive mode that can be used to install MySQL automatically
+ without requireing intervention. You can use this either in
+ scripts to automatically install MySQL or through a terminal
+ connection such as Telnet where you do not have access to the
+ standard Windows user interface. The MSI packages can also be used
+ in combination with Microsoft's Group Policy system (part of
+ Windows Server 2003 and Windows Server 2008) to install MySQL
+ across multiple machines.
+
+ To install MySQL from one of the MSI packages automatically from
+ the command line (or within a script), you need to use the
+ msiexec.exe tool. For example, to perform a quiet installation
+ (which shows no dialog boxes or progress):
+shell> msiexec /i /quiet mysql-5.1.39.msi
+
+ The /i indicates that you want to perform an installation. The
+ /quiet option indicates that you want no interactive elements.
+
+ To provide a dialog box showing the progress during installation,
+ and the dialog boxes providing information on the installation and
+ registration of MySQL, use /passive mode instead of /quiet:
+shell> msiexec /i /passive mysql-5.1.39.msi
+
+ Regardless of the mode of the installation, installing the package
+ in this manner performs a 'Typical' installation, and installs the
+ default components into the standard location.
+
+ You can also use this method to uninstall MySQL by using the
+ /uninstall or /x options:
+shell> msiexec /x /quiet mysql-5.1.39.msi
+
+ To install MySQL and configure a MySQL instance from the command
+ line, see Section 2.5.4.13, "Creating an Instance from the Command
+ Line."
+
+ For information on using MSI packages to install software
+ automatically using Group Policy, see How to use Group Policy to
+ remotely install software in Windows Server 2003
+ (http://support.microsoft.com/kb/816102).
+
+2.5.3.3. Removing MySQL Installed from the MSI Package
+
+ To uninstall a MySQL where you have used the MSI packages, you
+ must use the Add/Remove Programs tool within Control Panel. To do
+ this:
+
+ 1. Right click on the start menu and choose Control Panel.
+
+ 2. If the Control Panel is set to category mode (you will see
+ Pick a category at the top of the Control Panel window),
+ double click on Add or Remove Programs. If the Control is set
+ to classic mode, doubgle click on the Add or Remove Programs
+ icon.
+
+ 3. Find MySQL in the list of installed software. MySQL Server is
+ installed against major version numbers (MySQL 5.0, MySQL 5.1,
+ etc.). Select the version that you want to remove and click
+ Remove.
+
+ 4. You will be prompted to confirm the removal. Click Yes to
+ remove MySQL.
+
+ When MySQL is removed using this method, only the installed
+ components are removed. Any database information (including the
+ tables and data), import or export files, log files, and binary
+ logs produced during execution are kept in their configured
+ location.
+
+2.5.4. MySQL Server Instance Config Wizard
+
+ The MySQL Server Instance Config Wizard helps automate the process
+ of configuring your server. It creates a custom MySQL
+ configuration file (my.ini or my.cnf) by asking you a series of
+ questions and then applying your responses to a template to
+ generate the configuration file that is tuned to your
+ installation.
+
+ The complete and essential MSI installation packages include the
+ MySQL Server Instance Config Wizard in the MySQL 5.1 server. The
+ MySQL Server Instance Config Wizard is only available for Windows.
+
+ The workflow sequence for using the MySQL Server Instance Config
+ Wizard is shown in the figure below:
+
+ Figure 2.4. MySQL Server Instance Config Wizard Workflow
+ MySQL Server Instance Config Wizard Workflow
+
+2.5.4.1. Starting the MySQL Server Instance Config Wizard
+
+ The MySQL Server Instance Config Wizard is normally started as
+ part of the installation process. You should only need to run the
+ MySQL Server Instance Config Wizard again when you need to change
+ the configuration parameters of your server.
+
+ If you chose not to open a port prior to installing MySQL on
+ Windows Vista, you can choose to use the MySQL Server Instance
+ Config Wizard after installation. However, you must open a port in
+ the Windows Firewall. To do this see the instructions given in
+ Section 2.5.3.1.1, "Downloading and Starting the MySQL
+ Installation Wizard." Rather than opening a port, you also have
+ the option of adding MySQL as a program that bypasses the Windows
+ Firewall. One or the other option is sufficient --- you need not
+ do both. Additionally, when running the MySQL Server Config Wizard
+ on Windows Vista ensure that you are logged in as a user with
+ administrative rights.
+ MySQL Server Instance Config Wizard
+
+ You can launch the MySQL Config Wizard by clicking the MySQL
+ Server Instance Config Wizard entry in the MySQL section of the
+ Windows Start menu.
+
+ Alternatively, you can navigate to the bin directory of your MySQL
+ installation and launch the MySQLInstanceConfig.exe file directly.
+
+ The MySQL Server Instance Config Wizard places the my.ini file in
+ the installation directory for the MySQL server. This helps
+ associate configuration files with particular server instances.
+
+ To ensure that the MySQL server knows where to look for the my.ini
+ file, an argument similar to this is passed to the MySQL server as
+ part of the service installation:
+--defaults-file="C:\Program Files\MySQL\MySQL Server 5.1\my.ini"
+
+ Here, C:\Program Files\MySQL\MySQL Server 5.1 is replaced with the
+ installation path to the MySQL Server. The --defaults-file option
+ instructs the MySQL server to read the specified file for
+ configuration options when it starts.
+
+ Apart from making changes to the my.ini file by running the MySQL
+ Server Instance Config Wizard again, you can modify it by opening
+ it with a text editor and making any necessary changes. You can
+ also modify the server configuration with the MySQL Administrator
+ (http://www.mysql.com/products/administrator/) utility. For more
+ information about server configuration, see Section 5.1.2, "Server
+ Command Options."
+
+ MySQL clients and utilities such as the mysql and mysqldump
+ command-line clients are not able to locate the my.ini file
+ located in the server installation directory. To configure the
+ client and utility applications, create a new my.ini file in the
+ Windows installation directory (for example, C:\WINDOWS).
+
+ Under Windows Server 2003, Windows Server 2000, Windows XP, and
+ Windows Vista MySQL Server Instance Config Wizard will configure
+ MySQL to work as a Windows service. To start and stop MySQL you
+ use the Services application that is supplied as part of the
+ Windows Administrator Tools.
+
+2.5.4.2. Choosing a Maintenance Option
+
+ If the MySQL Server Instance Config Wizard detects an existing
+ configuration file, you have the option of either reconfiguring
+ your existing server, or removing the server instance by deleting
+ the configuration file and stopping and removing the MySQL
+ service.
+
+ To reconfigure an existing server, choose the Re-configure
+ Instance option and click the Next button. Any existing
+ configuration file is not overwritten, but renamed (within the
+ same directory) using a timestamp (Windows) or sequential number
+ (Linux). To remove the existing server instance, choose the Remove
+ Instance option and click the Next button.
+
+ If you choose the Remove Instance option, you advance to a
+ confirmation window. Click the Execute button. The MySQL Server
+ Config Wizard stops and removes the MySQL service, and then
+ deletes the configuration file. The server installation and its
+ data folder are not removed.
-2.13.1. Linux Notes
+ If you choose the Re-configure Instance option, you advance to the
+ Configuration Type dialog where you can choose the type of
+ installation that you wish to configure.
- This section discusses issues that have been found to occur on
- Linux. The first few subsections describe general operating
- system-related issues, problems that can occur when using binary
- or source distributions, and post-installation issues. The
- remaining subsections discuss problems that occur with Linux on
- specific platforms.
+2.5.4.3. Choosing a Configuration Type
- Note that most of these problems occur on older versions of Linux.
- If you are running a recent version, you may see none of them.
+ When you start the MySQL Server Instance Config Wizard for a new
+ MySQL installation, or choose the Re-configure Instance option for
+ an existing installation, you advance to the Configuration Type
+ dialog.
+ MySQL Server Instance Config Wizard: Configuration Type
-2.13.1.1. Linux Operating System Notes
+ There are two configuration types available: Detailed
+ Configuration and Standard Configuration. The Standard
+ Configuration option is intended for new users who want to get
+ started with MySQL quickly without having to make many decisions
+ about server configuration. The Detailed Configuration option is
+ intended for advanced users who want more fine-grained control
+ over server configuration.
+
+ If you are new to MySQL and need a server configured as a
+ single-user developer machine, the Standard Configuration should
+ suit your needs. Choosing the Standard Configuration option causes
+ the MySQL Config Wizard to set all configuration options
+ automatically with the exception of Service Options and Security
+ Options.
+
+ The Standard Configuration sets options that may be incompatible
+ with systems where there are existing MySQL installations. If you
+ have an existing MySQL installation on your system in addition to
+ the installation you wish to configure, the Detailed Configuration
+ option is recommended.
+
+ To complete the Standard Configuration, please refer to the
+ sections on Service Options and Security Options in Section
+ 2.5.4.10, "The Service Options Dialog," and Section 2.5.4.11, "The
+ Security Options Dialog," respectively.
+
+2.5.4.4. The Server Type Dialog
+
+ There are three different server types available to choose from.
+ The server type that you choose affects the decisions that the
+ MySQL Server Instance Config Wizard makes with regard to memory,
+ disk, and processor usage.
+ MySQL Server Instance Config Wizard: Server Type
+
+ * Developer Machine: Choose this option for a typical desktop
+ workstation where MySQL is intended only for personal use. It
+ is assumed that many other desktop applications are running.
+ The MySQL server is configured to use minimal system
+ resources.
+
+ * Server Machine: Choose this option for a server machine where
+ the MySQL server is running alongside other server
+ applications such as FTP, email, and Web servers. The MySQL
+ server is configured to use a moderate portion of the system
+ resources.
+
+ * Dedicated MySQL Server Machine: Choose this option for a
+ server machine that is intended to run only the MySQL server.
+ It is assumed that no other applications are running. The
+ MySQL server is configured to use all available system
+ resources.
+
+Note
+
+ By selecting one of the preconfigured configurations, the values
+ and settings of various options in your my.cnf or my.ini will be
+ altered accordingly. The default values and options as described
+ in the reference manual may therefore be different to the options
+ and values that were created during the execution of the Config
+ Wizard.
+
+2.5.4.5. The Database Usage Dialog
+
+ The Database Usage dialog allows you to indicate the storage
+ engines that you expect to use when creating MySQL tables. The
+ option you choose determines whether the InnoDB storage engine is
+ available and what percentage of the server resources are
+ available to InnoDB.
+ MySQL Server Instance Config Wizard: Usage Dialog
+
+ * Multifunctional Database: This option enables both the InnoDB
+ and MyISAM storage engines and divides resources evenly
+ between the two. This option is recommended for users who use
+ both storage engines on a regular basis.
+
+ * Transactional Database Only: This option enables both the
+ InnoDB and MyISAM storage engines, but dedicates most server
+ resources to the InnoDB storage engine. This option is
+ recommended for users who use InnoDB almost exclusively and
+ make only minimal use of MyISAM.
+
+ * Non-Transactional Database Only: This option disables the
+ InnoDB storage engine completely and dedicates all server
+ resources to the MyISAM storage engine. This option is
+ recommended for users who do not use InnoDB.
+
+ The Config Wizard uses a template to generate the server
+ configuration file. The Database Usage dialog sets one of the
+ following option strings:
+Multifunctional Database: MIXED
+Transactional Database Only: INNODB
+Non-Transactional Database Only: MYISAM
+
+ When these options are processed through the default template
+ (my-template.ini) the result is:
+Multifunctional Database:
+default-storage-engine=InnoDB
+_myisam_pct=50
+
+Transactional Database Only:
+default-storage-engine=InnoDB
+_myisam_pct=5
+
+Non-Transactional Database Only:
+default-storage-engine=MyISAM
+_myisam_pct=100
+skip-innodb
+
+ The _myisam_pct value is used to calculate the percentage of
+ resources dedicated to MyISAM. The remaining resources are
+ allocated to InnoDB.
+
+2.5.4.6. The InnoDB Tablespace Dialog
+
+ Some users may want to locate the InnoDB tablespace files in a
+ different location than the MySQL server data directory. Placing
+ the tablespace files in a separate location can be desirable if
+ your system has a higher capacity or higher performance storage
+ device available, such as a RAID storage system.
+ MySQL Server Instance Config Wizard: InnoDB Data Tablespace
+
+ To change the default location for the InnoDB tablespace files,
+ choose a new drive from the drop-down list of drive letters and
+ choose a new path from the drop-down list of paths. To create a
+ custom path, click the ... button.
+
+ If you are modifying the configuration of an existing server, you
+ must click the Modify button before you change the path. In this
+ situation you must move the existing tablespace files to the new
+ location manually before starting the server.
+
+2.5.4.7. The Concurrent Connections Dialog
+
+ To prevent the server from running out of resources, it is
+ important to limit the number of concurrent connections to the
+ MySQL server that can be established. The Concurrent Connections
+ dialog allows you to choose the expected usage of your server, and
+ sets the limit for concurrent connections accordingly. It is also
+ possible to set the concurrent connection limit manually.
+ MySQL Server Instance Config Wizard: Connections
+
+ * Decision Support (DSS)/OLAP: Choose this option if your server
+ does not require a large number of concurrent connections. The
+ maximum number of connections is set at 100, with an average
+ of 20 concurrent connections assumed.
+
+ * Online Transaction Processing (OLTP): Choose this option if
+ your server requires a large number of concurrent connections.
+ The maximum number of connections is set at 500.
+
+ * Manual Setting: Choose this option to set the maximum number
+ of concurrent connections to the server manually. Choose the
+ number of concurrent connections from the drop-down box
+ provided, or enter the maximum number of connections into the
+ drop-down box if the number you desire is not listed.
+
+2.5.4.8. The Networking and Strict Mode Options Dialog
+
+ Use the Networking Options dialog to enable or disable TCP/IP
+ networking and to configure the port number that is used to
+ connect to the MySQL server.
+ MySQL Server Instance Config Wizard: Network Configuration
+
+ TCP/IP networking is enabled by default. To disable TCP/IP
+ networking, uncheck the box next to the Enable TCP/IP Networking
+ option.
+
+ Port 3306 is used by default. To change the port used to access
+ MySQL, choose a new port number from the drop-down box or type a
+ new port number directly into the drop-down box. If the port
+ number you choose is in use, you are prompted to confirm your
+ choice of port number.
+
+ Set the Server SQL Mode to either enable or disable strict mode.
+ Enabling strict mode (default) makes MySQL behave more like other
+ database management systems. If you run applications that rely on
+ MySQL's old "forgiving" behavior, make sure to either adapt those
+ applications or to disable strict mode. For more information about
+ strict mode, see Section 5.1.8, "Server SQL Modes."
- MySQL needs at least Linux version 2.0.
+2.5.4.9. The Character Set Dialog
+
+ The MySQL server supports multiple character sets and it is
+ possible to set a default server character set that is applied to
+ all tables, columns, and databases unless overridden. Use the
+ Character Set dialog to change the default character set of the
+ MySQL server.
+ MySQL Server Instance Config Wizard: Character Set
+
+ * Standard Character Set: Choose this option if you want to use
+ latin1 as the default server character set. latin1 is used for
+ English and many Western European languages.
+
+ * Best Support For Multilingualism: Choose this option if you
+ want to use utf8 as the default server character set. This is
+ a Unicode character set that can store characters from many
+ different languages.
+
+ * Manual Selected Default Character Set / Collation: Choose this
+ option if you want to pick the server's default character set
+ manually. Choose the desired character set from the provided
+ drop-down list.
+
+2.5.4.10. The Service Options Dialog
+
+ On Windows platforms, the MySQL server can be installed as a
+ Windows service. When installed this way, the MySQL server can be
+ started automatically during system startup, and even restarted
+ automatically by Windows in the event of a service failure.
+
+ The MySQL Server Instance Config Wizard installs the MySQL server
+ as a service by default, using the service name MySQL. If you do
+ not wish to install the service, uncheck the box next to the
+ Install As Windows Service option. You can change the service name
+ by picking a new service name from the drop-down box provided or
+ by entering a new service name into the drop-down box.
+
+Note
+
+ Service names can include any legal character except forward (/)
+ or backward (\) slashes, and must be less than 256 characters
+ long.
Warning
- We have seen some strange problems with Linux 2.2.14 and MySQL on
- SMP systems. We also have reports from some MySQL users that they
- have encountered serious stability problems using MySQL with
- kernel 2.2.14. If you are using this kernel, you should upgrade to
- 2.2.19 (or newer) or to a 2.4 kernel. If you have a multiple-CPU
- box, you should seriously consider using 2.4 because it gives you
- a significant speed boost. Your system should be more stable.
-
- When using LinuxThreads, you should see a minimum of three mysqld
- processes running. These are in fact threads. There is one thread
- for the LinuxThreads manager, one thread to handle connections,
- and one thread to handle alarms and signals.
-
-2.13.1.2. Linux Binary Distribution Notes
-
- The Linux-Intel binary and RPM releases of MySQL are configured
- for the highest possible speed. We are always trying to use the
- fastest stable compiler available.
-
- The binary release is linked with -static, which means you do not
- normally need to worry about which version of the system libraries
- you have. You need not install LinuxThreads, either. A program
- linked with -static is slightly larger than a dynamically linked
- program, but also slightly faster (3-5%). However, one problem
- with a statically linked program is that you can't use
- user-defined functions (UDFs). If you are going to write or use
- UDFs (this is something for C or C++ programmers only), you must
- compile MySQL yourself using dynamic linking.
-
- A known issue with binary distributions is that on older Linux
- systems that use libc (such as Red Hat 4.x or Slackware), you get
- some (nonfatal) issues with host name resolution. If your system
- uses libc rather than glibc2, you probably will encounter some
- difficulties with host name resolution and getpwnam(). This
- happens because glibc (unfortunately) depends on some external
- libraries to implement host name resolution and getpwent(), even
- when compiled with -static. These problems manifest themselves in
- two ways:
-
- * You may see the following error message when you run
- mysql_install_db:
-Sorry, the host 'xxxx' could not be looked up
- You can deal with this by executing mysql_install_db --force,
- which does not execute the resolveip test in mysql_install_db.
- The downside is that you cannot use host names in the grant
- tables: except for localhost, you must use IP numbers instead.
- If you are using an old version of MySQL that does not support
- --force, you must manually remove the resolveip test in
- mysql_install_db using a text editor.
-
- * You also may see the following error when you try to run
- mysqld with the --user option:
-getpwnam: No such file or directory
- To work around this problem, start mysqld by using the su
- command rather than by specifying the --user option. This
- causes the system itself to change the user ID of the mysqld
- process so that mysqld need not do so.
-
- Another solution, which solves both problems, is not to use a
- binary distribution. Obtain a MySQL source distribution (in RPM or
- tar.gz format) and install that instead.
-
- On some Linux 2.2 versions, you may get the error Resource
- temporarily unavailable when clients make a great many new
- connections to a mysqld server over TCP/IP. The problem is that
- Linux has a delay between the time that you close a TCP/IP socket
- and the time that the system actually frees it. There is room for
- only a finite number of TCP/IP slots, so you encounter the
- resource-unavailable error if clients attempt too many new TCP/IP
- connections over a short period of time. For example, you may see
- the error when you run the MySQL test-connect benchmark over
- TCP/IP.
-
- We have inquired about this problem a few times on different Linux
- mailing lists but have never been able to find a suitable
- resolution. The only known "fix" is for clients to use persistent
- connections, or, if you are running the database server and
- clients on the same machine, to use Unix socket file connections
- rather than TCP/IP connections.
-
-2.13.1.3. Linux Source Distribution Notes
-
- The following notes regarding glibc apply only to the situation
- when you build MySQL yourself. If you are running Linux on an x86
- machine, in most cases it is much better for you to use our
- binary. We link our binaries against the best patched version of
- glibc we can find and with the best compiler options, in an
- attempt to make it suitable for a high-load server. For a typical
- user, even for setups with a lot of concurrent connections or
- tables exceeding the 2GB limit, our binary is the best choice in
- most cases. After reading the following text, if you are in doubt
- about what to do, try our binary first to determine whether it
- meets your needs. If you discover that it is not good enough, you
- may want to try your own build. In that case, we would appreciate
- a note about it so that we can build a better binary next time.
-
- MySQL uses LinuxThreads on Linux. If you are using an old Linux
- version that doesn't have glibc2, you must install LinuxThreads
- before trying to compile MySQL. You can obtain LinuxThreads from
- http://dev.mysql.com/downloads/os-linux.html.
-
- Note that glibc versions before and including version 2.1.1 have a
- fatal bug in pthread_mutex_timedwait() handling, which is used
- when INSERT DELAYED statements are issued. Do not use INSERT
- DELAYED before upgrading glibc.
-
- Note that Linux kernel and the LinuxThread library can by default
- handle a maximum of 1,024 threads. If you plan to have more than
- 1,000 concurrent connections, you need to make some changes to
- LinuxThreads, as follows:
-
- * Increase PTHREAD_THREADS_MAX in
- sysdeps/unix/sysv/linux/bits/local_lim.h to 4096 and decrease
- STACK_SIZE in linuxthreads/internals.h to 256KB. The paths are
- relative to the root of glibc. (Note that MySQL is not stable
- with 600-1000 connections if STACK_SIZE is the default of
- 2MB.)
-
- * Recompile LinuxThreads to produce a new libpthread.a library,
- and relink MySQL against it.
-
- There is another issue that greatly hurts MySQL performance,
- especially on SMP systems. The mutex implementation in
- LinuxThreads in glibc 2.1 is very poor for programs with many
- threads that hold the mutex only for a short time. This produces a
- paradoxical result: If you link MySQL against an unmodified
- LinuxThreads, removing processors from an SMP actually improves
- MySQL performance in many cases. We have made a patch available
- for glibc 2.1.3 to correct this behavior
- (http://dev.mysql.com/Downloads/Linux/linuxthreads-2.1-patch).
-
- With glibc 2.2.2, MySQL uses the adaptive mutex, which is much
- better than even the patched one in glibc 2.1.3. Be warned,
- however, that under some conditions, the current mutex code in
- glibc 2.2.2 overspins, which hurts MySQL performance. The
- likelihood that this condition occurs can be reduced by re-nicing
- the mysqld process to the highest priority. We have also been able
- to correct the overspin behavior with a patch, available at
- http://dev.mysql.com/Downloads/Linux/linuxthreads-2.2.2.patch. It
- combines the correction of overspin, maximum number of threads,
- and stack spacing all in one. You need to apply it in the
- linuxthreads directory with patch -p0
- </tmp/linuxthreads-2.2.2.patch. We hope it is included in some
- form in future releases of glibc 2.2. In any case, if you link
- against glibc 2.2.2, you still need to correct STACK_SIZE and
- PTHREAD_THREADS_MAX. We hope that the defaults is corrected to
- some more acceptable values for high-load MySQL setup in the
- future, so that the commands needed to produce your own build can
- be reduced to ./configure; make; make install.
-
- If you use these patches to build a special static version of
- libpthread.a, use it only for statically linking against MySQL. We
- know that these patches are safe for MySQL and significantly
- improve its performance, but we cannot say anything about their
- effects on other applications. If you link other applications that
- require LinuxThreads against the patched static version of the
- library, or build a patched shared version and install it on your
- system, you do so at your own risk.
-
- If you experience any strange problems during the installation of
- MySQL, or with some common utilities hanging, it is very likely
- that they are either library or compiler related. If this is the
- case, using our binary resolves them.
+ If you are installing multiple versions of MySQL onto the same
+ machine, you must choose a different service name for each version
+ that you install. If you do not choose a different service for
+ each installed version then the service manager information will
+ be inconsistent and this will cause problems when you try to
+ uninstall a previous version.
- If you link your own MySQL client programs, you may see the
- following error at runtime:
-ld.so.1: fatal: libmysqlclient.so.#:
-open failed: No such file or directory
+ If you have already installed multiple versions using the same
+ service name, you must manually edit the contents of the
+ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services parameters
+ within the Windows registry to update the association of the
+ service name with the correct server version.
- This problem can be avoided by one of the following methods:
+ Typically, when installing multiple versions you create a service
+ name based on the version information. For example, you might
+ install MySQL 5.x as mysql5, or specific versions such as MySQL
+ 5.1.30 as mysql50130.
- * Link clients with the -Wl,r/full/path/to/libmysqlclient.so
- flag rather than with -Lpath).
+ To install the MySQL server as a service but not have it started
+ automatically at startup, uncheck the box next to the Launch the
+ MySQL Server Automatically option.
- * Copy libmysqclient.so to /usr/lib.
+2.5.4.11. The Security Options Dialog
- * Add the path name of the directory where libmysqlclient.so is
- located to the LD_RUN_PATH environment variable before running
- your client.
+ It is strongly recommended that you set a root password for your
+ MySQL server, and the MySQL Server Instance Config Wizard requires
+ by default that you do so. If you do not wish to set a root
+ password, uncheck the box next to the Modify Security Settings
+ option.
+ MySQL Server Instance Config Wizard: Security
- If you are using the Fujitsu compiler (fcc/FCC), you may have some
- problems compiling MySQL because the Linux header files are very
- gcc oriented. The following configure line should work with
- fcc/FCC:
-CC=fcc CFLAGS="-O -K fast -K lib -K omitfp -Kpreex -D_GNU_SOURCE \
- -DCONST=const -DNO_STRTOLL_PROTO" \
-CXX=FCC CXXFLAGS="-O -K fast -K lib \
- -K omitfp -K preex --no_exceptions --no_rtti -D_GNU_SOURCE \
- -DCONST=const -Dalloca=__builtin_alloca -DNO_STRTOLL_PROTO \
- '-D_EXTERN_INLINE=static __inline'" \
-./configure \
- --prefix=/usr/local/mysql --enable-assembler \
- --with-mysqld-ldflags=-all-static --disable-shared \
- --with-low-memory
+ To set the root password, enter the desired password into both the
+ New root password and Confirm boxes. If you are reconfiguring an
+ existing server, you need to enter the existing root password into
+ the Current root password box.
+
+ To allow root logins from across the network, check the box next
+ to the Enable root access from remote machines option. This
+ decreases the security of your root account.
+
+ To create an anonymous user account, check the box next to the
+ Create An Anonymous Account option. Creating an anonymous account
+ can decrease server security and cause login and permission
+ difficulties. For this reason, it is not recommended.
+
+2.5.4.12. The Confirmation Dialog
+
+ The final dialog in the MySQL Server Instance Config Wizard is the
+ Confirmation Dialog. To start the configuration process, click the
+ Execute button. To return to a previous dialog, click the Back
+ button. To exit the MySQL Server Instance Config Wizard without
+ configuring the server, click the Cancel button.
+ MySQL Server Instance Config Wizard: Confirmation
+
+ After you click the Execute button, the MySQL Server Instance
+ Config Wizard performs a series of tasks and displays the progress
+ onscreen as the tasks are performed.
+
+ The MySQL Server Instance Config Wizard first determines
+ configuration file options based on your choices using a template
+ prepared by MySQL developers and engineers. This template is named
+ my-template.ini and is located in your server installation
+ directory.
+
+ The MySQL Config Wizard then writes these options to the
+ corresponding configuration file.
+
+ If you chose to create a service for the MySQL server, the MySQL
+ Server Instance Config Wizard creates and starts the service. If
+ you are reconfiguring an existing service, the MySQL Server
+ Instance Config Wizard restarts the service to apply your
+ configuration changes.
+
+ If you chose to set a root password, the MySQL Config Wizard
+ connects to the server, sets your new root password, and applies
+ any other security settings you may have selected.
+
+ After the MySQL Server Instance Config Wizard has completed its
+ tasks, it displays a summary. Click the Finish button to exit the
+ MySQL Server Config Wizard.
+
+2.5.4.13. Creating an Instance from the Command Line
+
+ In addition to using the GUI interface to the MySQL Server
+ Instance Config Wizard, you can also create instances
+ automatically from the command line.
+
+ To use the MySQL Server Instance Config Wizard on the command
+ line, you need to use the MySQLInstanceConfig.exe command that is
+ installed with MySQL in the bin directory within the installation
+ directory. MySQLInstanceConfig.exe takes a number of command-line
+ arguments the set the properties that would normally be selected
+ through the GUI interface, and then creates a new configuration
+ file (my.ini) by combining these selections with a template
+ configuration file to produce the working configuration file.
+
+ The main command line options are provided in the table below.
+ Some of the options are required, while some options are optional.
+
+ Table 2.4. MySQL Server Instance Config Wizard Command Line
+ Options
+ Option Description
+ Required Parameters
+ -nPRODUCTNAME The name of the instance when installed
+ -pPATH Path of the base directory for installation. This is
+ equivalent to the directory when using the basedir configuration
+ parameter
+ -vVERSION The version tag to use for this installation
+ Action to Perform
+ -i Install an instance
+ -r Remove an instance
+ -s Stop an existing instance
+ -q Perform the operation quietly
+ -lFILENAME Sae the installation progress in a logfile
+ Config File to Use
+ -tFILENAME Path to the template config file that will be used to
+ generate the installed configuration file
+ -cFILENAME Path to a config file to be generated
+
+ The -t and -c options work together to set the configuration
+ parameters for a new instance. The -t option specifies the
+ template configuration file to use as the basic configuration,
+ which are then merged with the configuration parameters generated
+ by the MySQL Server Instance Config Wizard into the configuration
+ file specified by the -c option.
+
+ A sample template file, my-template.ini is provided in the
+ toplevel MySQL installation directory. The file contains elements
+ are replaced automatically by the MySQL Server Instance Config
+ Wizard during configuration.
+
+ If you specify a configuration file that already exists, the
+ existing configuration file will be saved in the file with the
+ original, with the date and time added. For example, the mysql.ini
+ will be copied to mysql 2009-10-27 1646.ini.bak.
+
+ The parameters that you can specify on the command line are listed
+ in the table below.
+
+ Table 2.5. MySQL Server Instance Config Wizard Parameters
+ Parameter Description
+ ServiceName=$ Specify the name of the service to be created
+ AddBinToPath={yes | no} Specifies whether to add the binary
+ directory of MySQL to the standard PATH environment variable
+ ServerType={DEVELOPMENT | SERVER | DEDICATED} Specify the server
+ type. For more information, see Section 2.5.4.4, "The Server Type
+ Dialog"
+ DatabaseType={MIXED | INNODB | MYISAM} Specify the default
+ database type. For more information, see Section 2.5.4.5, "The
+ Database Usage Dialog"
+ ConnectionUsage={DSS | OLTP} Specify the type of connection
+ support, this automates the setting for the number of concurrent
+ connections (see the ConnectionCount parameter). For more
+ information, see Section 2.5.4.7, "The Concurrent Connections
+ Dialog"
+ ConnectionCount=# Specify the number of concurrent connections to
+ support. For more information, see Section 2.5.4.4, "The Server
+ Type Dialog"
+ SkipNetworking={yes | no} Specify whether network support should
+ be supported. Specifying yes disables network access altogether
+ Port=# Specify the network port number to use for network
+ connections. For more information, see Section 2.5.4.8, "The
+ Networking and Strict Mode Options Dialog"
+ StrictMode={yes | no} Specify whether to use the strict SQL mode.
+ For more information, see Section 2.5.4.8, "The Networking and
+ Strict Mode Options Dialog"
+ Charset=$ Specify the default character set. For more information,
+ see Section 2.5.4.9, "The Character Set Dialog"
+ RootPassword=$ Specify the root password
+ RootCurrentPassword=$ Specify the current root password then
+ stopping and/or reconfiguring an existing service
+
+Note
+
+ When specifying options on the command line, you can enclose the
+ entire command-line option and the value you are specifying using
+ double quotes. This enables you to use spaces in the options. For
+ example, "-cC:\mysql.ini".
+
+ The following command installs a MySQL Server 5.1 instance from
+ the directory C:\Program Files\MySQL\MySQL Server 5.1 using the
+ service name MySQL51 and setting the root password to 1234.
+shell> MySQLInstanceConfig.exe -i -q "-lC:\mysql_install_log.txt" »
+ "-nMySQL Server 5.1" "-pC:\Program Files\MySQL\MySQL Server 5.1" -
+v5.1.39 »
+ "-tmy-template.ini" "-cC:\mytest.ini" ServerType=DEVELOPMENT Datab
+aseType=MIXED »
+ ConnectionUsage=DSS Port=3311 ServiceName=MySQL51 RootPassword=123
+4
+
+ In the above example, a log file will be generated in
+ mysql_install_log.txt containing the information about the
+ instance creation process. The log file generated by the above
+ example is shown below:
+Welcome to the MySQL Server Instance Configuration Wizard 1.0.16.0
+Date: 2009-10-27 17:07:21
+
+Installing service ...
+
+Product Name: MySQL Server 5.1
+Version: 5.1.39
+Installation Path: C:\Program Files\MySQL\MySQL Server 5.1\
+
+Creating configuration file C:\mytest.ini using template my-template.
+ini.
+Options:
+DEVELOPMENT
+MIXED
+DSS
+STRICTMODE
+
+Variables:
+port: 3311
+default-character-set: latin1
+basedir: "C:/Program Files/MySQL/MySQL Server 5.1/"
+datadir: "C:/Program Files/MySQL/MySQL Server 5.1/Data/"
+
+
+Creating Windows service entry.
+Service name: "MySQL51"
+Parameters: "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld" --
+defaults-file="C:\mytest.ini" MySQL51.
+Windows service MySQL51 installed.
+
+ When using the command-line, the return values in the following
+ table indicate an error performing the specified option.
+
+ Table 2.6. Return Value from MySQL Server Instance Config Wizard
+ Value Description
+ 2 Configuration template file cannot be found
+ 3 The Windows service entry cannot be created
+ 4 Could not connect to the Service Control Manager
+ 5 The MySQL service cannot be started
+ 6 The MySQL service cannot be stopped
+ 7 The security settings cannot be applied
+ 8 The configuration file cannot be written
+ 9 The Windows service entry cannot be removed
+
+ You can perform an installation of MySQL automatically using the
+ MSI packe. For more information, see Section 2.5.3.2, "Installing
+ MySQL Automatically using MSI."
+
+2.5.5. Installing MySQL from a noinstall Zip Archive
+
+ Users who are installing from the noinstall package can use the
+ instructions in this section to manually install MySQL. The
+ process for installing MySQL from a Zip archive is as follows:
+
+ 1. Extract the archive to the desired install directory
+
+ 2. Create an option file
+
+ 3. Choose a MySQL server type
+
+ 4. Start the MySQL server
+
+ 5. Secure the default user accounts
+
+ This process is described in the sections that follow.
+
+2.5.5.1. Extracting the Install Archive
+
+ To install MySQL manually, do the following:
+
+ 1. If you are upgrading from a previous version please refer to
+ Section 2.5.7, "Upgrading MySQL on Windows," before beginning
+ the upgrade process.
+
+ 2. Make sure that you are logged in as a user with administrator
+ privileges.
+
+ 3. Choose an installation location. Traditionally, the MySQL
+ server is installed in C:\mysql. The MySQL Installation Wizard
+ installs MySQL under C:\Program Files\MySQL. If you do not
+ install MySQL at C:\mysql, you must specify the path to the
+ install directory during startup or in an option file. See
+ Section 2.5.5.2, "Creating an Option File."
+
+ 4. Extract the install archive to the chosen installation
+ location using your preferred Zip archive tool. Some tools may
+ extract the archive to a folder within your chosen
+ installation location. If this occurs, you can move the
+ contents of the subfolder into the chosen installation
+ location.
+
+2.5.5.2. Creating an Option File
+
+ If you need to specify startup options when you run the server,
+ you can indicate them on the command line or place them in an
+ option file. For options that are used every time the server
+ starts, you may find it most convenient to use an option file to
+ specify your MySQL configuration. This is particularly true under
+ the following circumstances:
+
+ * The installation or data directory locations are different
+ from the default locations (C:\Program Files\MySQL\MySQL
+ Server 5.1 and C:\Program Files\MySQL\MySQL Server 5.1\data).
+
+ * You need to tune the server settings, such as memory, cache,
+ or InnoDB configuration information.
+
+ When the MySQL server starts on Windows, it looks for option files
+ in several locations, such as the Windows directory, C:\, and the
+ MySQL installation directory (for the full list of locations, see
+ Section 4.2.3.3, "Using Option Files"). The Windows directory
+ typically is named something like C:\WINDOWS. You can determine
+ its exact location from the value of the WINDIR environment
+ variable using the following command:
+C:\> echo %WINDIR%
+
+ MySQL looks for options in each location first in the my.ini file,
+ and then in the my.cnf file. However, to avoid confusion, it is
+ best if you use only one file. If your PC uses a boot loader where
+ C: is not the boot drive, your only option is to use the my.ini
+ file. Whichever option file you use, it must be a plain text file.
+
+ You can also make use of the example option files included with
+ your MySQL distribution; see Section 4.2.3.3.2, "Preconfigured
+ Option Files."
+
+ An option file can be created and modified with any text editor,
+ such as Notepad. For example, if MySQL is installed in E:\mysql
+ and the data directory is in E:\mydata\data, you can create an
+ option file containing a [mysqld] section to specify values for
+ the basedir and datadir options:
+[mysqld]
+# set basedir to your installation path
+basedir=E:/mysql
+# set datadir to the location of your data directory
+datadir=E:/mydata/data
+
+ Note that Windows path names are specified in option files using
+ (forward) slashes rather than backslashes. If you do use
+ backslashes, double them:
+[mysqld]
+# set basedir to your installation path
+basedir=E:\\mysql
+# set datadir to the location of your data directory
+datadir=E:\\mydata\\data
+
+ The rules for use of backslash in option file values are given in
+ Section 4.2.3.3, "Using Option Files."
+
+ MySQL Enterprise For expert advice on the start-up options
+ appropriate to your circumstances, subscribe to the MySQL
+ Enterprise Monitor. For more information, see
+ http://www.mysql.com/products/enterprise/advisors.html.
+
+ In MySQL 5.1.23 and earlier, the MySQL installer places the data
+ directory directly under the directory where you install MySQL. On
+ MySQL 5.1.24 and later, the data directory is located within the
+ AppData directory for the user running MySQL.
+
+ If you would like to use a data directory in a different location,
+ you should copy the entire contents of the data directory to the
+ new location. For example, if you want to use E:\mydata as the
+ data directory instead, you must do two things:
+
+ 1. Move the entire data directory and all of its contents from
+ the default location (for example C:\Program Files\MySQL\MySQL
+ Server 5.1\data) to E:\mydata.
+
+ 2. Use a --datadir option to specify the new data directory
+ location each time you start the server.
+
+2.5.5.3. Selecting a MySQL Server Type
+
+ The following table shows the available servers for Windows in
+ MySQL 5.1.20 and earlier.
+ Binary Description
+ mysqld-nt Optimized binary with named-pipe support
+ mysqld Optimized binary without named-pipe support
+ mysqld-debug Like mysqld-nt, but compiled with full debugging and
+ automatic memory allocation checking
+
+ The following table shows the available servers for Windows in
+ MySQL 5.1.21 and later.
+ Binary Description
+ mysqld Optimized binary with named-pipe support
+ mysqld-debug Like mysqld, but compiled with full debugging and
+ automatic memory allocation checking
+
+ All of the preceding binaries are optimized for modern Intel
+ processors, but should work on any Intel i386-class or higher
+ processor.
+
+ Each of the servers in a distribution support the same set of
+ storage engines. The SHOW ENGINES statement displays which engines
+ a given server supports.
+
+ All Windows MySQL 5.1 servers have support for symbolic linking of
+ database directories.
+
+ MySQL supports TCP/IP on all Windows platforms. MySQL servers on
+ Windows support named pipes as indicated in the following list.
+ However, the default is to use TCP/IP regardless of platform.
+ (Named pipes are slower than TCP/IP in many Windows
+ configurations.)
+
+ Use of named pipes is subject to these conditions:
+
+ * Named pipes are enabled only if you start the server with the
+ --enable-named-pipe option. It is necessary to use this option
+ explicitly because some users have experienced problems with
+ shutting down the MySQL server when named pipes were used.
+
+ * For MySQL 5.1.20 and earlier, named-pipe connections are
+ allowed only by the mysqld-nt and mysqld-debug servers. For
+ MySQL 5.1.21 and later, the mysqld and mysqld-debug servers
+ both contain support for named-pipe connections.
+
+Note
+
+ Most of the examples in this manual use mysqld as the server name.
+ If you choose to use a different server, such as mysqld-nt or
+ mysqld-debug, make the appropriate substitutions in the commands
+ that are shown in the examples.
+
+2.5.5.4. Starting the Server for the First Time
+
+ This section gives a general overview of starting the MySQL
+ server. The following sections provide more specific information
+ for starting the MySQL server from the command line or as a
+ Windows service.
+
+ The information here applies primarily if you installed MySQL
+ using the Noinstall version, or if you wish to configure and test
+ MySQL manually rather than with the GUI tools.
+
+ The examples in these sections assume that MySQL is installed
+ under the default location of C:\Program Files\MySQL\MySQL Server
+ 5.1. Adjust the path names shown in the examples if you have MySQL
+ installed in a different location.
+
+ Clients have two options. They can use TCP/IP, or they can use a
+ named pipe if the server supports named-pipe connections.
+
+ MySQL for Windows also supports shared-memory connections if the
+ server is started with the --shared-memory option. Clients can
+ connect through shared memory by using the --protocol=MEMORY
+ option.
+
+ For information about which server binary to run, see Section
+ 2.5.5.3, "Selecting a MySQL Server Type."
+
+ Testing is best done from a command prompt in a console window (or
+ "DOS window"). In this way you can have the server display status
+ messages in the window where they are easy to see. If something is
+ wrong with your configuration, these messages make it easier for
+ you to identify and fix any problems.
+
+ To start the server, enter this command:
+C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld" --console
+
+ For a server that includes InnoDB support, you should see the
+ messages similar to those following as it starts (the path names
+ and sizes may differ):
+InnoDB: The first specified datafile c:\ibdata\ibdata1 did not exist:
+InnoDB: a new database to be created!
+InnoDB: Setting file c:\ibdata\ibdata1 size to 209715200
+InnoDB: Database physically writes the file full: wait...
+InnoDB: Log file c:\iblogs\ib_logfile0 did not exist: new to be creat
+ed
+InnoDB: Setting log file c:\iblogs\ib_logfile0 size to 31457280
+InnoDB: Log file c:\iblogs\ib_logfile1 did not exist: new to be creat
+ed
+InnoDB: Setting log file c:\iblogs\ib_logfile1 size to 31457280
+InnoDB: Log file c:\iblogs\ib_logfile2 did not exist: new to be creat
+ed
+InnoDB: Setting log file c:\iblogs\ib_logfile2 size to 31457280
+InnoDB: Doublewrite buffer not found: creating new
+InnoDB: Doublewrite buffer created
+InnoDB: creating foreign key constraint system tables
+InnoDB: foreign key constraint system tables created
+011024 10:58:25 InnoDB: Started
+
+ When the server finishes its startup sequence, you should see
+ something like this, which indicates that the server is ready to
+ service client connections:
+mysqld: ready for connections
+Version: '5.1.41' socket: '' port: 3306
+
+ The server continues to write to the console any further
+ diagnostic output it produces. You can open a new console window
+ in which to run client programs.
+
+ If you omit the --console option, the server writes diagnostic
+ output to the error log in the data directory (C:\Program
+ Files\MySQL\MySQL Server 5.1\data by default). The error log is
+ the file with the .err extension.
+
+Note
+
+ The accounts that are listed in the MySQL grant tables initially
+ have no passwords. After starting the server, you should set up
+ passwords for them using the instructions in Section 2.13,
+ "Post-Installation Setup and Testing."
+
+2.5.5.5. Starting MySQL from the Windows Command Line
+
+ The MySQL server can be started manually from the command line.
+ This can be done on any version of Windows.
+
+ To start the mysqld server from the command line, you should start
+ a console window (or "DOS window") and enter this command:
+C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld"
+
+ The path to mysqld may vary depending on the install location of
+ MySQL on your system.
+
+ You can stop the MySQL server by executing this command:
+C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqladmin" -u root
+ shutdown
+
+Note
+
+ If the MySQL root user account has a password, you need to invoke
+ mysqladmin with the -p option and supply the password when
+ prompted.
+
+ This command invokes the MySQL administrative utility mysqladmin
+ to connect to the server and tell it to shut down. The command
+ connects as the MySQL root user, which is the default
+ administrative account in the MySQL grant system. Note that users
+ in the MySQL grant system are wholly independent from any login
+ users under Windows.
+
+ If mysqld doesn't start, check the error log to see whether the
+ server wrote any messages there to indicate the cause of the
+ problem. The error log is located in the C:\Program
+ Files\MySQL\MySQL Server 5.1\data directory. It is the file with a
+ suffix of .err. You can also try to start the server as mysqld
+ --console; in this case, you may get some useful information on
+ the screen that may help solve the problem.
+
+ The last option is to start mysqld with the --standalone and
+ --debug options. In this case, mysqld writes a log file
+ C:\mysqld.trace that should contain the reason why mysqld doesn't
+ start. See MySQL Internals: Porting
+ (http://forge.mysql.com/wiki/MySQL_Internals_Porting).
+
+ Use mysqld --verbose --help to display all the options that mysqld
+ supports.
+
+2.5.5.6. Starting MySQL as a Windows Service
+
+ On Windows, the recommended way to run MySQL is to install it as a
+ Windows service, whereby MySQL starts and stops automatically when
+ Windows starts and stops. A MySQL server installed as a service
+ can also be controlled from the command line using NET commands,
+ or with the graphical Services utility. Generally, to install
+ MySQL as a Windows service you should be logged in using an
+ account that has administrator rights.
+
+ The Services utility (the Windows Service Control Manager) can be
+ found in the Windows Control Panel (under Administrative Tools on
+ Windows 2000, XP, Vista and Server 2003). To avoid conflicts, it
+ is advisable to close the Services utility while performing server
+ installation or removal operations from the command line.
+
+ Before installing MySQL as a Windows service, you should first
+ stop the current server if it is running by using the following
+ command:
+C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqladmin"
+ -u root shutdown
+
+Note
+
+ If the MySQL root user account has a password, you need to invoke
+ mysqladmin with the -p option and supply the password when
+ prompted.
+
+ This command invokes the MySQL administrative utility mysqladmin
+ to connect to the server and tell it to shut down. The command
+ connects as the MySQL root user, which is the default
+ administrative account in the MySQL grant system. Note that users
+ in the MySQL grant system are wholly independent from any login
+ users under Windows.
+
+ Install the server as a service using this command:
+C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld" --install
+
+ The service-installation command does not start the server.
+ Instructions for that are given later in this section.
+
+ To make it easier to invoke MySQL programs, you can add the path
+ name of the MySQL bin directory to your Windows system PATH
+ environment variable:
+
+ * On the Windows desktop, right-click on the My Computer icon,
+ and select Properties.
+
+ * Next select the Advanced tab from the System Properties menu
+ that appears, and click the Environment Variables button.
+
+ * Under System Variables, select Path, and then click the Edit
+ button. The Edit System Variable dialogue should appear.
+
+ * Place your cursor at the end of the text appearing in the
+ space marked Variable Value. (Use the End key to ensure that
+ your cursor is positioned at the very end of the text in this
+ space.) Then enter the complete path name of your MySQL bin
+ directory (for example, C:\Program Files\MySQL\MySQL Server
+ 5.1\bin), Note that there should be a semicolon separating
+ this path from any values present in this field. Dismiss this
+ dialogue, and each dialogue in turn, by clicking OK until all
+ of the dialogues that were opened have been dismissed. You
+ should now be able to invoke any MySQL executable program by
+ typing its name at the DOS prompt from any directory on the
+ system, without having to supply the path. This includes the
+ servers, the mysql client, and all MySQL command-line
+ utilities such as mysqladmin and mysqldump.
+ You should not add the MySQL bin directory to your Windows
+ PATH if you are running multiple MySQL servers on the same
+ machine.
+
+Warning
+
+ You must exercise great care when editing your system PATH by
+ hand; accidental deletion or modification of any portion of the
+ existing PATH value can leave you with a malfunctioning or even
+ unusable system.
+
+ The following additional arguments can be used in MySQL 5.1 when
+ installing the service:
+
+ * You can specify a service name immediately following the
+ --install option. The default service name is MySQL.
+
+ * If a service name is given, it can be followed by a single
+ option. By convention, this should be
+ --defaults-file=file_name to specify the name of an option
+ file from which the server should read options when it starts.
+ The use of a single option other than --defaults-file is
+ possible but discouraged. --defaults-file is more flexible
+ because it enables you to specify multiple startup options for
+ the server by placing them in the named option file.
+
+ * You can also specify a --local-service option following the
+ service name. This causes the server to run using the
+ LocalService Windows account that has limited system
+ privileges. This account is available only for Windows XP or
+ newer. If both --defaults-file and --local-service are given
+ following the service name, they can be in any order.
+
+ For a MySQL server that is installed as a Windows service, the
+ following rules determine the service name and option files that
+ the server uses:
+
+ * If the service-installation command specifies no service name
+ or the default service name (MySQL) following the --install
+ option, the server uses the a service name of MySQL and reads
+ options from the [mysqld] group in the standard option files.
+
+ * If the service-installation command specifies a service name
+ other than MySQL following the --install option, the server
+ uses that service name. It reads options from the [mysqld]
+ group and the group that has the same name as the service in
+ the standard option files. This allows you to use the [mysqld]
+ group for options that should be used by all MySQL services,
+ and an option group with the service name for use by the
+ server installed with that service name.
+
+ * If the service-installation command specifies a
+ --defaults-file option after the service name, the server
+ reads options only from the [mysqld] group of the named file
+ and ignores the standard option files.
+
+ As a more complex example, consider the following command:
+C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld"
+ --install MySQL --defaults-file=C:\my-opts.cnf
+
+ Here, the default service name (MySQL) is given after the
+ --install option. If no --defaults-file option had been given,
+ this command would have the effect of causing the server to read
+ the [mysqld] group from the standard option files. However,
+ because the --defaults-file option is present, the server reads
+ options from the [mysqld] option group, and only from the named
+ file.
+
+ You can also specify options as Start parameters in the Windows
+ Services utility before you start the MySQL service.
+
+ Once a MySQL server has been installed as a service, Windows
+ starts the service automatically whenever Windows starts. The
+ service also can be started immediately from the Services utility,
+ or by using a NET START MySQL command. The NET command is not case
+ sensitive.
+
+ When run as a service, mysqld has no access to a console window,
+ so no messages can be seen there. If mysqld does not start, check
+ the error log to see whether the server wrote any messages there
+ to indicate the cause of the problem. The error log is located in
+ the MySQL data directory (for example, C:\Program
+ Files\MySQL\MySQL Server 5.1\data). It is the file with a suffix
+ of .err.
+
+ When a MySQL server has been installed as a service, and the
+ service is running, Windows stops the service automatically when
+ Windows shuts down. The server also can be stopped manually by
+ using the Services utility, the NET STOP MySQL command, or the
+ mysqladmin shutdown command.
+
+ You also have the choice of installing the server as a manual
+ service if you do not wish for the service to be started
+ automatically during the boot process. To do this, use the
+ --install-manual option rather than the --install option:
+C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld" --install-m
+anual
+
+ To remove a server that is installed as a service, first stop it
+ if it is running by executing NET STOP MySQL. Then use the
+ --remove option to remove it:
+C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld" --remove
+
+ If mysqld is not running as a service, you can start it from the
+ command line. For instructions, see Section 2.5.5.5, "Starting
+ MySQL from the Windows Command Line."
+
+ Please see Section 2.5.6, "Troubleshooting a MySQL Installation
+ Under Windows," if you encounter difficulties during installation.
+
+2.5.5.7. Testing The MySQL Installation
+
+ You can test whether the MySQL server is working by executing any
+ of the following commands:
+C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqlshow"
+C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqlshow" -u root
+mysql
+C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqladmin" version
+ status proc
+C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysql" test
+
+Note
+
+ By default, mysqlshow will try to connect using the ODBC user.
+ This user is not created by default. You should specify a valid
+ user, or root with the right password to check the operation of
+ the server.
+
+ If mysqld is slow to respond to TCP/IP connections from client
+ programs, there is probably a problem with your DNS. In this case,
+ start mysqld with the --skip-name-resolve option and use only
+ localhost and IP numbers in the Host column of the MySQL grant
+ tables.
+
+ You can force a MySQL client to use a named-pipe connection rather
+ than TCP/IP by specifying the --pipe or --protocol=PIPE option, or
+ by specifying . (period) as the host name. Use the --socket option
+ to specify the name of the pipe if you do not want to use the
+ default pipe name.
+
+ Note that if you have set a password for the root account, deleted
+ the anonymous account, or created a new user account, then you
+ must use the appropriate -u and -p options with the commands shown
+ above in order to connect with the MySQL Server. See Section
+ 4.2.2, "Connecting to the MySQL Server."
+
+ For more information about mysqlshow, see Section 4.5.6,
+ "mysqlshow --- Display Database, Table, and Column Information."
+
+2.5.6. Troubleshooting a MySQL Installation Under Windows
+
+ When installing and running MySQL for the first time, you may
+ encounter certain errors that prevent the MySQL server from
+ starting. The purpose of this section is to help you diagnose and
+ correct some of these errors.
+
+ Your first resource when troubleshooting server issues is the
+ error log. The MySQL server uses the error log to record
+ information relevant to the error that prevents the server from
+ starting. The error log is located in the data directory specified
+ in your my.ini file. The default data directory location is
+ C:\Program Files\MySQL\MySQL Server 5.1\data. See Section 5.2.2,
+ "The Error Log."
+
+ Another source of information regarding possible errors is the
+ console messages displayed when the MySQL service is starting. Use
+ the NET START MySQL command from the command line after installing
+ mysqld as a service to see any error messages regarding the
+ starting of the MySQL server as a service. See Section 2.5.5.6,
+ "Starting MySQL as a Windows Service."
+
+ The following examples show other common error messages you may
+ encounter when installing MySQL and starting the server for the
+ first time:
+
+ * If the MySQL server cannot find the mysql privileges database
+ or other critical files, you may see these messages:
+System error 1067 has occurred.
+Fatal error: Can't open privilege tables: Table 'mysql.host' doesn't
+exist
+ These messages often occur when the MySQL base or data
+ directories are installed in different locations than the
+ default locations (C:\Program Files\MySQL\MySQL Server 5.1 and
+ C:\Program Files\MySQL\MySQL Server 5.1\data, respectively).
+ This situation may occur when MySQL is upgraded and installed
+ to a new location, but the configuration file is not updated
+ to reflect the new location. In addition, there may be old and
+ new configuration files that conflict. Be sure to delete or
+ rename any old configuration files when upgrading MySQL.
+ If you have installed MySQL to a directory other than
+ C:\Program Files\MySQL\MySQL Server 5.1, you need to ensure
+ that the MySQL server is aware of this through the use of a
+ configuration (my.ini) file. The my.ini file needs to be
+ located in your Windows directory, typically C:\WINDOWS. You
+ can determine its exact location from the value of the WINDIR
+ environment variable by issuing the following command from the
+ command prompt:
+C:\> echo %WINDIR%
+ An option file can be created and modified with any text
+ editor, such as Notepad. For example, if MySQL is installed in
+ E:\mysql and the data directory is D:\MySQLdata, you can
+ create the option file and set up a [mysqld] section to
+ specify values for the basedir and datadir options:
+[mysqld]
+# set basedir to your installation path
+basedir=E:/mysql
+# set datadir to the location of your data directory
+datadir=D:/MySQLdata
+ Note that Windows path names are specified in option files
+ using (forward) slashes rather than backslashes. If you do use
+ backslashes, double them:
+[mysqld]
+# set basedir to your installation path
+basedir=C:\\Program Files\\MySQL\\MySQL Server 5.1
+# set datadir to the location of your data directory
+datadir=D:\\MySQLdata
+ The rules for use of backslash in option file values are given
+ in Section 4.2.3.3, "Using Option Files."
+ If you change the datadir value in your MySQL configuration
+ file, you must move the contents of the existing MySQL data
+ directory before restarting the MySQL server.
+ See Section 2.5.5.2, "Creating an Option File."
+
+ * If you reinstall or upgrade MySQL without first stopping and
+ removing the existing MySQL service and install MySQL using
+ the MySQL Config Wizard, you may see this error:
+Error: Cannot create Windows service for MySql. Error: 0
+ This occurs when the Config Wizard tries to install the
+ service and finds an existing service with the same name.
+ One solution to this problem is to choose a service name other
+ than mysql when using the configuration wizard. This allows
+ the new service to be installed correctly, but leaves the
+ outdated service in place. Although this is harmless, it is
+ best to remove old services that are no longer in use.
+ To permanently remove the old mysql service, execute the
+ following command as a user with administrative privileges, on
+ the command-line:
+C:\> sc delete mysql
+[SC] DeleteService SUCCESS
+ If the sc utility is not available for your version of
+ Windows, download the delsrv utility from
+ http://www.microsoft.com/windows2000/techinfo/reskit/tools/exi
+ sting/delsrv-o.asp and use the delsrv mysql syntax.
+
+2.5.7. Upgrading MySQL on Windows
+
+ This section lists some of the steps you should take when
+ upgrading MySQL on Windows.
+
+ 1. Review Section 2.4.1, "Upgrading MySQL," for additional
+ information on upgrading MySQL that is not specific to
+ Windows.
+
+ 2. You should always back up your current MySQL installation
+ before performing an upgrade. See Section 6.1, "Database
+ Backup Methods."
+
+ 3. Download the latest Windows distribution of MySQL from
+ http://dev.mysql.com/downloads/.
+
+ 4. Before upgrading MySQL, you must stop the server. If the
+ server is installed as a service, stop the service with the
+ following command from the command prompt:
+C:\> NET STOP MySQL
+ If you are not running the MySQL server as a service, use the
+ following command to stop it:
+C:\> "C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqladmin" -u root
+ shutdown
+
+Note
+ If the MySQL root user account has a password, you need to
+ invoke mysqladmin with the -p option and supply the password
+ when prompted.
+
+ 5. When upgrading to MySQL 5.1 from a version previous to 4.1.5,
+ or when upgrading from a version of MySQL installed from a Zip
+ archive to a version of MySQL installed with the MySQL
+ Installation Wizard, you must manually remove the previous
+ installation and MySQL service (if the server is installed as
+ a service).
+ To remove the MySQL service, use the following command:
+C:\> C:\mysql\bin\mysqld --remove
+ If you do not remove the existing service, the MySQL
+ Installation Wizard may fail to properly install the new MySQL
+ service.
+
+ 6. When upgrading from MySQL 5.1.23 to MySQL 5.1.24, the change
+ in the default location of the data directory from a directory
+ within the MySQL installation to the AppData folder means that
+ you must manually copy the data files from your old
+ installation to the new location.
+
+ 7. If you are using the MySQL Installation Wizard, start the
+ wizard as described in Section 2.5.3.1, "Using the MySQL
+ Installation Wizard."
+
+ 8. If you are installing MySQL from a Zip archive, extract the
+ archive. You may either overwrite your existing MySQL
+ installation (usually located at C:\mysql), or install it into
+ a different directory, such as C:\mysql5. Overwriting the
+ existing installation is recommended.
+
+ 9. If you were running MySQL as a Windows service and you had to
+ remove the service earlier in this procedure, reinstall the
+ service. (See Section 2.5.5.6, "Starting MySQL as a Windows
+ Service.")
+ 10. Restart the server. For example, use NET START MySQL if you
+ run MySQL as a service, or invoke mysqld directly otherwise.
+ 11. If you encounter errors, see Section 2.5.6, "Troubleshooting a
+ MySQL Installation Under Windows."
+
+2.5.8. Windows Post-Installation Procedures
+
+ On Windows, the data directory and the grant tables do not have to
+ be created. MySQL Windows distributions include the grant tables
+ with a set of preinitialized accounts in the mysql database under
+ the data directory. It is unnecessary to run the mysql_install_db
+ script that is used on Unix. Regarding passwords, if you installed
+ MySQL using the Windows Installation Wizard, you may have already
+ assigned passwords to the accounts. (See Section 2.5.3.1, "Using
+ the MySQL Installation Wizard.") Otherwise, use the
+ password-assignment procedure given in Section 2.13.2, "Securing
+ the Initial MySQL Accounts."
+
+ Before setting up passwords, you might want to try running some
+ client programs to make sure that you can connect to the server
+ and that it is operating properly. Make sure that the server is
+ running (see Section 2.5.5.4, "Starting the Server for the First
+ Time"), and then issue the following commands to verify that you
+ can retrieve information from the server. The output should be
+ similar to what is shown here:
+C:\> C:\mysql\bin\mysqlshow
++--------------------+
+| Databases |
++--------------------+
+| information_schema |
+| mysql |
+| test |
++--------------------+
+
+Note
+
+ The above may not work if the correct user does not exist. If you
+ installed using the MSI packages and used the MySQL Server
+ Instance Config Wizard, then the root will haqve been created
+ automatically with the password you supplied. In this case, you
+ should use the -u and -p options where you will be prompted for
+ the password.
+
+Note
+
+ The list of installed databases may vary, but will always include
+ the minimum of mysql and information_schema. In most cases, the
+ test database will also be installed automatically.
+
+ If you specify the name of the database, then a list of the tables
+ within a given database will be displayed:
+C:\> C:\mysql\bin\mysqlshow mysql
+Database: mysql
++---------------------------+
+| Tables |
++---------------------------+
+| columns_priv |
+| db |
+| event |
+| func |
+| general_log |
+| help_category |
+| help_keyword |
+| help_relation |
+| help_topic |
+| host |
+| plugin |
+| proc |
+| procs_priv |
+| servers |
+| slow_log |
+| tables_priv |
+| time_zone |
+| time_zone_leap_second |
+| time_zone_name |
+| time_zone_transition |
+| time_zone_transition_type |
+| user |
++---------------------------+
+
+
+C:\> C:\mysql\bin\mysql -e "SELECT Host,Db,User FROM db" mysql
++------+-------+------+
+| host | db | user |
++------+-------+------+
+| % | test% | |
++------+-------+------+
+
+ You may need to specify a different directory from the one shown;
+ if you used the Windows Installation Wizard, then the default
+ directory is C:\Program Files\MySQL\MySQL Server 5.1, and the
+ mysql and mysqlshow client programs are in C:\Program
+ Files\MySQL\MySQL Server 5.1\bin. See Section 2.5.3.1, "Using the
+ MySQL Installation Wizard," for more information.
+
+ If you have already secured the initial MySQL accounts, you may
+ need to use the -u and -p options to supply a user name and
+ password to the mysqlshow and mysql client programs; otherwise the
+ programs may fail with an error, or you may not be able to view
+ all databases. For example, if you have assigned the password
+ "secretpass" to the MySQL root account, then you can invoke
+ mysqlshow and mysql as shown here:
+C:\> C:\mysql\bin\mysqlshow -uroot -psecretpass
++--------------------+
+| Databases |
++--------------------+
+| information_schema |
+| mysql |
+| test |
++--------------------+
+
+C:\> C:\mysql\bin\mysqlshow -uroot -psecretpass mysql
+Database: mysql
++---------------------------+
+| Tables |
++---------------------------+
+| columns_priv |
+| db |
+| event |
+| func |
+| general_log |
+| help_category |
+| help_keyword |
+| help_relation |
+| help_topic |
+| host |
+| plugin |
+| proc |
+| procs_priv |
+| servers |
+| slow_log |
+| tables_priv |
+| time_zone |
+| time_zone_leap_second |
+| time_zone_name |
+| time_zone_transition |
+| time_zone_transition_type |
+| user |
++---------------------------+
+
+
+C:\> C:\mysql\bin\mysql -uroot -psecretpass -e "SELECT Host,Db,User F
+ROM db" mysql
++------+-------+------+
+| host | db | user |
++------+-------+------+
+| % | test% | |
++------+-------+------+
+
+ For more information about these programs, see Section 4.5.6,
+ "mysqlshow --- Display Database, Table, and Column Information,"
+ and Section 4.5.1, "mysql --- The MySQL Command-Line Tool."
+
+ If you are running a version of Windows that supports services and
+ you want the MySQL server to run automatically when Windows
+ starts, see Section 2.5.5.6, "Starting MySQL as a Windows
+ Service."
+
+2.5.9. MySQL on Windows Compared to MySQL on Unix
+
+ MySQL for Windows has proven itself to be very stable. The Windows
+ version of MySQL has the same features as the corresponding Unix
+ version, with the following exceptions:
+
+ * Limited number of ports
+ Windows systems have about 4,000 ports available for client
+ connections, and after a connection on a port closes, it takes
+ two to four minutes before the port can be reused. In
+ situations where clients connect to and disconnect from the
+ server at a high rate, it is possible for all available ports
+ to be used up before closed ports become available again. If
+ this happens, the MySQL server appears to be unresponsive even
+ though it is running. Note that ports may be used by other
+ applications running on the machine as well, in which case the
+ number of ports available to MySQL is lower.
+ For more information about this problem, see
+ http://support.microsoft.com/default.aspx?scid=kb;en-us;196271
+ .
+
+ * Concurrent reads
+ MySQL depends on the pread() and pwrite() system calls to be
+ able to mix INSERT and SELECT. Currently, we use mutexes to
+ emulate pread() and pwrite(). We intend to replace the file
+ level interface with a virtual interface in the future so that
+ we can use the readfile()/writefile() interface to get more
+ speed. The current implementation limits the number of open
+ files that MySQL 5.1 can use to 2,048, which means that you
+ cannot run as many concurrent threads on Windows as on Unix.
+
+ * Blocking read
+ MySQL uses a blocking read for each connection. That has the
+ following implications if named-pipe connections are enabled:
+
+ + A connection is not disconnected automatically after
+ eight hours, as happens with the Unix version of MySQL.
+
+ + If a connection hangs, it is not possible to break it
+ without killing MySQL.
+
+ + mysqladmin kill does not work on a sleeping connection.
+
+ + mysqladmin shutdown cannot abort as long as there are
+ sleeping connections.
+ We plan to fix this problem in the future.
+
+ * ALTER TABLE
+ While you are executing an ALTER TABLE statement, the table is
+ locked from being used by other threads. This has to do with
+ the fact that on Windows, you can't delete a file that is in
+ use by another thread. In the future, we may find some way to
+ work around this problem.
+
+ * DATA DIRECTORY and INDEX DIRECTORY
+ The DATA DIRECTORY and INDEX DIRECTORY options for CREATE
+ TABLE are ignored on Windows, because Windows doesn't support
+ symbolic links. These options also are ignored on systems that
+ have a nonfunctional realpath() call.
+
+ * DROP DATABASE
+ You cannot drop a database that is in use by another thread.
+
+ * Case-insensitive names
+ File names are not case sensitive on Windows, so MySQL
+ database and table names are also not case sensitive on
+ Windows. The only restriction is that database and table names
+ must be specified using the same case throughout a given
+ statement. See Section 8.2.2, "Identifier Case Sensitivity."
+
+ * Directory and file names
+ On Windows, MySQL Server supports only directory and file
+ names that are compatible with the current ANSI code pages.
+ For example, the following Japanese directory name will not
+ work in the Western locale (code page 1252):
+datadir="C:/维基百科关于中文维基百科"
+ The same limitation applies to directory and file names
+ referred to in SQL statements, such as the data file path name
+ in LOAD DATA INFILE.
+
+ * The "\" path name separator character
+ Path name components in Windows are separated by the "\"
+ character, which is also the escape character in MySQL. If you
+ are using LOAD DATA INFILE or SELECT ... INTO OUTFILE, use
+ Unix-style file names with "/" characters:
+mysql> LOAD DATA INFILE 'C:/tmp/skr.txt' INTO TABLE skr;
+mysql> SELECT * INTO OUTFILE 'C:/tmp/skr.txt' FROM skr;
+ Alternatively, you must double the "\" character:
+mysql> LOAD DATA INFILE 'C:\\tmp\\skr.txt' INTO TABLE skr;
+mysql> SELECT * INTO OUTFILE 'C:\\tmp\\skr.txt' FROM skr;
+
+ * Problems with pipes
+ Pipes do not work reliably from the Windows command-line
+ prompt. If the pipe includes the character ^Z / CHAR(24),
+ Windows thinks that it has encountered end-of-file and aborts
+ the program.
+ This is mainly a problem when you try to apply a binary log as
+ follows:
+C:\> mysqlbinlog binary_log_file | mysql --user=root
+ If you have a problem applying the log and suspect that it is
+ because of a ^Z / CHAR(24) character, you can use the
+ following workaround:
+C:\> mysqlbinlog binary_log_file --result-file=/tmp/bin.sql
+C:\> mysql --user=root --execute "source /tmp/bin.sql"
+ The latter command also can be used to reliably read in any
+ SQL file that may contain binary data.
+
+ * Access denied for user error
+ If MySQL cannot resolve your host name properly, you may get
+ the following error when you attempt to run a MySQL client
+ program to connect to a server running on the same machine:
+Access denied for user 'some_user'@'unknown'
+to database 'mysql'
+ To fix this problem, you should create a file named
+ \windows\hosts containing the following information:
+127.0.0.1 localhost
+
+ Here are some open issues for anyone who might want to help us
+ improve MySQL on Windows:
+
+ * Add macros to use the faster thread-safe increment/decrement
+ methods provided by Windows.
+
+2.5.10. Installing MySQL from Source on Windows
+
+ These instructions describe how to build binaries from source for
+ MySQL 5.1 on Windows. Instructions are provided for building
+ binaries from a standard source distribution or from the Bazaar
+ tree that contains the latest development source.
-2.13.1.4. Linux Post-Installation Notes
+Note
+
+ The instructions here are strictly for users who want to test
+ MySQL on Microsoft Windows from the latest source distribution or
+ from the Bazaar tree. For production use, we do not advise using a
+ MySQL server built by yourself from source. Normally, it is best
+ to use precompiled binary distributions of MySQL that are built
+ specifically for optimal performance on Windows by Sun
+ Microsystems, Inc. Instructions for installing binary
+ distributions are available in Section 2.5, "Installing MySQL on
+ Windows."
+
+ To build MySQL on Windows from source, you must satisfy the
+ following system, compiler, and resource requirements:
+
+ * Windows 2000, Windows XP, or newer version.
+ Windows Vista is supported when using Visual Studio 2005
+ provided you have installed the following updates:
+
+ + Microsoft Visual Studio 2005 Professional Edition - ENU
+ Service Pack 1 (KB926601)
+ (http://support.microsoft.com/?kbid=926601)
+
+ + Security Update for Microsoft Visual Studio 2005
+ Professional Edition - ENU (KB937061)
+ (http://support.microsoft.com/?kbid=937061)
+
+ + Update for Microsoft Visual Studio 2005 Professional
+ Edition - ENU (KB932232)
+ (http://support.microsoft.com/?kbid=932232)
+
+ * CMake, which can be downloaded from http://www.cmake.org.
+ After installing, modify your path to include the cmake
+ binary.
+
+ * Microsoft Visual C++ 2005 Express Edition, Visual Studio .Net
+ 2003 (7.1), or Visual Studio 2005 (8.0) compiler system.
+
+ * If you are using Visual C++ 2005 Express Edition, you must
+ also install an appropriate Platform SDK. More information and
+ links to downloads for various Windows platforms is available
+ from
+ http://www.microsoft.com/downloads/details.aspx?familyid=0baf2
+ b35-c656-4969-ace8-e4c0c0716adb.
+
+ * If you are compiling from a Bazaar tree or making changes to
+ the parser, you need bison for Windows, which can be
+ downloaded from
+ http://gnuwin32.sourceforge.net/packages/bison.htm. Download
+ the package labeled "Complete package, excluding sources".
+ After installing the package, modify your path to include the
+ bison binary and ensure that this binary is accessible from
+ Visual Studio.
+
+ * Cygwin might be necessary if you want to run the test script
+ or package the compiled binaries and support files into a Zip
+ archive. (Cygwin is needed only to test or package the
+ distribution, not to build it.) Cygwin is available from
+ http://cygwin.com.
+
+ * 3GB to 5GB of disk space.
+
+ The exact system requirements for Visual Studio can be found here:
+ http://msdn.microsoft.com/vstudio/Previous/2003/sysreqs/default.as
+ px and
+ http://msdn.microsoft.com/vstudio/products/sysreqs/default.aspx
+
+ You also need a MySQL source distribution for Windows, which can
+ be obtained two ways:
+
+ * Obtain a source distribution packaged by Sun Microsystems,
+ Inc. These are available from http://dev.mysql.com/downloads/.
+
+ * Package a source distribution yourself from the latest Bazaar
+ developer source tree. For instructions on pulling the latest
+ source files, see Section 2.3.3, "Installing from the
+ Development Source Tree."
+
+ If you find something not working as expected, or you have
+ suggestions about ways to improve the current build process on
+ Windows, please send a message to the win32 mailing list. See
+ Section 1.5.1, "MySQL Mailing Lists."
+
+2.5.10.1. Building MySQL from Source Using CMake and Visual Studio
+
+ You can build MySQL on Windows by using a combination of cmake and
+ Microsoft Visual Studio .NET 2003 (7.1), Microsoft Visual Studio
+ 2005 (8.0) or Microsoft Visual C++ 2005 Express Edition. You must
+ have the appropriate Microsoft Platform SDK installed.
+
+Note
+
+ To compile from the source code on Windows you must use the
+ standard source distribution (for example, mysql-5.1.41.tar.gz).
+ You build from the same distribution as used to build MySQL on
+ Unix, Linux and other platforms. Do not use the Windows Source
+ distributions as they do not contain the necessary configuration
+ script and other files.
+
+ Follow this procedure to build MySQL:
+
+ 1. If you are installing from a packaged source distribution,
+ create a work directory (for example, C:\workdir), and unpack
+ the source distribution there using WinZip or another Windows
+ tool that can read .zip files. This directory is the work
+ directory in the following instructions.
+
+ 2. Using a command shell, navigate to the work directory and run
+ the following command:
+C:\workdir>win\configure.js options
+ If you have associated the .js file extension with an
+ application such as a text editor, then you may need to use
+ the following command to force configure.js to be executed as
+ a script:
+C:\workdir>cscript win\configure.js options
+ These options are available for configure.js:
+
+ + WITH_INNOBASE_STORAGE_ENGINE: Enable the InnoDB storage
+ engine.
+
+ + WITH_PARTITION_STORAGE_ENGINE: Enable user-defined
+ partitioning.
+
+ + WITH_ARCHIVE_STORAGE_ENGINE: Enable the ARCHIVE storage
+ engine.
+
+ + WITH_BLACKHOLE_STORAGE_ENGINE: Enable the BLACKHOLE
+ storage engine.
+
+ + WITH_EXAMPLE_STORAGE_ENGINE: Enable the EXAMPLE storage
+ engine.
+
+ + WITH_FEDERATED_STORAGE_ENGINE: Enable the FEDERATED
+ storage engine.
+
+ + WITH_NDBCLUSTER_STORAGE_ENGINE (experimental): Enable the
+ NDBCLUSTER storage engine in the MySQL server; cause
+ binaries for the MySQL Cluster management and data node,
+ management client, and other programs to be built.
+ This option is supported only in MySQL Cluster NDB 7.0
+ (NDBCLUSTER storage engine versions 6.4.0 and later)
+ using the MySQL Cluster sources. It cannot be used to
+ enable clustering support in other MySQL source trees or
+ distributions.
+
+ + MYSQL_SERVER_SUFFIX=suffix: Server suffix, default none.
+
+ + COMPILATION_COMMENT=comment: Server comment, default
+ "Source distribution".
+
+ + MYSQL_TCP_PORT=port: Server port, default 3306.
+
+ + DISABLE_GRANT_OPTIONS: Disables the --bootstrap,
+ --skip-grant-tables, and --init-file options for mysqld.
+ This option is available as of MySQL 5.1.15.
+ For example (type the command on one line):
+C:\workdir>win\configure.js WITH_INNOBASE_STORAGE_ENGINE
+ WITH_PARTITION_STORAGE_ENGINE MYSQL_SERVER_SUFFIX=-pro
+
+ 3. From the work directory, execute the win\build-vs8.bat or
+ win\build-vs71.bat file, depending on the version of Visual
+ Studio you have installed. The script invokes CMake, which
+ generates the mysql.sln solution file.
+ You can also use win\build-vs8_x64.bat to build the 64-bit
+ version of MySQL. However, you cannot build the 64-bit version
+ with Visual Studio Express Edition. You must use Visual Studio
+ 2005 (8.0) or higher.
+
+ 4. From the work directory, open the generated mysql.sln file
+ with Visual Studio and select the proper configuration using
+ the Configuration menu. The menu provides Debug, Release,
+ RelwithDebInfo, MinRelInfo options. Then select Solution >
+ Build to build the solution.
+ Remember the configuration that you use in this step. It is
+ important later when you run the test script because that
+ script needs to know which configuration you used.
+
+ 5. Test the server. The server built using the preceding
+ instructions expects that the MySQL base directory and data
+ directory are C:\mysql and C:\mysql\data by default. If you
+ want to test your server using the source tree root directory
+ and its data directory as the base directory and data
+ directory, you need to tell the server their path names. You
+ can either do this on the command line with the --basedir and
+ --datadir options, or by placing appropriate options in an
+ option file. (See Section 4.2.3.3, "Using Option Files.") If
+ you have an existing data directory elsewhere that you want to
+ use, you can specify its path name instead.
+ When the server is running in standalone fashion or as a
+ service based on your configuration, try to connect to it from
+ the mysql interactive command-line utility.
+ You can also run the standard test script, mysql-test-run.pl.
+ This script is written in Perl, so you'll need either Cygwin
+ or ActiveState Perl to run it. You may also need to install
+ the modules required by the script. To run the test script,
+ change location into the mysql-test directory under the work
+ directory, set the MTR_VS_CONFIG environment variable to the
+ configuration you selected earlier (or use the --vs-config
+ option), and invoke mysql-test-run.pl. For example (using
+ Cygwin and the bash shell):
+shell> cd mysql-test
+shell> export MTR_VS_CONFIG=debug
+shell> ./mysql-test-run.pl --force --timer
+shell> ./mysql-test-run.pl --force --timer --ps-protocol
+
+ When you are satisfied that the programs you have built are
+ working correctly, stop the server. Now you can install the
+ distribution. One way to do this is to use the make_win_bin_dist
+ script in the scripts directory of the MySQL source distribution
+ (see Section 4.4.2, "make_win_bin_dist --- Package MySQL
+ Distribution as ZIP Archive"). This is a shell script, so you must
+ have Cygwin installed if you want to use it. It creates a Zip
+ archive of the built executables and support files that you can
+ unpack in the location at which you want to install MySQL.
+
+ It is also possible to install MySQL by copying directories and
+ files directly:
+
+ 1. Create the directories where you want to install MySQL. For
+ example, to install into C:\mysql, use these commands:
+C:\> mkdir C:\mysql
+C:\> mkdir C:\mysql\bin
+C:\> mkdir C:\mysql\data
+C:\> mkdir C:\mysql\share
+C:\> mkdir C:\mysql\scripts
+ If you want to compile other clients and link them to MySQL,
+ you should also create several additional directories:
+C:\> mkdir C:\mysql\include
+C:\> mkdir C:\mysql\lib
+C:\> mkdir C:\mysql\lib\debug
+C:\> mkdir C:\mysql\lib\opt
+ If you want to benchmark MySQL, create this directory:
+C:\> mkdir C:\mysql\sql-bench
+ Benchmarking requires Perl support. See Section 2.15, "Perl
+ Installation Notes."
+
+ 2. From the work directory, copy into the C:\mysql directory the
+ following directories:
+C:\> cd \workdir
+C:\workdir> copy client_release\*.exe C:\mysql\bin
+C:\workdir> copy client_debug\mysqld.exe C:\mysql\bin\mysqld-debug.ex
+e
+C:\workdir> xcopy scripts\*.* C:\mysql\scripts /E
+C:\workdir> xcopy share\*.* C:\mysql\share /E
+ If you want to compile other clients and link them to MySQL,
+ you should also copy several libraries and header files:
+C:\workdir> copy lib_debug\mysqlclient.lib C:\mysql\lib\debug
+C:\workdir> copy lib_debug\libmysql.* C:\mysql\lib\debug
+C:\workdir> copy lib_debug\zlib.* C:\mysql\lib\debug
+C:\workdir> copy lib_release\mysqlclient.lib C:\mysql\lib\opt
+C:\workdir> copy lib_release\libmysql.* C:\mysql\lib\opt
+C:\workdir> copy lib_release\zlib.* C:\mysql\lib\opt
+C:\workdir> copy include\*.h C:\mysql\include
+C:\workdir> copy libmysql\libmysql.def C:\mysql\include
+ If you want to benchmark MySQL, you should also do this:
+C:\workdir> xcopy sql-bench\*.* C:\mysql\bench /E
+
+ After installation, set up and start the server in the same way as
+ for binary Windows distributions. See Section 2.5, "Installing
+ MySQL on Windows."
+
+2.5.11. Compiling MySQL Clients on Windows
+
+ In your source files, you should include my_global.h before
+ mysql.h:
+#include <my_global.h>
+#include <mysql.h>
+
+ my_global.h includes any other files needed for Windows
+ compatibility (such as windows.h) if you compile your program on
+ Windows.
+
+ You can either link your code with the dynamic libmysql.lib
+ library, which is just a wrapper to load in libmysql.dll on
+ demand, or link with the static mysqlclient.lib library.
+
+ The MySQL client libraries are compiled as threaded libraries, so
+ you should also compile your code to be multi-threaded.
+
+2.6. Installing MySQL on Linux
+
+ The following sections covers the installation of Linux using
+ RPMs. For information on using a generic binary package using tar,
+ see Section 2.2, "Installing MySQL from Generic Binaries on
+ Unix/Linux." For information on installing from source, see
+ Section 2.3, "MySQL Installation Using a Source Distribution."
mysql.server can be found in the support-files directory under the
MySQL installation directory or in a MySQL source tree. You can
install it as /etc/init.d/mysql for automatic MySQL startup and
- shutdown. See Section 2.11.2.2, "Starting and Stopping MySQL
+ shutdown. See Section 2.13.1.2, "Starting and Stopping MySQL
Automatically."
- If MySQL cannot open enough files or connections, it may be that
- you have not configured Linux to handle enough files.
-
- In Linux 2.2 and onward, you can check the number of allocated
- file handles as follows:
-shell> cat /proc/sys/fs/file-max
-shell> cat /proc/sys/fs/dquot-max
-shell> cat /proc/sys/fs/super-max
-
- If you have more than 16MB of memory, you should add something
- like the following to your init scripts (for example,
- /etc/init.d/boot.local on SuSE Linux):
-echo 65536 > /proc/sys/fs/file-max
-echo 8192 > /proc/sys/fs/dquot-max
-echo 1024 > /proc/sys/fs/super-max
-
- You can also run the echo commands from the command line as root,
- but these settings are lost the next time your computer restarts.
-
- Alternatively, you can set these parameters on startup by using
- the sysctl tool, which is used by many Linux distributions
- (including SuSE Linux 8.0 and later). Put the following values
- into a file named /etc/sysctl.conf:
-# Increase some values for MySQL
-fs.file-max = 65536
-fs.dquot-max = 8192
-fs.super-max = 1024
-
- You should also add the following to /etc/my.cnf:
-[mysqld_safe]
-open-files-limit=8192
-
- This should allow the server a limit of 8,192 for the combined
- number of connections and open files.
-
- The STACK_SIZE constant in LinuxThreads controls the spacing of
- thread stacks in the address space. It needs to be large enough so
- that there is plenty of room for each individual thread stack, but
- small enough to keep the stack of some threads from running into
- the global mysqld data. Unfortunately, as we have experimentally
- discovered, the Linux implementation of mmap() successfully unmaps
- a mapped region if you ask it to map out an address currently in
- use, zeroing out the data on the entire page instead of returning
- an error. So, the safety of mysqld or any other threaded
- application depends on the "gentlemanly" behavior of the code that
- creates threads. The user must take measures to make sure that the
- number of running threads at any given time is sufficiently low
- for thread stacks to stay away from the global heap. With mysqld,
- you should enforce this behavior by setting a reasonable value for
- the max_connections variable.
-
- If you build MySQL yourself, you can patch LinuxThreads for better
- stack use. See Section 2.13.1.3, "Linux Source Distribution
- Notes." If you do not want to patch LinuxThreads, you should set
- max_connections to a value no higher than 500. It should be even
- less if you have a large key buffer, large heap tables, or some
- other things that make mysqld allocate a lot of memory, or if you
- are running a 2.2 kernel with a 2GB patch. If you are using our
- binary or RPM version, you can safely set max_connections at 1500,
- assuming no large key buffer or heap tables with lots of data. The
- more you reduce STACK_SIZE in LinuxThreads the more threads you
- can safely create. Values between 128KB and 256KB are recommended.
-
- If you use a lot of concurrent connections, you may suffer from a
- "feature" in the 2.2 kernel that attempts to prevent fork bomb
- attacks by penalizing a process for forking or cloning a child.
- This causes MySQL not to scale well as you increase the number of
- concurrent clients. On single-CPU systems, we have seen this
- manifest as very slow thread creation; it may take a long time to
- connect to MySQL (as long as one minute), and it may take just as
- long to shut it down. On multiple-CPU systems, we have observed a
- gradual drop in query speed as the number of clients increases. In
- the process of trying to find a solution, we have received a
- kernel patch from one of our users who claimed it helped for his
- site. This patch is available at
- http://dev.mysql.com/Downloads/Patches/linux-fork.patch. We have
- done rather extensive testing of this patch on both development
- and production systems. It has significantly improved MySQL
- performance without causing any problems and is recommended for
- users who still run high-load servers on 2.2 kernels.
-
- This issue has been fixed in the 2.4 kernel, so if you are not
- satisfied with the current performance of your system, rather than
- patching your 2.2 kernel, it might be easier to upgrade to 2.4. On
- SMP systems, upgrading also gives you a nice SMP boost in addition
- to fixing the fairness bug.
-
- We have tested MySQL on the 2.4 kernel on a two-CPU machine and
- found MySQL scales much better. There was virtually no slowdown on
- query throughput all the way up to 1,000 clients, and the MySQL
- scaling factor (computed as the ratio of maximum throughput to the
- throughput for one client) was 180%. We have observed similar
- results on a four-CPU system: Virtually no slowdown as the number
- of clients was increased up to 1,000, and a 300% scaling factor.
- Based on these results, for a high-load SMP server using a 2.2
- kernel, it is definitely recommended to upgrade to the 2.4 kernel
- at this point.
-
- We have discovered that it is essential to run the mysqld process
- with the highest possible priority on the 2.4 kernel to achieve
- maximum performance. This can be done by adding a renice -20 $$
- command to mysqld_safe. In our testing on a four-CPU machine,
- increasing the priority resulted in a 60% throughput increase with
- 400 clients.
-
- We are currently also trying to collect more information on how
- well MySQL performs with a 2.4 kernel on four-way and eight-way
- systems. If you have access such a system and have done some
- benchmarks, please send an email message to benchmarks@mysql.com
- with the results. We will review them for inclusion in the manual.
-
- If you see a dead mysqld server process with ps, this usually
- means that you have found a bug in MySQL or you have a corrupted
- table. See Section B.1.4.2, "What to Do If MySQL Keeps Crashing."
-
- To get a core dump on Linux if mysqld dies with a SIGSEGV signal,
- you can start mysqld with the --core-file option. Note that you
- also probably need to raise the core file size by adding ulimit -c
- 1000000 to mysqld_safe or starting mysqld_safe with
- --core-file-size=1000000. See Section 4.3.2, "mysqld_safe ---
- MySQL Server Startup Script."
-
-2.13.1.5. Linux x86 Notes
-
- MySQL requires libc 5.4.12 or newer. It is known to work with libc
- 5.4.46. glibc 2.0.6 and later should also work. There have been
- some problems with the glibc RPMs from Red Hat, so if you have
- problems, check whether there are any updates. The glibc 2.0.7-19
- and 2.0.7-29 RPMs are known to work.
-
- If you are using Red Hat 8.0 or a new glibc 2.2.x library, you may
- see mysqld die in gethostbyaddr(). This happens because the new
- glibc library requires a stack size greater than 128KB for this
- call. To fix the problem, start mysqld with the
- --thread-stack=192K option. (Use -O thread_stack=192K before MySQL
- 4.) This stack size is the default on MySQL 4.0.10 and above, so
- you should not see the problem.
-
- If you are using gcc 3.0 and above to compile MySQL, you must
- install the libstdc++v3 library before compiling MySQL; if you
- don't do this, you get an error about a missing __cxa_pure_virtual
- symbol during linking.
-
- On some older Linux distributions, configure may produce an error
- like this:
-Syntax error in sched.h. Change _P to __P in the
-/usr/include/sched.h file.
-See the Installation chapter in the Reference Manual.
-
- Just do what the error message says. Add an extra underscore to
- the _P macro name that has only one underscore, and then try
- again.
-
- You may get some warnings when compiling. Those shown here can be
- ignored:
-mysqld.cc -o objs-thread/mysqld.o
-mysqld.cc: In function `void init_signals()':
-mysqld.cc:315: warning: assignment of negative value `-1' to
-`long unsigned int'
-mysqld.cc: In function `void * signal_hand(void *)':
-mysqld.cc:346: warning: assignment of negative value `-1' to
-`long unsigned int'
-
- If mysqld always dumps core when it starts, the problem may be
- that you have an old /lib/libc.a. Try renaming it, and then remove
- sql/mysqld and do a new make install and try again. This problem
- has been reported on some Slackware installations.
-
- If you get the following error when linking mysqld, it means that
- your libg++.a is not installed correctly:
-/usr/lib/libc.a(putc.o): In function `_IO_putc':
-putc.o(.text+0x0): multiple definition of `_IO_putc'
-
- You can avoid using libg++.a by running configure like this:
-shell> CXX=gcc ./configure
-
-2.13.1.6. Linux SPARC Notes
-
- In some implementations, readdir_r() is broken. The symptom is
- that the SHOW DATABASES statement always returns an empty set.
- This can be fixed by removing HAVE_READDIR_R from config.h after
- configuring and before compiling.
-
-2.13.1.7. Linux Alpha Notes
-
- We have tested MySQL 5.1 on Alpha with our benchmarks and test
- suite, and it appears to work well.
-
- We currently build the MySQL binary packages on SuSE Linux 7.0 for
- AXP, kernel 2.4.4-SMP, Compaq C compiler (V6.2-505) and Compaq C++
- compiler (V6.3-006) on a Compaq DS20 machine with an Alpha EV6
- processor.
+2.6.1. Installing MySQL from RPM Packages on Linux
- You can find the preceding compilers at
- http://www.support.compaq.com/alpha-tools/. By using these
- compilers rather than gcc, we get about 9-14% better MySQL
- performance.
-
- For MySQL on Alpha, we use the -arch generic flag to our compile
- options, which ensures that the binary runs on all Alpha
- processors. We also compile statically to avoid library problems.
- The configure command looks like this:
-CC=ccc CFLAGS="-fast -arch generic" CXX=cxx \
-CXXFLAGS="-fast -arch generic -noexceptions -nortti" \
-./configure --prefix=/usr/local/mysql --disable-shared \
- --with-extra-charsets=complex --enable-thread-safe-client \
- --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shar
-ed
+ The recommended way to install MySQL on RPM-based Linux
+ distributions is by using the RPM packages. The RPMs that we
+ provide to the community should work on all versions of Linux that
+ support RPM packages and use glibc 2.3. To obtain RPM packages,
+ see Section 2.1.3, "How to Get MySQL."
- Some known problems when running MySQL on Linux-Alpha:
+ For non-RPM Linux distributions, you can install MySQL using a
+ .tar.gz package. See Section 2.2, "Installing MySQL from Generic
+ Binaries on Unix/Linux."
- * Debugging threaded applications like MySQL does not work with
- gdb 4.18. You should use gdb 5.1 instead.
+ We do provide some platform-specific RPMs; the difference between
+ a platform-specific RPM and a generic RPM is that a
+ platform-specific RPM is built on the targeted platform and is
+ linked dynamically whereas a generic RPM is linked statically with
+ LinuxThreads.
- * If you try linking mysqld statically when using gcc, the
- resulting image dumps core at startup time. In other words, do
- not use --with-mysqld-ldflags=-all-static with gcc.
+Note
-2.13.1.8. Linux PowerPC Notes
+ RPM distributions of MySQL often are provided by other vendors. Be
+ aware that they may differ in features and capabilities from those
+ built by us, and that the instructions in this manual do not
+ necessarily apply to installing them. The vendor's instructions
+ should be consulted instead.
- MySQL should work on MkLinux with the newest glibc package (tested
- with glibc 2.0.7).
+ In most cases, you need to install only the MySQL-server and
+ MySQL-client packages to get a functional MySQL installation. The
+ other packages are not required for a standard installation.
-2.13.1.9. Linux MIPS Notes
+ RPMs for MySQL Cluster. Beginning with MySQL 5.1.24, standard
+ MySQL server RPMs built by MySQL no longer provide support for the
+ NDBCLUSTER storage engine. MySQL Cluster users wanting to upgrade
+ MySQL 5.1.23 or earlier installations from RPMs built by MySQL
+ should upgrade to MySQL Cluster NDB 6.2 or MySQL Cluster NDB 6.3;
+ RPMs that should work with most Linux distributions are available
+ for both of these release series.
- To get MySQL to work on Qube2 (Linux Mips), you need the newest
- glibc libraries. glibc-2.0.7-29C2 is known to work. You must also
- use gcc 2.95.2 or newer).
+Important
-2.13.1.10. Linux IA-64 Notes
+ When upgrading a MySQL Cluster RPM installation, you must upgrade
+ all installed RPMs, including the Server and Client RPMs.
- To get MySQL to compile on Linux IA-64, we use the following
- configure command for building with gcc 2.96:
-CC=gcc \
-CFLAGS="-O3 -fno-omit-frame-pointer" \
-CXX=gcc \
-CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors \
- -fno-exceptions -fno-rtti" \
- ./configure --prefix=/usr/local/mysql \
- "--with-comment=Official MySQL binary" \
- --with-extra-charsets=complex
+ For more information about installing MySQL Cluster from RPMs, see
+ Section 17.2.1, "MySQL Cluster Multi-Computer Installation."
- On IA-64, the MySQL client binaries use shared libraries. This
- means that if you install our binary distribution at a location
- other than /usr/local/mysql, you need to add the path of the
- directory where you have libmysqlclient.so installed either to the
- /etc/ld.so.conf file or to the value of your LD_LIBRARY_PATH
- environment variable.
+ For upgrades, if your installation was originally produced by
+ installing multiple RPM packages, it is best to upgrade all the
+ packages, not just some. For example, if you previously installed
+ the server and client RPMs, do not upgrade just the server RPM.
- See Section B.1.3.1, "Problems Linking to the MySQL Client
- Library."
+ The RPM packages shown in the following list are available. The
+ names shown here use a suffix of .glibc23.i386.rpm, but particular
+ packages can have different suffixes, described later.
-2.13.1.11. SELinux Notes
+ * MySQL-server-VERSION.glibc23.i386.rpm
+ The MySQL server. You need this unless you only want to
+ connect to a MySQL server running on another machine.
- RHEL4 comes with SELinux, which supports tighter access control
- for processes. If SELinux is enabled (SELINUX in
- /etc/selinux/config is set to enforcing, SELINUXTYPE is set to
- either targeted or strict), you might encounter problems
- installing Sun Microsystems, Inc. RPM packages.
+ * MySQL-client-VERSION.glibc23.i386.rpm
+ The standard MySQL client programs. You probably always want
+ to install this package.
- Red Hat has an update that solves this. It involves an update of
- the "security policy" specification to handle the install
- structure of the RPMs provided by Sun Microsystems, Inc. For
- further information, see
- https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=167551 and
- http://rhn.redhat.com/errata/RHBA-2006-0049.html.
+ * MySQL-devel-VERSION.glibc23.i386.rpm
+ The libraries and include files that are needed if you want to
+ compile other MySQL clients, such as the Perl modules.
- The preceding discussion applies only to RHEL4. The patch is
- unnecessary for RHEL5.
+ * MySQL-debuginfo-VERSION.glibc23.i386.rpm
+ This package contains debugging information. debuginfo RPMs
+ are never needed to use MySQL software; this is true both for
+ the server and for client programs. However, they contain
+ additional information that might be needed by a debugger to
+ analyze a crash.
-2.13.2. Mac OS X Notes
+ * MySQL-shared-VERSION.glibc23.i386.rpm
+ This package contains the shared libraries
+ (libmysqlclient.so*) that certain languages and applications
+ need to dynamically load and use MySQL. It contains
+ single-threaded and thread-safe libraries. If you install this
+ package, do not install the MySQL-shared-compat package.
- On Mac OS X, tar cannot handle long file names. If you need to
- unpack a .tar.gz distribution, use gnutar instead.
+ * MySQL-shared-compat-VERSION.glibc23.i386.rpm
+ This package includes the shared libraries for MySQL 3.23,
+ 4.0, and so on, up to the current release. It contains
+ single-threaded and thread-safe libraries. Install this
+ package instead of MySQL-shared if you have applications
+ installed that are dynamically linked against older versions
+ of MySQL but you want to upgrade to the current version
+ without breaking the library dependencies.
-2.13.2.1. Mac OS X 10.x (Darwin)
+ * MySQL-shared-compat-advanced-gpl-VERSION.glibc23.i386.rpm,
+ MySQL-shared-compat-advanced-VERSION.glibc23.i386.rpm
+ These are like the MySQL-shared-compat package, but are for
+ the "MySQL Enterprise Server - Advanced Edition" products.
+ Install these packages rather than the normal
+ MySQL-shared-compat package if you want to included shared
+ client libraries for older MySQL versions.
- MySQL should work without major problems on Mac OS X 10.x
- (Darwin).
+ * MySQL-embedded-VERSION.glibc23.i386.rpm
+ The embedded MySQL server library.
- Known issues:
+ * MySQL-ndb-management-VERSION.glibc23.i386.rpm,
+ MySQL-ndb-storage-VERSION.glibc23.i386.rpm,
+ MySQL-ndb-tools-VERSION.glibc23.i386.rpm,
+ MySQL-ndb-extra-VERSION.glibc23.i386.rpm
+ Packages that contain additional files for MySQL Cluster
+ installations.
- * If you have problems with performance under heavy load, try
- using the --skip-thread-priority option to mysqld. This runs
- all threads with the same priority. On Mac OS X, this gives
- better performance, at least until Apple fixes its thread
- scheduler.
+Note
+ The MySQL-ndb-tools RPM requires a working installation of
+ perl. Prior to MySQL 5.1.18, the DBI and HTML::Template
+ packages were also required. See Section 2.15, "Perl
+ Installation Notes," and Section 17.4.21, "ndb_size.pl ---
+ NDBCLUSTER Size Requirement Estimator," for more information.
- * The connection times (wait_timeout, interactive_timeout and
- net_read_timeout) values are not honored.
- This is probably a signal handling problem in the thread
- library where the signal doesn't break a pending read and we
- hope that a future update to the thread libraries will fix
- this.
+ * MySQL-test-VERSION.glibc23.i386.rpm
+ This package includes the MySQL test suite.
- Our binary for Mac OS X is compiled on Darwin 6.3 with the
- following configure line:
-CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc \
-CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors \
- -fno-exceptions -fno-rtti" \
- ./configure --prefix=/usr/local/mysql \
- --with-extra-charsets=complex --enable-thread-safe-client \
- --enable-local-infile --disable-shared
+ * MySQL-VERSION.src.rpm
+ This contains the source code for all of the previous
+ packages. It can also be used to rebuild the RPMs on other
+ architectures (for example, Alpha or SPARC).
- See Section 2.5, "Installing MySQL on Mac OS X."
+ The suffix of RPM package names (following the VERSION value) has
+ the following syntax:
+.PLATFORM.CPU.rpm
-2.13.2.2. Mac OS X Server 1.2 (Rhapsody)
+ The PLATFORM and CPU values indicate the type of system for which
+ the package is built. PLATFORM indicates the platform and CPU
+ indicates the processor type or family.
- For current versions of Mac OS X Server, no operating system
- changes are necessary before compiling MySQL. Compiling for the
- Server platform is the same as for the client version of Mac OS X.
+ All packages are dynamically linked against glibc 2.3. The
+ PLATFORM value indicates whether the package is platform
+ independent or intended for a specific platform, as shown in the
+ following table.
+ glibc23 Platform independent, should run on any Linux distribution
+ that supports glibc 2.3
+ rhel3, rhel4 Red Hat Enterprise Linux 3 or 4
+ sles9, sles10 SuSE Linux Enterprise Server 9 or 10
- For older versions (Mac OS X Server 1.2, a.k.a. Rhapsody), you
- must first install a pthread package before trying to configure
- MySQL.
+ In MySQL 5.1, only glibc23 packages are available currently.
- See Section 2.5, "Installing MySQL on Mac OS X."
+ The CPU value indicates the processor type or family for which the
+ package is built.
+ i386 x86 processor, 386 and up
+ i586 x86 processor, Pentium and up
+ x86_64 64-bit x86 processor
+ ia64 Itanium (IA-64) processor
-2.13.3. Solaris Notes
+ To see all files in an RPM package (for example, a MySQL-server
+ RPM), run a command like this:
+shell> rpm -qpl MySQL-server-VERSION.glibc23.i386.rpm
- For information about installing MySQL on Solaris using PKG
- distributions, see Section 2.6, "Installing MySQL on Solaris."
+ To perform a standard minimal installation, install the server and
+ client RPMs:
+shell> rpm -i MySQL-server-VERSION.glibc23.i386.rpm
+shell> rpm -i MySQL-client-VERSION.glibc23.i386.rpm
- On Solaris, you may run into trouble even before you get the MySQL
+ To install only the client programs, install just the client RPM:
+shell> rpm -i MySQL-client-VERSION.glibc23.i386.rpm
+
+ RPM provides a feature to verify the integrity and authenticity of
+ packages before installing them. If you would like to learn more
+ about this feature, see Section 2.1.4, "Verifying Package
+ Integrity Using MD5 Checksums or GnuPG."
+
+ The server RPM places data under the /var/lib/mysql directory. The
+ RPM also creates a login account for a user named mysql (if one
+ does not exist) to use for running the MySQL server, and creates
+ the appropriate entries in /etc/init.d/ to start the server
+ automatically at boot time. (This means that if you have performed
+ a previous installation and have made changes to its startup
+ script, you may want to make a copy of the script so that you
+ don't lose it when you install a newer RPM.) See Section 2.13.1.2,
+ "Starting and Stopping MySQL Automatically," for more information
+ on how MySQL can be started automatically on system startup.
+
+ If you want to install the MySQL RPM on older Linux distributions
+ that do not support initialization scripts in /etc/init.d
+ (directly or via a symlink), you should create a symbolic link
+ that points to the location where your initialization scripts
+ actually are installed. For example, if that location is
+ /etc/rc.d/init.d, use these commands before installing the RPM to
+ create /etc/init.d as a symbolic link that points there:
+shell> cd /etc
+shell> ln -s rc.d/init.d .
+
+ However, all current major Linux distributions should support the
+ new directory layout that uses /etc/init.d, because it is required
+ for LSB (Linux Standard Base) compliance.
+
+ If the RPM files that you install include MySQL-server, the mysqld
+ server should be up and running after installation. You should be
+ able to start using MySQL.
+
+ If something goes wrong, you can find more information in the
+ binary installation section. See Section 2.2, "Installing MySQL
+ from Generic Binaries on Unix/Linux."
+
+Note
+
+ The accounts that are listed in the MySQL grant tables initially
+ have no passwords. After starting the server, you should set up
+ passwords for them using the instructions in Section 2.13,
+ "Post-Installation Setup and Testing."
+
+ During RPM installation, a user named mysql and a group named
+ mysql are created on the system. This is done using the useradd,
+ groupadd, and usermod commands. Those commands require appropriate
+ administrative privileges, which is ensured for locally managed
+ users and groups (as listed in the /etc/passwd and /etc/group
+ files) by the RPM installation process being run by root.
+
+ For nonlocal user management (LDAP, NIS, and so forth), the
+ administrative tools may require additional authentication (such
+ as a password), and will fail if the installing user does not
+ provide this authentication. Even if they fail, the RPM
+ installation will not abort but succeed, and this is intentional.
+ If they failed, some of the intended transfer of ownership may be
+ missing, and it is recommended that the system administrator then
+ manually ensures some appropriate user andgroup exists and
+ manually transfers ownership following the actions in the RPM spec
+ file.
+
+2.7. Installing MySQL on Mac OS X
+
+ MySQL for Mac OS X is available in a number of different forms:
+
+ * Native Package Installer format, which uses the native Mac OS
+ X installer to walk you through the installation of MySQL. For
+ more information, see Section 2.7.1, "Installing MySQL Using
+ the Installation Package." You can use the package installer
+ with Mac OS X 10.3 and later, and available for both PowerPC
+ and Intel architectures, and both 32-bit and 64-bit
+ architectures. There is no Universal Binary available using
+ the package installation method. The user you use to perform
+ the installation must have administrator privileges.
+
+ * Tar package format, which uses a file packaged using the Unix
+ tar and gzip commands. To use this method, you will need to
+ open a Terminal window. You do not need administrator
+ privileges using this method, as you can install the MySQL
+ server anywhere using this method. For more information on
+ using this method, you can use the generic instructions for
+ using a tarball, Section 2.2, "Installing MySQL from Generic
+ Binaries on Unix/Linux."You can use the package installer with
+ Mac OS X 10.3 and later, and available for both PowerPC and
+ Intel architectures, and both 32-bit and 64-bit architectures.
+ A Universal Binary, incorporating both Power PC and Intel
+ architectures and 32-bit and 64-bit binaries is available.
+ In addition to the core installation, the Package Installer
+ also includes Section 2.7.2, "Installing the MySQL Startup
+ Item" and Section 2.7.3, "Installing and Using the MySQL
+ Preference Pane," both of which simplify the management of
+ your installation.
+
+ * Mac OS X server includes a version of MySQL as standard. If
+ you want to use a more recent version than that supplied with
+ the Mac OS X server release, you can make use of the package
+ or tar formats. For more information on using the MySQL
+ bundled with Mac OS X, see Section 2.7.4, "Using MySQL on Mac
+ OS X Server."
+
+ For additional information on using MySQL on Mac OS X, see Section
+ 2.7.5, "MySQL Installation on Mac OS X Notes."
+
+2.7.1. Installing MySQL Using the Installation Package
+
+ You can install MySQL on Mac OS X 10.3.x ("Panther") or newer
+ using a Mac OS X binary package in PKG format instead of the
+ binary tarball distribution. Please note that older versions of
+ Mac OS X (for example, 10.1.x or 10.2.x) are not supported by this
+ package.
+
+ The package is located inside a disk image (.dmg) file that you
+ first need to mount by double-clicking its icon in the Finder. It
+ should then mount the image and display its contents.
+
+Note
+
+ Before proceeding with the installation, be sure to shut down all
+ running MySQL server instances by either using the MySQL Manager
+ Application (on Mac OS X Server) or via mysqladmin shutdown on the
+ command line.
+
+ When installing from the package version, you should also install
+ the MySQL Preference Pane, which will allow you to control the
+ startup and execution of your MySQL server from System
+ Preferences. For more information, see Section 2.7.3, "Installing
+ and Using the MySQL Preference Pane."
+
+ When installing using the package installer, the files are
+ installed into a directory within /usr/local matching the name of
+ the installation version and platform. For example, the installer
+ file mysql-5.1.39-osx10.5-x86_64.pkg installs MySQL into
+ /usr/local/mysql-5.1.39-osx10.5-x86_64 . The installation layout
+ of the directory is as shown in the following table:
+ Directory Contents of Directory
+ bin Client programs and the mysqld server
+ data Log files, databases
+ docs Manual in Info format
+ include Include (header) files
+ lib Libraries
+ man Unix manual pages
+ mysql-test MySQL test suite
+ scripts Contains the mysql_install_db script
+ share/mysql Error message files
+ sql-bench Benchmarks
+ support-files Scripts and sample configuration files
+ /tmp/mysql.sock The location of the MySQL Unix socket
+
+ During the package installer process, a symbolic link from
+ /usr/local/mysql to the version/platform specific directory
+ created during installation will be created automatically.
+
+ 1. Download and open the MySQL package installer, which is
+ provided on a disk image (.dmg). Double-click to open the disk
+ image, which includes the main MySQL installation package, the
+ MySQLStartupItem.pkg installation package, and the
+ MySQL.prefPane.
+
+ 2. Double-click on the MySQL installer package. It will be named
+ according to the version of MySQL you have downloaded. For
+ example, if you have downloaded MySQL 5.1.39, double-click
+ mysql-5.1.39-osx10.5-x86.pkg.
+
+ 3. You will be presented with the openin installer dialog. Click
+ Continue to begihn installation.
+ MySQL Package Installer: Step 1
+
+ 4. A copy of the installation instructions and other important
+ information relevant to this installation are display. Click
+ Continue .
+
+ 5. If you have downloaded the community version of MySQL, you
+ will be shown a copy of the relevent GNU General Public
+ License. Click Continue .
+
+ 6. Select the drive you want to use to install the MySQL Startup
+ Item. The drive must have a valid, bootable, Mac OS X
+ operating system installed. Click Continue.
+ MySQL Package Installer: Step 4
+
+ 7. You will be asked to confirm the details of the installation,
+ including the space required for the installation. To change
+ the drive on which the startup item is installed you can click
+ either Go Back or Change Install Location.... To install the
+ startup item, click Install.
+
+ 8. Once the installation has been completed successfully, you
+ will be given an Install Succeeded message.
+
+ Once you have completed the basic installation, you must complete
+ the post-installation steps as specifed in Section 2.13,
+ "Post-Installation Setup and Testing."
+
+ For convenience, you may also want to install the Section 2.7.2,
+ "Installing the MySQL Startup Item" and Section 2.7.3, "Installing
+ and Using the MySQL Preference Pane."
+
+2.7.2. Installing the MySQL Startup Item
+
+ The MySQL Installation Package includes a startup item that can be
+ used to automatically startup and shutdown MySQL during boot.
+
+ To install the MySQL Startup Item:
+
+ 1. Download and open the MySQL package installer, which is
+ provided on a disk image (.dmg). Double-click to open the disk
+ image, which includes the main MySQL installation package, the
+ MySQLStartupItem.pkg installation package, and the
+ MySQL.prefPane.
+
+ 2. Double-click on the MySQLStartItem.pkg file to start the
+ installation process.
+
+ 3. You will be presented with the Install MySQL Startup Item
+ dialog.
+ MySQL Startup Item Installer: Step 1
+ Click Continue to continue the installation process.
+
+ 4. A copy of the installation instructions and other important
+ information relevant to this installation are display. Click
+ Continue .
+
+ 5. Select the drive you want to use to install the MySQL Startup
+ Item. The drive must have a valid, bootable, Mac OS X
+ operating system installed. Click Continue.
+ MySQL Startup Item Installer: Step 3
+
+ 6. You will be asked to confirm the details of the installation.
+ To change the drive on which the startup item is installed you
+ can click either Go Back or Change Install Location.... To
+ install the startup item, click Install.
+
+ 7. Once the installation has been completed successfully, you
+ will be given an Install Succeeded message.
+ MySQL Startup Item Installer: Step 5
+
+ The Startup Item for MySQL is installed into
+ /Library/StartupItems/MySQLCOM. The Startup Item installation adds
+ a variable MYSQLCOM=-YES- to the system configuration file
+ /etc/hostconfig. If you want to disable the automatic startup of
+ MySQL, simply change this variable to MYSQLCOM=-NO-.
+
+ After the installation, you can start up MySQL by running the
+ following commands in a terminal window. You must have
+ administrator privileges to perform this task.
+
+ If you have installed the Startup Item, use this command to start
+ the server:
+shell> sudo /Library/StartupItems/MySQLCOM/MySQLCOM start
+
+ You may be prompted for your password to complete the startup.
+
+ If you have installed the Startup Item, use this command to stop
+ the server:
+shell> sudo /Library/StartupItems/MySQLCOM/MySQLCOM stop
+
+ You may be prompted for your password to complete the shutdown.
+
+2.7.3. Installing and Using the MySQL Preference Pane
+
+ The MySQL Package installer disk image also includes a custom
+ MySQL Preference Pane that enables you to start, stop and control
+ automated startup during boot of your MySQL installation.
+
+ To install the MySQL Preference Pane:
+
+ 1. Download and open the MySQL package installer package, which
+ is provided on a disk image (.dmg). Double-click to open the
+ disk image, which includes the main MySQL installation
+ package, the MySQLStartupItem.pkg installation package, and
+ the MySQL.prefPane.
+
+ 2. Double click on MySQL.prefPane. The MySQL System Preferences
+ will open.
+
+ 3. If this is the first time you have installed the preference
+ pane, you will be asked to confirm installation and whether
+ you want to install the preference pane for all users, or only
+ the current user. To install the preference pane for all users
+ you will need administrator privileges. If necessary, you will
+ be prompted for the username and password for a user with
+ administrator privileges.
+
+ 4. If you already have the MySQL Preference Pane installed, you
+ will be asked to confirm whether you want to overwrite the
+ existing MySQL Preference Pane.
+
+Note
+
+ The MySQL Preference Pane only starts and stops MySQL installation
+ installed from the MySQL package installation that have been
+ installed in the default location.
+
+ Once the MySQL Preference Pane has been installed, you can control
+ your MySQL server instance using the preference pane. To use the
+ preference pane, open the System Preferences... from the Apple
+ menu. Select the MySQL preference pane by clicking on the MySQL
+ logo within the Other section of the preference panes list.
+ MySQL Preference Pane
+
+ The MySQL Preference Pane shows the current status of the MySQL
+ server, showing stopped (in red) if the server is not running and
+ running (in green) if the server has already been started. The
+ preference pane will also show the current setting for whether the
+ MySQL server has been set to start up automatically.
+
+ * To start MySQL using the preference pane:
+ Click Start MySQL Server. You may be prompted for the username
+ and password of a user with administrator privileges to start
+ the MySQL server.
+
+ * To stop MySQL using the preference pane:
+ Click Stop MySQL Server. You may be prompted for the username
+ and password of a user with administrator privileges to
+ shutdown the MySQL server.
+
+ * To automatically start the MySQL server when the system boots:
+ Check the checkbox next to Automatically Start MySQL Server on
+ Startup.
+
+ * To disable the automatic starting of the MySQL server when the
+ system boots:
+ Uncheck the checkbox next to Automatically Start MySQL Server
+ on Startup.
+
+ You can close the System Preferences... once you have completed
+ your settings.
+
+2.7.4. Using MySQL on Mac OS X Server
+
+ If you are running Mac OS X Server, a version of MySQL should
+ already be installed. The following table shows the versions of
+ MySQL that ship with Mac OS X Server versions.
+ Mac OS X Server Version MySQL Version
+ 10.2-10.2.2 3.23.51
+ 10.2.3-10.2.6 3.23.53
+ 10.3 4.0.14
+ 10.3.2 4.0.16
+ 10.4.0 4.1.10a
+ 10.5.0 5.0.45
+ 10.6.0 5.0.82
+
+ The installation layout of MySQL on Mac OS X Server is as shown in
+ the table below:
+ Directory Contents of Directory
+ /usr/bin Client programs
+ /var/mysql Log files, databases
+ /usr/libexec The mysqld server
+ /usr/share/man Unix manual pages
+ /usr/share/mysql/mysql-test MySQL test suite
+ /usr/share/mysql Contains the mysql_install_db script
+ /var/mysql/mysql.sock The location of the MySQL Unix socket
+
+Note
+
+ The MySQL server bundled with Mac OS X Server does not include the
+ MySQL client libraries and header files required if you want to
+ access and use MySQL from a third-party driver, such as Perl DBI
+ or PHP. For more information on obtaining and installing MySQL
+ libraries, see Mac OS X Server version 10.5: MySQL libraries
+ available for download (http://support.apple.com/kb/TA25017).
+ Alternatively, you can ignore the bundled MySQL server and install
+ MySQL from the package or tarball installation.
+
+ For more information on managing the bundled MySQL instance in Mac
+ OS X Server 10.5, see Mac OS X Server: Web Technologies
+ Administration For Version 10.5 Leopard
+ (http://images.apple.com/server/macosx/docs/Web_Technologies_Admin
+ _v10.5.pdf). For more information on managing the bundled MySQL
+ instance in Mac OS X Server 10.6, see Mac OS X Server: Web
+ Technologies Administration Version 10.6 Snow Leopard
+ (http://manuals.info.apple.com/en_US/WebTech_v10.6.pdf).
+
+2.7.5. MySQL Installation on Mac OS X Notes
+
+ You should keep the following issues and notes in mind:
+
+ * The default location for the MySQL Unix socket is different on
+ Mac OS X and Mac OS X Server depending on the installation
+ type you chose. The default locations by installation are as
+ follows:
+
+ Package Installer from MySQL /tmp/mysql.sock
+ Tarball from MySQL /tmp/mysql.sock
+ MySQL Bundled with Mac OS X Server /var/mysql/mysql.sock
+ To prevent issues, you should either change the configuration
+ of the socket used within your application (for example,
+ changing php.ini), or you should configure the socket location
+ using a MySQL configuration file and the socket option. For
+ more information, see Section 5.1.2, "Server Command Options."
+
+ * You may need (or want) to create a specific mysql user to own
+ the MySQL directory and data. On Mac OS X 10.4 and lower you
+ can do this by using the Netinfo Manager application, located
+ within the Utilities folder within the Applications folder. On
+ Mac OS X 10.5 and later you can do this through the Directory
+ Utility. From Mac OS X 10.5 and later (including Mac OS X
+ Server 10.5) the mysql should already exist. For use in single
+ user mode, an entry for _mysql (note the underscore prefix)
+ should already exist within the system /etc/passwd file.
+
+ * Due to a bug in the Mac OS X package installer, you may see
+ this error message in the destination disk selection dialog:
+You cannot install this software on this disk. (null)
+ If this error occurs, simply click the Go Back button once to
+ return to the previous screen. Then click Continue to advance
+ to the destination disk selection again, and you should be
+ able to choose the destination disk correctly. We have
+ reported this bug to Apple and it is investigating this
+ problem.
+
+ * Because the MySQL package installer installs the MySQL
+ contents into a version and platform specific directory, you
+ can use this to upgrade and migrate your database between
+ versions. You will need to either copy the data directory from
+ the old version to the new version, or alternatively specify
+ an alternative datadir value to set location of the data
+ directory.
+
+ * You might want to add aliases to your shell's resource file to
+ make it easier to access commonly used programs such as mysql
+ and mysqladmin from the command line. The syntax for bash is:
+alias mysql=/usr/local/mysql/bin/mysql
+alias mysqladmin=/usr/local/mysql/bin/mysqladmin
+ For tcsh, use:
+alias mysql /usr/local/mysql/bin/mysql
+alias mysqladmin /usr/local/mysql/bin/mysqladmin
+ Even better, add /usr/local/mysql/bin to your PATH environment
+ variable. You can do this by modifying the appropriate startup
+ file for your shell. For more information, see Section 4.2.1,
+ "Invoking MySQL Programs."
+
+ * After you have copied over the MySQL database files from the
+ previous installation and have successfully started the new
+ server, you should consider removing the old installation
+ files to save disk space. Additionally, you should also remove
+ older versions of the Package Receipt directories located in
+ /Library/Receipts/mysql-VERSION.pkg.
+
+2.8. Installing MySQL on Solaris
+
+ To obtain a binary MySQL distribution for Solaris in tarball or
+ PKG format, http://dev.mysql.com/downloads/mysql/5.1.html.
+
+ If you install MySQL using a binary tarball distribution on
+ Solaris, you may run into trouble even before you get the MySQL
distribution unpacked, as the Solaris tar cannot handle long file
names. This means that you may see errors when you try to unpack
MySQL.
@@ -7504,30 +6353,45 @@ CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors \
If this occurs, you must use GNU tar (gtar) to unpack the
distribution.
- Sun native threads work only on Solaris 2.5 and higher. For
- Solaris 2.4 and earlier, MySQL automatically uses MIT-pthreads.
- See Section 2.10.5, "MIT-pthreads Notes."
+ You can install MySQL on Solaris using a binary package in PKG
+ format instead of the binary tarball distribution. Before
+ installing using the binary PKG format, you should create the
+ mysql user and group, for example:
+groupadd mysql
+useradd -g mysql mysql
- If you get the following error from configure, it means that you
- have something wrong with your compiler installation:
-checking for restartable system calls... configure: error can not
-run test programs while cross compiling
+ Some basic PKG-handling commands follow:
- In this case, you should upgrade your compiler to a newer version.
- You may also be able to solve this problem by inserting the
- following row into the config.cache file:
-ac_cv_sys_restartable_syscalls=${ac_cv_sys_restartable_syscalls='no'}
+ * To add a package:
+pkgadd -d package_name.pkg
- If you are using Solaris on a SPARC, the recommended compiler is
- gcc 2.95.2 or 3.2. You can find this at http://gcc.gnu.org/. Note
- that gcc 2.8.1 does not work reliably on SPARC.
+ * To remove a package:
+pkgrm package_name
- The recommended configure line when using gcc 2.95.2 is:
-CC=gcc CFLAGS="-O3" \
-CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti"
- \
-./configure --prefix=/usr/local/mysql --with-low-memory \
- --enable-assembler
+ * To get a full list of installed packages:
+pkginfo
+
+ * To get detailed information for a package:
+pkginfo -l package_name
+
+ * To list the files belonging to a package:
+pkgchk -v package_name
+
+ * To get packaging information for an arbitrary file:
+pkgchk -l -p file_name
+
+2.8.1. Solaris Notes
+
+ For information about installing MySQL on Solaris using PKG
+ distributions, see Section 2.8, "Installing MySQL on Solaris."
+
+ On Solaris, you may run into trouble even before you get the MySQL
+ distribution unpacked, as the Solaris tar cannot handle long file
+ names. This means that you may see errors when you try to unpack
+ MySQL.
+
+ If this occurs, you must use GNU tar (gtar) to unpack the
+ distribution.
If you have an UltraSPARC system, you can get 4% better
performance by adding -mcpu=v8 -Wa,-xarch=v8plusa to the CFLAGS
@@ -7565,44 +6429,6 @@ CXX=CC CXXFLAGS="-noex -mt -xarch=v9" ASFLAGS="-xarch=v9" \
If you get a problem with fdatasync or sched_yield, you can fix
this by adding LIBS=-lrt to the configure line
- For compilers older than WorkShop 5.3, you might have to edit the
- configure script. Change this line:
-#if !defined(__STDC__) || __STDC__ != 1
-
- To this:
-#if !defined(__STDC__)
-
- If you turn on __STDC__ with the -Xc option, the Sun compiler
- can't compile with the Solaris pthread.h header file. This is a
- Sun bug (broken compiler or broken include file).
-
- If mysqld issues the following error message when you run it, you
- have tried to compile MySQL with the Sun compiler without enabling
- the -mt multi-thread option:
-libc internal error: _rmutex_unlock: rmutex not held
-
- Add -mt to CFLAGS and CXXFLAGS and recompile.
-
- If you are using the SFW version of gcc (which comes with Solaris
- 8), you must add /opt/sfw/lib to the environment variable
- LD_LIBRARY_PATH before running configure.
-
- If you are using the gcc available from sunfreeware.com, you may
- have many problems. To avoid this, you should recompile gcc and
- GNU binutils on the machine where you are running them.
-
- If you get the following error when compiling MySQL with gcc, it
- means that your gcc is not configured for your version of Solaris:
-shell> gcc -O3 -g -O2 -DDBUG_OFF -o thr_alarm ...
-./thr_alarm.c: In function `signal_hand':
-./thr_alarm.c:556: too many arguments to function `sigwait'
-
- The proper thing to do in this case is to get the newest version
- of gcc and compile it with your current gcc compiler. At least for
- Solaris 2.5, almost all binary versions of gcc have old, unusable
- include files that break all programs that use threads, and
- possibly other programs as well.
-
Solaris does not provide static versions of all system libraries
(libpthreads and libdl), so you cannot compile MySQL with
--static. If you try to do so, you get one of the following
@@ -7651,102 +6477,276 @@ Error in accept: Protocol error
You might try starting the server with the --back_log=50 option as
a workaround for this. (Use -O back_log=50 before MySQL 4.)
- Solaris doesn't support core files for setuid() applications, so
- you can't get a core file from mysqld if you are using the --user
- option.
+ To configure the generation of core files on Solaris you should
+ use the coreadm command. Because of the security implications of
+ generating a core on a setuid() application, by default, Solaris
+ does not support core files on setuid() programs. However, you can
+ modify this behavior using coreadm. If you enable setuid() core
+ files for the current user, they will be generated using the mode
+ 600 and owned by the superuser.
-2.13.3.1. Solaris 2.7/2.8 Notes
+2.9. Installing MySQL on i5/OS
- Normally, you can use a Solaris 2.6 binary on Solaris 2.7 and 2.8.
- Most of the Solaris 2.6 issues also apply for Solaris 2.7 and 2.8.
+ The i5/OS POWER MySQL package was created in cooperation with IBM.
+ MySQL works within the Portable Application Solution Environment
+ (PASE) on the System i series of hardware and will also provide
+ database services for the Zend Core for i5/OS.
- MySQL should be able to detect new versions of Solaris
- automatically and enable workarounds for the following problems.
+ MySQL for i5/OS is provided both as a tar file and as a save file
+ (.savf) package that can be downloaded and installed directly
+ without any additional installation steps required. To install
+ MySQL using the tar file, see Section 2.2, "Installing MySQL from
+ Generic Binaries on Unix/Linux."
- Solaris 2.7 / 2.8 has some bugs in the include files. You may see
- the following error when you use gcc:
-/usr/include/widec.h:42: warning: `getwc' redefined
-/usr/include/wchar.h:326: warning: this is the location of the previo
-us
-definition
+ MySQL is only supported on i5/OS V5R4 or later releases. The i5/OS
+ PASE must be installed for MySQL to operate. You must be able to
+ login as a user in *SECOFR class.
- If this occurs, you can fix the problem by copying
- /usr/include/widec.h to .../lib/gcc-lib/os/gcc-version/include and
- changing line 41 from this:
-#if !defined(lint) && !defined(__lint)
+ You should the installation notes and tips for i5/OS before
+ starting installation. See i5/OS Installation Notes.
- To this:
-#if !defined(lint) && !defined(__lint) && !defined(getwc)
+ Before Installation:
- Alternatively, you can edit /usr/include/widec.h directly. Either
- way, after you make the fix, you should remove config.cache and
- run configure again.
+Note
- If you get the following errors when you run make, it is because
- configure didn't detect the curses.h file (probably because of the
- error in /usr/include/widec.h):
-In file included from mysql.cc:50:
-/usr/include/term.h:1060: syntax error before `,'
-/usr/include/term.h:1081: syntax error before `;'
+ The installation package will use an existing configuration if you
+ have previously installed MySQL (which is identified by looking
+ for the file /etc/my.cnf). The values for the data directory
+ (DATADIR) and owner of the MySQL files (USRPRF) specified during
+ the installation will be ignored, and the values determined from
+ the /etc/my.cnf will be used instead.
- The solution to this problem is to do one of the following:
+ If you want to change these parameters during a new install, you
+ should temporarily rename /etc/my.cnf, install MySQL using the new
+ parameters you want to use, and then merge your previous
+ /etc/my.cnf configuration settings with the new /etc/my.cnf file
+ that is created during installation.
- 1. Configure with CFLAGS=-DHAVE_CURSES_H CXXFLAGS=-DHAVE_CURSES_H
- ./configure.
+ * You must have a user profile with PASE with suitable
+ privileges. The user should be within the *SECOFR class, such
+ as the QSECOFR user ID. You can use the WRKUSRPRF command to
+ check your user profile.
- 2. Edit /usr/include/widec.h as indicated in the preceding
- discussion and re-run configure.
+ * For network connections to MySQL, you must have TCP/IP
+ enabled. You should also check the following:
- 3. Remove the #define HAVE_TERM line from the config.h file and
- run make again.
+ + Ensure that a name has defined for the system. Run the
+ Configure TCP/IP (CFGTCP) command and select option 12
+ (Change TCP/IP domain information) to display this
+ setting. Make sure that a value is listed in the Host
+ name field.
- If your linker cannot find -lz when linking client programs, the
- problem is probably that your libz.so file is installed in
- /usr/local/lib. You can fix this problem by one of the following
- methods:
+ + Make sure that the system has a loopback entry which
+ represents the localhost or 127.0.0.1.
- * Add /usr/local/lib to LD_LIBRARY_PATH.
+ + Ensure that the IP address of the IBM i machine is mapped
+ correctly to the host name.
- * Add a link to libz.so from /lib.
+ To install MySQL on i5/OS, follow these steps:
- * If you are using Solaris 8, you can install the optional zlib
- from your Solaris 8 CD distribution.
+ 1. On the System i machine, create a save file that will be used
+ to receive the downloaded installation save file. The file
+ should be located within the General Purpose Library (QGPL):
+CRTSAVF FILE(QGPL/MYSQLINST) TESXT('MySQL Save file')
- * Run configure with the --with-named-z-libs=no option when
- building MySQL.
+ 2. Download the MySQL installation save file in 32-bit
+ (mysql-5.1.39-i5os-power-32bit.savf) or 64-bit
+ (mysql-5.1.39-i5os-power-64bit.savf) from MySQL Downloads
+ (http://dev.mysql.com/downloads).
-2.13.3.2. Solaris x86 Notes
+ 3. You need to FTP the downloaded .savf file directly into the
+ QGPL/MYSQLINST file on the System i server. You can do this
+ through FTP using the following steps after logging in to the
+ System i machine:
+ftp> bin
+ftp> cd qgpl
+ftp> put mysql-5.1.39-i5os-power.savf mysqlinst
+
+ 4. Log into the System i server using a user in the *SECOFR
+ class, such as the QSECOFR user ID.
- On Solaris 8 on x86, mysqld dumps core if you remove the debug
- symbols using strip.
+ 5. You need to restore the installation library stored in the
+ .savf save file:
+RSTLIB MYSQLINST DEV(*SAVF) SAVF(QGPL/MYSQLINST) MBROPT(*ALL) ALWOBJD
+IF(*ALL)
- If you are using gcc on Solaris x86 and you experience problems
- with core dumps under load, you should use the following configure
- command:
-CC=gcc CFLAGS="-O3 -fomit-frame-pointer -DHAVE_CURSES_H" \
-CXX=gcc \
-CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors \
- -fno-exceptions -fno-rtti -DHAVE_CURSES_H" \
-./configure --prefix=/usr/local/mysql
+Note
+ You can ignore the security changes-type message at the bottom
+ of the installation panel.
- This avoids problems with the libstdc++ library and with C++
- exceptions.
+ 6. Once you have finished restoring the MYSQLINST library, check
+ that all the necessary objects for installation are on the
+ system by using the Display Library (DSPLIB) command:
+DSPLIB LIB(MYSQLINST)
- If this doesn't help, you should compile a debug version and run
- it with a trace file or under gdb. See MySQL Internals: Porting
- (http://forge.mysql.com/wiki/MySQL_Internals_Porting).
+ 7. You need to execute the installation command,
+ MYSQLINST/INSMYSQL. You can specify three parameter settings
+ during installation:
-2.13.4. BSD Notes
+ + DIR('/QOpenSys/usr/local/mysql') sets the installation
+ location for the MySQL files. The directory will be
+ created if it does not already exist.
- This section provides information about using MySQL on variants of
- BSD Unix.
+ + DATADIR('/QOpenSys/usr/local/mysql/data') sets the
+ location of the directory that will be used to store the
+ database files and binary logs. The default setting is
+ /QOpenSys/usr/local/mysql/data. Note that if the
+ installer detects an existing installation (due to the
+ existence of /etc/my.cnf), then the existing setting will
+ be used instead of the default.
+
+ + USRPRF(MYSQL) sets the user profile that will own the
+ files that are installed. The profile will be created if
+ it does not already exist.
+
+Note
+ You should choose an appropriate user for using the MySQL
+ server installation. The user will be used whenever you
+ need to do any administration on the MySQL server.
+ Once you have set the appropriate parameters, you can begin
+ the installation.
+ The installation copies all the necessary files into a
+ directory matching the DIR configuration value; sets the
+ ownership on those files, sets up the MySQL environment and
+ creates the MySQL configuration file (in /etc/my.cnf)
+ completing all the steps in a typical binary installation
+ process automatically. If this is a new installation of MySQL,
+ or if the installer detects that this is a new version
+ (because the /etc/my.cnf file does not exist), then the
+ initial core MySQL databases will also be created during
+ installation.
+ Once the installation has been completed, you will get a
+ notice advising you to set the password for the root user. For
+ more information, Section 2.13, "Post-Installation Setup and
+ Testing."
+
+ 8. Once the installation has completed, you can delete the
+ installation file:
+DLTLIB LIB(MYSQLINST)
+
+ Upgrading an existing MySQL instance
+
+ You need to execute the upgrade command, MYSQLINST/UPGMYSQL. You
+ must specify 6 parameters to perform an upgrade:
+
+ * DIR('/QOpenSys/usr/local/') --- sets the installation location
+ for the MySQL files. The directory will be created if it does
+ not already exist. This is the directory that the MySQL server
+ will be installed into, inside a directory with a name
+ matching the version and release. For example if installing
+ MySQL 5.1.39 with the DIR set to /QOpenSys/usr/local/ would
+ result in /QOpenSys/usr/local/mysql-5.1.39-i5os-power64 and a
+ symbolic link to this directory will be created in
+ /QOpenSys/usr/local/mysql.
+
+ * DATADIR('/QOpenSys/mysql/data') --- sets the location of the
+ directory that will be upgraded.
+
+ * USRPRF('MYSQL') --- sets the user profile that will own the
+ files that are installed. The profile will be created if it
+ does not already exist; if it is created as part of the
+ upgrade process, it will be disabled initially. You may wish
+ to enable this user profile so that it can be used to start
+ the MySQL server later. It is best practice to use the one
+ previously created during the first installation.
+
+ * MYSQLUSR('root user') --- any user account in the current
+ MySQL server with SUPER privileges.
+
+ * PASSWORD('root user password') --- the password for the above
+ account. This is necessary as the upgrade starts the MySQL
+ server to upgrade the tables and the password is need to be
+ able to shutdown the MySQL server.
+
+ * CURINST('path to previous install') --- the full path to the
+ installation that is being upgraded. For example an
+ installation in /QOpenSys/usr/local/ will be
+ /QOpenSys/usr/local/msyql-5.1.30-i5os-power64. Failure to
+ specify this option may result in corruption of your existing
+ data files.
+
+ For example:
+MYSQLINST/UPGMYSQL DIR('/QOpenSys/usr/local/') DATADIR('/QOpenSys/mys
+ql/data') »
+ USERPRF(MYSQL) MYSQLUSR('root') PASSWORD('root') CURINST('/QOpen
+Sys/usr/local/mysql-5.1.30-i5os-power64')
+
+ You should receive a Program Message indicating UPGRADE
+ SUCCESSFUL! upon completion or an error message if there is a
+ problem.You can view the upgrade programs progression and the
+ error in the text file upgrade.log in the installation directory.
+
+ To start MySQL:
+
+ 1. Log into the System i server using the user profile create or
+ specified during installation. By default, this is MYSQL.
+
+Note
+ You should start mysqld_safe using a user that in the PASE
+ environment has the id=0 (the equivalent of the standard Unix
+ root user). If you do not use a user with this ID then the
+ system will be unable to change the user when executing mysqld
+ as set using --user option. If this happens, mysqld may be
+ unable to read the files located within the MySQL data
+ directory and the execution will fail.
+
+ 2. Enter the PASE environment using call qp2term.
+
+ 3. Start the MySQL server by changing to the installation
+ directory and running mysqld_safe, specifying the user name
+ used to install the server. The installer conveniently
+ installs a symbolic link to the installation directory
+ (mysql-5.0.42-i5os-power-32bit) as /opt/mysql/mysql:
+> cd /opt/mysql/mysql
+> bin/mysqld_safe --user=mysql &
+ You should see a message similar to the following:
+Starting mysqld daemon with databases »
+ from /opt/mysql/mysql-enterprise-5.0.42-i5os-power-32bit/data
+
+ If you are having problems starting MySQL server, see Section
+ 2.13.1.3, "Starting and Troubleshooting the MySQL Server."
+
+ To stop MySQL:
+
+ 1. Log into the System i server using the user profile create or
+ specified during installation. By default, this is MYSQL.
+
+ 2. Enter the PASE environment using call qp2term.
+
+ 3. Stop the MySQL server by changing into the installation
+ directory and running mysqladmin, specifying the user name
+ used to install the server:
+> cd /opt/mysql/mysql
+> bin/mysqladmin -u root shutdown
+ If the session that you started and stopped MySQL are the
+ same, you may get the log output from mysqld:
+ STOPPING server from pid file »
+ /opt/mysql/mysql-enterprise-5.0.42-i5os-power-32bit/data/I5DBX.R
+CHLAND.IBM.COM.pid
+ 070718 10:34:20 mysqld ended
+ If the sessions used to start and stop MySQL are different,
+ you will not receive any confirmation of the shutdown.
+
+ Note and tips
+
+ * A problem has been identified with the installation process on
+ DBCS systems. If you are having problems install MySQL on a
+ DBCS system, you need to change your job's coded character set
+ identifier (CSSID) to 37 (EBCDIC) before executing the install
+ command, INSMYSQL. To do this, determine your existing CSSID
+ (using DSPJOB and selecting option 2), execute CHGJOB
+ CSSID(37), run INSMYSQL to install MySQL and then execute
+ CHGJOB again with your original CSSID.
-2.13.4.1. FreeBSD Notes
+ * If you want to use the Perl scripts that are included with
+ MySQL, you need to download the iSeries Tools for Developers
+ (5799-PTL). See
+ http://www-03.ibm.com/servers/enable/site/porting/tools/.
- FreeBSD 4.x or newer is recommended for running MySQL, because the
- thread package is much more integrated. To get a secure and stable
- system, you should use only FreeBSD kernels that are marked
- -RELEASE.
+2.10. Installing MySQL on FreeBSD
+
+ This section provides information about using MySQL on variants of
+ FreeBSD Unix.
The easiest (and preferred) way to install MySQL is to use the
mysql-server and mysql-client ports available at
@@ -7766,37 +6766,6 @@ CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors \
* The ability to use pkg_delete to remove MySQL if you no longer
want it on your machine.
- It is recommended you use MIT-pthreads on FreeBSD 2.x, and native
- threads on FreeBSD 3 and up. It is possible to run with native
- threads on some late 2.2.x versions, but you may encounter
- problems shutting down mysqld.
-
- Unfortunately, certain function calls on FreeBSD are not yet fully
- thread-safe. Most notably, this includes the gethostbyname()
- function, which is used by MySQL to convert host names into IP
- addresses. Under certain circumstances, the mysqld process
- suddenly causes 100% CPU load and is unresponsive. If you
- encounter this problem, try to start MySQL using the
- --skip-name-resolve option.
-
- Alternatively, you can link MySQL on FreeBSD 4.x against the
- LinuxThreads library, which avoids a few of the problems that the
- native FreeBSD thread implementation has. For a very good
- comparison of LinuxThreads versus native threads, see Jeremy
- Zawodny's article FreeBSD or Linux for your MySQL Server? at
- http://jeremy.zawodny.com/blog/archives/000697.html.
-
- Known problem when using LinuxThreads on FreeBSD is:
-
- * The connection times (wait_timeout, interactive_timeout and
- net_read_timeout) values are not honored. The symptom is that
- persistent connections can hang for a very long time without
- getting closed down and that a 'kill' for a thread will not
- take affect until the thread does it a new command
- This is probably a signal handling problem in the thread
- library where the signal doesn't break a pending read. This is
- supposed to be fixed in FreeBSD 5.0
-
The MySQL build process requires GNU make (gmake) to work. If GNU
make is not available, you must install it first before compiling
MySQL.
@@ -7813,23 +6782,8 @@ cd /usr/local/mysql
bin/mysql_install_db --user=mysql
bin/mysqld_safe &
- If you notice that configure uses MIT-pthreads, you should read
- the MIT-pthreads notes. See Section 2.10.5, "MIT-pthreads Notes."
-
- If you get an error from make install that it can't find
- /usr/include/pthreads, configure didn't detect that you need
- MIT-pthreads. To fix this problem, remove config.cache, and then
- re-run configure with the --with-mit-threads option.
-
- Be sure that your name resolver setup is correct. Otherwise, you
- may experience resolver delays or failures when connecting to
- mysqld. Also make sure that the localhost entry in the /etc/hosts
- file is correct. The file should start with a line similar to
- this:
-127.0.0.1 localhost localhost.your.domain
-
FreeBSD is known to have a very low default file handle limit. See
- Section B.1.2.18, "'File' Not Found and Similar Errors." Start the
+ Section B.5.2.18, "'File' Not Found and Similar Errors." Start the
server by using the --open-files-limit option for mysqld_safe, or
raise the limits for the mysqld user in /etc/login.conf and
rebuild it with cap_mkdb /etc/login.conf. Also be sure that you
@@ -7837,15 +6791,11 @@ bin/mysqld_safe &
you are not using the default (use chpass mysqld-user-name). See
Section 4.3.2, "mysqld_safe --- MySQL Server Startup Script."
- FreeBSD limits the size of a process to 512MB, even if you have
- much more RAM available on the system. So you may get an error
- such as this:
-Out of memory (Needed 16391 bytes)
-
In current versions of FreeBSD (at least 4.x and greater), you may
- increase this limit by adding the following entries to the
- /boot/loader.conf file and rebooting the machine (these are not
- settings that can be changed at run time with the sysctl command):
+ increase the limit on the amount of memory available for a process
+ by adding the following entries to the /boot/loader.conf file and
+ rebooting the machine (these are not settings that can be changed
+ at run time with the sysctl command):
kern.maxdsiz="1073741824" # 1GB
kern.dfldsiz="1073741824" # 1GB
kern.maxssiz="134217728" # 128MB
@@ -7858,135 +6808,7 @@ kern.maxssiz="134217728" # 128MB
If you get problems with the current date in MySQL, setting the TZ
variable should help. See Section 2.14, "Environment Variables."
-2.13.4.2. NetBSD Notes
-
- To compile on NetBSD, you need GNU make. Otherwise, the build
- process fails when make tries to run lint on C++ files.
-
-2.13.4.3. OpenBSD 2.5 Notes
-
- On OpenBSD 2.5, you can compile MySQL with native threads with the
- following options:
-CFLAGS=-pthread CXXFLAGS=-pthread ./configure --with-mit-threads=no
-
-2.13.4.4. BSD/OS Version 2.x Notes
-
- If you get the following error when compiling MySQL, your ulimit
- value for virtual memory is too low:
-item_func.h: In method
-`Item_func_ge::Item_func_ge(const Item_func_ge &)':
-item_func.h:28: virtual memory exhausted
-make[2]: *** [item_func.o] Error 1
-
- Try using ulimit -v 80000 and run make again. If this doesn't work
- and you are using bash, try switching to csh or sh; some BSDI
- users have reported problems with bash and ulimit.
-
- If you are using gcc, you may also use have to use the
- --with-low-memory flag for configure to be able to compile
- sql_yacc.cc.
-
- If you get problems with the current date in MySQL, setting the TZ
- variable should help. See Section 2.14, "Environment Variables."
-
-2.13.4.5. BSD/OS Version 3.x Notes
-
- Upgrade to BSD/OS 3.1. If that is not possible, install BSDIpatch
- M300-038.
-
- Use the following command when configuring MySQL:
-env CXX=shlicc++ CC=shlicc2 \
-./configure \
- --prefix=/usr/local/mysql \
- --localstatedir=/var/mysql \
- --without-perl \
- --with-unix-socket-path=/var/mysql/mysql.sock
-
- The following is also known to work:
-env CC=gcc CXX=gcc CXXFLAGS=-O3 \
-./configure \
- --prefix=/usr/local/mysql \
- --with-unix-socket-path=/var/mysql/mysql.sock
-
- You can change the directory locations if you wish, or just use
- the defaults by not specifying any locations.
-
- If you have problems with performance under heavy load, try using
- the --skip-thread-priority option to mysqld. This runs all threads
- with the same priority. On BSDI 3.1, this gives better
- performance, at least until BSDI fixes its thread scheduler.
-
- If you get the error virtual memory exhausted while compiling, you
- should try using ulimit -v 80000 and running make again. If this
- doesn't work and you are using bash, try switching to csh or sh;
- some BSDI users have reported problems with bash and ulimit.
-
-2.13.4.6. BSD/OS Version 4.x Notes
-
- BSDI 4.x has some thread-related bugs. If you want to use MySQL on
- this, you should install all thread-related patches. At least
- M400-023 should be installed.
-
- On some BSDI 4.x systems, you may get problems with shared
- libraries. The symptom is that you can't execute any client
- programs, for example, mysqladmin. In this case, you need to
- reconfigure not to use shared libraries with the --disable-shared
- option to configure.
-
- Some customers have had problems on BSDI 4.0.1 that the mysqld
- binary after a while can't open tables. This occurs because some
- library/system-related bug causes mysqld to change current
- directory without having asked for that to happen.
-
- The fix is to either upgrade MySQL to at least version 3.23.34 or,
- after running configure, remove the line #define HAVE_REALPATH
- from config.h before running make.
-
- Note that this means that you can't symbolically link a database
- directories to another database directory or symbolic link a table
- to another database on BSDI. (Making a symbolic link to another
- disk is okay).
-
-2.13.5. Other Unix Notes
-
-2.13.5.1. HP-UX Version 10.20 Notes
-
- If you install MySQL using a binary tarball distribution on HP-UX,
- you may run into trouble even before you get the MySQL
- distribution unpacked, as the HP-UX tar cannot handle long file
- names. This means that you may see errors when you try to unpack
- MySQL.
-
- If this occurs, you must use GNU tar (gtar) to unpack the
- distribution.
-
- There are a couple of small problems when compiling MySQL on
- HP-UX. Use gcc instead of the HP-UX native compiler, because gcc
- produces better code.
-
- Use gcc 2.95 on HP-UX. Don't use high optimization flags (such as
- -O6) because they may not be safe on HP-UX.
-
- The following configure line should work with gcc 2.95:
-CFLAGS="-I/opt/dce/include -fpic" \
-CXXFLAGS="-I/opt/dce/include -felide-constructors -fno-exceptions \
--fno-rtti" \
-CXX=gcc \
-./configure --with-pthread \
- --with-named-thread-libs='-ldce' \
- --prefix=/usr/local/mysql --disable-shared
-
- The following configure line should work with gcc 3.1:
-CFLAGS="-DHPUX -I/opt/dce/include -O3 -fPIC" CXX=gcc \
-CXXFLAGS="-DHPUX -I/opt/dce/include -felide-constructors \
- -fno-exceptions -fno-rtti -O3 -fPIC" \
-./configure --prefix=/usr/local/mysql \
- --with-extra-charsets=complex --enable-thread-safe-client \
- --enable-local-infile --with-pthread \
- --with-named-thread-libs=-ldce --with-lib-ccflags=-fPIC
- --disable-shared
-
-2.13.5.2. HP-UX Version 11.x Notes
+2.11. Installing MySQL on HP-UX
If you install MySQL using a binary tarball distribution on HP-UX,
you may run into trouble even before you get the MySQL
@@ -8065,7 +6887,7 @@ Try gcc. See the Installation chapter in the Reference Manual.
11. If you encounter problems, you should be sure to check your
HP-UX patch level.
-2.13.5.3. IBM-AIX notes
+2.12. Installing MySQL on AIX
Automatic detection of xlC is missing from Autoconf, so a number
of variables need to be set before running configure. The
@@ -8127,6 +6949,9 @@ CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" \
This gives you a machine type and a machine model you can use to
determine what type of CPU you have.
+ If you have problems with threads on AIX 5.3, you should upgrade
+ AIX 5.3 to technology level 7 (5300-07).
+
If you have problems with signals (MySQL dies unexpectedly under
high load), you may have found an OS bug with threads and signals.
In this case, you can tell MySQL not to use signals by configuring
@@ -8211,752 +7036,904 @@ fined
extern int endwin (void);
extern int getcurx (WINDOW *);
-2.13.5.4. SunOS 4 Notes
-
- On SunOS 4, MIT-pthreads is needed to compile MySQL. This in turn
- means you need GNU make.
-
- Some SunOS 4 systems have problems with dynamic libraries and
- libtool. You can use the following configure line to avoid this
- problem:
-./configure --disable-shared --with-mysqld-ldflags=-all-static
-
- When compiling readline, you may get warnings about duplicate
- defines. These can be ignored.
-
- When compiling mysqld, there are some implicit declaration of
- function warnings. These can be ignored.
-
-2.13.5.5. Alpha-DEC-UNIX Notes (Tru64)
-
- If you are using egcs 1.1.2 on Digital Unix, you should upgrade to
- gcc 2.95.2, because egcs on DEC has some serious bugs!
-
- When compiling threaded programs under Digital Unix, the
- documentation recommends using the -pthread option for cc and cxx
- and the -lmach -lexc libraries (in addition to -lpthread). You
- should run configure something like this:
-CC="cc -pthread" CXX="cxx -pthread -O" \
-./configure --with-named-thread-libs="-lpthread -lmach -lexc -lc"
-
- When compiling mysqld, you may see a couple of warnings like this:
-mysqld.cc: In function void handle_connections()':
-mysqld.cc:626: passing long unsigned int *' as argument 3 of
-accept(int,sockadddr *, int *)'
-
- You can safely ignore these warnings. They occur because configure
- can detect only errors, not warnings.
-
- If you start the server directly from the command line, you may
- have problems with it dying when you log out. (When you log out,
- your outstanding processes receive a SIGHUP signal.) If so, try
- starting the server like this:
-nohup mysqld [options] &
-
- nohup causes the command following it to ignore any SIGHUP signal
- sent from the terminal. Alternatively, start the server by running
- mysqld_safe, which invokes mysqld using nohup for you. See Section
- 4.3.2, "mysqld_safe --- MySQL Server Startup Script."
-
- If you get a problem when compiling mysys/get_opt.c, just remove
- the #define _NO_PROTO line from the start of that file.
-
- If you are using Compaq's CC compiler, the following configure
- line should work:
-CC="cc -pthread"
-CFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed \
- -speculate all -arch host"
-CXX="cxx -pthread"
-CXXFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed \
- -speculate all -arch host -noexceptions -nortti"
-export CC CFLAGS CXX CXXFLAGS
-./configure \
- --prefix=/usr/local/mysql \
- --with-low-memory \
- --enable-large-files \
- --enable-shared=yes \
- --with-named-thread-libs="-lpthread -lmach -lexc -lc"
-gnumake
-
- If you get a problem with libtool when compiling with shared
- libraries as just shown, when linking mysql, you should be able to
- get around this by issuing these commands:
-cd mysql
-/bin/sh ../libtool --mode=link cxx -pthread -O3 -DDBUG_OFF \
- -O4 -ansi_alias -ansi_args -fast -inline speed \
- -speculate all \ -arch host -DUNDEF_HAVE_GETHOSTBYNAME_R \
- -o mysql mysql.o readline.o sql_string.o completion_hash.o \
- ../readline/libreadline.a -lcurses \
- ../libmysql/.libs/libmysqlclient.so -lm
-cd ..
-gnumake
-gnumake install
-scripts/mysql_install_db
-
-2.13.5.6. Alpha-DEC-OSF/1 Notes
-
- If you have problems compiling and have DEC CC and gcc installed,
- try running configure like this:
-CC=cc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 \
-./configure --prefix=/usr/local/mysql
-
- If you get problems with the c_asm.h file, you can create and use
- a 'dummy' c_asm.h file with:
-touch include/c_asm.h
-CC=gcc CFLAGS=-I./include \
-CXX=gcc CXXFLAGS=-O3 \
-./configure --prefix=/usr/local/mysql
-
- Note that the following problems with the ld program can be fixed
- by downloading the latest DEC (Compaq) patch kit from:
- http://ftp.support.compaq.com/public/unix/.
-
- On OSF/1 V4.0D and compiler "DEC C V5.6-071 on Digital Unix V4.0
- (Rev. 878)," the compiler had some strange behavior (undefined asm
- symbols). /bin/ld also appears to be broken (problems with _exit
- undefined errors occurring while linking mysqld). On this system,
- we have managed to compile MySQL with the following configure
- line, after replacing /bin/ld with the version from OSF 4.0C:
-CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
-
- With the Digital compiler "C++ V6.1-029," the following should
- work:
-CC=cc -pthread
-CFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed \
- -speculate all -arch host
-CXX=cxx -pthread
-CXXFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed \
- -speculate all -arch host -noexceptions -nortti
-export CC CFLAGS CXX CXXFLAGS
-./configure --prefix=/usr/mysql/mysql \
- --with-mysqld-ldflags=-all-static --disable-shared \
- --with-named-thread-libs="-lmach -lexc -lc"
-
- In some versions of OSF/1, the alloca() function is broken. Fix
- this by removing the line in config.h that defines 'HAVE_ALLOCA'.
-
- The alloca() function also may have an incorrect prototype in
- /usr/include/alloca.h. This warning resulting from this can be
- ignored.
-
- configure uses the following thread libraries automatically:
- --with-named-thread-libs="-lpthread -lmach -lexc -lc".
-
- When using gcc, you can also try running configure like this:
-CFLAGS=-D_PTHREAD_USE_D4 CXX=gcc CXXFLAGS=-O3 ./configure ...
+2.13. Post-Installation Setup and Testing
- If you have problems with signals (MySQL dies unexpectedly under
- high load), you may have found an OS bug with threads and signals.
- In this case, you can tell MySQL not to use signals by configuring
- with:
-CFLAGS=-DDONT_USE_THR_ALARM \
-CXXFLAGS=-DDONT_USE_THR_ALARM \
-./configure ...
+ After installing MySQL, there are some issues that you should
+ address. For example, on Unix, you should initialize the data
+ directory and create the MySQL grant tables. On all platforms, an
+ important security concern is that the initial accounts in the
+ grant tables have no passwords. You should assign passwords to
+ prevent unauthorized access to the MySQL server. Optionally, you
+ can create time zone tables to enable recognition of named time
+ zones.
- This does not affect the performance of MySQL, but has the side
- effect that you can't kill clients that are "sleeping" on a
- connection with mysqladmin kill or mysqladmin shutdown. Instead,
- the client dies when it issues its next command.
+ The following sections include post-installation procedures that
+ are specific to Windows systems and to Unix systems. Another
+ section, Section 2.13.1.3, "Starting and Troubleshooting the MySQL
+ Server," applies to all platforms; it describes what to do if you
+ have trouble getting the server to start. Section 2.13.2,
+ "Securing the Initial MySQL Accounts," also applies to all
+ platforms. You should follow its instructions to make sure that
+ you have properly protected your MySQL accounts by assigning
+ passwords to them.
- With gcc 2.95.2, you may encounter the following compile error:
-sql_acl.cc:1456: Internal compiler error in `scan_region',
-at except.c:2566
-Please submit a full bug report.
-
- To fix this, you should change to the sql directory and do a
- cut-and-paste of the last gcc line, but change -O3 to -O0 (or add
- -O0 immediately after gcc if you don't have any -O option on your
- compile line). After this is done, you can just change back to the
- top-level directory and run make again.
-
-2.13.5.7. SGI Irix Notes
-
- As of MySQL 5.0, we don't provide binaries for Irix any more.
-
- If you are using Irix 6.5.3 or newer, mysqld is able to create
- threads only if you run it as a user that has CAP_SCHED_MGT
- privileges (such as root) or give the mysqld server this privilege
- with the following shell command:
-chcap "CAP_SCHED_MGT+epi" /opt/mysql/libexec/mysqld
-
- You may have to undefine some symbols in config.h after running
- configure and before compiling.
-
- In some Irix implementations, the alloca() function is broken. If
- the mysqld server dies on some SELECT statements, remove the lines
- from config.h that define HAVE_ALLOC and HAVE_ALLOCA_H. If
- mysqladmin create doesn't work, remove the line from config.h that
- defines HAVE_READDIR_R. You may have to remove the HAVE_TERM_H
- line as well.
-
- SGI recommends that you install all the patches on this page as a
- set:
- http://support.sgi.com/surfzone/patches/patchset/6.2_indigo.rps.ht
- ml
-
- At the very minimum, you should install the latest kernel rollup,
- the latest rld rollup, and the latest libc rollup.
-
- You definitely need all the POSIX patches on this page, for
- pthreads support:
-
- http://support.sgi.com/surfzone/patches/patchset/6.2_posix.rps.htm
- l
-
- If you get the something like the following error when compiling
- mysql.cc:
-"/usr/include/curses.h", line 82: error(1084):
-invalid combination of type
-
- Type the following in the top-level directory of your MySQL source
- tree:
-extra/replace bool curses_bool < /usr/include/curses.h > include/curs
-es.h
-make
-
- There have also been reports of scheduling problems. If only one
- thread is running, performance is slow. Avoid this by starting
- another client. This may lead to a two-to-tenfold increase in
- execution speed thereafter for the other thread. This is a poorly
- understood problem with Irix threads; you may have to improvise to
- find solutions until this can be fixed.
-
- If you are compiling with gcc, you can use the following configure
- command:
-CC=gcc CXX=gcc CXXFLAGS=-O3 \
-./configure --prefix=/usr/local/mysql --enable-thread-safe-client \
- --with-named-thread-libs=-lpthread
-
- On Irix 6.5.11 with native Irix C and C++ compilers ver. 7.3.1.2,
- the following is reported to work
-CC=cc CXX=CC CFLAGS='-O3 -n32 -TARG:platform=IP22 -I/usr/local/includ
-e \
--L/usr/local/lib' CXXFLAGS='-O3 -n32 -TARG:platform=IP22 \
--I/usr/local/include -L/usr/local/lib' \
-./configure --prefix=/usr/local/mysql --with-innodb \
- --with-libwrap=/usr/local \
- --with-named-curses-libs=/usr/local/lib/libncurses.a
-
-2.13.5.8. SCO UNIX and OpenServer 5.0.x Notes
-
- The current port is tested only on sco3.2v5.0.5, sco3.2v5.0.6, and
- sco3.2v5.0.7 systems. There has also been progress on a port to
- sco3.2v4.2. Open Server 5.0.8 (Legend) has native threads and
- allows files greater than 2GB. The current maximum file size is
- 2GB.
-
- We have been able to compile MySQL with the following configure
- command on OpenServer with gcc 2.95.3.
-CC=gcc CFLAGS="-D_FILE_OFFSET_BITS=64 -O3" \
-CXX=gcc CXXFLAGS="-D_FILE_OFFSET_BITS=64 -O3" \
-./configure --prefix=/usr/local/mysql \
- --enable-thread-safe-client --with-innodb \
- --with-openssl --with-vio --with-extra-charsets=complex
-
- gcc is available at
- ftp://ftp.sco.com/pub/openserver5/opensrc/gnutools-5.0.7Kj.
-
- This development system requires the OpenServer Execution
- Environment Supplement oss646B on OpenServer 5.0.6 and oss656B and
- The OpenSource libraries found in gwxlibs. All OpenSource tools
- are in the opensrc directory. They are available at
- ftp://ftp.sco.com/pub/openserver5/opensrc/.
-
- Use the latest production release of MySQL.
-
- SCO provides operating system patches at
- ftp://ftp.sco.com/pub/openserver5 for OpenServer 5.0.[0-6] and
- ftp://ftp.sco.com/pub/openserverv5/507 for OpenServer 5.0.7.
-
- SCO provides information about security fixes at
- ftp://ftp.sco.com/pub/security/OpenServer for OpenServer 5.0.x.
-
- The maximum file size on an OpenServer 5.0.x system is 2GB.
-
- The total memory which can be allocated for streams buffers,
- clists, and lock records cannot exceed 60MB on OpenServer 5.0.x.
-
- Streams buffers are allocated in units of 4096 byte pages, clists
- are 70 bytes each, and lock records are 64 bytes each, so:
-(NSTRPAGES x 4096) + (NCLIST x 70) + (MAX_FLCKREC x 64) <= 62914560
-
- Follow this procedure to configure the Database Services option.
- If you are unsure whether an application requires this, see the
- documentation provided with the application.
-
- 1. Log in as root.
-
- 2. Enable the SUDS driver by editing the /etc/conf/sdevice.d/suds
- file. Change the N in the second field to a Y.
-
- 3. Use mkdev aio or the Hardware/Kernel Manager to enable support
- for asynchronous I/O and relink the kernel. To allow users to
- lock down memory for use with this type of I/O, update the
- aiomemlock(F) file. This file should be updated to include the
- names of users that can use AIO and the maximum amounts of
- memory they can lock down.
-
- 4. Many applications use setuid binaries so that you need to
- specify only a single user. See the documentation provided
- with the application to determine whether this is the case for
- your application.
-
- After you complete this process, reboot the system to create a new
- kernel incorporating these changes.
-
- By default, the entries in /etc/conf/cf.d/mtune are set as
- follows:
-Value Default Min Max
------ ------- --- ---
-NBUF 0 24 450000
-NHBUF 0 32 524288
-NMPBUF 0 12 512
-MAX_INODE 0 100 64000
-MAX_FILE 0 100 64000
-CTBUFSIZE 128 0 256
-MAX_PROC 0 50 16000
-MAX_REGION 0 500 160000
-NCLIST 170 120 16640
-MAXUP 100 15 16000
-NOFILES 110 60 11000
-NHINODE 128 64 8192
-NAUTOUP 10 0 60
-NGROUPS 8 0 128
-BDFLUSHR 30 1 300
-MAX_FLCKREC 0 50 16000
-PUTBUFSZ 8000 2000 20000
-MAXSLICE 100 25 100
-ULIMIT 4194303 2048 4194303
-* Streams Parameters
-NSTREAM 64 1 32768
-NSTRPUSH 9 9 9
-NMUXLINK 192 1 4096
-STRMSGSZ 16384 4096 524288
-STRCTLSZ 1024 1024 1024
-STRMAXBLK 524288 4096 524288
-NSTRPAGES 500 0 8000
-STRSPLITFRAC 80 50 100
-NLOG 3 3 3
-NUMSP 64 1 256
-NUMTIM 16 1 8192
-NUMTRW 16 1 8192
-* Semaphore Parameters
-SEMMAP 10 10 8192
-SEMMNI 10 10 8192
-SEMMNS 60 60 8192
-SEMMNU 30 10 8192
-SEMMSL 25 25 150
-SEMOPM 10 10 1024
-SEMUME 10 10 25
-SEMVMX 32767 32767 32767
-SEMAEM 16384 16384 16384
-* Shared Memory Parameters
-SHMMAX 524288 131072 2147483647
-SHMMIN 1 1 1
-SHMMNI 100 100 2000
-FILE 0 100 64000
-NMOUNT 0 4 256
-NPROC 0 50 16000
-NREGION 0 500 160000
-
- Set these values as follows:
-
- * NOFILES should be 4096 or 2048.
-
- * MAXUP should be 2048.
-
- To make changes to the kernel, use the idtune name parameter
- command. idtune modifies the /etc/conf/cf.d/stune file for you.
- For example, to change SEMMS to 200, execute this command as root:
-# /etc/conf/bin/idtune SEMMNS 200
-
- Then rebuild and reboot the kernel by issuing this command:
-# /etc/conf/bin/idbuild -B && init 6
-
- To tune the system, the proper parameter values to use depend on
- the number of users accessing the application or database and size
- the of the database (that is, the used buffer pool). The following
- kernel parameters can be set with idtune:
-
- * SHMMAX (recommended setting: 128MB) and SHMSEG (recommended
- setting: 15). These parameters have an influence on the MySQL
- database engine to create user buffer pools.
-
- * NOFILES and MAXUP should be set to at least 2048.
-
- * MAXPROC should be set to at least 3000/4000 (depends on number
- of users) or more.
-
- * The following formulas are recommended to calculate values for
- SEMMSL, SEMMNS, and SEMMNU:
-SEMMSL = 13
- 13 is what has been found to be the best for both Progress and
- MySQL.
-SEMMNS = SEMMSL x number of db servers to be run on the system
- Set SEMMNS to the value of SEMMSL multiplied by the number of
- database servers (maximum) that you are running on the system
- at one time.
-SEMMNU = SEMMNS
- Set the value of SEMMNU to equal the value of SEMMNS. You
- could probably set this to 75% of SEMMNS, but this is a
- conservative estimate.
-
- You need to at least install the SCO OpenServer Linker and
- Application Development Libraries or the OpenServer Development
- System to use gcc. You cannot use the GCC Dev system without
- installing one of these.
-
- You should get the FSU Pthreads package and install it first. This
- can be found at
- http://moss.csc.ncsu.edu/~mueller/ftp/pub/PART/pthreads.tar.gz.
- You can also get a precompiled package from
- ftp://ftp.zenez.com/pub/zenez/prgms/FSU-threads-3.14.tar.gz.
-
- FSU Pthreads can be compiled with SCO Unix 4.2 with tcpip, or
- using OpenServer 3.0 or Open Desktop 3.0 (OS 3.0 ODT 3.0) with the
- SCO Development System installed using a good port of GCC 2.5.x.
- For ODT or OS 3.0, you need a good port of GCC 2.5.x. There are a
- lot of problems without a good port. The port for this product
- requires the SCO Unix Development system. Without it, you are
- missing the libraries and the linker that is needed. You also need
- SCO-3.2v4.2-includes.tar.gz. This file contains the changes to the
- SCO Development include files that are needed to get MySQL to
- build. You need to replace the existing system include files with
- these modified header files. They can be obtained from
- ftp://ftp.zenez.com/pub/zenez/prgms/SCO-3.2v4.2-includes.tar.gz.
-
- To build FSU Pthreads on your system, all you should need to do is
- run GNU make. The Makefile in FSU-threads-3.14.tar.gz is set up to
- make FSU-threads.
-
- You can run ./configure in the threads/src directory and select
- the SCO OpenServer option. This command copies Makefile.SCO5 to
- Makefile. Then run make.
-
- To install in the default /usr/include directory, log in as root,
- and then cd to the thread/src directory and run make install.
-
- Remember that you must use GNU make to build MySQL.
+ When you are ready to create additional user accounts, you can
+ find information on the MySQL access control system and account
+ management in Section 5.4, "The MySQL Access Privilege System,"
+ and Section 5.5, "MySQL User Account Management."
-Note
+2.13.1. Unix Post-Installation Procedures
- If you don't start mysqld_safe as root, you should get only the
- default 110 open files per process. mysqld writes a note about
- this in the log file.
+ After installing MySQL on Unix, you need to initialize the grant
+ tables, start the server, and make sure that the server works
+ satisfactorily. You may also wish to arrange for the server to be
+ started and stopped automatically when your system starts and
+ stops. You should also assign passwords to the accounts in the
+ grant tables.
- With SCO 3.2V4.2, you should use FSU Pthreads version 3.14 or
- newer. The following configure command should work:
-CFLAGS="-D_XOPEN_XPG4" CXX=gcc CXXFLAGS="-D_XOPEN_XPG4" \
-./configure \
- --prefix=/usr/local/mysql \
- --with-named-thread-libs="-lgthreads -lsocket -lgen -lgthreads" \
- --with-named-curses-libs="-lcurses"
+ On Unix, the grant tables are set up by the mysql_install_db
+ program. For some installation methods, this program is run for
+ you automatically:
- You may have problems with some include files. In this case, you
- can find new SCO-specific include files at
- ftp://ftp.zenez.com/pub/zenez/prgms/SCO-3.2v4.2-includes.tar.gz.
+ * If you install MySQL on Linux using RPM distributions, the
+ server RPM runs mysql_install_db.
- You should unpack this file in the include directory of your MySQL
- source tree.
+ * If you install MySQL on Mac OS X using a PKG distribution, the
+ installer runs mysql_install_db.
- SCO development notes:
+ Otherwise, you'll need to run mysql_install_db yourself.
- * MySQL should automatically detect FSU Pthreads and link mysqld
- with -lgthreads -lsocket -lgthreads.
+ The following procedure describes how to initialize the grant
+ tables (if that has not previously been done) and then start the
+ server. It also suggests some commands that you can use to test
+ whether the server is accessible and working properly. For
+ information about starting and stopping the server automatically,
+ see Section 2.13.1.2, "Starting and Stopping MySQL Automatically."
- * The SCO development libraries are re-entrant in FSU Pthreads.
- SCO claims that its library functions are re-entrant, so they
- must be re-entrant with FSU Pthreads. FSU Pthreads on
- OpenServer tries to use the SCO scheme to make re-entrant
- libraries.
+ After you complete the procedure and have the server running, you
+ should assign passwords to the accounts created by
+ mysql_install_db. Instructions for doing so are given in Section
+ 2.13.2, "Securing the Initial MySQL Accounts."
- * FSU Pthreads (at least the version at ftp://ftp.zenez.com)
- comes linked with GNU malloc. If you encounter problems with
- memory usage, make sure that gmalloc.o is included in
- libgthreads.a and libgthreads.so.
+ In the examples shown here, the server runs under the user ID of
+ the mysql login account. This assumes that such an account exists.
+ Either create the account if it does not exist, or substitute the
+ name of a different existing login account that you plan to use
+ for running the server.
- * In FSU Pthreads, the following system calls are
- pthreads-aware: read(), write(), getmsg(), connect(),
- accept(), select(), and wait().
+ 1. Change location into the top-level directory of your MySQL
+ installation, represented here by BASEDIR:
+shell> cd BASEDIR
+ BASEDIR is likely to be something like /usr/local/mysql or
+ /usr/local. The following steps assume that you are located in
+ this directory.
- * The CSSA-2001-SCO.35.2 (the patch is listed in custom as
- erg711905-dscr_remap security patch (version 2.0.0)) breaks
- FSU threads and makes mysqld unstable. You have to remove this
- one if you want to run mysqld on an OpenServer 5.0.6 machine.
+ 2. If necessary, run the mysql_install_db program to set up the
+ initial MySQL grant tables containing the privileges that
+ determine how users are allowed to connect to the server.
+ You'll need to do this if you used a distribution type for
+ which the installation procedure doesn't run the program for
+ you.
+ Typically, mysql_install_db needs to be run only the first
+ time you install MySQL, so you can skip this step if you are
+ upgrading an existing installation, However, mysql_install_db
+ does not overwrite any existing privilege tables, so it should
+ be safe to run in any circumstances.
+ To initialize the grant tables, use one of the following
+ commands, depending on whether mysql_install_db is located in
+ the bin or scripts directory:
+shell> bin/mysql_install_db --user=mysql
+shell> scripts/mysql_install_db --user=mysql
+ It might be necessary to specify other options such as
+ --basedir or --datadir if mysql_install_db does not use the
+ correct locations for the installation directory or data
+ directory. For example:
+shell> bin/mysql_install_db --user=mysql \
+ --basedir=/opt/mysql/mysql \
+ --datadir=/opt/mysql/mysql/data
+ The mysql_install_db script creates the server's data
+ directory. Under the data directory, it creates directories
+ for the mysql database that holds all database privileges and
+ the test database that you can use to test MySQL. The script
+ also creates privilege table entries for root and
+ anonymous-user accounts. The accounts have no passwords
+ initially. A description of their initial privileges is given
+ in Section 2.13.2, "Securing the Initial MySQL Accounts."
+ Briefly, these privileges allow the MySQL root user to do
+ anything, and allow anybody to create or use databases with a
+ name of test or starting with test_.
+ It is important to make sure that the database directories and
+ files are owned by the mysql login account so that the server
+ has read and write access to them when you run it later. To
+ ensure this, the --user option should be used as shown if you
+ run mysql_install_db as root. Otherwise, you should execute
+ the script while logged in as mysql, in which case you can
+ omit the --user option from the command.
+ mysql_install_db creates several tables in the mysql database,
+ including user, db, host, tables_priv, columns_priv, func, and
+ others. See Section 5.4, "The MySQL Access Privilege System,"
+ for a complete listing and description of these tables.
+ If you don't want to have the test database, you can remove it
+ with mysqladmin -u root drop test after starting the server.
+ If you have trouble with mysql_install_db at this point, see
+ Section 2.13.1.1, "Problems Running mysql_install_db."
- * If you use SCO OpenServer 5, you may need to recompile FSU
- pthreads with -DDRAFT7 in CFLAGS. Otherwise, InnoDB may hang
- at a mysqld startup.
+ 3. Start the MySQL server:
+shell> bin/mysqld_safe --user=mysql &
+ It is important that the MySQL server be run using an
+ unprivileged (non-root) login account. To ensure this, the
+ --user option should be used as shown if you run mysqld_safe
+ as system root. Otherwise, you should execute the script while
+ logged in to the system as mysql, in which case you can omit
+ the --user option from the command.
+ Further instructions for running MySQL as an unprivileged user
+ are given in Section 5.3.5, "How to Run MySQL as a Normal
+ User."
+ If you neglected to create the grant tables before proceeding
+ to this step, the following message appears in the error log
+ file when you start the server:
+mysqld: Can't find file: 'host.frm'
+ If you have other problems starting the server, see Section
+ 2.13.1.3, "Starting and Troubleshooting the MySQL Server."
- * SCO provides operating system patches at
- ftp://ftp.sco.com/pub/openserver5 for OpenServer 5.0.x.
+ 4. Use mysqladmin to verify that the server is running. The
+ following commands provide simple tests to check whether the
+ server is up and responding to connections:
+shell> bin/mysqladmin version
+shell> bin/mysqladmin variables
+ The output from mysqladmin version varies slightly depending
+ on your platform and version of MySQL, but should be similar
+ to that shown here:
+shell> bin/mysqladmin version
+mysqladmin Ver 14.12 Distrib 5.1.41, for pc-linux-gnu on i686
+...
- * SCO provides security fixes and libsocket.so.2 at
- ftp://ftp.sco.com/pub/security/OpenServer and
- ftp://ftp.sco.com/pub/security/sse for OpenServer 5.0.x.
+Server version 5.1.41
+Protocol version 10
+Connection Localhost via UNIX socket
+UNIX socket /var/lib/mysql/mysql.sock
+Uptime: 14 days 5 hours 5 min 21 sec
- * Pre-OSR506 security fixes. Also, the telnetd fix at
- ftp://stage.caldera.com/pub/security/openserver/ or
- ftp://stage.caldera.com/pub/security/openserver/CSSA-2001-SCO.
- 10/ as both libsocket.so.2 and libresolv.so.1 with
- instructions for installing on pre-OSR506 systems.
- It is probably a good idea to install these patches before
- trying to compile/use MySQL.
+Threads: 1 Questions: 366 Slow queries: 0
+Opens: 0 Flush tables: 1 Open tables: 19
+Queries per second avg: 0.000
+ To see what else you can do with mysqladmin, invoke it with
+ the --help option.
- Beginning with Legend/OpenServer 6.0.0, there are native threads
- and no 2GB file size limit.
+ 5. Verify that you can shut down the server:
+shell> bin/mysqladmin -u root shutdown
-2.13.5.9. SCO OpenServer 6.0.x Notes
+ 6. Verify that you can start the server again. Do this by using
+ mysqld_safe or by invoking mysqld directly. For example:
+shell> bin/mysqld_safe --user=mysql --log &
+ If mysqld_safe fails, see Section 2.13.1.3, "Starting and
+ Troubleshooting the MySQL Server."
- OpenServer 6 includes these key improvements:
+ 7. Run some simple tests to verify that you can retrieve
+ information from the server. The output should be similar to
+ what is shown here:
+shell> bin/mysqlshow
++-----------+
+| Databases |
++-----------+
+| mysql |
+| test |
++-----------+
- * Larger file support up to 1 TB
+shell> bin/mysqlshow mysql
+Database: mysql
++---------------------------+
+| Tables |
++---------------------------+
+| columns_priv |
+| db |
+| func |
+| help_category |
+| help_keyword |
+| help_relation |
+| help_topic |
+| host |
+| proc |
+| procs_priv |
+| tables_priv |
+| time_zone |
+| time_zone_leap_second |
+| time_zone_name |
+| time_zone_transition |
+| time_zone_transition_type |
+| user |
++---------------------------+
- * Multiprocessor support increased from 4 to 32 processors
+shell> bin/mysql -e "SELECT Host,Db,User FROM db" mysql
++------+--------+------+
+| host | db | user |
++------+--------+------+
+| % | test | |
+| % | test_% | |
++------+--------+------+
- * Increased memory support up to 64GB
+ 8. There is a benchmark suite in the sql-bench directory (under
+ the MySQL installation directory) that you can use to compare
+ how MySQL performs on different platforms. The benchmark suite
+ is written in Perl. It requires the Perl DBI module that
+ provides a database-independent interface to the various
+ databases, and some other additional Perl modules:
+DBI
+DBD::mysql
+Data::Dumper
+Data::ShowTable
+ These modules can be obtained from CPAN
+ (http://www.cpan.org/). See also Section 2.15.1, "Installing
+ Perl on Unix."
+ The sql-bench/Results directory contains the results from many
+ runs against different databases and platforms. To run all
+ tests, execute these commands:
+shell> cd sql-bench
+shell> perl run-all-tests
+ If you don't have the sql-bench directory, you probably
+ installed MySQL using RPM files other than the source RPM.
+ (The source RPM includes the sql-bench benchmark directory.)
+ In this case, you must first install the benchmark suite
+ before you can use it. There are separate benchmark RPM files
+ named mysql-bench-VERSION.i386.rpm that contain benchmark code
+ and data.
+ If you have a source distribution, there are also tests in its
+ tests subdirectory that you can run. For example, to run
+ auto_increment.tst, execute this command from the top-level
+ directory of your source distribution:
+shell> mysql -vvf test < ./tests/auto_increment.tst
+ The expected result of the test can be found in the
+ ./tests/auto_increment.res file.
- * Extending the power of UnixWare into OpenServer 6
+ 9. At this point, you should have the server running. However,
+ none of the initial MySQL accounts have a password, so you
+ should assign passwords using the instructions found in
+ Section 2.13.2, "Securing the Initial MySQL Accounts."
- * Dramatic performance improvement
+ The MySQL 5.1 installation procedure creates time zone tables in
+ the mysql database. However, you must populate the tables manually
+ using the instructions in Section 9.7, "MySQL Server Time Zone
+ Support."
- OpenServer 6.0.0 commands are organized as follows:
+2.13.1.1. Problems Running mysql_install_db
- * /bin is for commands that behave exactly the same as on
- OpenServer 5.0.x.
+ The purpose of the mysql_install_db script is to generate new
+ MySQL privilege tables. It does not overwrite existing MySQL
+ privilege tables, and it does not affect any other data.
- * /u95/bin is for commands that have better standards
- conformance, for example Large File System (LFS) support.
+ If you want to re-create your privilege tables, first stop the
+ mysqld server if it is running. Then rename the mysql directory
+ under the data directory to save it, and then run
+ mysql_install_db. Suppose that your current directory is the MySQL
+ installation directory and that mysql_install_db is located in the
+ bin directory and the data directory is named data. To rename the
+ mysql database and re-run mysql_install_db, use these commands.
+shell> mv data/mysql data/mysql.old
+shell> bin/mysql_install_db --user=mysql
- * /udk/bin is for commands that behave the same as on UnixWare
- 7.1.4. The default is for the LFS support.
+ When you run mysql_install_db, you might encounter the following
+ problems:
- The following is a guide to setting PATH on OpenServer 6. If the
- user wants the traditional OpenServer 5.0.x then PATH should be
- /bin first. If the user wants LFS support, the path should be
- /u95/bin:/bin. If the user wants UnixWare 7 support first, the
- path would be /udk/bin:/u95/bin:/bin:.
+ * mysql_install_db fails to install the grant tables
+ You may find that mysql_install_db fails to install the grant
+ tables and terminates after displaying the following messages:
+Starting mysqld daemon with databases from XXXXXX
+mysqld ended
+ In this case, you should examine the error log file very
+ carefully. The log should be located in the directory XXXXXX
+ named by the error message and should indicate why mysqld
+ didn't start. If you do not understand what happened, include
+ the log when you post a bug report. See Section 1.6, "How to
+ Report Bugs or Problems."
- Use the latest production release of MySQL. Should you choose to
- use an older release of MySQL on OpenServer 6.0.x, you must use a
- version of MySQL at least as recent as 3.22.13 to get fixes for
- some portability and OS problems.
+ * There is a mysqld process running
+ This indicates that the server is running, in which case the
+ grant tables have probably been created already. If so, there
+ is no need to run mysql_install_db at all because it needs to
+ be run only once (when you install MySQL the first time).
- MySQL distribution files with names of the following form are tar
- archives of media are tar archives of media images suitable for
- installation with the SCO Software Manager (/etc/custom) on SCO
- OpenServer 6:
-mysql-PRODUCT-5.1.39-sco-osr6-i686.VOLS.tar
+ * Installing a second mysqld server does not work when one
+ server is running
+ This can happen when you have an existing MySQL installation,
+ but want to put a new installation in a different location.
+ For example, you might have a production installation, but you
+ want to create a second installation for testing purposes.
+ Generally the problem that occurs when you try to run a second
+ server is that it tries to use a network interface that is in
+ use by the first server. In this case, you should see one of
+ the following error messages:
+Can't start server: Bind on TCP/IP port:
+Address already in use
+Can't start server: Bind on unix socket...
+ For instructions on setting up multiple servers, see Section
+ 5.6, "Running Multiple MySQL Servers on the Same Machine."
+
+ * You do not have write access to the /tmp directory
+ If you do not have write access to create temporary files or a
+ Unix socket file in the default location (the /tmp directory),
+ an error occurs when you run mysql_install_db or the mysqld
+ server.
+ You can specify different locations for the temporary
+ directory and Unix socket file by executing these commands
+ prior to starting mysql_install_db or mysqld, where
+ some_tmp_dir is the full path name to some directory for which
+ you have write permission:
+shell> TMPDIR=/some_tmp_dir/
+shell> MYSQL_UNIX_PORT=/some_tmp_dir/mysql.sock
+shell> export TMPDIR MYSQL_UNIX_PORT
+ Then you should be able to run mysql_install_db and start the
+ server with these commands:
+shell> bin/mysql_install_db --user=mysql
+shell> bin/mysqld_safe --user=mysql &
+ If mysql_install_db is located in the scripts directory,
+ modify the first command to scripts/mysql_install_db.
+ See Section B.5.4.5, "How to Protect or Change the MySQL Unix
+ Socket File," and Section 2.14, "Environment Variables."
- A distribution where PRODUCT is pro-cert is the Commercially
- licensed MySQL Pro Certified server. A distribution where PRODUCT
- is pro-gpl-cert is the MySQL Pro Certified server licensed under
- the terms of the General Public License (GPL).
+ There are some alternatives to running the mysql_install_db script
+ provided in the MySQL distribution:
- Select whichever distribution you wish to install and, after
- download, extract the tar archive into an empty directory. For
- example:
-shell> mkdir /tmp/mysql-pro
-shell> cd /tmp/mysql-pro
-shell> tar xf /tmp/mysql-pro-cert-5.1.39-sco-osr6-i686.VOLS.tar
+ * If you want the initial privileges to be different from the
+ standard defaults, you can modify mysql_install_db before you
+ run it. However, it is preferable to use GRANT and REVOKE to
+ change the privileges after the grant tables have been set up.
+ In other words, you can run mysql_install_db, and then use
+ mysql -u root mysql to connect to the server as the MySQL root
+ user so that you can issue the necessary GRANT and REVOKE
+ statements.
+ If you want to install MySQL on several machines with the same
+ privileges, you can put the GRANT and REVOKE statements in a
+ file and execute the file as a script using mysql after
+ running mysql_install_db. For example:
+shell> bin/mysql_install_db --user=mysql
+shell> bin/mysql -u root < your_script_file
+ By doing this, you can avoid having to issue the statements
+ manually on each machine.
- Prior to installation, back up your data in accordance with the
- procedures outlined in Section 2.12.1, "Upgrading MySQL."
+ * It is possible to re-create the grant tables completely after
+ they have previously been created. You might want to do this
+ if you're just learning how to use GRANT and REVOKE and have
+ made so many modifications after running mysql_install_db that
+ you want to wipe out the tables and start over.
+ To re-create the grant tables, remove all the .frm, .MYI, and
+ .MYD files in the mysql database directory. Then run the
+ mysql_install_db script again.
- Remove any previously installed pkgadd version of MySQL:
-shell> pkginfo mysql 2>&1 > /dev/null && pkgrm mysql
+ * You can start mysqld manually using the --skip-grant-tables
+ option and add the privilege information yourself using mysql:
+shell> bin/mysqld_safe --user=mysql --skip-grant-tables &
+shell> bin/mysql mysql
+ From mysql, manually execute the SQL commands contained in
+ mysql_install_db. Make sure that you run mysqladmin
+ flush-privileges or mysqladmin reload afterward to tell the
+ server to reload the grant tables.
+ Note that by not using mysql_install_db, you not only have to
+ populate the grant tables manually, you also have to create
+ them first.
- Install MySQL Pro from media images using the SCO Software
- Manager:
-shell> /etc/custom -p SCO:MySQL -i -z /tmp/mysql-pro
+2.13.1.2. Starting and Stopping MySQL Automatically
- Alternatively, the SCO Software Manager can be displayed
- graphically by clicking on the Software Manager icon on the
- desktop, selecting Software -> Install New, selecting the host,
- selecting Media Images for the Media Device, and entering
- /tmp/mysql-pro as the Image Directory.
+ Generally, you start the mysqld server in one of these ways:
- After installation, run mkdev mysql as the root user to configure
- your newly installed MySQL Pro Certified server.
+ * Invoke mysqld directly. This works on any platform.
-Note
+ * Run the MySQL server as a Windows service. The service can be
+ set to start the server automatically when Windows starts, or
+ as a manual service that you start on request. For
+ instructions, see Section 2.5.5.6, "Starting MySQL as a
+ Windows Service."
- The installation procedure for VOLS packages does not create the
- mysql user and group that the package uses by default. You should
- either create the mysql user and group, or else select a different
- user and group using an option in mkdev mysql.
+ * Invoke mysqld_safe, which tries to determine the proper
+ options for mysqld and then runs it with those options. This
+ script is used on Unix and Unix-like systems. See Section
+ 4.3.2, "mysqld_safe --- MySQL Server Startup Script."
- If you wish to configure your MySQL Pro server to interface with
- the Apache Web server via PHP, download and install the PHP update
- from SCO at
- ftp://ftp.sco.com/pub/updates/OpenServer/SCOSA-2006.17/.
+ * Invoke mysql.server. This script is used primarily at system
+ startup and shutdown on systems that use System V-style run
+ directories, where it usually is installed under the name
+ mysql. The mysql.server script starts the server by invoking
+ mysqld_safe. See Section 4.3.3, "mysql.server --- MySQL Server
+ Startup Script."
- We have been able to compile MySQL with the following configure
- command on OpenServer 6.0.x:
-CC=cc CFLAGS="-D_FILE_OFFSET_BITS=64 -O3" \
-CXX=CC CXXFLAGS="-D_FILE_OFFSET_BITS=64 -O3" \
-./configure --prefix=/usr/local/mysql \
- --enable-thread-safe-client \
- --with-extra-charsets=complex \
- --build=i686-unknown-sysv5SCO_SV6.0.0
+ * On Mac OS X, install a separate MySQL Startup Item package to
+ enable the automatic startup of MySQL on system startup. The
+ Startup Item starts the server by invoking mysql.server. See
+ Section 2.7, "Installing MySQL on Mac OS X," for details.
- If you use gcc, you must use gcc 2.95.3 or newer.
-CC=gcc CXX=g++ ... ./configure ...
+ The mysqld_safe and mysql.server scripts and the Mac OS X Startup
+ Item can be used to start the server manually, or automatically at
+ system startup time. mysql.server and the Startup Item also can be
+ used to stop the server.
- SCO provides OpenServer 6 operating system patches at
- ftp://ftp.sco.com/pub/openserver6.
+ To start or stop the server manually using the mysql.server
+ script, invoke it with start or stop arguments:
+shell> mysql.server start
+shell> mysql.server stop
- SCO provides information about security fixes at
- ftp://ftp.sco.com/pub/security/OpenServer.
+ Before mysql.server starts the server, it changes location to the
+ MySQL installation directory, and then invokes mysqld_safe. If you
+ want the server to run as some specific user, add an appropriate
+ user option to the [mysqld] group of the /etc/my.cnf option file,
+ as shown later in this section. (It is possible that you will need
+ to edit mysql.server if you've installed a binary distribution of
+ MySQL in a nonstandard location. Modify it to change location into
+ the proper directory before it runs mysqld_safe. If you do this,
+ your modified version of mysql.server may be overwritten if you
+ upgrade MySQL in the future, so you should make a copy of your
+ edited version that you can reinstall.)
+
+ mysql.server stop stops the server by sending a signal to it. You
+ can also stop the server manually by executing mysqladmin
+ shutdown.
+
+ To start and stop MySQL automatically on your server, you need to
+ add start and stop commands to the appropriate places in your
+ /etc/rc* files.
- By default, the maximum file size on a OpenServer 6.0.0 system is
- 1TB. Some operating system utilities have a limitation of 2GB. The
- maximum possible file size on UnixWare 7 is 1TB with VXFS or HTFS.
+ If you use the Linux server RPM package
+ (MySQL-server-VERSION.rpm), the mysql.server script is installed
+ in the /etc/init.d directory with the name mysql. You need not
+ install it manually. See Section 2.6.1, "Installing MySQL from RPM
+ Packages on Linux," for more information on the Linux RPM
+ packages.
- OpenServer 6 can be configured for large file support (file sizes
- greater than 2GB) by tuning the UNIX kernel.
+ Some vendors provide RPM packages that install a startup script
+ under a different name such as mysqld.
- By default, the entries in /etc/conf/cf.d/mtune are set as
- follows:
-Value Default Min Max
------ ------- --- ---
-SVMMLIM 0x9000000 0x1000000 0x7FFFFFFF
-HVMMLIM 0x9000000 0x1000000 0x7FFFFFFF
-
- To make changes to the kernel, use the idtune name parameter
- command. idtune modifies the /etc/conf/cf.d/stune file for you. To
- set the kernel values, execute the following commands as root:
-# /etc/conf/bin/idtune SDATLIM 0x7FFFFFFF
-# /etc/conf/bin/idtune HDATLIM 0x7FFFFFFF
-# /etc/conf/bin/idtune SVMMLIM 0x7FFFFFFF
-# /etc/conf/bin/idtune HVMMLIM 0x7FFFFFFF
-# /etc/conf/bin/idtune SFNOLIM 2048
-# /etc/conf/bin/idtune HFNOLIM 2048
-
- Then rebuild and reboot the kernel by issuing this command:
-# /etc/conf/bin/idbuild -B && init 6
-
- To tune the system, the proper parameter values to use depend on
- the number of users accessing the application or database and size
- the of the database (that is, the used buffer pool). The following
- kernel parameters can be set with idtune:
-
- * SHMMAX (recommended setting: 128MB) and SHMSEG (recommended
- setting: 15). These parameters have an influence on the MySQL
- database engine to create user buffer pools.
-
- * SFNOLIM and HFNOLIM should be at maximum 2048.
-
- * NPROC should be set to at least 3000/4000 (depends on number
- of users).
-
- * The following formulas are recommended to calculate values for
- SEMMSL, SEMMNS, and SEMMNU:
-SEMMSL = 13
- 13 is what has been found to be the best for both Progress and
- MySQL.
-SEMMNS = SEMMSL x number of db servers to be run on the system
- Set SEMMNS to the value of SEMMSL multiplied by the number of
- database servers (maximum) that you are running on the system
- at one time.
-SEMMNU = SEMMNS
- Set the value of SEMMNU to equal the value of SEMMNS. You
- could probably set this to 75% of SEMMNS, but this is a
- conservative estimate.
-
-2.13.5.10. SCO UnixWare 7.1.x and OpenUNIX 8.0.0 Notes
-
- Use the latest production release of MySQL. Should you choose to
- use an older release of MySQL on UnixWare 7.1.x, you must use a
- version of MySQL at least as recent as 3.22.13 to get fixes for
- some portability and OS problems.
-
- We have been able to compile MySQL with the following configure
- command on UnixWare 7.1.x:
-CC="cc" CFLAGS="-I/usr/local/include" \
-CXX="CC" CXXFLAGS="-I/usr/local/include" \
-./configure --prefix=/usr/local/mysql \
- --enable-thread-safe-client \
- --with-innodb --with-openssl --with-extra-charsets=complex
-
- If you want to use gcc, you must use gcc 2.95.3 or newer.
-CC=gcc CXX=g++ ... ./configure ...
-
- SCO provides operating system patches at
- ftp://ftp.sco.com/pub/unixware7 for UnixWare 7.1.1,
- ftp://ftp.sco.com/pub/unixware7/713/ for UnixWare 7.1.3,
- ftp://ftp.sco.com/pub/unixware7/714/ for UnixWare 7.1.4, and
- ftp://ftp.sco.com/pub/openunix8 for OpenUNIX 8.0.0.
-
- SCO provides information about security fixes at
- ftp://ftp.sco.com/pub/security/OpenUNIX for OpenUNIX and
- ftp://ftp.sco.com/pub/security/UnixWare for UnixWare.
-
- The UnixWare 7 file size limit is 1 TB with VXFS. Some OS
- utilities have a limitation of 2GB.
-
- On UnixWare 7.1.4 you do not need to do anything to get large file
- support, but to enable large file support on prior versions of
- UnixWare 7.1.x, run fsadm.
-# fsadm -Fvxfs -o largefiles /
-# fsadm / * Note
-# ulimit unlimited
-# /etc/conf/bin/idtune SFSZLIM 0x7FFFFFFF ** Note
-# /etc/conf/bin/idtune HFSZLIM 0x7FFFFFFF ** Note
-# /etc/conf/bin/idbuild -B
-
-* This should report "largefiles".
-** 0x7FFFFFFF represents infinity for these values.
-
- Reboot the system using shutdown.
-
- By default, the entries in /etc/conf/cf.d/mtune are set as
+ If you install MySQL from a source distribution or using a binary
+ distribution format that does not install mysql.server
+ automatically, you can install it manually. The script can be
+ found in the support-files directory under the MySQL installation
+ directory or in a MySQL source tree.
+
+ To install mysql.server manually, copy it to the /etc/init.d
+ directory with the name mysql, and then make it executable. Do
+ this by changing location into the appropriate directory where
+ mysql.server is located and executing these commands:
+shell> cp mysql.server /etc/init.d/mysql
+shell> chmod +x /etc/init.d/mysql
+
+ Older Red Hat systems use the /etc/rc.d/init.d directory rather
+ than /etc/init.d. Adjust the preceding commands accordingly.
+ Alternatively, first create /etc/init.d as a symbolic link that
+ points to /etc/rc.d/init.d:
+shell> cd /etc
+shell> ln -s rc.d/init.d .
+
+ After installing the script, the commands needed to activate it to
+ run at system startup depend on your operating system. On Linux,
+ you can use chkconfig:
+shell> chkconfig --add mysql
+
+ On some Linux systems, the following command also seems to be
+ necessary to fully enable the mysql script:
+shell> chkconfig --level 345 mysql on
+
+ On FreeBSD, startup scripts generally should go in
+ /usr/local/etc/rc.d/. The rc(8) manual page states that scripts in
+ this directory are executed only if their basename matches the
+ *.sh shell file name pattern. Any other files or directories
+ present within the directory are silently ignored. In other words,
+ on FreeBSD, you should install the mysql.server script as
+ /usr/local/etc/rc.d/mysql.server.sh to enable automatic startup.
+
+ As an alternative to the preceding setup, some operating systems
+ also use /etc/rc.local or /etc/init.d/boot.local to start
+ additional services on startup. To start up MySQL using this
+ method, you could append a command like the one following to the
+ appropriate startup file:
+/bin/sh -c 'cd /usr/local/mysql; ./bin/mysqld_safe --user=mysql &'
+
+ For other systems, consult your operating system documentation to
+ see how to install startup scripts.
+
+ You can add options for mysql.server in a global /etc/my.cnf file.
+ A typical /etc/my.cnf file might look like this:
+[mysqld]
+datadir=/usr/local/mysql/var
+socket=/var/tmp/mysql.sock
+port=3306
+user=mysql
+
+[mysql.server]
+basedir=/usr/local/mysql
+
+ The mysql.server script supports the following options: basedir,
+ datadir, and pid-file. If specified, they must be placed in an
+ option file, not on the command line. mysql.server supports only
+ start and stop as command-line arguments.
+
+ The following table shows which option groups the server and each
+ startup script read from option files.
+ Script Option Groups
+ mysqld [mysqld], [server], [mysqld-major_version]
+ mysqld_safe [mysqld], [server], [mysqld_safe]
+ mysql.server [mysqld], [mysql.server], [server]
+
+ [mysqld-major_version] means that groups with names like
+ [mysqld-5.0] and [mysqld-5.1] are read by servers having versions
+ 5.0.x, 5.1.x, and so forth. This feature can be used to specify
+ options that can be read only by servers within a given release
+ series.
+
+ For backward compatibility, mysql.server also reads the
+ [mysql_server] group and mysqld_safe also reads the [safe_mysqld]
+ group. However, you should update your option files to use the
+ [mysql.server] and [mysqld_safe] groups instead when using MySQL
+ 5.1.
+
+ See Section 4.2.3.3, "Using Option Files."
+
+2.13.1.3. Starting and Troubleshooting the MySQL Server
+
+ This section provides troubleshooting suggestions for problems
+ starting the server on Unix. If you are using Windows, see Section
+ 2.5.6, "Troubleshooting a MySQL Installation Under Windows."
+
+ If you have problems starting the server, here are some things to
+ try:
+
+ * Check the error log to see why the server does not start.
+
+ * Specify any special options needed by the storage engines you
+ are using.
+
+ * Make sure that the server knows where to find the data
+ directory.
+
+ * Make sure that the server can access the data directory. The
+ ownership and permissions of the data directory and its
+ contents must be set such that the server can read and modify
+ them.
+
+ * Verify that the network interfaces the server wants to use are
+ available.
+
+ Some storage engines have options that control their behavior. You
+ can create a my.cnf file and specify startup options for the
+ engines that you plan to use. If you are going to use storage
+ engines that support transactional tables (InnoDB, NDB), be sure
+ that you have them configured the way you want before starting the
+ server:
+
+ * If you are using InnoDB tables, see Section 13.6.2, "InnoDB
+ Configuration."
+
+ * If you are using MySQL Cluster, see Section 17.3, "MySQL
+ Cluster Configuration."
+
+ MySQL Enterprise For expert advice on start-up options appropriate
+ to your circumstances, subscribe to The MySQL Enterprise Monitor.
+ For more information, see
+ http://www.mysql.com/products/enterprise/advisors.html.
+
+ Storage engines will use default option values if you specify
+ none, but it is recommended that you review the available options
+ and specify explicit values for those for which the defaults are
+ not appropriate for your installation.
+
+ When the mysqld server starts, it changes location to the data
+ directory. This is where it expects to find databases and where it
+ expects to write log files. The server also writes the pid
+ (process ID) file in the data directory.
+
+ The data directory location is hardwired in when the server is
+ compiled. This is where the server looks for the data directory by
+ default. If the data directory is located somewhere else on your
+ system, the server will not work properly. You can determine what
+ the default path settings are by invoking mysqld with the
+ --verbose and --help options.
+
+ If the default locations don't match the MySQL installation layout
+ on your system, you can override them by specifying options to
+ mysqld or mysqld_safe on the command line or in an option file.
+
+ To specify the location of the data directory explicitly, use the
+ --datadir option. However, normally you can tell mysqld the
+ location of the base directory under which MySQL is installed and
+ it looks for the data directory there. You can do this with the
+ --basedir option.
+
+ To check the effect of specifying path options, invoke mysqld with
+ those options followed by the --verbose and --help options. For
+ example, if you change location into the directory where mysqld is
+ installed and then run the following command, it shows the effect
+ of starting the server with a base directory of /usr/local:
+shell> ./mysqld --basedir=/usr/local --verbose --help
+
+ You can specify other options such as --datadir as well, but
+ --verbose and --help must be the last options.
+
+ Once you determine the path settings you want, start the server
+ without --verbose and --help.
+
+ If mysqld is currently running, you can find out what path
+ settings it is using by executing this command:
+shell> mysqladmin variables
+
+ Or:
+shell> mysqladmin -h host_name variables
+
+ host_name is the name of the MySQL server host.
+
+ If you get Errcode 13 (which means Permission denied) when
+ starting mysqld, this means that the privileges of the data
+ directory or its contents do not allow the server access. In this
+ case, you change the permissions for the involved files and
+ directories so that the server has the right to use them. You can
+ also start the server as root, but this raises security issues and
+ should be avoided.
+
+ On Unix, change location into the data directory and check the
+ ownership of the data directory and its contents to make sure the
+ server has access. For example, if the data directory is
+ /usr/local/mysql/var, use this command:
+shell> ls -la /usr/local/mysql/var
+
+ If the data directory or its files or subdirectories are not owned
+ by the login account that you use for running the server, change
+ their ownership to that account. If the account is named mysql,
+ use these commands:
+shell> chown -R mysql /usr/local/mysql/var
+shell> chgrp -R mysql /usr/local/mysql/var
+
+ If it possible that even with correct ownership, MySQL may fail to
+ start up if there is other security software running on your
+ system that manages application access to various parts of the
+ file system. In this case, you may need to reconfigure that
+ software to enable mysqld to access the directories it uses during
+ normal operation.
+
+ If the server fails to start up correctly, check the error log.
+ Log files are located in the data directory (typically C:\Program
+ Files\MySQL\MySQL Server 5.1\data on Windows,
+ /usr/local/mysql/data for a Unix binary distribution, and
+ /usr/local/var for a Unix source distribution). Look in the data
+ directory for files with names of the form host_name.err and
+ host_name.log, where host_name is the name of your server host.
+ Then examine the last few lines of these files. On Unix, you can
+ use tail to display them:
+shell> tail host_name.err
+shell> tail host_name.log
+
+ The error log should contain information that indicates why the
+ server couldn't start.
+
+ If either of the following errors occur, it means that some other
+ program (perhaps another mysqld server) is using the TCP/IP port
+ or Unix socket file that mysqld is trying to use:
+Can't start server: Bind on TCP/IP port: Address already in use
+Can't start server: Bind on unix socket...
+
+ Use ps to determine whether you have another mysqld server
+ running. If so, shut down the server before starting mysqld again.
+ (If another server is running, and you really want to run multiple
+ servers, you can find information about how to do so in Section
+ 5.6, "Running Multiple MySQL Servers on the Same Machine.")
+
+ If no other server is running, try to execute the command telnet
+ your_host_name tcp_ip_port_number. (The default MySQL port number
+ is 3306.) Then press Enter a couple of times. If you don't get an
+ error message like telnet: Unable to connect to remote host:
+ Connection refused, some other program is using the TCP/IP port
+ that mysqld is trying to use. You'll need to track down what
+ program this is and disable it, or else tell mysqld to listen to a
+ different port with the --port option. In this case, you'll also
+ need to specify the port number for client programs when
+ connecting to the server via TCP/IP.
+
+ Another reason the port might be inaccessible is that you have a
+ firewall running that blocks connections to it. If so, modify the
+ firewall settings to allow access to the port.
+
+ If the server starts but you can't connect to it, you should make
+ sure that you have an entry in /etc/hosts that looks like this:
+127.0.0.1 localhost
+
+ This problem occurs only on systems that do not have a working
+ thread library and for which MySQL must be configured to use
+ MIT-pthreads.
+
+ If you cannot get mysqld to start, you can try to make a trace
+ file to find the problem by using the --debug option. See MySQL
+ Internals: Porting
+ (http://forge.mysql.com/wiki/MySQL_Internals_Porting).
+
+2.13.2. Securing the Initial MySQL Accounts
+
+ Part of the MySQL installation process is to set up the mysql
+ database that contains the grant tables:
+
+ * Windows distributions contain preinitialized grant tables that
+ are installed automatically.
+
+ * On Unix, the grant tables are populated by the
+ mysql_install_db program. Some installation methods run this
+ program for you. Others require that you execute it manually.
+ For details, see Section 2.13.1, "Unix Post-Installation
+ Procedures."
+
+ The grant tables define the initial MySQL user accounts and their
+ access privileges. These accounts are set up as follows:
+
+ * Accounts with the user name root are created. These are
+ superuser accounts that can do anything. The initial root
+ account passwords are empty, so anyone can connect to the
+ MySQL server as root --- without a password --- and be granted
+ all privileges.
+
+ + On Windows, one root account is created; this account
+ allows connecting from the local host only. The Windows
+ installer will optionally create an account allowing for
+ connections from any host only if the user selects the
+ Enable root access from remote machines option during
+ installation.
+
+ + On Unix, both root accounts are for connections from the
+ local host. Connections must be made from the local host
+ by specifying a host name of localhost for one of the
+ accounts, or the actual host name or IP number for the
+ other.
+
+ * Two anonymous-user accounts are created, each with an empty
+ user name. The anonymous accounts have no password, so anyone
+ can use them to connect to the MySQL server.
+
+ + On Windows, one anonymous account is for connections from
+ the local host. It has no global privileges. (Before
+ MySQL 5.1.16, it has all global privileges, just like the
+ root accounts.) The other is for connections from any
+ host and has all privileges for the test database and for
+ other databases with names that start with test.
+
+ + On Unix, both anonymous accounts are for connections from
+ the local host. Connections must be made from the local
+ host by specifying a host name of localhost for one of
+ the accounts, or the actual host name or IP number for
+ the other. These accounts have all privileges for the
+ test database and for other databases with names that
+ start with test_.
+
+ As noted, none of the initial accounts have passwords. This means
+ that your MySQL installation is unprotected until you do something
+ about it:
+
+ * If you want to prevent clients from connecting as anonymous
+ users without a password, you should either assign a password
+ to each anonymous account or else remove the accounts.
+
+ * You should assign a password to each MySQL root account.
+
+ The following instructions describe how to set up passwords for
+ the initial MySQL accounts, first for the anonymous accounts and
+ then for the root accounts. Replace "newpwd" in the examples with
+ the actual password that you want to use. The instructions also
+ cover how to remove the anonymous accounts, should you prefer not
+ to allow anonymous access at all.
+
+ You might want to defer setting the passwords until later, so that
+ you don't need to specify them while you perform additional setup
+ or testing. However, be sure to set them before using your
+ installation for production purposes.
+
+ Anonymous Account Password Assignment
+
+ To assign passwords to the anonymous accounts, connect to the
+ server as root and then use either SET PASSWORD or UPDATE. In
+ either case, be sure to encrypt the password using the PASSWORD()
+ function.
+
+ To use SET PASSWORD on Windows, do this:
+shell> mysql -u root
+mysql> SET PASSWORD FOR ''@'localhost' = PASSWORD('newpwd');
+mysql> SET PASSWORD FOR ''@'%' = PASSWORD('newpwd');
+
+ To use SET PASSWORD on Unix, do this:
+shell> mysql -u root
+mysql> SET PASSWORD FOR ''@'localhost' = PASSWORD('newpwd');
+mysql> SET PASSWORD FOR ''@'host_name' = PASSWORD('newpwd');
+
+ In the second SET PASSWORD statement, replace host_name with the
+ name of the server host. This is the name that is specified in the
+ Host column of the non-localhost record for root in the user
+ table. If you don't know what host name this is, issue the
+ following statement before using SET PASSWORD:
+mysql> SELECT Host, User FROM mysql.user;
+
+ Look for the record that has root in the User column and something
+ other than localhost in the Host column. Then use that Host value
+ in the second SET PASSWORD statement.
+
+ Anonymous Account Removal
+
+ If you prefer to remove the anonymous accounts instead, do so as
follows:
-Value Default Min Max
------ ------- --- ---
-SVMMLIM 0x9000000 0x1000000 0x7FFFFFFF
-HVMMLIM 0x9000000 0x1000000 0x7FFFFFFF
-
- To make changes to the kernel, use the idtune name parameter
- command. idtune modifies the /etc/conf/cf.d/stune file for you. To
- set the kernel values, execute the following commands as root:
-# /etc/conf/bin/idtune SDATLIM 0x7FFFFFFF
-# /etc/conf/bin/idtune HDATLIM 0x7FFFFFFF
-# /etc/conf/bin/idtune SVMMLIM 0x7FFFFFFF
-# /etc/conf/bin/idtune HVMMLIM 0x7FFFFFFF
-# /etc/conf/bin/idtune SFNOLIM 2048
-# /etc/conf/bin/idtune HFNOLIM 2048
-
- Then rebuild and reboot the kernel by issuing this command:
-# /etc/conf/bin/idbuild -B && init 6
-
- To tune the system, the proper parameter values to use depend on
- the number of users accessing the application or database and size
- the of the database (that is, the used buffer pool). The following
- kernel parameters can be set with idtune:
-
- * SHMMAX (recommended setting: 128MB) and SHMSEG (recommended
- setting: 15). These parameters have an influence on the MySQL
- database engine to create user buffer pools.
-
- * SFNOLIM and HFNOLIM should be at maximum 2048.
-
- * NPROC should be set to at least 3000/4000 (depends on number
- of users).
-
- * The following formulas are recommended to calculate values for
- SEMMSL, SEMMNS, and SEMMNU:
-SEMMSL = 13
- 13 is what has been found to be the best for both Progress and
- MySQL.
-SEMMNS = SEMMSL x number of db servers to be run on the system
- Set SEMMNS to the value of SEMMSL multiplied by the number of
- database servers (maximum) that you are running on the system
- at one time.
-SEMMNU = SEMMNS
- Set the value of SEMMNU to equal the value of SEMMNS. You
- could probably set this to 75% of SEMMNS, but this is a
- conservative estimate.
+shell> mysql -u root
+mysql> DROP USER '';
+
+ The DROP statement applies both to Windows and to Unix. On
+ Windows, if you want to remove only the anonymous account that has
+ the same privileges as root, do this instead:
+shell> mysql -u root
+mysql> DROP USER ''@'localhost';
+
+ That account allows anonymous access but has full privileges, so
+ removing it improves security.
+
+ root Account Password Assignment
+
+ You can assign passwords to the root accounts in several ways. The
+ following discussion demonstrates three methods:
+
+ * Use the SET PASSWORD statement
+
+ * Use the mysqladmin command-line client program
+
+ * Use the UPDATE statement
+
+ To assign passwords using SET PASSWORD, connect to the server as
+ root and issue SET PASSWORD statements. Be sure to encrypt the
+ password using the PASSWORD() function.
+
+ For Windows, do this:
+shell> mysql -u root
+mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpwd');
+mysql> SET PASSWORD FOR 'root'@'%' = PASSWORD('newpwd');
+
+ For Unix, do this:
+shell> mysql -u root
+mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpwd');
+mysql> SET PASSWORD FOR 'root'@'host_name' = PASSWORD('newpwd');
+
+ In the second SET PASSWORD statement, replace host_name with the
+ name of the server host. This is the same host name that you used
+ when you assigned the anonymous account passwords.
+
+ If the user table contains an account with User and Host values of
+ 'root' and '127.0.0.1', use an additional SET PASSWORD statement
+ to set that account's password:
+mysql> SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('newpwd');
+
+ To assign passwords to the root accounts using mysqladmin, execute
+ the following commands:
+shell> mysqladmin -u root password "newpwd"
+shell> mysqladmin -u root -h host_name password "newpwd"
+
+ These commands apply both to Windows and to Unix. In the second
+ command, replace host_name with the name of the server host. The
+ double quotes around the password are not always necessary, but
+ you should use them if the password contains spaces or other
+ characters that are special to your command interpreter.
+
+ The mysqladmin method of setting the root account passwords does
+ not set the password for the 'root'@'127.0.0.1' account. To do so,
+ use SET PASSWORD as shown earlier.
+
+ You can also use UPDATE to modify the user table directly. The
+ following UPDATE statement assigns a password to all root
+ accounts:
+shell> mysql -u root
+mysql> UPDATE mysql.user SET Password = PASSWORD('newpwd')
+ -> WHERE User = 'root';
+mysql> FLUSH PRIVILEGES;
+
+ The UPDATE statement applies both to Windows and to Unix.
+
+ After the passwords have been set, you must supply the appropriate
+ password whenever you connect to the server. For example, if you
+ want to use mysqladmin to shut down the server, you can do so
+ using this command:
+shell> mysqladmin -u root -p shutdown
+Enter password: (enter root password here)
+
+Note
+
+ If you forget your root password after setting it up, Section
+ B.5.4.1, "How to Reset the Root Password," covers the procedure
+ for resetting it.
+
+ To set up additional accounts, you can use the GRANT statement.
+ For instructions, see Section 5.5.2, "Adding User Accounts."
2.14. Environment Variables
@@ -9003,7 +7980,7 @@ SEMMNU = SEMMNS
PATH Used by the shell to find MySQL programs.
TMPDIR The directory where temporary files are created.
TZ This should be set to your local time zone. See Section
- B.1.4.6, "Time Zone Problems."
+ B.5.4.6, "Time Zone Problems."
UMASK The user-file creation mode when creating files. See note
following table.
UMASK_DIR The user-directory creation mode when creating
@@ -9047,9 +8024,9 @@ SEMMNU = SEMMNS
sections describe how to do this.
Perl support for MySQL must be installed if you want to run the
- MySQL benchmark scripts; see Section 7.1.4, "The MySQL Benchmark
+ MySQL benchmark scripts; see Section 7.1.3, "The MySQL Benchmark
Suite." It is also required for the MySQL Cluster ndb_size.pl
- utility; see Section 17.6.21, "ndb_size.pl --- NDBCLUSTER Size
+ utility; see Section 17.4.21, "ndb_size.pl --- NDBCLUSTER Size
Requirement Estimator."
2.15.1. Installing Perl on Unix
diff --git a/INSTALL-WIN-SOURCE b/INSTALL-WIN-SOURCE
index 35137c9ad4b..90862398f81 100644
--- a/INSTALL-WIN-SOURCE
+++ b/INSTALL-WIN-SOURCE
@@ -1,5 +1,5 @@
-2.10.6. Installing MySQL from Source on Windows
+2.5.10. Installing MySQL from Source on Windows
These instructions describe how to build binaries from source for
MySQL 5.1 on Windows. Instructions are provided for building
@@ -15,7 +15,7 @@ Note
to use precompiled binary distributions of MySQL that are built
specifically for optimal performance on Windows by Sun
Microsystems, Inc. Instructions for installing binary
- distributions are available in Section 2.3, "Installing MySQL on
+ distributions are available in Section 2.5, "Installing MySQL on
Windows."
To build MySQL on Windows from source, you must satisfy the
@@ -68,7 +68,7 @@ Note
* 3GB to 5GB of disk space.
- The exact system requirements can be found here:
+ The exact system requirements for Visual Studio can be found here:
http://msdn.microsoft.com/vstudio/Previous/2003/sysreqs/default.as
px and
http://msdn.microsoft.com/vstudio/products/sysreqs/default.aspx
@@ -81,7 +81,7 @@ Note
* Package a source distribution yourself from the latest Bazaar
developer source tree. For instructions on pulling the latest
- source files, see Section 2.10.3, "Installing from the
+ source files, see Section 2.3.3, "Installing from the
Development Source Tree."
If you find something not working as expected, or you have
@@ -89,7 +89,7 @@ Note
Windows, please send a message to the win32 mailing list. See
Section 1.5.1, "MySQL Mailing Lists."
-2.10.6.1. Building MySQL from Source Using CMake and Visual Studio
+2.5.10.1. Building MySQL from Source Using CMake and Visual Studio
You can build MySQL on Windows by using a combination of cmake and
Microsoft Visual Studio .NET 2003 (7.1), Microsoft Visual Studio
@@ -99,7 +99,7 @@ Note
Note
To compile from the source code on Windows you must use the
- standard source distribution (for example, mysql-5.0.45.tar.gz).
+ standard source distribution (for example, mysql-5.1.41.tar.gz).
You build from the same distribution as used to build MySQL on
Unix, Linux and other platforms. Do not use the Windows Source
distributions as they do not contain the necessary configuration
@@ -264,5 +264,5 @@ C:\workdir> copy libmysql\libmysql.def C:\mysql\include
C:\workdir> xcopy sql-bench\*.* C:\mysql\bench /E
After installation, set up and start the server in the same way as
- for binary Windows distributions. See Section 2.3, "Installing
+ for binary Windows distributions. See Section 2.5, "Installing
MySQL on Windows."
diff --git a/Makefile.am b/Makefile.am
index 5d076adcda0..194f4c7b392 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+# Copyright 2000-2008 MySQL AB, 2009 Sun Microsystems, Inc.
#
# 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
@@ -26,7 +26,7 @@ EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \
SUBDIRS = . include @docs_dirs@ @zlib_dir@ \
@readline_topdir@ sql-common scripts \
@pstack_dir@ \
- @sql_union_dirs@ unittest storage plugin \
+ @sql_union_dirs@ storage \
@sql_server@ @man_dirs@ tests \
netware @libmysqld_dirs@ \
mysql-test support-files sql-bench @tools_dirs@ \
@@ -208,6 +208,10 @@ test-bt-fast:
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl $(MTR_EXTRA_OPTIONS) --force --comment=stress --suite=stress
+test-bt-fast2:
+ -cd mysql-test ; MTR_BUILD_THREAD=auto \
+ @PERL@ ./mysql-test-run.pl $(MTR_EXTRA_OPTIONS) --force --comment=ps --ps-protocol --report-features
+
test-bt-debug:
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl $(MTR_EXTRA_OPTIONS) --comment=debug --force --timer \
diff --git a/README b/README
index 7ad036784dd..5b574864f96 100644
--- a/README
+++ b/README
@@ -1,60 +1,57 @@
-This is a release of MariaDB, a branch of MySQL.
+This is a release of MariaDB.
-MariaDB is a drop-in replacement of MySQL, with more features, less
-bugs and better performance.
+MariaDB is designed as a drop-in replacement of MySQL(R) with more
+features, new storage engines, fewer bugs, and better performance.
-MariaDB is brought to you by many of the original developers of MySQL,
-that now work for Monty Program Ab, and by many people in the
+MariaDB is brought to you by many of the original developers of MySQL
+who now work for Monty Program Ab, and by many people in the
community.
-MySQL, which is the base of MariaDB, is brought to you by Sun.
+MySQL, which is the base of MariaDB, is a product and trademark of Sun
+Microsystems, Inc. For a list of developers and other contributors,
+see the Credits appendix. You can also do 'SHOW authors' to get a
+list of active contributors.
-License information can be found in these files:
-- For GPL (free) distributions, see the COPYING file and
- the EXCEPTIONS-CLIENT file.
-
-A description of the MariaDB project can be found at:
+A description of the MariaDB project and a manual can be found at:
http://askmonty.org/wiki/index.php/MariaDB
-
-GPLv2 Disclaimer
-For the avoidance of doubt, except that if any license choice
-other than GPL or LGPL is available it will apply instead, Sun
-elects to use only the General Public License version 2 (GPLv2)
-at this time for any software where a choice of GPL license versions
-is made available with the language indicating that GPLv2 or any
-later version may be used, or where a choice of which version of
-the GPL is applied is otherwise unspecified.
-
-The differences between MariaDB and MySQL can be found at:
http://askmonty.org/wiki/index.php/MariaDB_versus_MySQL
+http://askmonty.org/wiki/index.php/Manual:Contents
-Documentation about MySQL can be found at:
-http://dev.mysql.com/doc
-
-For further information about MySQL documentation, see:
-- The current MySQL documentation:
+As MariaDB is a full replacement of MySQL, the MySQL manual at
+http://dev.mysql.com/doc is generally applicable.
-Some manual sections of special interest:
+More help is available from the Maria Discuss mailing list
+https://launchpad.net/~maria-discuss
+and the #maria IRC channel on Freenode.
+***************************************************************************
+NOTE:
-- For a list of developers and other contributors, see the Credits
- appendix.
+MariaDB is specifically available only under version 2 of the GNU
+General Public License (GPLv2). (I.e. Without the "any later version"
+clause.) This is inherited from MySQL. Please see the README file in
+the MySQL distribution for more information.
-A local copy of the MySQL Reference Manual can be found in the Docs
-directory in GNU Info format. You can also browse the manual online or
-download it in any of several formats from
-http://dev.mysql.com/doc
+License information can be found in the COPYING file and the
+EXCEPTIONS-CLIENT file.
-************************************************************
+***************************************************************************
IMPORTANT:
-Bug or error reports regarding MariaDB should be sent to
+Bug and/or error reports regarding MariaDB should be submitted at
https://bugs.launchpad.net/maria
-Bugs in the MySQL code can also be sent to http://bugs.mysql.com
+
+Bugs in the MySQL code can also be submitted at http://bugs.mysql.com
+
***************************************************************************
+
+
+
+
+***************************************************************************
%%The following software may be included in this product:
Fred Fish's Dbug Library
diff --git a/client/mysql.cc b/client/mysql.cc
index fa03202f2d3..a9cf6ff8fee 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -83,7 +83,7 @@ extern "C" {
#include <term.h>
#endif
#endif
-#endif
+#endif /* defined(HAVE_CURSES_H) && defined(HAVE_TERM_H) */
#undef bcmp // Fix problem with new readline
#if defined(__WIN__)
@@ -92,7 +92,6 @@ extern "C" {
#include <readline/readline.h>
#define HAVE_READLINE
#endif
- //int vidattr(long unsigned int attrs); // Was missing in sun curses
}
#if !defined(HAVE_VIDATTR)
@@ -1024,7 +1023,7 @@ static const char *load_default_groups[]= { "mysql","client",0 };
static int embedded_server_arg_count= 0;
static char *embedded_server_args[MAX_SERVER_ARGS];
static const char *embedded_server_groups[]=
-{ "server", "embedded", "mysql_SERVER", 0 };
+{ "server", "embedded", "mysql_SERVER", "mariadb_SERVER", 0 };
#ifdef HAVE_READLINE
/*
@@ -1281,21 +1280,35 @@ sig_handler handle_sigint(int sig)
MYSQL *kill_mysql= NULL;
/* terminate if no query being executed, or we already tried interrupting */
- if (!executing_query || interrupted_query)
+ /* terminate if no query being executed, or we already tried interrupting */
+ if (!executing_query || (interrupted_query == 2))
+ {
+ tee_fprintf(stdout, "Ctrl-C -- exit!\n");
goto err;
+ }
kill_mysql= mysql_init(kill_mysql);
if (!mysql_real_connect(kill_mysql,current_host, current_user, opt_password,
"", opt_mysql_port, opt_mysql_unix_port,0))
+ {
+ tee_fprintf(stdout, "Ctrl-C -- sorry, cannot connect to server to kill query, giving up ...\n");
goto err;
+ }
+
+ interrupted_query++;
+
+ /* mysqld < 5 does not understand KILL QUERY, skip to KILL CONNECTION */
+ if ((interrupted_query == 1) && (mysql_get_server_version(&mysql) < 50000))
+ interrupted_query= 2;
/* kill_buffer is always big enough because max length of %lu is 15 */
- sprintf(kill_buffer, "KILL /*!50000 QUERY */ %lu", mysql_thread_id(&mysql));
- mysql_real_query(kill_mysql, kill_buffer, strlen(kill_buffer));
+ sprintf(kill_buffer, "KILL %s%lu",
+ (interrupted_query == 1) ? "QUERY " : "",
+ mysql_thread_id(&mysql));
+ tee_fprintf(stdout, "Ctrl-C -- sending \"%s\" to server ...\n", kill_buffer);
+ mysql_real_query(kill_mysql, kill_buffer, (uint) strlen(kill_buffer));
mysql_close(kill_mysql);
- tee_fprintf(stdout, "Query aborted by Ctrl+C\n");
-
- interrupted_query= 1;
+ tee_fprintf(stdout, "Ctrl-C -- query aborted.\n");
return;
@@ -2873,7 +2886,7 @@ com_help(String *buffer __attribute__((unused)),
"For developer information, including the MySQL Reference Manual, "
"visit:\n"
" http://dev.mysql.com/\n"
- "To buy MySQL Network Support, training, or other products, visit:\n"
+ "To buy MySQL Enterprise support, training, or other products, visit:\n"
" https://shop.mysql.com/\n", INFO_INFO);
put_info("List of all MySQL commands:", INFO_INFO);
if (!named_cmds)
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index 61ff5f49dbf..e8f336bcd99 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -54,6 +54,8 @@ static char **defaults_argv;
static my_bool not_used; /* Can't use GET_BOOL without a value pointer */
+static my_bool opt_write_binlog;
+
#include <help_start.h>
static struct my_option my_long_options[]=
@@ -124,6 +126,11 @@ static struct my_option my_long_options[]=
{"verbose", 'v', "Display more output about the process",
(uchar**) &opt_verbose, (uchar**) &opt_verbose, 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.",
+ (uchar**) &opt_write_binlog, (uchar**) &opt_write_binlog, 0, GET_BOOL, NO_ARG,
+ 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -448,6 +455,8 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res,
int ret;
File fd;
char query_file_path[FN_REFLEN];
+ const uchar sql_log_bin[]= "SET SQL_LOG_BIN=0;";
+
DBUG_ENTER("run_query");
DBUG_PRINT("enter", ("query: %s", query));
if ((fd= create_temp_file(query_file_path, opt_tmpdir,
@@ -455,6 +464,22 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res,
MYF(MY_WME))) < 0)
die("Failed to create temporary file for defaults");
+ /*
+ Master and slave should be upgraded separately. All statements executed
+ by mysql_upgrade will not be binlogged.
+ 'SET SQL_LOG_BIN=0' is executed before any other statements.
+ */
+ if (!opt_write_binlog)
+ {
+ if (my_write(fd, sql_log_bin, sizeof(sql_log_bin)-1,
+ MYF(MY_FNABP | MY_WME)))
+ {
+ my_close(fd, MYF(0));
+ my_delete(query_file_path, MYF(0));
+ die("Failed to write to '%s'", query_file_path);
+ }
+ }
+
if (my_write(fd, (uchar*) query, strlen(query),
MYF(MY_FNABP | MY_WME)))
{
@@ -552,7 +577,6 @@ static int upgrade_already_done(void)
FILE *in;
char upgrade_info_file[FN_REFLEN]= {0};
char buf[sizeof(MYSQL_SERVER_VERSION)+1];
- char *res;
if (get_upgrade_info_file_name(upgrade_info_file))
return 0; /* Could not get filename => not sure */
@@ -647,6 +671,7 @@ static int run_mysqlcheck_upgrade(void)
"--check-upgrade",
"--all-databases",
"--auto-repair",
+ opt_write_binlog ? "--write-binlog" : "--skip-write-binlog",
NULL);
}
@@ -661,6 +686,7 @@ static int run_mysqlcheck_fixnames(void)
"--all-databases",
"--fix-db-names",
"--fix-table-names",
+ opt_write_binlog ? "--write-binlog" : "--skip-write-binlog",
NULL);
}
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 1d519294042..1f3aad6891d 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -87,6 +87,9 @@ static const char* host = 0;
static int port= 0;
static uint my_end_arg;
static const char* sock= 0;
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name= 0;
+#endif
static const char* user = 0;
static char* pass = 0;
static char *charset= 0;
@@ -773,7 +776,10 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
case QUERY_EVENT:
{
Query_log_event *qe= (Query_log_event*)ev;
- if (shall_skip_database(qe->db))
+ if (strncmp(qe->query, "BEGIN", 5) &&
+ strncmp(qe->query, "COMMIT", 6) &&
+ strncmp(qe->query, "ROLLBACK", 8) &&
+ shall_skip_database(qe->db))
goto end;
print_use_stmt(print_event_info, qe->db, qe->db_len);
if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS)
@@ -1048,13 +1054,13 @@ static struct my_option my_long_options[] =
/* 'unspec' is not mentioned because it is just a placeholder. */
"Determine when the output statements should be base64-encoded BINLOG "
"statements: 'never' disables it and works only for binlogs without "
- "row-based events; 'auto' is the default and prints base64 only when "
- "necessary (i.e., for row-based events and format description events); "
- "'decode-rows' suppresses BINLOG statements for row events, but does "
- "not exit as an error if a row event is found, unlike 'never'; "
- "'always' prints base64 whenever possible. 'always' is for debugging "
- "only and should not be used in a production system. The default is "
- "'auto'. --base64-output is a short form for --base64-output=always."
+ "row-based events; 'decode-rows' decodes row events into commented SQL "
+ "statements if the --verbose option is also given; 'auto' prints base64 "
+ "only when necessary (i.e., for row-based events and format description "
+ "events); 'always' prints base64 whenever possible. 'always' is for "
+ "debugging only and should not be used in a production system. If this "
+ "argument is not given, the default is 'auto'; if it is given with no "
+ "argument, 'always' is used."
,(uchar**) &opt_base64_output_mode_str,
(uchar**) &opt_base64_output_mode_str,
0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
@@ -1133,6 +1139,12 @@ static struct my_option my_long_options[] =
{"set-charset", OPT_SET_CHARSET,
"Add 'SET NAMES character_set' to the output.", (uchar**) &charset,
(uchar**) &charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SMEM
+ {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
+ "Base name of shared memory.", (uchar**) &shared_memory_base_name,
+ (uchar**) &shared_memory_base_name,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"short-form", 's', "Just show regular queries: no extra info and no "
"row-based events. This is for testing only, and should not be used in "
"production systems. If you want to suppress base64-output, consider "
@@ -1486,6 +1498,11 @@ static Exit_status safe_connect()
if (opt_protocol)
mysql_options(mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol);
+#ifdef HAVE_SMEM
+ if (shared_memory_base_name)
+ mysql_options(mysql, MYSQL_SHARED_MEMORY_BASE_NAME,
+ shared_memory_base_name);
+#endif
if (!mysql_real_connect(mysql, host, user, pass, 0, port, sock, 0))
{
error("Failed on connect: %s", mysql_error(mysql));
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index 82aabd77b24..1533e602639 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -652,6 +652,17 @@ static int use_db(char *database)
return 0;
} /* use_db */
+static int disable_binlog()
+{
+ const char *stmt= "SET SQL_LOG_BIN=0";
+ if (mysql_query(sock, stmt))
+ {
+ fprintf(stderr, "Failed to %s\n", stmt);
+ fprintf(stderr, "Error: %s\n", mysql_error(sock));
+ return 1;
+ }
+ return 0;
+}
static int handle_request_for_tables(char *tables, uint length)
{
@@ -844,6 +855,14 @@ int main(int argc, char **argv)
if (dbConnect(current_host, current_user, opt_password))
exit(EX_MYSQLERR);
+ if (!opt_write_binlog)
+ {
+ if (disable_binlog()) {
+ first_error= 1;
+ goto end;
+ }
+ }
+
if (opt_auto_repair &&
my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16,64))
{
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index 92e9702aea0..ef38d760e5d 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright (C) 2000-2006 MySQL AB, 2009 Sun Microsystems, Inc.
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
@@ -583,7 +583,7 @@ error:
counter--;
pthread_cond_signal(&count_threshhold);
pthread_mutex_unlock(&counter_mutex);
- my_thread_end();
+ mysql_thread_end();
return 0;
}
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
index 2dba157dd78..f0f377971ac 100644
--- a/client/mysqlslap.c
+++ b/client/mysqlslap.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 MySQL AB
+/* Copyright (C) 2005 MySQL AB, 2009 Sun Microsystems, Inc.
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
@@ -423,6 +423,7 @@ void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr)
stats *sptr;
conclusions conclusion;
unsigned long long client_limit;
+ int sysret;
head_sptr= (stats *)my_malloc(sizeof(stats) * iterations,
MYF(MY_ZEROFILL|MY_FAE|MY_WME));
@@ -472,7 +473,10 @@ void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr)
run_query(mysql, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
if (pre_system)
- if (system(pre_system)) { /* Ignore for now */ }
+ if ((sysret= system(pre_system)) != 0)
+ fprintf(stderr,
+ "Warning: Execution of pre_system option returned %d.\n",
+ sysret);
/*
Pre statements are always run after all other logic so they can
@@ -487,8 +491,10 @@ void concurrency_loop(MYSQL *mysql, uint current, option_string *eptr)
run_statements(mysql, post_statements);
if (post_system)
- if (system(post_system)) { /* Ignore for now */ }
-
+ if ((sysret= system(post_system)) != 0)
+ fprintf(stderr,
+ "Warning: Execution of post_system option returned %d.\n",
+ sysret);
/* We are finished with this run */
if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
drop_primary_key_list();
@@ -597,8 +603,8 @@ static struct my_option my_long_options[] =
(uchar**) &detach_rate, (uchar**) &detach_rate, 0, GET_UINT, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{"engine", 'e', "Comma separated list of storage engines to use for creating the table."
- "The test is run for each engine. You can also specify an option for an engine"
- "after a `:', like memory:max_row=2300",
+ " The test is run for each engine. You can also specify an option for an engine"
+ " after a `:', like memory:max_row=2300",
(uchar**) &default_engine, (uchar**) &default_engine, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"host", 'h', "Connect to host.", (uchar**) &host, (uchar**) &host, 0, GET_STR,
@@ -1942,7 +1948,7 @@ end:
if (!opt_only_print)
mysql_close(mysql);
- my_thread_end();
+ mysql_thread_end();
pthread_mutex_lock(&counter_mutex);
thread_counter--;
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 0cd9cb3848d..217b6852656 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -82,6 +82,9 @@ enum {
static int record= 0, opt_sleep= -1;
static char *opt_db= 0, *opt_pass= 0;
const char *opt_user= 0, *opt_host= 0, *unix_sock= 0, *opt_basedir= "./";
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name=0;
+#endif
const char *opt_logdir= "";
const char *opt_include= 0, *opt_charsets_dir;
static int opt_port= 0;
@@ -429,6 +432,7 @@ static struct st_expected_errors saved_expected_errors;
struct st_command
{
char *query, *query_buf,*first_argument,*last_argument,*end;
+ DYNAMIC_STRING content;
int first_word_len, query_len;
my_bool abort_on_error;
struct st_expected_errors expected_errors;
@@ -1152,6 +1156,8 @@ void free_used_memory()
{
struct st_command **q= dynamic_element(&q_lines, i, struct st_command**);
my_free((*q)->query_buf,MYF(MY_ALLOW_ZERO_PTR));
+ if ((*q)->content.str)
+ dynstr_free(&(*q)->content);
my_free((*q),MYF(0));
}
for (i= 0; i < 10; i++)
@@ -1177,6 +1183,7 @@ void free_used_memory()
mysql_server_end();
/* Don't use DBUG after mysql_server_end() */
+ DBUG_VIOLATION_HELPER_LEAVE;
return;
}
@@ -1543,7 +1550,7 @@ void show_diff(DYNAMIC_STRING* ds,
else
diff_name = 0;
#else
- diff_name = "diff"; // Otherwise always assume it's called diff
+ diff_name = "diff"; /* Otherwise always assume it's called diff */
#endif
if (diff_name)
@@ -3321,21 +3328,30 @@ void do_write_file_command(struct st_command *command, my_bool append)
sizeof(write_file_args)/sizeof(struct command_arg),
' ');
- /* If no delimiter was provided, use EOF */
- if (ds_delimiter.length == 0)
- dynstr_set(&ds_delimiter, "EOF");
-
if (!append && access(ds_filename.str, F_OK) == 0)
{
/* The file should not be overwritten */
die("File already exist: '%s'", ds_filename.str);
}
- init_dynamic_string(&ds_content, "", 1024, 1024);
- read_until_delimiter(&ds_content, &ds_delimiter);
- DBUG_PRINT("info", ("Writing to file: %s", ds_filename.str));
- str_to_file2(ds_filename.str, ds_content.str, ds_content.length, append);
- dynstr_free(&ds_content);
+ ds_content= command->content;
+ /* If it hasn't been done already by a loop iteration, fill it in */
+ if (! ds_content.str)
+ {
+ /* If no delimiter was provided, use EOF */
+ if (ds_delimiter.length == 0)
+ dynstr_set(&ds_delimiter, "EOF");
+
+ init_dynamic_string(&ds_content, "", 1024, 1024);
+ read_until_delimiter(&ds_content, &ds_delimiter);
+ command->content= ds_content;
+ }
+ /* This function could be called even if "false", so check before printing */
+ if (cur_block->ok)
+ {
+ DBUG_PRINT("info", ("Writing to file: %s", ds_filename.str));
+ str_to_file2(ds_filename.str, ds_content.str, ds_content.length, append);
+ }
dynstr_free(&ds_filename);
dynstr_free(&ds_delimiter);
DBUG_VOID_RETURN;
@@ -3478,12 +3494,17 @@ void do_diff_files(struct st_command *command)
die("command \"diff_files\" failed, file '%s' does not exist",
ds_filename2.str);
- if ((error= compare_files(ds_filename.str, ds_filename2.str)))
+ if ((error= compare_files(ds_filename.str, ds_filename2.str)) &&
+ match_expected_error(command, error, NULL) < 0)
{
/* Compare of the two files failed, append them to output
- so the failure can be analyzed
+ so the failure can be analyzed, but only if it was not
+ expected to fail.
*/
show_diff(&ds_res, ds_filename.str, ds_filename2.str);
+ log_file.write(&ds_res);
+ log_file.flush();
+ dynstr_set(&ds_res, 0);
}
dynstr_free(&ds_filename);
@@ -4910,6 +4931,8 @@ do_handle_error:
<opts> - options to use for the connection
* SSL - use SSL if available
* COMPRESS - use compression if available
+ * SHM - use shared memory if available
+ * PIPE - use named pipe if available
*/
@@ -4918,6 +4941,7 @@ void do_connect(struct st_command *command)
int con_port= opt_port;
char *con_options;
my_bool con_ssl= 0, con_compress= 0;
+ my_bool con_pipe= 0, con_shm= 0;
struct st_connection* con_slot;
static DYNAMIC_STRING ds_connection_name;
@@ -4928,6 +4952,9 @@ void do_connect(struct st_command *command)
static DYNAMIC_STRING ds_port;
static DYNAMIC_STRING ds_sock;
static DYNAMIC_STRING ds_options;
+#ifdef HAVE_SMEM
+ static DYNAMIC_STRING ds_shm;
+#endif
const struct command_arg connect_args[] = {
{ "connection name", ARG_STRING, TRUE, &ds_connection_name, "Name of the connection" },
{ "host", ARG_STRING, TRUE, &ds_host, "Host to connect to" },
@@ -4955,6 +4982,11 @@ void do_connect(struct st_command *command)
die("Illegal argument for port: '%s'", ds_port.str);
}
+#ifdef HAVE_SMEM
+ /* Shared memory */
+ init_dynamic_string(&ds_shm, ds_sock.str, 0, 0);
+#endif
+
/* Sock */
if (ds_sock.length)
{
@@ -4993,6 +5025,10 @@ void do_connect(struct st_command *command)
con_ssl= 1;
else if (!strncmp(con_options, "COMPRESS", 8))
con_compress= 1;
+ else if (!strncmp(con_options, "PIPE", 4))
+ con_pipe= 1;
+ else if (!strncmp(con_options, "SHM", 3))
+ con_shm= 1;
else
die("Illegal option to connect: %.*s",
(int) (end - con_options), con_options);
@@ -5043,6 +5079,31 @@ void do_connect(struct st_command *command)
}
#endif
+#ifdef __WIN__
+ if (con_pipe)
+ {
+ uint protocol= MYSQL_PROTOCOL_PIPE;
+ mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol);
+ }
+#endif
+
+#ifdef HAVE_SMEM
+ if (con_shm)
+ {
+ uint protocol= MYSQL_PROTOCOL_MEMORY;
+ if (!ds_shm.length)
+ die("Missing shared memory base name");
+ mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, ds_shm.str);
+ mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol);
+ }
+ else if(shared_memory_base_name)
+ {
+ mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME,
+ shared_memory_base_name);
+ }
+#endif
+
+
/* Use default db name */
if (ds_database.length == 0)
dynstr_set(&ds_database, opt_db);
@@ -5075,6 +5136,9 @@ void do_connect(struct st_command *command)
dynstr_free(&ds_port);
dynstr_free(&ds_sock);
dynstr_free(&ds_options);
+#ifdef HAVE_SMEM
+ dynstr_free(&ds_shm);
+#endif
DBUG_VOID_RETURN;
}
@@ -5746,6 +5810,12 @@ static struct my_option my_long_options[] =
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"server-file", 'F', "Read embedded server arguments from file.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SMEM
+ {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
+ "Base name of shared memory.", (uchar**) &shared_memory_base_name,
+ (uchar**) &shared_memory_base_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
+ 0, 0, 0},
+#endif
{"silent", 's', "Suppress all normal output. Synonym for --quiet.",
(uchar**) &silent, (uchar**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
@@ -6809,8 +6879,10 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command,
MYSQL_STMT *stmt;
DYNAMIC_STRING ds_prepare_warnings;
DYNAMIC_STRING ds_execute_warnings;
+ ulonglong affected_rows;
DBUG_ENTER("run_query_stmt");
DBUG_PRINT("query", ("'%-.60s'", query));
+ LINT_INIT(affected_rows);
/*
Init a new stmt if it's not already one created for this connection
@@ -6950,32 +7022,43 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command,
*/
}
- if (!disable_warnings)
+ /*
+ Need to grab affected rows information before getting
+ warnings here
+ */
{
- /* Get the warnings from execute */
+ ulonglong affected_rows;
+ LINT_INIT(affected_rows);
+
+ if (!disable_info)
+ affected_rows= mysql_affected_rows(mysql);
- /* Append warnings to ds - if there are any */
- if (append_warnings(&ds_execute_warnings, mysql) ||
- ds_execute_warnings.length ||
- ds_prepare_warnings.length ||
- ds_warnings->length)
+ if (!disable_warnings)
{
- dynstr_append_mem(ds, "Warnings:\n", 10);
- if (ds_warnings->length)
- dynstr_append_mem(ds, ds_warnings->str,
- ds_warnings->length);
- if (ds_prepare_warnings.length)
- dynstr_append_mem(ds, ds_prepare_warnings.str,
- ds_prepare_warnings.length);
- if (ds_execute_warnings.length)
- dynstr_append_mem(ds, ds_execute_warnings.str,
- ds_execute_warnings.length);
- }
- }
+ /* Get the warnings from execute */
- if (!disable_info)
- append_info(ds, mysql_affected_rows(mysql), mysql_info(mysql));
+ /* Append warnings to ds - if there are any */
+ if (append_warnings(&ds_execute_warnings, mysql) ||
+ ds_execute_warnings.length ||
+ ds_prepare_warnings.length ||
+ ds_warnings->length)
+ {
+ dynstr_append_mem(ds, "Warnings:\n", 10);
+ if (ds_warnings->length)
+ dynstr_append_mem(ds, ds_warnings->str,
+ ds_warnings->length);
+ if (ds_prepare_warnings.length)
+ dynstr_append_mem(ds, ds_prepare_warnings.str,
+ ds_prepare_warnings.length);
+ if (ds_execute_warnings.length)
+ dynstr_append_mem(ds, ds_execute_warnings.str,
+ ds_execute_warnings.length);
+ }
+ }
+ if (!disable_info)
+ append_info(ds, affected_rows, mysql_info(mysql));
+ }
}
end:
@@ -7224,6 +7307,10 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
run_query_normal(cn, command, flags, query, query_len,
ds, &ds_warnings);
+ dynstr_free(&ds_warnings);
+ if (command->type == Q_EVAL)
+ dynstr_free(&eval_query);
+
if (display_result_sorted)
{
/* Sort the result set and append it to result */
@@ -7254,11 +7341,8 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
check_require(ds, command->require_file);
}
- dynstr_free(&ds_warnings);
if (ds == &ds_result)
dynstr_free(&ds_result);
- if (command->type == Q_EVAL)
- dynstr_free(&eval_query);
DBUG_VOID_RETURN;
}
@@ -7704,6 +7788,11 @@ int main(int argc, char **argv)
}
#endif
+#ifdef HAVE_SMEM
+ if (shared_memory_base_name)
+ mysql_options(&con->mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
+#endif
+
if (!(con->name = my_strdup("default", MYF(MY_WME))))
die("Out of memory");
@@ -7742,7 +7831,32 @@ int main(int argc, char **argv)
command->type= Q_COMMENT;
}
- if (cur_block->ok)
+ my_bool ok_to_do= cur_block->ok;
+ /*
+ Some commands need to be "done" the first time if they may get
+ re-iterated over in a true context. This can only happen if there's
+ a while loop at some level above the current block.
+ */
+ if (!ok_to_do)
+ {
+ if (command->type == Q_SOURCE ||
+ command->type == Q_ERROR ||
+ command->type == Q_WRITE_FILE ||
+ command->type == Q_APPEND_FILE ||
+ command->type == Q_PERL)
+ {
+ for (struct st_block *stb= cur_block-1; stb >= block_stack; stb--)
+ {
+ if (stb->cmd == cmd_while)
+ {
+ ok_to_do= 1;
+ break;
+ }
+ }
+ }
+ }
+
+ if (ok_to_do)
{
command->last_argument= command->first_argument;
processed = 1;
@@ -8053,6 +8167,8 @@ int main(int argc, char **argv)
if (parsing_disabled)
die("Test ended with parsing disabled");
+ my_bool empty_result= FALSE;
+
/*
The whole test has been executed _sucessfully_.
Time to compare result or save it to record file.
@@ -8093,11 +8209,20 @@ int main(int argc, char **argv)
}
else
{
- die("The test didn't produce any output");
+ /* Empty output is an error *unless* we also have an empty result file */
+ if (! result_file_name || record ||
+ compare_files (log_file.file_name(), result_file_name))
+ {
+ die("The test didn't produce any output");
+ }
+ else
+ {
+ empty_result= TRUE; /* Meaning empty was expected */
+ }
}
- if (!command_executed && result_file_name)
- die("No queries executed but result file found!");
+ if (!command_executed && result_file_name && !empty_result)
+ die("No queries executed but non-empty result file found!");
verbose_msg("Test has succeeded!");
timer_output();
@@ -8184,6 +8309,8 @@ void do_get_replace_column(struct st_command *command)
}
my_free(start, MYF(0));
command->last_argument= command->end;
+
+ DBUG_VOID_RETURN;
}
diff --git a/cmd-line-utils/readline/config_readline.h b/cmd-line-utils/readline/config_readline.h
index 141989ec3c9..9aa464958bb 100644
--- a/cmd-line-utils/readline/config_readline.h
+++ b/cmd-line-utils/readline/config_readline.h
@@ -7,6 +7,13 @@
# include <config.h>
#endif
+#ifdef NOT_YET /* causes problem on MacOSX */
+/* to get wcwidth() defined */
+#define _XOPEN_SOURCE 600
+#define _XOPEN_SOURCE_EXTENDED
+#define _XOPEN_
+#endif
+
/*
Ultrix botches type-ahead when switching from canonical to
non-canonical mode, at least through version 4.3
diff --git a/cmd-line-utils/readline/display.c b/cmd-line-utils/readline/display.c
index 720ef3a82e4..eb628896d69 100644
--- a/cmd-line-utils/readline/display.c
+++ b/cmd-line-utils/readline/display.c
@@ -461,12 +461,12 @@ rl_redisplay ()
register char *line;
int inv_botlin, lb_linenum, o_cpos;
int newlines, lpos, temp, modmark;
- char *prompt_this_line;
+ const char *prompt_this_line;
#if defined (HANDLE_MULTIBYTE)
- int num, n0;
+ int num, n0= 0;
wchar_t wc;
size_t wc_bytes;
- int wc_width;
+ int wc_width= 0;
mbstate_t ps;
int _rl_wrapped_multicolumn = 0;
#endif
@@ -824,7 +824,7 @@ rl_redisplay ()
cpos_buffer_position = out;
lb_linenum = newlines;
}
- for (i = in; i < in+wc_bytes; i++)
+ for (i = in; i < in+(int)wc_bytes; i++)
line[out++] = rl_line_buffer[i];
for (i = 0; i < wc_width; i++)
CHECK_LPOS();
diff --git a/cmd-line-utils/readline/history.c b/cmd-line-utils/readline/history.c
index c81101fc555..c6c46482f50 100644
--- a/cmd-line-utils/readline/history.c
+++ b/cmd-line-utils/readline/history.c
@@ -211,14 +211,14 @@ history_get (offset)
HIST_ENTRY *
alloc_history_entry (string, ts)
- char *string;
+ const char *string;
char *ts;
{
HIST_ENTRY *temp;
temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
- temp->line = string ? savestring (string) : string;
+ temp->line = string ? savestring ((char*) string) : (char*) string;
temp->data = (char *)NULL;
temp->timestamp = ts;
diff --git a/cmd-line-utils/readline/rlmbutil.h b/cmd-line-utils/readline/rlmbutil.h
index dd317e2a090..1ed402e0dba 100644
--- a/cmd-line-utils/readline/rlmbutil.h
+++ b/cmd-line-utils/readline/rlmbutil.h
@@ -109,8 +109,8 @@ extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int));
extern wchar_t _rl_char_value PARAMS((char *, int));
extern int _rl_walphabetic PARAMS((wchar_t));
-#define _rl_to_wupper(wc) (iswlower (wc) ? towupper (wc) : (wc))
-#define _rl_to_wlower(wc) (iswupper (wc) ? towlower (wc) : (wc))
+#define _rl_to_wupper(wc) (iswlower (wc) ? (wchar_t) towupper (wc) : (wc))
+#define _rl_to_wlower(wc) (iswupper (wc) ? (wchar_t) towlower (wc) : (wc))
#define MB_NEXTCHAR(b,s,c,f) \
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \
diff --git a/cmd-line-utils/readline/text.c b/cmd-line-utils/readline/text.c
index 9c21e784e1f..774ba1eb2c0 100644
--- a/cmd-line-utils/readline/text.c
+++ b/cmd-line-utils/readline/text.c
@@ -614,7 +614,7 @@ rl_arrow_keys (count, c)
#ifdef HANDLE_MULTIBYTE
static char pending_bytes[MB_LEN_MAX];
static int pending_bytes_length = 0;
-static mbstate_t ps = {0};
+static mbstate_t ps;
#endif
/* Insert the character C at the current location, moving point forward.
diff --git a/cmd-line-utils/readline/xmalloc.c b/cmd-line-utils/readline/xmalloc.c
index cf52da351a8..1a086852552 100644
--- a/cmd-line-utils/readline/xmalloc.c
+++ b/cmd-line-utils/readline/xmalloc.c
@@ -42,7 +42,7 @@
static void
memory_error_and_abort (fname)
- char *fname;
+ const char *fname;
{
fprintf (stderr, "%s: out of virtual memory\n", fname);
exit (2);
diff --git a/configure.in b/configure.in
index 34b655773f4..d73b081f235 100644
--- a/configure.in
+++ b/configure.in
@@ -1652,13 +1652,14 @@ then
DEBUG_OPTIMIZE_CXX="-O"
OPTIMIZE_CXXFLAGS="$MAX_CXX_OPTIMIZE"
else
- DEBUG_CXXFLAGS="-g"
DEBUG_OPTIMIZE_CXX=""
case $SYSTEM_TYPE in
*solaris*)
+ DEBUG_CXXFLAGS="-g0"
OPTIMIZE_CXXFLAGS="-O1"
;;
*)
+ DEBUG_CXXFLAGS="-g"
OPTIMIZE_CXXFLAGS="-O"
;;
esac
@@ -1715,6 +1716,23 @@ else
CXXFLAGS="$OPTIMIZE_CXXFLAGS $CXXFLAGS"
fi
+# Debug Sync Facility. NOTE: depends on 'with_debug'. Must be behind it.
+AC_MSG_CHECKING(if Debug Sync Facility should be enabled.)
+AC_ARG_ENABLE(debug_sync,
+ AS_HELP_STRING([--enable-debug-sync],
+ [Build a version with Debug Sync Facility]),
+ [ enable_debug_sync=$enableval ],
+ [ enable_debug_sync=$with_debug ])
+
+if test "$enable_debug_sync" != "no"
+then
+ AC_DEFINE([ENABLED_DEBUG_SYNC], [1],
+ [If Debug Sync Facility should be enabled])
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+
# If we should allow error injection tests
AC_ARG_WITH(error-inject,
AC_HELP_STRING([--with-error-inject],[Enable error injection in MySQL Server]),
@@ -2786,7 +2804,7 @@ server_scripts=
dnl This probably should be cleaned up more - for now the threaded
dnl client is just using plain-old libs.
-sql_client_dirs="strings regex mysys libmysql"
+sql_client_dirs="strings mysys dbug extra regex libmysql unittest"
AM_CONDITIONAL(THREAD_SAFE_CLIENT, test "$THREAD_SAFE_CLIENT" != "no")
@@ -2814,12 +2832,20 @@ fi
AC_SUBST(netware_dir)
AM_CONDITIONAL(HAVE_NETWARE, test "$netware_dir" = "netware")
-if test "$with_server" = "yes" -o "$THREAD_SAFE_CLIENT" != "no"
+if test "$with_server" != "no" -o "$THREAD_SAFE_CLIENT" != "no"
then
AC_DEFINE([THREAD], [1],
[Define if you want to have threaded code. This may be undef on client code])
+ # Avoid _PROGRAMS names
+ THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o my_thr_init.o mf_keycache.o mf_keycaches.o waiting_threads.o"
+ AC_SUBST(THREAD_LOBJECTS)
+fi
+AM_CONDITIONAL(NEED_THREAD, test "$with_server" != "no" -o "$THREAD_SAFE_CLIENT" != "no")
+
+if test "$with_server" != "no"
+then
server_scripts="mysqld_safe mysql_install_db"
- sql_server_dirs="strings mysys dbug extra regex"
+ sql_server_dirs="strings mysys dbug extra regex storage plugin"
sql_server="vio sql"
fi
@@ -2845,9 +2871,10 @@ AC_SUBST(mysql_plugin_defs)
# Now that sql_client_dirs and sql_server_dirs are stable, determine the union.
-# Start with the (longer) server list, add each client item not yet present.
-sql_union_dirs=" $sql_server_dirs "
-for DIR in $sql_client_dirs
+# We support client-only builds by "--without-server", but not vice versa,
+# so we start with the client list, then add each server item not yet present.
+sql_union_dirs=" $sql_client_dirs "
+for DIR in $sql_server_dirs
do
if echo " $sql_union_dirs " | grep " $DIR " >/dev/null
then
diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp
index 12489468e6b..1e761f559e2 100644
--- a/extra/yassl/include/yassl_int.hpp
+++ b/extra/yassl/include/yassl_int.hpp
@@ -441,7 +441,7 @@ public:
const Ciphers& GetCiphers() const;
const DH_Parms& GetDH_Parms() const;
const Stats& GetStats() const;
- VerifyCallback getVerifyCallback() const;
+ VerifyCallback getVerifyCallback() const;
pem_password_cb GetPasswordCb() const;
void* GetUserData() const;
bool GetSessionCacheOff() const;
diff --git a/extra/yassl/taocrypt/src/random.cpp b/extra/yassl/taocrypt/src/random.cpp
index 89fd5f7c7bc..2bbc0a85e8b 100644
--- a/extra/yassl/taocrypt/src/random.cpp
+++ b/extra/yassl/taocrypt/src/random.cpp
@@ -27,7 +27,6 @@
#include <time.h>
#if defined(_WIN32)
- #define _WIN32_WINNT 0x0400
#include <windows.h>
#include <wincrypt.h>
#else
diff --git a/include/ft_global.h b/include/ft_global.h
index dba8a6e75e5..8fe5ee5c42e 100644
--- a/include/ft_global.h
+++ b/include/ft_global.h
@@ -76,6 +76,8 @@ my_bool ft_boolean_check_syntax_string(const uchar *);
extern const HA_KEYSEG ft_keysegs[FT_SEGS];
+typedef union {int32 i; float f;} FT_WEIGTH;
+
#ifdef __cplusplus
}
#endif
diff --git a/include/m_ctype.h b/include/m_ctype.h
index 37e60af3e07..6229a82ee9c 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -49,6 +49,24 @@ typedef struct unicase_info_st
extern MY_UNICASE_INFO *my_unicase_default[256];
extern MY_UNICASE_INFO *my_unicase_turkish[256];
+#define MY_UCA_MAX_CONTRACTION 4
+#define MY_UCA_MAX_WEIGHT_SIZE 8
+
+typedef struct my_contraction_t
+{
+ my_wc_t ch[MY_UCA_MAX_CONTRACTION]; /* Character sequence */
+ uint16 weight[MY_UCA_MAX_WEIGHT_SIZE];/* Its weight string, 0-terminated */
+} MY_CONTRACTION;
+
+
+typedef struct my_contraction_list_t
+{
+ size_t nitems; /* Number of items in the list */
+ MY_CONTRACTION *item; /* List of contractions */
+ char *flags; /* Character flags, e.g. "is contraction head") */
+} MY_CONTRACTIONS;
+
+
typedef struct uni_ctype_st
{
uchar pctype;
@@ -262,7 +280,7 @@ typedef struct charset_info_st
uchar *to_lower;
uchar *to_upper;
uchar *sort_order;
- uint16 *contractions;
+ MY_CONTRACTIONS *contractions;
uint16 **sort_order_big;
uint16 *tab_to_uni;
MY_UNI_IDX *tab_from_uni;
@@ -475,6 +493,13 @@ my_bool my_charset_is_ascii_based(CHARSET_INFO *cs);
my_bool my_charset_is_8bit_pure_ascii(CHARSET_INFO *cs);
uint my_charset_repertoire(CHARSET_INFO *cs);
+my_bool my_uca_have_contractions(CHARSET_INFO *cs);
+my_bool my_uca_can_be_contraction_head(CHARSET_INFO *cs, my_wc_t wc);
+my_bool my_uca_can_be_contraction_tail(CHARSET_INFO *cs, my_wc_t wc);
+uint16 *my_uca_contraction2_weight(CHARSET_INFO *cs, my_wc_t wc1, my_wc_t wc2);
+
+
+
#define _MY_U 01 /* Upper case */
#define _MY_L 02 /* Lower case */
diff --git a/include/my_dbug.h b/include/my_dbug.h
index 5c185d5eef2..b32f12af8a0 100644
--- a/include/my_dbug.h
+++ b/include/my_dbug.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2000 MySQL AB & 2009 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
@@ -16,7 +16,30 @@
#ifndef _dbug_h
#define _dbug_h
-#ifdef __cplusplus
+#if defined(__cplusplus) && !defined(DBUG_OFF)
+class Dbug_violation_helper
+{
+public:
+ inline Dbug_violation_helper() :
+ _entered(TRUE)
+ { }
+
+ inline ~Dbug_violation_helper()
+ {
+ assert(!_entered);
+ }
+
+ inline void leave()
+ {
+ _entered= FALSE;
+ }
+
+private:
+ bool _entered;
+};
+#endif /* C++ */
+
+#ifdef __cplusplus
extern "C" {
#endif
#if !defined(DBUG_OFF) && !defined(_lint)
@@ -30,34 +53,51 @@ struct _db_stack_frame_ {
struct _db_code_state_;
extern my_bool _dbug_on_;
-extern my_bool _db_keyword_(struct _db_code_state_ *, const char *, int);
+extern my_bool _db_keyword_(struct _db_code_state_ *cs, const char *keyword,
+ int strict_flag);
+extern int _db_strict_keyword_(const char *keyword);
extern int _db_explain_(struct _db_code_state_ *cs, char *buf, size_t len);
extern int _db_explain_init_(char *buf, size_t len);
extern int _db_is_pushed_(void);
extern void _db_setjmp_(void);
extern void _db_longjmp_(void);
extern void _db_process_(const char *name);
-extern void _db_push_(const char *control);
-extern void _db_pop_(void);
+extern void _db_push_(const char *control);
+extern void _db_pop_(void);
extern void _db_set_(const char *control);
extern void _db_set_init_(const char *control);
-extern void _db_enter_(const char *_func_, const char *_file_, uint _line_,
- struct _db_stack_frame_ *_stack_frame_);
+extern void _db_enter_(const char *_func_, const char *_file_, uint _line_,
+ struct _db_stack_frame_ *_stack_frame_);
extern void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_);
extern void _db_pargs_(uint _line_,const char *keyword);
extern void _db_doprnt_ _VARARGS((const char *format,...))
ATTRIBUTE_FORMAT(printf, 1, 2);
-extern void _db_dump_(uint _line_,const char *keyword,
+extern void _db_dump_(uint _line_,const char *keyword,
const unsigned char *memory, size_t length);
-extern void _db_end_(void);
-extern void _db_lock_file_(void);
-extern void _db_unlock_file_(void);
-extern FILE *_db_fp_(void);
+extern void _db_end_(void);
+extern void _db_lock_file_(void);
+extern void _db_unlock_file_(void);
+extern FILE *_db_fp_(void);
extern void _db_flush_();
+#ifdef __cplusplus
+
#define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_; \
+ Dbug_violation_helper dbug_violation_helper; \
_db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_)
-#define DBUG_LEAVE _db_return_ (__LINE__, &_db_stack_frame_)
+#define DBUG_VIOLATION_HELPER_LEAVE dbug_violation_helper.leave()
+
+#else /* C */
+
+#define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_; \
+ _db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_)
+#define DBUG_VIOLATION_HELPER_LEAVE do { } while(0)
+
+#endif /* C++ */
+
+#define DBUG_LEAVE \
+ DBUG_VIOLATION_HELPER_LEAVE; \
+ _db_return_ (__LINE__, &_db_stack_frame_)
#define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0)
#define DBUG_VOID_RETURN do {DBUG_LEAVE; return;} while(0)
#define DBUG_EXECUTE(keyword,a1) \
@@ -88,28 +128,16 @@ extern void _db_flush_();
#define DEBUGGER_OFF do { _dbug_on_= 0; } while(0)
#define DEBUGGER_ON do { _dbug_on_= 1; } while(0)
#define IF_DBUG(A) A
-#ifndef __WIN__
#define DBUG_ABORT() (_db_flush_(), abort())
-#else
-/*
- Avoid popup with abort/retry/ignore buttons. When BUG#31745 is fixed we can
- call abort() instead of _exit(3) (now it would cause a "test signal" popup).
-*/
-#include <crtdbg.h>
-#define DBUG_ABORT() (_db_flush_(),\
- (void)_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE),\
- (void)_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR),\
- _exit(3))
-#endif
-
#else /* No debugger */
#define DBUG_ENTER(a1)
+#define DBUG_VIOLATION_HELPER_LEAVE do { } while(0)
#define DBUG_LEAVE
-#define DBUG_RETURN(a1) do { return(a1); } while(0)
-#define DBUG_VOID_RETURN do { return; } while(0)
-#define DBUG_EXECUTE(keyword,a1) do { } while(0)
-#define DBUG_EXECUTE_IF(keyword,a1) do { } while(0)
+#define DBUG_RETURN(a1) do { return(a1); } while(0)
+#define DBUG_VOID_RETURN do { return; } while(0)
+#define DBUG_EXECUTE(keyword,a1) do { } while(0)
+#define DBUG_EXECUTE_IF(keyword,a1) do { } while(0)
#define DBUG_EVALUATE(keyword,a1,a2) (a2)
#define DBUG_EVALUATE_IF(keyword,a1,a2) (a2)
#define DBUG_PRINT(keyword,arglist) do { } while(0)
diff --git a/include/my_sys.h b/include/my_sys.h
index 2afec2d0014..25676772e08 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -69,6 +69,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_HOLD_ON_ERROR 256 /* my_realloc() ; Return old ptr on error */
#define MY_DONT_OVERWRITE_FILE 2048 /* my_copy: Don't overwrite file */
#define MY_THREADSAFE 2048 /* my_seek(): lock fd mutex */
+#define MY_SYNC 4096 /* my_copy(): sync dst file */
#define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */
#define MY_GIVE_INFO 2 /* Give time info about process*/
@@ -175,6 +176,16 @@ extern char *my_strndup(const char *from, size_t length,
#define TRASH(A,B) /* nothing */
#endif
+#if defined(ENABLED_DEBUG_SYNC)
+extern void (*debug_sync_C_callback_ptr)(const char *, size_t);
+#define DEBUG_SYNC_C(_sync_point_name_) do { \
+ if (debug_sync_C_callback_ptr != NULL) \
+ (*debug_sync_C_callback_ptr)(STRING_WITH_LEN(_sync_point_name_)); } \
+ while(0)
+#else
+#define DEBUG_SYNC_C(_sync_point_name_)
+#endif /* defined(ENABLED_DEBUG_SYNC) */
+
#ifdef HAVE_LARGE_PAGES
extern uint my_get_large_page_size(void);
extern uchar * my_large_malloc(size_t size, myf my_flags);
@@ -727,7 +738,6 @@ extern int wild_compare(const char *str,const char *wildstr,
extern WF_PACK *wf_comp(char * str);
extern int wf_test(struct wild_file_pack *wf_pack,const char *name);
extern void wf_end(struct wild_file_pack *buffer);
-extern size_t strip_sp(char * str);
extern my_bool array_append_string_unique(const char *str,
const char **array, size_t size);
extern void get_date(char * to,int timeflag,time_t use_time);
diff --git a/include/my_tree.h b/include/my_tree.h
index e387b25d431..ceeb849ad0c 100644
--- a/include/my_tree.h
+++ b/include/my_tree.h
@@ -51,7 +51,7 @@ typedef struct st_tree {
TREE_ELEMENT *root,null_element;
TREE_ELEMENT **parents[MAX_TREE_HEIGHT];
uint offset_to_key,elements_in_tree,size_of_element;
- ulong memory_limit, allocated;
+ size_t memory_limit, allocated;
qsort_cmp2 compare;
void *custom_arg;
MEM_ROOT mem_root;
@@ -61,7 +61,7 @@ typedef struct st_tree {
} TREE;
/* Functions on whole tree */
-void init_tree(TREE *tree, ulong default_alloc_size, ulong memory_limit,
+void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit,
int size, qsort_cmp2 compare, my_bool with_delete,
tree_element_free free_element, void *custom_arg);
void delete_tree(TREE*);
diff --git a/include/myisamchk.h b/include/myisamchk.h
index 6d2d887cf68..057c06652a1 100644
--- a/include/myisamchk.h
+++ b/include/myisamchk.h
@@ -154,6 +154,10 @@ typedef struct st_handler_check_param
char temp_filename[FN_REFLEN];
IO_CACHE read_cache;
enum_handler_stats_method stats_method;
+#ifdef THREAD
+ pthread_mutex_t print_msg_mutex;
+ my_bool need_print_msg_lock;
+#endif
} HA_CHECK;
diff --git a/include/mysql.h b/include/mysql.h
index 074098aef1b..b4b399eccc1 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -558,6 +558,16 @@ unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql,
char *to,const char *from,
unsigned long length);
void STDCALL mysql_debug(const char *debug);
+char * STDCALL mysql_odbc_escape_string(MYSQL *mysql,
+ char *to,
+ unsigned long to_length,
+ const char *from,
+ unsigned long from_length,
+ void *param,
+ char *
+ (*extend_buffer)
+ (void *, char *to,
+ unsigned long *length));
void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
unsigned int STDCALL mysql_thread_safe(void);
my_bool STDCALL mysql_embedded(void);
diff --git a/include/mysql.h.pp b/include/mysql.h.pp
index c333cb2bec5..c6a64ccb96e 100644
--- a/include/mysql.h.pp
+++ b/include/mysql.h.pp
@@ -518,6 +518,16 @@ unsigned long mysql_real_escape_string(MYSQL *mysql,
char *to,const char *from,
unsigned long length);
void mysql_debug(const char *debug);
+char * mysql_odbc_escape_string(MYSQL *mysql,
+ char *to,
+ unsigned long to_length,
+ const char *from,
+ unsigned long from_length,
+ void *param,
+ char *
+ (*extend_buffer)
+ (void *, char *to,
+ unsigned long *length));
void myodbc_remove_escape(MYSQL *mysql,char *name);
unsigned int mysql_thread_safe(void);
my_bool mysql_embedded(void);
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
index 35af8a021f3..b33f5970110 100644
--- a/include/mysql/plugin.h
+++ b/include/mysql/plugin.h
@@ -564,19 +564,22 @@ typedef struct st_mysql_ftparser_boolean_info
nothing. See enum_ftparser_mode above.
*/
+/* TODO: Change the following int to size_t at next ABI update */
+typedef int mysql_ft_size_t;
+
typedef struct st_mysql_ftparser_param
{
int (*mysql_parse)(struct st_mysql_ftparser_param *,
- char *doc, int doc_len);
+ const unsigned char *doc, mysql_ft_size_t doc_len);
int (*mysql_add_word)(struct st_mysql_ftparser_param *,
- char *word, int word_len,
+ const unsigned char *word, mysql_ft_size_t word_len,
MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
void *ftparser_state;
void *mysql_ftparam;
struct charset_info_st *cs;
- char *doc;
- int length;
- int flags;
+ const unsigned char *doc;
+ mysql_ft_size_t length;
+ unsigned int flags;
enum enum_ftparser_mode mode;
} MYSQL_FTPARSER_PARAM;
diff --git a/include/mysql/plugin.h.pp b/include/mysql/plugin.h.pp
index c781bae9a97..2f44870b479 100644
--- a/include/mysql/plugin.h.pp
+++ b/include/mysql/plugin.h.pp
@@ -70,19 +70,20 @@ typedef struct st_mysql_ftparser_boolean_info
char prev;
char *quot;
} MYSQL_FTPARSER_BOOLEAN_INFO;
+typedef int mysql_ft_size_t;
typedef struct st_mysql_ftparser_param
{
int (*mysql_parse)(struct st_mysql_ftparser_param *,
- char *doc, int doc_len);
+ const unsigned char *doc, mysql_ft_size_t doc_len);
int (*mysql_add_word)(struct st_mysql_ftparser_param *,
- char *word, int word_len,
+ const unsigned char *word, mysql_ft_size_t word_len,
MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
void *ftparser_state;
void *mysql_ftparam;
struct charset_info_st *cs;
- char *doc;
- int length;
- int flags;
+ const unsigned char *doc;
+ mysql_ft_size_t length;
+ unsigned int flags;
enum enum_ftparser_mode mode;
} MYSQL_FTPARSER_PARAM;
struct st_mysql_ftparser
diff --git a/include/mysys_err.h b/include/mysys_err.h
index 754ae5d12ec..defdaa71fa3 100644
--- a/include/mysys_err.h
+++ b/include/mysys_err.h
@@ -63,8 +63,9 @@ extern const char * NEAR globerrs[]; /* my_error_messages is here */
#define EE_FILENOTFOUND 29
#define EE_FILE_NOT_CLOSED 30
#define EE_CANT_CHMOD 31
-#define EE_CANT_COPY_OWNERSHIP 32
-#define EE_ERROR_LAST 32 /* Copy last error nr */
+#define EE_CANT_SEEK 32
+#define EE_CANT_COPY_OWNERSHIP 33
+#define EE_ERROR_LAST 33 /* Copy last error nr */
/* Add error numbers before EE_ERROR_LAST and change it accordingly. */
/* exit codes for all MySQL programs */
diff --git a/include/violite.h b/include/violite.h
index 7f017635f31..9d104a0b23f 100644
--- a/include/violite.h
+++ b/include/violite.h
@@ -44,7 +44,7 @@ enum enum_vio_type
Vio* vio_new(my_socket sd, enum enum_vio_type type, uint flags);
#ifdef __WIN__
Vio* vio_new_win32pipe(HANDLE hPipe);
-Vio* vio_new_win32shared_memory(NET *net,HANDLE handle_file_map,
+Vio* vio_new_win32shared_memory(HANDLE handle_file_map,
HANDLE handle_map,
HANDLE event_server_wrote,
HANDLE event_server_read,
@@ -222,7 +222,11 @@ struct st_vio
HANDLE event_conn_closed;
size_t shared_memory_remain;
char *shared_memory_pos;
- NET *net;
#endif /* HAVE_SMEM */
+#ifdef _WIN32
+ OVERLAPPED pipe_overlapped;
+ DWORD read_timeout_millis;
+ DWORD write_timeout_millis;
+#endif
};
#endif /* vio_violite_h_ */
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 59406ecff09..768a62ea8b8 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -1642,6 +1642,20 @@ mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
return (uint) escape_string_for_mysql(mysql->charset, to, 0, from, length);
}
+
+char * STDCALL
+mysql_odbc_escape_string(MYSQL *mysql __attribute__((unused)),
+ char *to __attribute__((unused)),
+ ulong to_length __attribute__((unused)),
+ const char *from __attribute__((unused)),
+ ulong from_length __attribute__((unused)),
+ void *param __attribute__((unused)),
+ char * (*extend_buffer)(void *, char *, ulong *)
+ __attribute__((unused)))
+{
+ return NULL;
+}
+
void STDCALL
myodbc_remove_escape(MYSQL *mysql,char *name)
{
@@ -2284,7 +2298,7 @@ mysql_stmt_param_metadata(MYSQL_STMT *stmt)
/* Store type of parameter in network buffer. */
-static void store_param_type(char **pos, MYSQL_BIND *param)
+static void store_param_type(uchar **pos, MYSQL_BIND *param)
{
uint typecode= param->buffer_type | (param->is_unsigned ? 32768 : 0);
int2store(*pos, typecode);
@@ -2564,7 +2578,7 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
that is sent to the server.
*/
for (param= stmt->params; param < param_end ; param++)
- store_param_type((char**) &net->write_pos, param);
+ store_param_type(&net->write_pos, param);
}
for (param= stmt->params; param < param_end; param++)
diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def
index 45e85b15120..5c05bff8242 100644
--- a/libmysql/libmysql.def
+++ b/libmysql/libmysql.def
@@ -78,6 +78,7 @@ EXPORTS
mysql_next_result
mysql_num_fields
mysql_num_rows
+ mysql_odbc_escape_string
mysql_options
mysql_stmt_param_count
mysql_stmt_param_metadata
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
index f69f6d26c6d..7d2abb64065 100644
--- a/libmysqld/CMakeLists.txt
+++ b/libmysqld/CMakeLists.txt
@@ -90,8 +90,10 @@ ENDFOREACH(rpath)
FOREACH (ENGINE_LIB ${MYSQLD_STATIC_ENGINE_LIBS})
INCLUDE(${CMAKE_SOURCE_DIR}/storage/${plugin_dir_${ENGINE_LIB}}/CMakeLists.txt)
STRING(TOUPPER ${ENGINE_LIB} ENGINE_LIB_UPPER)
+ SET(ENGINE_DIR ${${ENGINE_LIB_UPPER}_DIR})
+ INCLUDE(${CMAKE_SOURCE_DIR}/storage/${ENGINE_DIR}/CMakeLists.txt)
FOREACH(rpath ${${ENGINE_LIB_UPPER}_SOURCES})
- SET(LIB_SOURCES ${LIB_SOURCES} ${CMAKE_SOURCE_DIR}/storage/${plugin_dir_${ENGINE_LIB}}/${rpath})
+ SET(LIB_SOURCES ${LIB_SOURCES} ${CMAKE_SOURCE_DIR}/storage/${ENGINE_DIR}/${rpath})
ENDFOREACH(rpath)
ENDFOREACH(ENGINE_LIB)
@@ -127,6 +129,7 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/sql_list.cc ../sql/sql_load.cc ../sql/sql_locale.cc
../sql/sql_binlog.cc ../sql/sql_manager.cc ../sql/sql_map.cc
../sql/sql_parse.cc ../sql/sql_partition.cc ../sql/sql_plugin.cc
+ ../sql/debug_sync.cc
../sql/sql_prepare.cc ../sql/sql_rename.cc ../sql/sql_repl.cc
../sql/sql_select.cc ../sql/sql_servers.cc
../sql/sql_show.cc ../sql/sql_state.c ../sql/sql_string.cc
@@ -152,6 +155,14 @@ ADD_LIBRARY(mysqlserver STATIC ${LIBMYSQLD_SOURCES})
ADD_DEPENDENCIES(mysqlserver GenServerSource GenError)
TARGET_LINK_LIBRARIES(mysqlserver)
+# Add any additional libraries requested by engine(s)
+FOREACH (ENGINE_LIB ${MYSQLD_STATIC_ENGINE_LIBS})
+ STRING(TOUPPER ${ENGINE_LIB} ENGINE_LIB_UPPER)
+ IF(${ENGINE_LIB_UPPER}_LIBS)
+ TARGET_LINK_LIBRARIES(mysqlserver ${${ENGINE_LIB_UPPER}_LIBS})
+ ENDIF(${ENGINE_LIB_UPPER}_LIBS)
+ENDFOREACH(ENGINE_LIB)
+
ADD_LIBRARY(libmysqld SHARED cmake_dummy.c libmysqld.def)
ADD_DEPENDENCIES(libmysqld mysqlserver)
TARGET_LINK_LIBRARIES(libmysqld mysqlserver wsock32)
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am
index ecf45a23399..f5da13b145b 100644
--- a/libmysqld/Makefile.am
+++ b/libmysqld/Makefile.am
@@ -74,6 +74,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \
parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
+ debug_sync.cc \
sql_tablespace.cc \
rpl_injector.cc my_user.c partition_info.cc \
sql_servers.cc event_parse_data.cc opt_table_elimination.cc
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 2622ae6988f..7de1ecd6ef3 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -142,6 +142,8 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
if (!skip_check)
result= thd->is_error() ? -1 : 0;
+ thd->mysys_var= 0;
+
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
thd->profiling.finish_current_query();
#endif
@@ -634,6 +636,7 @@ void *create_embedded_thd(int client_flag)
thread_count++;
threads.append(thd);
+ thd->mysys_var= 0;
return thd;
err:
delete(thd);
diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c
index aff9391e015..0c20b35236d 100644
--- a/libmysqld/libmysqld.c
+++ b/libmysqld/libmysqld.c
@@ -164,6 +164,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
port=0;
unix_socket=0;
+ client_flag|=mysql->options.client_flag;
/* Send client information for access check */
client_flag|=CLIENT_CAPABILITIES;
if (client_flag & CLIENT_MULTI_STATEMENTS)
diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def
index 754aa6b3c29..ed9ff2a6600 100644
--- a/libmysqld/libmysqld.def
+++ b/libmysqld/libmysqld.def
@@ -50,6 +50,7 @@ EXPORTS
mysql_next_result
mysql_num_fields
mysql_num_rows
+ mysql_odbc_escape_string
mysql_options
mysql_ping
mysql_query
diff --git a/man/comp_err.1 b/man/comp_err.1
index ee83ce389c1..8d135ae69bc 100644
--- a/man/comp_err.1
+++ b/man/comp_err.1
@@ -2,12 +2,12 @@
.\" Title: \fBcomp_err\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBCOMP_ERR\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBCOMP_ERR\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -91,7 +91,8 @@ Display a help message and exit\&.
.\}
.\" comp_err: charset option
.\" charset option: comp_err
-\fB\-\-charset=\fR\fB\fIpath\fR\fR\fB, \-C \fR\fB\fIpath\fR\fR
+\fB\-\-charset=\fR\fB\fIpath\fR\fR,
+\fB\-C \fR\fB\fIpath\fR\fR
.sp
The character set directory\&. The default is
\&.\&./sql/share/charsets\&.
@@ -107,7 +108,8 @@ The character set directory\&. The default is
.\}
.\" comp_err: debug option
.\" debug option: comp_err
-\fB\-\-debug=\fR\fB\fIdebug_options\fR\fR\fB, \-# \fR\fB\fIdebug_options\fR\fR
+\fB\-\-debug=\fR\fB\fIdebug_options\fR\fR,
+\fB\-# \fR\fB\fIdebug_options\fR\fR
.sp
Write a debugging log\&. A typical
\fIdebug_options\fR
@@ -142,7 +144,8 @@ Print some debugging information when the program exits\&.
.\}
.\" comp_err: header_file option
.\" header_file option: comp_err
-\fB\-\-header_file=\fR\fB\fIfile_name\fR\fR\fB, \-H \fR\fB\fIfile_name\fR\fR
+\fB\-\-header_file=\fR\fB\fIfile_name\fR\fR,
+\fB\-H \fR\fB\fIfile_name\fR\fR
.sp
The name of the error header file\&. The default is
mysqld_error\&.h\&.
@@ -158,7 +161,8 @@ mysqld_error\&.h\&.
.\}
.\" comp_err: in_file option
.\" in_file option: comp_err
-\fB\-\-in_file=\fR\fB\fIfile_name\fR\fR\fB, \-F \fR\fB\fIfile_name\fR\fR
+\fB\-\-in_file=\fR\fB\fIfile_name\fR\fR,
+\fB\-F \fR\fB\fIfile_name\fR\fR
.sp
The name of the input file\&. The default is
\&.\&./sql/share/errmsg\&.txt\&.
@@ -174,7 +178,8 @@ The name of the input file\&. The default is
.\}
.\" comp_err: name_file option
.\" name_file option: comp_err
-\fB\-\-name_file=\fR\fB\fIfile_name\fR\fR\fB, \-N \fR\fB\fIfile_name\fR\fR
+\fB\-\-name_file=\fR\fB\fIfile_name\fR\fR,
+\fB\-N \fR\fB\fIfile_name\fR\fR
.sp
The name of the error name file\&. The default is
mysqld_ername\&.h\&.
@@ -190,7 +195,8 @@ mysqld_ername\&.h\&.
.\}
.\" comp_err: out_dir option
.\" out_dir option: comp_err
-\fB\-\-out_dir=\fR\fB\fIpath\fR\fR\fB, \-D \fR\fB\fIpath\fR\fR
+\fB\-\-out_dir=\fR\fB\fIpath\fR\fR,
+\fB\-D \fR\fB\fIpath\fR\fR
.sp
The name of the output base directory\&. The default is
\&.\&./sql/share/\&.
@@ -206,7 +212,8 @@ The name of the output base directory\&. The default is
.\}
.\" comp_err: out_file option
.\" out_file option: comp_err
-\fB\-\-out_file=\fR\fB\fIfile_name\fR\fR\fB, \-O \fR\fB\fIfile_name\fR\fR
+\fB\-\-out_file=\fR\fB\fIfile_name\fR\fR,
+\fB\-O \fR\fB\fIfile_name\fR\fR
.sp
The name of the output file\&. The default is
errmsg\&.sys\&.
@@ -222,7 +229,8 @@ errmsg\&.sys\&.
.\}
.\" comp_err: statefile option
.\" statefile option: comp_err
-\fB\-\-statefile=\fR\fB\fIfile_name\fR\fR\fB, \-S \fR\fB\fIfile_name\fR\fR
+\fB\-\-statefile=\fR\fB\fIfile_name\fR\fR,
+\fB\-S \fR\fB\fIfile_name\fR\fR
.sp
The name for the SQLSTATE header file\&. The default is
sql_state\&.h\&.
diff --git a/man/innochecksum.1 b/man/innochecksum.1
index 01e54aea325..7a2c311af0e 100644
--- a/man/innochecksum.1
+++ b/man/innochecksum.1
@@ -2,12 +2,12 @@
.\" Title: \fBinnochecksum\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBINNOCHECKSUM\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBINNOCHECKSUM\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -29,7 +29,20 @@ innochecksum \- offline InnoDB file checksum utility
\fBinnochecksum\fR
prints checksums for
InnoDB
-files\&.
+files\&. This tool reads an
+InnoDB
+tablespace file, calculates the checksum for each page, compares the calculated checksum to the stored checksum, and reports mismatches, which indicate damaged pages\&. It was originally developed to speed up verifying the integrity of tablespace files after power outages but can also be used after file copies\&. Because checksum mismatches will cause
+InnoDB
+to deliberately shut down a running server, it can be preferable to use this tool rather than waiting for a server in production usage to encounter the damaged pages\&.
+.PP
+\fBinnochecksum\fR
+cannot be used on tablespace files that the server already has open\&. For such files, you should use
+CHECK TABLE
+to check tables within the tablespace\&.
+.PP
+If checksum mismatches are found, you would normally restore the tablespace from backup or start the server and attempt to use
+\fBmysqldump\fR
+to make a backup of the tables within the tablespace\&.
.PP
Invoke
\fBinnochecksum\fR
diff --git a/man/make_win_bin_dist.1 b/man/make_win_bin_dist.1
index c3fb3a90591..ad7c4f1f44e 100644
--- a/man/make_win_bin_dist.1
+++ b/man/make_win_bin_dist.1
@@ -2,12 +2,12 @@
.\" Title: \fBmake_win_bin_dist\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMAKE_WIN_BIN_DIST" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMAKE_WIN_BIN_DIST" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/msql2mysql.1 b/man/msql2mysql.1
index f726d393909..a8e0d0233e0 100644
--- a/man/msql2mysql.1
+++ b/man/msql2mysql.1
@@ -2,12 +2,12 @@
.\" Title: \fBmsql2mysql\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMSQL2MYSQL\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMSQL2MYSQL\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/my_print_defaults.1 b/man/my_print_defaults.1
index f239345a235..a411fa62187 100644
--- a/man/my_print_defaults.1
+++ b/man/my_print_defaults.1
@@ -2,12 +2,12 @@
.\" Title: \fBmy_print_defaults\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMY_PRINT_DEFAULTS" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMY_PRINT_DEFAULTS" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -100,7 +100,8 @@ Read only the given option file\&.
.\}
.\" my_print_defaults: debug option
.\" debug option: my_print_defaults
-\fB\-\-debug=\fR\fB\fIdebug_options\fR\fR\fB, \-# \fR\fB\fIdebug_options\fR\fR
+\fB\-\-debug=\fR\fB\fIdebug_options\fR\fR,
+\fB\-# \fR\fB\fIdebug_options\fR\fR
.sp
Write a debugging log\&. A typical
\fIdebug_options\fR
diff --git a/man/myisam_ftdump.1 b/man/myisam_ftdump.1
index 59cd4469257..3818bcf6ae7 100644
--- a/man/myisam_ftdump.1
+++ b/man/myisam_ftdump.1
@@ -2,12 +2,12 @@
.\" Title: \fBmyisam_ftdump\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYISAM_FTDUMP\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYISAM_FTDUMP\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/myisamchk.1 b/man/myisamchk.1
index 7a9f6931d65..d3f6a9f1670 100644
--- a/man/myisamchk.1
+++ b/man/myisamchk.1
@@ -2,12 +2,12 @@
.\" Title: \fBmyisamchk\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYISAMCHK\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYISAMCHK\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -275,7 +275,8 @@ Display a help message and exit\&. Options are presented in a single list\&.
.\}
.\" myisamchk: debug option
.\" debug option: myisamchk
-\fB\-\-debug=\fR\fB\fIdebug_options\fR\fR\fB, \-# \fR\fB\fIdebug_options\fR\fR
+\fB\-\-debug=\fR\fB\fIdebug_options\fR\fR,
+\fB\-# \fR\fB\fIdebug_options\fR\fR
.sp
Write a debugging log\&. A typical
\fIdebug_options\fR
@@ -520,7 +521,7 @@ system variable\&. For more information, see the description of
myisam_stats_method
in
Section\ \&5.1.4, \(lqServer System Variables\(rq, and
-Section\ \&7.4.6, \(lqMyISAM Index Statistics Collection\(rq\&. For MySQL 5\&.1,
+Section\ \&7.4.7, \(lqMyISAM Index Statistics Collection\(rq\&. For MySQL 5\&.1,
stats_method
was added in MySQL 5\&.0\&.14\&. For older versions, the statistics collection method is equivalent to
nulls_equal\&.
@@ -662,6 +663,9 @@ If you are using
and have plenty of memory, setting the
key_buffer_size
variable to a large value helps the repair operation run faster\&.
+.sp
+For a description of the output format, see
+the section called \(lqMYISAMCHK TABLE INFORMATION\(rq\&.
.RE
.sp
.RS 4
@@ -782,7 +786,11 @@ server is using the table and you are running it with external locking disabled\
.\" files: repairing
.PP
\fBmyisamchk\fR
-supports the following options for table repair operations:
+supports the following options for table repair operations (operations performed when an option such as
+\fB\-\-recover\fR
+or
+\fB\-\-safe\-recover\fR
+is given):
.sp
.RS 4
.ie n \{\
@@ -844,7 +852,8 @@ Correct the checksum information for the table\&.
.\}
.\" myisamchk: data-file-length option
.\" data-file-length option: myisamchk
-\fB\-\-data\-file\-length=\fR\fB\fIlen\fR\fR\fB, \-D \fR\fB\fIlen\fR\fR
+\fB\-\-data\-file\-length=\fR\fB\fIlen\fR\fR,
+\fB\-D \fR\fB\fIlen\fR\fR
.sp
The maximum length of the data file (when re\-creating data file when it is
\(lqfull\(rq)\&.
@@ -864,6 +873,9 @@ The maximum length of the data file (when re\-creating data file when it is
\fB\-e\fR
.sp
Do a repair that tries to recover every possible row from the data file\&. Normally, this also finds a lot of garbage rows\&. Do not use this option unless you are desperate\&.
+.sp
+For a description of the output format, see
+the section called \(lqMYISAMCHK TABLE INFORMATION\(rq\&.
.RE
.sp
.RS 4
@@ -1172,7 +1184,10 @@ Find the record that a block at the given offset belongs to\&.
\fB\-\-description\fR,
\fB\-d\fR
.sp
-Print some descriptive information about the table\&.
+Print some descriptive information about the table\&. Specifying the
+\fB\-\-verbose\fR
+option once or twice produces additional information\&. See
+the section called \(lqMYISAMCHK TABLE INFORMATION\(rq\&.
.RE
.sp
.RS 4
@@ -1243,6 +1258,1068 @@ sorts and moves records, it just overwrites record offsets in the index\&. If ke
\fBmyisamchk\fR
must unpack key blocks first, then re\-create indexes and pack the key blocks again\&. (In this case, re\-creating indexes is faster than updating offsets for each index\&.)
.RE
+.SH "MYISAMCHK TABLE INFORMATION"
+.\" table description: myisamchk
+.\" tables: information
+.\" examples: myisamchk output
+.\" myisamchk: example output
+.PP
+To obtain a description of a
+MyISAM
+table or statistics about it, use the commands shown here\&. The output from these commands is explained later in this section\&.
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBmyisamchk \-d \fR\fB\fItbl_name\fR\fR
+.sp
+Runs
+\fBmyisamchk\fR
+in
+\(lqdescribe mode\(rq
+to produce a description of your table\&. If you start the MySQL server with external locking disabled,
+\fBmyisamchk\fR
+may report an error for a table that is updated while it runs\&. However, because
+\fBmyisamchk\fR
+does not change the table in describe mode, there is no risk of destroying data\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBmyisamchk \-dv \fR\fB\fItbl_name\fR\fR
+.sp
+Adding
+\fB\-v\fR
+runs
+\fBmyisamchk\fR
+in verbose mode so that it produces more information about the table\&. Adding
+\fB\-v\fR
+a second time produces even more information\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBmyisamchk \-eis \fR\fB\fItbl_name\fR\fR
+.sp
+Shows only the most important information from a table\&. This operation is slow because it must read the entire table\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fBmyisamchk \-eiv \fR\fB\fItbl_name\fR\fR
+.sp
+This is like
+\fB\-eis\fR, but tells you what is being done\&.
+.RE
+.PP
+The
+\fItbl_name\fR
+argument can be either the name of a
+MyISAM
+table or the name of its index file, as described in
+\fBmyisamchk\fR(1)\&. Multiple
+\fItbl_name\fR
+arguments can be given\&.
+.PP
+Suppose that a table named
+person
+has the following structure\&. (The
+MAX_ROWS
+table option is included so that in the example output from
+\fBmyisamchk\fR
+shown later, some values are smaller and fit the output format more easily\&.)
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE person
+(
+ id INT NOT NULL AUTO_INCREMENT,
+ last_name VARCHAR(20) NOT NULL,
+ first_name VARCHAR(20) NOT NULL,
+ birth DATE,
+ death DATE,
+ PRIMARY KEY (id),
+ INDEX (last_name, first_name),
+ INDEX (birth)
+) MAX_ROWS = 1000000;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Suppose also that the table has these data and index file sizes:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\-rw\-rw\-\-\-\- 1 mysql mysql 9347072 Aug 19 11:47 person\&.MYD
+\-rw\-rw\-\-\-\- 1 mysql mysql 6066176 Aug 19 11:47 person\&.MYI
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Example of
+\fBmyisamchk \-dvv\fR
+output:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+MyISAM file: person
+Record format: Packed
+Character set: latin1_swedish_ci (8)
+File\-version: 1
+Creation time: 2009\-08\-19 16:47:41
+Recover time: 2009\-08\-19 16:47:56
+Status: checked,analyzed,optimized keys
+Auto increment key: 1 Last value: 306688
+Data records: 306688 Deleted blocks: 0
+Datafile parts: 306688 Deleted data: 0
+Datafile pointer (bytes): 4 Keyfile pointer (bytes): 3
+Datafile length: 9347072 Keyfile length: 6066176
+Max datafile length: 4294967294 Max keyfile length: 17179868159
+Recordlength: 54
+table description:
+Key Start Len Index Type Rec/key Root Blocksize
+1 2 4 unique long 1 99328 1024
+2 6 20 multip\&. varchar prefix 512 3563520 1024
+ 27 20 varchar 512
+3 48 3 multip\&. uint24 NULL 306688 6065152 1024
+Field Start Length Nullpos Nullbit Type
+1 1 1
+2 2 4 no zeros
+3 6 21 varchar
+4 27 21 varchar
+5 48 3 1 1 no zeros
+6 51 3 1 2 no zeros
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Explanations for the types of information
+\fBmyisamchk\fR
+produces are given here\&.
+\(lqKeyfile\(rq
+refers to the index file\&.
+\(lqRecord\(rq
+and
+\(lqrow\(rq
+are synonymous, as are
+\(lqfield\(rq
+and
+\(lqcolumn\&.\(rq
+.PP
+The initial part of the table description contains these values:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+MyISAM file
+.sp
+Name of the
+MyISAM
+(index) file\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Record format
+.sp
+The format used to store table rows\&. The preceding examples use
+Fixed length\&. Other possible values are
+Compressed
+and
+Packed\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Chararacter set
+.sp
+The table default character set\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+File\-version
+.sp
+Version of
+MyISAM
+format\&. Currently always 1\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Creation time
+.sp
+When the data file was created\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Recover time
+.sp
+When the index/data file was last reconstructed\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Status
+.sp
+Table status flags\&. Possible values are
+crashed,
+open,
+changed,
+analyzed,
+optimized keys, and
+sorted index pages\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Auto increment key,
+Last value
+.sp
+The key number associated the table\'s
+AUTO_INCREMENT
+column, and the most recently generated value for this column\&. These fields do not appear if there is no such column\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Data records
+.sp
+The number of rows in the table\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Deleted blocks
+.sp
+How many deleted blocks still have reserved space\&. You can optimize your table to minimize this space\&. See
+Section\ \&6.4.4, \(lqTable Optimization\(rq\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Datafile parts
+.sp
+For dynamic\-row format, this indicates how many data blocks there are\&. For an optimized table without fragmented rows, this is the same as
+Data records\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Deleted data
+.sp
+How many bytes of unreclaimed deleted data there are\&. You can optimize your table to minimize this space\&. See
+Section\ \&6.4.4, \(lqTable Optimization\(rq\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Datafile pointer
+.sp
+The size of the data file pointer, in bytes\&. It is usually 2, 3, 4, or 5 bytes\&. Most tables manage with 2 bytes, but this cannot be controlled from MySQL yet\&. For fixed tables, this is a row address\&. For dynamic tables, this is a byte address\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Keyfile pointer
+.sp
+The size of the index file pointer, in bytes\&. It is usually 1, 2, or 3 bytes\&. Most tables manage with 2 bytes, but this is calculated automatically by MySQL\&. It is always a block address\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Max datafile length
+.sp
+How long the table data file can become, in bytes\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Max keyfile length
+.sp
+How long the table index file can become, in bytes\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Recordlength
+.sp
+How much space each row takes, in bytes\&.
+.RE
+.PP
+The
+table description
+part of the output includes a list of all keys in the table\&. For each key,
+\fBmyisamchk\fR
+displays some low\-level information:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Key
+.sp
+This key\'s number\&. This value is shown only for the first column of the key\&. If this value is missing, the line corresponds to the second or later column of a multiple\-column key\&. For the table shown in the example, there are two
+table description
+lines for the second index\&. This indicates that it is a multiple\-part index with two parts\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Start
+.sp
+Where in the row this portion of the index starts\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Len
+.sp
+How long this portion of the index is\&. For packed numbers, this should always be the full length of the column\&. For strings, it may be shorter than the full length of the indexed column, because you can index a prefix of a string column\&. The total length of a multiple\-part key is the sum of the
+Len
+values for all key parts\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Index
+.sp
+Whether a key value can exist multiple times in the index\&. Possible values are
+unique
+or
+multip\&.
+(multiple)\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Type
+.sp
+What data type this portion of the index has\&. This is a
+MyISAM
+data type with the possible values
+packed,
+stripped, or
+empty\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Root
+.sp
+Address of the root index block\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Blocksize
+.sp
+The size of each index block\&. By default this is 1024, but the value may be changed at compile time when MySQL is built from source\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Rec/key
+.sp
+This is a statistical value used by the optimizer\&. It tells how many rows there are per value for this index\&. A unique index always has a value of 1\&. This may be updated after a table is loaded (or greatly changed) with
+\fBmyisamchk \-a\fR\&. If this is not updated at all, a default value of 30 is given\&.
+.RE
+.PP
+The last part of the output provides information about each column:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Field
+.sp
+The column number\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Start
+.sp
+The byte position of the column within table rows\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Length
+.sp
+The length of the column in bytes\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Nullpos,
+Nullbit
+.sp
+For columns that can be
+NULL,
+MyISAM
+stores
+NULL
+values as a flag in a byte\&. Depending on how many nullable columns there are, there can be one or more bytes used for this purpose\&. The
+Nullpos
+and
+Nullbit
+values, if nonempty, indicate which byte and bit contains that flag indicating whether the column is
+NULL\&.
+.sp
+The position and number of bytes used to store
+NULL
+flags is shown in the line for field 1\&. This is why there are six
+Field
+lines for the
+person
+table even though it has only five columns\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Type
+.sp
+The data type\&. The value may contain any of the following descriptors:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+constant
+.sp
+All rows have the same value\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+no endspace
+.sp
+Do not store endspace\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+no endspace, not_always
+.sp
+Do not store endspace and do not do endspace compression for all values\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+no endspace, no empty
+.sp
+Do not store endspace\&. Do not store empty values\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+table\-lookup
+.sp
+The column was converted to an
+ENUM\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+zerofill(\fIN\fR)
+.sp
+The most significant
+\fIN\fR
+bytes in the value are always 0 and are not stored\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+no zeros
+.sp
+Do not store zeros\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+always zero
+.sp
+Zero values are stored using one bit\&.
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Huff tree
+.sp
+The number of the Huffman tree associated with the column\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Bits
+.sp
+The number of bits used in the Huffman tree\&.
+.RE
+.PP
+The
+Huff tree
+and
+Bits
+fields are displayed if the table has been compressed with
+\fBmyisampack\fR\&. See
+\fBmyisampack\fR(1), for an example of this information\&.
+.PP
+Example of
+\fBmyisamchk \-eiv\fR
+output:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+Checking MyISAM file: person
+Data records: 306688 Deleted blocks: 0
+\- check file\-size
+\- check record delete\-chain
+No recordlinks
+\- check key delete\-chain
+block_size 1024:
+\- check index reference
+\- check data record references index: 1
+Key: 1: Keyblocks used: 98% Packed: 0% Max levels: 3
+\- check data record references index: 2
+Key: 2: Keyblocks used: 99% Packed: 97% Max levels: 3
+\- check data record references index: 3
+Key: 3: Keyblocks used: 98% Packed: \-14% Max levels: 3
+Total: Keyblocks used: 98% Packed: 89%
+\- check records and index references
+\fI*** LOTS OF ROW NUMBERS DELETED ***\fR
+Records: 306688 M\&.recordlength: 25 Packed: 83%
+Recordspace used: 97% Empty space: 2% Blocks/Record: 1\&.00
+Record blocks: 306688 Delete blocks: 0
+Record data: 7934464 Deleted data: 0
+Lost space: 256512 Linkdata: 1156096
+User time 43\&.08, System time 1\&.68
+Maximum resident set size 0, Integral resident set size 0
+Non\-physical pagefaults 0, Physical pagefaults 0, Swaps 0
+Blocks in 0 out 7, Messages in 0 out 0, Signals 0
+Voluntary context switches 0, Involuntary context switches 0
+Maximum memory usage: 1046926 bytes (1023k)
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+\fBmyisamchk \-eiv\fR
+output includes the following information:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Data records
+.sp
+The number of rows in the table\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Deleted blocks
+.sp
+How many deleted blocks still have reserved space\&. You can optimize your table to minimize this space\&. See
+Section\ \&6.4.4, \(lqTable Optimization\(rq\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Key
+.sp
+The key number\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Keyblocks used
+.sp
+What percentage of the keyblocks are used\&. When a table has just been reorganized with
+\fBmyisamchk\fR, the values are very high (very near theoretical maximum)\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Packed
+.sp
+MySQL tries to pack key values that have a common suffix\&. This can only be used for indexes on
+CHAR
+and
+VARCHAR
+columns\&. For long indexed strings that have similar leftmost parts, this can significantly reduce the space used\&. In the preceding example, the second key is 40 bytes long and a 97% reduction in space is achieved\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Max levels
+.sp
+How deep the B\-tree for this key is\&. Large tables with long key values get high values\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Records
+.sp
+How many rows are in the table\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+M\&.recordlength
+.sp
+The average row length\&. This is the exact row length for tables with fixed\-length rows, because all rows have the same length\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Packed
+.sp
+MySQL strips spaces from the end of strings\&. The
+Packed
+value indicates the percentage of savings achieved by doing this\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Recordspace used
+.sp
+What percentage of the data file is used\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Empty space
+.sp
+What percentage of the data file is unused\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Blocks/Record
+.sp
+Average number of blocks per row (that is, how many links a fragmented row is composed of)\&. This is always 1\&.0 for fixed\-format tables\&. This value should stay as close to 1\&.0 as possible\&. If it gets too large, you can reorganize the table\&. See
+Section\ \&6.4.4, \(lqTable Optimization\(rq\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Recordblocks
+.sp
+How many blocks (links) are used\&. For fixed\-format tables, this is the same as the number of rows\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Deleteblocks
+.sp
+How many blocks (links) are deleted\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Recorddata
+.sp
+How many bytes in the data file are used\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Deleted data
+.sp
+How many bytes in the data file are deleted (unused)\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Lost space
+.sp
+If a row is updated to a shorter length, some space is lost\&. This is the sum of all such losses, in bytes\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Linkdata
+.sp
+When the dynamic table format is used, row fragments are linked with pointers (4 to 7 bytes each)\&.
+Linkdata
+is the sum of the amount of storage used by all such pointers\&.
+.RE
.SH "MYISAMCHK MEMORY USAGE"
.\" memory usage: myisamchk
.PP
@@ -1259,8 +2336,10 @@ to operate faster\&. For example, if you have more than 32MB RAM, you could use
.RS 4
.\}
.nf
-shell> \fBmyisamchk \-\-sort_buffer_size=16M \-\-key_buffer_size=16M \e\fR
- \fB\-\-read_buffer_size=1M \-\-write_buffer_size=1M \&.\&.\&.\fR
+shell> \fBmyisamchk \-\-sort_buffer_size=16M \e\fR
+ \fB\-\-key_buffer_size=16M \e\fR
+ \fB\-\-read_buffer_size=1M \e\fR
+ \fB\-\-write_buffer_size=1M \&.\&.\&.\fR
.fi
.if n \{\
.RE
@@ -1275,13 +2354,13 @@ Be aware that
uses temporary files in
TMPDIR\&. If
TMPDIR
-points to a memory file system, you may easily get out of memory errors\&. If this happens, run
+points to a memory file system, out of memory errors can easily occur\&. If this happens, run
\fBmyisamchk\fR
with the
\fB\-\-tmpdir=\fR\fB\fIpath\fR\fR
-option to specify some directory located on a file system that has more space\&.
+option to specify a directory located on a file system that has more space\&.
.PP
-When repairing,
+When performing repair operations,
\fBmyisamchk\fR
also needs a lot of disk space:
.sp
@@ -1293,7 +2372,7 @@ also needs a lot of disk space:
.sp -1
.IP \(bu 2.3
.\}
-Double the size of the data file (the original file and a copy)\&. This space is not needed if you do a repair with
+Twice the size of the data file (the original file and a copy)\&. This space is not needed if you do a repair with
\fB\-\-quick\fR; in this case, only the index file is re\-created\&.
\fIThis space must be available on the same file system as the original data file\fR, as the copy is created in the same directory as the original\&.
.RE
@@ -1322,7 +2401,10 @@ When using
or
\fB\-\-sort\-recover\fR
(but not when using
-\fB\-\-safe\-recover\fR), you need space for a sort buffer\&. The following formula yields the amount of space required:
+\fB\-\-safe\-recover\fR), you need space on disk for sorting\&. This space is allocated in the temporary directory (specified by
+TMPDIR
+or
+\fB\-\-tmpdir=\fR\fB\fIpath\fR\fR)\&. The following formula yields the amount of space required:
.sp
.if n \{\
.RS 4
@@ -1335,12 +2417,27 @@ or
.\}
.sp
You can check the length of the keys and the
-row_pointer_length
+\fIrow_pointer_length\fR
with
-\fBmyisamchk \-dv \fR\fB\fItbl_name\fR\fR\&. This space is allocated in the temporary directory (specified by
-TMPDIR
-or
-\fB\-\-tmpdir=\fR\fB\fIpath\fR\fR)\&.
+\fBmyisamchk \-dv \fR\fB\fItbl_name\fR\fR
+(see
+the section called \(lqMYISAMCHK TABLE INFORMATION\(rq)\&. The
+\fIrow_pointer_length\fR
+and
+\fInumber_of_rows\fR
+values are the
+Datafile pointer
+and
+Data records
+values in the table description\&. To determine the
+\fIlargest_key\fR
+value, check the
+Key
+lines in the table description\&. The
+Len
+column indicates the number of bytes for each key part\&. For a multiple\-column index, the key size is the sum of the
+Len
+values for all key parts\&.
.RE
.PP
If you have a problem with disk space during repair, you can try
diff --git a/man/myisamlog.1 b/man/myisamlog.1
index 74f1134620a..825072e581e 100644
--- a/man/myisamlog.1
+++ b/man/myisamlog.1
@@ -2,12 +2,12 @@
.\" Title: \fBmyisamlog\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYISAMLOG\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYISAMLOG\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/myisampack.1 b/man/myisampack.1
index 17f96eb4f92..e1fdc5bfc8d 100644
--- a/man/myisampack.1
+++ b/man/myisampack.1
@@ -2,12 +2,12 @@
.\" Title: \fBmyisampack\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYISAMPACK\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYISAMPACK\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -652,9 +652,11 @@ After join
The number of distinct Huffman trees left after joining trees to save some header space\&.
.RE
.PP
-After a table has been compressed,
+After a table has been compressed, the
+Field
+lines displayed by
\fBmyisamchk \-dvv\fR
-prints additional information about each column:
+include additional information about each column:
.sp
.RS 4
.ie n \{\
diff --git a/man/mysql-stress-test.pl.1 b/man/mysql-stress-test.pl.1
index 3be857f1b45..298870b112d 100644
--- a/man/mysql-stress-test.pl.1
+++ b/man/mysql-stress-test.pl.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql-stress-test.pl\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/08/2009
+.\" Date: 10/29/2009
.\" Manual: MySQL Database System
.\" Source: MySQL
.\" Language: English
.\"
-.TH "\FBMYSQL\-STRESS\-TE" "1" "08/08/2009" "MySQL" "MySQL Database System"
+.TH "\FBMYSQL\-STRESS\-TE" "1" "10/29/2009" "MySQL" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysql-test-run.pl.1 b/man/mysql-test-run.pl.1
index 9961ed70427..cd8fec1d287 100644
--- a/man/mysql-test-run.pl.1
+++ b/man/mysql-test-run.pl.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql-test-run.pl\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/08/2009
+.\" Date: 10/29/2009
.\" Manual: MySQL Database System
.\" Source: MySQL
.\" Language: English
.\"
-.TH "\FBMYSQL\-TEST\-RUN\" "1" "08/08/2009" "MySQL" "MySQL Database System"
+.TH "\FBMYSQL\-TEST\-RUN\" "1" "10/29/2009" "MySQL" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -700,6 +700,9 @@ Specify a file that contains a list of test cases that should be displayed with
code rather than
[ fail ]
if they fail\&. This option was added in MySQL 5\&.1\&.33/6\&.0\&.11\&.
+.sp
+For an example of a file that might be specified via this option, see
+mysql\-test/collections/default\&.experimental\&.
.RE
.sp
.RS 4
@@ -1132,6 +1135,26 @@ not to generate a timing file\&.
.sp -1
.IP \(bu 2.3
.\}
+.\" mysql-test-run.pl: parallel option
+.\" parallel option: mysql-test-run.pl
+\fB\-\-parallel={\fR\fB\fIN\fR\fR\fB|auto}\fR
+.sp
+Run tests using
+\fIN\fR
+parallel threads\&. By default, 1 thread is used\&. Use
+\fB\-\-parallel=auto\fR
+for auto\-setting of
+\fIN\fR\&. This option was added in MySQL 5\&.1\&.36\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
.\" mysql-test-run.pl: ps-protocol option
.\" ps-protocol option: mysql-test-run.pl
\fB\-\-ps\-protocol\fR
diff --git a/man/mysql.1 b/man/mysql.1
index 1b13f0d3bcb..50e92795c18 100644
--- a/man/mysql.1
+++ b/man/mysql.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQL\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQL\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -334,8 +334,18 @@ to display result set metadata\&.
.sp
Use
\fIcharset_name\fR
-as the default character set\&. See
-Section\ \&9.2, \(lqThe Character Set Used for Data and Sorting\(rq\&.
+as the default character set for the client and connection\&.
+.sp
+A common issue that can occur when the operating system uses
+utf8
+or another multi\-byte character set is that output from the
+\fBmysql\fR
+client is formatted incorrectly, due to the fact that the MySQL client uses the
+latin1
+character set by default\&. You can usually fix such issues by using this option to force the client to use the system character set instead\&.
+.sp
+See
+Section\ \&9.2, \(lqThe Character Set Used for Data and Sorting\(rq, for more information\&.
.RE
.sp
.RS 4
@@ -648,7 +658,7 @@ PAGER
environment variable\&. Valid pagers are
\fBless\fR,
\fBmore\fR,
-\fBcat [> filename]\fR, and so forth\&. This option works only on Unix\&. It does not work in batch mode\&. To disable paging, use
+\fBcat [> filename]\fR, and so forth\&. This option works only on Unix and only in interactive mode\&. To disable paging, use
\fB\-\-skip\-pager\fR\&.
the section called \(lqMYSQL COMMANDS\(rq, discusses output paging further\&.
.RE
@@ -1026,7 +1036,7 @@ Display output in table format\&. This is the default for interactive use, but c
.\" tee option: mysql
\fB\-\-tee=\fR\fB\fIfile_name\fR\fR
.sp
-Append a copy of output to the given file\&. This option does not work in batch mode\&.
+Append a copy of output to the given file\&. This option works only in interactive mode\&.
the section called \(lqMYSQL COMMANDS\(rq, discusses tee files further\&.
.RE
.sp
@@ -1523,7 +1533,7 @@ is set to something other than the default of
\(lq;\(rq, instances of that character are sent to the server without interpretation\&. However, the server itself still interprets
\(lq;\(rq
as a statement delimiter and processes statements accordingly\&. This behavior on the server side comes into play for multiple\-statement execution (see
-Section\ \&21.10.12, \(lqC API Support for Multiple Statement Execution\(rq), and for parsing the body of stored procedures and functions, triggers, and events (see
+Section\ \&21.9.12, \(lqC API Support for Multiple Statement Execution\(rq), and for parsing the body of stored procedures and functions, triggers, and events (see
Section\ \&19.1, \(lqDefining Stored Programs\(rq)\&.
.RE
.sp
@@ -1680,7 +1690,7 @@ option when you invoke
\fBmysql\fR
checks the value of the
PAGER
-environment variable and sets the pager to that\&.
+environment variable and sets the pager to that\&. Pager functionality works only in interactive mode\&.
.sp
Output paging can be enabled interactively with the
\fBpager\fR
@@ -1853,7 +1863,7 @@ By using the
option when you invoke
\fBmysql\fR, you can log statements and their output\&. All the data displayed on the screen is appended into a given file\&. This can be very useful for debugging purposes also\&.
\fBmysql\fR
-flushes results to the file after each statement, just before it prints its next prompt\&.
+flushes results to the file after each statement, just before it prints its next prompt\&. Tee functionality works only in interactive mode\&.
.sp
You can enable this feature interactively with the
\fBtee\fR
@@ -2334,7 +2344,7 @@ prompt=(\e\eu@\e\eh) [\e\ed]>\e\e_
.sp
In this example, note that the backslashes are doubled\&. If you set the prompt using the
prompt
-option in an option file, it is advisable to double the backslashes when using the special prompt options\&. There is some overlap in the set of allowable prompt options and the set of special escape sequences that are recognized in option files\&. (These sequences are listed in
+option in an option file, it is advisable to double the backslashes when using the special prompt options\&. There is some overlap in the set of allowable prompt options and the set of special escape sequences that are recognized in option files\&. (The rules for escape sequences in option files are listed in
Section\ \&4.2.3.3, \(lqUsing Option Files\(rq\&.) The overlap may cause you problems if you use single backslashes\&. For example,
\es
is interpreted as a space rather than as the current seconds value\&. The following example shows how to define a prompt within an option file to include the current time in
@@ -2586,6 +2596,12 @@ SELECT \'<info_to_display>\' AS \' \';
The statement shown outputs
<info_to_display>\&.
.PP
+You can also invoke
+\fBmysql\fR
+with the
+\fB\-\-verbose\fR
+option, which causes each statement to be displayed before the result that it produces\&.
+.PP
As of MySQL 5\&.1\&.23,
\fBmysql\fR
ignores Unicode byte order mark (BOM) characters at the beginning of input files\&. Previously, it read them and sent them to the server, resulting in a syntax error\&. Presence of a BOM does not cause
@@ -2785,7 +2801,7 @@ client with the
option\&.
.PP
For more information about auto\-reconnect and its effect on state information when a reconnection occurs, see
-Section\ \&21.10.11, \(lqControlling Automatic Reconnection Behavior\(rq\&.
+Section\ \&21.9.11, \(lqControlling Automatic Reconnection Behavior\(rq\&.
.SH "COPYRIGHT"
.br
.PP
diff --git a/man/mysql.server.1 b/man/mysql.server.1
index 35c032864b9..1295f9e8584 100644
--- a/man/mysql.server.1
+++ b/man/mysql.server.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql.server\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQL\&.SERVER\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQL\&.SERVER\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -40,7 +40,7 @@ script will be installed in the
/etc/init\&.d
directory with the name
mysql\&. You need not install it manually\&. See
-Section\ \&2.4, \(lqInstalling MySQL from RPM Packages on Linux\(rq, for more information on the Linux RPM packages\&.
+Section\ \&2.6.1, \(lqInstalling MySQL from RPM Packages on Linux\(rq, for more information on the Linux RPM packages\&.
.PP
Some vendors provide RPM packages that install a startup script under a different name such as
\fBmysqld\fR\&.
@@ -48,7 +48,7 @@ Some vendors provide RPM packages that install a startup script under a differen
If you install MySQL from a source distribution or using a binary distribution format that does not install
\fBmysql\&.server\fR
automatically, you can install it manually\&. Instructions are provided in
-Section\ \&2.11.2.2, \(lqStarting and Stopping MySQL Automatically\(rq\&.
+Section\ \&2.13.1.2, \(lqStarting and Stopping MySQL Automatically\(rq\&.
.PP
\fBmysql\&.server\fR
reads options from the
diff --git a/man/mysql_client_test.1 b/man/mysql_client_test.1
index 1046c965a8b..3116a0aa037 100644
--- a/man/mysql_client_test.1
+++ b/man/mysql_client_test.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_client_test\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/08/2009
+.\" Date: 10/29/2009
.\" Manual: MySQL Database System
.\" Source: MySQL
.\" Language: English
.\"
-.TH "\FBMYSQL_CLIENT_TEST" "1" "08/08/2009" "MySQL" "MySQL Database System"
+.TH "\FBMYSQL_CLIENT_TEST" "1" "10/29/2009" "MySQL" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysql_config.1 b/man/mysql_config.1
index a52660576ff..c887be93998 100644
--- a/man/mysql_config.1
+++ b/man/mysql_config.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_config\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQL_CONFIG\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQL_CONFIG\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysql_convert_table_format.1 b/man/mysql_convert_table_format.1
index d55169d0abb..396c0702426 100644
--- a/man/mysql_convert_table_format.1
+++ b/man/mysql_convert_table_format.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_convert_table_format\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQL_CONVERT_TAB" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQL_CONVERT_TAB" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysql_find_rows.1 b/man/mysql_find_rows.1
index 80f1f291d40..81d88def92f 100644
--- a/man/mysql_find_rows.1
+++ b/man/mysql_find_rows.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_find_rows\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQL_FIND_ROWS\F" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQL_FIND_ROWS\F" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysql_fix_extensions.1 b/man/mysql_fix_extensions.1
index 51d140da033..82482e98f4a 100644
--- a/man/mysql_fix_extensions.1
+++ b/man/mysql_fix_extensions.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_fix_extensions\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQL_FIX_EXTENSI" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQL_FIX_EXTENSI" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysql_fix_privilege_tables.1 b/man/mysql_fix_privilege_tables.1
index b85cc5f0568..cd7c670afa2 100644
--- a/man/mysql_fix_privilege_tables.1
+++ b/man/mysql_fix_privilege_tables.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_fix_privilege_tables\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQL_FIX_PRIVILE" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQL_FIX_PRIVILE" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysql_install_db.1 b/man/mysql_install_db.1
index d5016b86834..d9c8981400a 100644
--- a/man/mysql_install_db.1
+++ b/man/mysql_install_db.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_install_db\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQL_INSTALL_DB\" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQL_INSTALL_DB\" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -81,7 +81,7 @@ with the
and
\fB\-\-skip\-grant\-tables\fR
options (see
-Section\ \&2.10.2, \(lqTypical configure Options\(rq)\&. If MySQL was configured with the
+Section\ \&2.3.2, \(lqTypical configure Options\(rq)\&. If MySQL was configured with the
\fB\-\-disable\-grant\-options\fR
option,
\fB\-\-bootstrap\fR
diff --git a/man/mysql_secure_installation.1 b/man/mysql_secure_installation.1
index 2e573c0e394..28ecad7d2cb 100644
--- a/man/mysql_secure_installation.1
+++ b/man/mysql_secure_installation.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_secure_installation\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQL_SECURE_INST" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQL_SECURE_INST" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysql_setpermission.1 b/man/mysql_setpermission.1
index 77a890d04d3..2dee4ca208f 100644
--- a/man/mysql_setpermission.1
+++ b/man/mysql_setpermission.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_setpermission\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQL_SETPERMISSI" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQL_SETPERMISSI" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysql_tzinfo_to_sql.1 b/man/mysql_tzinfo_to_sql.1
index 3bf86f4a75b..a32a3512b5b 100644
--- a/man/mysql_tzinfo_to_sql.1
+++ b/man/mysql_tzinfo_to_sql.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_tzinfo_to_sql\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQL_TZINFO_TO_S" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQL_TZINFO_TO_S" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysql_upgrade.1 b/man/mysql_upgrade.1
index 3bca120df32..b1b418a3131 100644
--- a/man/mysql_upgrade.1
+++ b/man/mysql_upgrade.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_upgrade\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQL_UPGRADE\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQL_UPGRADE\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -41,7 +41,7 @@ script, which should no longer be used\&.
If a table is found to have a possible incompatibility,
\fBmysql_upgrade\fR
performs a table check\&. If any problems are found, a table repair is attempted\&. If the table cannot be repaired, see
-Section\ \&2.12.4, \(lqRebuilding or Repairing Tables or Indexes\(rq
+Section\ \&2.4.4, \(lqRebuilding or Repairing Tables or Indexes\(rq
for manual table repair strategies\&.
.if n \{\
.sp
@@ -59,11 +59,11 @@ for manual table repair strategies\&.
You should always back up your current MySQL installation
\fIbefore\fR
performing an upgrade\&. See
-Section\ \&6.1, \(lqDatabase Backups\(rq\&.
+Section\ \&6.1, \(lqDatabase Backup Methods\(rq\&.
.PP
Some upgrade incompatibilities may require special handling before you upgrade your MySQL installation and run
\fBmysql_upgrade\fR\&. See
-Section\ \&2.12.1, \(lqUpgrading MySQL\(rq, for instructions on determining whether any such incompatibilities apply to your installation and how to handle them\&.
+Section\ \&2.4.1, \(lqUpgrading MySQL\(rq, for instructions on determining whether any such incompatibilities apply to your installation and how to handle them\&.
.sp .5v
.RE
.PP
@@ -189,7 +189,7 @@ If you install MySQL from RPM packages on Linux, you must install the server and
\fBmysql_upgrade\fR
is included in the server RPM but requires the client RPM because the latter includes
\fBmysqlcheck\fR\&. (See
-Section\ \&2.4, \(lqInstalling MySQL from RPM Packages on Linux\(rq\&.)
+Section\ \&2.6.1, \(lqInstalling MySQL from RPM Packages on Linux\(rq\&.)
.PP
In MySQL 5\&.1\&.7,
\fBmysql_upgrade \fR
@@ -352,6 +352,26 @@ root\&.
.sp
Verbose mode\&. Print more information about what the program does\&.
.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+.\" mysql_upgrade: write-binlog option
+.\" write-binlog option: mysql_upgrade
+\fB\-\-write\-binlog\fR
+.sp
+Cause binary logging to be enabled while
+\fBmysql_upgrade\fR
+runs\&. This is the default behavior; to disable binary logging during the upgrade, use the inverse of this option (that is, start the program with
+\fB\-\-skip\-write\-binlog\fR)\&.
+.sp
+This option was introduced in MySQL 5\&.1\&.40\&.
+.RE
.SH "COPYRIGHT"
.br
.PP
diff --git a/man/mysql_waitpid.1 b/man/mysql_waitpid.1
index 181da53314a..a0a7e0d0445 100644
--- a/man/mysql_waitpid.1
+++ b/man/mysql_waitpid.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_waitpid\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQL_WAITPID\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQL_WAITPID\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysql_zap.1 b/man/mysql_zap.1
index b92b8436c6f..26c3151def5 100644
--- a/man/mysql_zap.1
+++ b/man/mysql_zap.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysql_zap\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQL_ZAP\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQL_ZAP\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysqlaccess.1 b/man/mysqlaccess.1
index 211f99916af..bbd57f28f08 100644
--- a/man/mysqlaccess.1
+++ b/man/mysqlaccess.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqlaccess\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQLACCESS\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQLACCESS\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysqladmin.1 b/man/mysqladmin.1
index e1e43753a86..445beb30364 100644
--- a/man/mysqladmin.1
+++ b/man/mysqladmin.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqladmin\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQLADMIN\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQLADMIN\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysqlbinlog.1 b/man/mysqlbinlog.1
index 66861179bf4..f8a9ecaaa9c 100644
--- a/man/mysqlbinlog.1
+++ b/man/mysqlbinlog.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqlbinlog\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQLBINLOG\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQLBINLOG\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -855,7 +855,7 @@ You can pipe the output of
into the
\fBmysql\fR
client to execute the statements contained in the binary log\&. This is used to recover from a crash when you have an old backup (see
-Section\ \&6.1, \(lqDatabase Backups\(rq)\&. For example:
+Section\ \&6.1, \(lqDatabase Backup Methods\(rq)\&. For example:
.sp
.if n \{\
.RS 4
diff --git a/man/mysqlbug.1 b/man/mysqlbug.1
index bfe9173310c..099111bb19c 100644
--- a/man/mysqlbug.1
+++ b/man/mysqlbug.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqlbug\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQLBUG\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQLBUG\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysqlcheck.1 b/man/mysqlcheck.1
index 96b38c2090f..fb92e1c3c95 100644
--- a/man/mysqlcheck.1
+++ b/man/mysqlcheck.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqlcheck\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQLCHECK\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQLCHECK\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -34,7 +34,14 @@ The
\fBmysqlcheck\fR
client performs table maintenance: It checks, repairs, optimizes, or analyzes tables\&.
.PP
-Each table is locked and therefore unavailable to other sessions while it is being processed\&. Table maintenance operations can be time\-consuming, particularly for large tables\&. If you use the
+Each table is locked and therefore unavailable to other sessions while it is being processed, although for check operations, the table is locked with a
+READ
+lock only (see
+Section\ \&12.4.5, \(lqLOCK TABLES and UNLOCK TABLES Syntax\(rq, for more information about
+READ
+and
+WRITE
+locks)\&. Table maintenance operations can be time\-consuming, particularly for large tables\&. If you use the
\fB\-\-databases\fR
or
\fB\-\-all\-databases\fR
@@ -94,7 +101,7 @@ note : The storage engine for the table doesn\'t support check
If
\fBmysqlcheck\fR
is unable to repair a table, see
-Section\ \&2.12.4, \(lqRebuilding or Repairing Tables or Indexes\(rq
+Section\ \&2.4.4, \(lqRebuilding or Repairing Tables or Indexes\(rq
for manual table repair strategies\&. This will be the case, for example, for
InnoDB
tables, which can be checked with
diff --git a/man/mysqld.8 b/man/mysqld.8
index 1fbd435bc4f..f72c4122dfb 100644
--- a/man/mysqld.8
+++ b/man/mysqld.8
@@ -2,12 +2,12 @@
.\" Title: \fBmysqld\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQLD\FR" "8" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQLD\FR" "8" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysqld_multi.1 b/man/mysqld_multi.1
index 192eda1b4a4..c941e9f3b2a 100644
--- a/man/mysqld_multi.1
+++ b/man/mysqld_multi.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqld_multi\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQLD_MULTI\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQLD_MULTI\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -51,7 +51,7 @@ to specify which servers you want to start, stop, or obtain a status report for\
[mysqld]
group used for starting
\fBmysqld\fR\&. (See, for example,
-Section\ \&2.11.2.2, \(lqStarting and Stopping MySQL Automatically\(rq\&.) However, when using multiple servers, it is necessary that each one use its own value for options such as the Unix socket file and TCP/IP port number\&. For more information on which options must be unique per server in a multiple\-server environment, see
+Section\ \&2.13.1.2, \(lqStarting and Stopping MySQL Automatically\(rq\&.) However, when using multiple servers, it is necessary that each one use its own value for options such as the Unix socket file and TCP/IP port number\&. For more information on which options must be unique per server in a multiple\-server environment, see
Section\ \&5.6, \(lqRunning Multiple MySQL Servers on the Same Machine\(rq\&.
.PP
To invoke
@@ -183,12 +183,6 @@ Otherwise, option files in the standard list of locations are read, including an
option, if one is given\&. (If the option is given multiple times, the last value is used\&.)
.RE
.PP
-Option files read are searched for
-[mysqld_multi]
-and
-[mysqld\fIN\fR]
-option groups\&.
-.PP
Before MySQL 5\&.1\&.18, the preceding options are not recognized\&. Files in the standard locations are read, and any file named by the
\fB\-\-config\-file=\fR\fB\fIfile_name\fR\fR
option, if one is given\&. A file named by
@@ -199,6 +193,39 @@ option groups, not the
[mysqld_multi]
group\&.
.PP
+Option files read are searched for
+[mysqld_multi]
+and
+[mysqld\fIN\fR]
+option groups\&. The
+[mysqld_multi]
+group can be used for options to
+\fBmysqld_multi\fR
+itself\&.
+[mysqld\fIN\fR]
+groups can be used for options passed to specific
+\fBmysqld\fR
+instances\&.
+.PP
+As of MySQL 5\&.1\&.35, the
+[mysqld]
+or
+[mysqld_safe]
+groups can be used for common options read by all instances of
+\fBmysqld\fR
+or
+\fBmysqld_safe\fR\&. You can specify a
+\fB\-\-defaults\-file=\fR\fB\fIfile_name\fR\fR
+option to use a different configuration file for that instance, in which case the
+[mysqld]
+or
+[mysqld_safe]
+groups from that file will be used for that instance\&. Before MySQL 5\&.1\&.35, some versions of
+\fBmysqld_multi\fR
+pass the
+\fB\-\-no\-defaults\fR
+options to instances, so these techniques are inapplicable\&.
+.PP
\fBmysqld_multi\fR
supports the following options:
.sp
diff --git a/man/mysqld_safe.1 b/man/mysqld_safe.1
index 6774936073a..588c2da75ef 100644
--- a/man/mysqld_safe.1
+++ b/man/mysqld_safe.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqld_safe\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQLD_SAFE\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQLD_SAFE\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysqldump.1 b/man/mysqldump.1
index 177a444714c..49ae28ddb42 100644
--- a/man/mysqldump.1
+++ b/man/mysqldump.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqldump\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQLDUMP\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQLDUMP\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -575,7 +575,7 @@ uses
utf8, and earlier versions use
latin1\&.
.sp
-This option has no effect for output data files produced by using the
+Prior to MySQL 5\&.1\&.38, this option has no effect for output data files produced by using the
\fB\-\-tab\fR
option\&. See the description for that option\&.
.RE
@@ -1232,7 +1232,8 @@ statement for the table\&.
\fB\-\-no\-set\-names\fR
.sp
This option is deprecated\&. Use
-\fB\-\-skip\-set\-charset\fR\&. instead\&.
+\fB\-\-skip\-set\-charset\fR
+instead\&.
.RE
.sp
.RS 4
@@ -1657,11 +1658,11 @@ and
\fB\-\-lines\-terminated\-by\fR
options\&.
.sp
-Column values are dumped using the
-binary
-character set and the
+As of MySQL 5\&.1\&.38, column values are written converted to the character set specified by the
\fB\-\-default\-character\-set\fR
-option is ignored\&. In effect, there is no character set conversion\&. If a table contains columns in several character sets, the output data file will as well and you may not be able to reload the file correctly\&.
+option\&. Prior to 5\&.1\&.38 or if no such option is present, values are dumped using the
+binary
+character set\&. In effect, there is no character set conversion\&. If a table contains columns in several character sets, the output data file will as well and you may not be able to reload the file correctly\&.
.if n \{\
.sp
.\}
@@ -2110,7 +2111,7 @@ InnoDB
storage engine\&.
.PP
For more information on making backups, see
-Section\ \&6.1, \(lqDatabase Backups\(rq, and
+Section\ \&6.1, \(lqDatabase Backup Methods\(rq, and
Section\ \&6.2, \(lqExample Backup and Recovery Strategy\(rq\&.
.\" mysqldump: views
.\" mysqldump: problems
diff --git a/man/mysqldumpslow.1 b/man/mysqldumpslow.1
index 0a877f8279b..1d9e3765468 100644
--- a/man/mysqldumpslow.1
+++ b/man/mysqldumpslow.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqldumpslow\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQLDUMPSLOW\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQLDUMPSLOW\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysqlhotcopy.1 b/man/mysqlhotcopy.1
index a58e7445823..81abe794b97 100644
--- a/man/mysqlhotcopy.1
+++ b/man/mysqlhotcopy.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqlhotcopy\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQLHOTCOPY\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQLHOTCOPY\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysqlimport.1 b/man/mysqlimport.1
index 82bd2887a82..65e7215d201 100644
--- a/man/mysqlimport.1
+++ b/man/mysqlimport.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqlimport\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQLIMPORT\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQLIMPORT\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysqlmanager.8 b/man/mysqlmanager.8
index 5369730b6f3..227d0206f08 100644
--- a/man/mysqlmanager.8
+++ b/man/mysqlmanager.8
@@ -2,12 +2,12 @@
.\" Title: \fBmysqlmanager\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQLMANAGER\FR" "8" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQLMANAGER\FR" "8" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -274,7 +274,8 @@ Drop all users from the password file\&. This option was added in MySQL 5\&.1\&.
.\}
.\" mysqlmanager: debug option
.\" debug option: mysqlmanager
-\fB\-\-debug=\fR\fB\fIdebug_options\fR\fR\fB, \-# \fR\fB\fIdebug_options\fR\fR
+\fB\-\-debug=\fR\fB\fIdebug_options\fR\fR,
+\fB\-# \fR\fB\fIdebug_options\fR\fR
.sp
Write a debugging log\&. A typical
\fIdebug_options\fR
diff --git a/man/mysqlshow.1 b/man/mysqlshow.1
index 426e7f3d2dc..cc9f9421ced 100644
--- a/man/mysqlshow.1
+++ b/man/mysqlshow.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqlshow\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQLSHOW\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQLSHOW\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysqlslap.1 b/man/mysqlslap.1
index dda6c6d54d4..b8373c124de 100644
--- a/man/mysqlslap.1
+++ b/man/mysqlslap.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqlslap\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBMYSQLSLAP\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBMYSQLSLAP\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/mysqltest.1 b/man/mysqltest.1
index e8ecb587399..8bfa3d5da64 100644
--- a/man/mysqltest.1
+++ b/man/mysqltest.1
@@ -2,12 +2,12 @@
.\" Title: \fBmysqltest\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/08/2009
+.\" Date: 10/29/2009
.\" Manual: MySQL Database System
.\" Source: MySQL
.\" Language: English
.\"
-.TH "\FBMYSQLTEST\FR" "1" "08/08/2009" "MySQL" "MySQL Database System"
+.TH "\FBMYSQLTEST\FR" "1" "10/29/2009" "MySQL" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/ndbd.8 b/man/ndbd.8
index 36b0e686f85..759028d324e 100644
--- a/man/ndbd.8
+++ b/man/ndbd.8
@@ -2,12 +2,12 @@
.\" Title: \fBndbd\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBNDBD\FR" "8" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBNDBD\FR" "8" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -41,8 +41,9 @@ processes cooperate in handling data\&. These processes can execute on the same
.\" command options (MySQL Cluster): ndbd
.\" MySQL Cluster: ndbd process
.PP
-The following list describes command options specific to the MySQL Cluster data node program
-\fBndbd\fR\&.
+The following table includes command options specific to the MySQL Cluster data node program
+\fBndbd\fR\&. Additional descriptions follow the table\&. For options common to all MySQL Cluster programs, see
+Section\ \&17.4.2, \(lqOptions Common to MySQL Cluster Programs\(rq\&.
.if n \{\
.sp
.\}
@@ -68,7 +69,7 @@ wherever the latter occurs in this section\&.
For options common to all
NDBCLUSTER
programs, see
-Section\ \&17.6.2, \(lqOptions Common to MySQL Cluster Programs\(rq\&.
+Section\ \&17.4.2, \(lqOptions Common to MySQL Cluster Programs\(rq\&.
.sp
.RS 4
.ie n \{\
@@ -81,9 +82,11 @@ Section\ \&17.6.2, \(lqOptions Common to MySQL Cluster Programs\(rq\&.
\fB\-\-bind\-address\fR
.TS
allbox tab(:);
-l l
-l l
-l l.
+l l s
+l l s
+l l s
+^ l l
+^ l l.
T{
\fBVersion Introduced\fR
T}:T{
@@ -95,28 +98,16 @@ T}:T{
\-\-bind\-address=name
T}
T{
-\fBPermitted Values \fR
+\ \&
T}:T{
-[\fInested\ table\fR]*
+\fBPermitted Values \fR
T}
-.TE
-.sp 1
-.sp
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.B *[nested\ table]
-.TS
-allbox tab(:);
-l l
-l l.
-T{
+:T{
\fBType\fR
T}:T{
string
T}
-T{
+:T{
\fBDefault\fR
T}:T{
T}
@@ -141,36 +132,26 @@ This option was added in MySQL 5\&.1\&.12\&.
\fB\-d\fR
.TS
allbox tab(:);
-l l
-l l.
+l l s
+l l s
+^ l l
+^ l l.
T{
\fBCommand Line Format\fR
T}:T{
\-\-daemon
T}
T{
-\fBPermitted Values \fR
+\ \&
T}:T{
-[\fInested\ table\fR]*
+\fBPermitted Values \fR
T}
-.TE
-.sp 1
-.sp
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.B *[nested\ table]
-.TS
-allbox tab(:);
-l l
-l l.
-T{
+:T{
\fBType\fR
T}:T{
boolean
T}
-T{
+:T{
\fBDefault\fR
T}:T{
TRUE
@@ -182,6 +163,12 @@ Instructs
to execute as a daemon process\&. This is the default behavior\&.
\fB\-\-nodaemon\fR
can be used to prevent the process from running as a daemon\&.
+.sp
+This option has no effect when running
+\fBndbd\fR
+or
+\fBndbmtd\fR
+on Windows platforms\&.
.RE
.sp
.RS 4
@@ -197,36 +184,26 @@ can be used to prevent the process from running as a daemon\&.
\fB\-\-initial\fR
.TS
allbox tab(:);
-l l
-l l.
+l l s
+l l s
+^ l l
+^ l l.
T{
\fBCommand Line Format\fR
T}:T{
\-\-initial
T}
T{
-\fBPermitted Values \fR
+\ \&
T}:T{
-[\fInested\ table\fR]*
+\fBPermitted Values \fR
T}
-.TE
-.sp 1
-.sp
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.B *[nested\ table]
-.TS
-allbox tab(:);
-l l
-l l.
-T{
+:T{
\fBType\fR
T}:T{
boolean
T}
-T{
+:T{
\fBDefault\fR
T}:T{
FALSE
@@ -321,9 +298,11 @@ Backup files that have already been created by the affected node
.IP \(bu 2.3
.\}
MySQL Cluster Disk Data files (see
-Section\ \&17.10, \(lqMySQL Cluster Disk Data Tables\(rq)\&.
+Section\ \&17.5.9, \(lqMySQL Cluster Disk Data Tables\(rq)\&.
.RE
.RS 4
+.sp
+This option also has no effect on recovery of data by a data node that is just starting (or restarting) from data nodes that are already running\&. This recovery of data occurs automatically, and requires no user intervention in a MySQL Cluster that is running normally\&.
.sp .5v
.RE
It is permissible to use this option when starting the cluster for the very first time (that is, before any data node files have been created); however, it is
@@ -344,9 +323,11 @@ necessary to do so\&.
\fB\-\-initial\-start\fR
.TS
allbox tab(:);
-l l
-l l
-l l.
+l l s
+l l s
+l l s
+^ l l
+^ l l.
T{
\fBVersion Introduced\fR
T}:T{
@@ -358,28 +339,16 @@ T}:T{
\-\-initial\-start
T}
T{
-\fBPermitted Values \fR
+\ \&
T}:T{
-[\fInested\ table\fR]*
+\fBPermitted Values \fR
T}
-.TE
-.sp 1
-.sp
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.B *[nested\ table]
-.TS
-allbox tab(:);
-l l
-l l.
-T{
+:T{
\fBType\fR
T}:T{
boolean
T}
-T{
+:T{
\fBDefault\fR
T}:T{
FALSE
@@ -435,9 +404,11 @@ Prior to MySQL 5\&.1\&.19, it was not possible to perform DDL operations involvi
\fB\-\-nowait\-nodes=\fR\fB\fInode_id_1\fR\fR\fB[, \fR\fB\fInode_id_2\fR\fR\fB[, \&.\&.\&.]]\fR
.TS
allbox tab(:);
-l l
-l l
-l l.
+l l s
+l l s
+l l s
+^ l l
+^ l l.
T{
\fBVersion Introduced\fR
T}:T{
@@ -449,28 +420,16 @@ T}:T{
\-\-nowait\-nodes=list
T}
T{
-\fBPermitted Values \fR
+\ \&
T}:T{
-[\fInested\ table\fR]*
+\fBPermitted Values \fR
T}
-.TE
-.sp 1
-.sp
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.B *[nested\ table]
-.TS
-allbox tab(:);
-l l
-l l.
-T{
+:T{
\fBType\fR
T}:T{
string
T}
-T{
+:T{
\fBDefault\fR
T}:T{
T}
@@ -508,36 +467,26 @@ This option was added in MySQL 5\&.1\&.9\&.
\fB\-\-nodaemon\fR
.TS
allbox tab(:);
-l l
-l l.
+l l s
+l l s
+^ l l
+^ l l.
T{
\fBCommand Line Format\fR
T}:T{
\-\-nodaemon
T}
T{
-\fBPermitted Values \fR
+\ \&
T}:T{
-[\fInested\ table\fR]*
+\fBPermitted Values \fR
T}
-.TE
-.sp 1
-.sp
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.B *[nested\ table]
-.TS
-allbox tab(:);
-l l
-l l.
-T{
+:T{
\fBType\fR
T}:T{
boolean
T}
-T{
+:T{
\fBDefault\fR
T}:T{
FALSE
@@ -549,6 +498,12 @@ Instructs
not to start as a daemon process\&. This is useful when
\fBndbd\fR
is being debugged and you want output to be redirected to the screen\&.
+.sp
+As of MySQL Cluster NDB 7\&.0\&.8, the default behavior for
+\fBndbd\fR
+and
+\fBndbmtd\fR
+on Windows is to run in the foreground, making this option unnecessary on Windows platforms\&. (\m[blue]\fBBug#45588\fR\m[]\&\s-2\u[2]\d\s+2)
.RE
.sp
.RS 4
@@ -567,36 +522,26 @@ is being debugged and you want output to be redirected to the screen\&.
\fB\-n\fR
.TS
allbox tab(:);
-l l
-l l.
+l l s
+l l s
+^ l l
+^ l l.
T{
\fBCommand Line Format\fR
T}:T{
\-\-nostart
T}
T{
-\fBPermitted Values \fR
+\ \&
T}:T{
-[\fInested\ table\fR]*
+\fBPermitted Values \fR
T}
-.TE
-.sp 1
-.sp
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.B *[nested\ table]
-.TS
-allbox tab(:);
-l l
-l l.
-T{
+:T{
\fBType\fR
T}:T{
boolean
T}
-T{
+:T{
\fBDefault\fR
T}:T{
FALSE
@@ -610,7 +555,7 @@ not to start automatically\&. When this option is used,
connects to the management server, obtains configuration data from it, and initializes communication objects\&. However, it does not actually start the execution engine until specifically requested to do so by the management server\&. This can be accomplished by issuing the proper
START
command in the management client (see
-Section\ \&17.7.2, \(lqCommands in the MySQL Cluster Management Client\(rq)\&.
+Section\ \&17.5.2, \(lqCommands in the MySQL Cluster Management Client\(rq)\&.
.RE
.\" MySQL Cluster: log files
.\" log files (MySQL Cluster)
@@ -668,7 +613,7 @@ TraceFile: ndb_2_trace\&.log\&.2
Listings of possible
\fBndbd\fR
exit codes and messages generated when a data node process shuts down prematurely can be found in
-\m[blue]\fBndbd Error Messages\fR\m[]\&\s-2\u[2]\d\s+2\&.
+\m[blue]\fBndbd Error Messages\fR\m[]\&\s-2\u[3]\d\s+2\&.
.if n \{\
.sp
.\}
@@ -784,7 +729,7 @@ shell> \fBndbd \-\-connect\-string="nodeid=2;host=ndb_mgmd\&.mysql\&.com:1186"\f
.\}
.PP
See
-Section\ \&17.3.4.3, \(lqThe MySQL Cluster Connectstring\(rq, for additional information about this issue\&.
+Section\ \&17.3.2.3, \(lqThe MySQL Cluster Connectstring\(rq, for additional information about this issue\&.
\fBndbd\fR(8), describes other options for
\fBndbd\fR\&.
.PP
@@ -810,7 +755,7 @@ process can consume up to 2 CPUs if permitted to do so\&.
For a machine with many CPUs it is possible to use several
\fBndbd\fR
processes which belong to different node groups; however, such a configuration is still considered experimental and is not supported for MySQL 5\&.1 in a production setting\&. See
-Section\ \&17.12, \(lqKnown Limitations of MySQL Cluster\(rq\&.
+Section\ \&17.1.5, \(lqKnown Limitations of MySQL Cluster\(rq\&.
.SH "COPYRIGHT"
.br
.PP
@@ -829,6 +774,11 @@ Bug#24631
\%http://bugs.mysql.com/24631
.RE
.IP " 2." 4
+Bug#45588
+.RS 4
+\%http://bugs.mysql.com/45588
+.RE
+.IP " 3." 4
ndbd Error Messages
.RS 4
\%http://dev.mysql.com/doc/ndbapi/en/ndbd-error-messages.html
diff --git a/man/ndbd_redo_log_reader.1 b/man/ndbd_redo_log_reader.1
index ad63fe0b3ee..19c9befdeda 100644
--- a/man/ndbd_redo_log_reader.1
+++ b/man/ndbd_redo_log_reader.1
@@ -2,12 +2,12 @@
.\" Title: \fBndbd_redo_log_reader\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBNDBD_REDO_LOG_REA" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBNDBD_REDO_LOG_REA" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -37,6 +37,10 @@ The C++ source files for
can be found in the directory
/storage/ndb/src/kernel/blocks/dblqh/redoLogReader\&.
.PP
+The following table includes options that are specific to the MySQL Cluster program
+\fBndbd_redo_log_reader\fR\&. Additional descriptions follow the table\&. For options common to all MySQL Cluster programs, see
+Section\ \&17.4.2, \(lqOptions Common to MySQL Cluster Programs\(rq\&.
+.PP
\fBUsage\fR:
.sp
.if n \{\
@@ -56,105 +60,83 @@ ndb_\fI#\fR_fs/D\fI#\fR/LCP/\fI#\fR/T\fI#\fRF\fI#\fR\&.Data\&. In each case, the
represents a number (not necessarily the same number)\&. For more information, see
\m[blue]\fBCluster Data Node FileSystemDir Files\fR\m[]\&\s-2\u[1]\d\s+2\&.
.PP
-\fBAdditional Options\fR:
+The name of the file to be read may be followed by one or more of the options listed here:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
.TS
allbox tab(:);
-l l
-l l.
+l l s
+l l s
+^ l l
+^ l l.
T{
\fBCommand Line Format\fR
T}:T{
\-noprint
T}
T{
-\fBPermitted Values \fR
+\ \&
T}:T{
-[\fInested\ table\fR]*
+\fBPermitted Values \fR
T}
-.TE
-.sp 1
-.sp
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.B *[nested\ table]
-.TS
-allbox tab(:);
-l l
-l l.
-T{
+:T{
\fBType\fR
T}:T{
boolean
T}
-T{
+:T{
\fBDefault\fR
T}:T{
FALSE
T}
.TE
.sp 1
+\fB\-noprint\fR: Do not print the contents of the log file\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
.TS
allbox tab(:);
-l l
-l l.
+l l s
+l l s
+^ l l
+^ l l.
T{
\fBCommand Line Format\fR
T}:T{
\-nocheck
T}
T{
-\fBPermitted Values \fR
+\ \&
T}:T{
-[\fInested\ table\fR]*
+\fBPermitted Values \fR
T}
-.TE
-.sp 1
-.sp
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.B *[nested\ table]
-.TS
-allbox tab(:);
-l l
-l l.
-T{
+:T{
\fBType\fR
T}:T{
boolean
T}
-T{
+:T{
\fBDefault\fR
T}:T{
FALSE
T}
.TE
.sp 1
-.PP
-The name of the file to be read may be followed by one or more of the options listed here:
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-\fB\-noprint\fR: Do not print the contents of the log file\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
\fB\-nocheck\fR: Do not check the log file for errors\&.
.RE
.sp
@@ -184,7 +166,7 @@ You should have received a copy of the GNU General Public License along with the
.IP " 1." 4
Cluster Data Node FileSystemDir Files
.RS 4
-\%http://dev.mysql.com/doc/ndbapi/en/ndb-internals-ndbd-filesystem.html#ndb-internals-ndbd-filesystemdir-files
+\%http://dev.mysql.com/doc/ndbapi/en/ndb-internals-ndbd-filesystemdir-files.html
.RE
.SH "SEE ALSO"
For more information, please refer to the MySQL Reference Manual,
diff --git a/man/ndbmtd.8 b/man/ndbmtd.8
index 222e0e496bf..71d49de9acd 100644
--- a/man/ndbmtd.8
+++ b/man/ndbmtd.8
@@ -2,12 +2,12 @@
.\" Title: \fBndbmtd\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBNDBMTD\FR" "8" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBNDBMTD\FR" "8" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -49,8 +49,8 @@ Command\-line options and configuration parameters used with
\fBndbd\fR
also apply to
\fBndbmtd\fR\&. For more information about these options and parameters, see
-Section\ \&17.6.3.2, \(lqProgram Options for ndbd and ndbmtd\(rq, and
-Section\ \&17.3.4.6, \(lqDefining MySQL Cluster Data Nodes\(rq, respectively\&.
+\fBndbd\fR(8), and
+Section\ \&17.3.2.6, \(lqDefining MySQL Cluster Data Nodes\(rq, respectively\&.
.PP
\fBndbmtd\fR
is also file system\-compatible with
@@ -69,25 +69,13 @@ simply by stopping the node and then starting
\fBndbd\fR
in place of the multi\-threaded binary\&. It is not necessary when switching between the two to start the data node binary using
\fB\-\-initial\fR\&.
-.if n \{\
-.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBImportant\fR
-.ps -1
-.br
.PP
-We do not currently recommend using
+Prior to MySQL Cluster NDB 7\&.0\&.6, there were known issues when using
\fBndbmtd\fR
-with MySQL Cluster Disk Data tables in production, due to known issues which we are working to fix in a future MySQL Cluster release\&. (\m[blue]\fBBug#41915\fR\m[]\&\s-2\u[1]\d\s+2,
+with MySQL Cluster Disk Data tables\&. If you wish to use multi\-threaded data nodes with disk\-based
+NDB
+tables, you should insure that you are running MySQL Cluster NDB 7\&.0\&.6 or later\&. (\m[blue]\fBBug#41915\fR\m[]\&\s-2\u[1]\d\s+2,
\m[blue]\fBBug#44915\fR\m[]\&\s-2\u[2]\d\s+2)
-.sp .5v
-.RE
.PP
Using
\fBndbmtd\fR
@@ -129,6 +117,8 @@ failures\&.
.RE
.PP
These differences are discussed in more detail in the next few paragraphs\&.
+.\" execution threads (MySQL Cluster)
+.\" MySQL Cluster: execution threads
.\" ndbmtd: MaxNoOfExecutionThreads
.\" MaxNoOfExecutionThreads: ndbmtd
.\" ndbmtd: trace files
@@ -148,7 +138,7 @@ file, it is exclusive to
and does not apply to
\fBndbd\fR\&.
.PP
-This parameter takes an integer value from 2 to 8 inclusive\&. Generally, you should set this to the number of CPU cores on the data node host, as shown in the following table:
+This parameter takes an integer value from 2 to 8 inclusive\&. Generally, you should set this parameter equal to the number of CPU cores on the data node host, as shown in the following table:
.TS
allbox tab(:);
lB lB.
diff --git a/man/perror.1 b/man/perror.1
index 0530b4e699c..5bc4f417fa6 100644
--- a/man/perror.1
+++ b/man/perror.1
@@ -2,12 +2,12 @@
.\" Title: \fBperror\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBPERROR\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBPERROR\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/replace.1 b/man/replace.1
index c7edd5ce809..eb068de8696 100644
--- a/man/replace.1
+++ b/man/replace.1
@@ -2,12 +2,12 @@
.\" Title: \fBreplace\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBREPLACE\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBREPLACE\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/resolve_stack_dump.1 b/man/resolve_stack_dump.1
index 68dd127754c..8590665281d 100644
--- a/man/resolve_stack_dump.1
+++ b/man/resolve_stack_dump.1
@@ -2,12 +2,12 @@
.\" Title: \fBresolve_stack_dump\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBRESOLVE_STACK_DUM" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBRESOLVE_STACK_DUM" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/man/resolveip.1 b/man/resolveip.1
index 5f6a84181fc..602b080ef73 100644
--- a/man/resolveip.1
+++ b/man/resolveip.1
@@ -2,12 +2,12 @@
.\" Title: \fBresolveip\fR
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: 08/12/2009
+.\" Date: 11/04/2009
.\" Manual: MySQL Database System
.\" Source: MySQL 5.1
.\" Language: English
.\"
-.TH "\FBRESOLVEIP\FR" "1" "08/12/2009" "MySQL 5\&.1" "MySQL Database System"
+.TH "\FBRESOLVEIP\FR" "1" "11/04/2009" "MySQL 5\&.1" "MySQL Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
diff --git a/mysql-test/collections/README.experimental b/mysql-test/collections/README.experimental
index 9eee2394423..2f5ee7b00ab 100644
--- a/mysql-test/collections/README.experimental
+++ b/mysql-test/collections/README.experimental
@@ -23,3 +23,10 @@ The syntax is as follows:
start with the same characters up to the last letter before the asterisk
are considered experimental:
main.a* # get rid of main.alias, main.alibaba and main.agliolio
+
+6) Optionally, the test case may be followed by one or more platform
+ qualifiers beginning with @ or @!. The test will then be considered
+ experimental only/except on that platform. Basic OS names as
+ reported by $^O in Perl, or 'windows' are supported, this includes
+ solaris, linux, windows, aix, darwin, ... Example:
+ main.alias @aix @windows # Fails on those
diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental
index 8bec38a373b..a0fa2a30a69 100644
--- a/mysql-test/collections/default.experimental
+++ b/mysql-test/collections/default.experimental
@@ -1,6 +1,45 @@
+# For easier human reading (MTR doesn't care), please keep entries
+# in alphabetical order. This also helps with merge conflict resolution.
+
+binlog.binlog_multi_engine # joro : NDB tests marked as experimental as agreed with bochklin
+
funcs_1.charset_collation_1 # depends on compile-time decisions
-binlog.binlog_tmp_table # Bug#45578: Test binlog_tmp_table fails ramdonly on PB2: Unknown table 't2'
-main.ctype_gbk_binlog # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists
-rpl.rpl_row_create_table # Bug#45576: rpl_row_create_table fails on PB2
+funcs_1.is_cml_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+funcs_1.is_columns_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+funcs_1.is_engines_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+funcs_1.is_tables_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+funcs_1.ndb* # joro : NDB tests marked as experimental as agreed with bochklin
+
+funcs_2.ndb_charset # joro : NDB tests marked as experimental as agreed with bochklin
+
+main.ctype_gbk_binlog @solaris # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists
+main.innodb-autoinc* # Bug#47809 2009-10-04 joro innodb-autoinc.test fails with valgrind errors with the innodb plugin
+main.plugin_load @solaris # Bug#42144
+
+ndb.* # joro : NDB tests marked as experimental as agreed with bochklin
+
+rpl.rpl_cross_version* # Bug #43913 2009-10-26 joro rpl_cross_version can't pass on conflicts complainig clash with --slave-load-tm
+rpl.rpl_get_master_version_and_clock* # Bug#46931 2009-08-26 alik rpl.rpl_get_master_version_and_clock fails on hpux11.31
+rpl.rpl_innodb_bug28430* @solaris # Bug#46029
+rpl.rpl_row_create_table* # Bug#45576: rpl_row_create_table fails on PB2
+rpl.rpl_trigger* # Bug#47810 2009-10-04 joro rpl.rpl_trigger.test fails with valgrind errors with the innodb plugin
+
+rpl_ndb.* # joro : NDB tests marked as experimental as agreed with bochklin
rpl_ndb.rpl_ndb_log # Bug#38998
-rpl.rpl_innodb_bug28430 # Bug#46029
+
+stress.ddl_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+
+parts.ndb_dd_backuprestore # joro : NDB tests marked as experimental as agreed with bochklin
+parts.part_supported_sql_func_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+parts.partition_alter1_1_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+parts.partition_alter1_1_2_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+parts.partition_alter1_2_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+parts.partition_auto_increment_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+parts.partition_basic_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+parts.partition_engine_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+parts.partition_int_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+parts.partition_mgm_lc0_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+parts.partition_mgm_lc1_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+parts.partition_mgm_lc2_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+parts.partition_syntax_ndb # joro : NDB tests marked as experimental as agreed with bochklin
+parts.partition_value_ndb # joro : NDB tests marked as experimental as agreed with bochklin
diff --git a/mysql-test/extra/binlog_tests/binlog.test b/mysql-test/extra/binlog_tests/binlog.test
index 5d898d41a54..b819996acb0 100644
--- a/mysql-test/extra/binlog_tests/binlog.test
+++ b/mysql-test/extra/binlog_tests/binlog.test
@@ -270,3 +270,42 @@ INSERT INTO test.t1 VALUES (1), (2);
CREATE TABLE test.t2 SELECT * FROM test.t1;
USE test;
DROP TABLES t1, t2;
+
+#
+# Bug#46640
+# This test verifies if the server_id stored in the "format
+# description BINLOG statement" will override the server_id
+# of the server executing the statements.
+#
+
+connect (fresh,localhost,root,,test);
+connection fresh;
+
+RESET MASTER;
+CREATE TABLE t1 (a INT PRIMARY KEY);
+
+# Format description event, with server_id = 10;
+BINLOG '
+3u9kSA8KAAAAZgAAAGoAAAABAAQANS4xLjM1LW1hcmlhLWJldGExLWRlYnVnLWxvZwAAAAAAAAAA
+AAAAAAAAAAAAAAAAAADe72RIEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
+';
+
+# What server_id is logged for a statement? Should be our own, not the
+# one from the format description event.
+INSERT INTO t1 VALUES (1);
+
+# INSERT INTO t1 VALUES (2), with server_id=20. Check that this is logged
+# with our own server id, not the 20 from the BINLOG statement.
+BINLOG '
+3u9kSBMUAAAAKQAAAJEBAAAAABoAAAAAAAAABHRlc3QAAnQxAAEDAAA=
+3u9kSBcUAAAAIgAAALMBAAAQABoAAAAAAAEAAf/+AgAAAA==
+';
+
+# Show binlog events to check that server ids are correct.
+--replace_column 1 # 2 # 5 #
+--replace_regex /Server ver: .*, Binlog ver: .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/
+SHOW BINLOG EVENTS;
+
+DROP TABLE t1;
+disconnect fresh;
+
diff --git a/mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test b/mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test
new file mode 100644
index 00000000000..54f3c538c79
--- /dev/null
+++ b/mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test
@@ -0,0 +1,300 @@
+################################################################################
+# Let
+# - B be begin, C commit and R rollback.
+# - T a statement that accesses and changes only transactional tables, i.e.
+# T-tables
+# - N a statement that accesses and changes only non-transactional tables,
+# i.e, N-tables.
+# - M be a mixed statement, i.e. a statement that updates both T- and
+# N-tables.
+# - M* be a mixed statement that fails while updating either a T
+# or N-table.
+# - N* be a statement that fails while updating a N-table.
+#
+# In this test case, when changes are logged as rows either in the RBR or MIXED
+# modes, we check if a M* statement that happens early in a transaction is
+# written to the binary log outside the boundaries of the transaction and
+# wrapped up in a BEGIN/ROLLBACK. This is done to keep the slave consistent with
+# the master as the rollback will keep the changes on N-tables and undo them on
+# T-tables. In particular, we expect the following behavior:
+#
+# 1. B M* T C would generate in the binlog B M* R B T C.
+# 2. B M M* C would generate in the binlog B M M* C.
+# 3. B M* M* T C would generate in the binlog B M* R B M* R B T C.
+#
+# SBR is not considered in this test because a failing statement is written to
+# the binary along with the error code such that a slave executes and rolls it
+# back, thus undoing the effects on T-tables.
+#
+# Note that, in the first case, we are not preserving history from the master as
+# we are introducing a rollback that never happened. However, this seems to be
+# more acceptable than making the slave diverge. In the second case, the slave
+# will diverge as the changes on T-tables that originated from the M statement
+# are rolled back on the master but not on the slave. Unfortunately, we cannot
+# simply roll the transaction back as this would undo any uncommitted changes
+# on T-tables.
+#
+# We check two more cases. First, INSERT...SELECT* which produces the following
+# results:
+#
+# 1. B T INSERT M...SELECT* C" with an error in INSERT M...SELECT* generates in
+# the binlog the following entries: "Nothing".
+# 2. B INSERT M...SELECT* C" with an error in INSERT M...SELECT* generates in
+# the binlog the following entries: B INSERT M...SELECT* R.
+#
+# Finally, we also check if any N statement that happens early in a transaction
+# (i.e. before any T or M statement) is written to the binary log outside the
+# boundaries of the transaction. In particular, we expect the following
+# behavior:
+#
+# 1. B N N T C would generate in the binlog B N C B N C B T C.
+# 2. B N N T R would generate in the binlog B N C B N C B T R.
+# 3. B N* N* T C would generate in the binlog B N R B N R B T C.
+# 4. B N* N* T R would generate in the binlog B N R B N R B T R.
+# 5. B N N T N T C would generate in the binlog B N C B N C B T N T C.
+# 6. B N N T N T R would generate in the binlog the B N C B N C B T N T R.
+#
+# Such issues do not happen in SBR. In RBR and MBR, a full-fledged fix will be
+# pushed after the WL#2687.
+#
+# Please, remove this test case after pushing WL#2687.
+################################################################################
+
+
+--echo ###################################################################################
+--echo # CONFIGURATION
+--echo ###################################################################################
+CREATE TABLE nt_1 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
+CREATE TABLE nt_2 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
+CREATE TABLE tt_1 (a text, b int PRIMARY KEY) ENGINE = Innodb;
+CREATE TABLE tt_2 (a text, b int PRIMARY KEY) ENGINE = Innodb;
+
+DELIMITER |;
+
+CREATE TRIGGER tr_i_tt_1_to_nt_1 BEFORE INSERT ON tt_1 FOR EACH ROW
+BEGIN
+ INSERT INTO nt_1 VALUES (NEW.a, NEW.b);
+END|
+
+CREATE TRIGGER tr_i_nt_2_to_tt_2 BEFORE INSERT ON nt_2 FOR EACH ROW
+BEGIN
+ INSERT INTO tt_2 VALUES (NEW.a, NEW.b);
+END|
+
+DELIMITER ;|
+
+--echo ###################################################################################
+--echo # CHECK HISTORY IN BINLOG
+--echo ###################################################################################
+--echo
+--echo
+--echo
+--echo *** "B M* T C" with error in M* generates in the binlog the "B M* R B T C" entries
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+INSERT INTO nt_1 VALUES ("new text 1", 1);
+BEGIN;
+--error ER_DUP_ENTRY
+INSERT INTO tt_1 VALUES (USER(), 2), (USER(), 1);
+INSERT INTO tt_2 VALUES ("new text 3", 3);
+COMMIT;
+--source include/show_binlog_events.inc
+
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+INSERT INTO tt_2 VALUES ("new text 4", 4);
+BEGIN;
+--error ER_DUP_ENTRY
+INSERT INTO nt_2 VALUES (USER(), 5), (USER(), 4);
+INSERT INTO tt_2 VALUES ("new text 6", 6);
+COMMIT;
+--source include/show_binlog_events.inc
+
+--echo
+--echo
+--echo
+--echo *** "B M M* T C" with error in M* generates in the binlog the "B M M* T C" entries
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+INSERT INTO nt_1 VALUES ("new text 10", 10);
+BEGIN;
+INSERT INTO tt_1 VALUES ("new text 7", 7), ("new text 8", 8);
+--error ER_DUP_ENTRY
+INSERT INTO tt_1 VALUES (USER(), 9), (USER(), 10);
+INSERT INTO tt_2 VALUES ("new text 11", 11);
+COMMIT;
+--source include/show_binlog_events.inc
+
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+INSERT INTO tt_2 VALUES ("new text 15", 15);
+BEGIN;
+INSERT INTO nt_2 VALUES ("new text 12", 12), ("new text 13", 13);
+--error ER_DUP_ENTRY
+INSERT INTO nt_2 VALUES (USER(), 14), (USER(), 15);
+INSERT INTO tt_2 VALUES ("new text 16", 16);
+COMMIT;
+--source include/show_binlog_events.inc
+
+
+--echo
+--echo
+--echo
+--echo *** "B M* M* T C" with error in M* generates in the binlog the "B M* R B M* R B T C" entries
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+INSERT INTO nt_1 VALUES ("new text 18", 18);
+INSERT INTO nt_1 VALUES ("new text 20", 20);
+BEGIN;
+--error ER_DUP_ENTRY
+INSERT INTO tt_1 VALUES (USER(), 17), (USER(), 18);
+--error ER_DUP_ENTRY
+INSERT INTO tt_1 VALUES (USER(), 19), (USER(), 20);
+INSERT INTO tt_2 VALUES ("new text 21", 21);
+COMMIT;
+--source include/show_binlog_events.inc
+
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+INSERT INTO tt_2 VALUES ("new text 23", 23);
+INSERT INTO tt_2 VALUES ("new text 25", 25);
+BEGIN;
+--error ER_DUP_ENTRY
+INSERT INTO nt_2 VALUES (USER(), 22), (USER(), 23);
+--error ER_DUP_ENTRY
+INSERT INTO nt_2 VALUES (USER(), 24), (USER(), 25);
+INSERT INTO tt_2 VALUES ("new text 26", 26);
+COMMIT;
+--source include/show_binlog_events.inc
+
+--echo
+--echo
+--echo
+--echo *** "B T INSERT M...SELECT* C" with an error in INSERT M...SELECT* generates
+--echo *** in the binlog the following entries: "Nothing".
+--echo *** There is a bug in that will be fixed after WL#2687. Please, check BUG#47175 for further details.
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+TRUNCATE TABLE nt_2;
+TRUNCATE TABLE tt_2;
+INSERT INTO tt_2 VALUES ("new text 7", 7);
+BEGIN;
+INSERT INTO tt_2 VALUES ("new text 27", 27);
+--error ER_DUP_ENTRY
+INSERT INTO nt_2(a, b) SELECT USER(), b FROM nt_1;
+INSERT INTO tt_2 VALUES ("new text 28", 28);
+ROLLBACK;
+--source include/show_binlog_events.inc
+
+--echo
+--echo
+--echo
+--echo *** "B INSERT M..SELECT* C" with an error in INSERT M...SELECT* generates
+--echo *** in the binlog the following entries: "B INSERT M..SELECT* R".
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+TRUNCATE TABLE nt_2;
+TRUNCATE TABLE tt_2;
+INSERT INTO tt_2 VALUES ("new text 7", 7);
+BEGIN;
+--error ER_DUP_ENTRY
+INSERT INTO nt_2(a, b) SELECT USER(), b FROM nt_1;
+COMMIT;
+--source include/show_binlog_events.inc
+
+--echo
+--echo
+--echo
+--echo *** "B N N T C" generates in the binlog the "B N C B N C B T C" entries
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+TRUNCATE TABLE nt_1;
+TRUNCATE TABLE tt_2;
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 1);
+INSERT INTO nt_1 VALUES (USER(), 2);
+INSERT INTO tt_2 VALUES (USER(), 3);
+COMMIT;
+--source include/show_binlog_events.inc
+
+--echo
+--echo
+--echo
+--echo *** "B N N T R" generates in the binlog the "B N C B N C B T R" entries
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 4);
+INSERT INTO nt_1 VALUES (USER(), 5);
+INSERT INTO tt_2 VALUES (USER(), 6);
+ROLLBACK;
+--source include/show_binlog_events.inc
+
+--echo
+--echo
+--echo
+--echo *** "B N* N* T C" with error in N* generates in the binlog the "B N R B N R B T C" entries
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+BEGIN;
+--error ER_DUP_ENTRY
+INSERT INTO nt_1 VALUES (USER(), 7), (USER(), 1);
+--error ER_DUP_ENTRY
+INSERT INTO nt_1 VALUES (USER(), 8), (USER(), 1);
+INSERT INTO tt_2 VALUES (USER(), 9);
+COMMIT;
+--source include/show_binlog_events.inc
+
+--echo
+--echo
+--echo
+--echo *** "B N* N* T R" with error in N* generates in the binlog the "B N R B N R B T R" entries
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+BEGIN;
+--error ER_DUP_ENTRY
+INSERT INTO nt_1 VALUES (USER(), 10), (USER(), 1);
+--error ER_DUP_ENTRY
+INSERT INTO nt_1 VALUES (USER(), 11), (USER(), 1);
+INSERT INTO tt_2 VALUES (USER(), 12);
+ROLLBACK;
+--source include/show_binlog_events.inc
+
+--echo
+--echo
+--echo
+--echo *** "B N N T N T C" generates in the binlog the "B N C B N C B T N T C" entries
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 13);
+INSERT INTO nt_1 VALUES (USER(), 14);
+INSERT INTO tt_2 VALUES (USER(), 15);
+INSERT INTO nt_1 VALUES (USER(), 16);
+INSERT INTO tt_2 VALUES (USER(), 17);
+COMMIT;
+--source include/show_binlog_events.inc
+
+--echo
+--echo
+--echo
+--echo *** "B N N T N T R" generates in the binlog the "B N C B N C B T N T R" entries
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 18);
+INSERT INTO nt_1 VALUES (USER(), 19);
+INSERT INTO tt_2 VALUES (USER(), 20);
+INSERT INTO nt_1 VALUES (USER(), 21);
+INSERT INTO tt_2 VALUES (USER(), 22);
+ROLLBACK;
+--source include/show_binlog_events.inc
+
+--echo ###################################################################################
+--echo # CLEAN
+--echo ###################################################################################
+
+DROP TABLE tt_1;
+DROP TABLE tt_2;
+DROP TABLE nt_1;
+DROP TABLE nt_2;
diff --git a/mysql-test/extra/binlog_tests/drop_temp_table.test b/mysql-test/extra/binlog_tests/drop_temp_table.test
index 7d37fca2bef..63833c10c14 100644
--- a/mysql-test/extra/binlog_tests/drop_temp_table.test
+++ b/mysql-test/extra/binlog_tests/drop_temp_table.test
@@ -1,27 +1,72 @@
--disable_warnings
-drop database if exists `drop-temp+table-test`;
+DROP DATABASE IF EXISTS `drop-temp+table-test`;
--enable_warnings
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
connection con1;
-reset master;
-create database `drop-temp+table-test`;
-use `drop-temp+table-test`;
-create temporary table shortn1 (a int);
-create temporary table `table:name` (a int);
-create temporary table shortn2 (a int);
-select get_lock("a",10);
+RESET MASTER;
+CREATE DATABASE `drop-temp+table-test`;
+USE `drop-temp+table-test`;
+CREATE TEMPORARY TABLE shortn1 (a INT);
+CREATE TEMPORARY TABLE `table:name` (a INT);
+CREATE TEMPORARY TABLE shortn2 (a INT);
+
+##############################################################################
+# BUG#46572 DROP TEMPORARY table IF EXISTS does not have a consistent behavior
+# in ROW mode
+#
+# In RBR, 'DROP TEMPORARY TABLE ...' statement should never be binlogged no
+# matter if the tables exist or not. In contrast, both in SBR and MBR, the
+# statement should be always binlogged no matter if the tables exist or not.
+##############################################################################
+CREATE TEMPORARY TABLE tmp(c1 int);
+CREATE TEMPORARY TABLE tmp1(c1 int);
+CREATE TEMPORARY TABLE tmp2(c1 int);
+CREATE TEMPORARY TABLE tmp3(c1 int);
+CREATE TABLE t(c1 int);
+
+DROP TEMPORARY TABLE IF EXISTS tmp;
+
+--disable_warnings
+# Before fixing BUG#46572, 'DROP TEMPORARY TABLE IF EXISTS...' statement was
+# binlogged when the table did not exist in RBR.
+DROP TEMPORARY TABLE IF EXISTS tmp;
+
+# In RBR, 'DROP TEMPORARY TABLE ...' statement is never binlogged no matter if
+# the tables exist or not.
+DROP TEMPORARY TABLE IF EXISTS tmp, tmp1;
+DROP TEMPORARY TABLE tmp3;
+
+#In RBR, tmp2 will NOT be binlogged, because it is a temporary table.
+DROP TABLE IF EXISTS tmp2, t;
+
+#In RBR, tmp2 will be binlogged, because it does not exist and master do not know
+# whether it is a temporary table or not.
+DROP TABLE IF EXISTS tmp2, t;
+--enable_warnings
+
+SELECT GET_LOCK("a",10);
+
+#
+# BUG48216 Replication fails on all slaves after upgrade to 5.0.86 on master
+#
+# When the session is closed, any temporary tables of the session are dropped
+# and are binlogged. But it will be binlogged with a wrong database name when
+# the length of the database name('drop-temp-table-test') is greater than the
+# current database name('test').
+#
+USE test;
disconnect con1;
connection con2;
# We want to SHOW BINLOG EVENTS, to know what was logged. But there is no
# guarantee that logging of the terminated con1 has been done yet.
# To be sure that logging has been done, we use a user lock.
-select get_lock("a",10);
-let $VERSION=`select version()`;
+SELECT GET_LOCK("a",10);
+let $VERSION=`SELECT VERSION()`;
source include/show_binlog_events.inc;
-drop database `drop-temp+table-test`;
+DROP DATABASE `drop-temp+table-test`;
# End of 4.1 tests
diff --git a/mysql-test/extra/rpl_tests/rpl_auto_increment.test b/mysql-test/extra/rpl_tests/rpl_auto_increment.test
index 4bcb10c165e..86885a14f94 100644
--- a/mysql-test/extra/rpl_tests/rpl_auto_increment.test
+++ b/mysql-test/extra/rpl_tests/rpl_auto_increment.test
@@ -163,5 +163,81 @@ show create table t1;
connection master;
drop table t1;
+#
+# BUG#45999 Row based replication fails when auto_increment field = 0.
+# Store engine of Slaves auto-generates new sequence numbers for
+# auto_increment fields if the values of them are 0. There is an inconsistency
+# between slave and master. When MODE_NO_AUTO_VALUE_ON_ZERO are masters treat
+#
+source include/master-slave-reset.inc;
+
+connection master;
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+--enable_warnings
+
+eval CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=$engine_type;
+eval CREATE TABLE t2 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=$engine_type2;
+SET SQL_MODE='';
+# Value of the id will be 1;
+INSERT INTO t1 VALUES(NULL);
+INSERT INTO t2 VALUES(NULL);
+SELECT * FROM t1;
+SELECT * FROM t2;
+# Value of the id will be 2;
+INSERT INTO t1 VALUES();
+INSERT INTO t2 VALUES();
+SELECT * FROM t1;
+SELECT * FROM t2;
+# Value of the id will be 3. The master treats 0 as NULL or empty because
+# NO_AUTO_VALUE_ON_ZERO is not assign to SQL_MODE.
+INSERT INTO t1 VALUES(0);
+INSERT INTO t2 VALUES(0);
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+SET SQL_MODE=NO_AUTO_VALUE_ON_ZERO;
+# Value of the id will be 0. The master does not treat 0 as NULL or empty
+# because NO_AUTO_VALUE_ON_ZERO has assigned to SQL_MODE.
+INSERT INTO t1 VALUES(0);
+INSERT INTO t2 VALUES(0);
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+INSERT INTO t1 VALUES(4);
+INSERT INTO t2 VALUES(4);
+FLUSH LOGS;
+sync_slave_with_master;
+
+let $diff_table_1= master:test.t1;
+let $diff_table_2= slave:test.t1;
+source include/diff_tables.inc;
+
+let $diff_table_1= master:test.t2;
+let $diff_table_2= slave:test.t2;
+source include/diff_tables.inc;
+
+connection master;
+DROP TABLE t1;
+DROP TABLE t2;
+sync_slave_with_master;
+
+connection master;
+let $MYSQLD_DATADIR= `SELECT @@DATADIR`;
+--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 | $MYSQL test
+sync_slave_with_master;
+
+let $diff_table_1= master:test.t1;
+let $diff_table_2= slave:test.t1;
+source include/diff_tables.inc;
+
+let $diff_table_1= master:test.t2;
+let $diff_table_2= slave:test.t2;
+source include/diff_tables.inc;
+
# End cleanup
+DROP TABLE t1;
+DROP TABLE t2;
+SET SQL_MODE='';
sync_slave_with_master;
diff --git a/mysql-test/extra/rpl_tests/rpl_auto_increment_insert_view.test b/mysql-test/extra/rpl_tests/rpl_auto_increment_insert_view.test
new file mode 100644
index 00000000000..0bfa46de113
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_auto_increment_insert_view.test
@@ -0,0 +1,44 @@
+#
+# This test verifies if inserting data into view that invokes a
+# trigger will make the autoinc values become inconsistent on
+# master and slave.
+#
+connection master;
+CREATE TABLE t1(i1 int not null auto_increment, c1 INT, primary key(i1)) engine=innodb;
+CREATE TABLE t2(i1 int not null auto_increment, c2 INT, primary key(i1)) engine=innodb;
+CREATE TABLE t3(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+eval create trigger tr16 $insert_action on t1 for each row insert into t3(a) values(new.c1);
+eval create trigger tr17 $insert_action on t2 for each row insert into t3(a) values(new.c2);
+begin;
+INSERT INTO t1(c1) VALUES (11), (12);
+INSERT INTO t2(c2) VALUES (13), (14);
+
+CREATE VIEW v16 AS SELECT c1, c2 FROM t1, t2;
+
+INSERT INTO v16(c1) VALUES (15),(16);
+INSERT INTO v16(c2) VALUES (17),(18);
+
+connection master1;
+INSERT INTO v16(c1) VALUES (19),(20);
+INSERT INTO v16(c2) VALUES (21),(22);
+
+connection master;
+INSERT INTO v16(c1) VALUES (23), (24);
+INSERT INTO v16(c1) VALUES (25), (26);
+commit;
+sync_slave_with_master;
+--echo #Test if the results are consistent on master and slave
+--echo #for 'INSERT DATA INTO VIEW WHICH INVOKES TRIGGERS'
+let $diff_table_1=master:test.t3;
+let $diff_table_2=slave:test.t3;
+source include/diff_tables.inc;
+
+connection master;
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP VIEW v16;
+sync_slave_with_master;
+
+
+
diff --git a/mysql-test/extra/rpl_tests/rpl_auto_increment_invoke_trigger.test b/mysql-test/extra/rpl_tests/rpl_auto_increment_invoke_trigger.test
new file mode 100644
index 00000000000..614d79d9c2d
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_auto_increment_invoke_trigger.test
@@ -0,0 +1,82 @@
+#
+# This test verifies if concurrent transactions that invoke a
+# trigger that inserts more than one values into one or more
+# tables with an auto_increment column will make the autoinc
+# values become inconsistent on master and slave.
+#
+
+connection master;
+create table t1(a int, b int) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+eval create trigger tr1 $trigger_action on t1 for each row insert into t2(a) values(6);
+
+create table t3(a int, b int) engine=innodb;
+create table t4(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create table t5(a int) engine=innodb;
+delimiter |;
+eval create trigger tr2 $trigger_action on t3 for each row begin
+ insert into t4(a) values(f1_insert_triggered());
+ insert into t4(a) values(f1_insert_triggered());
+ insert into t5(a) values(8);
+end |
+delimiter ;|
+
+create table t6(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+delimiter //;
+CREATE FUNCTION f1_insert_triggered() RETURNS INTEGER
+BEGIN
+ INSERT INTO t6(a) values(2),(3);
+ RETURN 1;
+END//
+delimiter ;//
+
+begin;
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+insert into t1(a,b) values(1,1),(2,1);
+insert into t3(a,b) values(1,1),(2,1);
+update t1 set a = a + 5 where b = 1;
+update t3 set a = a + 5 where b = 1;
+delete from t1 where b = 1;
+delete from t3 where b = 1;
+
+connection master1;
+#The default autocommit is set to 1, so the statement is auto committed
+insert into t2(a) values(3);
+insert into t4(a) values(3);
+
+connection master;
+commit;
+insert into t1(a,b) values(4,2);
+insert into t3(a,b) values(4,2);
+update t1 set a = a + 5 where b = 2;
+update t3 set a = a + 5 where b = 2;
+delete from t1 where b = 2;
+delete from t3 where b = 2;
+--echo # To verify if insert/update in an autoinc column causes statement to be logged in row format
+source include/show_binlog_events.inc;
+commit;
+
+connection master;
+sync_slave_with_master;
+--echo #Test if the results are consistent on master and slave
+--echo #for 'INVOKES A TRIGGER with $trigger_action action'
+let $diff_table_1=master:test.t2;
+let $diff_table_2=slave:test.t2;
+source include/diff_tables.inc;
+let $diff_table_1=master:test.t4;
+let $diff_table_2=slave:test.t4;
+source include/diff_tables.inc;
+let $diff_table_1=master:test.t6;
+let $diff_table_2=slave:test.t6;
+source include/diff_tables.inc;
+
+connection master;
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+DROP TABLE t5;
+DROP TABLE t6;
+DROP FUNCTION f1_insert_triggered;
+sync_slave_with_master;
+
diff --git a/mysql-test/extra/rpl_tests/rpl_autoinc_func_invokes_trigger.test b/mysql-test/extra/rpl_tests/rpl_autoinc_func_invokes_trigger.test
new file mode 100644
index 00000000000..fece19b397d
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_autoinc_func_invokes_trigger.test
@@ -0,0 +1,57 @@
+#
+# This test verifies if concurrent transactions that call a
+# function which invokes a 'after/before insert action' trigger
+# that inserts more than one values into a table with autoinc
+# column will make the autoinc values become inconsistent on
+# master and slave.
+#
+
+connection master;
+create table t1(a int) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create table t3(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+delimiter |;
+CREATE FUNCTION f1_two_inserts_trigger() RETURNS INTEGER
+BEGIN
+ INSERT INTO t2(a) values(2),(3);
+ INSERT INTO t2(a) values(2),(3);
+ RETURN 1;
+END |
+eval create trigger tr11 $insert_action on t2 for each row begin
+ insert into t3(a) values(new.a);
+ insert into t3(a) values(new.a);
+end |
+delimiter ;|
+begin;
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+insert into t1(a) values(f1_two_inserts_trigger());
+
+connection master1;
+#The default autocommit is set to 1, so the statement is auto committed
+insert into t2(a) values(4),(5);
+
+connection master;
+commit;
+insert into t1(a) values(f1_two_inserts_trigger());
+--echo # To verify if insert/update in an autoinc column causes statement to be logged in row format
+source include/show_binlog_events.inc;
+commit;
+
+connection master;
+sync_slave_with_master;
+--echo #Test if the results are consistent on master and slave
+--echo #for 'CALLS A FUNCTION which INVOKES A TRIGGER with $insert_action action'
+let $diff_table_1=master:test.t2;
+let $diff_table_2=slave:test.t2;
+source include/diff_tables.inc;
+let $diff_table_1=master:test.t3;
+let $diff_table_2=slave:test.t3;
+source include/diff_tables.inc;
+
+connection master;
+drop table t1;
+drop table t2;
+drop table t3;
+drop function f1_two_inserts_trigger;
+sync_slave_with_master;
+
diff --git a/mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test b/mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test
index 6890913b7d1..a7b02065144 100644
--- a/mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test
+++ b/mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test
@@ -22,6 +22,8 @@ DROP TABLE IF EXISTS t1, t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t14a,t15,t1
# should stop the slave. #
#################################################
+call mtr.add_suppression("Slave: Unknown table 't6' Error_code: 1051");
+
--echo **** Diff Table Def Start ****
##############################################
diff --git a/mysql-test/extra/rpl_tests/rpl_failed_optimize.test b/mysql-test/extra/rpl_tests/rpl_failed_optimize.test
index 0c537ee188d..cd81f2497b8 100644
--- a/mysql-test/extra/rpl_tests/rpl_failed_optimize.test
+++ b/mysql-test/extra/rpl_tests/rpl_failed_optimize.test
@@ -22,3 +22,4 @@ connection master;
select * from t1;
commit;
drop table t1;
+-- sync_slave_with_master
diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata.test b/mysql-test/extra/rpl_tests/rpl_loaddata.test
index 26916642cae..7db12600456 100644
--- a/mysql-test/extra/rpl_tests/rpl_loaddata.test
+++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test
@@ -158,4 +158,65 @@ LOAD DATA INFILE "../../std_data/words.dat" INTO TABLE t1;
DROP TABLE IF EXISTS t1;
+# BUG#48297: Schema name is ignored when LOAD DATA is written into binlog,
+# replication aborts
+-- source include/master-slave-reset.inc
+
+-- let $db1= b48297_db1
+-- let $db2= b42897_db2
+
+-- connection master
+
+-- disable_warnings
+-- eval drop database if exists $db1
+-- eval drop database if exists $db2
+-- enable_warnings
+
+-- eval create database $db1
+-- eval create database $db2
+
+-- eval use $db1
+-- eval CREATE TABLE t1 (c1 VARCHAR(256)) engine=$engine_type;
+
+-- eval use $db2
+
+-- echo ### assertion: works with cross-referenced database
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1
+
+-- eval use $db1
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- echo ### assertion: works with fully qualified name on current database
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1
+
+-- echo ### assertion: works without fully qualified name on current database
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE t1
+
+-- echo ### create connection without default database
+-- echo ### connect (conn2,localhost,root,,*NO-ONE*);
+connect (conn2,localhost,root,,*NO-ONE*);
+-- connection conn2
+-- echo ### assertion: works without stating the default database
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1
+-- echo ### disconnect and switch back to master connection
+-- disconnect conn2
+-- connection master
+
+-- sync_slave_with_master
+-- eval use $db1
+
+let $diff_table_1=master:$db1.t1;
+let $diff_table_2=slave:$db1.t1;
+source include/diff_tables.inc;
+
+-- connection master
+
+-- eval DROP DATABASE $db1
+-- eval DROP DATABASE $db2
+
+-- sync_slave_with_master
+
# End of 4.1 tests
diff --git a/mysql-test/extra/rpl_tests/rpl_row_sp006.test b/mysql-test/extra/rpl_tests/rpl_row_sp006.test
index 897d7e492bf..16a8374ae7f 100644
--- a/mysql-test/extra/rpl_tests/rpl_row_sp006.test
+++ b/mysql-test/extra/rpl_tests/rpl_row_sp006.test
@@ -9,29 +9,27 @@
#############################################################################
# Begin clean up test section
-connection master;
--disable_warnings
-create database if not exists mysqltest1;
-DROP PROCEDURE IF EXISTS mysqltest1.p1;
-DROP PROCEDURE IF EXISTS mysqltest1.p2;
-DROP TABLE IF EXISTS mysqltest1.t2;
-DROP TABLE IF EXISTS mysqltest1.t1;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
--enable_warnings
# End of cleanup
# Begin test section 1
-eval CREATE TABLE IF NOT EXISTS mysqltest1.t1(name CHAR(16), birth DATE,PRIMARY KEY(name))ENGINE=$engine_type;
-eval CREATE TABLE IF NOT EXISTS mysqltest1.t2(name CHAR(16), age INT ,PRIMARY KEY(name))ENGINE=$engine_type;
+eval CREATE TABLE IF NOT EXISTS t1(name CHAR(16), birth DATE,PRIMARY KEY(name))ENGINE=$engine_type;
+eval CREATE TABLE IF NOT EXISTS t2(name CHAR(16), age INT ,PRIMARY KEY(name))ENGINE=$engine_type;
delimiter |;
-CREATE PROCEDURE mysqltest1.p1()
+CREATE PROCEDURE p1()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE spa CHAR(16);
DECLARE spb INT;
DECLARE cur1 CURSOR FOR SELECT name,
(YEAR(CURDATE())-YEAR(birth))-(RIGHT(CURDATE(),5)<RIGHT(birth,5))
- FROM mysqltest1.t1;
+ FROM t1;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
OPEN cur1;
@@ -41,7 +39,7 @@ BEGIN
FETCH cur1 INTO spa, spb;
IF NOT done THEN
START TRANSACTION;
- INSERT INTO mysqltest1.t2 VALUES (spa,spb);
+ INSERT INTO t2 VALUES (spa,spb);
COMMIT;
END IF;
UNTIL done END REPEAT;
@@ -49,30 +47,29 @@ BEGIN
SET AUTOCOMMIT=1;
CLOSE cur1;
END|
-CREATE PROCEDURE mysqltest1.p2()
+CREATE PROCEDURE p2()
BEGIN
- INSERT INTO mysqltest1.t1 VALUES ('MySQL','1993-02-04'),('ROCKS', '1990-08-27'),('Texas', '1999-03-30'),('kyle','2005-1-1');
+ INSERT INTO t1 VALUES ('MySQL','1993-02-04'),('ROCKS', '1990-08-27'),('Texas', '1999-03-30'),('kyle','2005-1-1');
END|
delimiter ;|
-CALL mysqltest1.p2();
+CALL p2();
sync_slave_with_master;
connection master;
-CALL mysqltest1.p1();
+CALL p1();
sync_slave_with_master;
connection master;
---exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > $MYSQLTEST_VARDIR/tmp/sp006_master.sql
---exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > $MYSQLTEST_VARDIR/tmp/sp006_slave.sql
+--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/sp006_master.sql
+--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/sp006_slave.sql
-DROP PROCEDURE IF EXISTS mysqltest1.p1;
-DROP PROCEDURE IF EXISTS mysqltest1.p2;
-DROP TABLE IF EXISTS mysqltest1.t1;
-DROP TABLE IF EXISTS mysqltest1.t2;
-DROP DATABASE mysqltest1;
+DROP TABLE t1;
+DROP TABLE t2;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
# Lets compare. Note: If they match test will pass, if they do not match
# the test will show that the diff statement failed and not reject file
diff --git a/mysql-test/extra/rpl_tests/rpl_stm_000001.test b/mysql-test/extra/rpl_tests/rpl_stm_000001.test
index 1f5eb5786dd..869a9e3b07c 100644
--- a/mysql-test/extra/rpl_tests/rpl_stm_000001.test
+++ b/mysql-test/extra/rpl_tests/rpl_stm_000001.test
@@ -93,7 +93,7 @@ kill @id;
# We don't drop t3 as this is a temporary table
drop table t2;
connection master;
---error 1053,2013
+--error 1317,2013
reap;
connection slave;
# The SQL slave thread should now have stopped because the query was killed on
diff --git a/mysql-test/include/check-warnings.test b/mysql-test/include/check-warnings.test
index 8267ccdd102..fab7fb2cff6 100644
--- a/mysql-test/include/check-warnings.test
+++ b/mysql-test/include/check-warnings.test
@@ -58,5 +58,5 @@ if (`select @result = 0`){
skip OK;
}
--enable_query_log
-echo ^ Found warnings!!;
+echo ^ Found warnings in $log_error;
exit;
diff --git a/mysql-test/include/concurrent.inc b/mysql-test/include/concurrent.inc
index 66f8a65a102..0b7299a3c34 100644
--- a/mysql-test/include/concurrent.inc
+++ b/mysql-test/include/concurrent.inc
@@ -25,8 +25,6 @@
# new wrapper t/concurrent_innodb_safelog.test
#
---source include/not_embedded.inc
-
connection default;
#
# Show prerequisites for this test.
diff --git a/mysql-test/include/have_case_insensitive_fs.inc b/mysql-test/include/have_case_insensitive_fs.inc
new file mode 100644
index 00000000000..de4ad73d780
--- /dev/null
+++ b/mysql-test/include/have_case_insensitive_fs.inc
@@ -0,0 +1,4 @@
+--require r/case_insensitive_fs.require
+--disable_query_log
+show variables like 'lower_case_file_system';
+--enable_query_log
diff --git a/mysql-test/include/have_debug_sync.inc b/mysql-test/include/have_debug_sync.inc
new file mode 100644
index 00000000000..7aa5baf3342
--- /dev/null
+++ b/mysql-test/include/have_debug_sync.inc
@@ -0,0 +1,5 @@
+--require r/have_debug_sync.require
+disable_query_log;
+let $value= query_get_value(SHOW VARIABLES LIKE 'debug_sync', Value, 1);
+eval SELECT ('$value' LIKE 'ON %') AS debug_sync;
+enable_query_log;
diff --git a/mysql-test/include/have_dynamic_loading.inc b/mysql-test/include/have_dynamic_loading.inc
index ddd7c61a730..1b2c85b3904 100644
--- a/mysql-test/include/have_dynamic_loading.inc
+++ b/mysql-test/include/have_dynamic_loading.inc
@@ -1,4 +1,7 @@
--- require r/have_dynamic_loading.require
+#
+# Whether server supports dynamic loading.
+#
+--require r/have_dynamic_loading.require
disable_query_log;
show variables like 'have_dynamic_loading';
enable_query_log;
diff --git a/mysql-test/include/have_example_plugin.inc b/mysql-test/include/have_example_plugin.inc
index 8e57c725eb5..a2fffc17b97 100644
--- a/mysql-test/include/have_example_plugin.inc
+++ b/mysql-test/include/have_example_plugin.inc
@@ -2,10 +2,7 @@
# Check if server has support for loading udf's
# i.e it will support dlopen
#
---require r/have_dynamic_loading.require
-disable_query_log;
-show variables like 'have_dynamic_loading';
-enable_query_log;
+--source include/have_dynamic_loading.inc
#
# Check if the variable EXAMPLE_PLUGIN is set
diff --git a/mysql-test/include/have_mysql_upgrade.inc b/mysql-test/include/have_mysql_upgrade.inc
new file mode 100644
index 00000000000..8f486176018
--- /dev/null
+++ b/mysql-test/include/have_mysql_upgrade.inc
@@ -0,0 +1,4 @@
+--require r/have_mysql_upgrade.result
+--disable_query_log
+select LENGTH("$MYSQL_UPGRADE")>0 as have_mysql_upgrade;
+--enable_query_log
diff --git a/mysql-test/include/have_not_innodb_plugin.inc b/mysql-test/include/have_not_innodb_plugin.inc
new file mode 100644
index 00000000000..aaefbaf661c
--- /dev/null
+++ b/mysql-test/include/have_not_innodb_plugin.inc
@@ -0,0 +1,4 @@
+disable_query_log;
+--require r/not_true.require
+select (PLUGIN_LIBRARY LIKE 'ha_innodb_plugin%') as `TRUE` from information_schema.plugins where PLUGIN_NAME='InnoDB';
+enable_query_log;
diff --git a/mysql-test/include/have_simple_parser.inc b/mysql-test/include/have_simple_parser.inc
index c85786bd524..5a4dc93ec81 100644
--- a/mysql-test/include/have_simple_parser.inc
+++ b/mysql-test/include/have_simple_parser.inc
@@ -2,10 +2,7 @@
# Check if server has support for loading udf's
# i.e it will support dlopen
#
---require r/have_dynamic_loading.require
-disable_query_log;
-show variables like 'have_dynamic_loading';
-enable_query_log;
+--source include/have_dynamic_loading.inc
#
# Check if the variable SIMPLE_PARSER is set
diff --git a/mysql-test/include/have_udf.inc b/mysql-test/include/have_udf.inc
index 3f7e260c5ba..7be57bbb7a9 100644
--- a/mysql-test/include/have_udf.inc
+++ b/mysql-test/include/have_udf.inc
@@ -2,10 +2,7 @@
# Check if server has support for loading udf's
# i.e it will support dlopen
#
---require r/have_dynamic_loading.require
-disable_query_log;
-show variables like 'have_dynamic_loading';
-enable_query_log;
+--source include/have_dynamic_loading.inc
#
# Check if the variable UDF_EXAMPLE_LIB is set
diff --git a/mysql-test/include/index_merge2.inc b/mysql-test/include/index_merge2.inc
index d65115eac0f..32a176630ad 100644
--- a/mysql-test/include/index_merge2.inc
+++ b/mysql-test/include/index_merge2.inc
@@ -122,12 +122,14 @@ insert into t1 (key1a, key1b, key2a, key2b, key3a, key3b)
analyze table t1;
select count(*) from t1;
+--replace_column 9 REF
explain select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
+--replace_column 9 REF
explain select count(*) from t1 where
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc
index 6dabe4864a9..194d9e41108 100644
--- a/mysql-test/include/mix1.inc
+++ b/mysql-test/include/mix1.inc
@@ -442,6 +442,8 @@ INSERT INTO t1(id, dept, age, name) VALUES
EXPLAIN SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5';
SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5';
DELETE FROM t1;
+--echo # Masking (#) number in "rows" column of the following EXPLAIN output, as it may vary (bug#47746).
+--replace_column 9 #
EXPLAIN SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5';
SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5';
diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql
index af491d4fe8a..c1c9785fda2 100644
--- a/mysql-test/include/mtr_warnings.sql
+++ b/mysql-test/include/mtr_warnings.sql
@@ -132,7 +132,7 @@ INSERT INTO global_suppressions VALUES
("Error in Log_event::read_log_event\\\(\\\): 'Sanity check failed', data_len: 258, event_type: 49"),
- ("Statement is not safe to log in statement format"),
+ ("Statement may not be safe to log in statement format"),
/* test case for Bug#bug29807 copies a stray frm into database */
("InnoDB: Error: table `test`.`bug29807` does not exist in the InnoDB internal"),
@@ -162,6 +162,8 @@ INSERT INTO global_suppressions VALUES
("Slave: Unknown column 'c7' in 't15' Error_code: 1054"),
("Slave: Can't DROP 'c7'.* 1091"),
("Slave: Key column 'c6'.* 1072"),
+ ("The slave I.O thread stops because a fatal error is encountered when it try to get the value of SERVER_ID variable from master."),
+ (".SELECT UNIX_TIMESTAMP... failed on master, do not trust column Seconds_Behind_Master of SHOW SLAVE STATUS"),
/* Test case for Bug#31590 in order_by.test produces the following error */
("Out of sort memory; increase server sort buffer size"),
@@ -171,6 +173,7 @@ INSERT INTO global_suppressions VALUES
this error message.
*/
("Can't find file: '.\\\\test\\\\\\?{8}.frm'"),
+ ("Slave: Unknown table 't1' Error_code: 1051"),
/* maria-recovery.test has warning about missing log file */
("File '.*maria_log.000.*' not found \\(Errcode: 2\\)"),
@@ -217,7 +220,7 @@ BEGIN
WHERE suspicious=1;
IF @num_warnings > 0 THEN
- SELECT file_name, line
+ SELECT line
FROM error_log WHERE suspicious=1;
--SELECT * FROM test_suppressions;
-- Return 2 -> check failed
diff --git a/mysql-test/include/not_windows_embedded.inc b/mysql-test/include/not_windows_embedded.inc
new file mode 100644
index 00000000000..46f5e0ccfce
--- /dev/null
+++ b/mysql-test/include/not_windows_embedded.inc
@@ -0,0 +1,11 @@
+let $is_win = `select convert(@@version_compile_os using latin1) IN ("Win32","Win64","Windows")`;
+let $is_embedded = `select version() like '%embedded%'`;
+#echo is_win: $is_win;
+#echo is_embedded: $is_embedded;
+if ($is_win)
+{
+ if ($is_embedded)
+ {
+ skip Not supported with embedded on windows;
+ }
+}
diff --git a/mysql-test/lib/My/ConfigFactory.pm b/mysql-test/lib/My/ConfigFactory.pm
index 855918a1284..3c9ddfa3814 100644
--- a/mysql-test/lib/My/ConfigFactory.pm
+++ b/mysql-test/lib/My/ConfigFactory.pm
@@ -7,6 +7,7 @@ use Carp;
use My::Config;
use My::Find;
+use My::Platform;
use File::Basename;
@@ -141,8 +142,7 @@ sub fix_secure_file_priv {
sub fix_std_data {
my ($self, $config, $group_name, $group)= @_;
- my $basedir= $self->get_basedir($group);
- return "$basedir/mysql-test/std_data";
+ return "$::opt_vardir/std_data";
}
sub ssl_supported {
@@ -207,8 +207,8 @@ my @mysqld_rules=
{ '#log-error' => \&fix_log_error },
{ 'general-log' => sub { return 1; } },
{ 'general-log-file' => \&fix_log },
- { 'slow-query-log-file' => \&fix_log_slow_queries },
{ 'slow-query-log' => sub { return 1; } },
+ { 'slow-query-log-file' => \&fix_log_slow_queries },
{ '#user' => sub { return shift->{ARGS}->{user} || ""; } },
{ '#password' => sub { return shift->{ARGS}->{password} || ""; } },
{ 'server-id' => \&fix_server_id, },
@@ -219,7 +219,13 @@ my @mysqld_rules=
{ 'ssl-key' => \&fix_ssl_server_key },
);
-
+if (IS_WINDOWS)
+{
+ # For simplicity, we use the same names for shared memory and
+ # named pipes.
+ push(@mysqld_rules, {'shared-memory-base-name' => \&fix_socket});
+}
+
sub fix_ndb_mgmd_port {
my ($self, $config, $group_name, $group)= @_;
my $hostname= $group->value('HostName');
@@ -348,6 +354,16 @@ sub post_check_client_group {
}
$config->insert($client_group_name, $name_to, $option->value())
}
+
+ if (IS_WINDOWS)
+ {
+ # Shared memory base may or may not be defined (e.g not defined in embedded)
+ my $shm = $group_to_copy_from->option("shared-memory-base-name");
+ if (defined $shm)
+ {
+ $config->insert($client_group_name,"shared-memory-base-name", $shm->value());
+ }
+ }
}
@@ -394,6 +410,7 @@ sub post_check_embedded_group {
(
'#log-error', # Embedded server writes stderr to mysqltest's log file
'slave-net-timeout', # Embedded server are not build with replication
+ 'shared-memory-base-name', # No shared memory for embedded
);
foreach my $option ( $mysqld->options(), $first_mysqld->options() ) {
diff --git a/mysql-test/lib/My/Platform.pm b/mysql-test/lib/My/Platform.pm
index 69ffdfbb4ce..371120ab644 100644
--- a/mysql-test/lib/My/Platform.pm
+++ b/mysql-test/lib/My/Platform.pm
@@ -106,10 +106,13 @@ sub check_socket_path_length {
my ($path)= @_;
return 0 if IS_WINDOWS;
+ # This may not be true, but we can't test for it on AIX due to Perl bug
+ # See Bug #45771
+ return 0 if ($^O eq 'aix');
require IO::Socket::UNIX;
- my $truncated= 1; # Be negative
+ my $truncated= undef;
# Create a tempfile name with same length as "path"
my $tmpdir = tempdir( CLEANUP => 0);
@@ -122,6 +125,7 @@ sub check_socket_path_length {
Local => $testfile,
Listen => 1,
);
+ $truncated= 1; # Be negatvie
die "Could not create UNIX domain socket: $!"
unless defined $sock;
@@ -133,6 +137,9 @@ sub check_socket_path_length {
};
+ die "Unexpected failure when checking socket path length: $@"
+ if $@ and not defined $truncated;
+
$sock= undef; # Close socket
rmtree($tmpdir); # Remove the tempdir and any socket file created
return $truncated;
diff --git a/mysql-test/lib/My/SafeProcess/safe_kill_win.cc b/mysql-test/lib/My/SafeProcess/safe_kill_win.cc
index c6256fd92e1..963a02c8099 100755
--- a/mysql-test/lib/My/SafeProcess/safe_kill_win.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_kill_win.cc
@@ -30,7 +30,7 @@ int main(int argc, const char** argv )
DWORD pid= -1;
HANDLE shutdown_event;
char safe_process_name[32]= {0};
- int retry_open_event= 100;
+ int retry_open_event= 2;
/* Ignore any signals */
signal(SIGINT, SIG_IGN);
signal(SIGBREAK, SIG_IGN);
@@ -51,15 +51,31 @@ int main(int argc, const char** argv )
{
/*
Check if the process is alive, otherwise there is really
- no idea to retry the open of the event
+ no sense to retry the open of the event
*/
HANDLE process;
- if ((process= OpenProcess(SYNCHRONIZE, FALSE, pid)) == NULL)
+ DWORD exit_code;
+ process= OpenProcess(SYNCHRONIZE| PROCESS_QUERY_INFORMATION, FALSE, pid);
+ if (!process)
{
- fprintf(stderr, "Could not open event or process %d, error: %d\n",
- pid, GetLastError());
- exit(3);
+ /* Already died */
+ exit(1);
+ }
+
+ if (!GetExitCodeProcess(process,&exit_code))
+ {
+ fprintf(stderr, "GetExitCodeProcess failed, pid= %d, err= %d\n",
+ pid, GetLastError());
+ exit(1);
}
+
+ if (exit_code != STILL_ACTIVE)
+ {
+ /* Already died */
+ CloseHandle(process);
+ exit(2);
+ }
+
CloseHandle(process);
if (retry_open_event--)
diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc
index 213989720bf..aa9093fb2b4 100755
--- a/mysql-test/lib/My/SafeProcess/safe_process_win.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_process_win.cc
@@ -50,9 +50,6 @@
is killed.
*/
-/* Requires Windows 2000 or higher */
-#define _WIN32_WINNT 0x0500
-
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
@@ -189,7 +186,14 @@ int main(int argc, const char** argv )
die("No real args -> nothing to do");
/* Copy the remaining args to child_arg */
for (int j= i+1; j < argc; j++) {
- to+= _snprintf(to, child_args + sizeof(child_args) - to, "%s ", argv[j]);
+ if (strchr (argv[j], ' ')) {
+ /* Protect with "" if this arg contains a space */
+ to+= _snprintf(to, child_args + sizeof(child_args) - to,
+ "\"%s\" ", argv[j]);
+ } else {
+ to+= _snprintf(to, child_args + sizeof(child_args) - to,
+ "%s ", argv[j]);
+ }
}
break;
} else {
diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
index 76575b2f498..28b79484aa8 100644
--- a/mysql-test/lib/mtr_cases.pm
+++ b/mysql-test/lib/mtr_cases.pm
@@ -41,6 +41,7 @@ our $opt_with_ndbcluster_only;
our $defaults_file;
our $defaults_extra_file;
our $reorder= 1;
+our $quick_collect;
sub collect_option {
my ($opt, $value)= @_;
@@ -68,6 +69,13 @@ require "mtr_misc.pl";
my $do_test_reg;
my $skip_test_reg;
+# Related to adding InnoDB plugin combinations
+my $lib_innodb_plugin;
+my $do_innodb_plugin;
+
+# If "Quick collect", set to 1 once a test to run has been found.
+my $some_test_found;
+
sub init_pattern {
my ($from, $what)= @_;
return undef unless defined $from;
@@ -100,10 +108,23 @@ sub collect_test_cases ($$) {
$do_test_reg= init_pattern($do_test, "--do-test");
$skip_test_reg= init_pattern($skip_test, "--skip-test");
+ $lib_innodb_plugin=
+ my_find_file($::basedir,
+ ["storage/innodb_plugin", "storage/innodb_plugin/.libs",
+ "lib/mysql/plugin", "lib/mariadb/plugin", "lib/plugin"],
+ ["ha_innodb_plugin.dll", "ha_innodb_plugin.so",
+ "ha_innodb_plugin.sl"],
+ NOT_REQUIRED);
+
+ $do_innodb_plugin= ($::mysql_version_id >= 50100 &&
+ !(IS_WINDOWS && $::opt_embedded_server) &&
+ $lib_innodb_plugin);
+
foreach my $suite (split(",", $suites))
{
push(@$cases, collect_one_suite($suite, $opt_cases));
$found_suites{$suite}= 1;
+ last if $some_test_found;
}
if ( @$opt_cases )
@@ -147,7 +168,7 @@ sub collect_test_cases ($$) {
}
}
- if ( $reorder )
+ if ( $reorder && !$quick_collect)
{
# Reorder the test cases in an order that will make them faster to run
my %sort_criteria;
@@ -398,7 +419,7 @@ sub collect_one_suite($)
# Read combinations for this suite and build testcases x combinations
# if any combinations exists
# ----------------------------------------------------------------------
- if ( ! $skip_combinations )
+ if ( ! $skip_combinations && ! $quick_collect )
{
my @combinations;
my $combination_file= "$suitedir/combinations";
@@ -491,21 +512,16 @@ sub collect_one_suite($)
# ----------------------------------------------------------------------
# Testing InnoDB plugin.
# ----------------------------------------------------------------------
- my $lib_innodb_plugin=
- mtr_file_exists(::vs_config_dirs('storage/innodb_plugin', 'ha_innodb_plugin.dll'),
- "$::basedir/storage/innodb_plugin/.libs/ha_innodb_plugin.so",
- "$::basedir/lib/mariadb/plugin/ha_innodb_plugin.so",
- "$::basedir/lib/mariadb/plugin/ha_innodb_plugin.dll",
- "$::basedir/lib/mysql/plugin/ha_innodb_plugin.so",
- "$::basedir/lib/mysql/plugin/ha_innodb_plugin.dll");
- if ($::mysql_version_id >= 50100 && !(IS_WINDOWS && $::opt_embedded_server) &&
- $lib_innodb_plugin)
+ if ($do_innodb_plugin)
{
my @new_cases;
+ my $sep= (IS_WINDOWS) ? ';' : ':';
foreach my $test (@cases)
{
- next if ($test->{'skip'} || !$test->{'innodb_test'});
+ next if (!$test->{'innodb_test'});
+ # If skipped due to no builtin innodb, we can still run it with plugin
+ next if ($test->{'skip'} && $test->{comment} ne "No innodb support");
# Exceptions
next if ($test->{'name'} eq 'main.innodb'); # Failed with wrong errno (fk)
next if ($test->{'name'} eq 'main.index_merge_innodb'); # Explain diff
@@ -515,6 +531,8 @@ sub collect_one_suite($)
next if ($test->{'name'} eq 'sys_vars.innodb_lock_wait_timeout_basic');
# Diff around innodb_thread_concurrency variable
next if ($test->{'name'} eq 'sys_vars.innodb_thread_concurrency_basic');
+ # Can't work with InnoPlug. Test framework needs to be re-designed.
+ next if ($test->{'name'} eq 'main.innodb_bug46000');
# Copy test options
my $new_test= My::Test->new();
while (my ($key, $value) = each(%$test))
@@ -525,23 +543,24 @@ sub collect_one_suite($)
}
else
{
- $new_test->{$key}= $value;
+ $new_test->{$key}= $value unless ($key eq 'skip');
}
}
my $plugin_filename= basename($lib_innodb_plugin);
+ my $plugin_list= "innodb=$plugin_filename" . $sep . "innodb_locks=$plugin_filename";
push(@{$new_test->{master_opt}}, '--ignore-builtin-innodb');
push(@{$new_test->{master_opt}}, '--plugin-dir=' . dirname($lib_innodb_plugin));
- push(@{$new_test->{master_opt}}, "--plugin_load=innodb=$plugin_filename;innodb_locks=$plugin_filename");
+ push(@{$new_test->{master_opt}}, "--plugin_load=$plugin_list");
push(@{$new_test->{slave_opt}}, '--ignore-builtin-innodb');
push(@{$new_test->{slave_opt}}, '--plugin-dir=' . dirname($lib_innodb_plugin));
- push(@{$new_test->{slave_opt}}, "--plugin_load=innodb=$plugin_filename;innodb_locks=$plugin_filename");
+ push(@{$new_test->{slave_opt}}, "--plugin_load=$plugin_list");
if ($new_test->{combination})
{
- $new_test->{combination}.= ' + InnoDB plugin';
+ $new_test->{combination}.= '+innodb_plugin';
}
else
{
- $new_test->{combination}= 'InnoDB plugin';
+ $new_test->{combination}= 'innodb_plugin';
}
push(@new_cases, $new_test);
}
@@ -670,34 +689,10 @@ sub optimize_cases {
}
}
- # =======================================================
- # Check that engine selected by
- # --default-storage-engine=<engine> is supported
- # =======================================================
- my %builtin_engines = ('myisam' => 1, 'memory' => 1);
-
- foreach my $opt ( @{$tinfo->{master_opt}} ) {
- my $default_engine=
- mtr_match_prefix($opt, "--default-storage-engine=");
-
- if (defined $default_engine){
-
-
- my $engine_value= $::mysqld_variables{$default_engine};
-
- if ( ! exists $::mysqld_variables{$default_engine} and
- ! exists $builtin_engines{$default_engine} )
- {
- $tinfo->{'skip'}= 1;
- $tinfo->{'comment'}=
- "'$default_engine' not supported";
- }
-
- $tinfo->{'ndb_test'}= 1
- if ( $default_engine =~ /^ndb/i );
- $tinfo->{'innodb_test'}= 1
- if ( $default_engine =~ /^innodb/i );
- }
+ if ($quick_collect && ! $tinfo->{'skip'})
+ {
+ $some_test_found= 1;
+ return;
}
}
@$cases= @new_cases;
@@ -1001,21 +996,24 @@ sub collect_one_test_case {
if ($tinfo->{'federated_test'})
{
- # This is a test that need federated, enable it
+ # This is a test that needs federated, enable it
push(@{$tinfo->{'master_opt'}}, "--loose-federated");
push(@{$tinfo->{'slave_opt'}}, "--loose-federated");
}
if ( $tinfo->{'innodb_test'} )
{
- # This is a test that need innodb
+ # This is a test that needs innodb
if ( $::mysqld_variables{'innodb'} eq "OFF" ||
! exists $::mysqld_variables{'innodb'} )
{
# innodb is not supported, skip it
$tinfo->{'skip'}= 1;
+ # This comment is checked for running with innodb plugin (see above),
+ # please keep that in mind if changing the text.
$tinfo->{'comment'}= "No innodb support";
- return $tinfo;
+ # But continue processing if we may run it with innodb plugin
+ return $tinfo unless $do_innodb_plugin;
}
}
else
@@ -1071,6 +1069,17 @@ sub collect_one_test_case {
}
}
+ if ( $tinfo->{'need_ssl'} )
+ {
+ # This is a test that needs ssl
+ if ( ! $::opt_ssl_supported ) {
+ # SSL is not supported, skip it
+ $tinfo->{'skip'}= 1;
+ $tinfo->{'comment'}= "No SSL support";
+ return $tinfo;
+ }
+ }
+
# ----------------------------------------------------------------------
# Find config file to use if not already selected in <testname>.opt file
# ----------------------------------------------------------------------
@@ -1163,7 +1172,8 @@ my @tags=
["federated.inc", "federated_test", 1],
["include/not_embedded.inc", "not_embedded", 1],
["include/not_valgrind.inc", "not_valgrind", 1],
- ["include/have_example_plugin.inc", "example_plugin_test", 1]
+ ["include/have_example_plugin.inc", "example_plugin_test", 1],
+ ["include/have_ssl.inc", "need_ssl", 1],
);
diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm
index bc27029351d..e0c5b004541 100644
--- a/mysql-test/lib/mtr_report.pm
+++ b/mysql-test/lib/mtr_report.pm
@@ -134,8 +134,8 @@ sub mtr_report_test ($) {
# an asterisk at the end, determine if the characters up to
# but excluding the asterisk are the same
if ( $exp ne "" && substr($exp, -1, 1) eq "*" ) {
- $exp = substr($exp, 0, length($exp) - 1);
- if ( substr($test_name, 0, length($exp)) ne $exp ) {
+ my $nexp = substr($exp, 0, length($exp) - 1);
+ if ( substr($test_name, 0, length($nexp)) ne $nexp ) {
# no match, try next entry
next;
}
@@ -146,6 +146,7 @@ sub mtr_report_test ($) {
}
}
$fail = "exp-fail";
+ $tinfo->{exp_fail}= 1;
last;
}
}
diff --git a/mysql-test/lib/v1/incompatible.tests b/mysql-test/lib/v1/incompatible.tests
new file mode 100644
index 00000000000..fefdad9ce4c
--- /dev/null
+++ b/mysql-test/lib/v1/incompatible.tests
@@ -0,0 +1,6 @@
+# This file lists tests that cannot run in MTR v1 for some reason.
+# They will be skipped.
+# Any text following white space after full test name is ignored
+# Only exact test names can be used, no regexp.
+
+main.fulltext_plugin # Refers to $SIMPLE_PARSER_OPT which is not set
diff --git a/mysql-test/lib/v1/mtr_cases.pl b/mysql-test/lib/v1/mtr_cases.pl
index 4d7b1f4ec70..288e8c22b44 100644
--- a/mysql-test/lib/v1/mtr_cases.pl
+++ b/mysql-test/lib/v1/mtr_cases.pl
@@ -32,6 +32,7 @@ sub mtr_options_from_test_file($$);
my $do_test;
my $skip_test;
+my %incompatible;
sub init_pattern {
my ($from, $what)= @_;
@@ -47,6 +48,15 @@ sub init_pattern {
}
+sub collect_incomp_tests {
+ open (INCOMP, "lib/v1/incompatible.tests");
+ while (<INCOMP>)
+ {
+ next unless /^\w/;
+ s/\s.*\n//; # Ignore anything from first white space
+ $incompatible{$_}= 1;
+ }
+}
##############################################################################
#
@@ -58,6 +68,8 @@ sub collect_test_cases ($) {
$do_test= init_pattern($::opt_do_test, "--do-test");
$skip_test= init_pattern($::opt_skip_test, "--skip-test");
+ collect_incomp_tests();
+
my $suites= shift; # Semicolon separated list of test suites
my $cases = []; # Array of hash
@@ -528,6 +540,17 @@ sub collect_one_test_case($$$$$$$$$) {
$tinfo->{'component_id'} = $component_id;
push(@$cases, $tinfo);
+ # Remove "combinations" part of test name
+ my $test_base_name= $tinfo->{'name'};
+ $test_base_name=~ s/\s.*\n//;
+
+ if (exists ($incompatible{$test_base_name}))
+ {
+ $tinfo->{'skip'}= 1;
+ $tinfo->{'comment'}= "Test cannot run in mtr v1";
+ return;
+ }
+
# ----------------------------------------------------------------------
# Skip some tests but include in list, just mark them to skip
# ----------------------------------------------------------------------
@@ -841,7 +864,7 @@ sub collect_one_test_case($$$$$$$$$) {
if ( $tinfo->{'innodb_test'} )
{
# This is a test that need innodb
- if ( $::mysqld_variables{'innodb'} ne "TRUE" )
+ if ( $::mysqld_variables{'innodb'} eq "OFF" )
{
# innodb is not supported, skip it
$tinfo->{'skip'}= 1;
diff --git a/mysql-test/mysql-stress-test.pl b/mysql-test/mysql-stress-test.pl
index ff2566b1476..8b94ba1404d 100755
--- a/mysql-test/mysql-stress-test.pl
+++ b/mysql-test/mysql-stress-test.pl
@@ -14,17 +14,16 @@
#
# Design of stress script should allow one:
#
-# - To stress test the mysqltest binary test engine.
-# - To stress test the regular test suite and any additional test suites
-# (such as mysql-test-extra-5.0).
-# - To specify files with lists of tests both for initialization of
-# stress db and for further testing itself.
-# - To define the number of threads to be concurrently used in testing.
-# - To define limitations for the test run. such as the number of tests or
-# loops for execution or duration of testing, delay between test
-# executions, and so forth.
-# - To get a readable log file that can be used for identification of
-# errors that occur during testing.
+# - to use for stress testing mysqltest binary as test engine
+# - to use for stress testing both regular test suite and any
+# additional test suites (e.g. mysql-test-extra-5.0)
+# - to specify files with lists of tests both for initialization of
+# stress db and for further testing itself
+# - to define number of threads that will be concurrently used in testing
+# - to define limitations for test run. e.g. number of tests or loops
+# for execution or duration of testing, delay between test executions, etc.
+# - to get readable log file which can be used for identification of
+# errors arose during testing
#
# Basic scenarios:
#
@@ -58,6 +57,8 @@
# to reproduce and debug errors that was found in continued stress
# testing
#
+# 2009-01-28 OBN Additions and modifications per WL#4685
+#
########################################################################
use Config;
@@ -114,13 +115,15 @@ $opt_stress_mode="random";
$opt_loop_count=0;
$opt_test_count=0;
$opt_test_duration=0;
-$opt_abort_on_error=0;
+# OBN: Changing abort-on-error default to -1 (for WL-4626/4685): -1 means no abort
+$opt_abort_on_error=-1;
$opt_sleep_time = 0;
$opt_threads=1;
$pid_file="mysql_stress_test.pid";
$opt_mysqltest= ($^O =~ /mswin32/i) ? "mysqltest.exe" : "mysqltest";
$opt_check_tests_file="";
-@mysqltest_args=("--silent", "-v", "--skip-safemalloc");
+# OBM adding a setting for 'max-connect-retries=7' the default of 500 is to high
+@mysqltest_args=("--silent", "-v", "--skip-safemalloc", "--max-connect-retries=7");
# Client ip address
$client_ip=inet_ntoa((gethostbyname(hostname()))[4]);
@@ -133,24 +136,31 @@ $client_ip=~ s/\.//g;
#
# S1 - Critical errors - cause immediately abort of testing. These errors
# could be caused by server crash or impossibility
-# of test execution
+# of test execution.
#
# S2 - Serious errors - these errors are bugs for sure as it knowns that
# they shouldn't appear during stress testing
#
-# S3 - Non-seriuos errros - these errors could be caused by fact that
+# S3 - Unknown errors - Errors were returned but we don't know what they are
+# so script can't determine if they are OK or not
+#
+# S4 - Non-seriuos errros - these errors could be caused by fact that
# we execute simultaneously statements that
# affect tests executed by other threads
%error_strings = ( 'Failed in mysql_real_connect()' => S1,
+ 'Can\'t connect' => S1,
'not found (Errcode: 2)' => S1 );
%error_codes = ( 1012 => S2, 1015 => S2, 1021 => S2,
1027 => S2, 1037 => S2, 1038 => S2,
1039 => S2, 1040 => S2, 1046 => S2,
- 1180 => S2, 1181 => S2, 1203 => S2,
- 1205 => S2, 1206 => S2, 1207 => S2,
- 1223 => S2, 2013 => S1);
+ 1053 => S2, 1180 => S2, 1181 => S2,
+ 1203 => S2, 1205 => S4, 1206 => S2,
+ 1207 => S2, 1213 => S4, 1223 => S2,
+ 2002 => S1, 2003 => S1, 2006 => S1,
+ 2013 => S1
+ );
share(%test_counters);
%test_counters=( loop_count => 0, test_count=>0);
@@ -158,6 +168,35 @@ share(%test_counters);
share($exiting);
$exiting=0;
+# OBN Code and 'set_exit_code' function added by ES to set an exit code based on the error category returned
+# in combination with the --abort-on-error value see WL#4685)
+use constant ABORT_MAKEWEIGHT => 20;
+share($gExitCode);
+$gExitCode = 0; # global exit code
+sub set_exit_code {
+ my $severity = shift;
+ my $code = 0;
+ if ( $severity =~ /^S(\d+)/ ) {
+ $severity = $1;
+ $code = 11 - $severity; # S1=10, S2=9, ... -- as per WL
+ }
+ else {
+ # we know how we call the sub: severity should be S<num>; so, we should never be here...
+ print STDERR "Unknown severity format: $severity; setting to S1\n";
+ $severity = 1;
+ }
+ $abort = 0;
+ if ( $severity <= $opt_abort_on_error ) {
+ # the test finished with a failure severe enough to abort. We are adding the 'abort flag' to the exit code
+ $code += ABORT_MAKEWEIGHT;
+ # but are not exiting just yet -- we need to update global exit code first
+ $abort = 1;
+ }
+ lock $gExitCode; # we can use lock here because the script uses threads anyway
+ $gExitCode = $code if $code > $gExitCode;
+ kill INT, $$ if $abort; # this is just a way to call sig_INT_handler: it will set exiting flag, which should do the rest
+}
+
share($test_counters_lock);
$test_counters_lock=0;
share($log_file_lock);
@@ -176,7 +215,8 @@ GetOptions("server-host=s", "server-logs-dir=s", "server-port=s",
"threads=s", "sleep-time=s", "loop-count=i", "test-count=i",
"test-duration=i", "test-suffix=s", "check-tests-file",
"verbose", "log-error-details", "cleanup", "mysqltest=s",
- "abort-on-error", "help") || usage();
+ # OBN: (changing 'abort-on-error' to numberic for WL-4626/4685)
+ "abort-on-error=i" => \$opt_abort_on_error, "help") || usage();
usage() if ($opt_help);
@@ -563,7 +603,15 @@ EOF
if ($opt_test_duration)
{
- sleep($opt_test_duration);
+ # OBN - At this point we need to wait for the duration of the test, hoever
+ # we need to be able to quit if an 'abort-on-error' condition has happend
+ # with one of the children (WL#4685). Using solution by ES and replacing
+ # the 'sleep' command with a loop checking the abort condition every second
+
+ foreach ( 1..$opt_test_duration ) {
+ last if $exiting;
+ sleep 1;
+ }
kill INT, $$; #Interrupt child threads
}
@@ -580,6 +628,8 @@ EOF
print "EXIT\n";
}
+exit $gExitCode; # ES WL#4685: script should return a meaningful exit code
+
sub test_init
{
my ($env)=@_;
@@ -681,7 +731,9 @@ sub test_execute
{
if (!exists($error_codes{$err_code}))
{
- $severity="S3";
+ # OBN Changing severity level to S4 from S3 as S3 now reserved
+ # for the case where the error is unknown (for WL#4626/4685
+ $severity="S4";
$err_code=0;
}
else
@@ -734,6 +786,7 @@ sub test_execute
{
push @{$env->{test_status}}, "Severity $severity: $total";
$env->{errors}->{total}=+$total;
+ set_exit_code($severity);
}
}
@@ -748,18 +801,20 @@ sub test_execute
log_session_errors($env, $test_file);
- if (!$exiting && ($signal_num == 2 || $signal_num == 15 ||
- ($opt_abort_on_error && $env->{errors}->{S1} > 0)))
+ #OBN Removing the case of S1 and abort-on-error as that is now set
+ # inside the set_exit_code function (for WL#4626/4685)
+ #if (!$exiting && ($signal_num == 2 || $signal_num == 15 ||
+ # ($opt_abort_on_error && $env->{errors}->{S1} > 0)))
+ if (!$exiting && ($signal_num == 2 || $signal_num == 15))
{
- #mysqltest was interrupted with INT or TERM signals or test was
- #ran with --abort-on-error option and we got errors with severity S1
+ #mysqltest was interrupted with INT or TERM signals
#so we assume that we should cancel testing and exit
$exiting=1;
+ # OBN - Adjusted text to exclude case of S1 and abort-on-error that
+ # was mentioned (for WL#4626/4685)
print STDERR<<EOF;
WARNING:
- mysqltest was interrupted with INT or TERM signals or test was
- ran with --abort-on-error option and we got errors with severity S1
- (test cann't connect to the server or server crashed) so we assume that
+ mysqltest was interrupted with INT or TERM signals so we assume that
we should cancel testing and exit. Please check log file for this thread
in $stress_log_file or
inspect below output of the last test case executed with mysqltest to
@@ -840,12 +895,23 @@ LOOP:
$client_env{test_count}."]:".
" TID ".$client_env{thread_id}.
" test: '$test_name' ".
- " Errors: ".join(" ",@{$client_env{test_status}}),"\n";
- print "\n";
+ " Errors: ".join(" ",@{$client_env{test_status}}).
+ ( $exiting ? " (thread aborting)" : "" )."\n";
}
- sleep($opt_sleep_time) if($opt_sleep_time);
-
+ # OBN - At this point we need to wait until the 'wait' time between test
+ # executions passes (in case it is specifed) passes, hoever we need
+ # to be able to quit and break out of the test if an 'abort-on-error'
+ # condition has happend with one of the other children (WL#4685).
+ # Using solution by ES and replacing the 'sleep' command with a loop
+ # checking the abort condition every second
+
+ if ( $opt_sleep_time ) {
+ foreach ( 1..$opt_sleep_time ) {
+ last if $exiting;
+ sleep 1;
+ }
+ }
}
}
@@ -1119,6 +1185,9 @@ mysql-stress-test.pl --stress-basedir=<dir> --stress-suite-basedir=<dir> --serve
--cleanup
Force to clean up working directory (specified with --stress-basedir)
+--abort-on-error=<number>
+ Causes the script to abort if an error with severity <= number was encounterd
+
--log-error-details
Enable errors details in the global error log file. (Default: off)
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 526077a7de1..74e2a35798c 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -126,13 +126,9 @@ my $path_config_file; # The generated config file, var/my.cnf
# executables will be used by the test suite.
our $opt_vs_config = $ENV{'MTR_VS_CONFIG'};
-my $DEFAULT_SUITES= "binlog,federated,main,maria,rpl,innodb,parts";
+my $DEFAULT_SUITES= "main,binlog,federated,rpl,innodb,maria,parts";
+my $opt_suites;
-our $opt_usage;
-our $opt_list_options;
-our $opt_suites;
-our $opt_suites_default= "main,backup,backup_engines,binlog,rpl,parts"; # Default suites to run
-our $opt_script_debug= 0; # Script debugging, enable with --script-debug
our $opt_verbose= 0; # Verbose output, enable with --verbose
our $exe_mysql;
our $exe_mysqladmin;
@@ -150,7 +146,7 @@ our @opt_extra_mysqltest_opt;
my $opt_compress;
my $opt_ssl;
my $opt_skip_ssl;
-my $opt_ssl_supported;
+our $opt_ssl_supported;
my $opt_ps_protocol;
my $opt_sp_protocol;
my $opt_cursor_protocol;
@@ -205,10 +201,10 @@ my $opt_mark_progress;
my $opt_sleep;
-my $opt_testcase_timeout= 15; # 15 minutes
-my $opt_suite_timeout = 360; # 6 hours
-my $opt_shutdown_timeout= 10; # 10 seconds
-my $opt_start_timeout = 180; # 180 seconds
+my $opt_testcase_timeout= 15; # minutes
+my $opt_suite_timeout = 300; # minutes
+my $opt_shutdown_timeout= 10; # seconds
+my $opt_start_timeout = 180; # seconds
sub testcase_timeout { return $opt_testcase_timeout * 60; };
sub suite_timeout { return $opt_suite_timeout * 60; };
@@ -216,9 +212,10 @@ sub check_timeout { return $opt_testcase_timeout * 6; };
my $opt_start;
my $opt_start_dirty;
+my $start_only;
my $opt_wait_all;
my $opt_repeat= 1;
-my $opt_retry= 3;
+my $opt_retry= 1;
my $opt_retry_failure= 2;
my $opt_strace_client;
@@ -292,11 +289,6 @@ sub main {
"mysql-5.1-telco-6.2-merge" => "ndb_team",
"mysql-5.1-telco-6.3" => "ndb_team",
"mysql-6.0-ndb" => "ndb_team",
- "mysql-6.0-falcon" => "falcon_team",
- "mysql-6.0-falcon-team" => "falcon_team",
- "mysql-6.0-falcon-wlad" => "falcon_team",
- "mysql-6.0-falcon-chris" => "falcon_team",
- "mysql-6.0-falcon-kevin" => "falcon_team",
);
foreach my $dir ( reverse splitdir($basedir) ) {
@@ -339,7 +331,8 @@ sub main {
for my $limit (2000, 1500, 1000, 500){
$opt_parallel-- if ($sys_info->min_bogomips() < $limit);
}
- $opt_parallel= 8 if ($opt_parallel > 8);
+ my $max_par= $ENV{MTR_MAX_PARALLEL} || 8;
+ $opt_parallel= $max_par if ($opt_parallel > $max_par);
$opt_parallel= $num_tests if ($opt_parallel > $num_tests);
$opt_parallel= 1 if (IS_WINDOWS and $sys_info->isvm());
$opt_parallel= 1 if ($opt_parallel < 1);
@@ -547,7 +540,8 @@ sub run_test_server ($$$) {
}
}
$num_saved_datadir++;
- $num_failed_test++ unless $result->{retries};
+ $num_failed_test++ unless ($result->{retries} ||
+ $result->{exp_fail});
$test_failure= 1;
if ( !$opt_force ) {
@@ -618,8 +612,9 @@ sub run_test_server ($$$) {
my $fake_test= My::Test::read_test($sock);
my $test_list= join (" ", @{$fake_test->{testnames}});
push @$extra_warnings, $test_list;
+ my $report= $fake_test->{'warnings'};
mtr_report("***Warnings generated in error logs during shutdown ".
- "after running tests: $test_list");
+ "after running tests: $test_list\n\n$report");
$test_failure= 1;
if ( !$opt_force ) {
# Test failure due to warnings, force is off
@@ -1052,6 +1047,9 @@ sub command_line_setup {
if ( $opt_experimental )
{
+ # $^O on Windows considered not generic enough
+ my $plat= (IS_WINDOWS) ? 'windows' : $^O;
+
# read the list of experimental test cases from the file specified on
# the command line
open(FILE, "<", $opt_experimental) or mtr_error("Can't read experimental file: $opt_experimental");
@@ -1062,6 +1060,15 @@ sub command_line_setup {
# remove comments (# foo) at the beginning of the line, or after a
# blank at the end of the line
s/( +|^)#.*$//;
+ # If @ platform specifier given, use this entry only if it contains
+ # @<platform> or @!<xxx> where xxx != platform
+ if (/\@.*/)
+ {
+ next if (/\@!$plat/);
+ next unless (/\@$plat/ or /\@!/);
+ # Then remove @ and everything after it
+ s/\@.*$//;
+ }
# remove whitespace
s/^ +//;
s/ +$//;
@@ -1312,8 +1319,6 @@ sub command_line_setup {
{
# Indicate that we are using debugger
$glob_debugger= 1;
- $opt_testcase_timeout= 60*60*24; # Don't abort debugging with timeout
- $opt_suite_timeout= $opt_testcase_timeout;
$opt_retry= 1;
$opt_retry_failure= 1;
@@ -1321,6 +1326,21 @@ sub command_line_setup {
{
mtr_error("Can't use --extern when using debugger");
}
+ # Set one week timeout (check-testcase timeout will be 1/10th)
+ $opt_testcase_timeout= 7 * 24 * 60;
+ $opt_suite_timeout= 7 * 24 * 60;
+ # One day to shutdown
+ $opt_shutdown_timeout= 24 * 60;
+ # One day for PID file creation (this is given in seconds not minutes)
+ $opt_start_timeout= 24 * 60 * 60;
+ }
+
+ # --------------------------------------------------------------------------
+ # Modified behavior with --start options
+ # --------------------------------------------------------------------------
+ if ($opt_start or $opt_start_dirty) {
+ collect_option ('quick-collect', 1);
+ $start_only= 1;
}
if ($opt_debug)
{
@@ -1334,7 +1354,7 @@ sub command_line_setup {
# Check use of wait-all
# --------------------------------------------------------------------------
- if ($opt_wait_all && ! ($opt_start_dirty || $opt_start))
+ if ($opt_wait_all && ! $start_only)
{
mtr_error("--wait-all can only be used with --start or --start-dirty");
}
@@ -1394,6 +1414,9 @@ sub command_line_setup {
push(@valgrind_args, @default_valgrind_args)
unless @valgrind_args;
+ # Make valgrind run in quiet mode so it only print errors
+ push(@valgrind_args, "--quiet" );
+
mtr_report("Running valgrind with options \"",
join(" ", @valgrind_args), "\"");
}
@@ -1609,6 +1632,10 @@ sub collect_mysqld_features_from_running_server ()
}
}
+ # "Convert" innodb flag
+ $mysqld_variables{'innodb'}= "ON"
+ if ($mysqld_variables{'have_innodb'} eq "YES");
+
# Parse version
my $version_str= $mysqld_variables{'version'};
if ( $version_str =~ /^([0-9]*)\.([0-9]*)\.([0-9]*)/ )
@@ -1909,11 +1936,11 @@ sub environment_setup {
# --------------------------------------------------------------------------
# Add the path where mysqld will find ha_example.so
# --------------------------------------------------------------------------
- if ($mysql_version_id >= 50100 && !(IS_WINDOWS && $opt_embedded_server)) {
+ if ($mysql_version_id >= 50100) {
my $plugin_filename;
if (IS_WINDOWS)
{
- $plugin_filename = "ha_example.dll";
+ $plugin_filename = "ha_example.dll";
}
else
{
@@ -1930,7 +1957,7 @@ sub environment_setup {
($lib_example_plugin ? dirname($lib_example_plugin) : "");
$ENV{'HA_EXAMPLE_SO'}="'".$plugin_filename."'";
- $ENV{'EXAMPLE_PLUGIN_LOAD'}="--plugin_load=;EXAMPLE=".$plugin_filename.";";
+ $ENV{'EXAMPLE_PLUGIN_LOAD'}="--plugin_load=EXAMPLE=".$plugin_filename;
}
# ----------------------------------------------------
@@ -2124,6 +2151,7 @@ sub environment_setup {
# Create an environment variable to make it possible
# to detect that valgrind is being used from test cases
$ENV{'VALGRIND_TEST'}= $opt_valgrind;
+
}
@@ -2880,8 +2908,8 @@ sub mysql_install_db {
my $bootstrap_sql_file= "$opt_vardir/tmp/bootstrap.sql";
my $path_sql= my_find_file($install_basedir,
- ["mysql", "sql/share", "share/mariadb",
- "share/mysql", "share", "scripts"],
+ ["mysql", "sql/share", "share/mysql",
+ "share/mariadb", "share", "scripts"],
"mysql_system_tables.sql",
NOT_REQUIRED);
@@ -3004,7 +3032,7 @@ sub run_testcase_check_skip_test($)
if ( $tinfo->{'skip'} )
{
- mtr_report_test_skipped($tinfo);
+ mtr_report_test_skipped($tinfo) unless $start_only;
return 1;
}
@@ -3174,7 +3202,8 @@ test case was executed:\n";
# Unknown process returned, most likley a crash, abort everything
$tinfo->{comment}=
"The server $proc crashed while running ".
- "'check testcase $mode test'";
+ "'check testcase $mode test'".
+ get_log_from_proc($proc, $tinfo->{name});
$result= 3;
}
@@ -3292,7 +3321,8 @@ sub run_on_all($$)
else {
# Unknown process returned, most likley a crash, abort everything
$tinfo->{comment}.=
- "The server $proc crashed while running '$run'";
+ "The server $proc crashed while running '$run'".
+ get_log_from_proc($proc, $tinfo->{name});
}
# Kill any check processes still running
@@ -3407,6 +3437,12 @@ sub run_testcase ($$) {
mtr_verbose("Running test:", $tinfo->{name});
+ # Allow only alpanumerics pluss _ - + . in combination names
+ my $combination= $tinfo->{combination};
+ if ($combination && $combination !~ /^\w[-\w\.\+]+$/)
+ {
+ mtr_error("Combination '$combination' contains illegal characters");
+ }
# -------------------------------------------------------
# Init variables that can change between each test case
# -------------------------------------------------------
@@ -3501,9 +3537,16 @@ sub run_testcase ($$) {
# server exits
# ----------------------------------------------------------------------
- if ( $opt_start or $opt_start_dirty )
+ if ( $start_only )
{
mtr_print("\nStarted", started(all_servers()));
+ mtr_print("Using config for test", $tinfo->{name});
+ mtr_print("Port and socket path for server(s):");
+ foreach my $mysqld ( mysqlds() )
+ {
+ mtr_print ($mysqld->name() . " " . $mysqld->value('port') .
+ " " . $mysqld->value('socket'));
+ }
mtr_print("Waiting for server(s) to exit...");
if ( $opt_wait_all ) {
My::SafeProcess->wait_all();
@@ -3597,7 +3640,7 @@ sub run_testcase ($$) {
my $check_res;
if ( restart_forced_by_test() )
{
- stop_all_servers();
+ stop_all_servers($opt_shutdown_timeout);
}
elsif ( $opt_check_testcases and
$check_res= check_testcase($tinfo, "after"))
@@ -3614,7 +3657,7 @@ sub run_testcase ($$) {
# test.
} else {
# Not checking warnings, so can do a hard shutdown.
- stop_all_servers();
+ stop_all_servers($opt_shutdown_timeout);
}
mtr_report("Resuming tests...\n");
}
@@ -3696,7 +3739,8 @@ sub run_testcase ($$) {
{
# Server failed, probably crashed
$tinfo->{comment}=
- "Server $proc failed during test run";
+ "Server $proc failed during test run" .
+ get_log_from_proc($proc, $tinfo->{name});
# ----------------------------------------------------
# It's not mysqltest that has exited, kill it
@@ -3809,6 +3853,64 @@ sub pre_write_errorlog {
}
}
+# Extract server log from after the last occurrence of named test
+# Return as an array of lines
+#
+
+sub extract_server_log ($$) {
+ my ($error_log, $tname) = @_;
+
+ # Open the servers .err log file and read all lines
+ # belonging to current tets into @lines
+ my $Ferr = IO::File->new($error_log)
+ or mtr_error("Could not open file '$error_log' for reading: $!");
+
+ my @lines;
+ my $found_test= 0; # Set once we've found the log of this test
+ while ( my $line = <$Ferr> )
+ {
+ if ($found_test)
+ {
+ # If test wasn't last after all, discard what we found, test again.
+ if ( $line =~ /^CURRENT_TEST:/)
+ {
+ @lines= ();
+ $found_test= $line =~ /^CURRENT_TEST: $tname/;
+ }
+ else
+ {
+ push(@lines, $line);
+ }
+ }
+ else
+ {
+ # Search for beginning of test, until found
+ $found_test= 1 if ($line =~ /^CURRENT_TEST: $tname/);
+ }
+ }
+ $Ferr = undef; # Close error log file
+
+ return @lines;
+}
+
+# Get log from server identified from its $proc object, from named test
+# Return as a single string
+#
+
+sub get_log_from_proc ($$) {
+ my ($proc, $name)= @_;
+ my $srv_log= "";
+
+ foreach my $mysqld (mysqlds()) {
+ if ($mysqld->{proc} eq $proc) {
+ my @srv_lines= extract_server_log($mysqld->value('#log-error'), $name);
+ $srv_log= "\nServer log from this test:\n" . join ("", @srv_lines);
+ last;
+ }
+ }
+ return $srv_log;
+}
+
#
# Perform a rough examination of the servers
# error log and write all lines that look
@@ -3858,16 +3960,9 @@ sub extract_warning_lines ($) {
my @patterns =
(
- # The patterns for detection of [Warning] and [ERROR]
- # in the server log files have been faulty for a longer period
- # and correcting them shows a few additional harmless warnings.
- # Thus those patterns are temporarily removed from the list
- # of patterns. For more info see BUG#42408
- # qr/^Warning:|mysqld: Warning|\[Warning\]/,
- # qr/^Error:|\[ERROR\]/,
- qr/^Warning:|mysqld: Warning/,
- qr/^Error:/,
- qr/^==.* at 0x/,
+ qr/^Warning:|mysqld: Warning|\[Warning\]/,
+ qr/^Error:|\[ERROR\]/,
+ qr/^==\d*==/, # valgrind errors
qr/InnoDB: Warning|InnoDB: Error/,
qr/^safe_mutex:|allocated at line/,
qr/missing DBUG_RETURN/,
@@ -3886,11 +3981,30 @@ sub extract_warning_lines ($) {
# Perl code.
my @antipatterns =
(
+ qr/error .*connecting to master/,
qr/InnoDB: Error: in ALTER TABLE `test`.`t[12]`/,
qr/InnoDB: Error: table `test`.`t[12]` does not exist in the InnoDB internal/,
+ qr/Slave: Unknown table 't1' Error_code: 1051/,
+ qr/Slave SQL:.*(Error_code: [[:digit:]]+|Query:.*)/,
+ qr/slave SQL thread aborted/,
+ qr/unknown option '--loose-/,
+ qr/unknown variable 'loose-/,
+ qr/Now setting lower_case_table_names to [02]/,
+ qr/Setting lower_case_table_names=2/,
+ qr/deprecated/,
+ qr/Slave SQL thread retried transaction/,
+ qr/Slave \(additional info\)/,
+ qr/Incorrect information in file/,
+ qr/Slave I\/O: Get master SERVER_ID failed with error:.*/,
+ qr/Slave I\/O: Get master clock failed with error:.*/,
+ qr/Slave I\/O: Get master COLLATION_SERVER failed with error:.*/,
+ qr/Slave I\/O: Get master TIME_ZONE failed with error:.*/,
+ qr/Slave I\/O: error reconnecting to master '.*' - retry-time: [1-3] retries/,
+ qr/Error reading packet/,
+ qr/Slave: Can't drop database.* database doesn't exist/,
);
- my $match_count= 0;
+ my $matched_lines= [];
LINE: foreach my $line ( @lines )
{
PAT: foreach my $pat ( @patterns )
@@ -3902,18 +4016,18 @@ sub extract_warning_lines ($) {
next LINE if $line =~ $apat;
}
print $Fwarn $line;
- ++$match_count;
+ push @$matched_lines, $line;
last PAT;
}
}
}
$Fwarn = undef; # Close file
- if ($match_count > 0 &&
+ if (scalar(@$matched_lines) > 0 &&
defined($last_warning_position->{$error_log}{test_names})) {
- return $last_warning_position->{$error_log}{test_names};
+ return ($last_warning_position->{$error_log}{test_names}, $matched_lines);
} else {
- return [];
+ return ([], $matched_lines);
}
}
@@ -3980,7 +4094,7 @@ sub start_check_warnings ($$) {
#
# Loop through our list of processes and check the error log
-# for unexepcted errors and warnings
+# for unexpected errors and warnings
#
sub check_warnings ($) {
my ($tinfo)= @_;
@@ -4067,7 +4181,8 @@ sub check_warnings ($) {
else {
# Unknown process returned, most likley a crash, abort everything
$tinfo->{comment}=
- "The server $proc crashed while running 'check warnings'";
+ "The server $proc crashed while running 'check warnings'".
+ get_log_from_proc($proc, $tinfo->{name});
$result= 3;
}
@@ -4083,18 +4198,24 @@ sub check_warnings ($) {
}
# Check for warnings generated during shutdown of a mysqld server.
-# If any, report them to master server, and return true; else just return false.
+# If any, report them to master server, and return true; else just return
+# false.
+
sub check_warnings_post_shutdown {
my ($server_socket)= @_;
my $testname_hash= { };
+ my $report= '';
foreach my $mysqld ( mysqlds())
{
- my $testlist= extract_warning_lines($mysqld->value('#log-error'));
+ my ($testlist, $match_lines)=
+ extract_warning_lines($mysqld->value('#log-error'));
$testname_hash->{$_}= 1 for @$testlist;
+ $report.= join('', @$match_lines);
}
my @warning_tests= keys(%$testname_hash);
if (@warning_tests) {
my $fake_test= My::Test->new(testnames => \@warning_tests);
+ $fake_test->{'warnings'}= $report;
$fake_test->write_test($server_socket, 'WARNINGS');
}
}
@@ -4343,6 +4464,7 @@ sub mysqld_stop {
mtr_init_args(\$args);
mtr_add_arg($args, "--no-defaults");
+ mtr_add_arg($args, "--character-sets-dir=%s", $mysqld->value('character-sets-dir'));
mtr_add_arg($args, "--user=%s", $opt_user);
mtr_add_arg($args, "--password=");
mtr_add_arg($args, "--port=%d", $mysqld->value('port'));
@@ -4392,7 +4514,7 @@ sub mysqld_arguments ($$$) {
if (!using_extern() and $mysql_version_id >= 50106 )
{
- # Turn on logging to bothe tables and file
+ # Turn on logging to file and tables
mtr_add_arg($args, "%s--log-output=table,file");
}
@@ -4555,7 +4677,8 @@ sub mysqld_start ($$) {
$opt_start_timeout,
$mysqld->{'proc'}))
{
- mtr_error("Failed to start mysqld $mysqld->name()");
+ my $mname= $mysqld->name();
+ mtr_error("Failed to start mysqld $mname with command $exe");
}
# Remember options used when starting
@@ -4566,11 +4689,12 @@ sub mysqld_start ($$) {
sub stop_all_servers () {
+ my $shutdown_timeout = $_[0] or 0;
mtr_verbose("Stopping all servers...");
# Kill all started servers
- My::SafeProcess::shutdown(0, # shutdown timeout 0 => kill
+ My::SafeProcess::shutdown($shutdown_timeout,
started(all_servers()));
# Remove pidfiles
@@ -4940,7 +5064,8 @@ sub start_servers($) {
my $logfile= $mysqld->value('#log-error');
if ( defined $logfile and -f $logfile )
{
- $tinfo->{logfile}= mtr_fromfile($logfile);
+ my @srv_lines= extract_server_log($logfile, $tinfo->{name});
+ $tinfo->{logfile}= "Server log is:\n" . join ("", @srv_lines);
}
else
{
@@ -5369,7 +5494,6 @@ sub valgrind_arguments {
else
{
mtr_add_arg($args, "--tool=memcheck"); # From >= 2.1.2 needs this option
- mtr_add_arg($args, "--alignment=8");
mtr_add_arg($args, "--leak-check=yes");
mtr_add_arg($args, "--num-callers=16");
mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir)
@@ -5468,7 +5592,7 @@ Options to control what test suites or cases to run
staging-run Run a limited number of tests (no slow tests). Used
for running staging trees with valgrind.
enable-disabled Run also tests marked as disabled
- print_testcases Don't run the tests but print details about all the
+ print-testcases Don't run the tests but print details about all the
selected tests, in the order they would be run.
Options that specify ports
diff --git a/mysql-test/r/almost_full.result b/mysql-test/r/almost_full.result
index eb28f12fa51..b2d7092aa51 100644
--- a/mysql-test/r/almost_full.result
+++ b/mysql-test/r/almost_full.result
@@ -1,3 +1,4 @@
+call mtr.add_suppression("The table 't1' is full");
drop table if exists t1;
set global myisam_data_pointer_size=2;
CREATE TABLE t1 (a int auto_increment primary key not null, b longtext) ENGINE=MyISAM;
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index b1e13f0f879..1d41ad3cbf5 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -1175,4 +1175,74 @@ a
42
DROP TABLE t1;
SET @@sql_mode=@save_sql_mode;
+#
+# Bug#45567: Fast ALTER TABLE broken for enum and set
+#
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a ENUM('a1','a2'));
+INSERT INTO t1 VALUES ('a1'),('a2');
+# No copy: No modification
+ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2');
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+# No copy: Add new enumeration to the end
+ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','a3');
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+# Copy: Modify and add new to the end
+ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','xx','a5');
+affected rows: 2
+info: Records: 2 Duplicates: 0 Warnings: 0
+# Copy: Remove from the end
+ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','xx');
+affected rows: 2
+info: Records: 2 Duplicates: 0 Warnings: 0
+# Copy: Add new enumeration
+ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','a0','xx');
+affected rows: 2
+info: Records: 2 Duplicates: 0 Warnings: 0
+# No copy: Add new enumerations to the end
+ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','a0','xx','a5','a6');
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+DROP TABLE t1;
+CREATE TABLE t1 (a SET('a1','a2'));
+INSERT INTO t1 VALUES ('a1'),('a2');
+# No copy: No modification
+ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2');
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+# No copy: Add new to the end
+ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a3');
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+# Copy: Modify and add new to the end
+ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','xx','a5');
+affected rows: 2
+info: Records: 2 Duplicates: 0 Warnings: 0
+# Copy: Remove from the end
+ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','xx');
+affected rows: 2
+info: Records: 2 Duplicates: 0 Warnings: 0
+# Copy: Add new member
+ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a0','xx');
+affected rows: 2
+info: Records: 2 Duplicates: 0 Warnings: 0
+# No copy: Add new to the end
+ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a0','xx','a5','a6');
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+# Copy: Numerical incrase (pack lenght)
+ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a0','xx','a5','a6','a7','a8','a9','a10');
+affected rows: 2
+info: Records: 2 Duplicates: 0 Warnings: 0
+DROP TABLE t1;
+CREATE TABLE t1 (f1 TIMESTAMP NULL DEFAULT NULL,
+f2 INT(11) DEFAULT NULL) ENGINE=MYISAM DEFAULT CHARSET=utf8;
+INSERT INTO t1 VALUES (NULL, NULL), ("2009-10-09 11:46:19", 2);
+this should affect no rows as there is no real change
+ALTER TABLE t1 CHANGE COLUMN f1 f1_no_real_change TIMESTAMP NULL DEFAULT NULL;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/analyse.result b/mysql-test/r/analyse.result
index 6eaa8731dc6..1820782d2f8 100644
--- a/mysql-test/r/analyse.result
+++ b/mysql-test/r/analyse.result
@@ -19,81 +19,10 @@ test.t1.empty_string 0 0 4 0 0.0000 NULL CHAR(0) NOT NULL
test.t1.bool N Y 1 1 0 0 1.0000 NULL ENUM('N','Y') NOT NULL
test.t1.d 2002-03-03 2002-03-05 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL
create table t2 select * from t1 procedure analyse();
-select * from t2;
-Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
-test.t1.i 1 7 1 1 0 0 4.0000 2.2361 ENUM('1','3','5','7') NOT NULL
-test.t1.j 2 8 1 1 0 0 5.0000 2.2361 ENUM('2','4','6','8') NOT NULL
-test.t1.empty_string 0 0 4 0 0.0000 NULL CHAR(0) NOT NULL
-test.t1.bool N Y 1 1 0 0 1.0000 NULL ENUM('N','Y') NOT NULL
-test.t1.d 2002-03-03 2002-03-05 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL
-drop table t1,t2;
+ERROR HY000: Incorrect usage of PROCEDURE and non-SELECT
+drop table t1;
EXPLAIN SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE();
ERROR HY000: Incorrect usage of PROCEDURE and subquery
-create table t1 (a int not null);
-create table t2 select * from t1 where 0=1 procedure analyse();
-show create table t2;
-Table Create Table
-t2 CREATE TABLE `t2` (
- `Field_name` varbinary(255) NOT NULL DEFAULT '',
- `Min_value` varbinary(255) DEFAULT NULL,
- `Max_value` varbinary(255) DEFAULT NULL,
- `Min_length` bigint(11) NOT NULL DEFAULT '0',
- `Max_length` bigint(11) NOT NULL DEFAULT '0',
- `Empties_or_zeros` bigint(11) NOT NULL DEFAULT '0',
- `Nulls` bigint(11) NOT NULL DEFAULT '0',
- `Avg_value_or_avg_length` varbinary(255) NOT NULL DEFAULT '',
- `Std` varbinary(255) DEFAULT NULL,
- `Optimal_fieldtype` varbinary(64) NOT NULL DEFAULT ''
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-select * from t1 where 0=1 procedure analyse();
-Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
-insert into t1 values(1);
-drop table t2;
-create table t2 select * from t1 where 0=1 procedure analyse();
-show create table t2;
-Table Create Table
-t2 CREATE TABLE `t2` (
- `Field_name` varbinary(255) NOT NULL DEFAULT '',
- `Min_value` varbinary(255) DEFAULT NULL,
- `Max_value` varbinary(255) DEFAULT NULL,
- `Min_length` bigint(11) NOT NULL DEFAULT '0',
- `Max_length` bigint(11) NOT NULL DEFAULT '0',
- `Empties_or_zeros` bigint(11) NOT NULL DEFAULT '0',
- `Nulls` bigint(11) NOT NULL DEFAULT '0',
- `Avg_value_or_avg_length` varbinary(255) NOT NULL DEFAULT '',
- `Std` varbinary(255) DEFAULT NULL,
- `Optimal_fieldtype` varbinary(64) NOT NULL DEFAULT ''
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-select * from t2;
-Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
-insert into t2 select * from t1 procedure analyse();
-select * from t2;
-Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
-test.t1.a 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL
-insert into t1 values(2);
-drop table t2;
-create table t2 select * from t1 where 0=1 procedure analyse();
-show create table t2;
-Table Create Table
-t2 CREATE TABLE `t2` (
- `Field_name` varbinary(255) NOT NULL DEFAULT '',
- `Min_value` varbinary(255) DEFAULT NULL,
- `Max_value` varbinary(255) DEFAULT NULL,
- `Min_length` bigint(11) NOT NULL DEFAULT '0',
- `Max_length` bigint(11) NOT NULL DEFAULT '0',
- `Empties_or_zeros` bigint(11) NOT NULL DEFAULT '0',
- `Nulls` bigint(11) NOT NULL DEFAULT '0',
- `Avg_value_or_avg_length` varbinary(255) NOT NULL DEFAULT '',
- `Std` varbinary(255) DEFAULT NULL,
- `Optimal_fieldtype` varbinary(64) NOT NULL DEFAULT ''
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
-select * from t2;
-Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
-insert into t2 select * from t1 procedure analyse();
-select * from t2;
-Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
-test.t1.a 1 2 1 1 0 0 1.5000 0.5000 ENUM('1','2') NOT NULL
-drop table t1,t2;
create table t1 (v varchar(128));
insert into t1 values ('abc'),('abc\'def\\hij\"klm\0opq'),('\''),('\"'),('\\'),('a\0'),('b\''),('c\"'),('d\\'),('\'b'),('\"c'),('\\d'),('a\0\0\0b'),('a\'\'\'\'b'),('a\"\"\"\"b'),('a\\\\\\\\b'),('\'\0\\\"'),('\'\''),('\"\"'),('\\\\'),('The\ZEnd');
select * from t1 procedure analyse();
@@ -157,3 +86,40 @@ SELECT * FROM (SELECT * FROM t1) d PROCEDURE ANALYSE();
ERROR HY000: Incorrect usage of PROCEDURE and subquery
DROP TABLE t1;
End of 4.1 tests
+#
+# Bug #48293: crash with procedure analyse, view with > 10 columns,
+# having clause...
+#
+CREATE TABLE t1(a INT, b INT, c INT, d INT, e INT,
+f INT, g INT, h INT, i INT, j INT,k INT);
+INSERT INTO t1 VALUES (),();
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+#should have a derived table
+EXPLAIN SELECT * FROM v1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ALL NULL NULL NULL NULL 2
+#should not crash
+SELECT * FROM v1 PROCEDURE analyse();
+ERROR HY000: Incorrect usage of PROCEDURE and view
+#should not crash
+SELECT * FROM t1 a, v1, t1 b PROCEDURE analyse();
+ERROR HY000: Incorrect usage of PROCEDURE and view
+#should not crash
+SELECT * FROM (SELECT * FROM t1 having a > 1) x PROCEDURE analyse();
+ERROR HY000: Incorrect usage of PROCEDURE and subquery
+#should not crash
+SELECT * FROM t1 a, (SELECT * FROM t1 having a > 1) x, t1 b PROCEDURE analyse();
+ERROR HY000: Incorrect usage of PROCEDURE and subquery
+#should not crash
+SELECT 1 FROM t1 group by a having a > 1 order by 1 PROCEDURE analyse();
+ERROR HY000: Can't use ORDER clause with this procedure
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1),(2);
+# should not crash
+CREATE TABLE t2 SELECT 1 FROM t1, t1 t3 GROUP BY t3.a PROCEDURE ANALYSE();
+ERROR HY000: Incorrect usage of PROCEDURE and non-SELECT
+DROP TABLE t1;
+End of 5.0 tests
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result
index 8c26ea1ff82..e865d775c6a 100644
--- a/mysql-test/r/archive.result
+++ b/mysql-test/r/archive.result
@@ -12695,3 +12695,25 @@ a b
1 NULL
2 NULL
DROP TABLE t1;
+CREATE TABLE t1(a INT, b BLOB) ENGINE=archive;
+SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM
+INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test';
+DATA_LENGTH AVG_ROW_LENGTH
+8666 15
+INSERT INTO t1 VALUES(1, 'sampleblob1'),(2, 'sampleblob2');
+SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM
+INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test';
+DATA_LENGTH AVG_ROW_LENGTH
+8700 4350
+DROP TABLE t1;
+SET @save_join_buffer_size= @@join_buffer_size;
+SET @@join_buffer_size= 8228;
+CREATE TABLE t1(a CHAR(255)) ENGINE=archive;
+INSERT INTO t1 VALUES('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
+('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
+('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
+SELECT COUNT(t1.a) FROM t1, t1 a, t1 b, t1 c, t1 d, t1 e;
+COUNT(t1.a)
+729
+DROP TABLE t1;
+SET @@join_buffer_size= @save_join_buffer_size;
diff --git a/mysql-test/r/bug40113.result b/mysql-test/r/bug40113.result
deleted file mode 100644
index 289037a3f35..00000000000
--- a/mysql-test/r/bug40113.result
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Bug #40113: Embedded SELECT inside UPDATE or DELETE can timeout
-# without error
-#
-CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b)) ENGINE=InnoDB;
-INSERT INTO t1 (a,b) VALUES (1070109,99);
-CREATE TABLE t2 (b int, a int, PRIMARY KEY (b)) ENGINE=InnoDB;
-INSERT INTO t2 (b,a) VALUES (7,1070109);
-SELECT * FROM t1;
-a b
-1070109 99
-BEGIN;
-SELECT b FROM t2 WHERE b=7 FOR UPDATE;
-b
-7
-BEGIN;
-SELECT b FROM t2 WHERE b=7 FOR UPDATE;
-ERROR HY000: Lock wait timeout exceeded; try restarting transaction
-INSERT INTO t1 (a) VALUES ((SELECT a FROM t2 WHERE b=7));
-ERROR HY000: Lock wait timeout exceeded; try restarting transaction
-UPDATE t1 SET a='7000000' WHERE a=(SELECT a FROM t2 WHERE b=7);
-ERROR HY000: Lock wait timeout exceeded; try restarting transaction
-DELETE FROM t1 WHERE a=(SELECT a FROM t2 WHERE b=7);
-ERROR HY000: Lock wait timeout exceeded; try restarting transaction
-SELECT * FROM t1;
-a b
-1070109 99
-DROP TABLE t2, t1;
-End of 5.0 tests
diff --git a/mysql-test/r/bug46080.result b/mysql-test/r/bug46080.result
index 18c7c22829a..2173768cdad 100644
--- a/mysql-test/r/bug46080.result
+++ b/mysql-test/r/bug46080.result
@@ -2,6 +2,8 @@
# Bug #46080: group_concat(... order by) crashes server when
# sort_buffer_size cannot allocate
#
+call mtr.add_suppression("Out of memory at line .*, 'my_alloc.c'");
+call mtr.add_suppression("needed .* byte .*k., memory in use: .* bytes .*k");
CREATE TABLE t1(a CHAR(255));
INSERT INTO t1 VALUES ('a');
SET @@SESSION.sort_buffer_size=5*16*1000000;
diff --git a/mysql-test/r/bug46760.result b/mysql-test/r/bug46760.result
new file mode 100644
index 00000000000..413df050b10
--- /dev/null
+++ b/mysql-test/r/bug46760.result
@@ -0,0 +1,43 @@
+#
+# Bug#46760: Fast ALTER TABLE no longer works for InnoDB
+#
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+# By using --enable_info and verifying that number of affected
+# rows is 0 we check that this ALTER TABLE is really carried
+# out as "fast/online" operation, i.e. without full-blown data
+# copying.
+#
+# I.e. info for the below statement should normally look like:
+#
+# affected rows: 0
+# info: Records: 0 Duplicates: 0 Warnings: 0
+ALTER TABLE t1 ALTER COLUMN a SET DEFAULT 10;
+affected rows: 0
+info: Records: 0 Duplicates: 0 Warnings: 0
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT '10'
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t1;
+#
+# MySQL Bug#39200: optimize table does not recognize
+# ROW_FORMAT=COMPRESSED
+#
+CREATE TABLE t1 (a INT) ROW_FORMAT=compressed;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED
+OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status Table is already up to date
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED
+DROP TABLE t1;
+End of 5.1 tests
diff --git a/mysql-test/r/case_insensitive_fs.require b/mysql-test/r/case_insensitive_fs.require
new file mode 100644
index 00000000000..062ac610ddd
--- /dev/null
+++ b/mysql-test/r/case_insensitive_fs.require
@@ -0,0 +1,2 @@
+Variable_name Value
+lower_case_file_system ON
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index 88e4bade130..29686d6e023 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -1588,6 +1588,19 @@ CREATE TABLE IF NOT EXISTS t2 (a INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY)
SELECT a FROM t1;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
DROP TABLE t1, t2;
+#
+# BUG#46384 - mysqld segfault when trying to create table with same
+# name as existing view
+#
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t1 VALUES (1),(2),(3);
+INSERT INTO t2 VALUES (1),(2),(3);
+CREATE VIEW v1 AS SELECT t1.a FROM t1, t2;
+CREATE TABLE v1 AS SELECT * FROM t1;
+ERROR 42S01: Table 'v1' already exists
+DROP VIEW v1;
+DROP TABLE t1,t2;
End of 5.0 tests
CREATE TABLE t1 (a int, b int);
insert into t1 values (1,1),(1,2);
diff --git a/mysql-test/r/ctype_ldml.result b/mysql-test/r/ctype_ldml.result
index 711921eb526..d5585dcfad9 100644
--- a/mysql-test/r/ctype_ldml.result
+++ b/mysql-test/r/ctype_ldml.result
@@ -41,6 +41,14 @@ efgh efgh
ijkl ijkl
DROP TABLE t1;
#
+# Bug#45645 Mysql server close all connection and restart using lower function
+#
+CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET utf8 COLLATE utf8_test_ci;
+INSERT INTO t1 (a) VALUES ('hello!');
+SELECT * FROM t1 WHERE LOWER(a)=LOWER('N');
+a
+DROP TABLE t1;
+#
# Bug#43827 Server closes connections and restarts
#
CREATE TABLE t1 (c1 VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_test_ci);
@@ -321,3 +329,11 @@ Vv
Xx
YyÃýỲỳỴỵỶỷỸỹ
drop table t1;
+Bug#46448 trailing spaces are not ignored when user collation maps space != 0x20
+set names latin1;
+show collation like 'latin1_test';
+Collation Charset Id Default Compiled Sortlen
+latin1_test latin1 99 Yes 1
+select "foo" = "foo " collate latin1_test;
+"foo" = "foo " collate latin1_test
+1
diff --git a/mysql-test/r/ctype_uca.result b/mysql-test/r/ctype_uca.result
index 04727f84ff2..d51cd2b1d06 100644
--- a/mysql-test/r/ctype_uca.result
+++ b/mysql-test/r/ctype_uca.result
@@ -159,6 +159,7 @@ insert into t1 values (_ucs2 0x01fc),(_ucs2 0x01fd),(_ucs2 0x01fe),(_ucs2 0x01ff
insert into t1 values ('AA'),('Aa'),('aa'),('aA');
insert into t1 values ('CH'),('Ch'),('ch'),('cH');
insert into t1 values ('DZ'),('Dz'),('dz'),('dZ');
+insert into t1 values ('DŽ'),('Dž'),('dž'),('dŽ');
insert into t1 values ('IJ'),('Ij'),('ij'),('iJ');
insert into t1 values ('LJ'),('Lj'),('lj'),('lJ');
insert into t1 values ('LL'),('Ll'),('ll'),('lL');
@@ -181,7 +182,7 @@ C,c,Ç,ç,Ć,ć,Ĉ,ĉ,ÄŠ,Ä‹,ÄŒ,Ä
CH,Ch,cH,ch
Ƈ,ƈ
D,d,ÄŽ,Ä
-DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DZ,Dz,DŽ,Dž,dZ,dz,dŽ,dž,DŽ,Dž,dž,DZ,Dz,dz
Ä,Ä‘
Ɖ
ÆŠ
@@ -286,7 +287,7 @@ C,c,Ç,ç,Ć,ć,Ĉ,ĉ,ÄŠ,Ä‹,ÄŒ,Ä
CH,Ch,cH,ch
Ƈ,ƈ
D,d,ÄŽ,Ä
-DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DZ,Dz,DŽ,Dž,dZ,dz,dŽ,dž,DŽ,Dž,dž,DZ,Dz,dz
Ã,ð
Ä,Ä‘
Ɖ
@@ -400,6 +401,7 @@ CH,Ch,cH,ch
Ƈ,ƈ
D,d,ÄŽ,Ä
DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DŽ,Dž,dŽ,dž
Ä,Ä‘
Ɖ
ÆŠ
@@ -513,7 +515,7 @@ C,c,Ç,ç,Ć,ć,Ĉ,ĉ,ÄŠ,Ä‹,ÄŒ,Ä
CH,Ch,cH,ch
Ƈ,ƈ
D,d,ÄŽ,Ä
-DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DZ,Dz,DŽ,Dž,dZ,dz,dŽ,dž,DŽ,Dž,dž,DZ,Dz,dz
Ä,Ä‘
Ɖ
ÆŠ
@@ -622,6 +624,7 @@ CH,Ch,cH,ch
Ƈ,ƈ
D,d,ÄŽ,Ä
DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DŽ,Dž,dŽ,dž
Ä,Ä‘
Ɖ
ÆŠ
@@ -729,7 +732,7 @@ CH,Ch,cH,ch
Ć,ć
Ƈ,ƈ
D,d,ÄŽ,Ä
-DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DZ,Dz,DŽ,Dž,dZ,dz,dŽ,dž,DŽ,Dž,dž,DZ,Dz,dz
Ä,Ä‘
Ɖ
ÆŠ
@@ -840,6 +843,7 @@ CH,Ch,cH,ch
Ƈ,ƈ
D,d,ÄŽ,Ä
DZ,Dz,dZ,dz
+DŽ,Dž,dŽ,dž
DŽ,Dž,dž,DZ,Dz,dz
Ä,Ä‘
Ɖ
@@ -951,7 +955,7 @@ C,c,Ç,ç,Ć,ć,Ĉ,ĉ,ÄŠ,Ä‹,ÄŒ,Ä
CH,Ch,cH,ch
Ƈ,ƈ
D,d,ÄŽ,Ä
-DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DZ,Dz,DŽ,Dž,dZ,dz,dŽ,dž,DŽ,Dž,dž,DZ,Dz,dz
Ä,Ä‘
Ɖ
ÆŠ
@@ -1056,7 +1060,7 @@ C,c,Ç,ç,Ć,ć,Ĉ,ĉ,ÄŠ,Ä‹,ÄŒ,Ä
CH,Ch,cH,ch
Ƈ,ƈ
D,d,ÄŽ,Ä
-DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DZ,Dz,DŽ,Dž,dZ,dz,dŽ,dž,DŽ,Dž,dž,DZ,Dz,dz
Ä,Ä‘
Ɖ
ÆŠ
@@ -1164,7 +1168,7 @@ CH,Ch,cH,ch
Ç,ç
Ƈ,ƈ
D,d,ÄŽ,Ä
-DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DZ,Dz,DŽ,Dž,dZ,dz,dŽ,dž,DŽ,Dž,dž,DZ,Dz,dz
Ä,Ä‘
Ɖ
ÆŠ
@@ -1275,6 +1279,7 @@ cH
Ƈ,ƈ
D,d,ÄŽ,Ä
DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DŽ,Dž,dŽ,dž
Ä,Ä‘
Ɖ
ÆŠ
@@ -1382,7 +1387,7 @@ C,c,Ç,ç,Ć,ć,Ĉ,ĉ,ÄŠ,Ä‹,ÄŒ,Ä
CH,Ch,cH,ch
Ƈ,ƈ
D,d,ÄŽ,Ä
-DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DZ,Dz,DŽ,Dž,dZ,dz,dŽ,dž,DŽ,Dž,dž,DZ,Dz,dz
Ä,Ä‘
Ɖ
ÆŠ
@@ -1491,6 +1496,7 @@ cH
Ƈ,ƈ
D,d,ÄŽ,Ä
DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DŽ,Dž,dŽ,dž
Ä,Ä‘
Ɖ
ÆŠ
@@ -1599,6 +1605,7 @@ cH
Ƈ,ƈ
D,d,ÄŽ,Ä
DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DŽ,Dž,dŽ,dž
Ä,Ä‘
Ɖ
ÆŠ
@@ -1707,7 +1714,7 @@ cH
CH,Ch,ch
Ƈ,ƈ
D,d,ÄŽ,Ä
-DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DZ,Dz,DŽ,Dž,dZ,dz,dŽ,dž,DŽ,Dž,dž,DZ,Dz,dz
Ä,Ä‘
Ɖ
ÆŠ
@@ -1813,7 +1820,7 @@ C,c,Ç,ç,Ć,ć,Ĉ,ĉ,ÄŠ,Ä‹,ÄŒ,Ä
CH,Ch,cH,ch
Ƈ,ƈ
D,d,ÄŽ,Ä
-DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DZ,Dz,DŽ,Dž,dZ,dz,dŽ,dž,DŽ,Dž,dž,DZ,Dz,dz
Ä,Ä‘
Ɖ
ÆŠ
@@ -1921,7 +1928,7 @@ CH,Ch,cH,ch
Ĉ,ĉ
Ƈ,ƈ
D,d,ÄŽ,Ä
-DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DZ,Dz,DŽ,Dž,dZ,dz,dŽ,dž,DŽ,Dž,dž,DZ,Dz,dz
Ä,Ä‘
Ɖ
ÆŠ
@@ -2030,7 +2037,7 @@ C,c,Ç,ç,Ć,ć,Ĉ,ĉ,ÄŠ,Ä‹,ÄŒ,Ä
CH,Ch,cH,ch
Ƈ,ƈ
D,d,ÄŽ,Ä
-DZ,Dz,dZ,dz,DŽ,Dž,dž,DZ,Dz,dz
+DZ,Dz,DŽ,Dž,dZ,dz,dŽ,dž,DŽ,Dž,dž,DZ,Dz,dz
Ä,Ä‘
Ɖ
ÆŠ
@@ -2121,6 +2128,118 @@ Z,z,Ź,ź,Ż,ż,Ž,ž
Ç
Ç‚
ǃ
+select group_concat(c1 order by c1) from t1 group by c1 collate utf8_croatian_ci;
+group_concat(c1 order by c1)
+÷
+×
+A,a,À,Ã,Â,Ã,Ä,Ã…,à,á,â,ã,ä,Ã¥,Ä€,Ä,Ä‚,ă,Ä„,Ä…,Ç,ÇŽ,Çž,ÇŸ,Ç ,Ç¡,Ǻ,Ç»
+AA,Aa,aA,aa
+Æ,æ,Ǣ,ǣ,Ǽ,ǽ
+B,b
+Æ€
+Ƃ,ƃ
+C,c,Ç,ç,Ĉ,ĉ,Ċ,ċ
+CH,Ch,cH,ch
+ÄŒ,Ä
+Ć,ć
+Ƈ,ƈ
+D,d,ÄŽ,Ä
+DZ,Dz,dZ,dz,DZ,Dz,dz
+dŽ
+DŽ,Dž,dž,DŽ,Dž,dž
+Ä,Ä‘
+Ɖ
+ÆŠ
+Ƌ,ƌ
+Ã,ð
+E,e,È,É,Ê,Ë,è,é,ê,ë,Ē,ē,Ĕ,ĕ,Ė,ė,Ę,ę,Ě,ě
+ÆŽ,Ç
+F,f
+Æ‘,Æ’
+G,g,Äœ,Ä,Äž,ÄŸ,Ä ,Ä¡,Ä¢,Ä£,Ǧ,ǧ,Ç´,ǵ
+Ǥ,ǥ
+Æ“
+Æ”
+Æ¢,Æ£
+H,h,Ĥ,ĥ
+ƕ,Ƕ
+Ħ,ħ
+I,i,ÃŒ,Ã,ÃŽ,Ã,ì,í,î,ï,Ĩ,Ä©,Ī,Ä«,Ĭ,Ä­,Ä®,į,Ä°,Ç,Ç
+IJ,Ij,iJ,ij,IJ,ij
+ı
+Æ—
+Æ–
+J,j,Ĵ,ĵ,ǰ
+K,k,Ķ,ķ,Ǩ,ǩ
+Ƙ,ƙ
+L,l,Ĺ,ĺ,Ļ,ļ,Ľ,ľ
+Ä¿,Å€
+lJ
+LL,Ll,lL,ll
+LJ,Lj,lj,LJ,Lj,lj
+Å,Å‚
+Æš
+Æ›
+M,m
+N,n,Ñ,ñ,Ń,ń,Ņ,ņ,Ň,ň,Ǹ,ǹ
+nJ
+NJ,Nj,nj,NJ,Nj,nj
+Æž
+ÅŠ,Å‹
+O,o,Ã’,Ó,Ô,Õ,Ö,ò,ó,ô,õ,ö,ÅŒ,Å,ÅŽ,Å,Å,Å‘,Æ ,Æ¡,Ç‘,Ç’,Ǫ,Ç«,Ǭ,Ç­
+OE,Oe,oE,oe,Å’,Å“
+Ø,ø,Ǿ,ǿ
+Ɔ
+ÆŸ
+P,p
+Ƥ,ƥ
+Q,q
+ĸ
+R,r,Ŕ,ŕ,Ŗ,ŗ,Ř,ř
+RR,Rr,rR,rr
+Ʀ
+S,s,Åš,Å›,Åœ,Å,Åž,ÅŸ,Å¿
+SS,Ss,sS,ss,ß
+Å ,Å¡
+Æ©
+ƪ
+T,t,Ţ,ţ,Ť,ť
+ƾ
+Ŧ,ŧ
+Æ«
+Ƭ,ƭ
+Æ®
+U,u,Ù,Ú,Û,Ü,ù,ú,û,ü,Ũ,ũ,Ū,ū,Ŭ,ŭ,Ů,ů,Ű,ű,Ų,ų,Ư,ư,Ǔ,ǔ,Ǖ,ǖ,Ǘ,ǘ,Ǚ,ǚ,Ǜ,ǜ
+Ɯ
+Ʊ
+V,v
+Ʋ
+W,w,Ŵ,ŵ
+X,x
+Y,y,Ã,ý,ÿ,Ŷ,Å·,Ÿ
+Ƴ,ƴ
+Z,z,Ź,ź,Ż,ż
+Ž,ž
+Ƶ,ƶ
+Ʒ,Ǯ,ǯ
+Ƹ,ƹ
+ƺ
+Þ,þ
+Æ¿,Ç·
+Æ»
+Ƨ,ƨ
+Ƽ,ƽ
+Æ„,Æ…
+ʼn
+Ç€
+Ç‚
+ǃ
drop table t1;
SET NAMES utf8;
CREATE TABLE t1 (c varchar(255) NOT NULL COLLATE utf8_general_ci, INDEX (c));
diff --git a/mysql-test/r/debug_sync.result b/mysql-test/r/debug_sync.result
new file mode 100644
index 00000000000..47e968f79cf
--- /dev/null
+++ b/mysql-test/r/debug_sync.result
@@ -0,0 +1,277 @@
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE IF EXISTS t1;
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: ''
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 EXECUTE 2 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 EXECUTE 2';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2';
+SET DEBUG_SYNC='p0 SIGNAL s1 EXECUTE 2 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 SIGNAL s1 EXECUTE 2';
+SET DEBUG_SYNC='p0 SIGNAL s1 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 SIGNAL s1';
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2';
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 6 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 6';
+SET DEBUG_SYNC='p0 WAIT_FOR s2 EXECUTE 2 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 WAIT_FOR s2 EXECUTE 2';
+SET DEBUG_SYNC='p0 WAIT_FOR s2 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 WAIT_FOR s2';
+SET DEBUG_SYNC='p0 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 CLEAR';
+SET DEBUG_SYNC='p0 TEST';
+SET DEBUG_SYNC='RESET';
+set debug_sync='p0 signal s1 wait_for s2 timeout 6 execute 2 hit_limit 3';
+set debug_sync='p0 signal s1 wait_for s2 timeout 6 execute 2';
+set debug_sync='p0 signal s1 wait_for s2 timeout 6 hit_limit 3';
+set debug_sync='p0 signal s1 wait_for s2 timeout 6';
+set debug_sync='p0 signal s1 wait_for s2 execute 2 hit_limit 3';
+set debug_sync='p0 signal s1 wait_for s2 execute 2';
+set debug_sync='p0 signal s1 wait_for s2 hit_limit 3';
+set debug_sync='p0 signal s1 wait_for s2';
+set debug_sync='p0 signal s1 execute 2 hit_limit 3';
+set debug_sync='p0 signal s1 execute 2';
+set debug_sync='p0 signal s1 hit_limit 3';
+set debug_sync='p0 signal s1';
+set debug_sync='p0 wait_for s2 timeout 6 execute 2 hit_limit 3';
+set debug_sync='p0 wait_for s2 timeout 6 execute 2';
+set debug_sync='p0 wait_for s2 timeout 6 hit_limit 3';
+set debug_sync='p0 wait_for s2 timeout 6';
+set debug_sync='p0 wait_for s2 execute 2 hit_limit 3';
+set debug_sync='p0 wait_for s2 execute 2';
+set debug_sync='p0 wait_for s2 hit_limit 3';
+set debug_sync='p0 wait_for s2';
+set debug_sync='p0 hit_limit 3';
+set debug_sync='p0 clear';
+set debug_sync='p0 test';
+set debug_sync='reset';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6
+ EXECUTE 2 HIT_LIMIT 3';
+SET DEBUG_SYNC=' p0 SIGNAL s1 WAIT_FOR s2';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 ';
+SET DEBUG_SYNC=' p0 SIGNAL s1 WAIT_FOR s2 ';
+SET DEBUG_SYNC=' p0 SIGNAL s1 WAIT_FOR s2 ';
+SET DEBUG_SYNC='';
+ERROR 42000: Missing synchronization point name
+SET DEBUG_SYNC=' ';
+ERROR 42000: Missing synchronization point name
+SET DEBUG_SYNC='p0';
+ERROR 42000: Missing action after synchronization point name 'p0'
+SET DEBUG_SYNC='p0 EXECUTE 2';
+ERROR 42000: Missing action before EXECUTE
+SET DEBUG_SYNC='p0 TIMEOUT 6 EXECUTE 2';
+ERROR 42000: Illegal or out of order stuff: 'TIMEOUT'
+SET DEBUG_SYNC='p0 TIMEOUT 6';
+ERROR 42000: Illegal or out of order stuff: 'TIMEOUT'
+SET DEBUG_SYNC='p0 WAIT_FOR s2 SIGNAL s1';
+ERROR 42000: Illegal or out of order stuff: 'SIGNAL'
+SET DEBUG_SYNC='p0 WAIT_FOR s2 SIGNAL s1 EXECUTE 2';
+ERROR 42000: Illegal or out of order stuff: 'SIGNAL'
+SET DEBUG_SYNC='p0 WAIT_FOR s2 SIGNAL s1 TIMEOUT 6 EXECUTE 2';
+ERROR 42000: Illegal or out of order stuff: 'SIGNAL'
+SET DEBUG_SYNC='p0 WAIT_FOR s2 SIGNAL s1 TIMEOUT 6';
+ERROR 42000: Illegal or out of order stuff: 'SIGNAL'
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 6 SIGNAL s1 EXECUTE 2';
+ERROR 42000: Illegal or out of order stuff: 'SIGNAL'
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 6 SIGNAL s1';
+ERROR 42000: Illegal or out of order stuff: 'SIGNAL'
+SET DEBUG_SYNC='p0 TIMEOUT 6 WAIT_FOR s2 EXECUTE 2';
+ERROR 42000: Illegal or out of order stuff: 'TIMEOUT'
+SET DEBUG_SYNC='p0 TIMEOUT 6 WAIT_FOR s2';
+ERROR 42000: Illegal or out of order stuff: 'TIMEOUT'
+SET DEBUG_SYNC='p0 SIGNAL s1 TIMEOUT 6 EXECUTE 2';
+ERROR 42000: Illegal or out of order stuff: 'TIMEOUT'
+SET DEBUG_SYNC='p0 SIGNAL s1 TIMEOUT 6';
+ERROR 42000: Illegal or out of order stuff: 'TIMEOUT'
+SET DEBUG_SYNC='p0 EXECUTE 2 SIGNAL s1 TIMEOUT 6';
+ERROR 42000: Missing action before EXECUTE
+SET DEBUG_SYNC='p0 TIMEOUT 6 SIGNAL s1';
+ERROR 42000: Illegal or out of order stuff: 'TIMEOUT'
+SET DEBUG_SYNC='p0 EXECUTE 2 TIMEOUT 6 SIGNAL s1';
+ERROR 42000: Missing action before EXECUTE
+SET DEBUG_SYNC='p0 CLEAR HIT_LIMIT 3';
+ERROR 42000: Nothing must follow action CLEAR
+SET DEBUG_SYNC='CLEAR';
+ERROR 42000: Missing action after synchronization point name 'CLEAR'
+SET DEBUG_SYNC='p0 CLEAR p0';
+ERROR 42000: Nothing must follow action CLEAR
+SET DEBUG_SYNC='TEST';
+ERROR 42000: Missing action after synchronization point name 'TEST'
+SET DEBUG_SYNC='p0 TEST p0';
+ERROR 42000: Nothing must follow action TEST
+SET DEBUG_SYNC='p0 RESET';
+ERROR 42000: Illegal or out of order stuff: 'RESET'
+SET DEBUG_SYNC='RESET p0';
+ERROR 42000: Illegal or out of order stuff: 'p0'
+SET DEBUG_SYNC='p0 RESET p0';
+ERROR 42000: Illegal or out of order stuff: 'RESET'
+SET DEBUG_SYNC='p0 SIGNAL ';
+ERROR 42000: Missing signal name after action SIGNAL
+SET DEBUG_SYNC='p0 WAIT_FOR ';
+ERROR 42000: Missing signal name after action WAIT_FOR
+SET DEBUG_SYNC='p0 SIGNAL s1 EXECUTE ';
+ERROR 42000: Missing valid number after EXECUTE
+SET DEBUG_SYNCx='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2 HIT_LIMIT 3';
+ERROR HY000: Unknown system variable 'DEBUG_SYNCx'
+SET DEBUG_SYNC='p0 SIGNAx s1 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2 HIT_LIMIT 3';
+ERROR 42000: Illegal or out of order stuff: 'SIGNAx'
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOx s2 TIMEOUT 6 EXECUTE 2 HIT_LIMIT 3';
+ERROR 42000: Illegal or out of order stuff: 'WAIT_FOx'
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUx 0 EXECUTE 2 HIT_LIMIT 3';
+ERROR 42000: Illegal or out of order stuff: 'TIMEOUx'
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 EXECUTx 2 HIT_LIMIT 3';
+ERROR 42000: Illegal or out of order stuff: 'EXECUTx'
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2 HIT_LIMIx 3';
+ERROR 42000: Illegal or out of order stuff: 'HIT_LIMIx'
+SET DEBUG_SYNC='p0 CLEARx';
+ERROR 42000: Illegal or out of order stuff: 'CLEARx'
+SET DEBUG_SYNC='p0 TESTx';
+ERROR 42000: Illegal or out of order stuff: 'TESTx'
+SET DEBUG_SYNC='RESETx';
+ERROR 42000: Missing action after synchronization point name 'RESETx'
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 0x6 EXECUTE 2 HIT_LIMIT 3';
+ERROR 42000: Missing valid number after TIMEOUT
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 6 EXECUTE 0x2 HIT_LIMIT 3';
+ERROR 42000: Missing valid number after EXECUTE
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 7 EXECUTE 2 HIT_LIMIT 0x3';
+ERROR 42000: Missing valid number after HIT_LIMIT
+SET DEBUG_SYNC= 7;
+ERROR 42000: Incorrect argument type to variable 'debug_sync'
+SET GLOBAL DEBUG_SYNC= 'p0 CLEAR';
+ERROR HY000: Variable 'debug_sync' is a SESSION variable and can't be used with SET GLOBAL
+SET @myvar= 'now SIGNAL from_myvar';
+SET DEBUG_SYNC= @myvar;
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: 'from_myvar'
+SET DEBUG_SYNC= LEFT('now SIGNAL from_function_cut_here', 24);
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: 'from_function'
+SET DEBUG_SYNC= 'now SIGNAL something';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: 'something'
+SET DEBUG_SYNC= 'now WAIT_FOR nothing TIMEOUT 0';
+Warnings:
+Warning #### debug sync point wait timed out
+SET DEBUG_SYNC= 'now SIGNAL nothing';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: 'nothing'
+SET DEBUG_SYNC= 'now WAIT_FOR nothing TIMEOUT 0';
+SET DEBUG_SYNC= 'now SIGNAL something EXECUTE 0';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: 'nothing'
+SET DEBUG_SYNC= 'now WAIT_FOR anotherthing TIMEOUT 0 EXECUTE 0';
+SET DEBUG_SYNC= 'now HIT_LIMIT 1';
+ERROR HY000: debug sync point hit limit reached
+SET DEBUG_SYNC= 'RESET';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: ''
+SET DEBUG_SYNC= 'p1abcd SIGNAL s1 EXECUTE 2';
+SET DEBUG_SYNC= 'p2abc SIGNAL s2 EXECUTE 2';
+SET DEBUG_SYNC= 'p9abcdef SIGNAL s9 EXECUTE 2';
+SET DEBUG_SYNC= 'p4a SIGNAL s4 EXECUTE 2';
+SET DEBUG_SYNC= 'p5abcde SIGNAL s5 EXECUTE 2';
+SET DEBUG_SYNC= 'p6ab SIGNAL s6 EXECUTE 2';
+SET DEBUG_SYNC= 'p7 SIGNAL s7 EXECUTE 2';
+SET DEBUG_SYNC= 'p8abcdef SIGNAL s8 EXECUTE 2';
+SET DEBUG_SYNC= 'p3abcdef SIGNAL s3 EXECUTE 2';
+SET DEBUG_SYNC= 'p4a TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: 's4'
+SET DEBUG_SYNC= 'p1abcd TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: 's1'
+SET DEBUG_SYNC= 'p7 TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: 's7'
+SET DEBUG_SYNC= 'p9abcdef TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: 's9'
+SET DEBUG_SYNC= 'p3abcdef TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: 's3'
+SET DEBUG_SYNC= 'p1abcd CLEAR';
+SET DEBUG_SYNC= 'p2abc CLEAR';
+SET DEBUG_SYNC= 'p5abcde CLEAR';
+SET DEBUG_SYNC= 'p6ab CLEAR';
+SET DEBUG_SYNC= 'p8abcdef CLEAR';
+SET DEBUG_SYNC= 'p9abcdef CLEAR';
+SET DEBUG_SYNC= 'p3abcdef CLEAR';
+SET DEBUG_SYNC= 'p4a CLEAR';
+SET DEBUG_SYNC= 'p7 CLEAR';
+SET DEBUG_SYNC= 'p1abcd TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: 's3'
+SET DEBUG_SYNC= 'p7 TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: 's3'
+SET DEBUG_SYNC= 'p9abcdef TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: 's3'
+SET DEBUG_SYNC= 'RESET';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+Variable_name Value
+debug_sync ON - current signal: ''
+CREATE USER mysqltest_1@localhost;
+GRANT SUPER ON *.* TO mysqltest_1@localhost;
+connection con1, mysqltest_1
+SET DEBUG_SYNC= 'RESET';
+connection default
+DROP USER mysqltest_1@localhost;
+CREATE USER mysqltest_2@localhost;
+GRANT ALL ON *.* TO mysqltest_2@localhost;
+REVOKE SUPER ON *.* FROM mysqltest_2@localhost;
+connection con1, mysqltest_2
+SET DEBUG_SYNC= 'RESET';
+ERROR 42000: Access denied; you need the SUPER privilege for this operation
+connection default
+DROP USER mysqltest_2@localhost;
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c1 INT);
+connection con1
+SET DEBUG_SYNC= 'before_lock_tables_takes_lock
+ SIGNAL opened WAIT_FOR flushed';
+INSERT INTO t1 VALUES(1);
+connection default
+SET DEBUG_SYNC= 'now WAIT_FOR opened';
+SET DEBUG_SYNC= 'after_flush_unlock SIGNAL flushed';
+FLUSH TABLE t1;
+connection con1
+connection default
+DROP TABLE t1;
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (c1 INT);
+LOCK TABLE t1 WRITE;
+connection con1
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL locked EXECUTE 2';
+INSERT INTO t1 VALUES (1);
+connection default
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+UNLOCK TABLES;
+connection con1
+retrieve INSERT result.
+connection default
+DROP TABLE t1;
+SET DEBUG_SYNC= 'RESET';
diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result
index eb93c69d960..0124a7da35a 100644
--- a/mysql-test/r/delete.result
+++ b/mysql-test/r/delete.result
@@ -279,3 +279,48 @@ ERROR 42000: Incorrect number of arguments for FUNCTION test.f1; expected 0, got
DROP TABLE t1;
DROP FUNCTION f1;
End of 5.0 tests
+#
+# Bug#46958: Assertion in Diagnostics_area::set_ok_status, trigger,
+# merge table
+#
+CREATE TABLE t1 ( a INT );
+CREATE TABLE t2 ( a INT );
+CREATE TABLE t3 ( a INT );
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1), (2);
+INSERT INTO t3 VALUES (1), (2);
+CREATE TRIGGER tr1 BEFORE DELETE ON t2
+FOR EACH ROW INSERT INTO no_such_table VALUES (1);
+DELETE t1, t2, t3 FROM t1, t2, t3;
+ERROR 42S02: Table 'test.no_such_table' doesn't exist
+SELECT * FROM t1;
+a
+SELECT * FROM t2;
+a
+1
+2
+SELECT * FROM t3;
+a
+1
+2
+DROP TABLE t1, t2, t3;
+CREATE TABLE t1 ( a INT );
+CREATE TABLE t2 ( a INT );
+CREATE TABLE t3 ( a INT );
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1), (2);
+INSERT INTO t3 VALUES (1), (2);
+CREATE TRIGGER tr1 AFTER DELETE ON t2
+FOR EACH ROW INSERT INTO no_such_table VALUES (1);
+DELETE t1, t2, t3 FROM t1, t2, t3;
+ERROR 42S02: Table 'test.no_such_table' doesn't exist
+SELECT * FROM t1;
+a
+SELECT * FROM t2;
+a
+2
+SELECT * FROM t3;
+a
+1
+2
+DROP TABLE t1, t2, t3;
diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result
index e0324af8cfd..b1cb70fa43c 100644
--- a/mysql-test/r/distinct.result
+++ b/mysql-test/r/distinct.result
@@ -763,4 +763,34 @@ a b d c
1 2 0 2
1 2 0 3
DROP TABLE t1;
+#
+# Bug #46159: simple query that never returns
+#
+SET @old_max_heap_table_size = @@max_heap_table_size;
+SET @@max_heap_table_size = 16384;
+SET @old_sort_buffer_size = @@sort_buffer_size;
+SET @@sort_buffer_size = 32804;
+CREATE TABLE t1(c1 int, c2 VARCHAR(20));
+INSERT INTO t1 VALUES (1, '1'), (1, '1'), (2, '2'), (3, '1'), (3, '1'), (4, '4');
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+SELECT c1, c2, COUNT(*) FROM t1 GROUP BY c1 LIMIT 4;
+c1 c2 COUNT(*)
+1 1 2
+2 2 1
+3 1 2
+4 4 1
+SELECT DISTINCT c2 FROM t1 GROUP BY c1 HAVING COUNT(*) > 1;
+c2
+1
+5
+DROP TABLE t1;
+SET @@sort_buffer_size = @old_sort_buffer_size;
+SET @@max_heap_table_size = @old_max_heap_table_size;
End of 5.1 tests
diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index a81ff554ca2..5a1bf1a1290 100644
--- a/mysql-test/r/explain.result
+++ b/mysql-test/r/explain.result
@@ -159,6 +159,14 @@ CREATE TABLE t1 (a INT PRIMARY KEY);
EXPLAIN EXTENDED SELECT COUNT(a) FROM t1 USE KEY(a);
ERROR 42000: Key 'a' doesn't exist in table 't1'
DROP TABLE t1;
+CREATE TABLE t1(a LONGTEXT);
+INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet));
+INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet));
+EXPLAIN SELECT DISTINCT 1 FROM t1,
+(SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) as d1
+WHERE t1.a = d1.a;
+ERROR 42S22: Unknown column 'd1.a' in 'where clause'
+DROP TABLE t1;
#
# Bug#37870: Usage of uninitialized value caused failed assertion.
#
@@ -186,4 +194,20 @@ dt
2001-01-01 01:01:01
2001-01-01 01:01:01
drop tables t1, t2;
+#
+# Bug#48295:
+# explain extended crash with subquery and ONLY_FULL_GROUP_BY sql_mode
+#
+CREATE TABLE t1 (f1 INT);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+EXPLAIN EXTENDED SELECT 1 FROM t1
+WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
+ERROR 42000: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
+SHOW WARNINGS;
+Level Code Message
+Error 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
+Note 1003 select 1 AS `1` from `test`.`t1` where <not>(<exists>(...))
+SET SESSION sql_mode=@old_sql_mode;
+DROP TABLE t1;
End of 5.1 tests.
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index 3d989ad1730..94147640cde 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -1477,3 +1477,47 @@ COUNT(*)
SET SQL_MODE=default;
DROP TABLE t1;
End of 5.0 tests
+#
+# BUG#47280 - strange results from count(*) with order by multiple
+# columns without where/group
+#
+#
+# Initialize test
+#
+CREATE TABLE t1 (
+pk INT NOT NULL,
+i INT,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,11),(2,12),(3,13);
+#
+# Start test
+# All the following queries shall return 1 record
+#
+
+# Masking all correct values {11...13} for column i in this result.
+SELECT MAX(pk) as max, i
+FROM t1
+ORDER BY max;
+max i
+3 #
+
+EXPLAIN
+SELECT MAX(pk) as max, i
+FROM t1
+ORDER BY max;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using temporary
+
+# Only 11 is correct for collumn i in this result
+SELECT MAX(pk) as max, i
+FROM t1
+WHERE pk<2
+ORDER BY max;
+max i
+1 11
+#
+# Cleanup
+#
+DROP TABLE t1;
+End of 5.1 tests
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index 88a822a2fa6..ffdacc43735 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -608,4 +608,146 @@ SELECT SUM( DISTINCT e ) FROM t1 GROUP BY b,c,d HAVING (b,c,d) IN
((AVG( 1 ), 1 + c, 1 + d), (AVG( 1 ), 2 + c, 2 + d));
SUM( DISTINCT e )
DROP TABLE t1;
+#
+# Bug #44139: Table scan when NULL appears in IN clause
+#
+CREATE TABLE t1 (
+c_int INT NOT NULL,
+c_decimal DECIMAL(5,2) NOT NULL,
+c_float FLOAT(5, 2) NOT NULL,
+c_bit BIT(10) NOT NULL,
+c_date DATE NOT NULL,
+c_datetime DATETIME NOT NULL,
+c_timestamp TIMESTAMP NOT NULL,
+c_time TIME NOT NULL,
+c_year YEAR NOT NULL,
+c_char CHAR(10) NOT NULL,
+INDEX(c_int), INDEX(c_decimal), INDEX(c_float), INDEX(c_bit), INDEX(c_date),
+INDEX(c_datetime), INDEX(c_timestamp), INDEX(c_time), INDEX(c_year),
+INDEX(c_char));
+INSERT INTO t1 (c_int) VALUES (1), (2), (3), (4), (5);
+INSERT INTO t1 (c_int) SELECT 0 FROM t1;
+INSERT INTO t1 (c_int) SELECT 0 FROM t1;
+EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, 2, 3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL, 1, 2, 3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, 2, 3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, NULL, 2, NULL, 3, NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL, NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (1, 2, 3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_decimal c_decimal 3 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL, 1, 2, 3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_decimal c_decimal 3 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL, NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_float IN (1, 2, 3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_float c_float 4 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL, 1, 2, 3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_float c_float 4 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL, NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_bit IN (1, 2, 3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_bit c_bit 2 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL, 1, 2, 3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_bit c_bit 2 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL, NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_date
+IN ('2009-09-01', '2009-09-02', '2009-09-03');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_date c_date 3 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_date
+IN (NULL, '2009-09-01', '2009-09-02', '2009-09-03');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_date c_date 3 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_date IN (NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_date IN (NULL, NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_datetime
+IN ('2009-09-01 00:00:01', '2009-09-02 00:00:01', '2009-09-03 00:00:01');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_datetime c_datetime 8 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_datetime
+IN (NULL, '2009-09-01 00:00:01', '2009-09-02 00:00:01', '2009-09-03 00:00:01');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_datetime c_datetime 8 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_datetime IN (NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_datetime IN (NULL, NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_timestamp
+IN ('2009-09-01 00:00:01', '2009-09-01 00:00:02', '2009-09-01 00:00:03');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_timestamp c_timestamp 4 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_timestamp
+IN (NULL, '2009-09-01 00:00:01', '2009-09-01 00:00:02', '2009-09-01 00:00:03');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_timestamp c_timestamp 4 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_timestamp IN (NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_timestamp IN (NULL, NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_year IN (1, 2, 3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_year c_year 1 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL, 1, 2, 3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_year c_year 1 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL, NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_char IN ('1', '2', '3');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_char c_char 10 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL, '1', '2', '3');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c_char c_char 10 NULL 3 Using where
+EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL, NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+DROP TABLE t1;
+#
End of 5.1 tests
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index a0c3935fde0..2a2fe50ad0f 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -2534,6 +2534,15 @@ SELECT LOAD_FILE(a) FROM t1;
LOAD_FILE(a)
NULL
DROP TABLE t1;
+CREATE TABLE t1 (f2 VARCHAR(20));
+CREATE TABLE t2 (f2 VARCHAR(20));
+INSERT INTO t1 VALUES ('MIN'),('MAX');
+INSERT INTO t2 VALUES ('LOAD');
+SELECT CONCAT_WS('_', (SELECT t2.f2 FROM t2), t1.f2) AS concat_name FROM t1;
+concat_name
+LOAD_MIN
+LOAD_MAX
+DROP TABLE t1, t2;
End of 5.0 tests
drop table if exists t1;
create table t1(f1 tinyint default null)engine=myisam;
diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result
index 77c340bbdec..4fa2f63598c 100644
--- a/mysql-test/r/gis-rtree.result
+++ b/mysql-test/r/gis-rtree.result
@@ -1037,4 +1037,43 @@ MBRINTERSECTS(b, GEOMFROMTEXT('LINESTRING(1 1,1102219 2)') );
COUNT(*)
2
DROP TABLE t1;
+#
+# Bug #48258: Assertion failed when using a spatial index
+#
+CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a));
+INSERT INTO t1 VALUES
+(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')),
+(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'));
+EXPLAIN SELECT 1 FROM t1 WHERE a = GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where
+SELECT 1 FROM t1 WHERE a = GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+1
+1
+1
+EXPLAIN SELECT 1 FROM t1 WHERE a < GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where
+SELECT 1 FROM t1 WHERE a < GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+1
+EXPLAIN SELECT 1 FROM t1 WHERE a <= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where
+SELECT 1 FROM t1 WHERE a <= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+1
+1
+1
+EXPLAIN SELECT 1 FROM t1 WHERE a > GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where
+SELECT 1 FROM t1 WHERE a > GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+1
+EXPLAIN SELECT 1 FROM t1 WHERE a >= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 2 Using where
+SELECT 1 FROM t1 WHERE a >= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+1
+1
+1
+DROP TABLE t1;
End of 5.0 tests.
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index a3708d06a1c..b40ff6be160 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -972,6 +972,18 @@ select min(`col002`) from t1 union select `col002` from t1;
min(`col002`)
NULL
drop table t1;
+#
+# Bug #47780: crash when comparing GIS items from subquery
+#
+CREATE TABLE t1(a INT, b MULTIPOLYGON);
+INSERT INTO t1 VALUES
+(0,
+GEOMFROMTEXT(
+'multipolygon(((1 2,3 4,5 6,7 8,9 8),(7 6,5 4,3 2,1 2,3 4)))'));
+# must not crash
+SELECT 1 FROM t1 WHERE a <> (SELECT GEOMETRYCOLLECTIONFROMWKB(b) FROM t1);
+1
+DROP TABLE t1;
End of 5.0 tests
create table t1 (f1 tinyint(1), f2 char(1), f3 varchar(1), f4 geometry, f5 datetime);
create view v1 as select * from t1;
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index a677d71b266..92beccd2a9e 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -1007,8 +1007,8 @@ DROP TABLE mysqltest1.t2;
SHOW GRANTS;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
-GRANT SELECT, INSERT, CREATE, DROP, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost'
GRANT SELECT, INSERT, CREATE, DROP, ALTER ON `mysqltest1`.`t1` TO 'mysqltest_1'@'localhost'
+GRANT SELECT, INSERT, CREATE, DROP, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost'
RENAME TABLE t1 TO t2;
RENAME TABLE t2 TO t1;
ALTER TABLE t1 RENAME TO t2;
@@ -1018,8 +1018,8 @@ REVOKE DROP, INSERT ON mysqltest1.t2 FROM mysqltest_1@localhost;
SHOW GRANTS;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
-GRANT SELECT, CREATE, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost'
GRANT SELECT, CREATE, ALTER ON `mysqltest1`.`t1` TO 'mysqltest_1'@'localhost'
+GRANT SELECT, CREATE, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost'
RENAME TABLE t1 TO t2;
ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 't1'
ALTER TABLE t1 RENAME TO t2;
diff --git a/mysql-test/r/grant3.result b/mysql-test/r/grant3.result
index f38848111ad..59c64ee84ae 100644
--- a/mysql-test/r/grant3.result
+++ b/mysql-test/r/grant3.result
@@ -154,4 +154,42 @@ SELECT * FROM mysqltest_1.t1;
a
DROP USER 'mysqltest1'@'%';
DROP DATABASE mysqltest_1;
+#
+# Bug#41597 - After rename of user, there are additional grants
+# when grants are reapplied.
+#
+CREATE DATABASE temp;
+CREATE TABLE temp.t1(a INT, b VARCHAR(10));
+INSERT INTO temp.t1 VALUES(1, 'name1');
+INSERT INTO temp.t1 VALUES(2, 'name2');
+INSERT INTO temp.t1 VALUES(3, 'name3');
+CREATE USER 'user1'@'%';
+RENAME USER 'user1'@'%' TO 'user2'@'%';
+# Show privileges after rename and BEFORE grant
+SHOW GRANTS FOR 'user2'@'%';
+Grants for user2@%
+GRANT USAGE ON *.* TO 'user2'@'%'
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%';
+# Show privileges after rename and grant
+SHOW GRANTS FOR 'user2'@'%';
+Grants for user2@%
+GRANT USAGE ON *.* TO 'user2'@'%'
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%'
+# Connect as the renamed user
+SHOW GRANTS;
+Grants for user2@%
+GRANT USAGE ON *.* TO 'user2'@'%'
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%'
+SELECT a FROM temp.t1;
+a
+1
+2
+3
+# Check for additional privileges by accessing a
+# non privileged column. We shouldn't be able to
+# access this column.
+SELECT b FROM temp.t1;
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for column 'b' in table 't1'
+DROP USER 'user2'@'%';
+DROP DATABASE temp;
End of 5.0 tests
diff --git a/mysql-test/r/grant_lowercase_fs.result b/mysql-test/r/grant_lowercase_fs.result
new file mode 100644
index 00000000000..5a3087ed5cd
--- /dev/null
+++ b/mysql-test/r/grant_lowercase_fs.result
@@ -0,0 +1,16 @@
+create database db1;
+GRANT CREATE ON db1.* to user_1@localhost;
+GRANT SELECT ON db1.* to USER_1@localhost;
+CREATE TABLE t1(f1 int);
+SELECT * FROM t1;
+ERROR 42000: SELECT command denied to user 'user_1'@'localhost' for table 't1'
+SELECT * FROM t1;
+f1
+CREATE TABLE t2(f1 int);
+ERROR 42000: CREATE command denied to user 'USER_1'@'localhost' for table 't2'
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1@localhost;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM USER_1@localhost;
+DROP USER user_1@localhost;
+DROP USER USER_1@localhost;
+DROP DATABASE db1;
+use test;
diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
index ac9a53ca238..620f5dc19ec 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -876,10 +876,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
explain select a1,a2,b, max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
+1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
+1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b111') and (c <= 'g112') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
@@ -924,7 +924,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
explain select a1,a2,b, max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range NULL idx_t2_1 146 NULL # Using where; Using index for group-by
+1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
diff --git a/mysql-test/r/have_debug_sync.require b/mysql-test/r/have_debug_sync.require
new file mode 100644
index 00000000000..c2090bc5657
--- /dev/null
+++ b/mysql-test/r/have_debug_sync.require
@@ -0,0 +1,2 @@
+debug_sync
+1
diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result
index e71f547d36a..ff00654aed8 100644
--- a/mysql-test/r/index_merge_innodb.result
+++ b/mysql-test/r/index_merge_innodb.result
@@ -111,7 +111,7 @@ count(*)
explain select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge i1,i2 i1,i2 10,10 NULL 3 Using intersect(i1,i2); Using where; Using index
+1 SIMPLE t1 index_merge i1,i2 i1,i2 10,10 NULL REF Using intersect(i1,i2); Using where; Using index
select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
count(*)
@@ -119,7 +119,7 @@ count(*)
explain select count(*) from t1 where
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge i1,i3 i1,i3 10,10 NULL 3 Using intersect(i1,i3); Using where; Using index
+1 SIMPLE t1 index_merge i1,i3 i1,i3 10,10 NULL REF Using intersect(i1,i3); Using where; Using index
select count(*) from t1 where
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
count(*)
diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result
index c639b20de91..c4e6a6d3f9c 100644
--- a/mysql-test/r/index_merge_myisam.result
+++ b/mysql-test/r/index_merge_myisam.result
@@ -945,7 +945,7 @@ count(*)
explain select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge i1,i2 i1,i2 10,10 NULL 2 Using intersect(i1,i2); Using where; Using index
+1 SIMPLE t1 index_merge i1,i2 i1,i2 10,10 NULL REF Using intersect(i1,i2); Using where; Using index
select count(*) from t1 where
key1a = 2 and key1b is null and key2a = 2 and key2b is null;
count(*)
@@ -953,7 +953,7 @@ count(*)
explain select count(*) from t1 where
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge i1,i3 i1,i3 10,10 NULL 2 Using intersect(i1,i3); Using where; Using index
+1 SIMPLE t1 index_merge i1,i3 i1,i3 10,10 NULL REF Using intersect(i1,i3); Using where; Using index
select count(*) from t1 where
key1a = 2 and key1b is null and key3a = 2 and key3b is null;
count(*)
diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result
index f639ab39ed4..b5be0137520 100644
--- a/mysql-test/r/information_schema_db.result
+++ b/mysql-test/r/information_schema_db.result
@@ -109,7 +109,7 @@ show create view testdb_1.v7;
View Create View character_set_client collation_connection
v7 CREATE ALGORITHM=UNDEFINED DEFINER=`no_such_user`@`no_such_host` SQL SECURITY DEFINER VIEW `v7` AS select `testdb_1`.`t2`.`f1` AS `f1` from `t2` latin1 latin1_swedish_ci
Warnings:
-Warning 1356 View 'testdb_1.v7' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note 1449 The user specified as a definer ('no_such_user'@'no_such_host') does not exist
show fields from testdb_1.v7;
Field Type Null Key Default Extra
f1 char(4) YES NULL
@@ -139,7 +139,7 @@ show create view testdb_1.v7;
View Create View character_set_client collation_connection
v7 CREATE ALGORITHM=UNDEFINED DEFINER=`no_such_user`@`no_such_host` SQL SECURITY DEFINER VIEW `v7` AS select `testdb_1`.`t2`.`f1` AS `f1` from `t2` latin1 latin1_swedish_ci
Warnings:
-Warning 1356 View 'testdb_1.v7' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note 1449 The user specified as a definer ('no_such_user'@'no_such_host') does not exist
revoke insert(f1) on v3 from testdb_2@localhost;
revoke show view on v5 from testdb_2@localhost;
use testdb_1;
@@ -157,7 +157,8 @@ ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v7'
show create view testdb_1.v7;
ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v7'
show create view v4;
-ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+View Create View character_set_client collation_connection
+v4 CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_2`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS select `v3`.`f1` AS `f1`,`v3`.`f2` AS `f2` from `testdb_1`.`v3` latin1 latin1_swedish_ci
show fields from v4;
Field Type Null Key Default Extra
f1 char(4) YES NULL
diff --git a/mysql-test/r/innodb-autoinc.result b/mysql-test/r/innodb-autoinc.result
index 8174ba52b41..a40a13dbe9f 100644
--- a/mysql-test/r/innodb-autoinc.result
+++ b/mysql-test/r/innodb-autoinc.result
@@ -197,7 +197,7 @@ c1 c2
5 9
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 100
auto_increment_offset 10
@@ -230,7 +230,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -269,7 +269,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -282,7 +282,7 @@ SELECT * FROM t1;
c1
-1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 100
auto_increment_offset 10
@@ -315,7 +315,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -330,7 +330,7 @@ SELECT * FROM t1;
c1
1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 100
auto_increment_offset 10
@@ -370,7 +370,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -385,7 +385,7 @@ SELECT * FROM t1;
c1
1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 100
auto_increment_offset 10
@@ -419,7 +419,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -434,7 +434,7 @@ c1
1
9223372036854775794
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 2
auto_increment_offset 10
@@ -452,7 +452,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -467,7 +467,7 @@ c1
1
18446744073709551603
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 2
auto_increment_offset 10
@@ -485,7 +485,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -500,7 +500,7 @@ c1
1
18446744073709551603
SET @@SESSION.AUTO_INCREMENT_INCREMENT=5, @@SESSION.AUTO_INCREMENT_OFFSET=7;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 5
auto_increment_offset 7
@@ -514,7 +514,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -533,7 +533,7 @@ c1
-9223372036854775806
1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=3, @@SESSION.AUTO_INCREMENT_OFFSET=3;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 3
auto_increment_offset 3
@@ -550,7 +550,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -568,7 +568,7 @@ SET @@SESSION.AUTO_INCREMENT_INCREMENT=1152921504606846976, @@SESSION.AUTO_INCRE
Warnings:
Warning 1292 Truncated incorrect auto_increment_increment value: '1152921504606846976'
Warning 1292 Truncated incorrect auto_increment_offset value: '1152921504606846976'
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 65535
auto_increment_offset 65535
@@ -581,7 +581,7 @@ c1
DROP TABLE t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
Variable_name Value
auto_increment_increment 1
auto_increment_offset 1
@@ -867,3 +867,262 @@ INSERT INTO t2 SELECT NULL FROM t1;
Got one of the listed errors
DROP TABLE t1;
DROP TABLE t2;
+SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (null);
+INSERT INTO t1 VALUES (null);
+ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT;
+SELECT * FROM t1;
+d1
+1
+3
+SELECT * FROM t1;
+d1
+1
+3
+INSERT INTO t1 VALUES(null);
+Got one of the listed errors
+ALTER TABLE t1 AUTO_INCREMENT = 3;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `d1` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`d1`)
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES(null);
+SELECT * FROM t1;
+d1
+1
+3
+4
+DROP TABLE t1;
+SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
+SHOW VARIABLES LIKE "%auto_inc%";
+Variable_name Value
+auto_increment_increment 1
+auto_increment_offset 1
+CREATE TABLE t1 (c1 TINYINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-127, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` tinyint(4) NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+-127 innodb
+-1 innodb
+1 NULL
+2 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 TINYINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (-127, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+1 NULL
+2 innodb
+3 innodb
+4 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 SMALLINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-32767, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` smallint(6) NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+-32767 innodb
+-1 innodb
+1 NULL
+2 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (-32757, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+1 NULL
+2 innodb
+3 innodb
+4 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 MEDIUMINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-8388607, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` mediumint(9) NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+-8388607 innodb
+-1 innodb
+1 NULL
+2 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 MEDIUMINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (-8388607, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+1 NULL
+2 innodb
+3 innodb
+4 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-2147483647, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(11) NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+-2147483647 innodb
+-1 innodb
+1 NULL
+2 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (-2147483647, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+1 NULL
+2 innodb
+3 innodb
+4 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-9223372036854775807, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` bigint(20) NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+-9223372036854775807 innodb
+-1 innodb
+1 NULL
+2 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (c1 BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (-9223372036854775807, 'innodb');
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+ `c2` varchar(10) DEFAULT NULL,
+ PRIMARY KEY (`c1`)
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+c1 c2
+1 NULL
+2 innodb
+3 innodb
+4 NULL
+DROP TABLE t1;
+CREATE TABLE T1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB;
+CREATE INDEX i1 on T1(c2);
+SHOW CREATE TABLE T1;
+Table Create Table
+T1 CREATE TABLE `T1` (
+ `c1` int(11) NOT NULL AUTO_INCREMENT,
+ `c2` int(11) DEFAULT NULL,
+ PRIMARY KEY (`c1`),
+ KEY `i1` (`c2`)
+) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1
+INSERT INTO T1 (c2) values (0);
+SELECT * FROM T1;
+c1 c2
+10 0
+DROP TABLE T1;
diff --git a/mysql-test/r/innodb-index.result b/mysql-test/r/innodb-index.result
index cfa44e03bfb..7c4627ae8b2 100644
--- a/mysql-test/r/innodb-index.result
+++ b/mysql-test/r/innodb-index.result
@@ -1134,4 +1134,41 @@ t2 CREATE TABLE `t2` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t2;
DROP TABLE t1;
+call mtr.add_suppression("InnoDB: insufficient history for index");
+CREATE TABLE t1 (a INT, b CHAR(1)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (3,'a'),(3,'b'),(1,'c'),(0,'d'),(1,'e');
+BEGIN;
+SELECT * FROM t1;
+a b
+3 a
+3 b
+1 c
+0 d
+1 e
+CREATE INDEX t1a ON t1(a);
+SELECT * FROM t1;
+a b
+3 a
+3 b
+1 c
+0 d
+1 e
+SELECT * FROM t1 FORCE INDEX(t1a) ORDER BY a;
+ERROR HY000: Table definition has changed, please retry transaction
+SELECT * FROM t1;
+a b
+3 a
+3 b
+1 c
+0 d
+1 e
+COMMIT;
+SELECT * FROM t1 FORCE INDEX(t1a) ORDER BY a;
+a b
+0 d
+1 c
+1 e
+3 a
+3 b
+DROP TABLE t1;
SET GLOBAL innodb_file_format_check=@save_innodb_file_format_check;
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 44c436e00ff..845083af478 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1738,7 +1738,7 @@ count(*)
drop table t1;
SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_buffer_pool_pages_total';
variable_value
-511
+8191
SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size';
variable_value
16384
@@ -1766,9 +1766,10 @@ variable_value - @innodb_row_lock_time_max_orig
SELECT variable_value - @innodb_row_lock_time_avg_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_avg';
variable_value - @innodb_row_lock_time_avg_orig
0
+SET @innodb_sync_spin_loops_orig = @@innodb_sync_spin_loops;
show variables like "innodb_sync_spin_loops";
Variable_name Value
-innodb_sync_spin_loops 20
+innodb_sync_spin_loops 30
set global innodb_sync_spin_loops=1000;
show variables like "innodb_sync_spin_loops";
Variable_name Value
@@ -1781,6 +1782,7 @@ set global innodb_sync_spin_loops=20;
show variables like "innodb_sync_spin_loops";
Variable_name Value
innodb_sync_spin_loops 20
+set global innodb_sync_spin_loops=@innodb_sync_spin_loops_orig;
SET @old_innodb_thread_concurrency= @@global.innodb_thread_concurrency;
show variables like "innodb_thread_concurrency";
Variable_name Value
diff --git a/mysql-test/r/innodb_bug36169.result b/mysql-test/r/innodb_bug36169.result
index 48f5895bdbd..0f43ab23f7a 100644
--- a/mysql-test/r/innodb_bug36169.result
+++ b/mysql-test/r/innodb_bug36169.result
@@ -1,5 +1,4 @@
-set @old_innodb_file_per_table=@@innodb_file_per_table;
set @old_innodb_file_format=@@innodb_file_format;
-set @old_innodb_file_format_check=@@innodb_file_format_check;
+set @old_innodb_file_per_table=@@innodb_file_per_table;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON;
diff --git a/mysql-test/suite/innodb/r/innodb_bug44032.result b/mysql-test/r/innodb_bug44032.result
index da2a000b06e..da2a000b06e 100644
--- a/mysql-test/suite/innodb/r/innodb_bug44032.result
+++ b/mysql-test/r/innodb_bug44032.result
diff --git a/mysql-test/r/innodb_bug44369.result b/mysql-test/r/innodb_bug44369.result
new file mode 100644
index 00000000000..9cf79aeffab
--- /dev/null
+++ b/mysql-test/r/innodb_bug44369.result
@@ -0,0 +1,14 @@
+create table bug44369 (DB_ROW_ID int) engine=innodb;
+ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
+create table bug44369 (db_row_id int) engine=innodb;
+ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
+show warnings;
+Level Code Message
+Warning 1005 Error creating table 'test/bug44369' with column name 'db_row_id'. 'db_row_id' is a reserved name. Please try to re-create the table with a different column name.
+Error 1005 Can't create table 'test.bug44369' (errno: -1)
+create table bug44369 (db_TRX_Id int) engine=innodb;
+ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
+show warnings;
+Level Code Message
+Warning 1005 Error creating table 'test/bug44369' with column name 'db_TRX_Id'. 'db_TRX_Id' is a reserved name. Please try to re-create the table with a different column name.
+Error 1005 Can't create table 'test.bug44369' (errno: -1)
diff --git a/mysql-test/r/innodb_bug46000.result b/mysql-test/r/innodb_bug46000.result
new file mode 100644
index 00000000000..b27b3d7443b
--- /dev/null
+++ b/mysql-test/r/innodb_bug46000.result
@@ -0,0 +1,18 @@
+create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb;
+ERROR 42000: Incorrect index name 'GEN_CLUST_INDEX'
+create table bug46000(`id` int, key `GEN_clust_INDEX`(`id`))engine=innodb;
+ERROR 42000: Incorrect index name 'GEN_CLUST_INDEX'
+show warnings;
+Level Code Message
+Warning 1280 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index.
+Error 1280 Incorrect index name 'GEN_CLUST_INDEX'
+Error 1005 Can't create table 'test.bug46000' (errno: -1)
+create table bug46000(id int) engine=innodb;
+create index GEN_CLUST_INDEX on bug46000(id);
+ERROR 42000: Incorrect index name 'GEN_CLUST_INDEX'
+show warnings;
+Level Code Message
+Warning 1280 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index.
+Error 1280 Incorrect index name 'GEN_CLUST_INDEX'
+create index idx on bug46000(id);
+drop table bug46000;
diff --git a/mysql-test/r/innodb_bug47777.result b/mysql-test/r/innodb_bug47777.result
new file mode 100644
index 00000000000..fbba47edcfc
--- /dev/null
+++ b/mysql-test/r/innodb_bug47777.result
@@ -0,0 +1,13 @@
+create table bug47777(c2 linestring not null, primary key (c2(1))) engine=innodb;
+insert into bug47777 values (geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)'));
+select count(*) from bug47777 where c2 =geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)');
+count(*)
+1
+update bug47777 set c2=GeomFromText('POINT(1 1)');
+select count(*) from bug47777 where c2 =geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)');
+count(*)
+0
+select count(*) from bug47777 where c2 = GeomFromText('POINT(1 1)');
+count(*)
+1
+drop table bug47777;
diff --git a/mysql-test/suite/innodb/r/innodb_file_format.result b/mysql-test/r/innodb_file_format.result
index 9cfac5f001c..7b13a310fe8 100644
--- a/mysql-test/suite/innodb/r/innodb_file_format.result
+++ b/mysql-test/r/innodb_file_format.result
@@ -1,3 +1,5 @@
+set @old_innodb_file_format=@@innodb_file_format;
+call mtr.add_suppression("InnoDB: invalid innodb_file_format_check value");
select @@innodb_file_format;
@@innodb_file_format
Antelope
@@ -42,3 +44,5 @@ ERROR HY000: Incorrect arguments to SET
select @@innodb_file_format_check;
@@innodb_file_format_check
Barracuda
+set global innodb_file_format=@old_innodb_file_format;
+set global innodb_file_format_check=Antelope;
diff --git a/mysql-test/r/innodb_lock_wait_timeout_1.result b/mysql-test/r/innodb_lock_wait_timeout_1.result
new file mode 100644
index 00000000000..a635b0d527a
--- /dev/null
+++ b/mysql-test/r/innodb_lock_wait_timeout_1.result
@@ -0,0 +1,357 @@
+#
+# Bug #40113: Embedded SELECT inside UPDATE or DELETE can timeout
+# without error
+#
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b)) ENGINE=InnoDB;
+INSERT INTO t1 (a,b) VALUES (1070109,99);
+CREATE TABLE t2 (b int, a int, PRIMARY KEY (b)) ENGINE=InnoDB;
+INSERT INTO t2 (b,a) VALUES (7,1070109);
+SELECT * FROM t1;
+a b
+1070109 99
+BEGIN;
+SELECT b FROM t2 WHERE b=7 FOR UPDATE;
+b
+7
+BEGIN;
+SELECT b FROM t2 WHERE b=7 FOR UPDATE;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+INSERT INTO t1 (a) VALUES ((SELECT a FROM t2 WHERE b=7));
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+UPDATE t1 SET a='7000000' WHERE a=(SELECT a FROM t2 WHERE b=7);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+DELETE FROM t1 WHERE a=(SELECT a FROM t2 WHERE b=7);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+SELECT * FROM t1;
+a b
+1070109 99
+DROP TABLE t2, t1;
+# End of 5.0 tests
+#
+# Bug#46539 Various crashes on INSERT IGNORE SELECT + SELECT
+# FOR UPDATE
+#
+drop table if exists t1;
+create table t1 (a int primary key auto_increment,
+b int, index(b)) engine=innodb;
+insert into t1 (b) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+set autocommit=0;
+begin;
+select * from t1 where b=5 for update;
+a b
+5 5
+insert ignore into t1 (b) select a as b from t1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# Cleanup
+#
+commit;
+set autocommit=default;
+drop table t1;
+#
+# Bug#41756 Strange error messages about locks from InnoDB
+#
+drop table if exists t1;
+# In the default transaction isolation mode, and/or with
+# innodb_locks_unsafe_for_binlog=OFF, handler::unlock_row()
+# in InnoDB does nothing.
+# Thus in order to reproduce the condition that led to the
+# warning, one needs to relax isolation by either
+# setting a weaker tx_isolation value, or by turning on
+# the unsafe replication switch.
+# For testing purposes, choose to tweak the isolation level,
+# since it's settable at runtime, unlike
+# innodb_locks_unsafe_for_binlog, which is
+# only a command-line switch.
+#
+set @@session.tx_isolation="read-committed";
+# Prepare data. We need a table with a unique index,
+# for join_read_key to be used. The other column
+# allows to control what passes WHERE clause filter.
+create table t1 (a int primary key, b int) engine=innodb;
+# Let's make sure t1 has sufficient amount of rows
+# to exclude JT_ALL access method when reading it,
+# i.e. make sure that JT_EQ_REF(a) is always preferred.
+insert into t1 values (1,1), (2,null), (3,1), (4,1),
+(5,1), (6,1), (7,1), (8,1), (9,1), (10,1),
+(11,1), (12,1), (13,1), (14,1), (15,1),
+(16,1), (17,1), (18,1), (19,1), (20,1);
+#
+# Demonstrate that for the SELECT statement
+# used later in the test JT_EQ_REF access method is used.
+#
+explain
+select 1 from t1 natural join (select 2 as a, 1 as b union all
+select 2 as a, 2 as b) as t2 for update;
+id 1
+select_type PRIMARY
+table <derived2>
+type ALL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows 2
+Extra
+id 1
+select_type PRIMARY
+table t1
+type eq_ref
+possible_keys PRIMARY
+key PRIMARY
+key_len 4
+ref t2.a
+rows 1
+Extra Using where
+id 2
+select_type DERIVED
+table NULL
+type NULL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows NULL
+Extra No tables used
+id 3
+select_type UNION
+table NULL
+type NULL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows NULL
+Extra No tables used
+id NULL
+select_type UNION RESULT
+table <union2,3>
+type ALL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows NULL
+Extra
+#
+# Demonstrate that the reported SELECT statement
+# no longer produces warnings.
+#
+select 1 from t1 natural join (select 2 as a, 1 as b union all
+select 2 as a, 2 as b) as t2 for update;
+1
+commit;
+#
+# Demonstrate that due to lack of inter-sweep "reset" function,
+# we keep some non-matching records locked, even though we know
+# we could unlock them.
+# To do that, show that if there is only one distinct value
+# for a in t2 (a=2), we will keep record (2,null) in t1 locked.
+# But if we add another value for "a" to t2, say 6,
+# join_read_key cache will be pruned at least once,
+# and thus record (2, null) in t1 will get unlocked.
+#
+begin;
+select 1 from t1 natural join (select 2 as a, 1 as b union all
+select 2 as a, 2 as b) as t2 for update;
+1
+#
+# Switching to connection con1
+# We should be able to delete all records from t1 except (2, null),
+# since they were not locked.
+begin;
+# Delete in series of 3 records so that full scan
+# is not used and we're not blocked on record (2,null)
+delete from t1 where a in (1,3,4);
+delete from t1 where a in (5,6,7);
+delete from t1 where a in (8,9,10);
+delete from t1 where a in (11,12,13);
+delete from t1 where a in (14,15,16);
+delete from t1 where a in (17,18);
+delete from t1 where a in (19,20);
+#
+# Record (2, null) is locked. This is actually unnecessary,
+# because the previous select returned no rows.
+# Just demonstrate the effect.
+#
+delete from t1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+rollback;
+#
+# Switching to connection default
+#
+# Show that the original contents of t1 is intact:
+select * from t1;
+a b
+1 1
+2 NULL
+3 1
+4 1
+5 1
+6 1
+7 1
+8 1
+9 1
+10 1
+11 1
+12 1
+13 1
+14 1
+15 1
+16 1
+17 1
+18 1
+19 1
+20 1
+commit;
+#
+# Have a one more record in t2 to show that
+# if join_read_key cache is purned, the current
+# row under the cursor is unlocked (provided, this row didn't
+# match the partial WHERE clause, of course).
+# Sic: the result of this test dependent on the order of retrieval
+# of records --echo # from the derived table, if !
+# We use DELETE to disable the JOIN CACHE. This DELETE modifies no
+# records. It also should leave no InnoDB row locks.
+#
+begin;
+delete t1.* from t1 natural join (select 2 as a, 2 as b union all
+select 0 as a, 0 as b) as t2;
+# Demonstrate that nothing was deleted form t1
+select * from t1;
+a b
+1 1
+2 NULL
+3 1
+4 1
+5 1
+6 1
+7 1
+8 1
+9 1
+10 1
+11 1
+12 1
+13 1
+14 1
+15 1
+16 1
+17 1
+18 1
+19 1
+20 1
+#
+# Switching to connection con1
+begin;
+# Since there is another distinct record in the derived table
+# the previous matching record in t1 -- (2,null) -- was unlocked.
+delete from t1;
+# We will need the contents of the table again.
+rollback;
+select * from t1;
+a b
+1 1
+2 NULL
+3 1
+4 1
+5 1
+6 1
+7 1
+8 1
+9 1
+10 1
+11 1
+12 1
+13 1
+14 1
+15 1
+16 1
+17 1
+18 1
+19 1
+20 1
+commit;
+#
+# Switching to connection default
+rollback;
+begin;
+#
+# Before this patch, we could wrongly unlock a record
+# that was cached and later used in a join. Demonstrate that
+# this is no longer the case.
+# Sic: this test is also order-dependent (i.e. the
+# the bug would show up only if the first record in the union
+# is retreived and processed first.
+#
+# Verify that JT_EQ_REF is used.
+explain
+select 1 from t1 natural join (select 3 as a, 2 as b union all
+select 3 as a, 1 as b) as t2 for update;
+id 1
+select_type PRIMARY
+table <derived2>
+type ALL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows 2
+Extra
+id 1
+select_type PRIMARY
+table t1
+type eq_ref
+possible_keys PRIMARY
+key PRIMARY
+key_len 4
+ref t2.a
+rows 1
+Extra Using where
+id 2
+select_type DERIVED
+table NULL
+type NULL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows NULL
+Extra No tables used
+id 3
+select_type UNION
+table NULL
+type NULL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows NULL
+Extra No tables used
+id NULL
+select_type UNION RESULT
+table <union2,3>
+type ALL
+possible_keys NULL
+key NULL
+key_len NULL
+ref NULL
+rows NULL
+Extra
+# Lock the record.
+select 1 from t1 natural join (select 3 as a, 2 as b union all
+select 3 as a, 1 as b) as t2 for update;
+1
+1
+# Switching to connection con1
+#
+# We should not be able to delete record (3,1) from t1,
+# (previously it was possible).
+#
+delete from t1 where a=3;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# Switching to connection default
+commit;
+set @@session.tx_isolation=default;
+drop table t1;
+#
+# End of 5.1 tests
+#
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index 3ff5f04b6c6..c882d2af1ed 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -385,9 +385,10 @@ name dept
rs5 cs10
rs5 cs9
DELETE FROM t1;
+# Masking (#) number in "rows" column of the following EXPLAIN output, as it may vary (bug#47746).
EXPLAIN SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range name name 44 NULL 2 Using where; Using index for group-by
+1 SIMPLE t1 range name name 44 NULL # Using where; Using index for group-by
SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5';
name dept
DROP TABLE t1;
@@ -2208,4 +2209,46 @@ EXPLAIN SELECT * FROM t1 FORCE INDEX(PRIMARY) WHERE b=1 AND c=1 ORDER BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 4 NULL 128 Using where
DROP TABLE t1;
+#
+# Bug #47963: Wrong results when index is used
+#
+CREATE TABLE t1(
+a VARCHAR(5) NOT NULL,
+b VARCHAR(5) NOT NULL,
+c DATETIME NOT NULL,
+KEY (c)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES('TEST', 'TEST', '2009-10-09 00:00:00');
+SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00' AND c <= '2009-10-09 00:00:00';
+a b c
+TEST TEST 2009-10-09 00:00:00
+SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00.0' AND c <= '2009-10-09 00:00:00.0';
+a b c
+TEST TEST 2009-10-09 00:00:00
+SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00.0' AND c <= '2009-10-09 00:00:00';
+a b c
+TEST TEST 2009-10-09 00:00:00
+SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00' AND c <= '2009-10-09 00:00:00.0';
+a b c
+TEST TEST 2009-10-09 00:00:00
+SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00.000' AND c <= '2009-10-09 00:00:00.000';
+a b c
+TEST TEST 2009-10-09 00:00:00
+SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00.00' AND c <= '2009-10-09 00:00:00.001';
+a b c
+TEST TEST 2009-10-09 00:00:00
+SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00';
+a b c
+EXPLAIN SELECT * FROM t1 WHERE a = 'TEST' AND
+c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result
index 94c58497101..cf3c0b0731e 100644
--- a/mysql-test/r/insert_select.result
+++ b/mysql-test/r/insert_select.result
@@ -833,3 +833,17 @@ Table Op Msg_type Msg_text
test.t2 check status OK
drop table t1,t2;
End of 5.0 tests
+##################################################################
+#
+# Bug #46075: Assertion failed: 0, file .\protocol.cc, line 416
+#
+CREATE TABLE t1(a INT);
+SET max_heap_table_size = 16384;
+SET @old_myisam_data_pointer_size = @@myisam_data_pointer_size;
+SET GLOBAL myisam_data_pointer_size = 2;
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
+call mtr.add_suppression("mysqld: The table '.*#sql.*' is full");
+INSERT IGNORE INTO t1 SELECT t1.a FROM t1,t1 t2,t1 t3,t1 t4,t1 t5,t1 t6,t1 t7;
+SET GLOBAL myisam_data_pointer_size = @old_myisam_data_pointer_size;
+DROP TABLE t1;
+End of 5.1 tests
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index 736ecf1d90e..baabf48cb2f 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -1063,4 +1063,68 @@ a b c d
127 NULL 127 NULL
128 NULL 128 NULL
DROP TABLE IF EXISTS t1,t2;
+#
+# Bug #42116: Mysql crash on specific query
+#
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+CREATE TABLE t3 (a INT, INDEX (a));
+CREATE TABLE t4 (a INT);
+CREATE TABLE t5 (a INT);
+CREATE TABLE t6 (a INT);
+INSERT INTO t1 VALUES (1), (1), (1);
+INSERT INTO t2 VALUES
+(2), (2), (2), (2), (2), (2), (2), (2), (2), (2);
+INSERT INTO t3 VALUES
+(3), (3), (3), (3), (3), (3), (3), (3), (3), (3);
+EXPLAIN
+SELECT *
+FROM
+t1 JOIN t2 ON t1.a = t2.a
+LEFT JOIN
+(
+(
+t3 LEFT JOIN t4 ON t3.a = t4.a
+)
+LEFT JOIN
+(
+t5 LEFT JOIN t6 ON t5.a = t6.a
+)
+ON t4.a = t5.a
+)
+ON t1.a = t3.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+1 SIMPLE t3 ref a a 5 test.t1.a 2 Using index
+1 SIMPLE t4 ALL NULL NULL NULL NULL 0
+1 SIMPLE t5 ALL NULL NULL NULL NULL 0
+1 SIMPLE t6 ALL NULL NULL NULL NULL 0
+1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using where; Using join buffer
+SELECT *
+FROM
+t1 JOIN t2 ON t1.a = t2.a
+LEFT JOIN
+(
+(
+t3 LEFT JOIN t4 ON t3.a = t4.a
+)
+LEFT JOIN
+(
+t5 LEFT JOIN t6 ON t5.a = t6.a
+)
+ON t4.a = t5.a
+)
+ON t1.a = t3.a;
+a a a a a a
+DROP TABLE t1,t2,t3,t4,t5,t6;
End of 5.0 tests.
+CREATE TABLE t1 (f1 int);
+CREATE TABLE t2 (f1 int);
+INSERT INTO t2 VALUES (1);
+CREATE VIEW v1 AS SELECT * FROM t2;
+PREPARE stmt FROM 'UPDATE t2 AS A NATURAL JOIN v1 B SET B.f1 = 1';
+EXECUTE stmt;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+DROP VIEW v1;
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/locale.result b/mysql-test/r/locale.result
new file mode 100644
index 00000000000..89883b070d2
--- /dev/null
+++ b/mysql-test/r/locale.result
@@ -0,0 +1,29 @@
+DROP TABLE IF EXISTS t1;
+Start of 5.4 tests
+#
+# Bug#43207 wrong LC_TIME names for romanian locale
+#
+SET NAMES utf8;
+SET lc_time_names=ro_RO;
+SELECT DATE_FORMAT('2001-01-01', '%w %a %W');
+DATE_FORMAT('2001-01-01', '%w %a %W')
+1 Lu Luni
+SELECT DATE_FORMAT('2001-01-02', '%w %a %W');
+DATE_FORMAT('2001-01-02', '%w %a %W')
+2 Ma Marţi
+SELECT DATE_FORMAT('2001-01-03', '%w %a %W');
+DATE_FORMAT('2001-01-03', '%w %a %W')
+3 Mi Miercuri
+SELECT DATE_FORMAT('2001-01-04', '%w %a %W');
+DATE_FORMAT('2001-01-04', '%w %a %W')
+4 Jo Joi
+SELECT DATE_FORMAT('2001-01-05', '%w %a %W');
+DATE_FORMAT('2001-01-05', '%w %a %W')
+5 Vi Vineri
+SELECT DATE_FORMAT('2001-01-06', '%w %a %W');
+DATE_FORMAT('2001-01-06', '%w %a %W')
+6 Sâ Sâmbătă
+SELECT DATE_FORMAT('2001-01-07', '%w %a %W');
+DATE_FORMAT('2001-01-07', '%w %a %W')
+0 Du Duminică
+End of 5.4 tests
diff --git a/mysql-test/r/lowercase_fs_off.result b/mysql-test/r/lowercase_fs_off.result
index ecb21261987..4a59801692d 100644
--- a/mysql-test/r/lowercase_fs_off.result
+++ b/mysql-test/r/lowercase_fs_off.result
@@ -10,3 +10,48 @@ create database D1;
ERROR 42000: Access denied for user 'sample'@'localhost' to database 'D1'
drop user 'sample'@'localhost';
drop database if exists d1;
+CREATE DATABASE d1;
+USE d1;
+CREATE TABLE T1(f1 INT);
+CREATE TABLE t1(f1 INT);
+GRANT SELECT ON T1 to user_1@localhost;
+select * from t1;
+ERROR 42000: SELECT command denied to user 'user_1'@'localhost' for table 't1'
+select * from T1;
+f1
+GRANT SELECT ON t1 to user_1@localhost;
+select * from information_schema.table_privileges;
+GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
+'user_1'@'localhost' NULL d1 T1 SELECT NO
+'user_1'@'localhost' NULL d1 t1 SELECT NO
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1@localhost;
+DROP USER user_1@localhost;
+DROP DATABASE d1;
+USE test;
+CREATE DATABASE db1;
+USE db1;
+CREATE PROCEDURE p1() BEGIN END;
+CREATE FUNCTION f1(i INT) RETURNS INT RETURN i+1;
+GRANT USAGE ON db1.* to user_1@localhost;
+GRANT EXECUTE ON PROCEDURE db1.P1 to user_1@localhost;
+GRANT EXECUTE ON FUNCTION db1.f1 to user_1@localhost;
+GRANT UPDATE ON db1.* to USER_1@localhost;
+call p1();
+call P1();
+select f1(1);
+f1(1)
+2
+call p1();
+ERROR 42000: execute command denied to user 'USER_1'@'localhost' for routine 'db1.p1'
+call P1();
+ERROR 42000: execute command denied to user 'USER_1'@'localhost' for routine 'db1.p1'
+select f1(1);
+ERROR 42000: execute command denied to user 'USER_1'@'localhost' for routine 'db1.f1'
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1@localhost;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM USER_1@localhost;
+DROP FUNCTION f1;
+DROP PROCEDURE p1;
+DROP USER user_1@localhost;
+DROP USER USER_1@localhost;
+DROP DATABASE db1;
+use test;
diff --git a/mysql-test/r/lowercase_mixed_tmpdir_innodb.result b/mysql-test/r/lowercase_mixed_tmpdir_innodb.result
new file mode 100755
index 00000000000..a478b49cfda
--- /dev/null
+++ b/mysql-test/r/lowercase_mixed_tmpdir_innodb.result
@@ -0,0 +1,6 @@
+drop table if exists t1;
+create table t1 (id int) engine=InnoDB;
+insert into t1 values (1);
+create temporary table t2 engine=InnoDB select * from t1;
+drop temporary table t2;
+drop table t1;
diff --git a/mysql-test/r/lowercase_table3.result b/mysql-test/r/lowercase_table3.result
index 1ef7d04bb1d..22e80aaeb26 100644
--- a/mysql-test/r/lowercase_table3.result
+++ b/mysql-test/r/lowercase_table3.result
@@ -1,4 +1,4 @@
-call mtr.add_suppression("Cannot find or open table test/BUG29839 from .*");
+call mtr.add_suppression("Cannot find or open table test/BUG29839 from");
DROP TABLE IF EXISTS t1,T1;
CREATE TABLE t1 (a INT);
SELECT * FROM T1;
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 0a02c25c322..ed4505b6073 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -2283,4 +2283,50 @@ h+0 d + 0 e g + 0
1 1 3 0
1 1 4 0
DROP TABLE t1;
+#
+# Test of BUG#35570 CHECKSUM TABLE unreliable if LINESTRING field
+# (same content / differen checksum)
+#
+CREATE TABLE t1 (line LINESTRING NOT NULL) engine=myisam;
+INSERT INTO t1 VALUES (GeomFromText("POINT(0 0)"));
+checksum table t1;
+Table Checksum
+test.t1 326284887
+CREATE TABLE t2 (line LINESTRING NOT NULL) engine=myisam;
+INSERT INTO t2 VALUES (GeomFromText("POINT(0 0)"));
+checksum table t2;
+Table Checksum
+test.t2 326284887
+CREATE TABLE t3 select * from t1;
+checksum table t3;
+Table Checksum
+test.t3 326284887
+drop table t1,t2,t3;
+CREATE TABLE t1(a INT, b CHAR(10), KEY(a), KEY(b));
+INSERT INTO t1 VALUES(1,'0'),(2,'0'),(3,'0'),(4,'0'),(5,'0'),
+(6,'0'),(7,'0');
+INSERT INTO t1 SELECT a+10,b FROM t1;
+INSERT INTO t1 SELECT a+20,b FROM t1;
+INSERT INTO t1 SELECT a+40,b FROM t1;
+INSERT INTO t1 SELECT a+80,b FROM t1;
+INSERT INTO t1 SELECT a+160,b FROM t1;
+INSERT INTO t1 SELECT a+320,b FROM t1;
+INSERT INTO t1 SELECT a+640,b FROM t1;
+INSERT INTO t1 SELECT a+1280,b FROM t1;
+INSERT INTO t1 SELECT a+2560,b FROM t1;
+INSERT INTO t1 SELECT a+5120,b FROM t1;
+SET myisam_sort_buffer_size=4;
+REPAIR TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 repair error myisam_sort_buffer_size is too small
+test.t1 repair warning Number of rows changed from 0 to 7168
+test.t1 repair status OK
+SET myisam_repair_threads=2;
+REPAIR TABLE t1;
+SET myisam_repair_threads=@@global.myisam_repair_threads;
+SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/r/myisam_crash_before_flush_keys.result b/mysql-test/r/myisam_crash_before_flush_keys.result
index 372f2e41590..d3545ea47d0 100644
--- a/mysql-test/r/myisam_crash_before_flush_keys.result
+++ b/mysql-test/r/myisam_crash_before_flush_keys.result
@@ -15,31 +15,13 @@ SET SESSION debug="d,crash_before_flush_keys";
# Run the crashing query
FLUSH TABLE t1;
ERROR HY000: Lost connection to MySQL server during query
-# Run MYISAMCHK tool to check the table t1 and repair
-myisamchk: MyISAM file MYSQLD_DATADIR/test/t1
-myisamchk: warning: 1 client is using or hasn't closed the table properly
-myisamchk: error: Size of indexfile is: 1024 Should be: 3072
-MYISAMCHK: Unknown error 126
-myisamchk: error: Can't read indexpage from filepos: 1024
-MyISAM-table 'MYSQLD_DATADIR/test/t1' is corrupted
-Fix it using switch "-r" or "-o"
# Write file to make mysql-test-run.pl start the server
# Turn on reconnect
# Call script that will poll the server waiting for
# it to be back online again
-SHOW CREATE TABLE t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `a` int(11) NOT NULL DEFAULT '0',
- `b` int(11) NOT NULL DEFAULT '0',
- PRIMARY KEY (`a`,`b`),
- KEY `b` (`b`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
-SELECT * FROM t1 FORCE INDEX (PRIMARY);
-a b
-1 2
-2 3
-3 4
-4 5
-5 6
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check warning 1 client is using or hasn't closed the table properly
+test.t1 check error Size of indexfile is: 1024 Should be: 3072
+test.t1 check error Corrupt
DROP TABLE t1;
diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result
index 295a2f41d40..5f32561798b 100644
--- a/mysql-test/r/mysqlbinlog.result
+++ b/mysql-test/r/mysqlbinlog.result
@@ -44,16 +44,16 @@ SET TIMESTAMP=1000000000/*!*/;
insert into t2 values ()
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
/*!*/;
DELIMITER ;
# End of log file
@@ -144,16 +144,16 @@ SET TIMESTAMP=1000000000/*!*/;
insert into t2 values ()
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word)
/*!*/;
DELIMITER ;
# End of log file
@@ -359,29 +359,29 @@ SET @@session.collation_database=DEFAULT/*!*/;
create table t1 (a varchar(64) character set utf8)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.collation_database=7/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO table t1
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.collation_database=7/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-a-0' INTO table t1
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-a-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-b-0' INTO table t1
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-b-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
-load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-c-0' INTO table t1 character set koi8r
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-c-0' INTO TABLE `t1` CHARACTER SET koi8r FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a)
/*!*/;
SET TIMESTAMP=1000000000/*!*/;
drop table t1
@@ -473,5 +473,94 @@ IS NOT NULL
SET @@global.server_id= 1;
RESET MASTER;
FLUSH LOGS;
+RESET MASTER;
+FLUSH LOGS;
+#
+# Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified is exist
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+ROLLBACK/*!*/;
+use test/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+SET @@session.pseudo_thread_id=999999999/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=0/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+create table t1(a int) engine= innodb
+/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+BEGIN
+/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+insert into t1 (a) values (1)
+/*!*/;
+COMMIT/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+create table t3(a int) engine= innodb
+/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+BEGIN
+/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+insert into t3 (a) values (2)
+/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+ROLLBACK
+/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+create table t5(a int) engine= NDB
+/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+BEGIN
+/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+insert into t5 (a) values (3)
+/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+COMMIT
+/*!*/;
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+#
+# Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified is not exist
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+ROLLBACK/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+SET @@session.pseudo_thread_id=999999999/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+SET @@session.sql_mode=0/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+BEGIN
+/*!*/;
+COMMIT/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+BEGIN
+/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+ROLLBACK
+/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+BEGIN
+/*!*/;
+SET TIMESTAMP=1253783037/*!*/;
+COMMIT
+/*!*/;
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
End of 5.0 tests
End of 5.1 tests
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index 52a1734ea54..2e3a9489593 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -314,20 +314,10 @@ here is the sourced script
1 = outer loop variable before dec
0 = outer loop variable after dec
-
-2 = outer loop variable after while
+outer=2 ifval=0
+outer=1 ifval=1
here is the sourced script
-
-2 = outer loop variable before dec
-
-1 = outer loop variable after dec
-
-1 = outer loop variable after while
-here is the sourced script
-
-1 = outer loop variable before dec
-
-0 = outer loop variable after dec
+ERROR 42S02: Table 'test.nowhere' doesn't exist
In loop
here is the sourced script
@@ -538,6 +528,10 @@ mysqltest: At line 1: Missing required argument 'filename' to command 'write_fil
mysqltest: At line 1: End of file encountered before 'EOF' delimiter was found
Content for test_file1
mysqltest: At line 1: File already exist: 'MYSQLTEST_VARDIR/tmp/test_file1.tmp'
+These lines should be repeated,
+if things work as expected
+These lines should be repeated,
+if things work as expected
Some data
for cat_file command
of mysqltest
diff --git a/mysql-test/r/not_true.require b/mysql-test/r/not_true.require
new file mode 100644
index 00000000000..0032832f3d1
--- /dev/null
+++ b/mysql-test/r/not_true.require
@@ -0,0 +1,2 @@
+TRUE
+NULL
diff --git a/mysql-test/r/olap.result b/mysql-test/r/olap.result
index 4540c9d5218..a7516d97888 100644
--- a/mysql-test/r/olap.result
+++ b/mysql-test/r/olap.result
@@ -733,4 +733,24 @@ SELECT 1 FROM t1 GROUP BY (DATE(NULL)) WITH ROLLUP;
1
1
DROP TABLE t1;
+#
+# Bug #48131: crash group by with rollup, distinct,
+# filesort, with temporary tables
+#
+CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY);
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (100);
+SELECT a, b FROM t1, t2 GROUP BY a, b WITH ROLLUP;
+a b
+1 100
+1 NULL
+2 100
+2 NULL
+NULL NULL
+SELECT DISTINCT b FROM t1, t2 GROUP BY a, b WITH ROLLUP;
+b
+100
+NULL
+DROP TABLE t1, t2;
End of 5.0 tests
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index 306fce1f3c2..0c72f816c21 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -1557,3 +1557,34 @@ a
2001
1991
DROP TABLE t1;
+#
+# Bug #43029: FORCE INDEX FOR ORDER BY is ignored when join buffering
+# is used
+#
+CREATE TABLE t1 (a INT, b INT, KEY (a));
+INSERT INTO t1 VALUES (0, NULL), (1, NULL), (2, NULL), (3, NULL);
+INSERT INTO t1 SELECT a+4, b FROM t1;
+INSERT INTO t1 SELECT a+8, b FROM t1;
+CREATE TABLE t2 (a INT, b INT);
+INSERT INTO t2 VALUES (0,NULL), (1,NULL), (2,NULL), (3,NULL), (4,NULL);
+INSERT INTO t2 SELECT a+4, b FROM t2;
+# shouldn't have "using filesort"
+EXPLAIN
+SELECT * FROM t1 FORCE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 2 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 10
+# should have "using filesort"
+EXPLAIN
+SELECT * FROM t1 USE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 2 Using where; Using temporary; Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer
+# should have "using filesort"
+EXPLAIN
+SELECT * FROM t1 FORCE INDEX FOR JOIN (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 2 Using where; Using temporary; Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer
+DROP TABLE t1, t2;
+End of 5.1 tests
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index 2d54a66fe11..6611d39628f 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -50,6 +50,21 @@ t1 CREATE TABLE `t1` (
PARTITION p3 VALUES LESS THAN (733969) ENGINE = MyISAM,
PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */
DROP TABLE t1;
+create table t1 (a int, b int, key(a))
+partition by list (a)
+( partition p0 values in (1),
+partition p1 values in (2));
+insert into t1 values (1,1),(2,1),(2,2),(2,3);
+show indexes from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 a 1 a A NULL NULL NULL YES BTREE
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+show indexes from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 a 1 a A 1 NULL NULL YES BTREE
+drop table t1;
CREATE TABLE t1 (a INT, FOREIGN KEY (a) REFERENCES t0 (a))
ENGINE=MyISAM
PARTITION BY HASH (a);
diff --git a/mysql-test/r/partition_csv.result b/mysql-test/r/partition_csv.result
index 07651f29da4..18e28d4670a 100644
--- a/mysql-test/r/partition_csv.result
+++ b/mysql-test/r/partition_csv.result
@@ -1,3 +1,4 @@
+call mtr.add_suppression("Failed to write to mysql.general_log");
drop table if exists t1;
create table t1 (a int)
engine = csv
diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result
index ad4d08e89ff..b8cfa25349d 100644
--- a/mysql-test/r/partition_innodb.result
+++ b/mysql-test/r/partition_innodb.result
@@ -1,4 +1,18 @@
drop table if exists t1;
+create table t1 (a int not null,
+b datetime not null,
+primary key (a,b))
+engine=innodb
+partition by range (to_days(b))
+subpartition by hash (a)
+subpartitions 2
+( partition p0 values less than (to_days('2009-01-01')),
+partition p1 values less than (to_days('2009-02-01')),
+partition p2 values less than (to_days('2009-03-01')),
+partition p3 values less than maxvalue);
+alter table t1 reorganize partition p1,p2 into
+( partition p2 values less than (to_days('2009-03-01')));
+drop table t1;
CREATE TABLE t1 (id INT PRIMARY KEY, data INT) ENGINE = InnoDB
PARTITION BY RANGE(id) (
PARTITION p0 VALUES LESS THAN (5),
@@ -256,3 +270,7 @@ SUBPARTITION BY KEY (char_column)
SUBPARTITIONS 2
(PARTITION p1 VALUES LESS THAN (5) ENGINE = MyISAM) */
drop table t1;
+CREATE TABLE t1 (a INT) ENGINE=InnoDB
+PARTITION BY list(a) (PARTITION p1 VALUES IN (1));
+CREATE INDEX i1 ON t1 (a);
+DROP TABLE t1;
diff --git a/mysql-test/r/partition_innodb_builtin.result b/mysql-test/r/partition_innodb_builtin.result
new file mode 100644
index 00000000000..384ce0790a4
--- /dev/null
+++ b/mysql-test/r/partition_innodb_builtin.result
@@ -0,0 +1,39 @@
+SET NAMES utf8;
+CREATE TABLE `t``\""e` (a INT, PRIMARY KEY (a))
+ENGINE=InnoDB
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH (a)
+(PARTITION `p0``\""e` VALUES LESS THAN (100)
+(SUBPARTITION `sp0``\""e`,
+SUBPARTITION `sp1``\""e`),
+PARTITION `p1``\""e` VALUES LESS THAN (MAXVALUE)
+(SUBPARTITION `sp2``\""e`,
+SUBPARTITION `sp3``\""e`));
+INSERT INTO `t``\""e` VALUES (0), (2), (6), (10), (14), (18), (22);
+START TRANSACTION;
+# con1
+SET NAMES utf8;
+START TRANSACTION;
+# default connection
+UPDATE `t``\""e` SET a = 16 WHERE a = 0;
+# con1
+UPDATE `t``\""e` SET a = 8 WHERE a = 22;
+UPDATE `t``\""e` SET a = 12 WHERE a = 0;
+# default connection
+UPDATE `t``\""e` SET a = 4 WHERE a = 22;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+# First table reported in 'SHOW ENGINE InnoDB STATUS'
+SHOW ENGINE InnoDB STATUS;
+Type Name Status
+InnoDB index `PRIMARY` of table `test`.`t``\""e` /* Partition `p0``\""e`, Subpartition `sp0``\""e` */
+set @old_sql_mode = @@sql_mode;
+set sql_mode = 'ANSI_QUOTES';
+SHOW ENGINE InnoDB STATUS;
+Type Name Status
+InnoDB index `PRIMARY` of table `test`.`t``\""e` /* Partition `p0``\""e`, Subpartition `sp0``\""e` */
+set @@sql_mode = @old_sql_mode;
+# con1
+ROLLBACK;
+# default connection
+DROP TABLE `t``\""e`;
+SET NAMES DEFAULT;
diff --git a/mysql-test/r/partition_innodb_plugin.result b/mysql-test/r/partition_innodb_plugin.result
new file mode 100644
index 00000000000..dd91eee316a
--- /dev/null
+++ b/mysql-test/r/partition_innodb_plugin.result
@@ -0,0 +1,50 @@
+SET NAMES utf8;
+CREATE TABLE `t``\""e` (a INT, PRIMARY KEY (a))
+ENGINE=InnoDB
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH (a)
+(PARTITION `p0``\""e` VALUES LESS THAN (100)
+(SUBPARTITION `sp0``\""e`,
+SUBPARTITION `sp1``\""e`),
+PARTITION `p1``\""e` VALUES LESS THAN (MAXVALUE)
+(SUBPARTITION `sp2``\""e`,
+SUBPARTITION `sp3``\""e`));
+INSERT INTO `t``\""e` VALUES (0), (2), (6), (10), (14), (18), (22);
+START TRANSACTION;
+# con1
+SET NAMES utf8;
+START TRANSACTION;
+# default connection
+UPDATE `t``\""e` SET a = 16 WHERE a = 0;
+# con1
+UPDATE `t``\""e` SET a = 8 WHERE a = 22;
+UPDATE `t``\""e` SET a = 12 WHERE a = 0;
+# default connection
+SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS
+GROUP BY lock_table;
+lock_table COUNT(*)
+`test`.`t``\""e` /* Partition `p0``\""e`, Subpartition `sp0``\""e` */ 2
+set @old_sql_mode = @@sql_mode;
+set sql_mode = 'ANSI_QUOTES';
+SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS
+GROUP BY lock_table;
+lock_table COUNT(*)
+"test"."t`\""""e" /* Partition "p0`\""""e", Subpartition "sp0`\""""e" */ 2
+set @@sql_mode = @old_sql_mode;
+UPDATE `t``\""e` SET a = 4 WHERE a = 22;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+# First table reported in 'SHOW ENGINE InnoDB STATUS'
+SHOW ENGINE InnoDB STATUS;
+Type Name Status
+InnoDB index `PRIMARY` of table `test`.`t``\""e` /* Partition `p0``\""e`, Subpartition `sp0``\""e` */
+set @old_sql_mode = @@sql_mode;
+set sql_mode = 'ANSI_QUOTES';
+SHOW ENGINE InnoDB STATUS;
+Type Name Status
+InnoDB index `PRIMARY` of table `test`.`t``\""e` /* Partition `p0``\""e`, Subpartition `sp0``\""e` */
+set @@sql_mode = @old_sql_mode;
+# con1
+ROLLBACK;
+# default connection
+DROP TABLE `t``\""e`;
+SET NAMES DEFAULT;
diff --git a/mysql-test/r/partition_open_files_limit.result b/mysql-test/r/partition_open_files_limit.result
new file mode 100644
index 00000000000..1441ba4e78e
--- /dev/null
+++ b/mysql-test/r/partition_open_files_limit.result
@@ -0,0 +1,22 @@
+DROP TABLE IF EXISTS `t1`;
+# Bug#46922: crash when adding partitions and open_files_limit is reached
+CREATE TABLE t1 (a INT PRIMARY KEY)
+ENGINE=MyISAM PARTITION BY KEY () PARTITIONS 1;
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11);
+# if the bug exists, then crash will happen here
+ALTER TABLE t1 ADD PARTITION PARTITIONS 511;
+ERROR HY000: Out of resources when opening file '<partition file>' (Errcode: 24)
+SELECT * FROM t1;
+a
+1
+10
+11
+2
+3
+4
+5
+6
+7
+8
+9
+DROP TABLE t1;
diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result
index 769d499fc0a..3128c57b2cf 100644
--- a/mysql-test/r/partition_pruning.result
+++ b/mysql-test/r/partition_pruning.result
@@ -1272,10 +1272,9 @@ INSERT INTO t1 VALUES (1, '2009-01-01'), (2, NULL);
# test with an invalid date, which lead to item->null_value is set.
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE b < CAST('2009-04-99' AS DATETIME);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 p20090401 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Warning 1292 Incorrect datetime value: '2009-04-99'
-Warning 1292 Incorrect datetime value: '2009-04-99'
DROP TABLE t1;
CREATE TABLE t1
(a INT NOT NULL AUTO_INCREMENT,
diff --git a/mysql-test/r/ps_grant.result b/mysql-test/r/ps_grant.result
index 8b16123ccea..672db74d9c0 100644
--- a/mysql-test/r/ps_grant.result
+++ b/mysql-test/r/ps_grant.result
@@ -32,19 +32,19 @@ identified by 'looser' ;
show grants for second_user@localhost ;
Grants for second_user@localhost
GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3'
-GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost'
GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost'
+GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost'
drop table mysqltest.t9 ;
show grants for second_user@localhost ;
Grants for second_user@localhost
GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3'
-GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost'
GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost'
+GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost'
show grants for second_user@localhost ;
Grants for second_user@localhost
GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3'
-GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost'
GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost'
+GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost'
prepare s_t1 from 'select a as my_col from t1' ;
execute s_t1 ;
my_col
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index 1c11932107e..a410f7b2dcf 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -1708,6 +1708,7 @@ Qcache_hits 2
DROP TABLE t1;
SET GLOBAL query_cache_size= default;
End of 5.0 tests
+SET GLOBAL query_cache_size=1024*1024*512;
CREATE TABLE t1 (a ENUM('rainbow'));
INSERT INTO t1 VALUES (),(),(),(),();
SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
@@ -1722,4 +1723,5 @@ SELECT 1 FROM t1 GROUP BY
1
1
DROP TABLE t1;
+SET GLOBAL query_cache_size= default;
End of 5.1 tests
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index cc5e8d2be96..2306f8b501e 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -1219,3 +1219,388 @@ explain select * from t2 where a=1000 and b<11;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref a a 5 const 502 Using where
drop table t1, t2;
+CREATE TABLE t1( a INT, b INT, KEY( a, b ) );
+CREATE TABLE t2( a INT, b INT, KEY( a, b ) );
+CREATE TABLE t3( a INT, b INT, KEY( a, b ) );
+INSERT INTO t1( a, b )
+VALUES (0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7);
+INSERT INTO t2( a, b )
+VALUES ( 1, 1), ( 2, 1), ( 3, 1), ( 4, 1), ( 5, 1),
+( 6, 1), ( 7, 1), ( 8, 1), ( 9, 1), (10, 1),
+(11, 1), (12, 1), (13, 1), (14, 1), (15, 1),
+(16, 1), (17, 1), (18, 1), (19, 1), (20, 1);
+INSERT INTO t2 SELECT a, 2 FROM t2 WHERE b = 1;
+INSERT INTO t2 SELECT a, 3 FROM t2 WHERE b = 1;
+INSERT INTO t2 SELECT -1, -1 FROM t2;
+INSERT INTO t2 SELECT -1, -1 FROM t2;
+INSERT INTO t2 SELECT -1, -1 FROM t2;
+INSERT INTO t3
+VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0),
+(6, 0), (7, 0), (8, 0), (9, 0), (10, 0);
+INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
+INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 < a AND b = 3 OR
+3 <= a;
+a b
+5 0
+9 7
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 < a AND b = 3 OR
+3 <= a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+a b
+5 0
+9 7
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+a b
+5 0
+9 7
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+3 <= a;
+a b
+5 0
+9 7
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+3 <= a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 1 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+a b
+1 1
+2 1
+3 1
+4 1
+5 1
+6 1
+7 1
+8 1
+9 1
+10 1
+11 1
+12 1
+13 1
+14 1
+15 1
+15 3
+16 1
+16 3
+17 1
+17 3
+18 1
+18 3
+19 1
+19 3
+20 1
+EXPLAIN
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 1 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 2 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+a b
+1 1
+2 1
+3 1
+4 1
+5 1
+5 2
+6 1
+6 2
+7 1
+7 2
+8 1
+8 2
+9 1
+9 2
+10 1
+11 1
+12 1
+13 1
+14 1
+15 1
+15 3
+16 1
+16 3
+17 1
+17 3
+18 1
+18 3
+19 1
+19 3
+20 1
+EXPLAIN
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 2 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index
+SELECT * FROM t3 WHERE
+5 <= a AND a < 10 AND b = 3 OR
+a < 5 OR
+a < 10;
+a b
+1 0
+2 0
+3 0
+4 0
+5 0
+6 0
+7 0
+8 0
+9 0
+EXPLAIN
+SELECT * FROM t3 WHERE
+5 <= a AND a < 10 AND b = 3 OR
+a < 5 OR
+a < 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range a a 5 NULL 8 Using where; Using index
+DROP TABLE t1, t2, t3;
+#
+# Bug #47123: Endless 100% CPU loop with STRAIGHT_JOIN
+#
+CREATE TABLE t1(a INT, KEY(a));
+INSERT INTO t1 VALUES (1), (NULL);
+SELECT * FROM t1 WHERE a <> NULL and (a <> NULL or a <= NULL);
+a
+DROP TABLE t1;
+#
+# Bug#47925: regression of range optimizer and date comparison in 5.1.39!
+#
+CREATE TABLE t1 ( a DATE, KEY ( a ) );
+CREATE TABLE t2 ( a DATETIME, KEY ( a ) );
+# Make optimizer choose range scan
+INSERT INTO t1 VALUES ('2009-09-22'), ('2009-09-22'), ('2009-09-22');
+INSERT INTO t1 VALUES ('2009-09-23'), ('2009-09-23'), ('2009-09-23');
+INSERT INTO t2 VALUES ('2009-09-22 12:00:00'), ('2009-09-22 12:00:00'),
+('2009-09-22 12:00:00');
+INSERT INTO t2 VALUES ('2009-09-23 12:00:00'), ('2009-09-23 12:00:00'),
+('2009-09-23 12:00:00');
+# DATE vs DATE
+EXPLAIN
+SELECT * FROM t1 WHERE a >= '2009/09/23';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t1 WHERE a >= '2009/09/23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '20090923';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= 20090923;
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009-9-23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009.09.23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009:09:23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+# DATE vs DATETIME
+EXPLAIN
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '20090923';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= 20090923;
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009-9-23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009.09.23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009:09:23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+# DATETIME vs DATETIME
+EXPLAIN
+SELECT * FROM t2 WHERE a >= '2009/09/23 12:00:00';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t2 WHERE a >= '2009/09/23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '20090923120000';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= 20090923120000;
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009-9-23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009.09.23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009:09:23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+# DATETIME vs DATE
+EXPLAIN
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '20090923000000';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= 20090923000000;
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009-9-23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009.09.23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009:09:23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+# Test of the new get_date_from_str implementation
+# Behavior differs slightly between the trunk and mysql-pe.
+# The former may give errors for the truncated values, while the latter
+# gives warnings. The purpose of this test is not to interfere, and only
+# preserve existing behavior.
+SELECT str_to_date('2007-10-00', '%Y-%m-%d') >= '' AND
+str_to_date('2007-10-00', '%Y-%m-%d') <= '2007/10/20';
+str_to_date('2007-10-00', '%Y-%m-%d') >= '' AND
+str_to_date('2007-10-00', '%Y-%m-%d') <= '2007/10/20'
+1
+Warnings:
+Warning 1292 Truncated incorrect date value: ''
+SELECT str_to_date('2007-20-00', '%Y-%m-%d') >= '2007/10/20' AND
+str_to_date('2007-20-00', '%Y-%m-%d') <= '';
+str_to_date('2007-20-00', '%Y-%m-%d') >= '2007/10/20' AND
+str_to_date('2007-20-00', '%Y-%m-%d') <= ''
+NULL
+Warnings:
+Warning 1292 Truncated incorrect date value: ''
+Error 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
+Error 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
+SELECT str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20';
+str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20'
+1
+Warnings:
+Warning 1292 Truncated incorrect datetime value: ''
+SELECT str_to_date('2007-20-00', '%Y-%m-%d') BETWEEN '2007/10/20' AND '';
+str_to_date('2007-20-00', '%Y-%m-%d') BETWEEN '2007/10/20' AND ''
+NULL
+Warnings:
+Error 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
+SELECT str_to_date('', '%Y-%m-%d');
+str_to_date('', '%Y-%m-%d')
+0000-00-00
+DROP TABLE t1, t2;
+End of 5.1 tests
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 6b9a6b7c185..56644ebd862 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -4385,6 +4385,47 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` > 1)) limit 2
DROP TABLE t1;
+#
+# Bug#47019: Assertion failed: 0, file .\rt_mbr.c, line 138 when
+# forcing a spatial index
+#
+CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a));
+INSERT INTO t1 VALUES
+(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')),
+(GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'));
+EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL a NULL NULL NULL 2
+SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
+1
+1
+1
+1
+1
+EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL a NULL NULL NULL 2
+SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
+1
+1
+1
+1
+1
+DROP TABLE t1;
+#
+# Bug #48291 : crash with row() operator,select into @var, and
+# subquery returning multiple rows
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (2),(3);
+# Should not crash
+SELECT 1 FROM t1 WHERE a <> 1 AND NOT
+ROW(a,a) <=> ROW((SELECT 1 FROM t1 WHERE 1=2),(SELECT 1 FROM t1))
+INTO @var0;
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1;
End of 5.0 tests
create table t1(a INT, KEY (a));
INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
diff --git a/mysql-test/r/sp-bugs.result b/mysql-test/r/sp-bugs.result
new file mode 100644
index 00000000000..14c5311bbe5
--- /dev/null
+++ b/mysql-test/r/sp-bugs.result
@@ -0,0 +1,47 @@
+#
+# Bug #47412: Valgrind warnings / user can read uninitalized memory
+# using SP variables
+#
+CREATE SCHEMA testdb;
+USE testdb;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+RETURN f_not_exists () ;
+END|
+CREATE PROCEDURE p3 ( arg1 VARCHAR(32) )
+BEGIN
+CALL p_not_exists ( );
+END|
+# should not return valgrind warnings
+CALL p3 ( f2 () );
+ERROR 42000: PROCEDURE testdb.p_not_exists does not exist
+DROP SCHEMA testdb;
+CREATE SCHEMA testdb;
+USE testdb;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+RETURN f_not_exists () ;
+END|
+CREATE PROCEDURE p3 ( arg2 INTEGER )
+BEGIN
+CALL p_not_exists ( );
+END|
+# should not return valgrind warnings
+CALL p3 ( f2 () );
+ERROR 42000: PROCEDURE testdb.p_not_exists does not exist
+DROP SCHEMA testdb;
+CREATE SCHEMA testdb;
+USE testdb;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+RETURN f_not_exists () ;
+END|
+# should not return valgrind warnings
+SELECT f2 ();
+f2 ()
+NULL
+DROP SCHEMA testdb;
+End of 5.1 tests
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index 17ab2b79043..b3968ea7eb6 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -1670,3 +1670,19 @@ NULL
SELECT non_existent (a) FROM t1 WHERE b = 999999;
ERROR 42000: FUNCTION test.non_existent does not exist
DROP TABLE t1;
+#
+# Bug #47788: Crash in TABLE_LIST::hide_view_error on UPDATE + VIEW +
+# SP + MERGE + ALTER
+#
+CREATE TABLE t1 (pk INT, b INT, KEY (b));
+CREATE ALGORITHM = TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+CREATE PROCEDURE p1 (a int) UPDATE IGNORE v1 SET b = a;
+CALL p1(5);
+ERROR HY000: The target table v1 of the UPDATE is not updatable
+ALTER TABLE t1 CHANGE COLUMN b b2 INT;
+CALL p1(7);
+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 PROCEDURE p1;
+DROP VIEW v1;
+DROP TABLE t1;
+End of 5.1 tests
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 3ad556b8c30..67514c314f4 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -6963,6 +6963,22 @@ CALL p1();
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1;
+#
+# Bug #46629: Item_in_subselect::val_int(): Assertion `0'
+# on subquery inside a SP
+#
+CREATE TABLE t1(a INT);
+CREATE TABLE t2(a INT, b INT PRIMARY KEY);
+CREATE PROCEDURE p1 ()
+BEGIN
+SELECT a FROM t1 A WHERE A.b IN (SELECT b FROM t2 AS B);
+END|
+CALL p1;
+ERROR 42S22: Unknown column 'A.b' in 'IN/ALL/ANY subquery'
+CALL p1;
+ERROR 42S22: Unknown column 'A.b' in 'IN/ALL/ANY subquery'
+DROP PROCEDURE p1;
+DROP TABLE t1, t2;
# ------------------------------------------------------------------
# -- End of 5.1 tests
# ------------------------------------------------------------------
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index d184ae47df3..316bfcbf3f3 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -75,7 +75,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
ERROR HY000: Incorrect usage of PROCEDURE and subquery
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
-ERROR HY000: Incorrect usage of PROCEDURE and subquery
+ERROR HY000: Incorrect parameters to procedure 'ANALYSE'
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
ERROR 42S22: Unknown column 'a' in 'field list'
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL;
@@ -4403,8 +4403,7 @@ FROM t1
WHERE a = 230;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-2 DEPENDENT SUBQUERY st1 index NULL a 5 NULL 2 Using index
-2 DEPENDENT SUBQUERY st2 index b b 5 NULL 2 Using where; Using index; Using join buffer
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
FROM t1
WHERE a = 230;
@@ -4561,4 +4560,18 @@ id g v s
51 50 NULL l
61 60 NULL l
drop table t1, t2;
+CREATE TABLE t1 (a ENUM('rainbow'));
+INSERT INTO t1 VALUES (),(),(),(),();
+SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
+1
+1
+DROP TABLE t1;
+CREATE TABLE t1 (a LONGBLOB);
+INSERT INTO t1 SET a = 'aaaa';
+INSERT INTO t1 SET a = 'aaaa';
+SELECT 1 FROM t1 GROUP BY
+(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
+1
+1
+DROP TABLE t1;
End of 5.1 tests.
diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result
index a661ec5c78b..38c9f47e0d7 100644
--- a/mysql-test/r/subselect3.result
+++ b/mysql-test/r/subselect3.result
@@ -895,3 +895,72 @@ t1.a < (select t4.a+10
from t4, t5 limit 2));
ERROR 21000: Subquery returns more than 1 row
drop table t0, t1, t2, t3, t4, t5;
+#
+# BUG#48177 - SELECTs with NOT IN subqueries containing NULL
+# values return too many records
+#
+CREATE TABLE t1 (
+i1 int DEFAULT NULL,
+i2 int DEFAULT NULL
+) ;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (2, 3);
+INSERT INTO t1 VALUES (4, NULL);
+INSERT INTO t1 VALUES (4, 0);
+INSERT INTO t1 VALUES (NULL, NULL);
+CREATE TABLE t2 (
+i1 int DEFAULT NULL,
+i2 int DEFAULT NULL
+) ;
+INSERT INTO t2 VALUES (4, NULL);
+INSERT INTO t2 VALUES (5, 0);
+
+Data in t1
+SELECT i1, i2 FROM t1;
+i1 i2
+1 NULL
+2 3
+4 NULL
+4 0
+NULL NULL
+
+Data in subquery (should be filtered out)
+SELECT i1, i2 FROM t2 ORDER BY i1;
+i1 i2
+4 NULL
+5 0
+FLUSH STATUS;
+
+SELECT i1, i2
+FROM t1
+WHERE (i1, i2)
+NOT IN (SELECT i1, i2 FROM t2);
+i1 i2
+1 NULL
+2 3
+
+# Check that the subquery only has to be evaluated once
+# for all-NULL values even though there are two (NULL,NULL) records
+# Baseline:
+SHOW STATUS LIKE '%Handler_read_rnd_next';
+Variable_name Value
+Handler_read_rnd_next 17
+
+INSERT INTO t1 VALUES (NULL, NULL);
+FLUSH STATUS;
+
+SELECT i1, i2
+FROM t1
+WHERE (i1, i2)
+NOT IN (SELECT i1, i2 FROM t2);
+i1 i2
+1 NULL
+2 3
+
+# Handler_read_rnd_next should be one more than baseline
+# (read record from t1, but do not read from t2)
+SHOW STATUS LIKE '%Handler_read_rnd_next';
+Variable_name Value
+Handler_read_rnd_next 18
+DROP TABLE t1,t2;
+End of 5.1 tests
diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result
new file mode 100644
index 00000000000..482e0045840
--- /dev/null
+++ b/mysql-test/r/subselect4.result
@@ -0,0 +1,61 @@
+#
+# Bug #46791: Assertion failed:(table->key_read==0),function unknown
+# function,file sql_base.cc
+#
+CREATE TABLE t1 (a INT, b INT, KEY(a));
+INSERT INTO t1 VALUES (1,1),(2,2);
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 VALUES (1,1),(2,2);
+CREATE TABLE t3 LIKE t1;
+# should have 1 impossible where and 2 dependent subqueries
+EXPLAIN
+SELECT 1 FROM t1
+WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))
+ORDER BY count(*);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL a 5 NULL 2 Using index; Using temporary
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+# should not crash the next statement
+SELECT 1 FROM t1
+WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))
+ORDER BY count(*);
+1
+1
+# should not crash: the crash is caused by the previous statement
+SELECT 1;
+1
+1
+DROP TABLE t1,t2,t3;
+#
+# Bug #47106: Crash / segfault on adding EXPLAIN to a non-crashing
+# query
+#
+CREATE TABLE t1 (
+a INT,
+b INT,
+PRIMARY KEY (a),
+KEY b (b)
+);
+INSERT INTO t1 VALUES (1, 1), (2, 1);
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 SELECT * FROM t1;
+CREATE TABLE t3 LIKE t1;
+INSERT INTO t3 SELECT * FROM t1;
+# Should not crash.
+# Should have 1 impossible where and 2 dependent subqs.
+EXPLAIN
+SELECT
+(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
+FROM t3 WHERE 1 = 0 GROUP BY 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 DEPENDENT SUBQUERY t1 index NULL PRIMARY 4 NULL 2 Using index
+2 DEPENDENT SUBQUERY t2 index b b 5 NULL 2 Using where; Using index; Using join buffer
+# should return 0 rows
+SELECT
+(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
+FROM t3 WHERE 1 = 0 GROUP BY 1;
+(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
+DROP TABLE t1,t2,t3;
+End of 5.0 tests.
diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result
index e252331cd1a..17fd95ab1c8 100644
--- a/mysql-test/r/system_mysql_db.result
+++ b/mysql-test/r/system_mysql_db.result
@@ -161,7 +161,7 @@ procs_priv CREATE TABLE `procs_priv` (
`Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
`Db` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
`User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '',
- `Routine_name` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',
+ `Routine_name` char(64) CHARACTER SET utf8 NOT NULL DEFAULT '',
`Routine_type` enum('FUNCTION','PROCEDURE') COLLATE utf8_bin NOT NULL,
`Grantor` char(77) COLLATE utf8_bin NOT NULL DEFAULT '',
`Proc_priv` set('Execute','Alter Routine','Grant') CHARACTER SET utf8 NOT NULL DEFAULT '',
diff --git a/mysql-test/r/trigger_notembedded.result b/mysql-test/r/trigger_notembedded.result
index 335e6910a3a..d66308a9bd7 100644
--- a/mysql-test/r/trigger_notembedded.result
+++ b/mysql-test/r/trigger_notembedded.result
@@ -180,8 +180,6 @@ NULL mysqltest_db1 trg5 DELETE NULL mysqltest_db1 t1 0 NULL SET @a = 5 ROW BEFOR
DROP USER mysqltest_dfn@localhost;
DROP USER mysqltest_inv@localhost;
DROP DATABASE mysqltest_db1;
-Warnings:
-Warning 1454 No definer attribute for trigger 'mysqltest_db1'.'trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.
DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result
index b831771d9c5..51feab0a421 100644
--- a/mysql-test/r/type_bit.result
+++ b/mysql-test/r/type_bit.result
@@ -749,6 +749,16 @@ bin(a1)
110000111111111
110001011111111
drop table t1bit7, t2bit7;
+#
+# Bug42803: Field_bit does not have unsigned_flag field,
+# can lead to bad memory access
+#
+CREATE TABLE t1 (a BIT(7), b BIT(9), KEY(a, b));
+INSERT INTO t1 VALUES(0, 0), (5, 3), (5, 6), (6, 4), (7, 0);
+EXPLAIN SELECT a+0, b+0 FROM t1 WHERE a > 4 and b < 7 ORDER BY 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 2 NULL 4 Using where; Using index; Using filesort
+DROP TABLE t1;
End of 5.0 tests
create table t1(a bit(7));
insert into t1 values(0x40);
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index c3d1e400b23..748aadee4fb 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -1495,9 +1495,9 @@ CREATE TABLE t1 (a int DEFAULT NULL, b int DEFAULT NULL);
INSERT INTO t1 VALUES (3,30), (1,10), (2,10);
SELECT a+CAST(1 AS decimal(65,30)) AS aa, SUM(b) FROM t1 GROUP BY aa;
aa SUM(b)
-2.00000000000000000000000000000 10
-3.00000000000000000000000000000 10
-4.00000000000000000000000000000 30
+2.000000000000000000000000000000 10
+3.000000000000000000000000000000 10
+4.000000000000000000000000000000 30
SELECT a+CAST(1 AS decimal(65,31)) AS aa, SUM(b) FROM t1 GROUP BY aa;
ERROR 42000: Too big scale 31 specified for column '1'. Maximum is 30.
DROP TABLE t1;
@@ -1521,13 +1521,13 @@ f1
DROP TABLE t1;
CREATE TABLE t1 SELECT 123451234512345123451234512345123451234512345.678906789067890678906789067890678906789067890 AS f1;
Warnings:
-Note 1265 Data truncated for column 'f1' at row 1
+Warning 1264 Out of range value for column 'f1' at row 1
DESC t1;
Field Type Null Key Default Extra
-f1 decimal(65,20) NO 0.00000000000000000000
+f1 decimal(65,30) NO 0.000000000000000000000000000000
SELECT f1 FROM t1;
f1
-123451234512345123451234512345123451234512345.67890678906789067891
+99999999999999999999999999999999999.999999999999999999999999999999
DROP TABLE t1;
select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 *
1.01500000 * 1.01500000 * 0.99500000);
@@ -1595,7 +1595,7 @@ Warnings:
Note 1265 Data truncated for column 'my_col' at row 1
DESCRIBE t1;
Field Type Null Key Default Extra
-my_col decimal(32,30) NO 0.000000000000000000000000000000
+my_col decimal(65,30) NO 0.000000000000000000000000000000
SELECT my_col FROM t1;
my_col
1.123456789123456789123456789123
@@ -1625,212 +1625,8 @@ Warnings:
Note 1265 Data truncated for column 'my_col' at row 1
DESCRIBE t1;
Field Type Null Key Default Extra
-my_col decimal(30,30) YES NULL
+my_col decimal(65,30) YES NULL
SELECT my_col FROM t1;
my_col
0.012345687012345687012345687012
DROP TABLE t1;
-#
-# Bug#45261: Crash, stored procedure + decimal
-#
-DROP TABLE IF EXISTS t1;
-CREATE TABLE t1 SELECT
-/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001
-AS c1;
-Warnings:
-Warning 1264 Out of range value for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,0) NO 0
-SELECT * FROM t1;
-c1
-99999999999999999999999999999999999999999999999999999999999999999
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.
-AS c1;
-Warnings:
-Warning 1264 Out of range value for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,0) NO 0
-SELECT * FROM t1;
-c1
-99999999999999999999999999999999999999999999999999999999999999999
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.1 /* 1 */
-AS c1;
-Warnings:
-Warning 1264 Out of range value for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,0) NO 0
-SELECT * FROM t1;
-c1
-99999999999999999999999999999999999999999999999999999999999999999
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001
-AS c1;
-Warnings:
-Error 1292 Truncated incorrect DECIMAL value: ''
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,0) NO 0
-SELECT * FROM t1;
-c1
-99999999999999999999999999999999999999999999999999999999999999999
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 40 */ 1000000000000000000000000000000000000001.1000000000000000000000000000000000000001 /* 40 */
-AS c1;
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,25) NO 0.0000000000000000000000000
-SELECT * FROM t1;
-c1
-1000000000000000000000000000000000000001.1000000000000000000000000
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 1 */ 1.10000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 80 */
-AS c1;
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(31,30) NO 0.000000000000000000000000000000
-SELECT * FROM t1;
-c1
-1.100000000000000000000000000000
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 1 */ 1.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
-AS c1;
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(31,30) NO 0.000000000000000000000000000000
-SELECT * FROM t1;
-c1
-1.100000000000000000000000000000
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
-AS c1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(30,30) NO 0.000000000000000000000000000000
-SELECT * FROM t1;
-c1
-0.100000000000000000000000000000
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 45 */ 123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345 /* 45 */
-AS c1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,20) NO 0.00000000000000000000
-SELECT * FROM t1;
-c1
-123456789012345678901234567890123456789012345.12345678901234567890
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 65 */ 12345678901234567890123456789012345678901234567890123456789012345.1 /* 1 */
-AS c1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,0) NO 0
-SELECT * FROM t1;
-c1
-12345678901234567890123456789012345678901234567890123456789012345
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-/* 66 */ 123456789012345678901234567890123456789012345678901234567890123456.1 /* 1 */
-AS c1;
-Warnings:
-Warning 1264 Out of range value for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,0) NO 0
-SELECT * FROM t1;
-c1
-99999999999999999999999999999999999999999999999999999999999999999
-DROP TABLE t1;
-CREATE TABLE t1 SELECT
-.123456789012345678901234567890123456789012345678901234567890123456 /* 66 */
-AS c1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(30,30) NO 0.000000000000000000000000000000
-SELECT * FROM t1;
-c1
-0.123456789012345678901234567890
-DROP TABLE t1;
-CREATE TABLE t1 AS SELECT 123.1234567890123456789012345678901 /* 31 */ AS c1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 1
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(33,30) NO 0.000000000000000000000000000000
-SELECT * FROM t1;
-c1
-123.123456789012345678901234567890
-DROP TABLE t1;
-CREATE TABLE t1 SELECT 1.1 + CAST(1 AS DECIMAL(65,30)) AS c1;
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,29) NO 0.00000000000000000000000000000
-SELECT * FROM t1;
-c1
-2.10000000000000000000000000000
-DROP TABLE t1;
-#
-# Test that the integer and decimal parts are properly calculated.
-#
-CREATE TABLE t1 (a DECIMAL(30,30));
-INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
-CREATE TABLE t2 SELECT MIN(a + 0.0000000000000000000000000000001) AS c1 FROM t1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 3
-DESC t2;
-Field Type Null Key Default Extra
-c1 decimal(32,30) YES NULL
-DROP TABLE t1,t2;
-CREATE TABLE t1 (a DECIMAL(30,30));
-INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
-CREATE TABLE t2 SELECT IFNULL(a + 0.0000000000000000000000000000001, NULL) AS c1 FROM t1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 1
-Note 1265 Data truncated for column 'c1' at row 2
-Note 1265 Data truncated for column 'c1' at row 3
-DESC t2;
-Field Type Null Key Default Extra
-c1 decimal(32,30) YES NULL
-DROP TABLE t1,t2;
-CREATE TABLE t1 (a DECIMAL(30,30));
-INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
-CREATE TABLE t2 SELECT CASE a WHEN 0.1 THEN 0.0000000000000000000000000000000000000000000000000000000000000000001 END AS c1 FROM t1;
-Warnings:
-Note 1265 Data truncated for column 'c1' at row 1
-DESC t2;
-Field Type Null Key Default Extra
-c1 decimal(31,30) YES NULL
-DROP TABLE t1,t2;
-#
-# Test that variables get maximum precision.
-#
-SET @decimal= 1.1;
-CREATE TABLE t1 SELECT @decimal AS c1;
-DESC t1;
-Field Type Null Key Default Extra
-c1 decimal(65,30) YES NULL
-SELECT * FROM t1;
-c1
-1.100000000000000000000000000000
-DROP TABLE t1;
diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result
index 15410ac2039..601b364fbbe 100644
--- a/mysql-test/r/udf.result
+++ b/mysql-test/r/udf.result
@@ -392,4 +392,20 @@ a
4
DROP FUNCTION sequence;
DROP TABLE t1,t2;
+#
+# Bug#46259: 5.0.83 -> 5.1.36, query doesn't work
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1), (2), (3);
+SELECT IF( a = 1, a, a ) AS `b` FROM t1 ORDER BY field( `b` + 1, 1 );
+b
+1
+2
+3
+SELECT IF( a = 1, a, a ) AS `b` FROM t1 ORDER BY field( `b`, 1 );
+b
+2
+3
+1
+DROP TABLE t1;
End of 5.0 tests.
diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result
index 7a51649fac5..d859579e835 100644
--- a/mysql-test/r/update.result
+++ b/mysql-test/r/update.result
@@ -503,3 +503,14 @@ ERROR HY000: Recursive stored functions and triggers are not allowed.
DROP TABLE t1;
DROP FUNCTION f1;
End of 5.0 tests
+#
+# Bug #47919 assert in open_table during ALTER temporary table
+#
+CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT, PRIMARY KEY (f1));
+CREATE TEMPORARY TABLE t2 LIKE t1;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+ALTER TABLE t2 COMMENT = 'ABC';
+UPDATE t2, t1 SET t2.f1 = 2, t1.f1 = 9;
+ALTER TABLE t2 COMMENT = 'DEF';
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/upgrade.result b/mysql-test/r/upgrade.result
index da6201692a9..034242079b1 100644
--- a/mysql-test/r/upgrade.result
+++ b/mysql-test/r/upgrade.result
@@ -108,11 +108,7 @@ a-b-c
show create view `a-b-c`.v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `a`.`f1` AS `f1` from (`a-b-c`.`t1` `a` join `information_schema`.`tables` `b`) where (convert(`a`.`f1` using utf8) = `b`.`TABLE_NAME`) utf8 utf8_general_ci
-Warnings:
-Note 1600 Creation context of view `a-b-c`.`v1' is invalid
select * from `a-b-c`.v1;
f1
-Warnings:
-Note 1600 Creation context of view `a-b-c`.`v1' is invalid
drop database `a-b-c`;
use test;
diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result
index 7e280fa2fe5..2d5c515d0b5 100644
--- a/mysql-test/r/view_grant.result
+++ b/mysql-test/r/view_grant.result
@@ -606,7 +606,7 @@ SHOW CREATE VIEW v;
View Create View character_set_client collation_connection
v CREATE ALGORITHM=UNDEFINED DEFINER=`no-such-user`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `test`.`t1`.`a` AS `a` from `t1` latin1 latin1_swedish_ci
Warnings:
-Warning 1356 View 'test.v' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note 1449 The user specified as a definer ('no-such-user'@'localhost') does not exist
SELECT * FROM v;
ERROR HY000: The user specified as a definer ('no-such-user'@'localhost') does not exist
DROP VIEW v;
@@ -963,7 +963,7 @@ SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`no_such`@`user_1` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
Warnings:
-Warning 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note 1449 The user specified as a definer ('no_such'@'user_1') does not exist
ALTER ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
Warnings:
Note 1449 The user specified as a definer ('no_such'@'user_1') does not exist
@@ -971,7 +971,7 @@ SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=MERGE DEFINER=`no_such`@`user_1` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
Warnings:
-Warning 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note 1449 The user specified as a definer ('no_such'@'user_1') does not exist
ALTER ALGORITHM=TEMPTABLE DEFINER=no_such@user_2 VIEW v1 AS SELECT * FROM t1;
Warnings:
Note 1449 The user specified as a definer ('no_such'@'user_2') does not exist
@@ -979,7 +979,7 @@ SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=TEMPTABLE DEFINER=`no_such`@`user_2` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
Warnings:
-Warning 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note 1449 The user specified as a definer ('no_such'@'user_2') does not exist
DROP VIEW v1;
DROP TABLE t1;
CREATE USER mysqluser1@localhost;
@@ -1044,3 +1044,196 @@ DROP DATABASE mysqltest1;
DROP VIEW test.v3;
DROP USER mysqluser1@localhost;
USE test;
+#
+# Bug#35996: SELECT + SHOW VIEW should be enough to display view
+# definition
+#
+CREATE USER mysqluser1@localhost;
+CREATE DATABASE mysqltest1;
+CREATE DATABASE mysqltest2;
+GRANT USAGE, SELECT, CREATE VIEW, SHOW VIEW
+ON mysqltest2.* TO mysqluser1@localhost;
+USE mysqltest1;
+CREATE TABLE t1( a INT );
+CREATE TABLE t2( a INT, b INT );
+CREATE FUNCTION f1() RETURNS INT RETURN 1;
+CREATE VIEW v1 AS SELECT 1 AS a;
+CREATE VIEW v2 AS SELECT 1 AS a, 2 AS b;
+GRANT SELECT ON TABLE t1 TO mysqluser1@localhost;
+GRANT SELECT (a, b) ON TABLE t2 TO mysqluser1@localhost;
+GRANT EXECUTE ON FUNCTION f1 TO mysqluser1@localhost;
+GRANT SELECT ON TABLE v1 TO mysqluser1@localhost;
+GRANT SELECT (a, b) ON TABLE v2 TO mysqluser1@localhost;
+CREATE VIEW v_t1 AS SELECT * FROM t1;
+CREATE VIEW v_t2 AS SELECT * FROM t2;
+CREATE VIEW v_f1 AS SELECT f1() AS a;
+CREATE VIEW v_v1 AS SELECT * FROM v1;
+CREATE VIEW v_v2 AS SELECT * FROM v2;
+GRANT SELECT, SHOW VIEW ON v_t1 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_t2 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_f1 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_v1 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_v2 TO mysqluser1@localhost;
+CREATE VIEW v_mysqluser1_t1 AS SELECT * FROM mysqltest1.t1;
+CREATE VIEW v_mysqluser1_t2 AS SELECT * FROM mysqltest1.t2;
+CREATE VIEW v_mysqluser1_f1 AS SELECT mysqltest1.f1() AS a;
+CREATE VIEW v_mysqluser1_v1 AS SELECT * FROM mysqltest1.v1;
+CREATE VIEW v_mysqluser1_v2 AS SELECT * FROM mysqltest1.v2;
+SHOW CREATE VIEW mysqltest1.v_t1;
+View Create View character_set_client collation_connection
+v_t1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_t2;
+View Create View character_set_client collation_connection
+v_t2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t2` AS select `mysqltest1`.`t2`.`a` AS `a`,`mysqltest1`.`t2`.`b` AS `b` from `mysqltest1`.`t2` latin1 latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_f1;
+View Create View character_set_client collation_connection
+v_f1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_f1` AS select `f1`() AS `a` latin1 latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_v1;
+View Create View character_set_client collation_connection
+v_v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1` latin1 latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_v2;
+View Create View character_set_client collation_connection
+v_v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v2` AS select `v2`.`a` AS `a`,`v2`.`b` AS `b` from `mysqltest1`.`v2` latin1 latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_t1;
+View Create View character_set_client collation_connection
+v_mysqluser1_t1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_t2;
+View Create View character_set_client collation_connection
+v_mysqluser1_t2 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t2` AS select `mysqltest1`.`t2`.`a` AS `a`,`mysqltest1`.`t2`.`b` AS `b` from `mysqltest1`.`t2` latin1 latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_f1;
+View Create View character_set_client collation_connection
+v_mysqluser1_f1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_f1` AS select `mysqltest1`.`f1`() AS `a` latin1 latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_v1;
+View Create View character_set_client collation_connection
+v_mysqluser1_v1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1` latin1 latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_v2;
+View Create View character_set_client collation_connection
+v_mysqluser1_v2 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v2` AS select `v2`.`a` AS `a`,`v2`.`b` AS `b` from `mysqltest1`.`v2` latin1 latin1_swedish_ci
+REVOKE SELECT ON TABLE t1 FROM mysqluser1@localhost;
+REVOKE SELECT (a) ON TABLE t2 FROM mysqluser1@localhost;
+REVOKE EXECUTE ON FUNCTION f1 FROM mysqluser1@localhost;
+REVOKE SELECT ON TABLE v1 FROM mysqluser1@localhost;
+SHOW CREATE VIEW mysqltest1.v_t1;
+View Create View character_set_client collation_connection
+v_t1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_t2;
+View Create View character_set_client collation_connection
+v_t2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t2` AS select `mysqltest1`.`t2`.`a` AS `a`,`mysqltest1`.`t2`.`b` AS `b` from `mysqltest1`.`t2` latin1 latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_f1;
+View Create View character_set_client collation_connection
+v_f1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_f1` AS select `f1`() AS `a` latin1 latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_v1;
+View Create View character_set_client collation_connection
+v_v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1` latin1 latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_v2;
+View Create View character_set_client collation_connection
+v_v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v2` AS select `v2`.`a` AS `a`,`v2`.`b` AS `b` from `mysqltest1`.`v2` latin1 latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_t1;
+View Create View character_set_client collation_connection
+v_mysqluser1_t1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_t2;
+View Create View character_set_client collation_connection
+v_mysqluser1_t2 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t2` AS select `mysqltest1`.`t2`.`a` AS `a`,`mysqltest1`.`t2`.`b` AS `b` from `mysqltest1`.`t2` latin1 latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_f1;
+View Create View character_set_client collation_connection
+v_mysqluser1_f1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_f1` AS select `mysqltest1`.`f1`() AS `a` latin1 latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_v1;
+View Create View character_set_client collation_connection
+v_mysqluser1_v1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1` latin1 latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_v2;
+View Create View character_set_client collation_connection
+v_mysqluser1_v2 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v2` AS select `v2`.`a` AS `a`,`v2`.`b` AS `b` from `mysqltest1`.`v2` latin1 latin1_swedish_ci
+# Testing the case when the views reference missing objects.
+# Obviously, there are no privileges to check for, so we
+# need only each object type once.
+DROP TABLE t1;
+DROP FUNCTION f1;
+DROP VIEW v1;
+SHOW CREATE VIEW mysqltest1.v_t1;
+View Create View character_set_client collation_connection
+v_t1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
+Warnings:
+Warning 1356 View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SHOW CREATE VIEW mysqltest1.v_f1;
+View Create View character_set_client collation_connection
+v_f1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_f1` AS select `f1`() AS `a` latin1 latin1_swedish_ci
+Warnings:
+Warning 1356 View 'mysqltest1.v_f1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SHOW CREATE VIEW mysqltest1.v_v1;
+View Create View character_set_client collation_connection
+v_v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1` latin1 latin1_swedish_ci
+Warnings:
+Warning 1356 View 'mysqltest1.v_v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SHOW CREATE VIEW v_mysqluser1_t1;
+View Create View character_set_client collation_connection
+v_mysqluser1_t1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
+Warnings:
+Warning 1356 View 'mysqltest2.v_mysqluser1_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SHOW CREATE VIEW v_mysqluser1_f1;
+View Create View character_set_client collation_connection
+v_mysqluser1_f1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_f1` AS select `mysqltest1`.`f1`() AS `a` latin1 latin1_swedish_ci
+Warnings:
+Warning 1356 View 'mysqltest2.v_mysqluser1_f1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SHOW CREATE VIEW v_mysqluser1_v1;
+View Create View character_set_client collation_connection
+v_mysqluser1_v1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1` latin1 latin1_swedish_ci
+Warnings:
+Warning 1356 View 'mysqltest2.v_mysqluser1_v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+REVOKE SHOW VIEW ON v_t1 FROM mysqluser1@localhost;
+REVOKE SHOW VIEW ON v_f1 FROM mysqluser1@localhost;
+REVOKE SHOW VIEW ON v_v1 FROM mysqluser1@localhost;
+SHOW CREATE VIEW mysqltest1.v_t1;
+ERROR 42000: SHOW VIEW command denied to user 'mysqluser1'@'localhost' for table 'v_t1'
+SHOW CREATE VIEW mysqltest1.v_f1;
+ERROR 42000: SHOW VIEW command denied to user 'mysqluser1'@'localhost' for table 'v_f1'
+SHOW CREATE VIEW mysqltest1.v_v1;
+ERROR 42000: SHOW VIEW command denied to user 'mysqluser1'@'localhost' for table 'v_v1'
+SHOW CREATE VIEW v_mysqluser1_t1;
+View Create View character_set_client collation_connection
+v_mysqluser1_t1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1` latin1 latin1_swedish_ci
+Warnings:
+Warning 1356 View 'mysqltest2.v_mysqluser1_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SHOW CREATE VIEW v_mysqluser1_f1;
+View Create View character_set_client collation_connection
+v_mysqluser1_f1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_f1` AS select `mysqltest1`.`f1`() AS `a` latin1 latin1_swedish_ci
+Warnings:
+Warning 1356 View 'mysqltest2.v_mysqluser1_f1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SHOW CREATE VIEW v_mysqluser1_v1;
+View Create View character_set_client collation_connection
+v_mysqluser1_v1 CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1` latin1 latin1_swedish_ci
+Warnings:
+Warning 1356 View 'mysqltest2.v_mysqluser1_v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+DROP USER mysqluser1@localhost;
+DROP DATABASE mysqltest1;
+DROP DATABASE mysqltest2;
+USE test;
+CREATE TABLE t1( a INT );
+CREATE DEFINER = no_such_user@no_such_host VIEW v1 AS SELECT * FROM t1;
+Warnings:
+Note 1449 The user specified as a definer ('no_such_user'@'no_such_host') does not exist
+SHOW CREATE VIEW v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`no_such_user`@`no_such_host` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`a` AS `a` from `t1` latin1 latin1_swedish_ci
+Warnings:
+Note 1449 The user specified as a definer ('no_such_user'@'no_such_host') does not exist
+DROP TABLE t1;
+DROP VIEW v1;
+#
+# Bug #46019: ERROR 1356 When selecting from within another
+# view that has Group By
+#
+CREATE DATABASE mysqltest1;
+USE mysqltest1;
+CREATE TABLE t1 (a INT);
+CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT a FROM t1 GROUP BY a;
+CREATE SQL SECURITY INVOKER VIEW v2 AS SELECT a FROM v1;
+CREATE USER mysqluser1;
+GRANT SELECT ON TABLE t1 TO mysqluser1;
+GRANT SELECT, SHOW VIEW ON TABLE v1 TO mysqluser1;
+GRANT SELECT, SHOW VIEW ON TABLE v2 TO mysqluser1;
+SELECT a FROM v1;
+a
+SELECT a FROM v2;
+a
+DROP USER mysqluser1;
+DROP DATABASE mysqltest1;
diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result
index 2e393aea9e4..8a87852d582 100644
--- a/mysql-test/r/warnings.result
+++ b/mysql-test/r/warnings.result
@@ -313,4 +313,9 @@ ERROR 22001: Data too long for column 'c_tinytext' at row 1
insert into t2 values(@q);
ERROR 22001: Data too long for column 'c_tinyblob' at row 1
drop table t1, t2;
+DROP TABLE t1;
+ERROR 42S02: Unknown table 't1'
+SHOW ERRORS;
+Level Code Message
+Error 1051 Unknown table 't1'
End of 5.0 tests
diff --git a/mysql-test/r/windows.result b/mysql-test/r/windows.result
index 4e0d73ea0eb..d0cdd858d4a 100644
--- a/mysql-test/r/windows.result
+++ b/mysql-test/r/windows.result
@@ -53,3 +53,10 @@ ERROR HY000: No paths allowed for shared library
execute abc;
ERROR HY000: No paths allowed for shared library
deallocate prepare abc;
+#
+# Bug#45498: Socket variable not available on Windows
+#
+SELECT VARIABLE_NAME FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME = 'socket';
+VARIABLE_NAME
+SOCKET
diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result
index a597806d897..d23c8e672b0 100644
--- a/mysql-test/r/xa.result
+++ b/mysql-test/r/xa.result
@@ -89,3 +89,28 @@ xa start 'a';
xa end 'a';
xa prepare 'a';
xa commit 'a';
+CREATE TABLE t1(a INT, KEY(a)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(1),(2);
+BEGIN;
+UPDATE t1 SET a=3 WHERE a=1;
+BEGIN;
+UPDATE t1 SET a=4 WHERE a=2;
+UPDATE t1 SET a=5 WHERE a=2;
+UPDATE t1 SET a=5 WHERE a=1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+ROLLBACK;
+ROLLBACK;
+BEGIN;
+UPDATE t1 SET a=3 WHERE a=1;
+XA START 'xid1';
+UPDATE t1 SET a=4 WHERE a=2;
+UPDATE t1 SET a=5 WHERE a=2;
+UPDATE t1 SET a=5 WHERE a=1;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+XA END 'xid1';
+ERROR XA102: XA_RBDEADLOCK: Transaction branch was rolled back: deadlock was detected
+XA ROLLBACK 'xid1';
+XA START 'xid1';
+XA END 'xid1';
+XA ROLLBACK 'xid1';
+DROP TABLE t1;
diff --git a/mysql-test/std_data/Index.xml b/mysql-test/std_data/Index.xml
index 988dddcc68a..3dc647d8195 100644
--- a/mysql-test/std_data/Index.xml
+++ b/mysql-test/std_data/Index.xml
@@ -68,4 +68,17 @@
</charset>
+ <charset name="latin1">
+ <family>Western</family>
+ <description>cp1252 West European</description>
+ <alias>csisolatin1</alias>
+ <alias>iso-8859-1</alias>
+ <alias>iso-ir-100</alias>
+ <alias>iso_8859-1</alias>
+ <alias>iso_8859-1:1987</alias>
+ <alias>l1</alias>
+ <alias>latin1</alias>
+ <collation name="latin1_test" id="99" order="test"/>
+ </charset>
+
</charsets>
diff --git a/mysql-test/std_data/binlog_transaction.000001 b/mysql-test/std_data/binlog_transaction.000001
new file mode 100644
index 00000000000..c1d0745d57c
--- /dev/null
+++ b/mysql-test/std_data/binlog_transaction.000001
Binary files differ
diff --git a/mysql-test/std_data/latin1.xml b/mysql-test/std_data/latin1.xml
new file mode 100644
index 00000000000..458b1c34da1
--- /dev/null
+++ b/mysql-test/std_data/latin1.xml
@@ -0,0 +1,135 @@
+<?xml version='1.0' encoding="utf-8"?>
+
+<charsets>
+
+<copyright>
+ Copyright (C) 2009 Sun Microsystems, Inc
+
+ 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
+</copyright>
+
+<charset name="latin1">
+
+<ctype>
+<map>
+ 00
+ 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20
+ 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
+ 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
+ 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10
+ 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01
+ 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10
+ 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02
+ 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20
+ 10 00 10 02 10 10 10 10 10 10 01 10 01 00 01 00
+ 00 10 10 10 10 10 10 10 10 10 02 10 02 00 02 01
+ 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
+ 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
+ 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
+ 01 01 01 01 01 01 01 10 01 01 01 01 01 01 01 02
+ 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
+ 02 02 02 02 02 02 02 10 02 02 02 02 02 02 02 02
+</map>
+</ctype>
+
+
+<lower>
+<map>
+ 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+ 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
+ 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
+ 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
+ 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
+ 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F
+ 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
+ 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
+ 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
+ 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
+ A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
+ B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
+ E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
+ F0 F1 F2 F3 F4 F5 F6 D7 F8 F9 FA FB FC FD FE DF
+ E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
+ F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF
+</map>
+</lower>
+
+
+<upper>
+<map>
+ 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+ 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
+ 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
+ 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
+ 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
+ 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
+ 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
+ 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F
+ 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
+ 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
+ A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
+ B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
+ C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
+ D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF
+ C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
+ D0 D1 D2 D3 D4 D5 D6 F7 D8 D9 DA DB DC DD DE FF
+</map>
+</upper>
+
+
+<unicode>
+<map>
+ 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F
+ 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F
+ 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F
+ 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F
+ 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F
+ 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F
+ 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F
+ 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F
+ 20AC 0081 201A 0192 201E 2026 2020 2021 02C6 2030 0160 2039 0152 008D 017D 008F
+ 0090 2018 2019 201C 201D 2022 2013 2014 02DC 2122 0161 203A 0153 009D 017E 0178
+ 00A0 00A1 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF
+ 00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00BA 00BB 00BC 00BD 00BE 00BF
+ 00C0 00C1 00C2 00C3 00C4 00C5 00C6 00C7 00C8 00C9 00CA 00CB 00CC 00CD 00CE 00CF
+ 00D0 00D1 00D2 00D3 00D4 00D5 00D6 00D7 00D8 00D9 00DA 00DB 00DC 00DD 00DE 00DF
+ 00E0 00E1 00E2 00E3 00E4 00E5 00E6 00E7 00E8 00E9 00EA 00EB 00EC 00ED 00EE 00EF
+ 00F0 00F1 00F2 00F3 00F4 00F5 00F6 00F7 00F8 00F9 00FA 00FB 00FC 00FD 00FE 00FF
+</map>
+</unicode>
+
+<collation name="latin1_test">
+<map>
+ 00 01 02 03 37 2D 2E 2F 16 05 25 0B 0C 0D 0E 0F
+ 10 11 12 13 3C 3D 32 26 18 19 3F 27 1C 1D 1E 1F
+ 40 4F 7F 7B 5B 6C 50 7D 4D 5D 5C 4E 6B 60 4B 61
+ F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 7A 5E 4C 7E 6E 6F
+ 7C C1 C2 C3 C4 C5 C6 C7 C8 C9 D1 D2 D3 D4 D5 D6
+ D7 D8 D9 E2 E3 E4 E5 E6 E7 E8 E9 4A E0 5A 5F 6D
+ 79 81 82 83 84 85 86 87 88 89 91 92 93 94 95 96
+ 97 98 99 A2 A3 A4 A5 A6 A7 A8 A9 C0 6A D0 A1 07
+ 20 21 22 23 24 15 06 17 28 29 2A 2B 2C 09 0A 1B
+ 30 31 1A 33 34 35 36 08 38 39 3A 3B 04 14 3E E1
+ 41 42 43 44 45 46 47 48 49 51 52 53 54 55 56 57
+ 58 59 62 63 64 65 66 67 68 69 70 71 72 73 74 75
+ 76 77 78 80 8A 8B 8C 8D 8E 8F 90 9A 9B 9C 9D 9E
+ 9F A0 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7
+ B8 B9 BA BB BC BD BE BF CA CB CC CD CE CF DA DB
+ DC DD DE DF EA EB EC ED EE EF FA FB FC FD FE FF
+</map>
+</collation>
+
+</charset>
+
+</charsets>
diff --git a/mysql-test/suite/binlog/r/binlog_delete_and_flush_index.result b/mysql-test/suite/binlog/r/binlog_delete_and_flush_index.result
new file mode 100644
index 00000000000..036ccf131bb
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_delete_and_flush_index.result
@@ -0,0 +1,50 @@
+RESET MASTER;
+CREATE TABLE t1 (a int);
+### assertion: index file contains regular entries
+SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
+SELECT @index;
+@index
+master-bin.000001
+
+### assertion: show original binlogs
+show binary logs;
+Log_name File_size
+master-bin.000001 #
+### assertion: binlog contents from regular entries
+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 (a int)
+FLUSH LOGS;
+### assertion: index file contains renamed binlog and the new one
+SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
+SELECT @index;
+@index
+master-bin-b34582.000001
+master-bin.000002
+
+### assertion: original binlog content still exists, despite we
+### renamed and changed the index file
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin-b34582.000001 # Query # # use `test`; CREATE TABLE t1 (a int)
+### assertion: user changed binlog index shows correct entries
+show binary logs;
+Log_name File_size
+master-bin-b34582.000001 #
+master-bin.000002 #
+DROP TABLE t1;
+### assertion: purging binlogs up to binlog created after instrumenting index file should work
+PURGE BINARY LOGS TO 'master-bin.000002';
+### assertion: show binary logs should only contain latest binlog
+show binary logs;
+Log_name File_size
+master-bin.000002 #
+### assertion: assert that binlog files were indeed purged (using file_exists calls)
+### assertion: assert that not purged binlog file exists
+### assertion: show index file contents and these should match show binary logs issued above
+SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
+SELECT @index;
+@index
+master-bin.000002
+
+RESET MASTER;
diff --git a/mysql-test/suite/binlog/r/binlog_killed_simulate.result b/mysql-test/suite/binlog/r/binlog_killed_simulate.result
index 634d3f62814..df04f5129cf 100644
--- a/mysql-test/suite/binlog/r/binlog_killed_simulate.result
+++ b/mysql-test/suite/binlog/r/binlog_killed_simulate.result
@@ -19,7 +19,7 @@ ERROR 70100: Query execution was interrupted
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
-master-bin.000001 # Execute_load_query # # use `test`; load data infile '../../std_data/rpl_loaddata.dat' into table t2 /* will be "killed" in the middle */ ;file_id=#
+master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, b) ;file_id=#
select
(@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
is not null;
diff --git a/mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result b/mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result
new file mode 100644
index 00000000000..dfc08d76a6a
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result
@@ -0,0 +1,406 @@
+###################################################################################
+# CONFIGURATION
+###################################################################################
+CREATE TABLE nt_1 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
+CREATE TABLE nt_2 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
+CREATE TABLE tt_1 (a text, b int PRIMARY KEY) ENGINE = Innodb;
+CREATE TABLE tt_2 (a text, b int PRIMARY KEY) ENGINE = Innodb;
+CREATE TRIGGER tr_i_tt_1_to_nt_1 BEFORE INSERT ON tt_1 FOR EACH ROW
+BEGIN
+INSERT INTO nt_1 VALUES (NEW.a, NEW.b);
+END|
+CREATE TRIGGER tr_i_nt_2_to_tt_2 BEFORE INSERT ON nt_2 FOR EACH ROW
+BEGIN
+INSERT INTO tt_2 VALUES (NEW.a, NEW.b);
+END|
+###################################################################################
+# CHECK HISTORY IN BINLOG
+###################################################################################
+
+
+
+*** "B M* T C" with error in M* generates in the binlog the "B M* R B T C" entries
+
+INSERT INTO nt_1 VALUES ("new text 1", 1);
+BEGIN;
+INSERT INTO tt_1 VALUES (USER(), 2), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES ("new text 3", 3);
+COMMIT;
+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 nt_1 VALUES ("new text 1", 1)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_1)
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 3", 3)
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+INSERT INTO tt_2 VALUES ("new text 4", 4);
+BEGIN;
+INSERT INTO nt_2 VALUES (USER(), 5), (USER(), 4);
+ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES ("new text 6", 6);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 4", 4)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_2)
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 6", 6)
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B M M* T C" with error in M* generates in the binlog the "B M M* T C" entries
+
+INSERT INTO nt_1 VALUES ("new text 10", 10);
+BEGIN;
+INSERT INTO tt_1 VALUES ("new text 7", 7), ("new text 8", 8);
+INSERT INTO tt_1 VALUES (USER(), 9), (USER(), 10);
+ERROR 23000: Duplicate entry '10' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES ("new text 11", 11);
+COMMIT;
+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 nt_1 VALUES ("new text 10", 10)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 7", 7), ("new text 8", 8)
+master-bin.000001 # Table_map # # table_id: # (test.tt_1)
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 11", 11)
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+INSERT INTO tt_2 VALUES ("new text 15", 15);
+BEGIN;
+INSERT INTO nt_2 VALUES ("new text 12", 12), ("new text 13", 13);
+INSERT INTO nt_2 VALUES (USER(), 14), (USER(), 15);
+ERROR 23000: Duplicate entry '15' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES ("new text 16", 16);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 15", 15)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 VALUES ("new text 12", 12), ("new text 13", 13)
+master-bin.000001 # Table_map # # table_id: # (test.nt_2)
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 16", 16)
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B M* M* T C" with error in M* generates in the binlog the "B M* R B M* R B T C" entries
+
+INSERT INTO nt_1 VALUES ("new text 18", 18);
+INSERT INTO nt_1 VALUES ("new text 20", 20);
+BEGIN;
+INSERT INTO tt_1 VALUES (USER(), 17), (USER(), 18);
+ERROR 23000: Duplicate entry '18' for key 'PRIMARY'
+INSERT INTO tt_1 VALUES (USER(), 19), (USER(), 20);
+ERROR 23000: Duplicate entry '20' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES ("new text 21", 21);
+COMMIT;
+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 nt_1 VALUES ("new text 18", 18)
+master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 20", 20)
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_1)
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_1)
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 21", 21)
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+INSERT INTO tt_2 VALUES ("new text 23", 23);
+INSERT INTO tt_2 VALUES ("new text 25", 25);
+BEGIN;
+INSERT INTO nt_2 VALUES (USER(), 22), (USER(), 23);
+ERROR 23000: Duplicate entry '23' for key 'PRIMARY'
+INSERT INTO nt_2 VALUES (USER(), 24), (USER(), 25);
+ERROR 23000: Duplicate entry '25' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES ("new text 26", 26);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 23", 23)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 25", 25)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_2)
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_2)
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 26", 26)
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B T INSERT M...SELECT* C" with an error in INSERT M...SELECT* generates
+*** in the binlog the following entries: "Nothing".
+*** There is a bug in that will be fixed after WL#2687. Please, check BUG#47175 for further details.
+
+TRUNCATE TABLE nt_2;
+TRUNCATE TABLE tt_2;
+INSERT INTO tt_2 VALUES ("new text 7", 7);
+BEGIN;
+INSERT INTO tt_2 VALUES ("new text 27", 27);
+INSERT INTO nt_2(a, b) SELECT USER(), b FROM nt_1;
+ERROR 23000: Duplicate entry '7' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES ("new text 28", 28);
+ROLLBACK;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_2
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 7", 7)
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B INSERT M..SELECT* C" with an error in INSERT M...SELECT* generates
+*** in the binlog the following entries: "B INSERT M..SELECT* R".
+
+TRUNCATE TABLE nt_2;
+TRUNCATE TABLE tt_2;
+INSERT INTO tt_2 VALUES ("new text 7", 7);
+BEGIN;
+INSERT INTO nt_2(a, b) SELECT USER(), b FROM nt_1;
+ERROR 23000: Duplicate entry '7' for key 'PRIMARY'
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_2
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 7", 7)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_2)
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+
+
+
+*** "B N N T C" generates in the binlog the "B N C B N C B T C" entries
+
+TRUNCATE TABLE nt_1;
+TRUNCATE TABLE tt_2;
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 1);
+INSERT INTO nt_1 VALUES (USER(), 2);
+INSERT INTO tt_2 VALUES (USER(), 3);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_1
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B N N T R" generates in the binlog the "B N C B N C B T R" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 4);
+INSERT INTO nt_1 VALUES (USER(), 5);
+INSERT INTO tt_2 VALUES (USER(), 6);
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+
+
+
+*** "B N* N* T C" with error in N* generates in the binlog the "B N R B N R B T C" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 7), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO nt_1 VALUES (USER(), 8), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES (USER(), 9);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B N* N* T R" with error in N* generates in the binlog the "B N R B N R B T R" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 10), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO nt_1 VALUES (USER(), 11), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES (USER(), 12);
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+
+
+
+*** "B N N T N T C" generates in the binlog the "B N C B N C B T N T C" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 13);
+INSERT INTO nt_1 VALUES (USER(), 14);
+INSERT INTO tt_2 VALUES (USER(), 15);
+INSERT INTO nt_1 VALUES (USER(), 16);
+INSERT INTO tt_2 VALUES (USER(), 17);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B N N T N T R" generates in the binlog the "B N C B N C B T N T R" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 18);
+INSERT INTO nt_1 VALUES (USER(), 19);
+INSERT INTO tt_2 VALUES (USER(), 20);
+INSERT INTO nt_1 VALUES (USER(), 21);
+INSERT INTO tt_2 VALUES (USER(), 22);
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+###################################################################################
+# CLEAN
+###################################################################################
+DROP TABLE tt_1;
+DROP TABLE tt_2;
+DROP TABLE nt_1;
+DROP TABLE nt_2;
diff --git a/mysql-test/suite/binlog/r/binlog_row_binlog.result b/mysql-test/suite/binlog/r/binlog_row_binlog.result
index f6b5392dbc8..4d32a4f4739 100644
--- a/mysql-test/suite/binlog/r/binlog_row_binlog.result
+++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result
@@ -1309,3 +1309,27 @@ INSERT INTO test.t1 VALUES (1), (2);
CREATE TABLE test.t2 SELECT * FROM test.t1;
USE test;
DROP TABLES t1, t2;
+RESET MASTER;
+CREATE TABLE t1 (a INT PRIMARY KEY);
+BINLOG '
+3u9kSA8KAAAAZgAAAGoAAAABAAQANS4xLjM1LW1hcmlhLWJldGExLWRlYnVnLWxvZwAAAAAAAAAA
+AAAAAAAAAAAAAAAAAADe72RIEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
+';
+INSERT INTO t1 VALUES (1);
+BINLOG '
+3u9kSBMUAAAAKQAAAJEBAAAAABoAAAAAAAAABHRlc3QAAnQxAAEDAAA=
+3u9kSBcUAAAAIgAAALMBAAAQABoAAAAAAAEAAf/+AgAAAA==
+';
+SHOW BINLOG EVENTS;
+Log_name Pos Event_type Server_id End_log_pos Info
+# # Format_desc 1 # Server ver: #, Binlog ver: #
+# # Query 1 # use `test`; CREATE TABLE t1 (a INT PRIMARY KEY)
+# # Query 1 # BEGIN
+# # Table_map 1 # table_id: # (test.t1)
+# # Write_rows 1 # table_id: # flags: STMT_END_F
+# # Query 1 # COMMIT
+# # Query 1 # BEGIN
+# # Table_map 1 # table_id: # (test.t1)
+# # Write_rows 1 # table_id: # flags: STMT_END_F
+# # Query 1 # COMMIT
+DROP TABLE t1;
diff --git a/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result b/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result
index 503076d66d9..75c088e595d 100644
--- a/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result
+++ b/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result
@@ -1,17 +1,32 @@
-drop database if exists `drop-temp+table-test`;
-reset master;
-create database `drop-temp+table-test`;
-use `drop-temp+table-test`;
-create temporary table shortn1 (a int);
-create temporary table `table:name` (a int);
-create temporary table shortn2 (a int);
-select get_lock("a",10);
-get_lock("a",10)
+DROP DATABASE IF EXISTS `drop-temp+table-test`;
+RESET MASTER;
+CREATE DATABASE `drop-temp+table-test`;
+USE `drop-temp+table-test`;
+CREATE TEMPORARY TABLE shortn1 (a INT);
+CREATE TEMPORARY TABLE `table:name` (a INT);
+CREATE TEMPORARY TABLE shortn2 (a INT);
+CREATE TEMPORARY TABLE tmp(c1 int);
+CREATE TEMPORARY TABLE tmp1(c1 int);
+CREATE TEMPORARY TABLE tmp2(c1 int);
+CREATE TEMPORARY TABLE tmp3(c1 int);
+CREATE TABLE t(c1 int);
+DROP TEMPORARY TABLE IF EXISTS tmp;
+DROP TEMPORARY TABLE IF EXISTS tmp;
+DROP TEMPORARY TABLE IF EXISTS tmp, tmp1;
+DROP TEMPORARY TABLE tmp3;
+DROP TABLE IF EXISTS tmp2, t;
+DROP TABLE IF EXISTS tmp2, t;
+SELECT GET_LOCK("a",10);
+GET_LOCK("a",10)
1
-select get_lock("a",10);
-get_lock("a",10)
+USE test;
+SELECT GET_LOCK("a",10);
+GET_LOCK("a",10)
1
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # create database `drop-temp+table-test`
-drop database `drop-temp+table-test`;
+master-bin.000001 # Query # # CREATE DATABASE `drop-temp+table-test`
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TABLE t(c1 int)
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS `t` /* generated by server */
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS tmp2, t
+DROP DATABASE `drop-temp+table-test`;
diff --git a/mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result b/mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result
new file mode 100644
index 00000000000..45c8640d3e3
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result
@@ -0,0 +1,440 @@
+###################################################################################
+# CONFIGURATION
+###################################################################################
+CREATE TABLE nt_1 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
+CREATE TABLE nt_2 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
+CREATE TABLE tt_1 (a text, b int PRIMARY KEY) ENGINE = Innodb;
+CREATE TABLE tt_2 (a text, b int PRIMARY KEY) ENGINE = Innodb;
+CREATE TRIGGER tr_i_tt_1_to_nt_1 BEFORE INSERT ON tt_1 FOR EACH ROW
+BEGIN
+INSERT INTO nt_1 VALUES (NEW.a, NEW.b);
+END|
+CREATE TRIGGER tr_i_nt_2_to_tt_2 BEFORE INSERT ON nt_2 FOR EACH ROW
+BEGIN
+INSERT INTO tt_2 VALUES (NEW.a, NEW.b);
+END|
+###################################################################################
+# CHECK HISTORY IN BINLOG
+###################################################################################
+
+
+
+*** "B M* T C" with error in M* generates in the binlog the "B M* R B T C" entries
+
+INSERT INTO nt_1 VALUES ("new text 1", 1);
+BEGIN;
+INSERT INTO tt_1 VALUES (USER(), 2), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES ("new text 3", 3);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_1)
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+INSERT INTO tt_2 VALUES ("new text 4", 4);
+BEGIN;
+INSERT INTO nt_2 VALUES (USER(), 5), (USER(), 4);
+ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES ("new text 6", 6);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_2)
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B M M* T C" with error in M* generates in the binlog the "B M M* T C" entries
+
+INSERT INTO nt_1 VALUES ("new text 10", 10);
+BEGIN;
+INSERT INTO tt_1 VALUES ("new text 7", 7), ("new text 8", 8);
+INSERT INTO tt_1 VALUES (USER(), 9), (USER(), 10);
+ERROR 23000: Duplicate entry '10' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES ("new text 11", 11);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_1)
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.tt_1)
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+INSERT INTO tt_2 VALUES ("new text 15", 15);
+BEGIN;
+INSERT INTO nt_2 VALUES ("new text 12", 12), ("new text 13", 13);
+INSERT INTO nt_2 VALUES (USER(), 14), (USER(), 15);
+ERROR 23000: Duplicate entry '15' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES ("new text 16", 16);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_2)
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.nt_2)
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B M* M* T C" with error in M* generates in the binlog the "B M* R B M* R B T C" entries
+
+INSERT INTO nt_1 VALUES ("new text 18", 18);
+INSERT INTO nt_1 VALUES ("new text 20", 20);
+BEGIN;
+INSERT INTO tt_1 VALUES (USER(), 17), (USER(), 18);
+ERROR 23000: Duplicate entry '18' for key 'PRIMARY'
+INSERT INTO tt_1 VALUES (USER(), 19), (USER(), 20);
+ERROR 23000: Duplicate entry '20' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES ("new text 21", 21);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_1)
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_1)
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+INSERT INTO tt_2 VALUES ("new text 23", 23);
+INSERT INTO tt_2 VALUES ("new text 25", 25);
+BEGIN;
+INSERT INTO nt_2 VALUES (USER(), 22), (USER(), 23);
+ERROR 23000: Duplicate entry '23' for key 'PRIMARY'
+INSERT INTO nt_2 VALUES (USER(), 24), (USER(), 25);
+ERROR 23000: Duplicate entry '25' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES ("new text 26", 26);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_2)
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_2)
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B T INSERT M...SELECT* C" with an error in INSERT M...SELECT* generates
+*** in the binlog the following entries: "Nothing".
+*** There is a bug in that will be fixed after WL#2687. Please, check BUG#47175 for further details.
+
+TRUNCATE TABLE nt_2;
+TRUNCATE TABLE tt_2;
+INSERT INTO tt_2 VALUES ("new text 7", 7);
+BEGIN;
+INSERT INTO tt_2 VALUES ("new text 27", 27);
+INSERT INTO nt_2(a, b) SELECT USER(), b FROM nt_1;
+ERROR 23000: Duplicate entry '7' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES ("new text 28", 28);
+ROLLBACK;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_2
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B INSERT M..SELECT* C" with an error in INSERT M...SELECT* generates
+*** in the binlog the following entries: "B INSERT M..SELECT* R".
+
+TRUNCATE TABLE nt_2;
+TRUNCATE TABLE tt_2;
+INSERT INTO tt_2 VALUES ("new text 7", 7);
+BEGIN;
+INSERT INTO nt_2(a, b) SELECT USER(), b FROM nt_1;
+ERROR 23000: Duplicate entry '7' for key 'PRIMARY'
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_2
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_2)
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+
+
+
+*** "B N N T C" generates in the binlog the "B N C B N C B T C" entries
+
+TRUNCATE TABLE nt_1;
+TRUNCATE TABLE tt_2;
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 1);
+INSERT INTO nt_1 VALUES (USER(), 2);
+INSERT INTO tt_2 VALUES (USER(), 3);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_1
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B N N T R" generates in the binlog the "B N C B N C B T R" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 4);
+INSERT INTO nt_1 VALUES (USER(), 5);
+INSERT INTO tt_2 VALUES (USER(), 6);
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+
+
+
+*** "B N* N* T C" with error in N* generates in the binlog the "B N R B N R B T C" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 7), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO nt_1 VALUES (USER(), 8), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES (USER(), 9);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B N* N* T R" with error in N* generates in the binlog the "B N R B N R B T R" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 10), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO nt_1 VALUES (USER(), 11), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES (USER(), 12);
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+
+
+
+*** "B N N T N T C" generates in the binlog the "B N C B N C B T N T C" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 13);
+INSERT INTO nt_1 VALUES (USER(), 14);
+INSERT INTO tt_2 VALUES (USER(), 15);
+INSERT INTO nt_1 VALUES (USER(), 16);
+INSERT INTO tt_2 VALUES (USER(), 17);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B N N T N T R" generates in the binlog the "B N C B N C B T N T R" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 18);
+INSERT INTO nt_1 VALUES (USER(), 19);
+INSERT INTO tt_2 VALUES (USER(), 20);
+INSERT INTO nt_1 VALUES (USER(), 21);
+INSERT INTO tt_2 VALUES (USER(), 22);
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+###################################################################################
+# CLEAN
+###################################################################################
+DROP TABLE tt_1;
+DROP TABLE tt_2;
+DROP TABLE nt_1;
+DROP TABLE nt_2;
diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
index 9ae5121f618..4ccc3b5e797 100644
--- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
+++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
@@ -133,6 +133,10 @@ master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
insert into t1 values(11);
commit;
show binlog events from <binlog_start>;
@@ -144,6 +148,8 @@ master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t2)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
@@ -272,6 +278,10 @@ master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; drop table t1,t2
master-bin.000001 # Query # # use `test`; create table t0 (n int)
master-bin.000001 # Query # # BEGIN
@@ -372,7 +382,7 @@ master-bin.000001 # Query # # use `test`; DROP TABLE if exists t2
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t2
master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (a int, b int, primary key (a)) engine=innodb
master-bin.000001 # Query # # BEGIN
@@ -390,9 +400,11 @@ master-bin.000001 # Query # # use `test`; DROP TABLE t2
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
@@ -400,7 +412,7 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
-master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; TRUNCATE table t2
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
@@ -917,7 +929,7 @@ master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
master-bin.000001 # Intvar # # INSERT_ID=10
master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci
-master-bin.000001 # Execute_load_query # # use `test`; load data infile '../../std_data/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2) ;file_id=#
+master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, @b) SET b=((@b) + `bug27417`(2)) ;file_id=#
master-bin.000001 # Query # # ROLLBACK
drop trigger trg_del_t2;
drop table t1,t2,t3,t4,t5;
diff --git a/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result
new file mode 100644
index 00000000000..2687b21213a
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result
@@ -0,0 +1,161 @@
+Verbose statements from : write-partial-row.binlog
+select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
+stmt
+### INSERT INTO mysql.ndb_apply_status
+### SET
+### @1=1
+### @2=25769803786
+### @3=''
+### @4=0
+### @5=0
+### INSERT INTO test.ba
+### SET
+### @1=3
+### @2=3
+### @3=3
+### INSERT INTO test.ba
+### SET
+### @1=1
+### @2=1
+### @3=1
+### INSERT INTO test.ba
+### SET
+### @1=2
+### @2=2
+### @3=2
+### INSERT INTO test.ba
+### SET
+### @1=4
+### @2=4
+### @3=4
+### INSERT INTO test.ba
+### SET
+### @1=4
+### @3=40
+### DELETE FROM test.ba
+### WHERE
+### @1=2
+drop table raw_binlog_rows;
+Verbose statements from : write-full-row.binlog
+select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
+stmt
+### INSERT INTO mysql.ndb_apply_status
+### SET
+### @1=2
+### @2=25769803786
+### @3=''
+### @4=0
+### @5=0
+### INSERT INTO test.ba
+### SET
+### @1=3
+### @2=3
+### @3=3
+### INSERT INTO test.ba
+### SET
+### @1=1
+### @2=1
+### @3=1
+### INSERT INTO test.ba
+### SET
+### @1=2
+### @2=2
+### @3=2
+### INSERT INTO test.ba
+### SET
+### @1=4
+### @2=4
+### @3=4
+### INSERT INTO test.ba
+### SET
+### @1=4
+### @2=4
+### @3=40
+### DELETE FROM test.ba
+### WHERE
+### @1=2
+drop table raw_binlog_rows;
+Verbose statements from : update-partial-row.binlog
+select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
+stmt
+### INSERT INTO mysql.ndb_apply_status
+### SET
+### @1=3
+### @2=25769803786
+### @3=''
+### @4=0
+### @5=0
+### INSERT INTO test.ba
+### SET
+### @1=3
+### @2=3
+### @3=3
+### INSERT INTO test.ba
+### SET
+### @1=1
+### @2=1
+### @3=1
+### INSERT INTO test.ba
+### SET
+### @1=2
+### @2=2
+### @3=2
+### INSERT INTO test.ba
+### SET
+### @1=4
+### @2=4
+### @3=4
+### UPDATE test.ba
+### WHERE
+### @1=4
+### @3=4
+### SET
+### @1=4
+### @3=40
+### DELETE FROM test.ba
+### WHERE
+### @1=2
+drop table raw_binlog_rows;
+Verbose statements from : update-full-row.binlog
+select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
+stmt
+### INSERT INTO mysql.ndb_apply_status
+### SET
+### @1=4
+### @2=25769803786
+### @3=''
+### @4=0
+### @5=0
+### INSERT INTO test.ba
+### SET
+### @1=3
+### @2=3
+### @3=3
+### INSERT INTO test.ba
+### SET
+### @1=1
+### @2=1
+### @3=1
+### INSERT INTO test.ba
+### SET
+### @1=2
+### @2=2
+### @3=2
+### INSERT INTO test.ba
+### SET
+### @1=4
+### @2=4
+### @3=4
+### UPDATE test.ba
+### WHERE
+### @1=4
+### @2=4
+### @3=4
+### SET
+### @1=4
+### @2=4
+### @3=40
+### DELETE FROM test.ba
+### WHERE
+### @1=2
+drop table raw_binlog_rows;
diff --git a/mysql-test/suite/binlog/r/binlog_stm_binlog.result b/mysql-test/suite/binlog/r/binlog_stm_binlog.result
index d05d3ccdb7a..eebcfceaa25 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result
@@ -784,3 +784,24 @@ INSERT INTO test.t1 VALUES (1), (2);
CREATE TABLE test.t2 SELECT * FROM test.t1;
USE test;
DROP TABLES t1, t2;
+RESET MASTER;
+CREATE TABLE t1 (a INT PRIMARY KEY);
+BINLOG '
+3u9kSA8KAAAAZgAAAGoAAAABAAQANS4xLjM1LW1hcmlhLWJldGExLWRlYnVnLWxvZwAAAAAAAAAA
+AAAAAAAAAAAAAAAAAADe72RIEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
+';
+INSERT INTO t1 VALUES (1);
+BINLOG '
+3u9kSBMUAAAAKQAAAJEBAAAAABoAAAAAAAAABHRlc3QAAnQxAAEDAAA=
+3u9kSBcUAAAAIgAAALMBAAAQABoAAAAAAAEAAf/+AgAAAA==
+';
+SHOW BINLOG EVENTS;
+Log_name Pos Event_type Server_id End_log_pos Info
+# # Format_desc 1 # Server ver: #, Binlog ver: #
+# # Query 1 # use `test`; CREATE TABLE t1 (a INT PRIMARY KEY)
+# # Query 1 # use `test`; INSERT INTO t1 VALUES (1)
+# # Query 1 # BEGIN
+# # Table_map 1 # table_id: # (test.t1)
+# # Write_rows 1 # table_id: # flags: STMT_END_F
+# # Query 1 # COMMIT
+DROP TABLE t1;
diff --git a/mysql-test/suite/binlog/r/binlog_stm_blackhole.result b/mysql-test/suite/binlog/r/binlog_stm_blackhole.result
index f3a01f66fc2..434c1b0896f 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_blackhole.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_blackhole.result
@@ -127,7 +127,7 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; create table t2 (a varchar(200)) engine=blackhole
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=581
-master-bin.000001 # Execute_load_query # # use `test`; load data infile '../../std_data/words.dat' into table t2 ;file_id=#
+master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) ;file_id=#
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; alter table t1 add b int
master-bin.000001 # Query # # use `test`; alter table t1 drop b
diff --git a/mysql-test/suite/binlog/r/binlog_stm_do_db.result b/mysql-test/suite/binlog/r/binlog_stm_do_db.result
new file mode 100644
index 00000000000..ab4ba7cdca1
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_stm_do_db.result
@@ -0,0 +1,42 @@
+SET @old_isolation_level= @@session.tx_isolation;
+SET @@session.tx_isolation= 'READ-COMMITTED';
+CREATE DATABASE b42829;
+use b42829;
+CREATE TABLE t1 (x int, y int) engine=InnoDB;
+CREATE TABLE t2 (x int, y int) engine=InnoDB;
+CREATE DATABASE b42829_filtered;
+use b42829_filtered;
+CREATE TABLE t1 (x int, y int) engine=InnoDB;
+CREATE TABLE t2 (x int, y int) engine=InnoDB;
+SET @@session.sql_log_bin= 0;
+INSERT INTO b42829_filtered.t1 VALUES (100,100);
+INSERT INTO b42829.t1 VALUES (100,100);
+SET @@session.sql_log_bin= 1;
+### assertion: the inserts will not raise log error because
+### binlog-do-db is filtering used database
+INSERT INTO t2 VALUES (1,2), (1,3), (1,4);
+INSERT INTO t1 SELECT * FROM t2;
+### assertion: assert that despite updating a not filtered
+### database this wont trigger an error as the
+### used database is the filtered one.
+UPDATE b42829_filtered.t1 ft1, b42829.t1 nft1 SET ft1.x=1, nft1.x=2;
+use b42829;
+### assertion: the statements *will* raise log error because
+### binlog-do-db is not filtering used database
+BEGIN;
+INSERT INTO t2 VALUES (1,2), (1,3), (1,4);
+ERROR HY000: Binary logging not possible. Message: Transaction level 'READ-COMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT'
+UPDATE b42829_filtered.t1 ft1, b42829.t1 nft1 SET ft1.x=1, nft1.x=2;
+ERROR HY000: Binary logging not possible. Message: Transaction level 'READ-COMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT'
+INSERT INTO t1 SELECT * FROM t2;
+ERROR HY000: Binary logging not possible. Message: Transaction level 'READ-COMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT'
+COMMIT;
+### assertion: filtered events did not make into the binlog
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # CREATE DATABASE b42829
+master-bin.000001 # Query # # use `b42829`; CREATE TABLE t1 (x int, y int) engine=InnoDB
+master-bin.000001 # Query # # use `b42829`; CREATE TABLE t2 (x int, y int) engine=InnoDB
+DROP DATABASE b42829;
+DROP DATABASE b42829_filtered;
+SET @@session.tx_isolation= @old_isolation_level;
diff --git a/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result b/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result
index 4d24b2409b9..19ddcf49080 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result
@@ -1,21 +1,44 @@
-drop database if exists `drop-temp+table-test`;
-reset master;
-create database `drop-temp+table-test`;
-use `drop-temp+table-test`;
-create temporary table shortn1 (a int);
-create temporary table `table:name` (a int);
-create temporary table shortn2 (a int);
-select get_lock("a",10);
-get_lock("a",10)
+DROP DATABASE IF EXISTS `drop-temp+table-test`;
+RESET MASTER;
+CREATE DATABASE `drop-temp+table-test`;
+USE `drop-temp+table-test`;
+CREATE TEMPORARY TABLE shortn1 (a INT);
+CREATE TEMPORARY TABLE `table:name` (a INT);
+CREATE TEMPORARY TABLE shortn2 (a INT);
+CREATE TEMPORARY TABLE tmp(c1 int);
+CREATE TEMPORARY TABLE tmp1(c1 int);
+CREATE TEMPORARY TABLE tmp2(c1 int);
+CREATE TEMPORARY TABLE tmp3(c1 int);
+CREATE TABLE t(c1 int);
+DROP TEMPORARY TABLE IF EXISTS tmp;
+DROP TEMPORARY TABLE IF EXISTS tmp;
+DROP TEMPORARY TABLE IF EXISTS tmp, tmp1;
+DROP TEMPORARY TABLE tmp3;
+DROP TABLE IF EXISTS tmp2, t;
+DROP TABLE IF EXISTS tmp2, t;
+SELECT GET_LOCK("a",10);
+GET_LOCK("a",10)
1
-select get_lock("a",10);
-get_lock("a",10)
+USE test;
+SELECT GET_LOCK("a",10);
+GET_LOCK("a",10)
1
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query # # create database `drop-temp+table-test`
-master-bin.000001 # Query # # use `drop-temp+table-test`; create temporary table shortn1 (a int)
-master-bin.000001 # Query # # use `drop-temp+table-test`; create temporary table `table:name` (a int)
-master-bin.000001 # Query # # use `drop-temp+table-test`; create temporary table shortn2 (a int)
+master-bin.000001 # Query # # CREATE DATABASE `drop-temp+table-test`
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TEMPORARY TABLE shortn1 (a INT)
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TEMPORARY TABLE `table:name` (a INT)
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TEMPORARY TABLE shortn2 (a INT)
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TEMPORARY TABLE tmp(c1 int)
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TEMPORARY TABLE tmp1(c1 int)
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TEMPORARY TABLE tmp2(c1 int)
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TEMPORARY TABLE tmp3(c1 int)
+master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TABLE t(c1 int)
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TEMPORARY TABLE IF EXISTS tmp
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TEMPORARY TABLE IF EXISTS tmp
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TEMPORARY TABLE IF EXISTS tmp, tmp1
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TEMPORARY TABLE tmp3
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS tmp2, t
+master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS tmp2, t
master-bin.000001 # Query # # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `shortn2`,`table:name`,`shortn1`
-drop database `drop-temp+table-test`;
+DROP DATABASE `drop-temp+table-test`;
diff --git a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
index c15374dc1c6..06c57fba2e7 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result
@@ -625,7 +625,7 @@ master-bin.000001 # Query # # BEGIN
master-bin.000001 # Intvar # # INSERT_ID=10
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
master-bin.000001 # Intvar # # INSERT_ID=10
-master-bin.000001 # Execute_load_query # # use `test`; load data infile '../../std_data/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2) ;file_id=#
+master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, @b) SET b=((@b) + `bug27417`(2)) ;file_id=#
master-bin.000001 # Query # # ROLLBACK
/* the output must denote there is the query */;
drop trigger trg_del_t2;
@@ -863,7 +863,7 @@ master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
master-bin.000001 # Intvar # # INSERT_ID=10
master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci
-master-bin.000001 # Execute_load_query # # use `test`; load data infile '../../std_data/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2) ;file_id=#
+master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, @b) SET b=((@b) + `bug27417`(2)) ;file_id=#
master-bin.000001 # Query # # ROLLBACK
drop trigger trg_del_t2;
drop table t1,t2,t3,t4,t5;
diff --git a/mysql-test/suite/binlog/std_data/update-full-row.binlog b/mysql-test/suite/binlog/std_data/update-full-row.binlog
new file mode 100644
index 00000000000..866a351033e
--- /dev/null
+++ b/mysql-test/suite/binlog/std_data/update-full-row.binlog
Binary files differ
diff --git a/mysql-test/suite/binlog/std_data/update-partial-row.binlog b/mysql-test/suite/binlog/std_data/update-partial-row.binlog
new file mode 100644
index 00000000000..67e3611aa3a
--- /dev/null
+++ b/mysql-test/suite/binlog/std_data/update-partial-row.binlog
Binary files differ
diff --git a/mysql-test/suite/binlog/std_data/write-full-row.binlog b/mysql-test/suite/binlog/std_data/write-full-row.binlog
new file mode 100644
index 00000000000..b9edb89e91a
--- /dev/null
+++ b/mysql-test/suite/binlog/std_data/write-full-row.binlog
Binary files differ
diff --git a/mysql-test/suite/binlog/std_data/write-partial-row.binlog b/mysql-test/suite/binlog/std_data/write-partial-row.binlog
new file mode 100644
index 00000000000..7424ec4e940
--- /dev/null
+++ b/mysql-test/suite/binlog/std_data/write-partial-row.binlog
Binary files differ
diff --git a/mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test b/mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test
new file mode 100644
index 00000000000..84c83687486
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test
@@ -0,0 +1,114 @@
+# BUG#34582: FLUSH LOGS does not close and reopen the binlog index
+# file
+#
+# WHAT
+# ====
+#
+# We want to test that FLUSH LOGS closes and reopens binlog index
+# file.
+#
+# HOW
+# ===
+#
+# PREPARE:
+# 1. create some binlog events
+# 2. show index content, binlog events and binlog contents
+# for mysql-bin.000001
+# 3. copy the mysql-bin.000001 to mysql-bin-b34582.000001
+# 4. change the index file so that mysql-bin.000001 is replaced
+# with mysql-bin-b34582.000001
+# 5. FLUSH the logs so that new index is closed and reopened
+#
+# ASSERTIONS:
+# 1. index file contents shows mysql-bin-b34582.000001 and
+# mysql-bin.000002
+# 1. show binary logs shows current index entries
+# 2. binlog contents for mysql-bin-b34582.000001 are displayed
+# 3. Purge binlogs up to the latest one succeeds
+# 4. SHOW BINARY LOGS presents the latest one only after purging
+# 5. Purged binlogs files don't exist in the filesystem
+# 6. Not purged binlog file exists in the filesystem
+#
+# CLEAN UP:
+# 1. RESET MASTER
+#
+
+-- source include/have_log_bin.inc
+
+RESET MASTER;
+
+-- let $datadir= `SELECT @@datadir`
+-- let $index=$datadir/master-bin.index
+-- chmod 0644 $index
+
+# action: issue one command so that binlog gets some event
+CREATE TABLE t1 (a int);
+
+-- echo ### assertion: index file contains regular entries
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval SET @index=LOAD_FILE('$index')
+-- replace_regex /\.[\\\/]master/master/
+SELECT @index;
+
+--echo ### assertion: show original binlogs
+-- source include/show_binary_logs.inc
+
+--echo ### assertion: binlog contents from regular entries
+-- source include/show_binlog_events.inc
+
+# action: copy binlogs to other names and change entries in index file
+-- copy_file $datadir/master-bin.000001 $datadir/master-bin-b34582.000001
+let INDEX_FILE=$index;
+perl;
+$file= $ENV{'INDEX_FILE'};
+open(FILE, ">$file") || die "Unable to open $file.";
+truncate(FILE,0);
+close ($file);
+EOF
+
+-- append_file $index
+master-bin-b34582.000001
+EOF
+
+# action: should cause rotation, and creation of new binlogs
+FLUSH LOGS;
+
+# file is not used anymore - remove it (mysql closed on flush logs).
+-- remove_file $datadir/master-bin.000001
+
+-- echo ### assertion: index file contains renamed binlog and the new one
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval SET @index=LOAD_FILE('$index')
+-- replace_regex /\.[\\\/]master/master/
+SELECT @index;
+
+-- echo ### assertion: original binlog content still exists, despite we
+-- echo ### renamed and changed the index file
+-- source include/show_binlog_events.inc
+
+-- echo ### assertion: user changed binlog index shows correct entries
+-- source include/show_binary_logs.inc
+
+DROP TABLE t1;
+
+-- echo ### assertion: purging binlogs up to binlog created after instrumenting index file should work
+-- let $current_binlog= query_get_value(SHOW MASTER STATUS, File, 1)
+-- eval PURGE BINARY LOGS TO '$current_binlog'
+
+-- echo ### assertion: show binary logs should only contain latest binlog
+-- source include/show_binary_logs.inc
+
+-- echo ### assertion: assert that binlog files were indeed purged (using file_exists calls)
+-- error 1
+-- file_exists $datadir/master-bin-b34852.000001
+
+-- echo ### assertion: assert that not purged binlog file exists
+-- file_exists $datadir/$current_binlog
+
+-- echo ### assertion: show index file contents and these should match show binary logs issued above
+-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+-- eval SET @index=LOAD_FILE('$index')
+-- replace_regex /\.[\\\/]master/master/
+SELECT @index;
+
+RESET MASTER;
diff --git a/mysql-test/suite/binlog/t/binlog_mixed_failure_mixing_engines.test b/mysql-test/suite/binlog/t/binlog_mixed_failure_mixing_engines.test
new file mode 100644
index 00000000000..09b168c2882
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_mixed_failure_mixing_engines.test
@@ -0,0 +1,4 @@
+--source include/have_binlog_format_mixed.inc
+--source include/have_innodb.inc
+
+--source extra/binlog_tests/binlog_failure_mixing_engines.test
diff --git a/mysql-test/suite/binlog/t/binlog_row_failure_mixing_engines.test b/mysql-test/suite/binlog/t/binlog_row_failure_mixing_engines.test
new file mode 100644
index 00000000000..e25af7a7e10
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_row_failure_mixing_engines.test
@@ -0,0 +1,4 @@
+--source include/have_binlog_format_row.inc
+--source include/have_innodb.inc
+
+--source extra/binlog_tests/binlog_failure_mixing_engines.test
diff --git a/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test b/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test
index 0422c204270..6682d84d9c9 100644
--- a/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test
+++ b/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_db_filter.test
@@ -112,17 +112,22 @@ while($i)
# remove unecessary files
-- remove_file $outfile.1
-- remove_file $outfile.2
-
+
+ #
+ # The two tests are canceled since we introduced the patch of bug#46998,
+ # which will make mydsqlbinlog output the 'BEGIN', 'COMMIT' and 'ROLLBACK'
+ # in regardless of database filtering
+ #
# assertion: events for database test are filtered
- if (`SELECT INSTR(@b42941_output.1, 'test')`)
- {
- -- echo **** ERROR **** Database name 'test' FOUND in mysqlbinlog output ($flags $outfile.1).
- }
-
- if (`SELECT INSTR(@b42941_output.2, 'test')`)
- {
- -- echo **** ERROR **** Database name 'test' FOUND in mysqlbinlog output ($flags $outfile.2).
- }
+ #if (`SELECT INSTR(@b42941_output.1, 'test')`)
+ #{
+ #-- echo **** ERROR **** Database name 'test' FOUND in mysqlbinlog output ($flags $outfile.1).
+ #}
+
+ #if (`SELECT INSTR(@b42941_output.2, 'test')`)
+ #{
+ #-- echo **** ERROR **** Database name 'test' FOUND in mysqlbinlog output ($flags $outfile.2).
+ #}
# assertion: events for database b42941 are not filtered
if (!`SELECT INSTR(@b42941_output.1, 'b42941')`)
diff --git a/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test b/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test
new file mode 100644
index 00000000000..42d92e1a44d
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test
@@ -0,0 +1,86 @@
+########################################################
+# Test mysqlbinlog command with Ndb produced Binlog
+# variants
+#
+# WHAT
+# ====
+# This test aims to check that the mysqlbinlog --verbose
+# command can output binlogs in 4 format variants, currently
+# used by Ndb
+#
+# 1) Updates logged as write_row events
+# Only primary key and updated columns included in the
+# event
+# 2) Updates logged as write_row_events
+# All columns included in the event
+# 3) Updates logged as update_row events
+# Only primary key and updated columns included in the
+# event
+# 4) Updates logged as update_row events
+# All columns included in the event
+#
+# Format variant (1) is the Ndb default.
+# Bug#47323 resulted in binlogs generated in format (1)
+# being incorrectly parsed by the mysqlbinlog --verbose
+# option
+#
+# HOW
+# ===
+# Row-based binlog files in each format have been
+# captured from an Ndb cluster
+# These are output using the mysqlbinlog --verbose
+# tool and the output is checked.
+#
+########################################################
+
+# We require binlog_format_row as we're independent of binlog format
+# and there's no point running the same test 3 times
+-- source include/have_binlog_format_row.inc
+
+--disable_query_log
+--let $binlog_file=write-partial-row.binlog
+--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+create table raw_binlog_rows (txt varchar(1000));
+--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
+--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+--enable_query_log
+--echo Verbose statements from : $binlog_file
+# Output --verbose lines, with extra Windows CR's trimmed
+select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
+drop table raw_binlog_rows;
+
+--disable_query_log
+--let $binlog_file=write-full-row.binlog
+--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+create table raw_binlog_rows (txt varchar(1000));
+--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
+--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+--enable_query_log
+--echo Verbose statements from : $binlog_file
+# Output --verbose lines, with extra Windows CR's trimmed
+select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
+drop table raw_binlog_rows;
+
+--disable_query_log
+--let $binlog_file=update-partial-row.binlog
+--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+create table raw_binlog_rows (txt varchar(1000));
+--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
+--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+--enable_query_log
+--echo Verbose statements from : $binlog_file
+# Output --verbose lines, with extra Windows CR's trimmed
+select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
+drop table raw_binlog_rows;
+
+--disable_query_log
+--let $binlog_file=update-full-row.binlog
+--exec $MYSQL_BINLOG --verbose suite/binlog/std_data/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+create table raw_binlog_rows (txt varchar(1000));
+--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n';
+--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
+--enable_query_log
+--echo Verbose statements from : $binlog_file
+# Output --verbose lines, with extra Windows CR's trimmed
+select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
+drop table raw_binlog_rows;
diff --git a/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt b/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt
new file mode 100644
index 00000000000..e2cfcb299cf
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_stm_do_db-master.opt
@@ -0,0 +1 @@
+--binlog-do-db=b42829
diff --git a/mysql-test/suite/binlog/t/binlog_stm_do_db.test b/mysql-test/suite/binlog/t/binlog_stm_do_db.test
new file mode 100644
index 00000000000..858bc8cc683
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_stm_do_db.test
@@ -0,0 +1,90 @@
+# BUG#42829: binlogging enabled for all schemas regardless of
+# binlog-db-db / binlog-ignore-db
+#
+# WHAT
+# ====
+#
+# We want to test whether filtered events from binlog will cause
+# raising an error mentioning that statement is unable to be logged or
+# not, when:
+#
+# 1. isolation level READ-COMMITTED; AND
+#
+# 2. using InnoDB engine; AND
+#
+# 3. using SBL (in which case InnoDB will only allow RBL).
+#
+# HOW
+# ===
+#
+# The test is implemented as follows:
+#
+# i) set tx_isolation to read-committed.
+#
+# ii) create two databases (one filtered other not - using
+# binlog-do-db)
+#
+# iii) Create statements that are to be filtered on filtered db
+#
+# - At this point, before fix, an error would be raised
+#
+# iv) do the same thing for not the filtered database and check
+# that events throw an error:
+#
+# - Error: ER_BINLOG_STMT_MODE_AND_ROW_ENGINE
+#
+
+-- source include/have_log_bin.inc
+-- source include/have_innodb.inc
+-- source include/have_binlog_format_statement.inc
+
+SET @old_isolation_level= @@session.tx_isolation;
+SET @@session.tx_isolation= 'READ-COMMITTED';
+
+-- let $engine= InnoDB
+-- let $filtered= b42829_filtered
+-- let $not_filtered= b42829
+
+-- eval CREATE DATABASE $not_filtered
+-- eval use $not_filtered
+-- eval CREATE TABLE t1 (x int, y int) engine=$engine
+-- eval CREATE TABLE t2 (x int, y int) engine=$engine
+
+-- eval CREATE DATABASE $filtered
+-- eval use $filtered
+-- eval CREATE TABLE t1 (x int, y int) engine=$engine
+-- eval CREATE TABLE t2 (x int, y int) engine=$engine
+
+SET @@session.sql_log_bin= 0;
+-- eval INSERT INTO $filtered.t1 VALUES (100,100)
+-- eval INSERT INTO $not_filtered.t1 VALUES (100,100)
+SET @@session.sql_log_bin= 1;
+
+-- echo ### assertion: the inserts will not raise log error because
+-- echo ### binlog-do-db is filtering used database
+INSERT INTO t2 VALUES (1,2), (1,3), (1,4);
+INSERT INTO t1 SELECT * FROM t2;
+
+-- echo ### assertion: assert that despite updating a not filtered
+-- echo ### database this wont trigger an error as the
+-- echo ### used database is the filtered one.
+-- eval UPDATE $filtered.t1 ft1, $not_filtered.t1 nft1 SET ft1.x=1, nft1.x=2
+
+-- eval use $not_filtered
+-- echo ### assertion: the statements *will* raise log error because
+-- echo ### binlog-do-db is not filtering used database
+BEGIN;
+-- error ER_BINLOG_LOGGING_IMPOSSIBLE
+INSERT INTO t2 VALUES (1,2), (1,3), (1,4);
+-- error ER_BINLOG_LOGGING_IMPOSSIBLE
+-- eval UPDATE $filtered.t1 ft1, $not_filtered.t1 nft1 SET ft1.x=1, nft1.x=2
+-- error ER_BINLOG_LOGGING_IMPOSSIBLE
+INSERT INTO t1 SELECT * FROM t2;
+COMMIT;
+
+-- echo ### assertion: filtered events did not make into the binlog
+source include/show_binlog_events.inc;
+
+-- eval DROP DATABASE $not_filtered
+-- eval DROP DATABASE $filtered
+SET @@session.tx_isolation= @old_isolation_level;
diff --git a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test
index a5472952f08..21c11d5a3df 100644
--- a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test
+++ b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test
@@ -94,15 +94,24 @@ DROP TABLE t1;
SET GLOBAL log_warnings = @old_log_warnings;
-let LOG_ERROR= `SELECT @@GLOBAL.log_error`;
+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_;
--echo # Count the number of times the "Unsafe" message was printed
--echo # to the error log.
perl;
- $log_error= $ENV{'LOG_ERROR'};
+ use strict;
+ my $log_error= $ENV{'LOG_ERROR'} or die "LOG_ERROR not set";
open(FILE, "$log_error") or die("Unable to open $log_error: $!\n");
- $count = () = grep(/Bug#46265/g,<FILE>);
+ my $count = () = grep(/Bug#46265/g,<FILE>);
print "Occurrences: $count\n";
close(FILE);
EOF
diff --git a/mysql-test/suite/federated/federated_debug-master.opt b/mysql-test/suite/federated/federated_debug-master.opt
new file mode 100644
index 00000000000..ad9ba4795af
--- /dev/null
+++ b/mysql-test/suite/federated/federated_debug-master.opt
@@ -0,0 +1 @@
+--loose-debug=d,simulate_detached_thread_refresh
diff --git a/mysql-test/suite/federated/federated_debug.result b/mysql-test/suite/federated/federated_debug.result
new file mode 100644
index 00000000000..73a6cac892e
--- /dev/null
+++ b/mysql-test/suite/federated/federated_debug.result
@@ -0,0 +1,33 @@
+CREATE DATABASE federated;
+CREATE DATABASE federated;
+#
+# Bug#47525: MySQL crashed (Federated)
+#
+# Switch to slave
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1);
+# Switch to master
+CREATE TABLE t1(a INT) ENGINE=FEDERATED
+CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
+SELECT * FROM t1;
+a
+1
+# Start a asynchronous reload
+# Wait for tables to be closed
+# Timeout in include/wait_show_condition.inc for
+# show_statement : SHOW STATUS LIKE 'Open_tables'
+# field : Value
+# condition : = '0'
+# max_run_time : 31
+# Ensure that the server didn't crash
+SELECT * FROM t1;
+a
+1
+# Drop tables on master and slave
+DROP TABLE t1;
+DROP TABLE t1;
+# Federated cleanup
+DROP TABLE IF EXISTS federated.t1;
+DROP DATABASE IF EXISTS federated;
+DROP TABLE IF EXISTS federated.t1;
+DROP DATABASE IF EXISTS federated;
diff --git a/mysql-test/suite/federated/federated_debug.test b/mysql-test/suite/federated/federated_debug.test
new file mode 100644
index 00000000000..4152d2975b3
--- /dev/null
+++ b/mysql-test/suite/federated/federated_debug.test
@@ -0,0 +1,39 @@
+--source include/have_debug.inc
+--source federated.inc
+
+--echo #
+--echo # Bug#47525: MySQL crashed (Federated)
+--echo #
+
+connection slave;
+--echo # Switch to slave
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1);
+
+connection master;
+--echo # Switch to master
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval CREATE TABLE t1(a INT) ENGINE=FEDERATED
+ CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1';
+
+SELECT * FROM t1;
+
+--echo # Start a asynchronous reload
+--exec $MYSQLADMIN --no-defaults -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= refresh 2>&1
+
+--echo # Wait for tables to be closed
+let $show_statement= SHOW STATUS LIKE 'Open_tables';
+let $field= Value;
+let $condition= = '0';
+--source include/wait_show_condition.inc
+
+--echo # Ensure that the server didn't crash
+SELECT * FROM t1;
+--echo # Drop tables on master and slave
+DROP TABLE t1;
+connection slave;
+DROP TABLE t1;
+
+connection default;
+--echo # Federated cleanup
+source federated_cleanup.inc;
diff --git a/mysql-test/suite/federated/my.cnf b/mysql-test/suite/federated/my.cnf
index 3e84845b945..82600949712 100644
--- a/mysql-test/suite/federated/my.cnf
+++ b/mysql-test/suite/federated/my.cnf
@@ -9,4 +9,7 @@ log-bin= master-bin
[ENV]
MASTER_MYPORT= @mysqld.1.port
+MASTER_MYSOCK= @mysqld.1.socket
+
SLAVE_MYPORT= @mysqld.2.port
+SLAVE_MYSOCK= @mysqld.2.socket
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 2f1f61c0525..98eeacdb74c 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result
@@ -130,7 +130,7 @@ NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references
NULL mysql procs_priv Host 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
NULL mysql procs_priv Proc_priv 7 NO set 27 81 NULL NULL utf8 utf8_general_ci set('Execute','Alter Routine','Grant') select,insert,update,references
-NULL mysql procs_priv Routine_name 4 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
+NULL mysql procs_priv Routine_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
NULL mysql procs_priv Routine_type 5 NULL NO enum 9 27 NULL NULL utf8 utf8_bin enum('FUNCTION','PROCEDURE') PRI select,insert,update,references
NULL mysql procs_priv Timestamp 8 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL NULL NULL timestamp on update CURRENT_TIMESTAMP select,insert,update,references
NULL mysql procs_priv User 3 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
@@ -411,7 +411,7 @@ NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
3.0000 mysql procs_priv Host char 60 180 utf8 utf8_bin char(60)
3.0000 mysql procs_priv Db char 64 192 utf8 utf8_bin char(64)
3.0000 mysql procs_priv User char 16 48 utf8 utf8_bin char(16)
-3.0000 mysql procs_priv Routine_name char 64 192 utf8 utf8_bin char(64)
+3.0000 mysql procs_priv Routine_name char 64 192 utf8 utf8_general_ci char(64)
3.0000 mysql procs_priv Routine_type enum 9 27 utf8 utf8_bin enum('FUNCTION','PROCEDURE')
3.0000 mysql procs_priv Grantor char 77 231 utf8 utf8_bin char(77)
3.0000 mysql procs_priv Proc_priv set 27 81 utf8 utf8_general_ci set('Execute','Alter Routine','Grant')
diff --git a/mysql-test/suite/funcs_1/r/is_statistics.result b/mysql-test/suite/funcs_1/r/is_statistics.result
index 989fd9dc4e6..8452536d4ed 100644
--- a/mysql-test/suite/funcs_1/r/is_statistics.result
+++ b/mysql-test/suite/funcs_1/r/is_statistics.result
@@ -166,8 +166,8 @@ NULL db_datadict_2 t4 0 db_datadict_2 PRIMARY 1 f1 NULL 0 NULL NULL HASH
SHOW GRANTS FOR 'testuser1'@'localhost';
Grants for testuser1@localhost
GRANT USAGE ON *.* TO 'testuser1'@'localhost'
-GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost'
GRANT SELECT ON `db_datadict`.`t1` TO 'testuser1'@'localhost' WITH GRANT OPTION
+GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost'
SHOW GRANTS FOR 'testuser2'@'localhost';
Grants for testuser2@localhost
GRANT USAGE ON *.* TO 'testuser2'@'localhost'
@@ -185,8 +185,8 @@ NULL db_datadict_2 t3 0 db_datadict_2 PRIMARY 1 f1 NULL 0 NULL NULL HASH
SHOW GRANTS FOR 'testuser1'@'localhost';
Grants for testuser1@localhost
GRANT USAGE ON *.* TO 'testuser1'@'localhost'
-GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost'
GRANT SELECT ON `db_datadict`.`t1` TO 'testuser1'@'localhost' WITH GRANT OPTION
+GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO 'testuser1'@'localhost'
SHOW GRANTS FOR 'testuser2'@'localhost';
ERROR 42000: Access denied for user 'testuser1'@'localhost' to database 'mysql'
# Switch to connection testuser2
diff --git a/mysql-test/suite/innodb/r/innodb-consistent.result b/mysql-test/suite/innodb/r/innodb-consistent.result
new file mode 100644
index 00000000000..9115791b99c
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-consistent.result
@@ -0,0 +1,35 @@
+drop table if exists t1;
+set session transaction isolation level read committed;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+create table t2 like t1;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7);
+set autocommit=0;
+begin;
+replace into t1 select * from t2;
+set session transaction isolation level read committed;
+set autocommit=0;
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+commit;
+begin;
+insert into t1 select * from t2;
+set session transaction isolation level read committed;
+set autocommit=0;
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+commit;
+select * from t1;
+a
+1
+2
+3
+4
+5
+6
+7
+drop table t1;
+drop table t2;
diff --git a/mysql-test/suite/innodb/r/innodb-zip.result b/mysql-test/suite/innodb/r/innodb-zip.result
index c81401743a5..21396d81ba8 100644
--- a/mysql-test/suite/innodb/r/innodb-zip.result
+++ b/mysql-test/suite/innodb/r/innodb-zip.result
@@ -141,7 +141,7 @@ drop table t1;
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440)))
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
-CREATE TABLE t1(c TEXT, PRIMARY KEY (c(439)))
+CREATE TABLE t1(c TEXT, PRIMARY KEY (c(438)))
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512));
DROP TABLE t1;
@@ -196,15 +196,15 @@ drop table t1;
set innodb_strict_mode = on;
create table t1 (id int primary key) engine = innodb key_block_size = 0;
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 0. Valid values are [1, 2, 4, 8, 16]
+Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 0. Valid values are [1, 2, 4, 8, 16]
Error 1005 Can't create table 'test.t1' (errno: 1478)
create table t2 (id int primary key) engine = innodb key_block_size = 9;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
+Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t3 (id int primary key) engine = innodb key_block_size = 1;
create table t4 (id int primary key) engine = innodb key_block_size = 2;
@@ -233,30 +233,30 @@ key_block_size = 8 row_format = compressed;
create table t2 (id int primary key) engine = innodb
key_block_size = 8 row_format = redundant;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t3 (id int primary key) engine = innodb
key_block_size = 8 row_format = compact;
ERROR HY000: Can't create table 'test.t3' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t3' (errno: 1478)
create table t4 (id int primary key) engine = innodb
key_block_size = 8 row_format = dynamic;
ERROR HY000: Can't create table 'test.t4' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t4' (errno: 1478)
create table t5 (id int primary key) engine = innodb
key_block_size = 8 row_format = default;
ERROR HY000: Can't create table 'test.t5' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t5' (errno: 1478)
SELECT table_schema, table_name, row_format
FROM information_schema.tables WHERE engine='innodb';
@@ -266,26 +266,26 @@ drop table t1;
create table t1 (id int primary key) engine = innodb
key_block_size = 9 row_format = redundant;
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
-Error 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t1' (errno: 1478)
create table t2 (id int primary key) engine = innodb
key_block_size = 9 row_format = compact;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
-Error 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t2 (id int primary key) engine = innodb
key_block_size = 9 row_format = dynamic;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
-Error 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
+Warning 1478 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16]
+Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
Error 1005 Can't create table 'test.t2' (errno: 1478)
SELECT table_schema, table_name, row_format
FROM information_schema.tables WHERE engine='innodb';
@@ -293,45 +293,45 @@ table_schema table_name row_format
set global innodb_file_per_table = off;
create table t1 (id int primary key) engine = innodb key_block_size = 1;
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table 'test.t1' (errno: 1478)
create table t2 (id int primary key) engine = innodb key_block_size = 2;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t3 (id int primary key) engine = innodb key_block_size = 4;
ERROR HY000: Can't create table 'test.t3' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table 'test.t3' (errno: 1478)
create table t4 (id int primary key) engine = innodb key_block_size = 8;
ERROR HY000: Can't create table 'test.t4' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table 'test.t4' (errno: 1478)
create table t5 (id int primary key) engine = innodb key_block_size = 16;
ERROR HY000: Can't create table 'test.t5' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table 'test.t5' (errno: 1478)
create table t6 (id int primary key) engine = innodb row_format = compressed;
ERROR HY000: Can't create table 'test.t6' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table.
+Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table.
Error 1005 Can't create table 'test.t6' (errno: 1478)
create table t7 (id int primary key) engine = innodb row_format = dynamic;
ERROR HY000: Can't create table 'test.t7' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
+Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
Error 1005 Can't create table 'test.t7' (errno: 1478)
create table t8 (id int primary key) engine = innodb row_format = compact;
create table t9 (id int primary key) engine = innodb row_format = redundant;
@@ -345,45 +345,45 @@ set global innodb_file_per_table = on;
set global innodb_file_format = `0`;
create table t1 (id int primary key) engine = innodb key_block_size = 1;
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t1' (errno: 1478)
create table t2 (id int primary key) engine = innodb key_block_size = 2;
ERROR HY000: Can't create table 'test.t2' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t2' (errno: 1478)
create table t3 (id int primary key) engine = innodb key_block_size = 4;
ERROR HY000: Can't create table 'test.t3' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t3' (errno: 1478)
create table t4 (id int primary key) engine = innodb key_block_size = 8;
ERROR HY000: Can't create table 'test.t4' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t4' (errno: 1478)
create table t5 (id int primary key) engine = innodb key_block_size = 16;
ERROR HY000: Can't create table 'test.t5' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t5' (errno: 1478)
create table t6 (id int primary key) engine = innodb row_format = compressed;
ERROR HY000: Can't create table 'test.t6' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t6' (errno: 1478)
create table t7 (id int primary key) engine = innodb row_format = dynamic;
ERROR HY000: Can't create table 'test.t7' (errno: 1478)
-show errors;
+show warnings;
Level Code Message
-Error 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope.
+Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.t7' (errno: 1478)
create table t8 (id int primary key) engine = innodb row_format = compact;
create table t9 (id int primary key) engine = innodb row_format = redundant;
diff --git a/mysql-test/suite/innodb/r/innodb_bug44571.result b/mysql-test/suite/innodb/r/innodb_bug44571.result
new file mode 100644
index 00000000000..36374edcb3e
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_bug44571.result
@@ -0,0 +1,9 @@
+CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
+ALTER TABLE bug44571 CHANGE foo bar INT;
+ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
+ERROR 42000: Key column 'foo' doesn't exist in table
+ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
+ERROR HY000: Incorrect key file for table 'bug44571'; try to repair it
+CREATE INDEX bug44571b ON bug44571 (bar);
+ERROR HY000: Incorrect key file for table 'bug44571'; try to repair it
+DROP TABLE bug44571;
diff --git a/mysql-test/suite/innodb/t/innodb-consistent-master.opt b/mysql-test/suite/innodb/t/innodb-consistent-master.opt
new file mode 100644
index 00000000000..e76299453d3
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-consistent-master.opt
@@ -0,0 +1 @@
+--innodb_lock_wait_timeout=2
diff --git a/mysql-test/suite/innodb/t/innodb-consistent.test b/mysql-test/suite/innodb/t/innodb-consistent.test
new file mode 100644
index 00000000000..b58d0cb0e62
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-consistent.test
@@ -0,0 +1,59 @@
+-- source include/not_embedded.inc
+-- source include/have_innodb.inc
+-- source suite/innodb/include/have_innodb_plugin.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+# REPLACE INTO ... SELECT and INSERT INTO ... SELECT should do
+# a consistent read of the source table.
+
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+set session transaction isolation level read committed;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+create table t2 like t1;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7);
+set autocommit=0;
+
+# REPLACE INTO ... SELECT case
+begin;
+# this should not result in any locks on t2.
+replace into t1 select * from t2;
+
+connection b;
+set session transaction isolation level read committed;
+set autocommit=0;
+# should not cuase a lock wait.
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+connection a;
+commit;
+
+# INSERT INTO ... SELECT case
+begin;
+# this should not result in any locks on t2.
+insert into t1 select * from t2;
+
+connection b;
+set session transaction isolation level read committed;
+set autocommit=0;
+# should not cuase a lock wait.
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+connection a;
+commit;
+
+select * from t1;
+drop table t1;
+drop table t2;
+
+connection default;
+disconnect a;
+disconnect b;
diff --git a/mysql-test/suite/innodb/t/innodb-zip.test b/mysql-test/suite/innodb/t/innodb-zip.test
index 3ee278b7c5a..c27392ac4fa 100644
--- a/mysql-test/suite/innodb/t/innodb-zip.test
+++ b/mysql-test/suite/innodb/t/innodb-zip.test
@@ -106,7 +106,7 @@ drop table t1;
--error ER_TOO_BIG_ROWSIZE
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440)))
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
-CREATE TABLE t1(c TEXT, PRIMARY KEY (c(439)))
+CREATE TABLE t1(c TEXT, PRIMARY KEY (c(438)))
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512));
DROP TABLE t1;
@@ -175,11 +175,11 @@ set innodb_strict_mode = on;
--error ER_CANT_CREATE_TABLE
create table t1 (id int primary key) engine = innodb key_block_size = 0;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb key_block_size = 9;
-show errors;
+show warnings;
create table t3 (id int primary key) engine = innodb key_block_size = 1;
@@ -205,22 +205,22 @@ key_block_size = 8 row_format = compressed;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb
key_block_size = 8 row_format = redundant;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t3 (id int primary key) engine = innodb
key_block_size = 8 row_format = compact;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t4 (id int primary key) engine = innodb
key_block_size = 8 row_format = dynamic;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t5 (id int primary key) engine = innodb
key_block_size = 8 row_format = default;
-show errors;
+show warnings;
SELECT table_schema, table_name, row_format
FROM information_schema.tables WHERE engine='innodb';
@@ -230,17 +230,17 @@ drop table t1;
--error ER_CANT_CREATE_TABLE
create table t1 (id int primary key) engine = innodb
key_block_size = 9 row_format = redundant;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb
key_block_size = 9 row_format = compact;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb
key_block_size = 9 row_format = dynamic;
-show errors;
+show warnings;
SELECT table_schema, table_name, row_format
FROM information_schema.tables WHERE engine='innodb';
@@ -250,25 +250,25 @@ set global innodb_file_per_table = off;
--error ER_CANT_CREATE_TABLE
create table t1 (id int primary key) engine = innodb key_block_size = 1;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb key_block_size = 2;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t3 (id int primary key) engine = innodb key_block_size = 4;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t4 (id int primary key) engine = innodb key_block_size = 8;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t5 (id int primary key) engine = innodb key_block_size = 16;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t6 (id int primary key) engine = innodb row_format = compressed;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t7 (id int primary key) engine = innodb row_format = dynamic;
-show errors;
+show warnings;
create table t8 (id int primary key) engine = innodb row_format = compact;
create table t9 (id int primary key) engine = innodb row_format = redundant;
@@ -282,25 +282,25 @@ set global innodb_file_format = `0`;
--error ER_CANT_CREATE_TABLE
create table t1 (id int primary key) engine = innodb key_block_size = 1;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t2 (id int primary key) engine = innodb key_block_size = 2;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t3 (id int primary key) engine = innodb key_block_size = 4;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t4 (id int primary key) engine = innodb key_block_size = 8;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t5 (id int primary key) engine = innodb key_block_size = 16;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t6 (id int primary key) engine = innodb row_format = compressed;
-show errors;
+show warnings;
--error ER_CANT_CREATE_TABLE
create table t7 (id int primary key) engine = innodb row_format = dynamic;
-show errors;
+show warnings;
create table t8 (id int primary key) engine = innodb row_format = compact;
create table t9 (id int primary key) engine = innodb row_format = redundant;
diff --git a/mysql-test/suite/innodb/t/innodb_bug44571.test b/mysql-test/suite/innodb/t/innodb_bug44571.test
new file mode 100644
index 00000000000..43f290cde84
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_bug44571.test
@@ -0,0 +1,18 @@
+#
+# Bug#44571 InnoDB Plugin crashes on ADD INDEX
+# http://bugs.mysql.com/44571
+#
+-- source include/have_innodb.inc
+-- source suite/innodb/include/have_innodb_plugin.inc
+
+CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
+ALTER TABLE bug44571 CHANGE foo bar INT;
+-- error ER_KEY_COLUMN_DOES_NOT_EXITS
+ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
+# The following will fail, because the CHANGE foo bar was
+# not communicated to InnoDB.
+--error ER_NOT_KEYFILE
+ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
+--error ER_NOT_KEYFILE
+CREATE INDEX bug44571b ON bug44571 (bar);
+DROP TABLE bug44571;
diff --git a/mysql-test/suite/innodb/t/innodb_information_schema.test b/mysql-test/suite/innodb/t/innodb_information_schema.test
index df65139448c..599215e9ca4 100644
--- a/mysql-test/suite/innodb/t/innodb_information_schema.test
+++ b/mysql-test/suite/innodb/t/innodb_information_schema.test
@@ -110,14 +110,18 @@ SELECT * FROM ```t'\"_str` WHERE c1 = '3' FOR UPDATE;
-- send
SELECT * FROM ```t'\"_str` WHERE c1 = '4' FOR UPDATE;
-# Give time to the above 2 queries to execute before continuing.
-# Without this sleep it sometimes happens that the SELECT from innodb_locks
-# executes before some of them, resulting in less than expected number
-# of rows being selected from innodb_locks.
--- sleep 0.1
-
-- enable_result_log
-- connection con_verify_innodb_locks
+# Wait for the above queries to execute before continuing.
+# Without this, it sometimes happens that the SELECT from innodb_locks
+# executes before some of them, resulting in less than expected number
+# of rows being selected from innodb_locks. If there is a bug and there
+# are no 14 rows in innodb_locks then this test will fail with timeout.
+let $count = 14;
+let $table = INFORMATION_SCHEMA.INNODB_LOCKS;
+-- source include/wait_until_rows_count.inc
+# the above enables the query log, re-disable it
+-- disable_query_log
SELECT lock_mode, lock_type, lock_table, lock_index, lock_rec, lock_data
FROM INFORMATION_SCHEMA.INNODB_LOCKS ORDER BY lock_data;
diff --git a/mysql-test/suite/parts/inc/partition_auto_increment.inc b/mysql-test/suite/parts/inc/partition_auto_increment.inc
index 6963de90c83..2c615e58ef9 100644
--- a/mysql-test/suite/parts/inc/partition_auto_increment.inc
+++ b/mysql-test/suite/parts/inc/partition_auto_increment.inc
@@ -623,3 +623,195 @@ SHOW CREATE TABLE t1;
SELECT * FROM t1 ORDER BY c1;
DROP TABLE t1;
+if (!$skip_negative_auto_inc)
+{
+--echo #############################################################################
+--echo # Bug #45823 - Assertion failure in file row/row0mysql.c line 1386
+--echo # Bug #43988 - AUTO_INCREMENT errors with partitioned InnoDB tables in 5.1.31
+--echo ##############################################################################
+
+--echo # Inserting negative autoincrement values into a partition table (partitions >= 4)
+
+eval CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+ c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 4;
+
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t(c2) VALUES (40);
+
+SELECT * FROM t ORDER BY c1 ASC;
+
+DROP TABLE t;
+
+--echo # Reading from a partition table (partitions >= 2 ) after inserting a negative
+--echo # value into the auto increment column
+
+
+eval CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+ c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 2;
+
+INSERT INTO t VALUES (-2,-20);
+INSERT INTO t(c2) VALUES (30);
+
+SELECT * FROM t ORDER BY c1 ASC;
+
+DROP TABLE t;
+
+--echo # Inserting negative auto increment value into a partition table (partitions >= 2)
+--echo # auto increment value > 2.
+
+eval CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+ c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 2;
+
+INSERT INTO t VALUES (-4,-20);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t(c2) VALUES (40);
+
+SELECT * FROM t ORDER BY c1 ASC;
+
+DROP TABLE t;
+
+--echo # Inserting -1 into autoincrement column of a partition table (partition >= 4)
+
+eval CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+ c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 4;
+
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+
+SELECT * FROM t ORDER BY c1 ASC;
+
+INSERT INTO t(c2) VALUES (30);
+
+SELECT * FROM t ORDER BY c1 ASC;
+
+DROP TABLE t;
+
+--echo # Deleting from an auto increment table after inserting negative values
+
+eval CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+ c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 4;
+
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t VALUES (-3,-20);
+INSERT INTO t(c2) VALUES (40);
+
+SELECT * FROM t ORDER BY c1 ASC;
+
+if (!$skip_delete)
+{
+DELETE FROM t WHERE c1 > 1;
+}
+
+SELECT * FROM t ORDER BY c1 ASC;
+
+DROP TABLE t;
+
+--echo # Inserting a positive value that exceeds maximum allowed value for an
+--echo # Auto Increment column (positive maximum)
+
+eval CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+ c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 4;
+
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (126,30);
+INSERT INTO t VALUES (127,40);
+
+--error ER_DUP_ENTRY
+INSERT INTO t VALUES (128,50);
+--error ER_DUP_ENTRY
+INSERT INTO t VALUES (129,60);
+
+SELECT * FROM t ORDER BY c1 ASC;
+
+DROP TABLE t;
+
+--echo # Inserting a negative value that goes below minimum allowed value for an
+--echo # Auto Increment column (negative minimum)
+
+eval CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+ c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 4;
+
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-127,30);
+INSERT INTO t VALUES (-128,40);
+
+--error ER_DUP_ENTRY
+INSERT INTO t VALUES (-129,50);
+--error ER_DUP_ENTRY
+INSERT INTO t VALUES (-130,60);
+
+SELECT * FROM t ORDER BY c1 ASC;
+
+DROP TABLE t;
+
+--echo # Updating the partition table with a negative Auto Increment value
+
+eval CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+ c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 4;
+
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+
+SELECT * FROM t ORDER BY c1 ASC;
+
+if (!$skip_update)
+{
+UPDATE t SET c1 = -6 WHERE c1 = 2;
+}
+
+SELECT * FROM t ORDER BY c1 ASC;
+
+INSERT INTO t(c2) VALUES (40);
+INSERT INTO t(c2) VALUES (50);
+
+if (!$skip_update)
+{
+UPDATE t SET c1 = -6 WHERE c1 = 2;
+}
+
+SELECT * FROM t ORDER BY c1 ASC;
+
+DROP TABLE t;
+
+--echo # Updating the partition table with a value that crosses the upper limits
+--echo # on both the positive and the negative side.
+
+eval CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+ c2 INT) ENGINE=$engine PARTITION BY HASH(c1) PARTITIONS 4;
+
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (126,30);
+INSERT INTO t VALUES (127,40);
+
+SELECT * FROM t ORDER BY c1 ASC;
+
+if (!$skip_update)
+{
+UPDATE t SET c1 = 130 where c1 = 127;
+}
+
+SELECT * FROM t ORDER BY c1 ASC;
+
+if (!$skip_update)
+{
+UPDATE t SET c1 = -140 where c1 = 126;
+}
+
+SELECT * FROM t ORDER BY c1 ASC;
+
+DROP TABLE t;
+
+--echo ##############################################################################
+}
diff --git a/mysql-test/suite/parts/r/partition_auto_increment_innodb.result b/mysql-test/suite/parts/r/partition_auto_increment_innodb.result
index 9a23cd4364e..6295d14d98f 100644
--- a/mysql-test/suite/parts/r/partition_auto_increment_innodb.result
+++ b/mysql-test/suite/parts/r/partition_auto_increment_innodb.result
@@ -825,3 +825,194 @@ c1
4
5
DROP TABLE t1;
+#############################################################################
+# Bug #45823 - Assertion failure in file row/row0mysql.c line 1386
+# Bug #43988 - AUTO_INCREMENT errors with partitioned InnoDB tables in 5.1.31
+##############################################################################
+# Inserting negative autoincrement values into a partition table (partitions >= 4)
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t(c2) VALUES (40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+3 30
+4 40
+DROP TABLE t;
+# Reading from a partition table (partitions >= 2 ) after inserting a negative
+# value into the auto increment column
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 2;
+INSERT INTO t VALUES (-2,-20);
+INSERT INTO t(c2) VALUES (30);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-2 -20
+1 30
+DROP TABLE t;
+# Inserting negative auto increment value into a partition table (partitions >= 2)
+# auto increment value > 2.
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 2;
+INSERT INTO t VALUES (-4,-20);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t(c2) VALUES (40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-4 -20
+1 30
+2 40
+DROP TABLE t;
+# Inserting -1 into autoincrement column of a partition table (partition >= 4)
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+INSERT INTO t(c2) VALUES (30);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+3 30
+DROP TABLE t;
+# Deleting from an auto increment table after inserting negative values
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t VALUES (-3,-20);
+INSERT INTO t(c2) VALUES (40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-3 -20
+-1 -10
+1 10
+2 20
+3 30
+4 40
+DELETE FROM t WHERE c1 > 1;
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-3 -20
+-1 -10
+1 10
+DROP TABLE t;
+# Inserting a positive value that exceeds maximum allowed value for an
+# Auto Increment column (positive maximum)
+CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (126,30);
+INSERT INTO t VALUES (127,40);
+INSERT INTO t VALUES (128,50);
+ERROR 23000: Duplicate entry '127' for key 'PRIMARY'
+INSERT INTO t VALUES (129,60);
+ERROR 23000: Duplicate entry '127' for key 'PRIMARY'
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+1 10
+2 20
+126 30
+127 40
+DROP TABLE t;
+# Inserting a negative value that goes below minimum allowed value for an
+# Auto Increment column (negative minimum)
+CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-127,30);
+INSERT INTO t VALUES (-128,40);
+INSERT INTO t VALUES (-129,50);
+ERROR 23000: Duplicate entry '-128' for key 'PRIMARY'
+INSERT INTO t VALUES (-130,60);
+ERROR 23000: Duplicate entry '-128' for key 'PRIMARY'
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-128 40
+-127 30
+1 10
+2 20
+DROP TABLE t;
+# Updating the partition table with a negative Auto Increment value
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+3 30
+UPDATE t SET c1 = -6 WHERE c1 = 2;
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-6 20
+-1 -10
+1 10
+3 30
+INSERT INTO t(c2) VALUES (40);
+INSERT INTO t(c2) VALUES (50);
+UPDATE t SET c1 = -6 WHERE c1 = 2;
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-6 20
+-1 -10
+1 10
+3 30
+4 40
+5 50
+DROP TABLE t;
+# Updating the partition table with a value that crosses the upper limits
+# on both the positive and the negative side.
+CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='InnoDB' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (126,30);
+INSERT INTO t VALUES (127,40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+1 10
+2 20
+126 30
+127 40
+UPDATE t SET c1 = 130 where c1 = 127;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+1 10
+2 20
+126 30
+127 40
+UPDATE t SET c1 = -140 where c1 = 126;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-128 30
+1 10
+2 20
+127 40
+DROP TABLE t;
+##############################################################################
diff --git a/mysql-test/suite/parts/r/partition_auto_increment_maria.result b/mysql-test/suite/parts/r/partition_auto_increment_maria.result
index 1c1911732ea..419ac10f521 100644
--- a/mysql-test/suite/parts/r/partition_auto_increment_maria.result
+++ b/mysql-test/suite/parts/r/partition_auto_increment_maria.result
@@ -870,3 +870,194 @@ c1
4
5
DROP TABLE t1;
+#############################################################################
+# Bug #45823 - Assertion failure in file row/row0mysql.c line 1386
+# Bug #43988 - AUTO_INCREMENT errors with partitioned InnoDB tables in 5.1.31
+##############################################################################
+# Inserting negative autoincrement values into a partition table (partitions >= 4)
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t(c2) VALUES (40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+3 30
+4 40
+DROP TABLE t;
+# Reading from a partition table (partitions >= 2 ) after inserting a negative
+# value into the auto increment column
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 2;
+INSERT INTO t VALUES (-2,-20);
+INSERT INTO t(c2) VALUES (30);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-2 -20
+1 30
+DROP TABLE t;
+# Inserting negative auto increment value into a partition table (partitions >= 2)
+# auto increment value > 2.
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 2;
+INSERT INTO t VALUES (-4,-20);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t(c2) VALUES (40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-4 -20
+1 30
+2 40
+DROP TABLE t;
+# Inserting -1 into autoincrement column of a partition table (partition >= 4)
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+INSERT INTO t(c2) VALUES (30);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+3 30
+DROP TABLE t;
+# Deleting from an auto increment table after inserting negative values
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t VALUES (-3,-20);
+INSERT INTO t(c2) VALUES (40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-3 -20
+-1 -10
+1 10
+2 20
+3 30
+4 40
+DELETE FROM t WHERE c1 > 1;
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-3 -20
+-1 -10
+1 10
+DROP TABLE t;
+# Inserting a positive value that exceeds maximum allowed value for an
+# Auto Increment column (positive maximum)
+CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (126,30);
+INSERT INTO t VALUES (127,40);
+INSERT INTO t VALUES (128,50);
+ERROR 23000: Duplicate entry '127' for key 'PRIMARY'
+INSERT INTO t VALUES (129,60);
+ERROR 23000: Duplicate entry '127' for key 'PRIMARY'
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+1 10
+2 20
+126 30
+127 40
+DROP TABLE t;
+# Inserting a negative value that goes below minimum allowed value for an
+# Auto Increment column (negative minimum)
+CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-127,30);
+INSERT INTO t VALUES (-128,40);
+INSERT INTO t VALUES (-129,50);
+ERROR 23000: Duplicate entry '-128' for key 'PRIMARY'
+INSERT INTO t VALUES (-130,60);
+ERROR 23000: Duplicate entry '-128' for key 'PRIMARY'
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-128 40
+-127 30
+1 10
+2 20
+DROP TABLE t;
+# Updating the partition table with a negative Auto Increment value
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+3 30
+UPDATE t SET c1 = -6 WHERE c1 = 2;
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-6 20
+-1 -10
+1 10
+3 30
+INSERT INTO t(c2) VALUES (40);
+INSERT INTO t(c2) VALUES (50);
+UPDATE t SET c1 = -6 WHERE c1 = 2;
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-6 20
+-1 -10
+1 10
+3 30
+4 40
+5 50
+DROP TABLE t;
+# Updating the partition table with a value that crosses the upper limits
+# on both the positive and the negative side.
+CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MARIA' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (126,30);
+INSERT INTO t VALUES (127,40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+1 10
+2 20
+126 30
+127 40
+UPDATE t SET c1 = 130 where c1 = 127;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+1 10
+2 20
+126 30
+127 40
+UPDATE t SET c1 = -140 where c1 = 126;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-128 30
+1 10
+2 20
+127 40
+DROP TABLE t;
+##############################################################################
diff --git a/mysql-test/suite/parts/r/partition_auto_increment_memory.result b/mysql-test/suite/parts/r/partition_auto_increment_memory.result
index f4d783825f4..6e3b990dc0f 100644
--- a/mysql-test/suite/parts/r/partition_auto_increment_memory.result
+++ b/mysql-test/suite/parts/r/partition_auto_increment_memory.result
@@ -851,3 +851,194 @@ c1
4
5
DROP TABLE t1;
+#############################################################################
+# Bug #45823 - Assertion failure in file row/row0mysql.c line 1386
+# Bug #43988 - AUTO_INCREMENT errors with partitioned InnoDB tables in 5.1.31
+##############################################################################
+# Inserting negative autoincrement values into a partition table (partitions >= 4)
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t(c2) VALUES (40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+3 30
+4 40
+DROP TABLE t;
+# Reading from a partition table (partitions >= 2 ) after inserting a negative
+# value into the auto increment column
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 2;
+INSERT INTO t VALUES (-2,-20);
+INSERT INTO t(c2) VALUES (30);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-2 -20
+1 30
+DROP TABLE t;
+# Inserting negative auto increment value into a partition table (partitions >= 2)
+# auto increment value > 2.
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 2;
+INSERT INTO t VALUES (-4,-20);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t(c2) VALUES (40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-4 -20
+1 30
+2 40
+DROP TABLE t;
+# Inserting -1 into autoincrement column of a partition table (partition >= 4)
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+INSERT INTO t(c2) VALUES (30);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+3 30
+DROP TABLE t;
+# Deleting from an auto increment table after inserting negative values
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t VALUES (-3,-20);
+INSERT INTO t(c2) VALUES (40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-3 -20
+-1 -10
+1 10
+2 20
+3 30
+4 40
+DELETE FROM t WHERE c1 > 1;
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-3 -20
+-1 -10
+1 10
+DROP TABLE t;
+# Inserting a positive value that exceeds maximum allowed value for an
+# Auto Increment column (positive maximum)
+CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (126,30);
+INSERT INTO t VALUES (127,40);
+INSERT INTO t VALUES (128,50);
+ERROR 23000: Duplicate entry '127' for key 'PRIMARY'
+INSERT INTO t VALUES (129,60);
+ERROR 23000: Duplicate entry '127' for key 'PRIMARY'
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+1 10
+2 20
+126 30
+127 40
+DROP TABLE t;
+# Inserting a negative value that goes below minimum allowed value for an
+# Auto Increment column (negative minimum)
+CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-127,30);
+INSERT INTO t VALUES (-128,40);
+INSERT INTO t VALUES (-129,50);
+ERROR 23000: Duplicate entry '-128' for key 'PRIMARY'
+INSERT INTO t VALUES (-130,60);
+ERROR 23000: Duplicate entry '-128' for key 'PRIMARY'
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-128 40
+-127 30
+1 10
+2 20
+DROP TABLE t;
+# Updating the partition table with a negative Auto Increment value
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+3 30
+UPDATE t SET c1 = -6 WHERE c1 = 2;
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-6 20
+-1 -10
+1 10
+3 30
+INSERT INTO t(c2) VALUES (40);
+INSERT INTO t(c2) VALUES (50);
+UPDATE t SET c1 = -6 WHERE c1 = 2;
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-6 20
+-1 -10
+1 10
+3 30
+4 40
+5 50
+DROP TABLE t;
+# Updating the partition table with a value that crosses the upper limits
+# on both the positive and the negative side.
+CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='Memory' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (126,30);
+INSERT INTO t VALUES (127,40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+1 10
+2 20
+126 30
+127 40
+UPDATE t SET c1 = 130 where c1 = 127;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+1 10
+2 20
+126 30
+127 40
+UPDATE t SET c1 = -140 where c1 = 126;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-128 30
+1 10
+2 20
+127 40
+DROP TABLE t;
+##############################################################################
diff --git a/mysql-test/suite/parts/r/partition_auto_increment_myisam.result b/mysql-test/suite/parts/r/partition_auto_increment_myisam.result
index 6abf08b68a0..047b974f0a3 100644
--- a/mysql-test/suite/parts/r/partition_auto_increment_myisam.result
+++ b/mysql-test/suite/parts/r/partition_auto_increment_myisam.result
@@ -870,3 +870,194 @@ c1
4
5
DROP TABLE t1;
+#############################################################################
+# Bug #45823 - Assertion failure in file row/row0mysql.c line 1386
+# Bug #43988 - AUTO_INCREMENT errors with partitioned InnoDB tables in 5.1.31
+##############################################################################
+# Inserting negative autoincrement values into a partition table (partitions >= 4)
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t(c2) VALUES (40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+3 30
+4 40
+DROP TABLE t;
+# Reading from a partition table (partitions >= 2 ) after inserting a negative
+# value into the auto increment column
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 2;
+INSERT INTO t VALUES (-2,-20);
+INSERT INTO t(c2) VALUES (30);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-2 -20
+1 30
+DROP TABLE t;
+# Inserting negative auto increment value into a partition table (partitions >= 2)
+# auto increment value > 2.
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 2;
+INSERT INTO t VALUES (-4,-20);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t(c2) VALUES (40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-4 -20
+1 30
+2 40
+DROP TABLE t;
+# Inserting -1 into autoincrement column of a partition table (partition >= 4)
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+INSERT INTO t(c2) VALUES (30);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+3 30
+DROP TABLE t;
+# Deleting from an auto increment table after inserting negative values
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t VALUES (-3,-20);
+INSERT INTO t(c2) VALUES (40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-3 -20
+-1 -10
+1 10
+2 20
+3 30
+4 40
+DELETE FROM t WHERE c1 > 1;
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-3 -20
+-1 -10
+1 10
+DROP TABLE t;
+# Inserting a positive value that exceeds maximum allowed value for an
+# Auto Increment column (positive maximum)
+CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (126,30);
+INSERT INTO t VALUES (127,40);
+INSERT INTO t VALUES (128,50);
+ERROR 23000: Duplicate entry '127' for key 'PRIMARY'
+INSERT INTO t VALUES (129,60);
+ERROR 23000: Duplicate entry '127' for key 'PRIMARY'
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+1 10
+2 20
+126 30
+127 40
+DROP TABLE t;
+# Inserting a negative value that goes below minimum allowed value for an
+# Auto Increment column (negative minimum)
+CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-127,30);
+INSERT INTO t VALUES (-128,40);
+INSERT INTO t VALUES (-129,50);
+ERROR 23000: Duplicate entry '-128' for key 'PRIMARY'
+INSERT INTO t VALUES (-130,60);
+ERROR 23000: Duplicate entry '-128' for key 'PRIMARY'
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-128 40
+-127 30
+1 10
+2 20
+DROP TABLE t;
+# Updating the partition table with a negative Auto Increment value
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+3 30
+UPDATE t SET c1 = -6 WHERE c1 = 2;
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-6 20
+-1 -10
+1 10
+3 30
+INSERT INTO t(c2) VALUES (40);
+INSERT INTO t(c2) VALUES (50);
+UPDATE t SET c1 = -6 WHERE c1 = 2;
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-6 20
+-1 -10
+1 10
+3 30
+4 40
+5 50
+DROP TABLE t;
+# Updating the partition table with a value that crosses the upper limits
+# on both the positive and the negative side.
+CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='MyISAM' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (126,30);
+INSERT INTO t VALUES (127,40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+1 10
+2 20
+126 30
+127 40
+UPDATE t SET c1 = 130 where c1 = 127;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+1 10
+2 20
+126 30
+127 40
+UPDATE t SET c1 = -140 where c1 = 126;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-128 30
+1 10
+2 20
+127 40
+DROP TABLE t;
+##############################################################################
diff --git a/mysql-test/suite/parts/r/partition_auto_increment_ndb.result b/mysql-test/suite/parts/r/partition_auto_increment_ndb.result
index 5a1c5b06b36..317669be7ad 100644
--- a/mysql-test/suite/parts/r/partition_auto_increment_ndb.result
+++ b/mysql-test/suite/parts/r/partition_auto_increment_ndb.result
@@ -846,3 +846,194 @@ c1
4
5
DROP TABLE t1;
+#############################################################################
+# Bug #45823 - Assertion failure in file row/row0mysql.c line 1386
+# Bug #43988 - AUTO_INCREMENT errors with partitioned InnoDB tables in 5.1.31
+##############################################################################
+# Inserting negative autoincrement values into a partition table (partitions >= 4)
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t(c2) VALUES (40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+3 30
+4 40
+DROP TABLE t;
+# Reading from a partition table (partitions >= 2 ) after inserting a negative
+# value into the auto increment column
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 2;
+INSERT INTO t VALUES (-2,-20);
+INSERT INTO t(c2) VALUES (30);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-2 -20
+1 30
+DROP TABLE t;
+# Inserting negative auto increment value into a partition table (partitions >= 2)
+# auto increment value > 2.
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 2;
+INSERT INTO t VALUES (-4,-20);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t(c2) VALUES (40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-4 -20
+1 30
+2 40
+DROP TABLE t;
+# Inserting -1 into autoincrement column of a partition table (partition >= 4)
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+INSERT INTO t(c2) VALUES (30);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+3 30
+DROP TABLE t;
+# Deleting from an auto increment table after inserting negative values
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+INSERT INTO t VALUES (-3,-20);
+INSERT INTO t(c2) VALUES (40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-3 -20
+-1 -10
+1 10
+2 20
+3 30
+4 40
+DELETE FROM t WHERE c1 > 1;
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-3 -20
+-1 -10
+1 10
+DROP TABLE t;
+# Inserting a positive value that exceeds maximum allowed value for an
+# Auto Increment column (positive maximum)
+CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (126,30);
+INSERT INTO t VALUES (127,40);
+INSERT INTO t VALUES (128,50);
+ERROR 23000: Duplicate entry '127' for key 'PRIMARY'
+INSERT INTO t VALUES (129,60);
+ERROR 23000: Duplicate entry '127' for key 'PRIMARY'
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+1 10
+2 20
+126 30
+127 40
+DROP TABLE t;
+# Inserting a negative value that goes below minimum allowed value for an
+# Auto Increment column (negative minimum)
+CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-127,30);
+INSERT INTO t VALUES (-128,40);
+INSERT INTO t VALUES (-129,50);
+ERROR 23000: Duplicate entry '-128' for key 'PRIMARY'
+INSERT INTO t VALUES (-130,60);
+ERROR 23000: Duplicate entry '-128' for key 'PRIMARY'
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-128 40
+-127 30
+1 10
+2 20
+DROP TABLE t;
+# Updating the partition table with a negative Auto Increment value
+CREATE TABLE t (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (-1,-10);
+INSERT INTO t(c2) VALUES (30);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-1 -10
+1 10
+2 20
+3 30
+UPDATE t SET c1 = -6 WHERE c1 = 2;
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-6 20
+-1 -10
+1 10
+3 30
+INSERT INTO t(c2) VALUES (40);
+INSERT INTO t(c2) VALUES (50);
+UPDATE t SET c1 = -6 WHERE c1 = 2;
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-6 20
+-1 -10
+1 10
+3 30
+4 40
+5 50
+DROP TABLE t;
+# Updating the partition table with a value that crosses the upper limits
+# on both the positive and the negative side.
+CREATE TABLE t (c1 TINYINT NOT NULL AUTO_INCREMENT, PRIMARY KEY(c1),
+c2 INT) ENGINE='NDB' PARTITION BY HASH(c1) PARTITIONS 4;
+INSERT INTO t(c2) VALUES (10);
+INSERT INTO t(c2) VALUES (20);
+INSERT INTO t VALUES (126,30);
+INSERT INTO t VALUES (127,40);
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+1 10
+2 20
+126 30
+127 40
+UPDATE t SET c1 = 130 where c1 = 127;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+1 10
+2 20
+126 30
+127 40
+UPDATE t SET c1 = -140 where c1 = 126;
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+SELECT * FROM t ORDER BY c1 ASC;
+c1 c2
+-128 30
+1 10
+2 20
+127 40
+DROP TABLE t;
+##############################################################################
diff --git a/mysql-test/suite/parts/r/partition_recover_myisam.result b/mysql-test/suite/parts/r/partition_recover_myisam.result
index df737ec2853..49775ee498e 100644
--- a/mysql-test/suite/parts/r/partition_recover_myisam.result
+++ b/mysql-test/suite/parts/r/partition_recover_myisam.result
@@ -1,3 +1,5 @@
+call mtr.add_suppression("./test/t1_will_crash");
+call mtr.add_suppression("Got an error from unknown thread, ha_myisam.cc");
CREATE TABLE t1_will_crash (a INT, KEY (a)) ENGINE=MyISAM;
INSERT INTO t1_will_crash VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11);
FLUSH TABLES;
diff --git a/mysql-test/suite/parts/t/partition_auto_increment_archive.test b/mysql-test/suite/parts/t/partition_auto_increment_archive.test
index fb09557204f..e99a0b23b36 100644
--- a/mysql-test/suite/parts/t/partition_auto_increment_archive.test
+++ b/mysql-test/suite/parts/t/partition_auto_increment_archive.test
@@ -30,6 +30,9 @@ let $skip_delete= 1;
let $skip_truncate= 1;
let $skip_update= 1;
let $only_ai_pk= 1;
+# Bug#45823 Assertion failure in file row/row0mysql.c line 1386
+# Archive does not handle negative autoincrement values correctly
+let $skip_negative_auto_inc= 1;
##### Storage engine to be tested
let $engine= 'Archive';
diff --git a/mysql-test/suite/parts/t/partition_auto_increment_blackhole.test b/mysql-test/suite/parts/t/partition_auto_increment_blackhole.test
index 64cd96c6173..f92dc33f263 100644
--- a/mysql-test/suite/parts/t/partition_auto_increment_blackhole.test
+++ b/mysql-test/suite/parts/t/partition_auto_increment_blackhole.test
@@ -25,6 +25,9 @@
#------------------------------------------------------------------------------#
# Engine specific settings and requirements
--source include/have_blackhole.inc
+# Bug#45823 Assertion failure in file row/row0mysql.c line 1386
+# Blackhole does not handle negative autoincrement values correctly
+let $skip_negative_auto_inc= 1;
##### Storage engine to be tested
let $engine= 'Blackhole';
diff --git a/mysql-test/suite/parts/t/partition_recover_myisam.test b/mysql-test/suite/parts/t/partition_recover_myisam.test
index dbab4e8f1a2..fe8a51b17cc 100644
--- a/mysql-test/suite/parts/t/partition_recover_myisam.test
+++ b/mysql-test/suite/parts/t/partition_recover_myisam.test
@@ -1,4 +1,8 @@
# test the auto-recover (--myisam-recover) of partitioned myisam tables
+
+call mtr.add_suppression("./test/t1_will_crash");
+call mtr.add_suppression("Got an error from unknown thread, ha_myisam.cc");
+
--source include/have_partition.inc
--disable_warnings
--disable_query_log
diff --git a/mysql-test/suite/pbxt/r/func_group.result b/mysql-test/suite/pbxt/r/func_group.result
index d1a0d09ad09..5da10aa243a 100644
--- a/mysql-test/suite/pbxt/r/func_group.result
+++ b/mysql-test/suite/pbxt/r/func_group.result
@@ -601,7 +601,7 @@ AME AME
explain
select min(a1) from t1 where a1 > 'KKK' or a1 < 'XXX';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 0 NULL 1 Using where; Using index
+1 SIMPLE t1 index PRIMARY PRIMARY 3 NULL 15 Using where; Using index
explain
select min(a1) from t1 where a1 != 'KKK';
id select_type table type possible_keys key key_len ref rows Extra
diff --git a/mysql-test/suite/pbxt/r/grant.result b/mysql-test/suite/pbxt/r/grant.result
index 94f89f2fd87..74cac3ea4f0 100644
--- a/mysql-test/suite/pbxt/r/grant.result
+++ b/mysql-test/suite/pbxt/r/grant.result
@@ -993,9 +993,9 @@ GRANT INSERT, SELECT, CREATE, ALTER, DROP ON mysqltest1.t2 TO mysqltest_1@localh
DROP TABLE mysqltest1.t2;
SHOW GRANTS;
Grants for mysqltest_1@localhost
-GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
-GRANT SELECT, INSERT, CREATE, DROP, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost'
GRANT SELECT, INSERT, CREATE, DROP, ALTER ON `mysqltest1`.`t1` TO 'mysqltest_1'@'localhost'
+GRANT SELECT, INSERT, CREATE, DROP, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost'
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
RENAME TABLE t1 TO t2;
RENAME TABLE t2 TO t1;
ALTER TABLE t1 RENAME TO t2;
@@ -1004,9 +1004,9 @@ REVOKE DROP, INSERT ON mysqltest1.t1 FROM mysqltest_1@localhost;
REVOKE DROP, INSERT ON mysqltest1.t2 FROM mysqltest_1@localhost;
SHOW GRANTS;
Grants for mysqltest_1@localhost
-GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
-GRANT SELECT, CREATE, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost'
GRANT SELECT, CREATE, ALTER ON `mysqltest1`.`t1` TO 'mysqltest_1'@'localhost'
+GRANT SELECT, CREATE, ALTER ON `mysqltest1`.`t2` TO 'mysqltest_1'@'localhost'
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
RENAME TABLE t1 TO t2;
ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 't1'
ALTER TABLE t1 RENAME TO t2;
diff --git a/mysql-test/suite/pbxt/r/group_min_max.result b/mysql-test/suite/pbxt/r/group_min_max.result
index a1e2ce15743..debf70e9b41 100644
--- a/mysql-test/suite/pbxt/r/group_min_max.result
+++ b/mysql-test/suite/pbxt/r/group_min_max.result
@@ -876,10 +876,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 129 Using where; Using index for group-by
explain select a1,a2,b, max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range NULL idx_t1_1 147 NULL 129 Using where; Using index for group-by
+1 SIMPLE t1 range NULL idx_t1_1 163 NULL 129 Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range NULL idx_t1_1 147 NULL 129 Using where; Using index for group-by
+1 SIMPLE t1 range NULL idx_t1_1 163 NULL 129 Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b111') and (c <= 'g112') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 129 Using where; Using index for group-by
@@ -924,7 +924,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
explain select a1,a2,b, max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range NULL idx_t2_1 146 NULL # Using where; Using index for group-by
+1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
diff --git a/mysql-test/suite/pbxt/r/join_nested.result b/mysql-test/suite/pbxt/r/join_nested.result
index 92dc4f8acf2..0e4c3e74414 100644
--- a/mysql-test/suite/pbxt/r/join_nested.result
+++ b/mysql-test/suite/pbxt/r/join_nested.result
@@ -958,15 +958,15 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
-1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00 Using where
1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
CREATE INDEX idx_b ON t8(b);
EXPLAIN EXTENDED
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
@@ -1008,13 +1008,13 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
-1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00
+1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00 Using where
1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 1 100.00 Using where
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
Warnings:
CREATE INDEX idx_b ON t1(b);
CREATE INDEX idx_a ON t0(a);
@@ -1058,13 +1058,13 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ref idx_b idx_b 5 test.t0.b 1 100.00 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
-1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00
+1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00 Using where
1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 1 100.00 Using where
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
Warnings:
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b
diff --git a/mysql-test/suite/pbxt/r/negation_elimination.result b/mysql-test/suite/pbxt/r/negation_elimination.result
index f8a6b0f764d..f3edfccf67e 100644
--- a/mysql-test/suite/pbxt/r/negation_elimination.result
+++ b/mysql-test/suite/pbxt/r/negation_elimination.result
@@ -327,7 +327,7 @@ a
0
explain select * from t1 where not((a < 5 or a < 10) and (not(a > 16) or a > 17));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index
+1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
select * from t1 where not((a < 5 or a < 10) and (not(a > 16) or a > 17));
a
10
@@ -342,7 +342,7 @@ a
19
explain select * from t1 where not((a < 5 and a < 10) and (not(a > 16) or a > 17));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index
+1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index
select * from t1 where not((a < 5 and a < 10) and (not(a > 16) or a > 17));
a
5
diff --git a/mysql-test/suite/pbxt/r/ps_grant.result b/mysql-test/suite/pbxt/r/ps_grant.result
index 8b16123ccea..18e281703ef 100644
--- a/mysql-test/suite/pbxt/r/ps_grant.result
+++ b/mysql-test/suite/pbxt/r/ps_grant.result
@@ -31,20 +31,20 @@ grant select on mysqltest.t1 to second_user@localhost
identified by 'looser' ;
show grants for second_user@localhost ;
Grants for second_user@localhost
-GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3'
GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost'
GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost'
+GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3'
drop table mysqltest.t9 ;
show grants for second_user@localhost ;
Grants for second_user@localhost
-GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3'
GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost'
GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost'
+GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3'
show grants for second_user@localhost ;
Grants for second_user@localhost
-GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3'
GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost'
GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost'
+GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3'
prepare s_t1 from 'select a as my_col from t1' ;
execute s_t1 ;
my_col
diff --git a/mysql-test/suite/pbxt/r/skip_grants.result b/mysql-test/suite/pbxt/r/skip_grants.result
index 15c5b38f00f..ac4069c47d7 100644
--- a/mysql-test/suite/pbxt/r/skip_grants.result
+++ b/mysql-test/suite/pbxt/r/skip_grants.result
@@ -54,7 +54,7 @@ SHOW CREATE VIEW v3;
View Create View character_set_client collation_connection
v3 CREATE ALGORITHM=UNDEFINED DEFINER=`a`@`` SQL SECURITY DEFINER VIEW `v3` AS select `test`.`t1`.`c` AS `c` from `t1` latin1 latin1_swedish_ci
Warnings:
-Warning 1356 View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note 1449 The user specified as a definer ('a'@'') does not exist
SHOW CREATE PROCEDURE p3;
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
p3 CREATE DEFINER=`a`@`` PROCEDURE `p3`()
diff --git a/mysql-test/suite/pbxt/r/subselect.result b/mysql-test/suite/pbxt/r/subselect.result
index bb2073030e3..bae93f76b2c 100644
--- a/mysql-test/suite/pbxt/r/subselect.result
+++ b/mysql-test/suite/pbxt/r/subselect.result
@@ -75,7 +75,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
ERROR HY000: Incorrect usage of PROCEDURE and subquery
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
-ERROR HY000: Incorrect usage of PROCEDURE and subquery
+ERROR HY000: Incorrect parameters to procedure 'ANALYSE'
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
ERROR 42S22: Unknown column 'a' in 'field list'
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL;
diff --git a/mysql-test/suite/pbxt/r/view_grant.result b/mysql-test/suite/pbxt/r/view_grant.result
index 5e2744c2933..f66ff458761 100644
--- a/mysql-test/suite/pbxt/r/view_grant.result
+++ b/mysql-test/suite/pbxt/r/view_grant.result
@@ -605,7 +605,7 @@ SHOW CREATE VIEW v;
View Create View character_set_client collation_connection
v CREATE ALGORITHM=UNDEFINED DEFINER=`no-such-user`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `test`.`t1`.`a` AS `a` from `t1` latin1 latin1_swedish_ci
Warnings:
-Warning 1356 View 'test.v' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note 1449 The user specified as a definer ('no-such-user'@'localhost') does not exist
SELECT * FROM v;
ERROR HY000: The user specified as a definer ('no-such-user'@'localhost') does not exist
DROP VIEW v;
@@ -936,7 +936,7 @@ SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`no_such`@`user_1` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
Warnings:
-Warning 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note 1449 The user specified as a definer ('no_such'@'user_1') does not exist
ALTER ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
Warnings:
Note 1449 The user specified as a definer ('no_such'@'user_1') does not exist
@@ -944,7 +944,7 @@ SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=MERGE DEFINER=`no_such`@`user_1` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
Warnings:
-Warning 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note 1449 The user specified as a definer ('no_such'@'user_1') does not exist
ALTER ALGORITHM=TEMPTABLE DEFINER=no_such@user_2 VIEW v1 AS SELECT * FROM t1;
Warnings:
Note 1449 The user specified as a definer ('no_such'@'user_2') does not exist
@@ -952,7 +952,7 @@ SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=TEMPTABLE DEFINER=`no_such`@`user_2` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`i` AS `i` from `t1` latin1 latin1_swedish_ci
Warnings:
-Warning 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note 1449 The user specified as a definer ('no_such'@'user_2') does not exist
DROP VIEW v1;
DROP TABLE t1;
End of 5.1 tests.
diff --git a/mysql-test/suite/pbxt/t/grant.test b/mysql-test/suite/pbxt/t/grant.test
index 24b4eb926ce..35b2c1c0bae 100644
--- a/mysql-test/suite/pbxt/t/grant.test
+++ b/mysql-test/suite/pbxt/t/grant.test
@@ -876,6 +876,7 @@ GRANT INSERT, SELECT, CREATE, ALTER, DROP ON mysqltest1.t2 TO mysqltest_1@localh
DROP TABLE mysqltest1.t2;
connect (conn42,localhost,mysqltest_1,,mysqltest1);
+--sorted_result
SHOW GRANTS;
RENAME TABLE t1 TO t2;
RENAME TABLE t2 TO t1;
@@ -887,6 +888,7 @@ REVOKE DROP, INSERT ON mysqltest1.t1 FROM mysqltest_1@localhost;
REVOKE DROP, INSERT ON mysqltest1.t2 FROM mysqltest_1@localhost;
connect (conn42,localhost,mysqltest_1,,mysqltest1);
+--sorted_result
SHOW GRANTS;
--error ER_TABLEACCESS_DENIED_ERROR
RENAME TABLE t1 TO t2;
diff --git a/mysql-test/suite/pbxt/t/ps_grant.test b/mysql-test/suite/pbxt/t/ps_grant.test
index b25facdb418..90ee088e2e7 100644
--- a/mysql-test/suite/pbxt/t/ps_grant.test
+++ b/mysql-test/suite/pbxt/t/ps_grant.test
@@ -64,8 +64,10 @@ select a as my_col from t1;
connection default;
grant select on mysqltest.t1 to second_user@localhost
identified by 'looser' ;
+--sorted_result
show grants for second_user@localhost ;
drop table mysqltest.t9 ;
+--sorted_result
show grants for second_user@localhost ;
@@ -73,6 +75,7 @@ show grants for second_user@localhost ;
## switch to the second session
connection con3;
######## Question 1: The table t1 should be now accessible. ########
+--sorted_result
show grants for second_user@localhost ;
prepare s_t1 from 'select a as my_col from t1' ;
execute s_t1 ;
diff --git a/mysql-test/suite/pbxt/t/subselect.test b/mysql-test/suite/pbxt/t/subselect.test
index 0d7b1252404..15ccef0e025 100644
--- a/mysql-test/suite/pbxt/t/subselect.test
+++ b/mysql-test/suite/pbxt/t/subselect.test
@@ -28,9 +28,9 @@ SELECT * FROM (SELECT 1 as id) b WHERE id IN (SELECT * FROM (SELECT 1 as id) c O
SELECT * FROM (SELECT 1) a WHERE 1 IN (SELECT 1,1);
SELECT 1 IN (SELECT 1);
SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
--- error 1221
-select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
-- error ER_WRONG_USAGE
+select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
+-- error ER_WRONG_PARAMETERS_TO_PROCEDURE
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
-- error ER_BAD_FIELD_ERROR
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
diff --git a/mysql-test/suite/rpl/r/rpl_auto_increment.result b/mysql-test/suite/rpl/r/rpl_auto_increment.result
index 17aa592654f..831e9b5c8b5 100644
--- a/mysql-test/suite/rpl/r/rpl_auto_increment.result
+++ b/mysql-test/suite/rpl/r/rpl_auto_increment.result
@@ -244,3 +244,71 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
drop table t1;
+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 t1;
+DROP TABLE IF EXISTS t2;
+CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=myisam;
+SET SQL_MODE='';
+INSERT INTO t1 VALUES(NULL);
+INSERT INTO t2 VALUES(NULL);
+SELECT * FROM t1;
+id
+1
+SELECT * FROM t2;
+id
+1
+INSERT INTO t1 VALUES();
+INSERT INTO t2 VALUES();
+SELECT * FROM t1;
+id
+1
+2
+SELECT * FROM t2;
+id
+1
+2
+INSERT INTO t1 VALUES(0);
+INSERT INTO t2 VALUES(0);
+SELECT * FROM t1;
+id
+1
+2
+3
+SELECT * FROM t2;
+id
+1
+2
+3
+SET SQL_MODE=NO_AUTO_VALUE_ON_ZERO;
+INSERT INTO t1 VALUES(0);
+INSERT INTO t2 VALUES(0);
+SELECT * FROM t1;
+id
+0
+1
+2
+3
+SELECT * FROM t2;
+id
+0
+1
+2
+3
+INSERT INTO t1 VALUES(4);
+INSERT INTO t2 VALUES(4);
+FLUSH LOGS;
+Comparing tables master:test.t1 and slave:test.t1
+Comparing tables master:test.t2 and slave:test.t2
+DROP TABLE t1;
+DROP TABLE t2;
+Comparing tables master:test.t1 and slave:test.t1
+Comparing tables master:test.t2 and slave:test.t2
+DROP TABLE t1;
+DROP TABLE t2;
+SET SQL_MODE='';
diff --git a/mysql-test/suite/rpl/r/rpl_auto_increment_update_failure.result b/mysql-test/suite/rpl/r/rpl_auto_increment_update_failure.result
new file mode 100644
index 00000000000..b2cc92491c3
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_auto_increment_update_failure.result
@@ -0,0 +1,1041 @@
+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;
+# Test case1: INVOKES A TRIGGER with after insert action
+create table t1(a int, b int) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create trigger tr1 after insert on t1 for each row insert into t2(a) values(6);
+create table t3(a int, b int) engine=innodb;
+create table t4(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create table t5(a int) engine=innodb;
+create trigger tr2 after insert on t3 for each row begin
+insert into t4(a) values(f1_insert_triggered());
+insert into t4(a) values(f1_insert_triggered());
+insert into t5(a) values(8);
+end |
+create table t6(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+CREATE FUNCTION f1_insert_triggered() RETURNS INTEGER
+BEGIN
+INSERT INTO t6(a) values(2),(3);
+RETURN 1;
+END//
+begin;
+insert into t1(a,b) values(1,1),(2,1);
+insert into t3(a,b) values(1,1),(2,1);
+update t1 set a = a + 5 where b = 1;
+update t3 set a = a + 5 where b = 1;
+delete from t1 where b = 1;
+delete from t3 where b = 1;
+insert into t2(a) values(3);
+insert into t4(a) values(3);
+commit;
+insert into t1(a,b) values(4,2);
+insert into t3(a,b) values(4,2);
+update t1 set a = a + 5 where b = 2;
+update t3 set a = a + 5 where b = 2;
+delete from t1 where b = 2;
+delete from t3 where b = 2;
+# To verify if insert/update in an autoinc column causes statement to be logged in row format
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=3
+master-bin.000001 # Query # # use `test`; insert into t2(a) values(3)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=5
+master-bin.000001 # Query # # use `test`; insert into t4(a) values(3)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t5)
+master-bin.000001 # Table_map # # table_id: # (test.t4)
+master-bin.000001 # Table_map # # table_id: # (test.t6)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # use `test`; update t1 set a = a + 5 where b = 1
+master-bin.000001 # Query # # use `test`; update t3 set a = a + 5 where b = 1
+master-bin.000001 # Query # # use `test`; delete from t1 where b = 1
+master-bin.000001 # Query # # use `test`; delete from t3 where b = 1
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t5)
+master-bin.000001 # Table_map # # table_id: # (test.t4)
+master-bin.000001 # Table_map # # table_id: # (test.t6)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; update t1 set a = a + 5 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; update t3 set a = a + 5 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; delete from t1 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; delete from t3 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+commit;
+#Test if the results are consistent on master and slave
+#for 'INVOKES A TRIGGER with after insert action'
+Comparing tables master:test.t2 and slave:test.t2
+Comparing tables master:test.t4 and slave:test.t4
+Comparing tables master:test.t6 and slave:test.t6
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+DROP TABLE t5;
+DROP TABLE t6;
+DROP FUNCTION f1_insert_triggered;
+# Test case2: INVOKES A TRIGGER with before insert action
+create table t1(a int, b int) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create trigger tr1 before insert on t1 for each row insert into t2(a) values(6);
+create table t3(a int, b int) engine=innodb;
+create table t4(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create table t5(a int) engine=innodb;
+create trigger tr2 before insert on t3 for each row begin
+insert into t4(a) values(f1_insert_triggered());
+insert into t4(a) values(f1_insert_triggered());
+insert into t5(a) values(8);
+end |
+create table t6(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+CREATE FUNCTION f1_insert_triggered() RETURNS INTEGER
+BEGIN
+INSERT INTO t6(a) values(2),(3);
+RETURN 1;
+END//
+begin;
+insert into t1(a,b) values(1,1),(2,1);
+insert into t3(a,b) values(1,1),(2,1);
+update t1 set a = a + 5 where b = 1;
+update t3 set a = a + 5 where b = 1;
+delete from t1 where b = 1;
+delete from t3 where b = 1;
+insert into t2(a) values(3);
+insert into t4(a) values(3);
+commit;
+insert into t1(a,b) values(4,2);
+insert into t3(a,b) values(4,2);
+update t1 set a = a + 5 where b = 2;
+update t3 set a = a + 5 where b = 2;
+delete from t1 where b = 2;
+delete from t3 where b = 2;
+# To verify if insert/update in an autoinc column causes statement to be logged in row format
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=3
+master-bin.000001 # Query # # use `test`; insert into t2(a) values(3)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=5
+master-bin.000001 # Query # # use `test`; insert into t4(a) values(3)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t5)
+master-bin.000001 # Table_map # # table_id: # (test.t4)
+master-bin.000001 # Table_map # # table_id: # (test.t6)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # use `test`; update t1 set a = a + 5 where b = 1
+master-bin.000001 # Query # # use `test`; update t3 set a = a + 5 where b = 1
+master-bin.000001 # Query # # use `test`; delete from t1 where b = 1
+master-bin.000001 # Query # # use `test`; delete from t3 where b = 1
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t5)
+master-bin.000001 # Table_map # # table_id: # (test.t4)
+master-bin.000001 # Table_map # # table_id: # (test.t6)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; update t1 set a = a + 5 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; update t3 set a = a + 5 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; delete from t1 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; delete from t3 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+commit;
+#Test if the results are consistent on master and slave
+#for 'INVOKES A TRIGGER with before insert action'
+Comparing tables master:test.t2 and slave:test.t2
+Comparing tables master:test.t4 and slave:test.t4
+Comparing tables master:test.t6 and slave:test.t6
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+DROP TABLE t5;
+DROP TABLE t6;
+DROP FUNCTION f1_insert_triggered;
+# Test case3: INVOKES A TRIGGER with after update action
+create table t1(a int, b int) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create trigger tr1 after update on t1 for each row insert into t2(a) values(6);
+create table t3(a int, b int) engine=innodb;
+create table t4(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create table t5(a int) engine=innodb;
+create trigger tr2 after update on t3 for each row begin
+insert into t4(a) values(f1_insert_triggered());
+insert into t4(a) values(f1_insert_triggered());
+insert into t5(a) values(8);
+end |
+create table t6(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+CREATE FUNCTION f1_insert_triggered() RETURNS INTEGER
+BEGIN
+INSERT INTO t6(a) values(2),(3);
+RETURN 1;
+END//
+begin;
+insert into t1(a,b) values(1,1),(2,1);
+insert into t3(a,b) values(1,1),(2,1);
+update t1 set a = a + 5 where b = 1;
+update t3 set a = a + 5 where b = 1;
+delete from t1 where b = 1;
+delete from t3 where b = 1;
+insert into t2(a) values(3);
+insert into t4(a) values(3);
+commit;
+insert into t1(a,b) values(4,2);
+insert into t3(a,b) values(4,2);
+update t1 set a = a + 5 where b = 2;
+update t3 set a = a + 5 where b = 2;
+delete from t1 where b = 2;
+delete from t3 where b = 2;
+# To verify if insert/update in an autoinc column causes statement to be logged in row format
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=3
+master-bin.000001 # Query # # use `test`; insert into t2(a) values(3)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=5
+master-bin.000001 # Query # # use `test`; insert into t4(a) values(3)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; insert into t1(a,b) values(1,1),(2,1)
+master-bin.000001 # Query # # use `test`; insert into t3(a,b) values(1,1),(2,1)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Update_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Update_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t5)
+master-bin.000001 # Table_map # # table_id: # (test.t4)
+master-bin.000001 # Table_map # # table_id: # (test.t6)
+master-bin.000001 # Update_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Update_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # use `test`; delete from t1 where b = 1
+master-bin.000001 # Query # # use `test`; delete from t3 where b = 1
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; insert into t1(a,b) values(4,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; insert into t3(a,b) values(4,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Update_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t5)
+master-bin.000001 # Table_map # # table_id: # (test.t4)
+master-bin.000001 # Table_map # # table_id: # (test.t6)
+master-bin.000001 # Update_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; delete from t1 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; delete from t3 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+commit;
+#Test if the results are consistent on master and slave
+#for 'INVOKES A TRIGGER with after update action'
+Comparing tables master:test.t2 and slave:test.t2
+Comparing tables master:test.t4 and slave:test.t4
+Comparing tables master:test.t6 and slave:test.t6
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+DROP TABLE t5;
+DROP TABLE t6;
+DROP FUNCTION f1_insert_triggered;
+# Test case4: INVOKES A TRIGGER with before update action
+create table t1(a int, b int) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create trigger tr1 before update on t1 for each row insert into t2(a) values(6);
+create table t3(a int, b int) engine=innodb;
+create table t4(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create table t5(a int) engine=innodb;
+create trigger tr2 before update on t3 for each row begin
+insert into t4(a) values(f1_insert_triggered());
+insert into t4(a) values(f1_insert_triggered());
+insert into t5(a) values(8);
+end |
+create table t6(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+CREATE FUNCTION f1_insert_triggered() RETURNS INTEGER
+BEGIN
+INSERT INTO t6(a) values(2),(3);
+RETURN 1;
+END//
+begin;
+insert into t1(a,b) values(1,1),(2,1);
+insert into t3(a,b) values(1,1),(2,1);
+update t1 set a = a + 5 where b = 1;
+update t3 set a = a + 5 where b = 1;
+delete from t1 where b = 1;
+delete from t3 where b = 1;
+insert into t2(a) values(3);
+insert into t4(a) values(3);
+commit;
+insert into t1(a,b) values(4,2);
+insert into t3(a,b) values(4,2);
+update t1 set a = a + 5 where b = 2;
+update t3 set a = a + 5 where b = 2;
+delete from t1 where b = 2;
+delete from t3 where b = 2;
+# To verify if insert/update in an autoinc column causes statement to be logged in row format
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=3
+master-bin.000001 # Query # # use `test`; insert into t2(a) values(3)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=5
+master-bin.000001 # Query # # use `test`; insert into t4(a) values(3)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; insert into t1(a,b) values(1,1),(2,1)
+master-bin.000001 # Query # # use `test`; insert into t3(a,b) values(1,1),(2,1)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Update_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t5)
+master-bin.000001 # Table_map # # table_id: # (test.t4)
+master-bin.000001 # Table_map # # table_id: # (test.t6)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Update_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # use `test`; delete from t1 where b = 1
+master-bin.000001 # Query # # use `test`; delete from t3 where b = 1
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; insert into t1(a,b) values(4,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; insert into t3(a,b) values(4,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t5)
+master-bin.000001 # Table_map # # table_id: # (test.t4)
+master-bin.000001 # Table_map # # table_id: # (test.t6)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; delete from t1 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; delete from t3 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+commit;
+#Test if the results are consistent on master and slave
+#for 'INVOKES A TRIGGER with before update action'
+Comparing tables master:test.t2 and slave:test.t2
+Comparing tables master:test.t4 and slave:test.t4
+Comparing tables master:test.t6 and slave:test.t6
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+DROP TABLE t5;
+DROP TABLE t6;
+DROP FUNCTION f1_insert_triggered;
+# Test case5: INVOKES A TRIGGER with after delete action
+create table t1(a int, b int) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create trigger tr1 after delete on t1 for each row insert into t2(a) values(6);
+create table t3(a int, b int) engine=innodb;
+create table t4(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create table t5(a int) engine=innodb;
+create trigger tr2 after delete on t3 for each row begin
+insert into t4(a) values(f1_insert_triggered());
+insert into t4(a) values(f1_insert_triggered());
+insert into t5(a) values(8);
+end |
+create table t6(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+CREATE FUNCTION f1_insert_triggered() RETURNS INTEGER
+BEGIN
+INSERT INTO t6(a) values(2),(3);
+RETURN 1;
+END//
+begin;
+insert into t1(a,b) values(1,1),(2,1);
+insert into t3(a,b) values(1,1),(2,1);
+update t1 set a = a + 5 where b = 1;
+update t3 set a = a + 5 where b = 1;
+delete from t1 where b = 1;
+delete from t3 where b = 1;
+insert into t2(a) values(3);
+insert into t4(a) values(3);
+commit;
+insert into t1(a,b) values(4,2);
+insert into t3(a,b) values(4,2);
+update t1 set a = a + 5 where b = 2;
+update t3 set a = a + 5 where b = 2;
+delete from t1 where b = 2;
+delete from t3 where b = 2;
+# To verify if insert/update in an autoinc column causes statement to be logged in row format
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=3
+master-bin.000001 # Query # # use `test`; insert into t2(a) values(3)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=5
+master-bin.000001 # Query # # use `test`; insert into t4(a) values(3)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; insert into t1(a,b) values(1,1),(2,1)
+master-bin.000001 # Query # # use `test`; insert into t3(a,b) values(1,1),(2,1)
+master-bin.000001 # Query # # use `test`; update t1 set a = a + 5 where b = 1
+master-bin.000001 # Query # # use `test`; update t3 set a = a + 5 where b = 1
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Delete_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Delete_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t5)
+master-bin.000001 # Table_map # # table_id: # (test.t4)
+master-bin.000001 # Table_map # # table_id: # (test.t6)
+master-bin.000001 # Delete_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Delete_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; insert into t1(a,b) values(4,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; insert into t3(a,b) values(4,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; update t1 set a = a + 5 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; update t3 set a = a + 5 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Delete_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t5)
+master-bin.000001 # Table_map # # table_id: # (test.t4)
+master-bin.000001 # Table_map # # table_id: # (test.t6)
+master-bin.000001 # Delete_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+commit;
+#Test if the results are consistent on master and slave
+#for 'INVOKES A TRIGGER with after delete action'
+Comparing tables master:test.t2 and slave:test.t2
+Comparing tables master:test.t4 and slave:test.t4
+Comparing tables master:test.t6 and slave:test.t6
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+DROP TABLE t5;
+DROP TABLE t6;
+DROP FUNCTION f1_insert_triggered;
+# Test case6: INVOKES A TRIGGER with before delete action
+create table t1(a int, b int) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create trigger tr1 before delete on t1 for each row insert into t2(a) values(6);
+create table t3(a int, b int) engine=innodb;
+create table t4(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create table t5(a int) engine=innodb;
+create trigger tr2 before delete on t3 for each row begin
+insert into t4(a) values(f1_insert_triggered());
+insert into t4(a) values(f1_insert_triggered());
+insert into t5(a) values(8);
+end |
+create table t6(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+CREATE FUNCTION f1_insert_triggered() RETURNS INTEGER
+BEGIN
+INSERT INTO t6(a) values(2),(3);
+RETURN 1;
+END//
+begin;
+insert into t1(a,b) values(1,1),(2,1);
+insert into t3(a,b) values(1,1),(2,1);
+update t1 set a = a + 5 where b = 1;
+update t3 set a = a + 5 where b = 1;
+delete from t1 where b = 1;
+delete from t3 where b = 1;
+insert into t2(a) values(3);
+insert into t4(a) values(3);
+commit;
+insert into t1(a,b) values(4,2);
+insert into t3(a,b) values(4,2);
+update t1 set a = a + 5 where b = 2;
+update t3 set a = a + 5 where b = 2;
+delete from t1 where b = 2;
+delete from t3 where b = 2;
+# To verify if insert/update in an autoinc column causes statement to be logged in row format
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=3
+master-bin.000001 # Query # # use `test`; insert into t2(a) values(3)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=5
+master-bin.000001 # Query # # use `test`; insert into t4(a) values(3)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; insert into t1(a,b) values(1,1),(2,1)
+master-bin.000001 # Query # # use `test`; insert into t3(a,b) values(1,1),(2,1)
+master-bin.000001 # Query # # use `test`; update t1 set a = a + 5 where b = 1
+master-bin.000001 # Query # # use `test`; update t3 set a = a + 5 where b = 1
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Delete_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t5)
+master-bin.000001 # Table_map # # table_id: # (test.t4)
+master-bin.000001 # Table_map # # table_id: # (test.t6)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Delete_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; insert into t1(a,b) values(4,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; insert into t3(a,b) values(4,2)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; update t1 set a = a + 5 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; update t3 set a = a + 5 where b = 2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t5)
+master-bin.000001 # Table_map # # table_id: # (test.t4)
+master-bin.000001 # Table_map # # table_id: # (test.t6)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+commit;
+#Test if the results are consistent on master and slave
+#for 'INVOKES A TRIGGER with before delete action'
+Comparing tables master:test.t2 and slave:test.t2
+Comparing tables master:test.t4 and slave:test.t4
+Comparing tables master:test.t6 and slave:test.t6
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+DROP TABLE t5;
+DROP TABLE t6;
+DROP FUNCTION f1_insert_triggered;
+# Test case7: CALLS A FUNCTION which INVOKES A TRIGGER with after insert action
+create table t1(a int) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create table t3(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+CREATE FUNCTION f1_two_inserts_trigger() RETURNS INTEGER
+BEGIN
+INSERT INTO t2(a) values(2),(3);
+INSERT INTO t2(a) values(2),(3);
+RETURN 1;
+END |
+create trigger tr11 after insert on t2 for each row begin
+insert into t3(a) values(new.a);
+insert into t3(a) values(new.a);
+end |
+begin;
+insert into t1(a) values(f1_two_inserts_trigger());
+insert into t2(a) values(4),(5);
+commit;
+insert into t1(a) values(f1_two_inserts_trigger());
+# To verify if insert/update in an autoinc column causes statement to be logged in row format
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+commit;
+#Test if the results are consistent on master and slave
+#for 'CALLS A FUNCTION which INVOKES A TRIGGER with after insert action'
+Comparing tables master:test.t2 and slave:test.t2
+Comparing tables master:test.t3 and slave:test.t3
+drop table t1;
+drop table t2;
+drop table t3;
+drop function f1_two_inserts_trigger;
+# Test case8: CALLS A FUNCTION which INVOKES A TRIGGER with before insert action
+create table t1(a int) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create table t3(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+CREATE FUNCTION f1_two_inserts_trigger() RETURNS INTEGER
+BEGIN
+INSERT INTO t2(a) values(2),(3);
+INSERT INTO t2(a) values(2),(3);
+RETURN 1;
+END |
+create trigger tr11 before insert on t2 for each row begin
+insert into t3(a) values(new.a);
+insert into t3(a) values(new.a);
+end |
+begin;
+insert into t1(a) values(f1_two_inserts_trigger());
+insert into t2(a) values(4),(5);
+commit;
+insert into t1(a) values(f1_two_inserts_trigger());
+# To verify if insert/update in an autoinc column causes statement to be logged in row format
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+commit;
+#Test if the results are consistent on master and slave
+#for 'CALLS A FUNCTION which INVOKES A TRIGGER with before insert action'
+Comparing tables master:test.t2 and slave:test.t2
+Comparing tables master:test.t3 and slave:test.t3
+drop table t1;
+drop table t2;
+drop table t3;
+drop function f1_two_inserts_trigger;
+# Test case9: INSERT DATA INTO VIEW WHICH INVOKES TRIGGERS with after insert action
+CREATE TABLE t1(i1 int not null auto_increment, c1 INT, primary key(i1)) engine=innodb;
+CREATE TABLE t2(i1 int not null auto_increment, c2 INT, primary key(i1)) engine=innodb;
+CREATE TABLE t3(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create trigger tr16 after insert on t1 for each row insert into t3(a) values(new.c1);
+create trigger tr17 after insert on t2 for each row insert into t3(a) values(new.c2);
+begin;
+INSERT INTO t1(c1) VALUES (11), (12);
+INSERT INTO t2(c2) VALUES (13), (14);
+CREATE VIEW v16 AS SELECT c1, c2 FROM t1, t2;
+INSERT INTO v16(c1) VALUES (15),(16);
+INSERT INTO v16(c2) VALUES (17),(18);
+INSERT INTO v16(c1) VALUES (19),(20);
+INSERT INTO v16(c2) VALUES (21),(22);
+INSERT INTO v16(c1) VALUES (23), (24);
+INSERT INTO v16(c1) VALUES (25), (26);
+commit;
+#Test if the results are consistent on master and slave
+#for 'INSERT DATA INTO VIEW WHICH INVOKES TRIGGERS'
+Comparing tables master:test.t3 and slave:test.t3
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP VIEW v16;
+# Test case10: INSERT DATA INTO VIEW WHICH INVOKES TRIGGERS with before insert action
+CREATE TABLE t1(i1 int not null auto_increment, c1 INT, primary key(i1)) engine=innodb;
+CREATE TABLE t2(i1 int not null auto_increment, c2 INT, primary key(i1)) engine=innodb;
+CREATE TABLE t3(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+create trigger tr16 before insert on t1 for each row insert into t3(a) values(new.c1);
+create trigger tr17 before insert on t2 for each row insert into t3(a) values(new.c2);
+begin;
+INSERT INTO t1(c1) VALUES (11), (12);
+INSERT INTO t2(c2) VALUES (13), (14);
+CREATE VIEW v16 AS SELECT c1, c2 FROM t1, t2;
+INSERT INTO v16(c1) VALUES (15),(16);
+INSERT INTO v16(c2) VALUES (17),(18);
+INSERT INTO v16(c1) VALUES (19),(20);
+INSERT INTO v16(c2) VALUES (21),(22);
+INSERT INTO v16(c1) VALUES (23), (24);
+INSERT INTO v16(c1) VALUES (25), (26);
+commit;
+#Test if the results are consistent on master and slave
+#for 'INSERT DATA INTO VIEW WHICH INVOKES TRIGGERS'
+Comparing tables master:test.t3 and slave:test.t3
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP VIEW v16;
+# Test case11: INVOKES A FUNCTION TO INSERT TWO OR MORE VALUES INTO A TABLE WITH AUTOINC COLUMN
+create table t1(a int) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+CREATE FUNCTION f1_two_inserts() RETURNS INTEGER
+BEGIN
+INSERT INTO t2(a) values(2);
+INSERT INTO t2(a) values(2);
+RETURN 1;
+END//
+begin;
+insert into t1(a) values(f1_two_inserts());
+insert into t2(a) values(4),(5);
+commit;
+insert into t1(a) values(f1_two_inserts());
+commit;
+#Test result for INVOKES A FUNCTION TO INSERT TWO OR MORE VALUES on master
+select * from t2 ORDER BY i1;
+i1 a
+1 2
+2 2
+3 4
+4 5
+5 2
+6 2
+#Test result for INVOKES A FUNCTION TO INSERT TWO OR MORE VALUES on slave
+select * from t2 ORDER BY i1;
+i1 a
+1 2
+2 2
+3 4
+4 5
+5 2
+6 2
+drop table t1;
+drop table t2;
+drop function f1_two_inserts;
+# Test case12: INVOKES A FUNCTION TO UPDATE TWO OR MORE VALUES OF A TABLE WITH AUTOINC COLUMN
+create table t1(a int) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, b int, primary key(i1)) engine=innodb;
+CREATE FUNCTION f1_two_updates() RETURNS INTEGER
+BEGIN
+update t2 set a = a + 5 where b = 1;
+update t2 set a = a + 5 where b = 2;
+update t2 set a = a + 5 where b = 3;
+update t2 set a = a + 5 where b = 4;
+RETURN 1;
+END//
+insert into t2(a,b) values(1,1);
+insert into t2(a,b) values(2,2);
+insert into t2(a,b) values(3,3);
+insert into t2(a,b) values(4,4);
+insert into t1(a) values(f1_two_updates());
+begin;
+insert into t1(a) values(f1_two_updates());
+commit;
+#Test result for INVOKES A FUNCTION TO UPDATE TWO OR MORE VALUES on master
+select * from t2 ORDER BY i1;
+i1 a b
+1 11 1
+2 12 2
+3 13 3
+4 14 4
+#Test result for INVOKES A FUNCTION TO UPDATE TWO OR MORE VALUES on slave
+select * from t2 ORDER BY i1;
+i1 a b
+1 11 1
+2 12 2
+3 13 3
+4 14 4
+drop table t1;
+drop table t2;
+drop function f1_two_updates;
+# Test case13: UPDATE MORE THAN ONE TABLES ON TOP-STATEMENT
+create table t1(i1 int not null auto_increment, a int, b int, primary key(i1)) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, b int, primary key(i1)) engine=innodb;
+begin;
+insert into t1(a,b) values(1,1),(2,2);
+insert into t2(a,b) values(1,1),(2,2);
+update t1,t2 set t1.a=t1.a+5, t2.a=t2.a+5 where t1.b=t2.b;
+insert into t1(a,b) values(3,3);
+insert into t2(a,b) values(3,3);
+commit;
+# To verify if it works fine when these statements are not be marked as unsafe
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=1
+master-bin.000001 # Query # # use `test`; insert into t1(a,b) values(1,1),(2,2)
+master-bin.000001 # Intvar # # INSERT_ID=1
+master-bin.000001 # Query # # use `test`; insert into t2(a,b) values(1,1),(2,2)
+master-bin.000001 # Query # # use `test`; update t1,t2 set t1.a=t1.a+5, t2.a=t2.a+5 where t1.b=t2.b
+master-bin.000001 # Intvar # # INSERT_ID=3
+master-bin.000001 # Query # # use `test`; insert into t1(a,b) values(3,3)
+master-bin.000001 # Intvar # # INSERT_ID=3
+master-bin.000001 # Query # # use `test`; insert into t2(a,b) values(3,3)
+master-bin.000001 # Xid # # COMMIT /* XID */
+#Test if the results are consistent on master and slave
+#for 'UPDATE MORE THAN ONE TABLES ON TOP-STATEMENT'
+Comparing tables master:test.t1 and slave:test.t1
+Comparing tables master:test.t2 and slave:test.t2
+drop table t1;
+drop table t2;
+# Test case14: INSERT DATA INTO VIEW WHICH INVOLVED MORE THAN ONE TABLES
+CREATE TABLE t1(i1 int not null auto_increment, c1 INT, primary key(i1)) engine=innodb;
+CREATE TABLE t2(i1 int not null auto_increment, c2 INT, primary key(i1)) engine=innodb;
+begin;
+INSERT INTO t1(c1) VALUES (11), (12);
+INSERT INTO t2(c2) VALUES (13), (14);
+CREATE VIEW v15 AS SELECT c1, c2 FROM t1, t2;
+INSERT INTO v15(c1) VALUES (15),(16);
+INSERT INTO v15(c2) VALUES (17),(18);
+INSERT INTO v15(c1) VALUES (19),(20);
+INSERT INTO v15(c2) VALUES (21),(22);
+INSERT INTO v15(c1) VALUES (23), (24);
+INSERT INTO v15(c2) VALUES (25), (26);
+commit;
+# To verify if it works fine when these statements are not be marked as unsafe
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=1
+master-bin.000001 # Query # # use `test`; INSERT INTO t1(c1) VALUES (11), (12)
+master-bin.000001 # Intvar # # INSERT_ID=1
+master-bin.000001 # Query # # use `test`; INSERT INTO t2(c2) VALUES (13), (14)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v15` AS SELECT c1, c2 FROM t1, t2
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=3
+master-bin.000001 # Query # # use `test`; INSERT INTO v15(c1) VALUES (15),(16)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=3
+master-bin.000001 # Query # # use `test`; INSERT INTO v15(c2) VALUES (17),(18)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=5
+master-bin.000001 # Query # # use `test`; INSERT INTO v15(c1) VALUES (19),(20)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=5
+master-bin.000001 # Query # # use `test`; INSERT INTO v15(c2) VALUES (21),(22)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=7
+master-bin.000001 # Query # # use `test`; INSERT INTO v15(c1) VALUES (23), (24)
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Intvar # # INSERT_ID=7
+master-bin.000001 # Query # # use `test`; INSERT INTO v15(c2) VALUES (25), (26)
+master-bin.000001 # Xid # # COMMIT /* XID */
+#Test if the results are consistent on master and slave
+#for 'INSERT DATA INTO VIEW WHICH INVOLVED MORE THAN ONE TABLES'
+Comparing tables master:test.t1 and slave:test.t1
+Comparing tables master:test.t2 and slave:test.t2
+drop table t1;
+drop table t2;
+drop view v15;
diff --git a/mysql-test/suite/rpl/r/rpl_bug33931.result b/mysql-test/suite/rpl/r/rpl_bug33931.result
index 85c8fb0da9c..a17941f6ba9 100644
--- a/mysql-test/suite/rpl/r/rpl_bug33931.result
+++ b/mysql-test/suite/rpl/r/rpl_bug33931.result
@@ -1,5 +1,5 @@
reset master;
-call mtr.add_suppression("Failed during slave thread initialization");
+call mtr.add_suppression("Failed during slave I/O thread initialization");
stop slave;
reset slave;
SET GLOBAL debug="d,simulate_io_slave_error_on_init,simulate_sql_slave_error_on_init";
diff --git a/mysql-test/suite/rpl/r/rpl_do_grant.result b/mysql-test/suite/rpl/r/rpl_do_grant.result
index 69bcfad4347..0913b1afdbf 100644
--- a/mysql-test/suite/rpl/r/rpl_do_grant.result
+++ b/mysql-test/suite/rpl/r/rpl_do_grant.result
@@ -166,4 +166,7 @@ DROP FUNCTION upgrade_del_func;
DROP FUNCTION upgrade_alter_func;
DROP DATABASE bug42217_db;
DROP USER 'create_rout_db'@'localhost';
+call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+USE mtr;
+call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
"End of test"
diff --git a/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result b/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result
index e57daad3342..e2ec78e7adc 100644
--- a/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result
+++ b/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+call mtr.add_suppression("Slave: Unknown table 't6' Error_code: 1051");
**** Diff Table Def Start ****
*** On Slave ***
STOP SLAVE;
diff --git a/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result b/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result
index 6696ddc7789..ed5b4eac27d 100644
--- a/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result
+++ b/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+call mtr.add_suppression("Slave: Unknown table 't6' Error_code: 1051");
**** Diff Table Def Start ****
*** On Slave ***
STOP SLAVE;
diff --git a/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result b/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result
index e4d5127ac07..5f2a55b5e35 100644
--- a/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result
+++ b/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result
@@ -4,6 +4,10 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+call mtr.add_suppression("Get master clock failed with error: ");
+call mtr.add_suppression("Get master SERVER_ID failed with error: ");
+call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again");
+call mtr.add_suppression("Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; .*");
SELECT IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP");
IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP")
1
diff --git a/mysql-test/suite/rpl/r/rpl_idempotency.result b/mysql-test/suite/rpl/r/rpl_idempotency.result
index 3341c03db0f..bfdcbc6fa23 100644
--- a/mysql-test/suite/rpl/r/rpl_idempotency.result
+++ b/mysql-test/suite/rpl/r/rpl_idempotency.result
@@ -4,7 +4,8 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
-call mtr.add_suppression("Slave: Can\'t find record in \'t1\' Error_code: 1032");
+call mtr.add_suppression("Slave: Can't find record in 't.' Error_code: 1032");
+call mtr.add_suppression("Slave: Cannot delete or update a parent row: a foreign key constraint fails .* Error_code: 1451");
call mtr.add_suppression("Slave: Cannot add or update a child row: a foreign key constraint fails .* Error_code: 1452");
SET @old_slave_exec_mode= @@global.slave_exec_mode;
CREATE TABLE t1 (a INT PRIMARY KEY);
diff --git a/mysql-test/suite/rpl/r/rpl_init_slave_errors.result b/mysql-test/suite/rpl/r/rpl_init_slave_errors.result
index ab957e6d9bc..c6ee82b13f3 100644
--- a/mysql-test/suite/rpl/r/rpl_init_slave_errors.result
+++ b/mysql-test/suite/rpl/r/rpl_init_slave_errors.result
@@ -9,6 +9,7 @@ reset slave;
SET GLOBAL debug= "d,simulate_io_slave_error_on_init,simulate_sql_slave_error_on_init";
start slave;
Reporting the following error: Failed during slave thread initialization
+call mtr.add_suppression("Failed during slave I/O thread initialization");
SET GLOBAL debug= "";
stop slave;
reset slave;
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 81c486cb43c..3a1c2b68b01 100644
--- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result
+++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result
@@ -885,7 +885,7 @@ master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2
master-bin.000001 # Xid 1 # #
master-bin.000001 # Query 1 # BEGIN
master-bin.000001 # Begin_load_query 1 # ;file_id=#;block_len=#
-master-bin.000001 # Execute_load_query 1 # use `test_rpl`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/std_data/rpl_mixed.dat' INTO TABLE t1 FIELDS TERMINATED BY '|' ;file_id=#
+master-bin.000001 # Execute_load_query 1 # use `test_rpl`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/std_data/rpl_mixed.dat' INTO TABLE `t1` FIELDS TERMINATED BY '|' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, b) ;file_id=#
master-bin.000001 # Xid 1 # #
master-bin.000001 # Query 1 # BEGIN
master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1
diff --git a/mysql-test/suite/rpl/r/rpl_loaddata.result b/mysql-test/suite/rpl/r/rpl_loaddata.result
index d7a02bc84a5..ca9c14691b0 100644
--- a/mysql-test/suite/rpl/r/rpl_loaddata.result
+++ b/mysql-test/suite/rpl/r/rpl_loaddata.result
@@ -36,7 +36,7 @@ set global sql_slave_skip_counter=1;
start slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1797 # # master-bin.000001 Yes Yes # 0 0 1797 # None 0 No # No 0 0
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 2009 # # master-bin.000001 Yes Yes # 0 0 2009 # None 0 No # No 0 0
set sql_log_bin=0;
delete from t1;
set sql_log_bin=1;
@@ -46,7 +46,7 @@ change master to master_user='test';
change master to master_user='root';
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1832 # # master-bin.000001 No No # 0 0 1832 # None 0 No # No 0 0
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 2044 # # master-bin.000001 No No # 0 0 2044 # None 0 No # No 0 0
set global sql_slave_skip_counter=1;
start slave;
set sql_log_bin=0;
@@ -86,3 +86,32 @@ CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB;
LOAD DATA INFILE "../../std_data/words.dat" INTO TABLE t1;
ERROR 23000: Duplicate entry 'Aarhus' for key 'PRIMARY'
DROP TABLE IF EXISTS t1;
+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 database if exists b48297_db1;
+drop database if exists b42897_db2;
+create database b48297_db1;
+create database b42897_db2;
+use b48297_db1;
+CREATE TABLE t1 (c1 VARCHAR(256)) engine=MyISAM;;
+use b42897_db2;
+### assertion: works with cross-referenced database
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE b48297_db1.t1;
+use b48297_db1;
+### assertion: works with fully qualified name on current database
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE b48297_db1.t1;
+### assertion: works without fully qualified name on current database
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE t1;
+### create connection without default database
+### connect (conn2,localhost,root,,*NO-ONE*);
+### assertion: works without stating the default database
+LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE b48297_db1.t1;
+### disconnect and switch back to master connection
+use b48297_db1;
+Comparing tables master:b48297_db1.t1 and slave:b48297_db1.t1
+DROP DATABASE b48297_db1;
+DROP DATABASE b42897_db2;
diff --git a/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result b/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result
index 27fb8623e85..35696615b5a 100644
--- a/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result
+++ b/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result
@@ -53,7 +53,7 @@ Master_User root
Master_Port MASTER_PORT
Connect_Retry 1
Master_Log_File master-bin.000001
-Read_Master_Log_Pos 465
+Read_Master_Log_Pos 556
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
diff --git a/mysql-test/suite/rpl/r/rpl_loaddata_map.result b/mysql-test/suite/rpl/r/rpl_loaddata_map.result
index 901f3352b44..006f84043a4 100644
--- a/mysql-test/suite/rpl/r/rpl_loaddata_map.result
+++ b/mysql-test/suite/rpl/r/rpl_loaddata_map.result
@@ -20,7 +20,7 @@ master-bin.000001 # Query # # use `test`; create table t2 (id int not null prima
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
master-bin.000001 # Append_block # # ;file_id=#;block_len=#
master-bin.000001 # Append_block # # ;file_id=#;block_len=#
-master-bin.000001 # Execute_load_query # # use `test`; load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2 ;file_id=#
+master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (id) ;file_id=#
==== Verify results on slave ====
[on slave]
select count(*) from t2 /* 5 000 */;
diff --git a/mysql-test/suite/rpl/r/rpl_loaddatalocal.result b/mysql-test/suite/rpl/r/rpl_loaddatalocal.result
index 93ef33f3fc0..6dccaa3d74c 100644
--- a/mysql-test/suite/rpl/r/rpl_loaddatalocal.result
+++ b/mysql-test/suite/rpl/r/rpl_loaddatalocal.result
@@ -54,3 +54,31 @@ a
[on master]
DROP TABLE t1;
[on slave]
+
+Bug #43746:
+"return wrong query string when parse 'load data infile' sql statement"
+
+[master]
+SELECT @@SESSION.sql_mode INTO @old_mode;
+SET sql_mode='ignore_space';
+CREATE TABLE t1(a int);
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+SELECT * INTO OUTFILE 'MYSQLD_DATADIR/bug43746.sql' FROM t1;
+TRUNCATE TABLE t1;
+LOAD DATA LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1;
+LOAD/* look mum, with comments in weird places! */DATA/* oh hai */LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql'/* we are */INTO/* from the internets */TABLE t1;
+LOAD DATA/*!10000 LOCAL */INFILE 'MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1;
+LOAD DATA LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql' /*!10000 INTO */ TABLE t1;
+LOAD DATA LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql' /*!10000 INTO TABLE */ t1;
+LOAD DATA /*!10000 LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql' INTO TABLE */ t1;
+LOAD DATA/*!10000 LOCAL */INFILE 'MYSQLD_DATADIR/bug43746.sql'/*!10000 INTO*/TABLE t1;
+LOAD DATA/*!10000 LOCAL */INFILE 'MYSQLD_DATADIR/bug43746.sql'/* empty */INTO TABLE t1;
+LOAD DATA/*!10000 LOCAL */INFILE 'MYSQLD_DATADIR/bug43746.sql' INTO/* empty */TABLE t1;
+LOAD/*!99999 special comments that do not expand */DATA/*!99999 code from the future */LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql'/*!99999 have flux capacitor */INTO/*!99999 will travel */TABLE t1;
+SET sql_mode='PIPES_AS_CONCAT,ANSI_QUOTES,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER';
+LOAD DATA LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1;
+[slave]
+[master]
+DROP TABLE t1;
+SET SESSION sql_mode=@old_mode;
+[slave]
diff --git a/mysql-test/suite/rpl/r/rpl_log_pos.result b/mysql-test/suite/rpl/r/rpl_log_pos.result
index 7b3ebf62959..85fa4c10eac 100644
--- a/mysql-test/suite/rpl/r/rpl_log_pos.result
+++ b/mysql-test/suite/rpl/r/rpl_log_pos.result
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+call mtr.add_suppression ("Slave I/O: Got fatal error 1236 from master when reading data from binary");
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 # <Binlog_Do_DB> <Binlog_Ignore_DB>
diff --git a/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result b/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result
new file mode 100644
index 00000000000..09a9121d22c
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result
@@ -0,0 +1,13 @@
+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 DATABASE IF EXISTS `#mysql50#mysqltest-1`;
+CREATE DATABASE `#mysql50#mysqltest-1`;
+Master position is not changed
+STOP SLAVE SQL_THREAD;
+Master position has been changed
+DROP DATABASE `mysqltest-1`;
+DROP DATABASE `#mysql50#mysqltest-1`;
diff --git a/mysql-test/suite/rpl/r/rpl_packet.result b/mysql-test/suite/rpl/r/rpl_packet.result
index 4c64054e348..0a9495751fe 100644
--- a/mysql-test/suite/rpl/r/rpl_packet.result
+++ b/mysql-test/suite/rpl/r/rpl_packet.result
@@ -4,6 +4,8 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+call mtr.add_suppression("Slave I/O: Got a packet bigger than 'max_allowed_packet' bytes, Error_code: 1153");
+call mtr.add_suppression("Slave I/O: Got fatal error 1236 from master when reading data from binary log:");
drop database if exists DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________;
create database DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________;
SET @@global.max_allowed_packet=1024;
@@ -32,6 +34,21 @@ include/start_slave.inc
CREATE TABLE `t1` (`f1` LONGTEXT) ENGINE=MyISAM;
INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048');
Slave_IO_Running = No (expect No)
+SELECT "Got a packet bigger than 'max_allowed_packet' bytes" AS Last_IO_Error;
+Last_IO_Error
+Got a packet bigger than 'max_allowed_packet' bytes
+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 (f1 int PRIMARY KEY, f2 LONGTEXT, f3 LONGTEXT) ENGINE=MyISAM;
+INSERT INTO t1(f1, f2, f3) VALUES(1, REPEAT('a', @@global.max_allowed_packet), REPEAT('b', @@global.max_allowed_packet));
+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'
==== clean up ====
DROP TABLE t1;
SET @@global.max_allowed_packet= 1024;
diff --git a/mysql-test/suite/rpl/r/rpl_row_create_table.result b/mysql-test/suite/rpl/r/rpl_row_create_table.result
index 5bed9106009..b7122adea2a 100644
--- a/mysql-test/suite/rpl/r/rpl_row_create_table.result
+++ b/mysql-test/suite/rpl/r/rpl_row_create_table.result
@@ -176,7 +176,7 @@ Log_name Pos Event_type Server_id End_log_pos Info
# 106 Query # 174 BEGIN
# 174 Table_map # 216 table_id: # (test.t7)
# 216 Write_rows # 272 table_id: # flags: STMT_END_F
-# 272 Query # 343 ROLLBACK
+# 272 Query # 341 COMMIT
SELECT * FROM t7 ORDER BY a,b;
a b
1 2
@@ -327,7 +327,7 @@ Log_name Pos Event_type Server_id End_log_pos Info
# 1329 Query # 1397 BEGIN
# 1397 Table_map # 1438 table_id: # (test.t1)
# 1438 Write_rows # 1482 table_id: # flags: STMT_END_F
-# 1482 Query # 1553 ROLLBACK
+# 1482 Query # 1551 COMMIT
SHOW TABLES;
Tables_in_test
t1
diff --git a/mysql-test/suite/rpl/r/rpl_row_disabled_slave_key.result b/mysql-test/suite/rpl/r/rpl_row_disabled_slave_key.result
new file mode 100644
index 00000000000..01e3dfd6508
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_row_disabled_slave_key.result
@@ -0,0 +1,26 @@
+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;
+SET SQL_LOG_BIN=0;
+CREATE TABLE t (a int, b int, c int, key(b));
+SET SQL_LOG_BIN=1;
+CREATE TABLE t (a int, b int, c int);
+INSERT INTO t VALUES (1,2,4);
+INSERT INTO t VALUES (4,3,4);
+DELETE FROM t;
+DROP TABLE t;
+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 t (a int, b int, c int, key(b));
+ALTER TABLE t DISABLE KEYS;
+INSERT INTO t VALUES (1,2,4);
+INSERT INTO t VALUES (4,3,4);
+DELETE FROM t;
+DROP TABLE t;
diff --git a/mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result b/mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result
index 8339e77d3a0..6792a701577 100644
--- a/mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result
+++ b/mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result
@@ -4,21 +4,20 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
-create database if not exists mysqltest1;
-DROP PROCEDURE IF EXISTS mysqltest1.p1;
-DROP PROCEDURE IF EXISTS mysqltest1.p2;
-DROP TABLE IF EXISTS mysqltest1.t2;
-DROP TABLE IF EXISTS mysqltest1.t1;
-CREATE TABLE IF NOT EXISTS mysqltest1.t1(name CHAR(16), birth DATE,PRIMARY KEY(name))ENGINE=InnoDB;
-CREATE TABLE IF NOT EXISTS mysqltest1.t2(name CHAR(16), age INT ,PRIMARY KEY(name))ENGINE=InnoDB;
-CREATE PROCEDURE mysqltest1.p1()
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+CREATE TABLE IF NOT EXISTS t1(name CHAR(16), birth DATE,PRIMARY KEY(name))ENGINE=InnoDB;
+CREATE TABLE IF NOT EXISTS t2(name CHAR(16), age INT ,PRIMARY KEY(name))ENGINE=InnoDB;
+CREATE PROCEDURE p1()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE spa CHAR(16);
DECLARE spb INT;
DECLARE cur1 CURSOR FOR SELECT name,
(YEAR(CURDATE())-YEAR(birth))-(RIGHT(CURDATE(),5)<RIGHT(birth,5))
-FROM mysqltest1.t1;
+FROM t1;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
OPEN cur1;
SET AUTOCOMMIT=0;
@@ -26,21 +25,20 @@ REPEAT
FETCH cur1 INTO spa, spb;
IF NOT done THEN
START TRANSACTION;
-INSERT INTO mysqltest1.t2 VALUES (spa,spb);
+INSERT INTO t2 VALUES (spa,spb);
COMMIT;
END IF;
UNTIL done END REPEAT;
SET AUTOCOMMIT=1;
CLOSE cur1;
END|
-CREATE PROCEDURE mysqltest1.p2()
+CREATE PROCEDURE p2()
BEGIN
-INSERT INTO mysqltest1.t1 VALUES ('MySQL','1993-02-04'),('ROCKS', '1990-08-27'),('Texas', '1999-03-30'),('kyle','2005-1-1');
+INSERT INTO t1 VALUES ('MySQL','1993-02-04'),('ROCKS', '1990-08-27'),('Texas', '1999-03-30'),('kyle','2005-1-1');
END|
-CALL mysqltest1.p2();
-CALL mysqltest1.p1();
-DROP PROCEDURE IF EXISTS mysqltest1.p1;
-DROP PROCEDURE IF EXISTS mysqltest1.p2;
-DROP TABLE IF EXISTS mysqltest1.t1;
-DROP TABLE IF EXISTS mysqltest1.t2;
-DROP DATABASE mysqltest1;
+CALL p2();
+CALL p1();
+DROP TABLE t1;
+DROP TABLE t2;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
diff --git a/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result b/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result
index 777f7d8427b..e2efcf08d7a 100644
--- a/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result
+++ b/mysql-test/suite/rpl/r/rpl_slave_load_remove_tmpfile.result
@@ -51,3 +51,4 @@ Last_SQL_Errno 9
Last_SQL_Error Error in Begin_load_query event: write to '../../tmp/SQL_LOAD.data' failed
drop table t1;
drop table t1;
+call mtr.add_suppression("Slave: Error writing file 'UNKNOWN' .Errcode: 9. Error_code: 3");
diff --git a/mysql-test/suite/rpl/r/rpl_stm_log.result b/mysql-test/suite/rpl/r/rpl_stm_log.result
index bcefc6f9d3d..d73b8990041 100644
--- a/mysql-test/suite/rpl/r/rpl_stm_log.result
+++ b/mysql-test/suite/rpl/r/rpl_stm_log.result
@@ -25,7 +25,7 @@ master-bin.000001 # Query 1 # use `test`; insert into t1 values (NULL)
master-bin.000001 # Query 1 # use `test`; drop table t1
master-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM
master-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581
-master-bin.000001 # Execute_load_query 1 # use `test`; load data infile '../../std_data/words.dat' into table t1 ignore 1 lines ;file_id=1
+master-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (word) ;file_id=1
show binlog events from 106 limit 1;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=MyISAM
@@ -193,7 +193,7 @@ master-bin.000001 # Query # # use `test`; insert into t1 values (NULL)
master-bin.000001 # Query # # use `test`; drop table t1
master-bin.000001 # Query # # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
-master-bin.000001 # Execute_load_query # # use `test`; load data infile '../../std_data/words.dat' into table t1 ignore 1 lines ;file_id=#
+master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (word) ;file_id=#
master-bin.000001 # Rotate # # master-bin.000002;pos=4
show binlog events in 'master-bin.000002';
Log_name Pos Event_type Server_id End_log_pos Info
@@ -218,7 +218,7 @@ slave-bin.000001 # Query 1 # use `test`; insert into t1 values (NULL)
slave-bin.000001 # Query 1 # use `test`; drop table t1
slave-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM
slave-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581
-slave-bin.000001 # Execute_load_query 1 # use `test`; load data INFILE '../../tmp/SQL_LOAD-2-1-1.data' INTO table t1 ignore 1 lines ;file_id=1
+slave-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE '../../tmp/SQL_LOAD-2-1-1.data' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (word) ;file_id=1
slave-bin.000001 # Query 1 # use `test`; create table t3 (a int)ENGINE=MyISAM
slave-bin.000001 # Rotate 2 # slave-bin.000002;pos=4
show binlog events in 'slave-bin.000002' from 4;
diff --git a/mysql-test/suite/rpl/r/rpl_temporary_errors.result b/mysql-test/suite/rpl/r/rpl_temporary_errors.result
index d14380a6369..e5d9ea5837c 100644
--- a/mysql-test/suite/rpl/r/rpl_temporary_errors.result
+++ b/mysql-test/suite/rpl/r/rpl_temporary_errors.result
@@ -82,3 +82,4 @@ Last_SQL_Error
DROP TABLE t1;
**** On Master ****
DROP TABLE t1;
+STOP SLAVE;
diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def
index af8eef764ed..8cae44a3607 100644
--- a/mysql-test/suite/rpl/t/disabled.def
+++ b/mysql-test/suite/rpl/t/disabled.def
@@ -10,6 +10,3 @@
#
##############################################################################
-rpl_cross_version : Bug#42311 2009-03-27 joro rpl_cross_version fails on macosx
-rpl_init_slave : Bug#44920 2009-07006 pcrews MTR2 is not processing master.opt input properly on Windows. *Must be done this way due to the nature of the bug*
-
diff --git a/mysql-test/suite/rpl/t/rpl_auto_increment_update_failure.test b/mysql-test/suite/rpl/t/rpl_auto_increment_update_failure.test
new file mode 100644
index 00000000000..f38d2151ab3
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_auto_increment_update_failure.test
@@ -0,0 +1,214 @@
+#
+# Bug45677
+# This test verifies the following two properties:
+# P1) insert/update in an autoinc column causes statement to
+# be logged in row format if binlog_format=mixed.
+# P2) if binlog_format=mixed, and a trigger or function contains
+# two or more inserts/updates in a table that has an autoinc
+# column, then the slave should not go out of sync, even if
+# there are concurrent transactions.
+#
+# Property (P1) is tested by executing an insert and an update on
+# a table that has an autoinc column, and verifying that these
+# statements result in row events in the binlog.
+# Property (P2) is tested by setting up the test scenario and
+# verifying that the tables are identical on master and slave.
+#
+
+source include/have_binlog_format_mixed.inc;
+source include/have_innodb.inc;
+source include/master-slave.inc;
+
+--echo # Test case1: INVOKES A TRIGGER with after insert action
+let $trigger_action = after insert;
+source extra/rpl_tests/rpl_auto_increment_invoke_trigger.test;
+
+--echo # Test case2: INVOKES A TRIGGER with before insert action
+let $trigger_action = before insert;
+source extra/rpl_tests/rpl_auto_increment_invoke_trigger.test;
+
+--echo # Test case3: INVOKES A TRIGGER with after update action
+let $trigger_action = after update;
+source extra/rpl_tests/rpl_auto_increment_invoke_trigger.test;
+
+--echo # Test case4: INVOKES A TRIGGER with before update action
+let $trigger_action = before update;
+source extra/rpl_tests/rpl_auto_increment_invoke_trigger.test;
+
+--echo # Test case5: INVOKES A TRIGGER with after delete action
+let $trigger_action = after delete;
+source extra/rpl_tests/rpl_auto_increment_invoke_trigger.test;
+
+--echo # Test case6: INVOKES A TRIGGER with before delete action
+let $trigger_action = before delete;
+source extra/rpl_tests/rpl_auto_increment_invoke_trigger.test;
+
+--echo # Test case7: CALLS A FUNCTION which INVOKES A TRIGGER with after insert action
+let $insert_action = after insert;
+source extra/rpl_tests/rpl_autoinc_func_invokes_trigger.test;
+
+--echo # Test case8: CALLS A FUNCTION which INVOKES A TRIGGER with before insert action
+let $insert_action = before insert;
+source extra/rpl_tests/rpl_autoinc_func_invokes_trigger.test;
+
+--echo # Test case9: INSERT DATA INTO VIEW WHICH INVOKES TRIGGERS with after insert action
+let $insert_action = after insert;
+source extra/rpl_tests/rpl_auto_increment_insert_view.test;
+
+--echo # Test case10: INSERT DATA INTO VIEW WHICH INVOKES TRIGGERS with before insert action
+let $insert_action = before insert;
+source extra/rpl_tests/rpl_auto_increment_insert_view.test;
+
+--echo # Test case11: INVOKES A FUNCTION TO INSERT TWO OR MORE VALUES INTO A TABLE WITH AUTOINC COLUMN
+connection master;
+create table t1(a int) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb;
+delimiter //;
+CREATE FUNCTION f1_two_inserts() RETURNS INTEGER
+BEGIN
+ INSERT INTO t2(a) values(2);
+ INSERT INTO t2(a) values(2);
+ RETURN 1;
+END//
+delimiter ;//
+begin;
+insert into t1(a) values(f1_two_inserts());
+
+connection master1;
+#The default autocommit is set to 1, so the statement is auto committed
+insert into t2(a) values(4),(5);
+
+connection master;
+commit;
+insert into t1(a) values(f1_two_inserts());
+commit;
+
+connection master;
+--echo #Test result for INVOKES A FUNCTION TO INSERT TWO OR MORE VALUES on master
+select * from t2 ORDER BY i1;
+
+sync_slave_with_master;
+connection slave;
+--echo #Test result for INVOKES A FUNCTION TO INSERT TWO OR MORE VALUES on slave
+select * from t2 ORDER BY i1;
+
+connection master;
+drop table t1;
+drop table t2;
+drop function f1_two_inserts;
+sync_slave_with_master;
+
+--echo # Test case12: INVOKES A FUNCTION TO UPDATE TWO OR MORE VALUES OF A TABLE WITH AUTOINC COLUMN
+connection master;
+create table t1(a int) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, b int, primary key(i1)) engine=innodb;
+delimiter //;
+CREATE FUNCTION f1_two_updates() RETURNS INTEGER
+BEGIN
+ update t2 set a = a + 5 where b = 1;
+ update t2 set a = a + 5 where b = 2;
+ update t2 set a = a + 5 where b = 3;
+ update t2 set a = a + 5 where b = 4;
+ RETURN 1;
+END//
+delimiter ;//
+
+connection master1;
+#The default autocommit is set to 1, so the statement is auto committed
+insert into t2(a,b) values(1,1);
+insert into t2(a,b) values(2,2);
+insert into t2(a,b) values(3,3);
+insert into t2(a,b) values(4,4);
+insert into t1(a) values(f1_two_updates());
+
+connection master;
+begin;
+insert into t1(a) values(f1_two_updates());
+commit;
+
+connection master;
+--echo #Test result for INVOKES A FUNCTION TO UPDATE TWO OR MORE VALUES on master
+select * from t2 ORDER BY i1;
+
+sync_slave_with_master;
+connection slave;
+--echo #Test result for INVOKES A FUNCTION TO UPDATE TWO OR MORE VALUES on slave
+select * from t2 ORDER BY i1;
+
+connection master;
+drop table t1;
+drop table t2;
+drop function f1_two_updates;
+sync_slave_with_master;
+
+--echo # Test case13: UPDATE MORE THAN ONE TABLES ON TOP-STATEMENT
+connection master;
+create table t1(i1 int not null auto_increment, a int, b int, primary key(i1)) engine=innodb;
+create table t2(i1 int not null auto_increment, a int, b int, primary key(i1)) engine=innodb;
+begin;
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+insert into t1(a,b) values(1,1),(2,2);
+insert into t2(a,b) values(1,1),(2,2);
+update t1,t2 set t1.a=t1.a+5, t2.a=t2.a+5 where t1.b=t2.b;
+insert into t1(a,b) values(3,3);
+insert into t2(a,b) values(3,3);
+commit;
+--echo # To verify if it works fine when these statements are not be marked as unsafe
+source include/show_binlog_events.inc;
+
+sync_slave_with_master;
+--echo #Test if the results are consistent on master and slave
+--echo #for 'UPDATE MORE THAN ONE TABLES ON TOP-STATEMENT'
+let $diff_table_1=master:test.t1;
+let $diff_table_2=slave:test.t1;
+source include/diff_tables.inc;
+let $diff_table_1=master:test.t2;
+let $diff_table_2=slave:test.t2;
+source include/diff_tables.inc;
+
+connection master;
+drop table t1;
+drop table t2;
+sync_slave_with_master;
+
+--echo # Test case14: INSERT DATA INTO VIEW WHICH INVOLVED MORE THAN ONE TABLES
+connection master;
+CREATE TABLE t1(i1 int not null auto_increment, c1 INT, primary key(i1)) engine=innodb;
+CREATE TABLE t2(i1 int not null auto_increment, c2 INT, primary key(i1)) engine=innodb;
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+begin;
+INSERT INTO t1(c1) VALUES (11), (12);
+INSERT INTO t2(c2) VALUES (13), (14);
+
+CREATE VIEW v15 AS SELECT c1, c2 FROM t1, t2;
+
+INSERT INTO v15(c1) VALUES (15),(16);
+INSERT INTO v15(c2) VALUES (17),(18);
+
+connection master1;
+INSERT INTO v15(c1) VALUES (19),(20);
+INSERT INTO v15(c2) VALUES (21),(22);
+
+connection master;
+INSERT INTO v15(c1) VALUES (23), (24);
+INSERT INTO v15(c2) VALUES (25), (26);
+commit;
+--echo # To verify if it works fine when these statements are not be marked as unsafe
+source include/show_binlog_events.inc;
+
+sync_slave_with_master;
+--echo #Test if the results are consistent on master and slave
+--echo #for 'INSERT DATA INTO VIEW WHICH INVOLVED MORE THAN ONE TABLES'
+let $diff_table_1=master:test.t1;
+let $diff_table_2=slave:test.t1;
+source include/diff_tables.inc;
+let $diff_table_1=master:test.t2;
+let $diff_table_2=slave:test.t2;
+source include/diff_tables.inc;
+
+connection master;
+drop table t1;
+drop table t2;
+drop view v15;
+sync_slave_with_master;
+
diff --git a/mysql-test/suite/rpl/t/rpl_bug33931.test b/mysql-test/suite/rpl/t/rpl_bug33931.test
index 13f781c644b..1316ddb7401 100644
--- a/mysql-test/suite/rpl/t/rpl_bug33931.test
+++ b/mysql-test/suite/rpl/t/rpl_bug33931.test
@@ -15,7 +15,7 @@ reset master;
connection slave;
# Add suppression for expected warnings in slaves error log
-call mtr.add_suppression("Failed during slave thread initialization");
+call mtr.add_suppression("Failed during slave I/O thread initialization");
--disable_warnings
stop slave;
diff --git a/mysql-test/suite/rpl/t/rpl_do_grant.test b/mysql-test/suite/rpl/t/rpl_do_grant.test
index a60a4bd6c3d..38f44091b59 100644
--- a/mysql-test/suite/rpl/t/rpl_do_grant.test
+++ b/mysql-test/suite/rpl/t/rpl_do_grant.test
@@ -210,5 +210,10 @@ DROP FUNCTION upgrade_del_func;
DROP FUNCTION upgrade_alter_func;
DROP DATABASE bug42217_db;
DROP USER 'create_rout_db'@'localhost';
-
+
+call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+connection slave;
+USE mtr;
+call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
+
--echo "End of test"
diff --git a/mysql-test/suite/rpl/t/rpl_drop_temp.test b/mysql-test/suite/rpl/t/rpl_drop_temp.test
index df162d3b244..7827e16e45f 100644
--- a/mysql-test/suite/rpl/t/rpl_drop_temp.test
+++ b/mysql-test/suite/rpl/t/rpl_drop_temp.test
@@ -23,6 +23,8 @@ disconnect con_temp;
--source include/wait_until_disconnected.inc
connection master;
+-- let $wait_binlog_event= DROP
+-- source include/wait_for_binlog_event.inc
sync_slave_with_master;
connection slave;
diff --git a/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test b/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test
index b9ab66165cc..e77cd308f39 100644
--- a/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test
+++ b/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test
@@ -50,7 +50,7 @@ kill @id;
drop table t2,t3;
insert into t4 values (3),(4);
connection master;
---error 0,1053,2013
+--error 0,1317,2013
reap;
connection master1;
save_master_pos;
diff --git a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock-slave.opt b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock-slave.opt
new file mode 100644
index 00000000000..f9aa8c0367e
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock-slave.opt
@@ -0,0 +1 @@
+--master-retry-count=60
diff --git a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test
index 40d11f2cec2..69c63eaa69f 100644
--- a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test
+++ b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test
@@ -16,6 +16,10 @@
source include/master-slave.inc;
source include/have_debug.inc;
+call mtr.add_suppression("Get master clock failed with error: ");
+call mtr.add_suppression("Get master SERVER_ID failed with error: ");
+call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again");
+call mtr.add_suppression("Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; .*");
#Test case 1: Try to get the value of the UNIX_TIMESTAMP from master under network disconnection
connection slave;
let $debug_saved= `select @@global.debug`;
diff --git a/mysql-test/suite/rpl/t/rpl_idempotency.test b/mysql-test/suite/rpl/t/rpl_idempotency.test
index bfd1860759e..c96b88a1b1a 100644
--- a/mysql-test/suite/rpl/t/rpl_idempotency.test
+++ b/mysql-test/suite/rpl/t/rpl_idempotency.test
@@ -8,7 +8,8 @@ connection slave;
source include/have_innodb.inc;
# Add suppression for expected warning(s) in slaves error log
-call mtr.add_suppression("Slave: Can\'t find record in \'t1\' Error_code: 1032");
+call mtr.add_suppression("Slave: Can't find record in 't.' Error_code: 1032");
+call mtr.add_suppression("Slave: Cannot delete or update a parent row: a foreign key constraint fails .* Error_code: 1451");
call mtr.add_suppression("Slave: Cannot add or update a child row: a foreign key constraint fails .* Error_code: 1452");
SET @old_slave_exec_mode= @@global.slave_exec_mode;
diff --git a/mysql-test/suite/rpl/t/rpl_init_slave_errors.test b/mysql-test/suite/rpl/t/rpl_init_slave_errors.test
index 4ca0de6ec66..180821730ec 100644
--- a/mysql-test/suite/rpl/t/rpl_init_slave_errors.test
+++ b/mysql-test/suite/rpl/t/rpl_init_slave_errors.test
@@ -57,6 +57,7 @@ source include/wait_for_slave_to_stop.inc;
let $error= query_get_value(SHOW SLAVE STATUS, Last_Error, 1);
echo Reporting the following error: $error;
+call mtr.add_suppression("Failed during slave I/O thread initialization");
SET GLOBAL debug= "";
diff --git a/mysql-test/suite/rpl/t/rpl_loaddatalocal.test b/mysql-test/suite/rpl/t/rpl_loaddatalocal.test
index 23c802ab3de..a93a82d6d9f 100644
--- a/mysql-test/suite/rpl/t/rpl_loaddatalocal.test
+++ b/mysql-test/suite/rpl/t/rpl_loaddatalocal.test
@@ -98,3 +98,73 @@ DROP TABLE t1;
--echo [on slave]
sync_slave_with_master;
+--echo
+--echo Bug #43746:
+--echo "return wrong query string when parse 'load data infile' sql statement"
+--echo
+
+--echo [master]
+connection master;
+let $MYSQLD_DATADIR= `select @@datadir`;
+SELECT @@SESSION.sql_mode INTO @old_mode;
+
+SET sql_mode='ignore_space';
+
+CREATE TABLE t1(a int);
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+eval SELECT * INTO OUTFILE '$MYSQLD_DATADIR/bug43746.sql' FROM t1;
+TRUNCATE TABLE t1;
+
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+eval LOAD DATA LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1;
+
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+eval LOAD/* look mum, with comments in weird places! */DATA/* oh hai */LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql'/* we are */INTO/* from the internets */TABLE t1;
+
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+eval LOAD DATA/*!10000 LOCAL */INFILE '$MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1;
+
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+eval LOAD DATA LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql' /*!10000 INTO */ TABLE t1;
+
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+eval LOAD DATA LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql' /*!10000 INTO TABLE */ t1;
+
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+eval LOAD DATA /*!10000 LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql' INTO TABLE */ t1;
+
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+eval LOAD DATA/*!10000 LOCAL */INFILE '$MYSQLD_DATADIR/bug43746.sql'/*!10000 INTO*/TABLE t1;
+
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+eval LOAD DATA/*!10000 LOCAL */INFILE '$MYSQLD_DATADIR/bug43746.sql'/* empty */INTO TABLE t1;
+
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+eval LOAD DATA/*!10000 LOCAL */INFILE '$MYSQLD_DATADIR/bug43746.sql' INTO/* empty */TABLE t1;
+
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+eval LOAD/*!99999 special comments that do not expand */DATA/*!99999 code from the future */LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql'/*!99999 have flux capacitor */INTO/*!99999 will travel */TABLE t1;
+
+SET sql_mode='PIPES_AS_CONCAT,ANSI_QUOTES,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER';
+
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+eval LOAD DATA LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1;
+
+--echo [slave]
+sync_slave_with_master;
+
+# cleanup
+
+--remove_file $MYSQLD_DATADIR/bug43746.sql
+
+--echo [master]
+connection master;
+DROP TABLE t1;
+SET SESSION sql_mode=@old_mode;
+
+--echo [slave]
+sync_slave_with_master;
+
+connection master;
diff --git a/mysql-test/suite/rpl/t/rpl_log_pos.test b/mysql-test/suite/rpl/t/rpl_log_pos.test
index 5e8390f97ed..48effa00b64 100644
--- a/mysql-test/suite/rpl/t/rpl_log_pos.test
+++ b/mysql-test/suite/rpl/t/rpl_log_pos.test
@@ -11,6 +11,7 @@
# Passes with rbr no problem, removed statement include [jbm]
source include/master-slave.inc;
+call mtr.add_suppression ("Slave I/O: Got fatal error 1236 from master when reading data from binary");
source include/show_master_status.inc;
sync_slave_with_master;
source include/stop_slave.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test b/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test
new file mode 100644
index 00000000000..bf5c6d2b921
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test
@@ -0,0 +1,56 @@
+#############################################################################
+# BUG#43579 mysql_upgrade tries to alter log tables on replicated database
+# Master and slave should be upgraded separately. All statements executed by
+# mysql_upgrade will not be binlogged. --write-binlog and --skip-write-binlog
+# options are added into mysql_upgrade. These options control whether sql
+# statements are binlogged or not.
+#############################################################################
+--source include/master-slave.inc
+
+# Only run test if "mysql_upgrade" is found
+--source include/have_mysql_upgrade.inc
+
+connection master;
+--disable_warnings
+DROP DATABASE IF EXISTS `#mysql50#mysqltest-1`;
+CREATE DATABASE `#mysql50#mysqltest-1`;
+--enable_warnings
+sync_slave_with_master;
+
+connection master;
+let $before_position= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+#With '--force' option, mysql_upgrade always executes all sql statements for upgrading.
+#--skip-write-binlog option disables binlog.
+--exec $MYSQL_UPGRADE --skip-write-binlog --skip-verbose --force --user=root > $MYSQLTEST_VARDIR/log/mysql_upgrade.log 2>&1
+sync_slave_with_master;
+
+connection master;
+let $after_position= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+if (`SELECT '$before_position'='$after_position'`)
+{
+ echo Master position is not changed;
+}
+
+#Some log events of the mysql_upgrade's will cause errors on slave.
+connection slave;
+STOP SLAVE SQL_THREAD;
+source include/wait_for_slave_sql_to_stop.inc;
+
+connection master;
+#With '--force' option, mysql_upgrade always executes all sql statements for upgrading.
+--exec $MYSQL_UPGRADE --skip-verbose --force --user=root > $MYSQLTEST_VARDIR/log/mysql_upgrade.log 2>&1
+
+connection master;
+let $after_file= query_get_value(SHOW MASTER STATUS, File, 1);
+let $after_position= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+if (!`SELECT '$before_position'='$after_position'`)
+{
+ echo Master position has been changed;
+}
+
+DROP DATABASE `mysqltest-1`;
+connection slave;
+DROP DATABASE `#mysql50#mysqltest-1`;
diff --git a/mysql-test/suite/rpl/t/rpl_packet.test b/mysql-test/suite/rpl/t/rpl_packet.test
index 79cb2d9d735..bfc144c759b 100644
--- a/mysql-test/suite/rpl/t/rpl_packet.test
+++ b/mysql-test/suite/rpl/t/rpl_packet.test
@@ -5,6 +5,9 @@
# max-out size db name
source include/master-slave.inc;
+source include/have_binlog_format_row.inc;
+call mtr.add_suppression("Slave I/O: Got a packet bigger than 'max_allowed_packet' bytes, Error_code: 1153");
+call mtr.add_suppression("Slave I/O: Got fatal error 1236 from master when reading data from binary log:");
let $db= DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________;
disable_warnings;
@@ -86,6 +89,35 @@ connection slave;
--source include/wait_for_slave_io_to_stop.inc
let $slave_io_running= query_get_value(SHOW SLAVE STATUS, Slave_IO_Running, 1);
--echo Slave_IO_Running = $slave_io_running (expect No)
+#
+# Bug#42914: The slave I/O thread must stop after trying to read the above
+# event, However there is no Last_IO_Error report.
+#
+let $last_io_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1);
+eval SELECT "$last_io_error" AS Last_IO_Error;
+
+#
+# Bug#42914: On the master, if a binary log event is larger than
+# max_allowed_packet, the error message ER_MASTER_FATAL_ERROR_READING_BINLOG
+# is sent to a slave when it requests a dump from the master, thus leading the
+# I/O thread to stop. However, there is no Last_IO_Error reported.
+#
+source include/master-slave-reset.inc;
+connection master;
+CREATE TABLE t1 (f1 int PRIMARY KEY, f2 LONGTEXT, f3 LONGTEXT) ENGINE=MyISAM;
+sync_slave_with_master;
+
+connection master;
+INSERT INTO t1(f1, f2, f3) VALUES(1, REPEAT('a', @@global.max_allowed_packet), REPEAT('b', @@global.max_allowed_packet));
+
+connection slave;
+# The slave I/O thread must stop after receiving
+# ER_MASTER_FATAL_ERROR_READING_BINLOG error message from master.
+--source include/wait_for_slave_io_to_stop.inc
+let $slave_io_running= query_get_value(SHOW SLAVE STATUS, Slave_IO_Running, 1);
+--echo Slave_IO_Running = $slave_io_running (expect No)
+let $last_io_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1);
+eval SELECT "$last_io_error" AS Last_IO_Error;
--echo ==== clean up ====
connection master;
diff --git a/mysql-test/suite/rpl/t/rpl_row_disabled_slave_key.test b/mysql-test/suite/rpl/t/rpl_row_disabled_slave_key.test
new file mode 100644
index 00000000000..1d7e134f4f4
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_row_disabled_slave_key.test
@@ -0,0 +1,73 @@
+# BUG#47312: RBR: Disabling key on slave breaks replication:
+# HA_ERR_WRONG_INDEX
+#
+# Description
+# ===========
+#
+# This test case checks whether disabling a key on a slave breaks
+# replication or not.
+#
+# Case #1, shows that while not using ALTER TABLE... DISABLE KEYS and
+# the slave has no key defined while the master has one, replication
+# won't break.
+#
+# Case #2, shows that before patch for BUG#47312, if defining key on
+# slave table, and later disable it, replication would break. This
+# has been fixed.
+#
+
+-- source include/master-slave.inc
+-- source include/have_binlog_format_row.inc
+
+#
+# Case #1: master has key, but slave has not.
+# Replication does not break.
+#
+
+SET SQL_LOG_BIN=0;
+CREATE TABLE t (a int, b int, c int, key(b));
+SET SQL_LOG_BIN=1;
+
+-- connection slave
+
+CREATE TABLE t (a int, b int, c int);
+
+-- connection master
+
+INSERT INTO t VALUES (1,2,4);
+INSERT INTO t VALUES (4,3,4);
+DELETE FROM t;
+
+-- sync_slave_with_master
+
+-- connection master
+DROP TABLE t;
+
+-- sync_slave_with_master
+
+#
+# Case #2: master has key, slave also has one,
+# but it gets disabled sometime.
+# Replication does not break anymore.
+#
+-- source include/master-slave-reset.inc
+-- connection master
+
+CREATE TABLE t (a int, b int, c int, key(b));
+
+-- sync_slave_with_master
+
+ALTER TABLE t DISABLE KEYS;
+
+-- connection master
+
+INSERT INTO t VALUES (1,2,4);
+INSERT INTO t VALUES (4,3,4);
+DELETE FROM t;
+
+-- sync_slave_with_master
+
+-- connection master
+DROP TABLE t;
+
+-- sync_slave_with_master
diff --git a/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test b/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test
index 39f3b700f94..437e1ebb92d 100644
--- a/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test
+++ b/mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test
@@ -7,6 +7,7 @@
# 1 - Creates a table and populates it through "LOAD DATA INFILE".
# 2 - Catches error.
##########################################################################
+
--source include/have_binlog_format_mixed_or_statement.inc
--source include/have_innodb.inc
--source include/have_debug.inc
@@ -47,3 +48,5 @@ drop table t1;
connection slave;
drop table t1;
+
+call mtr.add_suppression("Slave: Error writing file 'UNKNOWN' .Errcode: 9. Error_code: 3");
diff --git a/mysql-test/suite/rpl/t/rpl_temporary_errors.test b/mysql-test/suite/rpl/t/rpl_temporary_errors.test
index 3b373e00a62..ad0e6174c54 100644
--- a/mysql-test/suite/rpl/t/rpl_temporary_errors.test
+++ b/mysql-test/suite/rpl/t/rpl_temporary_errors.test
@@ -31,3 +31,12 @@ DROP TABLE t1;
--echo **** On Master ****
connection master;
DROP TABLE t1;
+
+# We must wait for the slave to stop.
+# Otherwise the warnings in the error log about deadlock may be written to
+# the error log only during shutdown, and currently the suppression of
+# "Deadlock found" set in this test case is not effective during server
+# shutdown.
+connection slave;
+STOP SLAVE;
+--source include/wait_for_slave_to_stop.inc
diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_circular_simplex.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_circular_simplex.result
index 01f8d94da48..b6f32668c42 100644
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_circular_simplex.result
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_circular_simplex.result
@@ -102,3 +102,4 @@ Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 0
Last_SQL_Error
+DROP TABLE t1;
diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result
index d51599fd18b..f812509de6f 100644
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result
@@ -4,6 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+call mtr.add_suppression("Slave: Unknown table 't6' Error_code: 1051");
**** Diff Table Def Start ****
*** On Slave ***
STOP SLAVE;
diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_sp006.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_sp006.result
index 482d43c8f10..047402f826f 100644
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_sp006.result
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_sp006.result
@@ -4,21 +4,20 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
-create database if not exists mysqltest1;
-DROP PROCEDURE IF EXISTS mysqltest1.p1;
-DROP PROCEDURE IF EXISTS mysqltest1.p2;
-DROP TABLE IF EXISTS mysqltest1.t2;
-DROP TABLE IF EXISTS mysqltest1.t1;
-CREATE TABLE IF NOT EXISTS mysqltest1.t1(name CHAR(16), birth DATE,PRIMARY KEY(name))ENGINE=NDBCLUSTER;
-CREATE TABLE IF NOT EXISTS mysqltest1.t2(name CHAR(16), age INT ,PRIMARY KEY(name))ENGINE=NDBCLUSTER;
-CREATE PROCEDURE mysqltest1.p1()
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+CREATE TABLE IF NOT EXISTS t1(name CHAR(16), birth DATE,PRIMARY KEY(name))ENGINE=NDBCLUSTER;
+CREATE TABLE IF NOT EXISTS t2(name CHAR(16), age INT ,PRIMARY KEY(name))ENGINE=NDBCLUSTER;
+CREATE PROCEDURE p1()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE spa CHAR(16);
DECLARE spb INT;
DECLARE cur1 CURSOR FOR SELECT name,
(YEAR(CURDATE())-YEAR(birth))-(RIGHT(CURDATE(),5)<RIGHT(birth,5))
-FROM mysqltest1.t1;
+FROM t1;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
OPEN cur1;
SET AUTOCOMMIT=0;
@@ -26,21 +25,20 @@ REPEAT
FETCH cur1 INTO spa, spb;
IF NOT done THEN
START TRANSACTION;
-INSERT INTO mysqltest1.t2 VALUES (spa,spb);
+INSERT INTO t2 VALUES (spa,spb);
COMMIT;
END IF;
UNTIL done END REPEAT;
SET AUTOCOMMIT=1;
CLOSE cur1;
END|
-CREATE PROCEDURE mysqltest1.p2()
+CREATE PROCEDURE p2()
BEGIN
-INSERT INTO mysqltest1.t1 VALUES ('MySQL','1993-02-04'),('ROCKS', '1990-08-27'),('Texas', '1999-03-30'),('kyle','2005-1-1');
+INSERT INTO t1 VALUES ('MySQL','1993-02-04'),('ROCKS', '1990-08-27'),('Texas', '1999-03-30'),('kyle','2005-1-1');
END|
-CALL mysqltest1.p2();
-CALL mysqltest1.p1();
-DROP PROCEDURE IF EXISTS mysqltest1.p1;
-DROP PROCEDURE IF EXISTS mysqltest1.p2;
-DROP TABLE IF EXISTS mysqltest1.t1;
-DROP TABLE IF EXISTS mysqltest1.t2;
-DROP DATABASE mysqltest1;
+CALL p2();
+CALL p1();
+DROP TABLE t1;
+DROP TABLE t2;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
diff --git a/mysql-test/suite/rpl_ndb/t/rpl_ndb_circular.test b/mysql-test/suite/rpl_ndb/t/rpl_ndb_circular.test
index 2cc46e2420e..7b8497d8dab 100644
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_circular.test
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_circular.test
@@ -58,3 +58,4 @@ STOP SLAVE;
# cleanup
--connection master
DROP TABLE t1;
+-- sync_slave_with_master
diff --git a/mysql-test/suite/rpl_ndb/t/rpl_ndb_circular_simplex.test b/mysql-test/suite/rpl_ndb/t/rpl_ndb_circular_simplex.test
index d5ddfc2b739..eb04dc2e260 100644
--- a/mysql-test/suite/rpl_ndb/t/rpl_ndb_circular_simplex.test
+++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_circular_simplex.test
@@ -78,3 +78,7 @@ SELECT * FROM t1 ORDER BY a;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # 35 # 36 #
query_vertical SHOW SLAVE STATUS;
+
+-- connection master
+DROP TABLE t1;
+-- sync_slave_with_master
diff --git a/mysql-test/t/almost_full.test b/mysql-test/t/almost_full.test
index c192a7c1cd4..2517008fdf8 100644
--- a/mysql-test/t/almost_full.test
+++ b/mysql-test/t/almost_full.test
@@ -2,6 +2,8 @@
# Some special cases with empty tables
#
+call mtr.add_suppression("The table 't1' is full");
+
--disable_warnings
drop table if exists t1;
--enable_warnings
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index efda5fc1893..98ae90ce13c 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -1027,5 +1027,65 @@ INSERT INTO t1 (a) VALUES (11);
SELECT * FROM t1 ORDER BY a;
DROP TABLE t1;
SET @@sql_mode=@save_sql_mode;
+--echo #
+--echo # Bug#45567: Fast ALTER TABLE broken for enum and set
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a ENUM('a1','a2'));
+INSERT INTO t1 VALUES ('a1'),('a2');
+--enable_info
+--echo # No copy: No modification
+ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2');
+--echo # No copy: Add new enumeration to the end
+ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','a3');
+--echo # Copy: Modify and add new to the end
+ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','xx','a5');
+--echo # Copy: Remove from the end
+ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','xx');
+--echo # Copy: Add new enumeration
+ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','a0','xx');
+--echo # No copy: Add new enumerations to the end
+ALTER TABLE t1 MODIFY COLUMN a ENUM('a1','a2','a0','xx','a5','a6');
+--disable_info
+DROP TABLE t1;
+
+CREATE TABLE t1 (a SET('a1','a2'));
+INSERT INTO t1 VALUES ('a1'),('a2');
+--enable_info
+--echo # No copy: No modification
+ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2');
+--echo # No copy: Add new to the end
+ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a3');
+--echo # Copy: Modify and add new to the end
+ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','xx','a5');
+--echo # Copy: Remove from the end
+ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','xx');
+--echo # Copy: Add new member
+ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a0','xx');
+--echo # No copy: Add new to the end
+ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a0','xx','a5','a6');
+--echo # Copy: Numerical incrase (pack lenght)
+ALTER TABLE t1 MODIFY COLUMN a SET('a1','a2','a0','xx','a5','a6','a7','a8','a9','a10');
+--disable_info
+DROP TABLE t1;
+
+#
+# Bug#43508: Renaming timestamp or date column triggers table copy
+#
+
+CREATE TABLE t1 (f1 TIMESTAMP NULL DEFAULT NULL,
+ f2 INT(11) DEFAULT NULL) ENGINE=MYISAM DEFAULT CHARSET=utf8;
+
+INSERT INTO t1 VALUES (NULL, NULL), ("2009-10-09 11:46:19", 2);
+
+--echo this should affect no rows as there is no real change
+--enable_info
+ALTER TABLE t1 CHANGE COLUMN f1 f1_no_real_change TIMESTAMP NULL DEFAULT NULL;
+--disable_info
+DROP TABLE t1;
--echo End of 5.1 tests
diff --git a/mysql-test/t/analyse.test b/mysql-test/t/analyse.test
index d8466df14bf..05f739bfd69 100644
--- a/mysql-test/t/analyse.test
+++ b/mysql-test/t/analyse.test
@@ -10,37 +10,14 @@ insert into t1 values (1,2,"","Y","2002-03-03"), (3,4,"","N","2002-03-04"), (5,6
select count(*) from t1 procedure analyse();
select * from t1 procedure analyse();
select * from t1 procedure analyse(2);
+--error ER_WRONG_USAGE
create table t2 select * from t1 procedure analyse();
-select * from t2;
-drop table t1,t2;
+drop table t1;
--error ER_WRONG_USAGE
EXPLAIN SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE();
#
-# Test with impossible where
-#
-create table t1 (a int not null);
-create table t2 select * from t1 where 0=1 procedure analyse();
-show create table t2;
-select * from t1 where 0=1 procedure analyse();
-insert into t1 values(1);
-drop table t2;
-create table t2 select * from t1 where 0=1 procedure analyse();
-show create table t2;
-select * from t2;
-insert into t2 select * from t1 procedure analyse();
-select * from t2;
-insert into t1 values(2);
-drop table t2;
-create table t2 select * from t1 where 0=1 procedure analyse();
-show create table t2;
-select * from t2;
-insert into t2 select * from t1 procedure analyse();
-select * from t2;
-drop table t1,t2;
-
-#
# Bug#2813 - analyse does not quote string values in enums from string
#
@@ -113,3 +90,46 @@ SELECT * FROM (SELECT * FROM t1) d PROCEDURE ANALYSE();
DROP TABLE t1;
--echo End of 4.1 tests
+
+--echo #
+--echo # Bug #48293: crash with procedure analyse, view with > 10 columns,
+--echo # having clause...
+--echo #
+
+CREATE TABLE t1(a INT, b INT, c INT, d INT, e INT,
+ f INT, g INT, h INT, i INT, j INT,k INT);
+INSERT INTO t1 VALUES (),();
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+--echo #should have a derived table
+EXPLAIN SELECT * FROM v1;
+--echo #should not crash
+--error ER_WRONG_USAGE
+SELECT * FROM v1 PROCEDURE analyse();
+--echo #should not crash
+--error ER_WRONG_USAGE
+SELECT * FROM t1 a, v1, t1 b PROCEDURE analyse();
+--echo #should not crash
+--error ER_WRONG_USAGE
+SELECT * FROM (SELECT * FROM t1 having a > 1) x PROCEDURE analyse();
+--echo #should not crash
+--error ER_WRONG_USAGE
+SELECT * FROM t1 a, (SELECT * FROM t1 having a > 1) x, t1 b PROCEDURE analyse();
+--echo #should not crash
+--error ER_ORDER_WITH_PROC
+SELECT 1 FROM t1 group by a having a > 1 order by 1 PROCEDURE analyse();
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1),(2);
+
+--echo # should not crash
+--error ER_WRONG_USAGE
+CREATE TABLE t2 SELECT 1 FROM t1, t1 t3 GROUP BY t3.a PROCEDURE ANALYSE();
+
+DROP TABLE t1;
+
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test
index 5864e539b08..9f67547f729 100644
--- a/mysql-test/t/archive.test
+++ b/mysql-test/t/archive.test
@@ -1601,3 +1601,27 @@ INSERT INTO t1 VALUES (NULL, NULL),(NULL, NULL);
FLUSH TABLE t1;
SELECT * FROM t1 ORDER BY a;
DROP TABLE t1;
+
+#
+# BUG#29203 - archive tables have weird values in show table status
+#
+CREATE TABLE t1(a INT, b BLOB) ENGINE=archive;
+SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM
+ INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test';
+INSERT INTO t1 VALUES(1, 'sampleblob1'),(2, 'sampleblob2');
+SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM
+ INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test';
+DROP TABLE t1;
+
+#
+# BUG#46961 - archive engine loses rows during self joining select!
+#
+SET @save_join_buffer_size= @@join_buffer_size;
+SET @@join_buffer_size= 8228;
+CREATE TABLE t1(a CHAR(255)) ENGINE=archive;
+INSERT INTO t1 VALUES('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
+ ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
+ ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
+SELECT COUNT(t1.a) FROM t1, t1 a, t1 b, t1 c, t1 d, t1 e;
+DROP TABLE t1;
+SET @@join_buffer_size= @save_join_buffer_size;
diff --git a/mysql-test/t/bug40113.test b/mysql-test/t/bug40113.test
deleted file mode 100644
index 6d35d0b73d3..00000000000
--- a/mysql-test/t/bug40113.test
+++ /dev/null
@@ -1,46 +0,0 @@
---source include/have_innodb.inc
-
---echo #
---echo # Bug #40113: Embedded SELECT inside UPDATE or DELETE can timeout
---echo # without error
---echo #
-
-CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b)) ENGINE=InnoDB;
-
-INSERT INTO t1 (a,b) VALUES (1070109,99);
-
-CREATE TABLE t2 (b int, a int, PRIMARY KEY (b)) ENGINE=InnoDB;
-
-INSERT INTO t2 (b,a) VALUES (7,1070109);
-
-SELECT * FROM t1;
-
-BEGIN;
-
-SELECT b FROM t2 WHERE b=7 FOR UPDATE;
-
-CONNECT (addconroot, localhost, root,,);
-CONNECTION addconroot;
-
-BEGIN;
-
---error ER_LOCK_WAIT_TIMEOUT
-SELECT b FROM t2 WHERE b=7 FOR UPDATE;
-
---error ER_LOCK_WAIT_TIMEOUT
-INSERT INTO t1 (a) VALUES ((SELECT a FROM t2 WHERE b=7));
-
---error ER_LOCK_WAIT_TIMEOUT
-UPDATE t1 SET a='7000000' WHERE a=(SELECT a FROM t2 WHERE b=7);
-
---error ER_LOCK_WAIT_TIMEOUT
-DELETE FROM t1 WHERE a=(SELECT a FROM t2 WHERE b=7);
-
-SELECT * FROM t1;
-
-CONNECTION default;
-DISCONNECT addconroot;
-
-DROP TABLE t2, t1;
-
---echo End of 5.0 tests
diff --git a/mysql-test/t/bug46080.test b/mysql-test/t/bug46080.test
index 7e56e3ce421..8b4cee4d8b0 100644
--- a/mysql-test/t/bug46080.test
+++ b/mysql-test/t/bug46080.test
@@ -3,6 +3,9 @@
--echo # sort_buffer_size cannot allocate
--echo #
+call mtr.add_suppression("Out of memory at line .*, 'my_alloc.c'");
+call mtr.add_suppression("needed .* byte .*k., memory in use: .* bytes .*k");
+
CREATE TABLE t1(a CHAR(255));
INSERT INTO t1 VALUES ('a');
diff --git a/mysql-test/t/bug46760-master.opt b/mysql-test/t/bug46760-master.opt
new file mode 100644
index 00000000000..f830d135149
--- /dev/null
+++ b/mysql-test/t/bug46760-master.opt
@@ -0,0 +1,2 @@
+--innodb-lock-wait-timeout=2
+--innodb-file-per-table
diff --git a/mysql-test/t/bug46760.test b/mysql-test/t/bug46760.test
new file mode 100644
index 00000000000..f55edbbfa42
--- /dev/null
+++ b/mysql-test/t/bug46760.test
@@ -0,0 +1,38 @@
+-- source include/have_innodb.inc
+
+--echo #
+--echo # Bug#46760: Fast ALTER TABLE no longer works for InnoDB
+--echo #
+
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+
+--echo # By using --enable_info and verifying that number of affected
+--echo # rows is 0 we check that this ALTER TABLE is really carried
+--echo # out as "fast/online" operation, i.e. without full-blown data
+--echo # copying.
+--echo #
+--echo # I.e. info for the below statement should normally look like:
+--echo #
+--echo # affected rows: 0
+--echo # info: Records: 0 Duplicates: 0 Warnings: 0
+
+--enable_info
+ALTER TABLE t1 ALTER COLUMN a SET DEFAULT 10;
+--disable_info
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
+--echo #
+--echo # MySQL Bug#39200: optimize table does not recognize
+--echo # ROW_FORMAT=COMPRESSED
+--echo #
+
+CREATE TABLE t1 (a INT) ROW_FORMAT=compressed;
+SHOW CREATE TABLE t1;
+OPTIMIZE TABLE t1;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index 63968caed94..885803cb90f 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -1198,6 +1198,23 @@ CREATE TABLE IF NOT EXISTS t2 (a INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY)
DROP TABLE t1, t2;
+--echo #
+--echo # BUG#46384 - mysqld segfault when trying to create table with same
+--echo # name as existing view
+--echo #
+
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+
+INSERT INTO t1 VALUES (1),(2),(3);
+INSERT INTO t2 VALUES (1),(2),(3);
+
+CREATE VIEW v1 AS SELECT t1.a FROM t1, t2;
+--error ER_TABLE_EXISTS_ERROR
+CREATE TABLE v1 AS SELECT * FROM t1;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
--echo End of 5.0 tests
diff --git a/mysql-test/t/ctype_ldml.test b/mysql-test/t/ctype_ldml.test
index db9461bfbf7..0395de273de 100644
--- a/mysql-test/t/ctype_ldml.test
+++ b/mysql-test/t/ctype_ldml.test
@@ -38,6 +38,14 @@ SELECT * FROM t1 WHERE col1=col2 ORDER BY col1;
DROP TABLE t1;
--echo #
+--echo # Bug#45645 Mysql server close all connection and restart using lower function
+--echo #
+CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET utf8 COLLATE utf8_test_ci;
+INSERT INTO t1 (a) VALUES ('hello!');
+SELECT * FROM t1 WHERE LOWER(a)=LOWER('N');
+DROP TABLE t1;
+
+--echo #
--echo # Bug#43827 Server closes connections and restarts
--echo #
# Crash happened with a user-defined utf8 collation,
@@ -86,3 +94,8 @@ select hex(c1) as h, c1 from t1 order by c1, h;
select group_concat(hex(c1) order by hex(c1)) from t1 group by c1;
select group_concat(c1 order by hex(c1) SEPARATOR '') from t1 group by c1;
drop table t1;
+
+--echo Bug#46448 trailing spaces are not ignored when user collation maps space != 0x20
+set names latin1;
+show collation like 'latin1_test';
+select "foo" = "foo " collate latin1_test;
diff --git a/mysql-test/t/ctype_uca.test b/mysql-test/t/ctype_uca.test
index 11a489ba24d..96831c8c915 100644
--- a/mysql-test/t/ctype_uca.test
+++ b/mysql-test/t/ctype_uca.test
@@ -186,6 +186,7 @@ insert into t1 values (_ucs2 0x01fc),(_ucs2 0x01fd),(_ucs2 0x01fe),(_ucs2 0x01ff
insert into t1 values ('AA'),('Aa'),('aa'),('aA');
insert into t1 values ('CH'),('Ch'),('ch'),('cH');
insert into t1 values ('DZ'),('Dz'),('dz'),('dZ');
+insert into t1 values ('DŽ'),('Dž'),('dž'),('dŽ');
insert into t1 values ('IJ'),('Ij'),('ij'),('iJ');
insert into t1 values ('LJ'),('Lj'),('lj'),('lJ');
insert into t1 values ('LL'),('Ll'),('ll'),('lL');
@@ -213,6 +214,7 @@ select group_concat(c1 order by c1) from t1 group by c1 collate utf8_spanish2_ci
select group_concat(c1 order by c1) from t1 group by c1 collate utf8_roman_ci;
select group_concat(c1 order by c1) from t1 group by c1 collate utf8_esperanto_ci;
select group_concat(c1 order by c1) from t1 group by c1 collate utf8_hungarian_ci;
+select group_concat(c1 order by c1) from t1 group by c1 collate utf8_croatian_ci;
drop table t1;
diff --git a/mysql-test/t/debug_sync.test b/mysql-test/t/debug_sync.test
new file mode 100644
index 00000000000..514e471b603
--- /dev/null
+++ b/mysql-test/t/debug_sync.test
@@ -0,0 +1,420 @@
+###################### t/debug_sync.test ###############################
+# #
+# Testing of the Debug Sync Facility. #
+# #
+# There is important documentation within sql/debug_sync.cc #
+# #
+# Used objects in this test case: #
+# p0 - synchronization point 0. Non-existent dummy sync point. #
+# s1 - signal 1. #
+# s2 - signal 2. #
+# #
+# Creation: #
+# 2008-02-18 istruewing #
+# #
+########################################################################
+
+#
+# We need the Debug Sync Facility.
+#
+--source include/have_debug_sync.inc
+
+#
+# We are checking privileges, which the embedded server cannot do.
+#
+--source include/not_embedded.inc
+
+#
+# Preparative cleanup.
+#
+--disable_warnings
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+#
+# Show the special system variable.
+# It shows ON or OFF depending on the command line option --debug-sync.
+# The test case assumes it is ON (command line option present).
+#
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+
+#
+# Syntax. Valid forms.
+#
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 EXECUTE 2 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 EXECUTE 2';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2';
+SET DEBUG_SYNC='p0 SIGNAL s1 EXECUTE 2 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 SIGNAL s1 EXECUTE 2';
+SET DEBUG_SYNC='p0 SIGNAL s1 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 SIGNAL s1';
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2';
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 6 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 6';
+SET DEBUG_SYNC='p0 WAIT_FOR s2 EXECUTE 2 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 WAIT_FOR s2 EXECUTE 2';
+SET DEBUG_SYNC='p0 WAIT_FOR s2 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 WAIT_FOR s2';
+SET DEBUG_SYNC='p0 HIT_LIMIT 3';
+SET DEBUG_SYNC='p0 CLEAR';
+SET DEBUG_SYNC='p0 TEST';
+SET DEBUG_SYNC='RESET';
+
+#
+# Syntax. Valid forms. Lower case.
+#
+set debug_sync='p0 signal s1 wait_for s2 timeout 6 execute 2 hit_limit 3';
+set debug_sync='p0 signal s1 wait_for s2 timeout 6 execute 2';
+set debug_sync='p0 signal s1 wait_for s2 timeout 6 hit_limit 3';
+set debug_sync='p0 signal s1 wait_for s2 timeout 6';
+set debug_sync='p0 signal s1 wait_for s2 execute 2 hit_limit 3';
+set debug_sync='p0 signal s1 wait_for s2 execute 2';
+set debug_sync='p0 signal s1 wait_for s2 hit_limit 3';
+set debug_sync='p0 signal s1 wait_for s2';
+set debug_sync='p0 signal s1 execute 2 hit_limit 3';
+set debug_sync='p0 signal s1 execute 2';
+set debug_sync='p0 signal s1 hit_limit 3';
+set debug_sync='p0 signal s1';
+set debug_sync='p0 wait_for s2 timeout 6 execute 2 hit_limit 3';
+set debug_sync='p0 wait_for s2 timeout 6 execute 2';
+set debug_sync='p0 wait_for s2 timeout 6 hit_limit 3';
+set debug_sync='p0 wait_for s2 timeout 6';
+set debug_sync='p0 wait_for s2 execute 2 hit_limit 3';
+set debug_sync='p0 wait_for s2 execute 2';
+set debug_sync='p0 wait_for s2 hit_limit 3';
+set debug_sync='p0 wait_for s2';
+set debug_sync='p0 hit_limit 3';
+set debug_sync='p0 clear';
+set debug_sync='p0 test';
+set debug_sync='reset';
+
+#
+# Syntax. Valid forms. Line wrap, leading, mid, trailing space.
+#
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6
+ EXECUTE 2 HIT_LIMIT 3';
+SET DEBUG_SYNC=' p0 SIGNAL s1 WAIT_FOR s2';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2';
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 ';
+SET DEBUG_SYNC=' p0 SIGNAL s1 WAIT_FOR s2 ';
+SET DEBUG_SYNC=' p0 SIGNAL s1 WAIT_FOR s2 ';
+
+#
+# Syntax. Invalid forms.
+#
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC=' ';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 EXECUTE 2';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 TIMEOUT 6 EXECUTE 2';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 TIMEOUT 6';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 WAIT_FOR s2 SIGNAL s1';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 WAIT_FOR s2 SIGNAL s1 EXECUTE 2';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 WAIT_FOR s2 SIGNAL s1 TIMEOUT 6 EXECUTE 2';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 WAIT_FOR s2 SIGNAL s1 TIMEOUT 6';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 6 SIGNAL s1 EXECUTE 2';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 6 SIGNAL s1';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 TIMEOUT 6 WAIT_FOR s2 EXECUTE 2';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 TIMEOUT 6 WAIT_FOR s2';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 SIGNAL s1 TIMEOUT 6 EXECUTE 2';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 SIGNAL s1 TIMEOUT 6';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 EXECUTE 2 SIGNAL s1 TIMEOUT 6';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 TIMEOUT 6 SIGNAL s1';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 EXECUTE 2 TIMEOUT 6 SIGNAL s1';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 CLEAR HIT_LIMIT 3';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='CLEAR';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 CLEAR p0';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='TEST';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 TEST p0';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 RESET';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='RESET p0';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 RESET p0';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 SIGNAL ';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 WAIT_FOR ';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 SIGNAL s1 EXECUTE ';
+
+#
+# Syntax. Invalid keywords used.
+#
+--error ER_UNKNOWN_SYSTEM_VARIABLE
+SET DEBUG_SYNCx='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2 HIT_LIMIT 3';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 SIGNAx s1 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2 HIT_LIMIT 3';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOx s2 TIMEOUT 6 EXECUTE 2 HIT_LIMIT 3';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUx 0 EXECUTE 2 HIT_LIMIT 3';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 EXECUTx 2 HIT_LIMIT 3';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 SIGNAL s1 WAIT_FOR s2 TIMEOUT 6 EXECUTE 2 HIT_LIMIx 3';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 CLEARx';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 TESTx';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='RESETx';
+
+#
+# Syntax. Invalid numbers. Decimal only.
+#
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 0x6 EXECUTE 2 HIT_LIMIT 3';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 6 EXECUTE 0x2 HIT_LIMIT 3';
+--error ER_PARSE_ERROR
+SET DEBUG_SYNC='p0 WAIT_FOR s2 TIMEOUT 7 EXECUTE 2 HIT_LIMIT 0x3';
+
+#
+# Syntax. Invalid value type.
+#
+--error ER_WRONG_TYPE_FOR_VAR
+SET DEBUG_SYNC= 7;
+
+#
+# Syntax. DEBUG_SYNC is a SESSION-only variable.
+#
+--error ER_LOCAL_VARIABLE
+SET GLOBAL DEBUG_SYNC= 'p0 CLEAR';
+
+#
+# Syntax. The variable value does not need to be a string literal.
+#
+SET @myvar= 'now SIGNAL from_myvar';
+SET DEBUG_SYNC= @myvar;
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+#
+SET DEBUG_SYNC= LEFT('now SIGNAL from_function_cut_here', 24);
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+
+#
+# Functional tests.
+#
+# NOTE: There is the special synchronization point 'now'. It is placed
+# immediately after setting of the DEBUG_SYNC variable.
+# So it is executed before the SET statement ends.
+#
+# NOTE: There is only one global signal (say "signal post" or "flag mast").
+# A SIGNAL action writes its signal into it ("sets a flag").
+# The signal persists until explicitly overwritten.
+# To avoid confusion for later tests, it is recommended to clear
+# the signal by signalling "empty" ("setting the 'empty' flag"):
+# SET DEBUG_SYNC= 'now SIGNAL empty';
+# Preferably you can reset the whole facility with:
+# SET DEBUG_SYNC= 'RESET';
+# The signal is then '' (really empty) which connot be done otherwise.
+#
+
+#
+# Time out immediately. This gives just a warning.
+#
+SET DEBUG_SYNC= 'now SIGNAL something';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+# Suppress warning number
+--replace_column 2 ####
+SET DEBUG_SYNC= 'now WAIT_FOR nothing TIMEOUT 0';
+#
+# If signal is present already, TIMEOUT 0 does not give a warning.
+#
+SET DEBUG_SYNC= 'now SIGNAL nothing';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+SET DEBUG_SYNC= 'now WAIT_FOR nothing TIMEOUT 0';
+
+#
+# EXECUTE 0 is effectively a no-op.
+#
+SET DEBUG_SYNC= 'now SIGNAL something EXECUTE 0';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+SET DEBUG_SYNC= 'now WAIT_FOR anotherthing TIMEOUT 0 EXECUTE 0';
+
+#
+# Run into HIT_LIMIT. This gives an error.
+#
+--error ER_DEBUG_SYNC_HIT_LIMIT
+SET DEBUG_SYNC= 'now HIT_LIMIT 1';
+
+#
+# Many actions. Watch the array growing and shrinking in the debug trace:
+# egrep 'query:|debug_sync_action:' mysql-test/var/log/master.trace
+#
+SET DEBUG_SYNC= 'RESET';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+SET DEBUG_SYNC= 'p1abcd SIGNAL s1 EXECUTE 2';
+SET DEBUG_SYNC= 'p2abc SIGNAL s2 EXECUTE 2';
+SET DEBUG_SYNC= 'p9abcdef SIGNAL s9 EXECUTE 2';
+SET DEBUG_SYNC= 'p4a SIGNAL s4 EXECUTE 2';
+SET DEBUG_SYNC= 'p5abcde SIGNAL s5 EXECUTE 2';
+SET DEBUG_SYNC= 'p6ab SIGNAL s6 EXECUTE 2';
+SET DEBUG_SYNC= 'p7 SIGNAL s7 EXECUTE 2';
+SET DEBUG_SYNC= 'p8abcdef SIGNAL s8 EXECUTE 2';
+SET DEBUG_SYNC= 'p3abcdef SIGNAL s3 EXECUTE 2';
+#
+# Execute some actions to show they exist. Each sets a distinct signal.
+#
+SET DEBUG_SYNC= 'p4a TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+SET DEBUG_SYNC= 'p1abcd TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+SET DEBUG_SYNC= 'p7 TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+SET DEBUG_SYNC= 'p9abcdef TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+SET DEBUG_SYNC= 'p3abcdef TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+#
+# Clear the actions.
+#
+SET DEBUG_SYNC= 'p1abcd CLEAR';
+SET DEBUG_SYNC= 'p2abc CLEAR';
+SET DEBUG_SYNC= 'p5abcde CLEAR';
+SET DEBUG_SYNC= 'p6ab CLEAR';
+SET DEBUG_SYNC= 'p8abcdef CLEAR';
+SET DEBUG_SYNC= 'p9abcdef CLEAR';
+SET DEBUG_SYNC= 'p3abcdef CLEAR';
+SET DEBUG_SYNC= 'p4a CLEAR';
+SET DEBUG_SYNC= 'p7 CLEAR';
+#
+# Execute some actions to show they have gone.
+#
+SET DEBUG_SYNC= 'p1abcd TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+SET DEBUG_SYNC= 'p7 TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+SET DEBUG_SYNC= 'p9abcdef TEST';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+#
+# Now cleanup. Actions are clear already, but signal needs to be cleared.
+#
+SET DEBUG_SYNC= 'RESET';
+SHOW VARIABLES LIKE 'DEBUG_SYNC';
+
+#
+# Facility requires SUPER privilege.
+#
+CREATE USER mysqltest_1@localhost;
+GRANT SUPER ON *.* TO mysqltest_1@localhost;
+--echo connection con1, mysqltest_1
+connect (con1,localhost,mysqltest_1,,);
+SET DEBUG_SYNC= 'RESET';
+disconnect con1;
+--echo connection default
+connection default;
+DROP USER mysqltest_1@localhost;
+#
+CREATE USER mysqltest_2@localhost;
+GRANT ALL ON *.* TO mysqltest_2@localhost;
+REVOKE SUPER ON *.* FROM mysqltest_2@localhost;
+--echo connection con1, mysqltest_2
+connect (con1,localhost,mysqltest_2,,);
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+SET DEBUG_SYNC= 'RESET';
+disconnect con1;
+--echo connection default
+connection default;
+DROP USER mysqltest_2@localhost;
+
+#
+# Example 1.
+#
+# Preparative cleanup.
+--disable_warnings
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+#
+# Test.
+CREATE TABLE t1 (c1 INT);
+ --echo connection con1
+ connect (con1,localhost,root,,);
+ SET DEBUG_SYNC= 'before_lock_tables_takes_lock
+ SIGNAL opened WAIT_FOR flushed';
+ send INSERT INTO t1 VALUES(1);
+--echo connection default
+connection default;
+SET DEBUG_SYNC= 'now WAIT_FOR opened';
+SET DEBUG_SYNC= 'after_flush_unlock SIGNAL flushed';
+FLUSH TABLE t1;
+ --echo connection con1
+ connection con1;
+ reap;
+ disconnect con1;
+--echo connection default
+connection default;
+DROP TABLE t1;
+
+#
+# Example 2.
+#
+# Preparative cleanup.
+--disable_warnings
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+#
+# Test.
+CREATE TABLE t1 (c1 INT);
+LOCK TABLE t1 WRITE;
+ --echo connection con1
+ connect (con1,localhost,root,,);
+ # Retain action after use. First used by general_log.
+ SET DEBUG_SYNC= 'wait_for_lock SIGNAL locked EXECUTE 2';
+ send INSERT INTO t1 VALUES (1);
+--echo connection default
+connection default;
+# Wait until INSERT waits for lock.
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+# let INSERT continue.
+UNLOCK TABLES;
+ --echo connection con1
+ connection con1;
+ --echo retrieve INSERT result.
+ reap;
+ disconnect con1;
+--echo connection default
+connection default;
+DROP TABLE t1;
+
+#
+# Cleanup after test case.
+# Otherwise signal would contain 'flushed' here,
+# which could confuse the next test.
+#
+SET DEBUG_SYNC= 'RESET';
+
diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test
index 602e30687c8..d77f5eb128b 100644
--- a/mysql-test/t/delete.test
+++ b/mysql-test/t/delete.test
@@ -292,3 +292,47 @@ DROP TABLE t1;
DROP FUNCTION f1;
--echo End of 5.0 tests
+
+--echo #
+--echo # Bug#46958: Assertion in Diagnostics_area::set_ok_status, trigger,
+--echo # merge table
+--echo #
+CREATE TABLE t1 ( a INT );
+CREATE TABLE t2 ( a INT );
+CREATE TABLE t3 ( a INT );
+
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1), (2);
+INSERT INTO t3 VALUES (1), (2);
+
+CREATE TRIGGER tr1 BEFORE DELETE ON t2
+FOR EACH ROW INSERT INTO no_such_table VALUES (1);
+
+--error ER_NO_SUCH_TABLE
+DELETE t1, t2, t3 FROM t1, t2, t3;
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+SELECT * FROM t3;
+
+DROP TABLE t1, t2, t3;
+
+CREATE TABLE t1 ( a INT );
+CREATE TABLE t2 ( a INT );
+CREATE TABLE t3 ( a INT );
+
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1), (2);
+INSERT INTO t3 VALUES (1), (2);
+
+CREATE TRIGGER tr1 AFTER DELETE ON t2
+FOR EACH ROW INSERT INTO no_such_table VALUES (1);
+
+--error ER_NO_SUCH_TABLE
+DELETE t1, t2, t3 FROM t1, t2, t3;
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+SELECT * FROM t3;
+
+DROP TABLE t1, t2, t3;
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 5436b7166f4..ad7617b9403 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -10,7 +10,8 @@
#
##############################################################################
kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild.
-innodb_bug39438 : Bug#42383 2009-01-28 lsoares "This fails in embedded and on windows. Note that this test is not run on windows and on embedded in PB for main trees currently"
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
-init_connect : Bug#44920 2009-07-06 pcrews MTR not processing master.opt input properly on Windows. *Must be done this way due to the nature of the bug*
-
+partition_innodb_builtin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
+partition_innodb_plugin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
+innodb-autoinc : Bug#48482 2009-11-02 svoj innodb-autoinc.test fails with results difference
+rpl_killed_ddl : Bug#45520: rpl_killed_ddl fails sporadically in pb2
diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test
index a77d1136840..bf4c23562cf 100644
--- a/mysql-test/t/distinct.test
+++ b/mysql-test/t/distinct.test
@@ -573,4 +573,44 @@ SELECT DISTINCT a, b, d, c FROM t1;
DROP TABLE t1;
+--echo #
+--echo # Bug #46159: simple query that never returns
+--echo #
+
+# Set max_heap_table_size to the minimum value so that GROUP BY table in the
+# SELECT query below gets converted to MyISAM
+SET @old_max_heap_table_size = @@max_heap_table_size;
+SET @@max_heap_table_size = 16384;
+
+# Set sort_buffer_size to the mininum value so that remove_duplicates() calls
+# remove_dup_with_compare()
+SET @old_sort_buffer_size = @@sort_buffer_size;
+SET @@sort_buffer_size = 32804;
+
+CREATE TABLE t1(c1 int, c2 VARCHAR(20));
+INSERT INTO t1 VALUES (1, '1'), (1, '1'), (2, '2'), (3, '1'), (3, '1'), (4, '4');
+# Now we just need to pad the table with random data so we have enough unique
+# values to force conversion of the GROUP BY table to MyISAM
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+INSERT INTO t1 SELECT 5 + 10000 * RAND(), '5' FROM t1;
+
+# First rows of the GROUP BY table that will be processed by
+# remove_dup_with_compare()
+SELECT c1, c2, COUNT(*) FROM t1 GROUP BY c1 LIMIT 4;
+
+# The actual test case
+SELECT DISTINCT c2 FROM t1 GROUP BY c1 HAVING COUNT(*) > 1;
+
+# Cleanup
+
+DROP TABLE t1;
+SET @@sort_buffer_size = @old_sort_buffer_size;
+SET @@max_heap_table_size = @old_max_heap_table_size;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test
index 755e126baf2..77b49a8b1a5 100644
--- a/mysql-test/t/explain.test
+++ b/mysql-test/t/explain.test
@@ -135,6 +135,17 @@ EXPLAIN EXTENDED SELECT COUNT(a) FROM t1 USE KEY(a);
DROP TABLE t1;
+#
+# Bug#45989 memory leak after explain encounters an error in the query
+#
+CREATE TABLE t1(a LONGTEXT);
+INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet));
+INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet));
+--error ER_BAD_FIELD_ERROR
+EXPLAIN SELECT DISTINCT 1 FROM t1,
+ (SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) as d1
+ WHERE t1.a = d1.a;
+DROP TABLE t1;
# End of 5.0 tests.
@@ -156,4 +167,24 @@ flush tables;
SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
drop tables t1, t2;
+--echo #
+--echo # Bug#48295:
+--echo # explain extended crash with subquery and ONLY_FULL_GROUP_BY sql_mode
+--echo #
+
+CREATE TABLE t1 (f1 INT);
+
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+
+# EXPLAIN EXTENDED (with subselect). used to crash. should give NOTICE.
+--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS
+EXPLAIN EXTENDED SELECT 1 FROM t1
+ WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
+SHOW WARNINGS;
+
+SET SESSION sql_mode=@old_sql_mode;
+
+DROP TABLE t1;
+
--echo End of 5.1 tests.
diff --git a/mysql-test/t/flush_read_lock_kill.test b/mysql-test/t/flush_read_lock_kill.test
index aeb09d52460..2d359383949 100644
--- a/mysql-test/t/flush_read_lock_kill.test
+++ b/mysql-test/t/flush_read_lock_kill.test
@@ -57,7 +57,7 @@ connection con1;
# debug build running without our --debug=make_global..., will be
# error 0 (no error). The only important thing to test is that on
# debug builds with our --debug=make_global... we don't hang forever.
---error 0,1053,2013
+--error 0,1317,2013
reap;
connection con2;
diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test
index b0a3d0feb79..6e39795a5d6 100644
--- a/mysql-test/t/func_group.test
+++ b/mysql-test/t/func_group.test
@@ -1006,3 +1006,51 @@ DROP TABLE t1;
###
--echo End of 5.0 tests
+
+--echo #
+--echo # BUG#47280 - strange results from count(*) with order by multiple
+--echo # columns without where/group
+--echo #
+
+--echo #
+--echo # Initialize test
+--echo #
+
+CREATE TABLE t1 (
+ pk INT NOT NULL,
+ i INT,
+ PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,11),(2,12),(3,13);
+
+--echo #
+--echo # Start test
+--echo # All the following queries shall return 1 record
+--echo #
+
+--echo
+--echo # Masking all correct values {11...13} for column i in this result.
+--replace_column 2 #
+SELECT MAX(pk) as max, i
+FROM t1
+ORDER BY max;
+
+--echo
+EXPLAIN
+SELECT MAX(pk) as max, i
+FROM t1
+ORDER BY max;
+
+--echo
+--echo # Only 11 is correct for collumn i in this result
+SELECT MAX(pk) as max, i
+FROM t1
+WHERE pk<2
+ORDER BY max;
+
+--echo #
+--echo # Cleanup
+--echo #
+DROP TABLE t1;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test
index adc074259ad..61ae812d874 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -456,4 +456,89 @@ SELECT SUM( DISTINCT e ) FROM t1 GROUP BY b,c,d HAVING (b,c,d) IN
((AVG( 1 ), 1 + c, 1 + d), (AVG( 1 ), 2 + c, 2 + d));
DROP TABLE t1;
+--echo #
+--echo # Bug #44139: Table scan when NULL appears in IN clause
+--echo #
+
+--disable_warnings
+
+CREATE TABLE t1 (
+ c_int INT NOT NULL,
+ c_decimal DECIMAL(5,2) NOT NULL,
+ c_float FLOAT(5, 2) NOT NULL,
+ c_bit BIT(10) NOT NULL,
+ c_date DATE NOT NULL,
+ c_datetime DATETIME NOT NULL,
+ c_timestamp TIMESTAMP NOT NULL,
+ c_time TIME NOT NULL,
+ c_year YEAR NOT NULL,
+ c_char CHAR(10) NOT NULL,
+ INDEX(c_int), INDEX(c_decimal), INDEX(c_float), INDEX(c_bit), INDEX(c_date),
+ INDEX(c_datetime), INDEX(c_timestamp), INDEX(c_time), INDEX(c_year),
+ INDEX(c_char));
+
+INSERT INTO t1 (c_int) VALUES (1), (2), (3), (4), (5);
+INSERT INTO t1 (c_int) SELECT 0 FROM t1;
+INSERT INTO t1 (c_int) SELECT 0 FROM t1;
+
+--enable_warnings
+
+EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, 2, 3);
+EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL, 1, 2, 3);
+
+EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, 2, 3);
+EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, NULL, 2, NULL, 3, NULL);
+EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL);
+EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL, NULL);
+
+EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (1, 2, 3);
+EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL, 1, 2, 3);
+EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL);
+EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL, NULL);
+
+EXPLAIN SELECT * FROM t1 WHERE c_float IN (1, 2, 3);
+EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL, 1, 2, 3);
+EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL);
+EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL, NULL);
+
+EXPLAIN SELECT * FROM t1 WHERE c_bit IN (1, 2, 3);
+EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL, 1, 2, 3);
+EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL);
+EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL, NULL);
+
+EXPLAIN SELECT * FROM t1 WHERE c_date
+ IN ('2009-09-01', '2009-09-02', '2009-09-03');
+EXPLAIN SELECT * FROM t1 WHERE c_date
+ IN (NULL, '2009-09-01', '2009-09-02', '2009-09-03');
+EXPLAIN SELECT * FROM t1 WHERE c_date IN (NULL);
+EXPLAIN SELECT * FROM t1 WHERE c_date IN (NULL, NULL);
+
+EXPLAIN SELECT * FROM t1 WHERE c_datetime
+ IN ('2009-09-01 00:00:01', '2009-09-02 00:00:01', '2009-09-03 00:00:01');
+EXPLAIN SELECT * FROM t1 WHERE c_datetime
+ IN (NULL, '2009-09-01 00:00:01', '2009-09-02 00:00:01', '2009-09-03 00:00:01');
+EXPLAIN SELECT * FROM t1 WHERE c_datetime IN (NULL);
+EXPLAIN SELECT * FROM t1 WHERE c_datetime IN (NULL, NULL);
+
+EXPLAIN SELECT * FROM t1 WHERE c_timestamp
+ IN ('2009-09-01 00:00:01', '2009-09-01 00:00:02', '2009-09-01 00:00:03');
+EXPLAIN SELECT * FROM t1 WHERE c_timestamp
+ IN (NULL, '2009-09-01 00:00:01', '2009-09-01 00:00:02', '2009-09-01 00:00:03');
+EXPLAIN SELECT * FROM t1 WHERE c_timestamp IN (NULL);
+EXPLAIN SELECT * FROM t1 WHERE c_timestamp IN (NULL, NULL);
+
+EXPLAIN SELECT * FROM t1 WHERE c_year IN (1, 2, 3);
+EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL, 1, 2, 3);
+EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL);
+EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL, NULL);
+
+EXPLAIN SELECT * FROM t1 WHERE c_char IN ('1', '2', '3');
+EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL, '1', '2', '3');
+EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL);
+EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL, NULL);
+
+DROP TABLE t1;
+
+--echo #
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index 7cb7f7f72d2..66b9eabd385 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -1291,6 +1291,19 @@ INSERT INTO t1 VALUES ('aaaaaaaa');
SELECT LOAD_FILE(a) FROM t1;
DROP TABLE t1;
+#
+# Bug#46815 CONCAT_WS returning wrong data
+#
+CREATE TABLE t1 (f2 VARCHAR(20));
+CREATE TABLE t2 (f2 VARCHAR(20));
+
+INSERT INTO t1 VALUES ('MIN'),('MAX');
+INSERT INTO t2 VALUES ('LOAD');
+
+SELECT CONCAT_WS('_', (SELECT t2.f2 FROM t2), t1.f2) AS concat_name FROM t1;
+
+DROP TABLE t1, t2;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/gis-rtree.test b/mysql-test/t/gis-rtree.test
index 944a00f008f..8ce4abf45d4 100644
--- a/mysql-test/t/gis-rtree.test
+++ b/mysql-test/t/gis-rtree.test
@@ -893,4 +893,25 @@ SELECT COUNT(*) FROM t1 IGNORE INDEX (b) WHERE
DROP TABLE t1;
+
+--echo #
+--echo # Bug #48258: Assertion failed when using a spatial index
+--echo #
+CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a));
+INSERT INTO t1 VALUES
+ (GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')),
+ (GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'));
+EXPLAIN SELECT 1 FROM t1 WHERE a = GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+SELECT 1 FROM t1 WHERE a = GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+EXPLAIN SELECT 1 FROM t1 WHERE a < GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+SELECT 1 FROM t1 WHERE a < GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+EXPLAIN SELECT 1 FROM t1 WHERE a <= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+SELECT 1 FROM t1 WHERE a <= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+EXPLAIN SELECT 1 FROM t1 WHERE a > GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+SELECT 1 FROM t1 WHERE a > GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+EXPLAIN SELECT 1 FROM t1 WHERE a >= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+SELECT 1 FROM t1 WHERE a >= GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)');
+DROP TABLE t1;
+
+
--echo End of 5.0 tests.
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index 4a60e777cc7..2d10c3bf1e1 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -655,6 +655,22 @@ insert into t1 values (),(),();
select min(`col002`) from t1 union select `col002` from t1;
drop table t1;
+--echo #
+--echo # Bug #47780: crash when comparing GIS items from subquery
+--echo #
+
+CREATE TABLE t1(a INT, b MULTIPOLYGON);
+INSERT INTO t1 VALUES
+ (0,
+ GEOMFROMTEXT(
+ 'multipolygon(((1 2,3 4,5 6,7 8,9 8),(7 6,5 4,3 2,1 2,3 4)))'));
+
+--echo # must not crash
+SELECT 1 FROM t1 WHERE a <> (SELECT GEOMETRYCOLLECTIONFROMWKB(b) FROM t1);
+
+DROP TABLE t1;
+
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/grant3.test b/mysql-test/t/grant3.test
index 9a635048774..437fc9a278f 100644
--- a/mysql-test/t/grant3.test
+++ b/mysql-test/t/grant3.test
@@ -163,6 +163,41 @@ connection default;
DROP USER 'mysqltest1'@'%';
DROP DATABASE mysqltest_1;
+--echo #
+--echo # Bug#41597 - After rename of user, there are additional grants
+--echo # when grants are reapplied.
+--echo #
+
+CREATE DATABASE temp;
+CREATE TABLE temp.t1(a INT, b VARCHAR(10));
+INSERT INTO temp.t1 VALUES(1, 'name1');
+INSERT INTO temp.t1 VALUES(2, 'name2');
+INSERT INTO temp.t1 VALUES(3, 'name3');
+
+
+CREATE USER 'user1'@'%';
+RENAME USER 'user1'@'%' TO 'user2'@'%';
+--echo # Show privileges after rename and BEFORE grant
+SHOW GRANTS FOR 'user2'@'%';
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%';
+--echo # Show privileges after rename and grant
+SHOW GRANTS FOR 'user2'@'%';
+
+--echo # Connect as the renamed user
+connect (conn1, localhost, user2,,);
+connection conn1;
+SHOW GRANTS;
+SELECT a FROM temp.t1;
+--echo # Check for additional privileges by accessing a
+--echo # non privileged column. We shouldn't be able to
+--echo # access this column.
+--error ER_COLUMNACCESS_DENIED_ERROR
+SELECT b FROM temp.t1;
+disconnect conn1;
+
+connection default;
+DROP USER 'user2'@'%';
+DROP DATABASE temp;
--echo End of 5.0 tests
diff --git a/mysql-test/t/grant_lowercase_fs.test b/mysql-test/t/grant_lowercase_fs.test
new file mode 100644
index 00000000000..f57f950ec8c
--- /dev/null
+++ b/mysql-test/t/grant_lowercase_fs.test
@@ -0,0 +1,30 @@
+-- source include/have_case_insensitive_fs.inc
+-- source include/not_embedded.inc
+
+
+#
+# Bug#41049 does syntax "grant" case insensitive?
+#
+create database db1;
+GRANT CREATE ON db1.* to user_1@localhost;
+GRANT SELECT ON db1.* to USER_1@localhost;
+
+connect (con1,localhost,user_1,,db1);
+CREATE TABLE t1(f1 int);
+--error 1142
+SELECT * FROM t1;
+connect (con2,localhost,USER_1,,db1);
+SELECT * FROM t1;
+--error 1142
+CREATE TABLE t2(f1 int);
+
+connection default;
+disconnect con1;
+disconnect con2;
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1@localhost;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM USER_1@localhost;
+DROP USER user_1@localhost;
+DROP USER USER_1@localhost;
+DROP DATABASE db1;
+use test;
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index aa9915bf5c9..1298bb89754 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -5,6 +5,9 @@
# on the presence of the log tables (which are CSV-based).
--source include/have_csv.inc
+# Check that InnoDB/XtraDB was compiled in as result depends on it
+-- source include/have_innodb.inc
+
# Save the initial number of concurrent sessions
--source include/count_sessions.inc
diff --git a/mysql-test/t/information_schema_db.test b/mysql-test/t/information_schema_db.test
index 59cd0fba024..bfe6745f5ae 100644
--- a/mysql-test/t/information_schema_db.test
+++ b/mysql-test/t/information_schema_db.test
@@ -181,7 +181,6 @@ show fields from testdb_1.v7;
--error ER_TABLEACCESS_DENIED_ERROR
show create view testdb_1.v7;
---error ER_VIEW_NO_EXPLAIN
show create view v4;
#--error ER_VIEW_NO_EXPLAIN
show fields from v4;
diff --git a/mysql-test/t/innodb-autoinc.test b/mysql-test/t/innodb-autoinc.test
index 87ad470949d..3f45bb9d003 100644
--- a/mysql-test/t/innodb-autoinc.test
+++ b/mysql-test/t/innodb-autoinc.test
@@ -156,7 +156,7 @@ DROP TABLE t1;
#
# Test changes to AUTOINC next value calculation
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL),(5),(NULL);
@@ -173,7 +173,7 @@ DROP TABLE t1;
# Reset the AUTOINC session variables
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(0);
@@ -193,13 +193,13 @@ DROP TABLE t1;
# Reset the AUTOINC session variables
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(-1);
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
INSERT INTO t1 VALUES (-2), (NULL),(2),(NULL);
INSERT INTO t1 VALUES (250),(NULL);
SELECT * FROM t1;
@@ -214,13 +214,13 @@ DROP TABLE t1;
# Reset the AUTOINC session variables
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(-1);
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
INSERT INTO t1 VALUES (-2);
INSERT INTO t1 VALUES (NULL);
INSERT INTO t1 VALUES (2);
@@ -240,13 +240,13 @@ DROP TABLE t1;
# Reset the AUTOINC session variables
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(-1);
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=100, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
INSERT INTO t1 VALUES (-2),(NULL),(2),(NULL);
INSERT INTO t1 VALUES (250),(NULL);
SELECT * FROM t1;
@@ -262,7 +262,7 @@ DROP TABLE t1;
# Check for overflow handling when increment is > 1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 BIGINT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
# TODO: Fix the autoinc init code
@@ -271,7 +271,7 @@ INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (9223372036854775794); #-- 2^63 - 14
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
# This should just fit
INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
SELECT * FROM t1;
@@ -281,7 +281,7 @@ DROP TABLE t1;
# Check for overflow handling when increment and offser are > 1
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
# TODO: Fix the autoinc init code
@@ -290,7 +290,7 @@ INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (18446744073709551603); #-- 2^64 - 13
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
# This should fail because of overflow but it doesn't, it seems to be
# a MySQL server bug. It wraps around to 0 for the last value.
# See MySQL Bug# 39828
@@ -313,7 +313,7 @@ DROP TABLE t1;
# Check for overflow handling when increment and offset are odd numbers
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
# TODO: Fix the autoinc init code
@@ -322,7 +322,7 @@ INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (18446744073709551603); #-- 2^64 - 13
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=5, @@SESSION.AUTO_INCREMENT_OFFSET=7;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
# This should fail because of overflow but it doesn't. It fails with
# a duplicate entry message because of a MySQL server bug, it wraps
# around. See MySQL Bug# 39828, once MySQL fix the bug we can replace
@@ -344,7 +344,7 @@ DROP TABLE t1;
# and check for large -ve numbers
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 BIGINT AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
# TODO: Fix the autoinc init code
@@ -355,7 +355,7 @@ INSERT INTO t1 VALUES(-9223372036854775807); #-- -2^63 + 1
INSERT INTO t1 VALUES(-9223372036854775808); #-- -2^63
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=3, @@SESSION.AUTO_INCREMENT_OFFSET=3;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
INSERT INTO t1 VALUES (NULL),(NULL), (NULL);
SELECT * FROM t1;
DROP TABLE t1;
@@ -364,7 +364,7 @@ DROP TABLE t1;
# large numbers 2^60
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(c1)) ENGINE=InnoDB;
# TODO: Fix the autoinc init code
@@ -373,7 +373,7 @@ INSERT INTO t1 VALUES(NULL);
INSERT INTO t1 VALUES (18446744073709551610); #-- 2^64 - 2
SELECT * FROM t1;
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1152921504606846976, @@SESSION.AUTO_INCREMENT_OFFSET=1152921504606846976;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
# This should fail because of overflow but it doesn't. It wraps around
# and the autoinc values look bogus too.
# See MySQL Bug# 39828, once MySQL fix the bug we can enable the error
@@ -396,7 +396,7 @@ DROP TABLE t1;
#
SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
SET @@INSERT_ID=1;
-SHOW VARIABLES LIKE "auto_inc%";
+SHOW VARIABLES LIKE "%auto_inc%";
CREATE TABLE t1 (c1 DOUBLE NOT NULL AUTO_INCREMENT, c2 INT, PRIMARY KEY (c1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(NULL, 1);
INSERT INTO t1 VALUES(NULL, 2);
@@ -478,3 +478,145 @@ INSERT INTO t2 SELECT c1 FROM t1;
INSERT INTO t2 SELECT NULL FROM t1;
DROP TABLE t1;
DROP TABLE t2;
+#
+# 44030: Error: (1500) Couldn't read the MAX(ID) autoinc value from
+# the index (PRIMARY)
+# This test requires a restart of the server
+SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (null);
+INSERT INTO t1 VALUES (null);
+ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT;
+SELECT * FROM t1;
+# Restart the server
+-- source include/restart_mysqld.inc
+# The MySQL and InnoDB data dictionaries should now be out of sync.
+# The select should print message to the error log
+SELECT * FROM t1;
+# MySQL have made a change (http://lists.mysql.com/commits/75268) that no
+# longer results in the two data dictionaries being out of sync. If they
+# revert their changes then this check for ER_AUTOINC_READ_FAILED will need
+# to be enabled.
+-- error ER_AUTOINC_READ_FAILED,1467
+INSERT INTO t1 VALUES(null);
+ALTER TABLE t1 AUTO_INCREMENT = 3;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES(null);
+SELECT * FROM t1;
+DROP TABLE t1;
+
+# If the user has specified negative values for an AUTOINC column then
+# InnoDB should ignore those values when setting the table's max value.
+SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
+SHOW VARIABLES LIKE "%auto_inc%";
+# TINYINT
+CREATE TABLE t1 (c1 TINYINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-127, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 TINYINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-127, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# SMALLINT
+#
+CREATE TABLE t1 (c1 SMALLINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-32767, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-32757, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# MEDIUMINT
+#
+CREATE TABLE t1 (c1 MEDIUMINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-8388607, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 MEDIUMINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-8388607, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# INT
+#
+CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-2147483647, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-2147483647, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# BIGINT
+#
+CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-9223372036854775807, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (c1 BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (-1, 'innodb');
+INSERT INTO t1 VALUES (-9223372036854775807, 'innodb');
+INSERT INTO t1 VALUES (NULL, NULL);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+#
+# End negative number check
+
+##
+# 47125: auto_increment start value is ignored if an index is created
+# and engine=innodb
+#
+CREATE TABLE T1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB;
+CREATE INDEX i1 on T1(c2);
+SHOW CREATE TABLE T1;
+INSERT INTO T1 (c2) values (0);
+SELECT * FROM T1;
+DROP TABLE T1;
diff --git a/mysql-test/t/innodb-index.test b/mysql-test/t/innodb-index.test
index dd2c7f3f3c3..b8fa2e93916 100644
--- a/mysql-test/t/innodb-index.test
+++ b/mysql-test/t/innodb-index.test
@@ -515,4 +515,30 @@ SHOW CREATE TABLE t2;
DROP TABLE t2;
DROP TABLE t1;
+
+call mtr.add_suppression("InnoDB: insufficient history for index");
+
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+CREATE TABLE t1 (a INT, b CHAR(1)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (3,'a'),(3,'b'),(1,'c'),(0,'d'),(1,'e');
+connection b;
+BEGIN;
+SELECT * FROM t1;
+connection a;
+CREATE INDEX t1a ON t1(a);
+connection b;
+SELECT * FROM t1;
+--error ER_TABLE_DEF_CHANGED
+SELECT * FROM t1 FORCE INDEX(t1a) ORDER BY a;
+SELECT * FROM t1;
+COMMIT;
+SELECT * FROM t1 FORCE INDEX(t1a) ORDER BY a;
+connection default;
+disconnect a;
+disconnect b;
+
+DROP TABLE t1;
+
SET GLOBAL innodb_file_format_check=@save_innodb_file_format_check;
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index 220621a3576..6eb32b554bb 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -1321,7 +1321,7 @@ drop table t1;
# InnoDB aligns the memory for the buffer pool to a page boundary. This may
# cause actual pool size to be one less than requested depending on exact
# alignment of obtained memory.
---replace_result 512 511
+--replace_result 8192 8191
SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_buffer_pool_pages_total';
SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size';
SELECT variable_value - @innodb_rows_deleted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_deleted';
@@ -1336,6 +1336,7 @@ SELECT variable_value - @innodb_row_lock_time_max_orig FROM information_schema.g
SELECT variable_value - @innodb_row_lock_time_avg_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_avg';
# Test for innodb_sync_spin_loops variable
+SET @innodb_sync_spin_loops_orig = @@innodb_sync_spin_loops;
show variables like "innodb_sync_spin_loops";
set global innodb_sync_spin_loops=1000;
show variables like "innodb_sync_spin_loops";
@@ -1343,6 +1344,7 @@ set global innodb_sync_spin_loops=0;
show variables like "innodb_sync_spin_loops";
set global innodb_sync_spin_loops=20;
show variables like "innodb_sync_spin_loops";
+set global innodb_sync_spin_loops=@innodb_sync_spin_loops_orig;
# Test for innodb_thread_concurrency variable
SET @old_innodb_thread_concurrency= @@global.innodb_thread_concurrency;
@@ -2555,6 +2557,8 @@ CONNECTION default;
SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig;
+-- enable_query_log
+
#######################################################################
# #
# Please, DO NOT TOUCH this file as well as the innodb.result file. #
diff --git a/mysql-test/t/innodb_bug36169.test b/mysql-test/t/innodb_bug36169.test
index b95e66fa34a..22a2f6ddada 100644
--- a/mysql-test/t/innodb_bug36169.test
+++ b/mysql-test/t/innodb_bug36169.test
@@ -4,9 +4,8 @@
#
-- source include/have_innodb.inc
-set @old_innodb_file_per_table=@@innodb_file_per_table;
set @old_innodb_file_format=@@innodb_file_format;
-set @old_innodb_file_format_check=@@innodb_file_format_check;
+set @old_innodb_file_per_table=@@innodb_file_per_table;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON;
@@ -1156,7 +1155,5 @@ DROP TABLE IF EXISTS table4;
DROP TABLE IF EXISTS table5;
DROP TABLE IF EXISTS table6;
-set global innodb_file_per_table=@old_innodb_file_per_table;
set global innodb_file_format=@old_innodb_file_format;
-set global innodb_file_format_check=@old_innodb_file_format_check;
-
+set global innodb_file_per_table=@old_innodb_file_per_table;
diff --git a/mysql-test/t/innodb_bug36172.test b/mysql-test/t/innodb_bug36172.test
index 935e5c8d5c4..6fc6906be2f 100644
--- a/mysql-test/t/innodb_bug36172.test
+++ b/mysql-test/t/innodb_bug36172.test
@@ -15,7 +15,6 @@ SET storage_engine=InnoDB;
-- disable_result_log
set @old_innodb_file_per_table=@@innodb_file_per_table;
set @old_innodb_file_format=@@innodb_file_format;
-set @old_innodb_file_format_check=@@innodb_file_format_check;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=on;
@@ -30,5 +29,4 @@ CHECK TABLE table0 EXTENDED;
DROP TABLE table0;
set global innodb_file_per_table=@old_innodb_file_per_table;
set global innodb_file_format=@old_innodb_file_format;
-set global innodb_file_format_check=@old_innodb_file_format_check;
-
+set global innodb_file_format_check=Antelope;
diff --git a/mysql-test/t/innodb_bug39438.test b/mysql-test/t/innodb_bug39438.test
index 4dc3d957c39..2a51e5fcbb8 100644
--- a/mysql-test/t/innodb_bug39438.test
+++ b/mysql-test/t/innodb_bug39438.test
@@ -9,6 +9,10 @@
-- source include/have_innodb.inc
+--disable_query_log
+call mtr.add_suppression("InnoDB: Error: table 'test/bug39438'");
+--enable_query_log
+
SET storage_engine=InnoDB;
# we care only that the following SQL commands do not crash the server
diff --git a/mysql-test/suite/innodb/t/innodb_bug44032.test b/mysql-test/t/innodb_bug44032.test
index a963cb8b68f..a963cb8b68f 100644
--- a/mysql-test/suite/innodb/t/innodb_bug44032.test
+++ b/mysql-test/t/innodb_bug44032.test
diff --git a/mysql-test/t/innodb_bug44369.test b/mysql-test/t/innodb_bug44369.test
new file mode 100644
index 00000000000..238dc3d8fb1
--- /dev/null
+++ b/mysql-test/t/innodb_bug44369.test
@@ -0,0 +1,21 @@
+# This is the test for bug 44369. We should
+# block table creation with columns match
+# some innodb internal reserved key words,
+# both case sensitively and insensitely.
+
+--source include/have_innodb.inc
+
+# This create table operation should fail.
+--error ER_CANT_CREATE_TABLE
+create table bug44369 (DB_ROW_ID int) engine=innodb;
+
+# This create should fail as well
+--error ER_CANT_CREATE_TABLE
+create table bug44369 (db_row_id int) engine=innodb;
+
+show warnings;
+
+--error ER_CANT_CREATE_TABLE
+create table bug44369 (db_TRX_Id int) engine=innodb;
+
+show warnings;
diff --git a/mysql-test/t/innodb_bug46000.test b/mysql-test/t/innodb_bug46000.test
new file mode 100644
index 00000000000..03942c86c98
--- /dev/null
+++ b/mysql-test/t/innodb_bug46000.test
@@ -0,0 +1,34 @@
+# This is the test for bug 46000. We shall
+# block any index creation with the name of
+# "GEN_CLUST_INDEX", which is the reserved
+# name for innodb default primary index.
+
+--source include/have_innodb.inc
+
+# This 'create table' operation should fail because of
+# using the reserve name as its index name.
+--error ER_WRONG_NAME_FOR_INDEX
+create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb;
+
+# Mixed upper/lower case of the reserved key words
+--error ER_WRONG_NAME_FOR_INDEX
+create table bug46000(`id` int, key `GEN_clust_INDEX`(`id`))engine=innodb;
+
+show warnings;
+
+create table bug46000(id int) engine=innodb;
+
+# This 'create index' operation should fail.
+--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
+--error ER_WRONG_NAME_FOR_INDEX
+create index GEN_CLUST_INDEX on bug46000(id);
+
+--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
+show warnings;
+
+# This 'create index' operation should succeed, no
+# temp table left from last failed create index
+# operation.
+create index idx on bug46000(id);
+
+drop table bug46000;
diff --git a/mysql-test/t/innodb_bug47777.test b/mysql-test/t/innodb_bug47777.test
new file mode 100644
index 00000000000..8f2985b2cf0
--- /dev/null
+++ b/mysql-test/t/innodb_bug47777.test
@@ -0,0 +1,24 @@
+# This is the test for bug 47777. GEOMETRY
+# data is treated as BLOB data in innodb.
+# Consequently, its key value generation/storing
+# should follow the process for the BLOB
+# datatype as well.
+
+--source include/have_innodb.inc
+
+create table bug47777(c2 linestring not null, primary key (c2(1))) engine=innodb;
+
+insert into bug47777 values (geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)'));
+
+# Verify correct row get inserted.
+select count(*) from bug47777 where c2 =geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)');
+
+# Update table bug47777 should be successful.
+update bug47777 set c2=GeomFromText('POINT(1 1)');
+
+# Verify the row get updated successfully. The original
+# c2 value should be changed to GeomFromText('POINT(1 1)').
+select count(*) from bug47777 where c2 =geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)');
+select count(*) from bug47777 where c2 = GeomFromText('POINT(1 1)');
+
+drop table bug47777;
diff --git a/mysql-test/suite/innodb/t/innodb_file_format.test b/mysql-test/t/innodb_file_format.test
index 293e87a413e..0999517bdd8 100644
--- a/mysql-test/suite/innodb/t/innodb_file_format.test
+++ b/mysql-test/t/innodb_file_format.test
@@ -1,8 +1,7 @@
-- source include/have_innodb.inc
--- source suite/innodb/include/have_innodb_plugin.inc
+set @old_innodb_file_format=@@innodb_file_format;
-let $format=`select @@innodb_file_format`;
-let $innodb_file_format_check_orig=`select @@innodb_file_format_check`;
+call mtr.add_suppression("InnoDB: invalid innodb_file_format_check value");
select @@innodb_file_format;
select @@innodb_file_format_check;
@@ -31,11 +30,5 @@ set global innodb_file_format=on;
set global innodb_file_format=off;
select @@innodb_file_format_check;
-#
-# restore environment to the state it was before this test execution
-#
-
--- disable_query_log
-eval set global innodb_file_format=$format;
-eval set global innodb_file_format_check=$innodb_file_format_check_orig;
--- enable_query_log
+set global innodb_file_format=@old_innodb_file_format;
+set global innodb_file_format_check=Antelope;
diff --git a/mysql-test/t/bug40113-master.opt b/mysql-test/t/innodb_lock_wait_timeout_1-master.opt
index 462f8fbe828..462f8fbe828 100644
--- a/mysql-test/t/bug40113-master.opt
+++ b/mysql-test/t/innodb_lock_wait_timeout_1-master.opt
diff --git a/mysql-test/t/innodb_lock_wait_timeout_1.test b/mysql-test/t/innodb_lock_wait_timeout_1.test
new file mode 100644
index 00000000000..e42e9f3e37c
--- /dev/null
+++ b/mysql-test/t/innodb_lock_wait_timeout_1.test
@@ -0,0 +1,230 @@
+--source include/have_innodb.inc
+
+--echo #
+--echo # Bug #40113: Embedded SELECT inside UPDATE or DELETE can timeout
+--echo # without error
+--echo #
+
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b)) ENGINE=InnoDB;
+
+INSERT INTO t1 (a,b) VALUES (1070109,99);
+
+CREATE TABLE t2 (b int, a int, PRIMARY KEY (b)) ENGINE=InnoDB;
+
+INSERT INTO t2 (b,a) VALUES (7,1070109);
+
+SELECT * FROM t1;
+
+BEGIN;
+
+SELECT b FROM t2 WHERE b=7 FOR UPDATE;
+
+CONNECT (addconroot, localhost, root,,);
+CONNECTION addconroot;
+
+BEGIN;
+
+--error ER_LOCK_WAIT_TIMEOUT
+SELECT b FROM t2 WHERE b=7 FOR UPDATE;
+
+--error ER_LOCK_WAIT_TIMEOUT
+INSERT INTO t1 (a) VALUES ((SELECT a FROM t2 WHERE b=7));
+
+--error ER_LOCK_WAIT_TIMEOUT
+UPDATE t1 SET a='7000000' WHERE a=(SELECT a FROM t2 WHERE b=7);
+
+--error ER_LOCK_WAIT_TIMEOUT
+DELETE FROM t1 WHERE a=(SELECT a FROM t2 WHERE b=7);
+
+SELECT * FROM t1;
+
+CONNECTION default;
+DISCONNECT addconroot;
+
+DROP TABLE t2, t1;
+
+--echo # End of 5.0 tests
+
+--echo #
+--echo # Bug#46539 Various crashes on INSERT IGNORE SELECT + SELECT
+--echo # FOR UPDATE
+--echo #
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int primary key auto_increment,
+ b int, index(b)) engine=innodb;
+insert into t1 (b) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+set autocommit=0;
+begin;
+select * from t1 where b=5 for update;
+connect (con1, localhost, root,,);
+connection con1;
+--error ER_LOCK_WAIT_TIMEOUT
+insert ignore into t1 (b) select a as b from t1;
+connection default;
+--echo # Cleanup
+--echo #
+disconnect con1;
+commit;
+set autocommit=default;
+drop table t1;
+
+--echo #
+--echo # Bug#41756 Strange error messages about locks from InnoDB
+--echo #
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+--echo # In the default transaction isolation mode, and/or with
+--echo # innodb_locks_unsafe_for_binlog=OFF, handler::unlock_row()
+--echo # in InnoDB does nothing.
+--echo # Thus in order to reproduce the condition that led to the
+--echo # warning, one needs to relax isolation by either
+--echo # setting a weaker tx_isolation value, or by turning on
+--echo # the unsafe replication switch.
+--echo # For testing purposes, choose to tweak the isolation level,
+--echo # since it's settable at runtime, unlike
+--echo # innodb_locks_unsafe_for_binlog, which is
+--echo # only a command-line switch.
+--echo #
+set @@session.tx_isolation="read-committed";
+
+--echo # Prepare data. We need a table with a unique index,
+--echo # for join_read_key to be used. The other column
+--echo # allows to control what passes WHERE clause filter.
+create table t1 (a int primary key, b int) engine=innodb;
+--echo # Let's make sure t1 has sufficient amount of rows
+--echo # to exclude JT_ALL access method when reading it,
+--echo # i.e. make sure that JT_EQ_REF(a) is always preferred.
+insert into t1 values (1,1), (2,null), (3,1), (4,1),
+ (5,1), (6,1), (7,1), (8,1), (9,1), (10,1),
+ (11,1), (12,1), (13,1), (14,1), (15,1),
+ (16,1), (17,1), (18,1), (19,1), (20,1);
+--echo #
+--echo # Demonstrate that for the SELECT statement
+--echo # used later in the test JT_EQ_REF access method is used.
+--echo #
+--vertical_results
+explain
+select 1 from t1 natural join (select 2 as a, 1 as b union all
+ select 2 as a, 2 as b) as t2 for update;
+--horizontal_results
+--echo #
+--echo # Demonstrate that the reported SELECT statement
+--echo # no longer produces warnings.
+--echo #
+select 1 from t1 natural join (select 2 as a, 1 as b union all
+ select 2 as a, 2 as b) as t2 for update;
+commit;
+--echo #
+--echo # Demonstrate that due to lack of inter-sweep "reset" function,
+--echo # we keep some non-matching records locked, even though we know
+--echo # we could unlock them.
+--echo # To do that, show that if there is only one distinct value
+--echo # for a in t2 (a=2), we will keep record (2,null) in t1 locked.
+--echo # But if we add another value for "a" to t2, say 6,
+--echo # join_read_key cache will be pruned at least once,
+--echo # and thus record (2, null) in t1 will get unlocked.
+--echo #
+begin;
+select 1 from t1 natural join (select 2 as a, 1 as b union all
+ select 2 as a, 2 as b) as t2 for update;
+connect (con1,localhost,root,,);
+--echo #
+--echo # Switching to connection con1
+connection con1;
+--echo # We should be able to delete all records from t1 except (2, null),
+--echo # since they were not locked.
+begin;
+--echo # Delete in series of 3 records so that full scan
+--echo # is not used and we're not blocked on record (2,null)
+delete from t1 where a in (1,3,4);
+delete from t1 where a in (5,6,7);
+delete from t1 where a in (8,9,10);
+delete from t1 where a in (11,12,13);
+delete from t1 where a in (14,15,16);
+delete from t1 where a in (17,18);
+delete from t1 where a in (19,20);
+--echo #
+--echo # Record (2, null) is locked. This is actually unnecessary,
+--echo # because the previous select returned no rows.
+--echo # Just demonstrate the effect.
+--echo #
+--error ER_LOCK_WAIT_TIMEOUT
+delete from t1;
+rollback;
+--echo #
+--echo # Switching to connection default
+connection default;
+--echo #
+--echo # Show that the original contents of t1 is intact:
+select * from t1;
+commit;
+--echo #
+--echo # Have a one more record in t2 to show that
+--echo # if join_read_key cache is purned, the current
+--echo # row under the cursor is unlocked (provided, this row didn't
+--echo # match the partial WHERE clause, of course).
+--echo # Sic: the result of this test dependent on the order of retrieval
+--echo # of records --echo # from the derived table, if !
+--echo # We use DELETE to disable the JOIN CACHE. This DELETE modifies no
+--echo # records. It also should leave no InnoDB row locks.
+--echo #
+begin;
+delete t1.* from t1 natural join (select 2 as a, 2 as b union all
+ select 0 as a, 0 as b) as t2;
+--echo # Demonstrate that nothing was deleted form t1
+select * from t1;
+--echo #
+--echo # Switching to connection con1
+connection con1;
+begin;
+--echo # Since there is another distinct record in the derived table
+--echo # the previous matching record in t1 -- (2,null) -- was unlocked.
+delete from t1;
+--echo # We will need the contents of the table again.
+rollback;
+select * from t1;
+commit;
+--echo #
+--echo # Switching to connection default
+connection default;
+rollback;
+begin;
+--echo #
+--echo # Before this patch, we could wrongly unlock a record
+--echo # that was cached and later used in a join. Demonstrate that
+--echo # this is no longer the case.
+--echo # Sic: this test is also order-dependent (i.e. the
+--echo # the bug would show up only if the first record in the union
+--echo # is retreived and processed first.
+--echo #
+--echo # Verify that JT_EQ_REF is used.
+--vertical_results
+explain
+select 1 from t1 natural join (select 3 as a, 2 as b union all
+ select 3 as a, 1 as b) as t2 for update;
+--horizontal_results
+--echo # Lock the record.
+select 1 from t1 natural join (select 3 as a, 2 as b union all
+ select 3 as a, 1 as b) as t2 for update;
+--echo # Switching to connection con1
+connection con1;
+--echo #
+--echo # We should not be able to delete record (3,1) from t1,
+--echo # (previously it was possible).
+--echo #
+--error ER_LOCK_WAIT_TIMEOUT
+delete from t1 where a=3;
+--echo # Switching to connection default
+connection default;
+commit;
+
+disconnect con1;
+set @@session.tx_isolation=default;
+drop table t1;
+
+--echo #
+--echo # End of 5.1 tests
+--echo #
diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test
index d604bcfe769..8d2b70d4a0f 100644
--- a/mysql-test/t/innodb_mysql.test
+++ b/mysql-test/t/innodb_mysql.test
@@ -463,4 +463,33 @@ EXPLAIN SELECT * FROM t1 FORCE INDEX(PRIMARY) WHERE b=1 AND c=1 ORDER BY a;
DROP TABLE t1;
+--echo #
+--echo # Bug #47963: Wrong results when index is used
+--echo #
+CREATE TABLE t1(
+ a VARCHAR(5) NOT NULL,
+ b VARCHAR(5) NOT NULL,
+ c DATETIME NOT NULL,
+ KEY (c)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES('TEST', 'TEST', '2009-10-09 00:00:00');
+SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00' AND c <= '2009-10-09 00:00:00';
+SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00.0' AND c <= '2009-10-09 00:00:00.0';
+SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00.0' AND c <= '2009-10-09 00:00:00';
+SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00' AND c <= '2009-10-09 00:00:00.0';
+SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00.000' AND c <= '2009-10-09 00:00:00.000';
+SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00.00' AND c <= '2009-10-09 00:00:00.001';
+SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00';
+EXPLAIN SELECT * FROM t1 WHERE a = 'TEST' AND
+ c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00';
+DROP TABLE t1;
+
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test
index 50c40e38b5b..d740445fb4d 100644
--- a/mysql-test/t/insert_select.test
+++ b/mysql-test/t/insert_select.test
@@ -392,4 +392,32 @@ insert into t1 values(1),(2),(3);
create table t2 (key(f1)) engine=myisam select sql_buffer_result f1 from t1;
check table t2 extended;
drop table t1,t2;
+
--echo End of 5.0 tests
+
+# The following is not relevant for MariaDB as we are using Maria for
+# tmp tables.
+
+--echo ##################################################################
+--echo #
+--echo # Bug #46075: Assertion failed: 0, file .\protocol.cc, line 416
+--echo #
+
+CREATE TABLE t1(a INT);
+# To force MyISAM temp. table in the following INSERT ... SELECT.
+SET max_heap_table_size = 16384;
+# To overflow the temp. table.
+SET @old_myisam_data_pointer_size = @@myisam_data_pointer_size;
+SET GLOBAL myisam_data_pointer_size = 2;
+
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5);
+
+call mtr.add_suppression("mysqld: The table '.*#sql.*' is full");
+--error 0,ER_RECORD_FILE_FULL,ER_RECORD_FILE_FULL
+INSERT IGNORE INTO t1 SELECT t1.a FROM t1,t1 t2,t1 t3,t1 t4,t1 t5,t1 t6,t1 t7;
+
+# Cleanup
+SET GLOBAL myisam_data_pointer_size = @old_myisam_data_pointer_size;
+DROP TABLE t1;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test
index b5e30e63f54..dbf36dedec8 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/join.test
@@ -729,4 +729,78 @@ SELECT * FROM t1 JOIN t2 ON b=c ORDER BY a;
SELECT * FROM t1 JOIN t2 ON a=c ORDER BY a;
DROP TABLE IF EXISTS t1,t2;
+
+
+--echo #
+--echo # Bug #42116: Mysql crash on specific query
+--echo #
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+CREATE TABLE t3 (a INT, INDEX (a));
+CREATE TABLE t4 (a INT);
+CREATE TABLE t5 (a INT);
+CREATE TABLE t6 (a INT);
+
+INSERT INTO t1 VALUES (1), (1), (1);
+
+INSERT INTO t2 VALUES
+(2), (2), (2), (2), (2), (2), (2), (2), (2), (2);
+
+INSERT INTO t3 VALUES
+(3), (3), (3), (3), (3), (3), (3), (3), (3), (3);
+
+EXPLAIN
+SELECT *
+FROM
+ t1 JOIN t2 ON t1.a = t2.a
+ LEFT JOIN
+ (
+ (
+ t3 LEFT JOIN t4 ON t3.a = t4.a
+ )
+ LEFT JOIN
+ (
+ t5 LEFT JOIN t6 ON t5.a = t6.a
+ )
+ ON t4.a = t5.a
+ )
+ ON t1.a = t3.a;
+
+SELECT *
+FROM
+ t1 JOIN t2 ON t1.a = t2.a
+ LEFT JOIN
+ (
+ (
+ t3 LEFT JOIN t4 ON t3.a = t4.a
+ )
+ LEFT JOIN
+ (
+ t5 LEFT JOIN t6 ON t5.a = t6.a
+ )
+ ON t4.a = t5.a
+ )
+ ON t1.a = t3.a;
+
+DROP TABLE t1,t2,t3,t4,t5,t6;
+
--echo End of 5.0 tests.
+
+
+#
+# Bug#47150 Assertion in Field_long::val_int() on MERGE + TRIGGER + multi-table UPDATE
+#
+CREATE TABLE t1 (f1 int);
+
+CREATE TABLE t2 (f1 int);
+INSERT INTO t2 VALUES (1);
+CREATE VIEW v1 AS SELECT * FROM t2;
+
+PREPARE stmt FROM 'UPDATE t2 AS A NATURAL JOIN v1 B SET B.f1 = 1';
+EXECUTE stmt;
+EXECUTE stmt;
+
+DEALLOCATE PREPARE stmt;
+
+DROP VIEW v1;
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test
index 44d04abf486..b199a1224c3 100644
--- a/mysql-test/t/kill.test
+++ b/mysql-test/t/kill.test
@@ -99,7 +99,7 @@ select ((@id := kill_id) - kill_id) from t3;
kill @id;
connection conn1;
--- error 1053,2013
+-- error 1317,2013
reap;
connection default;
diff --git a/mysql-test/t/locale.test b/mysql-test/t/locale.test
new file mode 100644
index 00000000000..7ceb49fd1f4
--- /dev/null
+++ b/mysql-test/t/locale.test
@@ -0,0 +1,18 @@
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo Start of 5.4 tests
+--echo #
+--echo # Bug#43207 wrong LC_TIME names for romanian locale
+--echo #
+SET NAMES utf8;
+SET lc_time_names=ro_RO;
+SELECT DATE_FORMAT('2001-01-01', '%w %a %W');
+SELECT DATE_FORMAT('2001-01-02', '%w %a %W');
+SELECT DATE_FORMAT('2001-01-03', '%w %a %W');
+SELECT DATE_FORMAT('2001-01-04', '%w %a %W');
+SELECT DATE_FORMAT('2001-01-05', '%w %a %W');
+SELECT DATE_FORMAT('2001-01-06', '%w %a %W');
+SELECT DATE_FORMAT('2001-01-07', '%w %a %W');
+--echo End of 5.4 tests
diff --git a/mysql-test/t/lowercase_fs_off.test b/mysql-test/t/lowercase_fs_off.test
index 878564c32ab..86d1e084c29 100644
--- a/mysql-test/t/lowercase_fs_off.test
+++ b/mysql-test/t/lowercase_fs_off.test
@@ -29,3 +29,65 @@ disconnect master;
connection default;
# End of 4.1 tests
+
+#
+# Bug#41049 does syntax "grant" case insensitive?
+#
+CREATE DATABASE d1;
+USE d1;
+CREATE TABLE T1(f1 INT);
+CREATE TABLE t1(f1 INT);
+GRANT SELECT ON T1 to user_1@localhost;
+
+connect (con1,localhost,user_1,,d1);
+--error ER_TABLEACCESS_DENIED_ERROR
+select * from t1;
+select * from T1;
+connection default;
+GRANT SELECT ON t1 to user_1@localhost;
+connection con1;
+select * from information_schema.table_privileges;
+connection default;
+disconnect con1;
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1@localhost;
+DROP USER user_1@localhost;
+DROP DATABASE d1;
+USE test;
+
+CREATE DATABASE db1;
+USE db1;
+CREATE PROCEDURE p1() BEGIN END;
+CREATE FUNCTION f1(i INT) RETURNS INT RETURN i+1;
+
+GRANT USAGE ON db1.* to user_1@localhost;
+GRANT EXECUTE ON PROCEDURE db1.P1 to user_1@localhost;
+GRANT EXECUTE ON FUNCTION db1.f1 to user_1@localhost;
+GRANT UPDATE ON db1.* to USER_1@localhost;
+
+connect (con1,localhost,user_1,,db1);
+call p1();
+call P1();
+select f1(1);
+connect (con2,localhost,USER_1,,db1);
+--error ER_PROCACCESS_DENIED_ERROR
+call p1();
+--error ER_PROCACCESS_DENIED_ERROR
+call P1();
+--error ER_PROCACCESS_DENIED_ERROR
+select f1(1);
+
+connection default;
+disconnect con1;
+disconnect con2;
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_1@localhost;
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM USER_1@localhost;
+DROP FUNCTION f1;
+DROP PROCEDURE p1;
+DROP USER user_1@localhost;
+DROP USER USER_1@localhost;
+DROP DATABASE db1;
+use test;
+
+# End of 5.0 tests
diff --git a/mysql-test/t/lowercase_mixed_tmpdir_innodb-master.opt b/mysql-test/t/lowercase_mixed_tmpdir_innodb-master.opt
new file mode 100644
index 00000000000..272f91d629c
--- /dev/null
+++ b/mysql-test/t/lowercase_mixed_tmpdir_innodb-master.opt
@@ -0,0 +1,2 @@
+--lower-case-table-names=2
+--tmpdir=$MYSQLTEST_VARDIR/tmp/MixedCase
diff --git a/mysql-test/t/lowercase_mixed_tmpdir_innodb-master.sh b/mysql-test/t/lowercase_mixed_tmpdir_innodb-master.sh
new file mode 100644
index 00000000000..95c26e3aa02
--- /dev/null
+++ b/mysql-test/t/lowercase_mixed_tmpdir_innodb-master.sh
@@ -0,0 +1,6 @@
+# This test requires a non-lowercase tmpdir directory on a case-sensitive
+# filesystem.
+
+d="$MYSQLTEST_VARDIR/tmp/MixedCase"
+test -d "$d" || mkdir "$d"
+rm -f "$d"/*
diff --git a/mysql-test/t/lowercase_mixed_tmpdir_innodb.test b/mysql-test/t/lowercase_mixed_tmpdir_innodb.test
new file mode 100644
index 00000000000..e3b9b7b2a32
--- /dev/null
+++ b/mysql-test/t/lowercase_mixed_tmpdir_innodb.test
@@ -0,0 +1,12 @@
+--source include/have_lowercase2.inc
+--source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+create table t1 (id int) engine=InnoDB;
+insert into t1 values (1);
+create temporary table t2 engine=InnoDB select * from t1;
+drop temporary table t2;
+drop table t1;
diff --git a/mysql-test/t/lowercase_table3.test b/mysql-test/t/lowercase_table3.test
index 4748953fe95..f7ca8211288 100644
--- a/mysql-test/t/lowercase_table3.test
+++ b/mysql-test/t/lowercase_table3.test
@@ -9,7 +9,7 @@
--source include/have_case_insensitive_file_system.inc
--source include/not_windows.inc
-call mtr.add_suppression("Cannot find or open table test/BUG29839 from .*");
+call mtr.add_suppression("Cannot find or open table test/BUG29839 from");
--disable_warnings
DROP TABLE IF EXISTS t1,T1;
diff --git a/mysql-test/t/myisam-system.test b/mysql-test/t/myisam-system.test
index dc5bb58b6a2..d908e639a4e 100644
--- a/mysql-test/t/myisam-system.test
+++ b/mysql-test/t/myisam-system.test
@@ -12,11 +12,11 @@ let $MYSQLD_DATADIR= `select @@datadir`;
drop table if exists t1;
create table t1 (a int) engine=myisam;
--remove_file $MYSQLD_DATADIR/test/t1.MYI
---error 1051,6
+--error ER_BAD_TABLE_ERROR,6
drop table t1;
create table t1 (a int) engine=myisam;
--remove_file $MYSQLD_DATADIR/test/t1.MYD
---error 1105,6,29
+--error ER_BAD_TABLE_ERROR,6,29
drop table t1;
---error 1051
+--error ER_BAD_TABLE_ERROR
drop table t1;
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index 69a0330fd9d..41445cea8ce 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -1549,4 +1549,50 @@ SELECT h+0, d + 0, e, g + 0 FROM t1;
DROP TABLE t1;
+--echo #
+--echo # Test of BUG#35570 CHECKSUM TABLE unreliable if LINESTRING field
+--echo # (same content / differen checksum)
+--echo #
+
+CREATE TABLE t1 (line LINESTRING NOT NULL) engine=myisam;
+INSERT INTO t1 VALUES (GeomFromText("POINT(0 0)"));
+checksum table t1;
+CREATE TABLE t2 (line LINESTRING NOT NULL) engine=myisam;
+INSERT INTO t2 VALUES (GeomFromText("POINT(0 0)"));
+checksum table t2;
+CREATE TABLE t3 select * from t1;
+checksum table t3;
+drop table t1,t2,t3;
+
+
+#
+# BUG#47073 - valgrind errs, corruption,failed repair of partition,
+# low myisam_sort_buffer_size
+#
+CREATE TABLE t1(a INT, b CHAR(10), KEY(a), KEY(b));
+INSERT INTO t1 VALUES(1,'0'),(2,'0'),(3,'0'),(4,'0'),(5,'0'),
+ (6,'0'),(7,'0');
+INSERT INTO t1 SELECT a+10,b FROM t1;
+INSERT INTO t1 SELECT a+20,b FROM t1;
+INSERT INTO t1 SELECT a+40,b FROM t1;
+INSERT INTO t1 SELECT a+80,b FROM t1;
+INSERT INTO t1 SELECT a+160,b FROM t1;
+INSERT INTO t1 SELECT a+320,b FROM t1;
+INSERT INTO t1 SELECT a+640,b FROM t1;
+INSERT INTO t1 SELECT a+1280,b FROM t1;
+INSERT INTO t1 SELECT a+2560,b FROM t1;
+INSERT INTO t1 SELECT a+5120,b FROM t1;
+SET myisam_sort_buffer_size=4;
+REPAIR TABLE t1;
+
+SET myisam_repair_threads=2;
+# May report different values depending on threads activity.
+--disable_result_log
+REPAIR TABLE t1;
+--enable_result_log
+SET myisam_repair_threads=@@global.myisam_repair_threads;
+SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
+CHECK TABLE t1;
+DROP TABLE t1;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/myisam_crash_before_flush_keys.test b/mysql-test/t/myisam_crash_before_flush_keys.test
index d6559f7760d..1860ddd27e3 100644
--- a/mysql-test/t/myisam_crash_before_flush_keys.test
+++ b/mysql-test/t/myisam_crash_before_flush_keys.test
@@ -26,12 +26,6 @@ SET SESSION debug="d,crash_before_flush_keys";
--error 2013
FLUSH TABLE t1;
---echo # Run MYISAMCHK tool to check the table t1 and repair
---replace_result $MYISAMCHK MYISAMCHK $MYSQLD_DATADIR MYSQLD_DATADIR
---error 255
---exec $MYISAMCHK -cs $MYSQLD_DATADIR/test/t1 2>&1
---exec $MYISAMCHK -rs $MYSQLD_DATADIR/test/t1
-
--echo # Write file to make mysql-test-run.pl start the server
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
@@ -42,8 +36,6 @@ FLUSH TABLE t1;
--echo # it to be back online again
--source include/wait_until_connected_again.inc
-SHOW CREATE TABLE t1;
-
-SELECT * FROM t1 FORCE INDEX (PRIMARY);
-
+# Must report that the table wasn't closed properly
+CHECK TABLE t1;
DROP TABLE t1;
diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test
index 7767abe43d0..78661b1bbc4 100644
--- a/mysql-test/t/mysqlbinlog.test
+++ b/mysql-test/t/mysqlbinlog.test
@@ -71,7 +71,8 @@ select "--- --position --" as "";
--enable_query_log
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
---exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --position=239 $MYSQLD_DATADIR/master-bin.000002
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --position=330 $MYSQLD_DATADIR/master-bin.000002
+
# These are tests for remote binlog.
# They should return the same as previous test.
@@ -107,7 +108,7 @@ select "--- --position --" as "";
--enable_query_log
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/
---exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --position=239 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --position=330 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
# Bug#7853 mysqlbinlog does not accept input from stdin
--disable_query_log
@@ -377,6 +378,68 @@ FLUSH LOGS;
# We do not need the results, just make sure that mysqlbinlog does not crash
--exec $MYSQL_BINLOG --hexdump --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 >/dev/null
+#
+# #46998
+# This test verifies if the 'BEGIN', 'COMMIT' and 'ROLLBACK' are output
+# in regardless of database filtering
+#
+
+RESET MASTER;
+FLUSH LOGS;
+
+# The following three test cases were wrtten into binlog_transaction.000001
+# Test case1: Test if the 'BEGIN' and 'COMMIT' are output for the 'test' database
+# in transaction1 base on innodb engine tables
+# use test;
+# create table t1(a int) engine= innodb;
+# use mysql;
+# create table t2(a int) engine= innodb;
+# Transaction1 begin
+# begin;
+# use test;
+# insert into t1 (a) values (1);
+# use mysql;
+# insert into t2 (a) values (1);
+# commit;
+# Transaction1 end
+
+# Test case2: Test if the 'BEGIN' and 'ROLLBACK' are output for the 'test' database
+# in transaction2 base on innodb and myisam engine tables
+# use test;
+# create table t3(a int) engine= innodb;
+# use mysql;
+# create table t4(a int) engine= myisam;
+# Transaction2 begin
+# begin;
+# use test;
+# insert into t3 (a) values (2);
+# use mysql;
+# insert into t4 (a) values (2);
+# rollback;
+# Transaction2 end
+
+# Test case3: Test if the 'BEGIN' and 'COMMIT' are output for the 'test' database
+# in transaction3 base on NDB engine tables
+# use test;
+# create table t5(a int) engine= NDB;
+# use mysql;
+# create table t6(a int) engine= NDB;
+# Transaction3 begin
+# begin;
+# use test;
+# insert into t5 (a) values (3);
+# use mysql;
+# insert into t6 (a) values (3);
+# commit;
+# Transaction3 end
+
+--echo #
+--echo # Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified is exist
+--exec $MYSQL_BINLOG --database=test --short-form $MYSQLTEST_VARDIR/std_data/binlog_transaction.000001
+--echo #
+--echo # Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified is not exist
+--exec $MYSQL_BINLOG --database=not_exist --short-form $MYSQLTEST_VARDIR/std_data/binlog_transaction.000001
+
--echo End of 5.0 tests
--echo End of 5.1 tests
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index 578b2bf5c6c..bcf33aa8c27 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -853,16 +853,21 @@ while ($outer)
eval SELECT '$outer = outer loop variable after dec' AS "";
}
+# Test source in an if in a while which is false on 1st iteration
+# Also test --error in same context
let $outer= 2; # Number of outer loops
+let $ifval= 0; # false 1st time
while ($outer)
{
- eval SELECT '$outer = outer loop variable after while' AS "";
-
- echo here is the sourced script;
+ echo outer=$outer ifval=$ifval;
- eval SELECT '$outer = outer loop variable before dec' AS "";
+ if ($ifval) {
+ --source $MYSQLTEST_VARDIR/tmp/sourced.inc
+ --error ER_NO_SUCH_TABLE
+ SELECT * from nowhere;
+ }
dec $outer;
- eval SELECT '$outer = outer loop variable after dec' AS "";
+ inc $ifval;
}
@@ -1663,6 +1668,20 @@ EOF
remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+# Test append_file within while
+let $outer= 2; # Number of outer loops
+while ($outer)
+{
+ append_file $MYSQLTEST_VARDIR/tmp/app_while.tmp;
+These lines should be repeated,
+if things work as expected
+EOF
+ dec $outer;
+}
+
+cat_file $MYSQLTEST_VARDIR/tmp/app_while.tmp;
+remove_file $MYSQLTEST_VARDIR/tmp/app_while.tmp;
+
# ----------------------------------------------------------------------------
# test for cat_file
# ----------------------------------------------------------------------------
@@ -1710,10 +1729,6 @@ EOF
--diff_files $MYSQLTEST_VARDIR/tmp/diff1.tmp $MYSQLTEST_VARDIR/tmp/diff2.tmp
--diff_files $MYSQLTEST_VARDIR/tmp/diff2.tmp $MYSQLTEST_VARDIR/tmp/diff1.tmp
-# Write the below commands to a intermediary file and execute them with
-# mysqltest in --exec, since the output will vary depending on what "diff"
-# is available it is sent to /dev/null
---write_file $MYSQLTEST_VARDIR/tmp/diff.test
# Compare files that differ in size
--error 2
--diff_files $MYSQLTEST_VARDIR/tmp/diff1.tmp $MYSQLTEST_VARDIR/tmp/diff3.tmp
@@ -1725,13 +1740,6 @@ EOF
--diff_files $MYSQLTEST_VARDIR/tmp/diff1.tmp $MYSQLTEST_VARDIR/tmp/diff4.tmp
--error 1
--diff_files $MYSQLTEST_VARDIR/tmp/diff4.tmp $MYSQLTEST_VARDIR/tmp/diff1.tmp
-exit;
-EOF
-
-# Execute the above diffs, and send their output to /dev/null - only
-# interesting to see that it returns correct error codes
---exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/diff.test > /dev/null 2>&1
-
# Compare equal files, again...
--diff_files $MYSQLTEST_VARDIR/tmp/diff1.tmp $MYSQLTEST_VARDIR/tmp/diff2.tmp
@@ -1740,7 +1748,6 @@ EOF
--remove_file $MYSQLTEST_VARDIR/tmp/diff2.tmp
--remove_file $MYSQLTEST_VARDIR/tmp/diff3.tmp
--remove_file $MYSQLTEST_VARDIR/tmp/diff4.tmp
---remove_file $MYSQLTEST_VARDIR/tmp/diff.test
# ----------------------------------------------------------------------------
diff --git a/mysql-test/t/named_pipe.test b/mysql-test/t/named_pipe.test
index e3dfd24bb52..e88fd8e1ef8 100644
--- a/mysql-test/t/named_pipe.test
+++ b/mysql-test/t/named_pipe.test
@@ -9,6 +9,11 @@ if (`SELECT '$nmp' != 'ON'`){
skip No named pipe support;
}
+# Connect using named pipe for testing
+connect(pipe_con,localhost,root,,,,,PIPE);
+
# Source select test case
-- source include/common-tests.inc
+connection default;
+disconnect pipe_con;
diff --git a/mysql-test/t/not_partition.test b/mysql-test/t/not_partition.test
index 78e6c7495cf..78ca44acf18 100644
--- a/mysql-test/t/not_partition.test
+++ b/mysql-test/t/not_partition.test
@@ -15,7 +15,7 @@ let $MYSQLD_DATADIR= `SELECT @@datadir`;
# Bug#39893: Crash if select on a partitioned table,
# when partitioning is disabled
FLUSH TABLES;
---copy_file $MYSQLTEST_VARDIR/std_data_ln/parts/t1.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file $MYSQLTEST_VARDIR/std_data/parts/t1.frm $MYSQLD_DATADIR/test/t1.frm
SELECT * FROM t1;
TRUNCATE TABLE t1;
ANALYZE TABLE t1;
diff --git a/mysql-test/t/olap.test b/mysql-test/t/olap.test
index d1e40024733..8f672af40a3 100644
--- a/mysql-test/t/olap.test
+++ b/mysql-test/t/olap.test
@@ -375,4 +375,19 @@ INSERT INTO t1 VALUES(0);
SELECT 1 FROM t1 GROUP BY (DATE(NULL)) WITH ROLLUP;
DROP TABLE t1;
+--echo #
+--echo # Bug #48131: crash group by with rollup, distinct,
+--echo # filesort, with temporary tables
+--echo #
+
+CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY);
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (100);
+
+SELECT a, b FROM t1, t2 GROUP BY a, b WITH ROLLUP;
+SELECT DISTINCT b FROM t1, t2 GROUP BY a, b WITH ROLLUP;
+
+DROP TABLE t1, t2;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index e8887c07612..7d461df9cc8 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -1404,3 +1404,35 @@ SELECT DISTINCT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 0, 9;
SELECT DISTINCT a FROM t1 WHERE b = 1 ORDER BY c DESC LIMIT 0, 9;
DROP TABLE t1;
+
+--echo #
+--echo # Bug #43029: FORCE INDEX FOR ORDER BY is ignored when join buffering
+--echo # is used
+--echo #
+
+CREATE TABLE t1 (a INT, b INT, KEY (a));
+
+INSERT INTO t1 VALUES (0, NULL), (1, NULL), (2, NULL), (3, NULL);
+INSERT INTO t1 SELECT a+4, b FROM t1;
+INSERT INTO t1 SELECT a+8, b FROM t1;
+
+CREATE TABLE t2 (a INT, b INT);
+
+INSERT INTO t2 VALUES (0,NULL), (1,NULL), (2,NULL), (3,NULL), (4,NULL);
+INSERT INTO t2 SELECT a+4, b FROM t2;
+
+--echo # shouldn't have "using filesort"
+EXPLAIN
+SELECT * FROM t1 FORCE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
+
+--echo # should have "using filesort"
+EXPLAIN
+SELECT * FROM t1 USE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
+
+--echo # should have "using filesort"
+EXPLAIN
+SELECT * FROM t1 FORCE INDEX FOR JOIN (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
+
+DROP TABLE t1, t2;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test
index c0e7cf2c66c..6fc0ba2a743 100644
--- a/mysql-test/t/partition.test
+++ b/mysql-test/t/partition.test
@@ -62,6 +62,19 @@ SHOW CREATE TABLE t1;
DROP TABLE t1;
#
+# Bug#44059: rec_per_key on empty partition gives weird optimiser results
+#
+create table t1 (a int, b int, key(a))
+partition by list (a)
+( partition p0 values in (1),
+ partition p1 values in (2));
+insert into t1 values (1,1),(2,1),(2,2),(2,3);
+show indexes from t1;
+analyze table t1;
+show indexes from t1;
+drop table t1;
+
+#
# Bug#36001: Partitions: spelling and using some error messages
#
--error ER_FOREIGN_KEY_ON_PARTITIONED
diff --git a/mysql-test/t/partition_csv.test b/mysql-test/t/partition_csv.test
index dd2ef7c1d1f..44013dd4b0a 100644
--- a/mysql-test/t/partition_csv.test
+++ b/mysql-test/t/partition_csv.test
@@ -10,6 +10,8 @@
--source include/have_partition.inc
--source include/have_csv.inc
+call mtr.add_suppression("Failed to write to mysql.general_log");
+
#
# Bug#19307: Partitions: csv delete failure
# = CSV engine crashes
diff --git a/mysql-test/t/partition_innodb.test b/mysql-test/t/partition_innodb.test
index 722fad2919e..6a70f20c7f3 100644
--- a/mysql-test/t/partition_innodb.test
+++ b/mysql-test/t/partition_innodb.test
@@ -6,6 +6,23 @@ drop table if exists t1;
--enable_warnings
#
+# Bug#47029: Crash when reorganize partition with subpartition
+#
+create table t1 (a int not null,
+ b datetime not null,
+ primary key (a,b))
+engine=innodb
+partition by range (to_days(b))
+subpartition by hash (a)
+subpartitions 2
+( partition p0 values less than (to_days('2009-01-01')),
+ partition p1 values less than (to_days('2009-02-01')),
+ partition p2 values less than (to_days('2009-03-01')),
+ partition p3 values less than maxvalue);
+alter table t1 reorganize partition p1,p2 into
+( partition p2 values less than (to_days('2009-03-01')));
+drop table t1;
+#
# Bug#40595: Non-matching rows not released with READ-COMMITTED on tables
# with partitions
CREATE TABLE t1 (id INT PRIMARY KEY, data INT) ENGINE = InnoDB
@@ -270,3 +287,15 @@ PARTITION BY RANGE (int_column)
(PARTITION p1 VALUES LESS THAN (5));
show create table t1;
drop table t1;
+
+#
+# BUG#46483 - drop table of partitioned table may leave extraneous file
+# Note: was only repeatable with InnoDB plugin
+#
+CREATE TABLE t1 (a INT) ENGINE=InnoDB
+ PARTITION BY list(a) (PARTITION p1 VALUES IN (1));
+CREATE INDEX i1 ON t1 (a);
+DROP TABLE t1;
+let $MYSQLD_DATADIR= `SELECT @@datadir`;
+# Before the fix it should show extra file like #sql-2405_2.par
+--list_files $MYSQLD_DATADIR/test/ *
diff --git a/mysql-test/t/partition_innodb_builtin.test b/mysql-test/t/partition_innodb_builtin.test
new file mode 100644
index 00000000000..a9be41c7455
--- /dev/null
+++ b/mysql-test/t/partition_innodb_builtin.test
@@ -0,0 +1,67 @@
+--source include/have_partition.inc
+--source include/have_innodb.inc
+--source include/have_not_innodb_plugin.inc
+
+#
+# Bug#32430 - show engine innodb status causes errors
+#
+SET NAMES utf8;
+CREATE TABLE `t``\""e` (a INT, PRIMARY KEY (a))
+ENGINE=InnoDB
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH (a)
+(PARTITION `p0``\""e` VALUES LESS THAN (100)
+ (SUBPARTITION `sp0``\""e`,
+ SUBPARTITION `sp1``\""e`),
+ PARTITION `p1``\""e` VALUES LESS THAN (MAXVALUE)
+ (SUBPARTITION `sp2``\""e`,
+ SUBPARTITION `sp3``\""e`));
+INSERT INTO `t``\""e` VALUES (0), (2), (6), (10), (14), (18), (22);
+START TRANSACTION;
+--echo # con1
+connect(con1,localhost,root,,);
+SET NAMES utf8;
+START TRANSACTION;
+--echo # default connection
+connection default;
+UPDATE `t``\""e` SET a = 16 WHERE a = 0;
+--echo # con1
+connection con1;
+UPDATE `t``\""e` SET a = 8 WHERE a = 22;
+let $id_1= `SELECT CONNECTION_ID()`;
+SEND;
+UPDATE `t``\""e` SET a = 12 WHERE a = 0;
+--echo # default connection
+connection default;
+let $wait_timeout= 2;
+let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE ID = $id_1 AND STATE = 'Searching rows for update';
+--source include/wait_condition.inc
+#--echo # tested wait condition $wait_condition_reps times
+--error ER_LOCK_DEADLOCK
+UPDATE `t``\""e` SET a = 4 WHERE a = 22;
+--echo # First table reported in 'SHOW ENGINE InnoDB STATUS'
+# RECORD LOCKS space id 0 page no 50 n bits 80 index `PRIMARY` in \
+# Database `test`, Table `t1`, Partition `p0`, Subpartition `sp0` \
+# trx id 0 775
+# NOTE: replace_regex is very slow on match copy/past '(.*)' regex's
+# on big texts, removing a lot of text before + after makes it much faster.
+#/.*in (.*) trx.*/\1/
+--replace_regex /.*RECORD LOCKS space id [0-9]* page no [0-9]* n bits [0-9]* // / trx id .*// /.*index .* in //
+SHOW ENGINE InnoDB STATUS;
+set @old_sql_mode = @@sql_mode;
+set sql_mode = 'ANSI_QUOTES';
+# INNODB_LOCKS only exists in innodb_plugin
+#SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
+--replace_regex /.*RECORD LOCKS space id [0-9]* page no [0-9]* n bits [0-9]* // / trx id .*// /.*index .* in //
+SHOW ENGINE InnoDB STATUS;
+set @@sql_mode = @old_sql_mode;
+--echo # con1
+connection con1;
+REAP;
+ROLLBACK;
+disconnect con1;
+--echo # default connection
+connection default;
+DROP TABLE `t``\""e`;
+SET NAMES DEFAULT;
diff --git a/mysql-test/t/partition_innodb_plugin.test b/mysql-test/t/partition_innodb_plugin.test
new file mode 100644
index 00000000000..fed8c96424a
--- /dev/null
+++ b/mysql-test/t/partition_innodb_plugin.test
@@ -0,0 +1,75 @@
+--source include/have_partition.inc
+--source include/have_innodb.inc
+--source suite/innodb/include/have_innodb_plugin.inc
+
+#
+# Bug#32430 - show engine innodb status causes errors
+#
+SET NAMES utf8;
+CREATE TABLE `t``\""e` (a INT, PRIMARY KEY (a))
+ENGINE=InnoDB
+PARTITION BY RANGE (a)
+SUBPARTITION BY HASH (a)
+(PARTITION `p0``\""e` VALUES LESS THAN (100)
+ (SUBPARTITION `sp0``\""e`,
+ SUBPARTITION `sp1``\""e`),
+ PARTITION `p1``\""e` VALUES LESS THAN (MAXVALUE)
+ (SUBPARTITION `sp2``\""e`,
+ SUBPARTITION `sp3``\""e`));
+INSERT INTO `t``\""e` VALUES (0), (2), (6), (10), (14), (18), (22);
+START TRANSACTION;
+--echo # con1
+connect(con1,localhost,root,,);
+SET NAMES utf8;
+START TRANSACTION;
+--echo # default connection
+connection default;
+UPDATE `t``\""e` SET a = 16 WHERE a = 0;
+--echo # con1
+connection con1;
+UPDATE `t``\""e` SET a = 8 WHERE a = 22;
+let $id_1= `SELECT CONNECTION_ID()`;
+SEND;
+UPDATE `t``\""e` SET a = 12 WHERE a = 0;
+--echo # default connection
+connection default;
+let $wait_timeout= 2;
+let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE ID = $id_1 AND STATE = 'Searching rows for update';
+--source include/wait_condition.inc
+#--echo # tested wait condition $wait_condition_reps times
+# INNODB_LOCKS only exists in innodb_plugin
+--sorted_result
+SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS
+GROUP BY lock_table;
+set @old_sql_mode = @@sql_mode;
+set sql_mode = 'ANSI_QUOTES';
+--sorted_result
+SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS
+GROUP BY lock_table;
+set @@sql_mode = @old_sql_mode;
+--error ER_LOCK_DEADLOCK
+UPDATE `t``\""e` SET a = 4 WHERE a = 22;
+--echo # First table reported in 'SHOW ENGINE InnoDB STATUS'
+# RECORD LOCKS space id 0 page no 50 n bits 80 index `PRIMARY` in \
+# Database `test`, Table `t1`, Partition `p0`, Subpartition `sp0` \
+# trx id 0 775
+# NOTE: replace_regex is very slow on match copy/past '(.*)' regex's
+# on big texts, removing a lot of text before + after makes it much faster.
+#/.*in (.*) trx.*/\1/
+--replace_regex /.*RECORD LOCKS space id [0-9]* page no [0-9]* n bits [0-9]* // / trx id .*// /.*index .* in //
+SHOW ENGINE InnoDB STATUS;
+set @old_sql_mode = @@sql_mode;
+set sql_mode = 'ANSI_QUOTES';
+--replace_regex /.*RECORD LOCKS space id [0-9]* page no [0-9]* n bits [0-9]* // / trx id .*// /.*index .* in //
+SHOW ENGINE InnoDB STATUS;
+set @@sql_mode = @old_sql_mode;
+--echo # con1
+connection con1;
+REAP;
+ROLLBACK;
+disconnect con1;
+--echo # default connection
+connection default;
+DROP TABLE `t``\""e`;
+SET NAMES DEFAULT;
diff --git a/mysql-test/t/partition_open_files_limit-master.opt b/mysql-test/t/partition_open_files_limit-master.opt
new file mode 100644
index 00000000000..4c1ed0c3da3
--- /dev/null
+++ b/mysql-test/t/partition_open_files_limit-master.opt
@@ -0,0 +1 @@
+--open-files-limit=5 --max_connections=2 --table_open_cache=1
diff --git a/mysql-test/t/partition_open_files_limit.test b/mysql-test/t/partition_open_files_limit.test
new file mode 100644
index 00000000000..e62ebd0ade7
--- /dev/null
+++ b/mysql-test/t/partition_open_files_limit.test
@@ -0,0 +1,26 @@
+--source include/have_partition.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS `t1`;
+--enable_warnings
+
+# On some platforms the lowest possible open_files_limit is too high...
+let $max_open_files_limit= `SELECT @@open_files_limit > 511`;
+if ($max_open_files_limit)
+{
+ skip Need open_files_limit to be lower than 512;
+}
+
+#
+--echo # Bug#46922: crash when adding partitions and open_files_limit is reached
+#
+CREATE TABLE t1 (a INT PRIMARY KEY)
+ENGINE=MyISAM PARTITION BY KEY () PARTITIONS 1;
+INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11);
+--echo # if the bug exists, then crash will happen here
+--replace_regex /file '.*'/file '<partition file>'/
+--error 23
+ALTER TABLE t1 ADD PARTITION PARTITIONS 511;
+--sorted_result
+SELECT * FROM t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/plugin.test b/mysql-test/t/plugin.test
index 7fc62b445c9..788a7b336ef 100644
--- a/mysql-test/t/plugin.test
+++ b/mysql-test/t/plugin.test
@@ -1,3 +1,4 @@
+--source include/not_windows_embedded.inc
--source include/have_example_plugin.inc
CREATE TABLE t1(a int) ENGINE=EXAMPLE;
diff --git a/mysql-test/t/plugin_load.test b/mysql-test/t/plugin_load.test
index 8555247dd71..97b2afbe219 100644
--- a/mysql-test/t/plugin_load.test
+++ b/mysql-test/t/plugin_load.test
@@ -1,3 +1,4 @@
+--source include/not_windows_embedded.inc
--source include/have_example_plugin.inc
SELECT @@global.example_enum_var = 'e2';
diff --git a/mysql-test/t/ps_not_windows.test b/mysql-test/t/ps_not_windows.test
index 1dceacd73da..0ab08b59f1e 100644
--- a/mysql-test/t/ps_not_windows.test
+++ b/mysql-test/t/ps_not_windows.test
@@ -2,7 +2,7 @@
--source include/not_embedded.inc
# Non-windows specific ps tests.
--source include/not_windows.inc
-# Requires ability to install plugins.
+# requires dynamic loading
--source include/have_dynamic_loading.inc
#
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index 9a1547fa3d4..3d9045d3aa6 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -1294,7 +1294,7 @@ SET GLOBAL query_cache_size= default;
# Bug #31157: Crash when select+order by the avg of some field within the
# group by
#
-
+SET GLOBAL query_cache_size=1024*1024*512;
CREATE TABLE t1 (a ENUM('rainbow'));
INSERT INTO t1 VALUES (),(),(),(),();
SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
@@ -1305,6 +1305,7 @@ INSERT INTO t1 SET a = 'aaaa';
SELECT 1 FROM t1 GROUP BY
(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
DROP TABLE t1;
+SET GLOBAL query_cache_size= default;
--echo End of 5.1 tests
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index e1411e7fd46..3a845471cd0 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -1046,3 +1046,218 @@ explain select * from t2 where a=1000 and b<11;
drop table t1, t2;
+#
+# Bug#42846: wrong result returned for range scan when using covering index
+#
+CREATE TABLE t1( a INT, b INT, KEY( a, b ) );
+
+CREATE TABLE t2( a INT, b INT, KEY( a, b ) );
+
+CREATE TABLE t3( a INT, b INT, KEY( a, b ) );
+
+INSERT INTO t1( a, b )
+VALUES (0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7);
+
+INSERT INTO t2( a, b )
+VALUES ( 1, 1), ( 2, 1), ( 3, 1), ( 4, 1), ( 5, 1),
+ ( 6, 1), ( 7, 1), ( 8, 1), ( 9, 1), (10, 1),
+ (11, 1), (12, 1), (13, 1), (14, 1), (15, 1),
+ (16, 1), (17, 1), (18, 1), (19, 1), (20, 1);
+
+INSERT INTO t2 SELECT a, 2 FROM t2 WHERE b = 1;
+INSERT INTO t2 SELECT a, 3 FROM t2 WHERE b = 1;
+
+# To make range scan compelling to the optimizer
+INSERT INTO t2 SELECT -1, -1 FROM t2;
+INSERT INTO t2 SELECT -1, -1 FROM t2;
+INSERT INTO t2 SELECT -1, -1 FROM t2;
+
+INSERT INTO t3
+VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0),
+ (6, 0), (7, 0), (8, 0), (9, 0), (10, 0);
+
+# To make range scan compelling to the optimizer
+INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
+INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
+
+
+#
+# Problem#1 Test queries. Will give missing results unless Problem#1 is fixed.
+# With one exception, they are independent of Problem#2.
+#
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 < a AND b = 3 OR
+3 <= a;
+
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 < a AND b = 3 OR
+3 <= a;
+
+# Query below: Tests both Problem#1 and Problem#2 (EXPLAIN differs as well)
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+3 <= a;
+
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+3 <= a;
+
+#
+# Problem#2 Test queries.
+# These queries will give missing results if Problem#1 is fixed.
+# But Problem#1 also hides this bug.
+#
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 1 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+
+EXPLAIN
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 1 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 2 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+
+EXPLAIN
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 2 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+
+SELECT * FROM t3 WHERE
+5 <= a AND a < 10 AND b = 3 OR
+a < 5 OR
+a < 10;
+
+EXPLAIN
+SELECT * FROM t3 WHERE
+5 <= a AND a < 10 AND b = 3 OR
+a < 5 OR
+a < 10;
+
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # Bug #47123: Endless 100% CPU loop with STRAIGHT_JOIN
+--echo #
+
+CREATE TABLE t1(a INT, KEY(a));
+INSERT INTO t1 VALUES (1), (NULL);
+SELECT * FROM t1 WHERE a <> NULL and (a <> NULL or a <= NULL);
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#47925: regression of range optimizer and date comparison in 5.1.39!
+--echo #
+CREATE TABLE t1 ( a DATE, KEY ( a ) );
+CREATE TABLE t2 ( a DATETIME, KEY ( a ) );
+
+--echo # Make optimizer choose range scan
+INSERT INTO t1 VALUES ('2009-09-22'), ('2009-09-22'), ('2009-09-22');
+INSERT INTO t1 VALUES ('2009-09-23'), ('2009-09-23'), ('2009-09-23');
+
+INSERT INTO t2 VALUES ('2009-09-22 12:00:00'), ('2009-09-22 12:00:00'),
+ ('2009-09-22 12:00:00');
+INSERT INTO t2 VALUES ('2009-09-23 12:00:00'), ('2009-09-23 12:00:00'),
+ ('2009-09-23 12:00:00');
+
+--echo # DATE vs DATE
+--replace_column 1 X 2 X 3 X 7 X 8 X 9 X 10 X
+EXPLAIN
+SELECT * FROM t1 WHERE a >= '2009/09/23';
+SELECT * FROM t1 WHERE a >= '2009/09/23';
+SELECT * FROM t1 WHERE a >= '20090923';
+SELECT * FROM t1 WHERE a >= 20090923;
+SELECT * FROM t1 WHERE a >= '2009-9-23';
+SELECT * FROM t1 WHERE a >= '2009.09.23';
+SELECT * FROM t1 WHERE a >= '2009:09:23';
+
+--echo # DATE vs DATETIME
+--replace_column 1 X 2 X 3 X 7 X 8 X 9 X 10 X
+EXPLAIN
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+SELECT * FROM t2 WHERE a >= '20090923';
+SELECT * FROM t2 WHERE a >= 20090923;
+SELECT * FROM t2 WHERE a >= '2009-9-23';
+SELECT * FROM t2 WHERE a >= '2009.09.23';
+SELECT * FROM t2 WHERE a >= '2009:09:23';
+
+--echo # DATETIME vs DATETIME
+--replace_column 1 X 2 X 3 X 7 X 8 X 9 X 10 X
+EXPLAIN
+SELECT * FROM t2 WHERE a >= '2009/09/23 12:00:00';
+SELECT * FROM t2 WHERE a >= '2009/09/23 12:00:00';
+SELECT * FROM t2 WHERE a >= '20090923120000';
+SELECT * FROM t2 WHERE a >= 20090923120000;
+SELECT * FROM t2 WHERE a >= '2009-9-23 12:00:00';
+SELECT * FROM t2 WHERE a >= '2009.09.23 12:00:00';
+SELECT * FROM t2 WHERE a >= '2009:09:23 12:00:00';
+
+--echo # DATETIME vs DATE
+--replace_column 1 X 2 X 3 X 7 X 8 X 9 X 10 X
+EXPLAIN
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+SELECT * FROM t1 WHERE a >= '20090923000000';
+SELECT * FROM t1 WHERE a >= 20090923000000;
+SELECT * FROM t1 WHERE a >= '2009-9-23 00:00:00';
+SELECT * FROM t1 WHERE a >= '2009.09.23 00:00:00';
+SELECT * FROM t1 WHERE a >= '2009:09:23 00:00:00';
+
+--echo # Test of the new get_date_from_str implementation
+--echo # Behavior differs slightly between the trunk and mysql-pe.
+--echo # The former may give errors for the truncated values, while the latter
+--echo # gives warnings. The purpose of this test is not to interfere, and only
+--echo # preserve existing behavior.
+SELECT str_to_date('2007-10-00', '%Y-%m-%d') >= '' AND
+ str_to_date('2007-10-00', '%Y-%m-%d') <= '2007/10/20';
+
+SELECT str_to_date('2007-20-00', '%Y-%m-%d') >= '2007/10/20' AND
+ str_to_date('2007-20-00', '%Y-%m-%d') <= '';
+
+SELECT str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20';
+SELECT str_to_date('2007-20-00', '%Y-%m-%d') BETWEEN '2007/10/20' AND '';
+
+SELECT str_to_date('', '%Y-%m-%d');
+
+DROP TABLE t1, t2;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 7d3785ecccc..51f0cd73374 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -3739,7 +3739,40 @@ EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND a = b LIMIT 2;
EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND b = a LIMIT 2;
DROP TABLE t1;
+
+
+--echo #
+--echo # Bug#47019: Assertion failed: 0, file .\rt_mbr.c, line 138 when
+--echo # forcing a spatial index
+--echo #
+CREATE TABLE t1(a LINESTRING NOT NULL, SPATIAL KEY(a));
+INSERT INTO t1 VALUES
+ (GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)')),
+ (GEOMFROMTEXT('LINESTRING(-1 -1, 1 -1, -1 -1, -1 1, 1 1)'));
+EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
+SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2;
+EXPLAIN SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
+SELECT 1 FROM t1 NATURAL LEFT JOIN t1 AS t2 FORCE INDEX(a);
+DROP TABLE t1;
+
+
+--echo #
+--echo # Bug #48291 : crash with row() operator,select into @var, and
+--echo # subquery returning multiple rows
+--echo #
+
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (2),(3);
+
+--echo # Should not crash
+--error ER_SUBQUERY_NO_1_ROW
+SELECT 1 FROM t1 WHERE a <> 1 AND NOT
+ROW(a,a) <=> ROW((SELECT 1 FROM t1 WHERE 1=2),(SELECT 1 FROM t1))
+INTO @var0;
+
+DROP TABLE t1;
+
--echo End of 5.0 tests
#
diff --git a/mysql-test/t/sp-bugs.test b/mysql-test/t/sp-bugs.test
new file mode 100644
index 00000000000..7b94e65a5e9
--- /dev/null
+++ b/mysql-test/t/sp-bugs.test
@@ -0,0 +1,61 @@
+# Test file for stored procedure bugfixes
+
+--echo #
+--echo # Bug #47412: Valgrind warnings / user can read uninitalized memory
+--echo # using SP variables
+--echo #
+
+CREATE SCHEMA testdb;
+USE testdb;
+DELIMITER |;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+ RETURN f_not_exists () ;
+END|
+CREATE PROCEDURE p3 ( arg1 VARCHAR(32) )
+BEGIN
+ CALL p_not_exists ( );
+END|
+DELIMITER ;|
+--echo # should not return valgrind warnings
+--error ER_SP_DOES_NOT_EXIST
+CALL p3 ( f2 () );
+
+DROP SCHEMA testdb;
+
+CREATE SCHEMA testdb;
+USE testdb;
+DELIMITER |;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+ RETURN f_not_exists () ;
+END|
+CREATE PROCEDURE p3 ( arg2 INTEGER )
+BEGIN
+ CALL p_not_exists ( );
+END|
+DELIMITER ;|
+--echo # should not return valgrind warnings
+--error ER_SP_DOES_NOT_EXIST
+CALL p3 ( f2 () );
+
+DROP SCHEMA testdb;
+
+CREATE SCHEMA testdb;
+USE testdb;
+DELIMITER |;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+ RETURN f_not_exists () ;
+END|
+DELIMITER ;|
+--echo # should not return valgrind warnings
+SELECT f2 ();
+
+DROP SCHEMA testdb;
+
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index 66b960c938f..18a4a117939 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -2448,3 +2448,27 @@ SELECT AVG (a) FROM t1 WHERE b = 999999;
--error ER_SP_DOES_NOT_EXIST
SELECT non_existent (a) FROM t1 WHERE b = 999999;
DROP TABLE t1;
+
+--echo #
+--echo # Bug #47788: Crash in TABLE_LIST::hide_view_error on UPDATE + VIEW +
+--echo # SP + MERGE + ALTER
+--echo #
+
+CREATE TABLE t1 (pk INT, b INT, KEY (b));
+CREATE ALGORITHM = TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+
+CREATE PROCEDURE p1 (a int) UPDATE IGNORE v1 SET b = a;
+
+--error ER_NON_UPDATABLE_TABLE
+CALL p1(5);
+
+ALTER TABLE t1 CHANGE COLUMN b b2 INT;
+
+--error ER_VIEW_INVALID
+CALL p1(7);
+
+DROP PROCEDURE p1;
+DROP VIEW v1;
+DROP TABLE t1;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 5eeac457958..44c4556340e 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -8242,6 +8242,28 @@ while ($tab_count)
DROP PROCEDURE p1;
DROP TABLE t1;
+
+--echo #
+--echo # Bug #46629: Item_in_subselect::val_int(): Assertion `0'
+--echo # on subquery inside a SP
+--echo #
+CREATE TABLE t1(a INT);
+CREATE TABLE t2(a INT, b INT PRIMARY KEY);
+
+DELIMITER |;
+CREATE PROCEDURE p1 ()
+BEGIN
+ SELECT a FROM t1 A WHERE A.b IN (SELECT b FROM t2 AS B);
+END|
+DELIMITER ;|
+--error ER_BAD_FIELD_ERROR
+CALL p1;
+--error ER_BAD_FIELD_ERROR
+CALL p1;
+DROP PROCEDURE p1;
+DROP TABLE t1, t2;
+
+
--echo # ------------------------------------------------------------------
--echo # -- End of 5.1 tests
--echo # ------------------------------------------------------------------
diff --git a/mysql-test/t/status-master.opt b/mysql-test/t/status-master.opt
new file mode 100644
index 00000000000..eb3bb4fe50d
--- /dev/null
+++ b/mysql-test/t/status-master.opt
@@ -0,0 +1 @@
+--log-output=table,file
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index ead7c89d1c0..2391554dccd 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -30,7 +30,7 @@ SELECT 1 IN (SELECT 1);
SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
-- error ER_WRONG_USAGE
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
--- error ER_WRONG_USAGE
+-- error ER_WRONG_PARAMETERS_TO_PROCEDURE
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
-- error ER_BAD_FIELD_ERROR
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
@@ -3554,4 +3554,19 @@ where v in(select v
where t1.g=t2.g) is unknown;
drop table t1, t2;
+#
+# Bug #31157: Crash when select+order by the avg of some field within the
+# group by
+#
+CREATE TABLE t1 (a ENUM('rainbow'));
+INSERT INTO t1 VALUES (),(),(),(),();
+SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
+DROP TABLE t1;
+CREATE TABLE t1 (a LONGBLOB);
+INSERT INTO t1 SET a = 'aaaa';
+INSERT INTO t1 SET a = 'aaaa';
+SELECT 1 FROM t1 GROUP BY
+ (SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
+DROP TABLE t1;
+
--echo End of 5.1 tests.
diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test
index ee90fb9ff52..8d403279a48 100644
--- a/mysql-test/t/subselect3.test
+++ b/mysql-test/t/subselect3.test
@@ -730,3 +730,69 @@ where
from t4, t5 limit 2));
drop table t0, t1, t2, t3, t4, t5;
+
+--echo #
+--echo # BUG#48177 - SELECTs with NOT IN subqueries containing NULL
+--echo # values return too many records
+--echo #
+
+CREATE TABLE t1 (
+ i1 int DEFAULT NULL,
+ i2 int DEFAULT NULL
+) ;
+
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (2, 3);
+INSERT INTO t1 VALUES (4, NULL);
+INSERT INTO t1 VALUES (4, 0);
+INSERT INTO t1 VALUES (NULL, NULL);
+
+CREATE TABLE t2 (
+ i1 int DEFAULT NULL,
+ i2 int DEFAULT NULL
+) ;
+
+INSERT INTO t2 VALUES (4, NULL);
+INSERT INTO t2 VALUES (5, 0);
+
+--echo
+--echo Data in t1
+SELECT i1, i2 FROM t1;
+
+--echo
+--echo Data in subquery (should be filtered out)
+SELECT i1, i2 FROM t2 ORDER BY i1;
+
+FLUSH STATUS;
+
+--echo
+SELECT i1, i2
+FROM t1
+WHERE (i1, i2)
+ NOT IN (SELECT i1, i2 FROM t2);
+
+--echo
+--echo # Check that the subquery only has to be evaluated once
+--echo # for all-NULL values even though there are two (NULL,NULL) records
+--echo # Baseline:
+SHOW STATUS LIKE '%Handler_read_rnd_next';
+
+--echo
+INSERT INTO t1 VALUES (NULL, NULL);
+FLUSH STATUS;
+
+--echo
+SELECT i1, i2
+FROM t1
+WHERE (i1, i2)
+ NOT IN (SELECT i1, i2 FROM t2);
+
+--echo
+--echo # Handler_read_rnd_next should be one more than baseline
+--echo # (read record from t1, but do not read from t2)
+SHOW STATUS LIKE '%Handler_read_rnd_next';
+
+
+DROP TABLE t1,t2;
+
+--echo End of 5.1 tests
diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test
new file mode 100644
index 00000000000..440eca22828
--- /dev/null
+++ b/mysql-test/t/subselect4.test
@@ -0,0 +1,64 @@
+# General purpose bug fix tests go here : subselect.test too large
+
+
+--echo #
+--echo # Bug #46791: Assertion failed:(table->key_read==0),function unknown
+--echo # function,file sql_base.cc
+--echo #
+
+CREATE TABLE t1 (a INT, b INT, KEY(a));
+INSERT INTO t1 VALUES (1,1),(2,2);
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 VALUES (1,1),(2,2);
+CREATE TABLE t3 LIKE t1;
+
+--echo # should have 1 impossible where and 2 dependent subqueries
+EXPLAIN
+SELECT 1 FROM t1
+WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))
+ORDER BY count(*);
+
+--echo # should not crash the next statement
+SELECT 1 FROM t1
+WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))
+ORDER BY count(*);
+
+--echo # should not crash: the crash is caused by the previous statement
+SELECT 1;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #47106: Crash / segfault on adding EXPLAIN to a non-crashing
+--echo # query
+--echo #
+
+CREATE TABLE t1 (
+ a INT,
+ b INT,
+ PRIMARY KEY (a),
+ KEY b (b)
+);
+INSERT INTO t1 VALUES (1, 1), (2, 1);
+
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 SELECT * FROM t1;
+
+CREATE TABLE t3 LIKE t1;
+INSERT INTO t3 SELECT * FROM t1;
+
+--echo # Should not crash.
+--echo # Should have 1 impossible where and 2 dependent subqs.
+EXPLAIN
+SELECT
+ (SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
+FROM t3 WHERE 1 = 0 GROUP BY 1;
+
+--echo # should return 0 rows
+SELECT
+ (SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
+FROM t3 WHERE 1 = 0 GROUP BY 1;
+
+DROP TABLE t1,t2,t3;
+
+--echo End of 5.0 tests.
diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test
index dc5120db430..530389b3ab9 100644
--- a/mysql-test/t/type_bit.test
+++ b/mysql-test/t/type_bit.test
@@ -397,6 +397,17 @@ insert into t2bit7 values (b'110011011111111');
select bin(a1) from t1bit7, t2bit7 where t1bit7.a1=t2bit7.b1;
drop table t1bit7, t2bit7;
+
+--echo #
+--echo # Bug42803: Field_bit does not have unsigned_flag field,
+--echo # can lead to bad memory access
+--echo #
+CREATE TABLE t1 (a BIT(7), b BIT(9), KEY(a, b));
+INSERT INTO t1 VALUES(0, 0), (5, 3), (5, 6), (6, 4), (7, 0);
+EXPLAIN SELECT a+0, b+0 FROM t1 WHERE a > 4 and b < 7 ORDER BY 2;
+DROP TABLE t1;
+
+
--echo End of 5.0 tests
#
diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test
index 65bafaae77e..cd3c3f81510 100644
--- a/mysql-test/t/type_newdecimal.test
+++ b/mysql-test/t/type_newdecimal.test
@@ -1286,137 +1286,3 @@ CREATE TABLE t1 SELECT 1 % .1234567891234567891234567891234567891234567891234567
DESCRIBE t1;
SELECT my_col FROM t1;
DROP TABLE t1;
-
---echo #
---echo # Bug#45261: Crash, stored procedure + decimal
---echo #
-
---disable_warnings
-DROP TABLE IF EXISTS t1;
---enable_warnings
-
-CREATE TABLE t1 SELECT
- /* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 81 */ 100000000000000000000000000000000000000000000000000000000000000000000000000000001.1 /* 1 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 82 */ 1000000000000000000000000000000000000000000000000000000000000000000000000000000001
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 40 */ 1000000000000000000000000000000000000001.1000000000000000000000000000000000000001 /* 40 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 1 */ 1.10000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 80 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 1 */ 1.100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- .100000000000000000000000000000000000000000000000000000000000000000000000000000001 /* 81 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 45 */ 123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345 /* 45 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 65 */ 12345678901234567890123456789012345678901234567890123456789012345.1 /* 1 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- /* 66 */ 123456789012345678901234567890123456789012345678901234567890123456.1 /* 1 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT
- .123456789012345678901234567890123456789012345678901234567890123456 /* 66 */
- AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 AS SELECT 123.1234567890123456789012345678901 /* 31 */ AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
-CREATE TABLE t1 SELECT 1.1 + CAST(1 AS DECIMAL(65,30)) AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
---echo #
---echo # Test that the integer and decimal parts are properly calculated.
---echo #
-
-CREATE TABLE t1 (a DECIMAL(30,30));
-INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
-CREATE TABLE t2 SELECT MIN(a + 0.0000000000000000000000000000001) AS c1 FROM t1;
-DESC t2;
-DROP TABLE t1,t2;
-
-CREATE TABLE t1 (a DECIMAL(30,30));
-INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
-CREATE TABLE t2 SELECT IFNULL(a + 0.0000000000000000000000000000001, NULL) AS c1 FROM t1;
-DESC t2;
-DROP TABLE t1,t2;
-
-CREATE TABLE t1 (a DECIMAL(30,30));
-INSERT INTO t1 VALUES (0.1),(0.2),(0.3);
-CREATE TABLE t2 SELECT CASE a WHEN 0.1 THEN 0.0000000000000000000000000000000000000000000000000000000000000000001 END AS c1 FROM t1;
-DESC t2;
-DROP TABLE t1,t2;
-
---echo #
---echo # Test that variables get maximum precision.
---echo #
-
-SET @decimal= 1.1;
-CREATE TABLE t1 SELECT @decimal AS c1;
-DESC t1;
-SELECT * FROM t1;
-DROP TABLE t1;
diff --git a/mysql-test/t/udf.test b/mysql-test/t/udf.test
index e9ae1a31079..7bf252040e5 100644
--- a/mysql-test/t/udf.test
+++ b/mysql-test/t/udf.test
@@ -436,4 +436,16 @@ SELECT * FROM t2 WHERE a = sequence();
DROP FUNCTION sequence;
DROP TABLE t1,t2;
+--echo #
+--echo # Bug#46259: 5.0.83 -> 5.1.36, query doesn't work
+--echo #
+CREATE TABLE t1 ( a INT );
+
+INSERT INTO t1 VALUES (1), (2), (3);
+
+SELECT IF( a = 1, a, a ) AS `b` FROM t1 ORDER BY field( `b` + 1, 1 );
+SELECT IF( a = 1, a, a ) AS `b` FROM t1 ORDER BY field( `b`, 1 );
+
+DROP TABLE t1;
+
--echo End of 5.0 tests.
diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test
index 7d56df259ba..02e8763a630 100644
--- a/mysql-test/t/update.test
+++ b/mysql-test/t/update.test
@@ -452,3 +452,18 @@ DROP TABLE t1;
DROP FUNCTION f1;
--echo End of 5.0 tests
+
+--echo #
+--echo # Bug #47919 assert in open_table during ALTER temporary table
+--echo #
+
+CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT, PRIMARY KEY (f1));
+CREATE TEMPORARY TABLE t2 LIKE t1;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+
+ALTER TABLE t2 COMMENT = 'ABC';
+UPDATE t2, t1 SET t2.f1 = 2, t1.f1 = 9;
+ALTER TABLE t2 COMMENT = 'DEF';
+
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/upgrade.test b/mysql-test/t/upgrade.test
index d571a2efc7c..e390e8a1253 100644
--- a/mysql-test/t/upgrade.test
+++ b/mysql-test/t/upgrade.test
@@ -124,6 +124,8 @@ with_check_option=0
timestamp=2009-04-10 11:53:37
create-version=1
source=select f1 from `a-b-c`.t1 a, information_schema.tables b\nwhere a.f1 = b.table_name
+client_cs_name=utf8
+connection_cl_name=utf8_general_ci
EOF
show databases like '%a-b-c%';
diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test
index 824c67d867e..175468db702 100644
--- a/mysql-test/t/view_grant.test
+++ b/mysql-test/t/view_grant.test
@@ -1382,6 +1382,153 @@ DROP VIEW test.v3;
DROP USER mysqluser1@localhost;
USE test;
+--echo #
+--echo # Bug#35996: SELECT + SHOW VIEW should be enough to display view
+--echo # definition
+--echo #
+-- source include/not_embedded.inc
+CREATE USER mysqluser1@localhost;
+CREATE DATABASE mysqltest1;
+CREATE DATABASE mysqltest2;
+GRANT USAGE, SELECT, CREATE VIEW, SHOW VIEW
+ON mysqltest2.* TO mysqluser1@localhost;
+
+USE mysqltest1;
+
+CREATE TABLE t1( a INT );
+CREATE TABLE t2( a INT, b INT );
+CREATE FUNCTION f1() RETURNS INT RETURN 1;
+CREATE VIEW v1 AS SELECT 1 AS a;
+CREATE VIEW v2 AS SELECT 1 AS a, 2 AS b;
+
+GRANT SELECT ON TABLE t1 TO mysqluser1@localhost;
+GRANT SELECT (a, b) ON TABLE t2 TO mysqluser1@localhost;
+GRANT EXECUTE ON FUNCTION f1 TO mysqluser1@localhost;
+GRANT SELECT ON TABLE v1 TO mysqluser1@localhost;
+GRANT SELECT (a, b) ON TABLE v2 TO mysqluser1@localhost;
+
+CREATE VIEW v_t1 AS SELECT * FROM t1;
+CREATE VIEW v_t2 AS SELECT * FROM t2;
+CREATE VIEW v_f1 AS SELECT f1() AS a;
+CREATE VIEW v_v1 AS SELECT * FROM v1;
+CREATE VIEW v_v2 AS SELECT * FROM v2;
+
+GRANT SELECT, SHOW VIEW ON v_t1 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_t2 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_f1 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_v1 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_v2 TO mysqluser1@localhost;
+
+--connect (connection1, localhost, mysqluser1,, mysqltest2)
+CREATE VIEW v_mysqluser1_t1 AS SELECT * FROM mysqltest1.t1;
+CREATE VIEW v_mysqluser1_t2 AS SELECT * FROM mysqltest1.t2;
+CREATE VIEW v_mysqluser1_f1 AS SELECT mysqltest1.f1() AS a;
+CREATE VIEW v_mysqluser1_v1 AS SELECT * FROM mysqltest1.v1;
+CREATE VIEW v_mysqluser1_v2 AS SELECT * FROM mysqltest1.v2;
+
+SHOW CREATE VIEW mysqltest1.v_t1;
+SHOW CREATE VIEW mysqltest1.v_t2;
+SHOW CREATE VIEW mysqltest1.v_f1;
+SHOW CREATE VIEW mysqltest1.v_v1;
+SHOW CREATE VIEW mysqltest1.v_v2;
+
+SHOW CREATE VIEW v_mysqluser1_t1;
+SHOW CREATE VIEW v_mysqluser1_t2;
+SHOW CREATE VIEW v_mysqluser1_f1;
+SHOW CREATE VIEW v_mysqluser1_v1;
+SHOW CREATE VIEW v_mysqluser1_v2;
+
+--connection default
+REVOKE SELECT ON TABLE t1 FROM mysqluser1@localhost;
+REVOKE SELECT (a) ON TABLE t2 FROM mysqluser1@localhost;
+REVOKE EXECUTE ON FUNCTION f1 FROM mysqluser1@localhost;
+REVOKE SELECT ON TABLE v1 FROM mysqluser1@localhost;
+
+--connection connection1
+SHOW CREATE VIEW mysqltest1.v_t1;
+SHOW CREATE VIEW mysqltest1.v_t2;
+SHOW CREATE VIEW mysqltest1.v_f1;
+SHOW CREATE VIEW mysqltest1.v_v1;
+SHOW CREATE VIEW mysqltest1.v_v2;
+
+SHOW CREATE VIEW v_mysqluser1_t1;
+SHOW CREATE VIEW v_mysqluser1_t2;
+SHOW CREATE VIEW v_mysqluser1_f1;
+SHOW CREATE VIEW v_mysqluser1_v1;
+SHOW CREATE VIEW v_mysqluser1_v2;
+
+--connection default
+--echo # Testing the case when the views reference missing objects.
+--echo # Obviously, there are no privileges to check for, so we
+--echo # need only each object type once.
+DROP TABLE t1;
+DROP FUNCTION f1;
+DROP VIEW v1;
+
+--connection connection1
+SHOW CREATE VIEW mysqltest1.v_t1;
+SHOW CREATE VIEW mysqltest1.v_f1;
+SHOW CREATE VIEW mysqltest1.v_v1;
+
+SHOW CREATE VIEW v_mysqluser1_t1;
+SHOW CREATE VIEW v_mysqluser1_f1;
+SHOW CREATE VIEW v_mysqluser1_v1;
+
+--connection default
+REVOKE SHOW VIEW ON v_t1 FROM mysqluser1@localhost;
+REVOKE SHOW VIEW ON v_f1 FROM mysqluser1@localhost;
+REVOKE SHOW VIEW ON v_v1 FROM mysqluser1@localhost;
+
+--connection connection1
+--error ER_TABLEACCESS_DENIED_ERROR
+SHOW CREATE VIEW mysqltest1.v_t1;
+--error ER_TABLEACCESS_DENIED_ERROR
+SHOW CREATE VIEW mysqltest1.v_f1;
+--error ER_TABLEACCESS_DENIED_ERROR
+SHOW CREATE VIEW mysqltest1.v_v1;
+SHOW CREATE VIEW v_mysqluser1_t1;
+SHOW CREATE VIEW v_mysqluser1_f1;
+SHOW CREATE VIEW v_mysqluser1_v1;
+
+--disconnect connection1
+--connection default
+DROP USER mysqluser1@localhost;
+DROP DATABASE mysqltest1;
+DROP DATABASE mysqltest2;
+USE test;
+
+CREATE TABLE t1( a INT );
+CREATE DEFINER = no_such_user@no_such_host VIEW v1 AS SELECT * FROM t1;
+SHOW CREATE VIEW v1;
+DROP TABLE t1;
+DROP VIEW v1;
+
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
+--echo #
+--echo # Bug #46019: ERROR 1356 When selecting from within another
+--echo # view that has Group By
+--echo #
+CREATE DATABASE mysqltest1;
+USE mysqltest1;
+
+CREATE TABLE t1 (a INT);
+
+CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT a FROM t1 GROUP BY a;
+CREATE SQL SECURITY INVOKER VIEW v2 AS SELECT a FROM v1;
+
+CREATE USER mysqluser1;
+
+GRANT SELECT ON TABLE t1 TO mysqluser1;
+GRANT SELECT, SHOW VIEW ON TABLE v1 TO mysqluser1;
+GRANT SELECT, SHOW VIEW ON TABLE v2 TO mysqluser1;
+
+--connect (mysqluser1, localhost, mysqluser1,,mysqltest1)
+SELECT a FROM v1;
+SELECT a FROM v2;
+
+--connection default
+--disconnect mysqluser1
+DROP USER mysqluser1;
+DROP DATABASE mysqltest1;
diff --git a/mysql-test/t/warnings.test b/mysql-test/t/warnings.test
index b8235825cf2..3c9129aedb1 100644
--- a/mysql-test/t/warnings.test
+++ b/mysql-test/t/warnings.test
@@ -227,4 +227,11 @@ insert into t2 values(@q);
drop table t1, t2;
+#
+# Bug#42364 SHOW ERRORS returns empty resultset after dropping non existent table
+#
+--error ER_BAD_TABLE_ERROR
+DROP TABLE t1;
+SHOW ERRORS;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/windows.test b/mysql-test/t/windows.test
index 89cd2ed19e8..b7d31948d23 100755
--- a/mysql-test/t/windows.test
+++ b/mysql-test/t/windows.test
@@ -92,3 +92,9 @@ execute abc;
execute abc;
deallocate prepare abc;
+--echo #
+--echo # Bug#45498: Socket variable not available on Windows
+--echo #
+
+SELECT VARIABLE_NAME FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+ WHERE VARIABLE_NAME = 'socket';
diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test
index 7b1c6a268d5..f84d822170f 100644
--- a/mysql-test/t/xa.test
+++ b/mysql-test/t/xa.test
@@ -149,6 +149,68 @@ xa end 'a';
xa prepare 'a';
xa commit 'a';
+#
+# BUG#43171 - Assertion failed: thd->transaction.xid_state.xid.is_null()
+#
+CREATE TABLE t1(a INT, KEY(a)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(1),(2);
+connect(con1,localhost,root,,);
+
+# Part 1: Prepare to test XA START after regular transaction deadlock
+BEGIN;
+UPDATE t1 SET a=3 WHERE a=1;
+
+connection default;
+BEGIN;
+UPDATE t1 SET a=4 WHERE a=2;
+
+connection con1;
+let $conn_id= `SELECT CONNECTION_ID()`;
+SEND UPDATE t1 SET a=5 WHERE a=2;
+
+connection default;
+let $wait_timeout= 2;
+let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE ID=$conn_id AND STATE='Searching rows for update';
+--source include/wait_condition.inc
+
+--error ER_LOCK_DEADLOCK
+UPDATE t1 SET a=5 WHERE a=1;
+ROLLBACK;
+
+# Part 2: Prepare to test XA START after XA transaction deadlock
+connection con1;
+REAP;
+ROLLBACK;
+BEGIN;
+UPDATE t1 SET a=3 WHERE a=1;
+
+connection default;
+XA START 'xid1';
+UPDATE t1 SET a=4 WHERE a=2;
+
+connection con1;
+SEND UPDATE t1 SET a=5 WHERE a=2;
+
+connection default;
+let $wait_timeout= 2;
+let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE ID=$conn_id AND STATE='Searching rows for update';
+--source include/wait_condition.inc
+
+--error ER_LOCK_DEADLOCK
+UPDATE t1 SET a=5 WHERE a=1;
+--error ER_XA_RBDEADLOCK
+XA END 'xid1';
+XA ROLLBACK 'xid1';
+
+XA START 'xid1';
+XA END 'xid1';
+XA ROLLBACK 'xid1';
+
+disconnect con1;
+DROP TABLE t1;
+
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp
index 5b06273ad6b..6ea2817e240 100644
--- a/mysql-test/valgrind.supp
+++ b/mysql-test/valgrind.supp
@@ -1,4 +1,3 @@
-#
# Suppress some common (not fatal) errors in system libraries found by valgrind
#
@@ -894,3 +893,101 @@
obj: /lib64/libnss_dns-*so)
fun: gethostbyaddr_r
}
+
+# suppressions for glibc 2.6.1 64 bit
+
+{
+ Mem loss within nptl_pthread_exit_hack_handler 6
+ Memcheck:Leak
+ fun:malloc
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ fun:__libc_dlopen_mode
+ fun:pthread_cancel_init
+ fun:_Unwind_ForcedUnwind
+ fun:__pthread_unwind
+ fun:pthread_exit
+ fun:nptl_pthread_exit_hack_handler
+}
+
+{
+ Mem loss within nptl_pthread_exit_hack_handler 7
+ Memcheck:Leak
+ fun:malloc
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ fun:__libc_dlopen_mode
+ fun:pthread_cancel_init
+ fun:_Unwind_ForcedUnwind
+ fun:__pthread_unwind
+ fun:pthread_exit
+ fun:nptl_pthread_exit_hack_handler
+ fun:start_thread
+ fun:clone
+}
+
+{
+ Mem loss within nptl_pthread_exit_hack_handler 8
+ Memcheck:Leak
+ fun:calloc
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ fun:__libc_dlopen_mode
+ fun:pthread_cancel_init
+ fun:_Unwind_ForcedUnwind
+ fun:__pthread_unwind
+ fun:pthread_exit
+ fun:nptl_pthread_exit_hack_handler
+ fun:start_thread
+ fun:clone
+}
+
+{
+ Mem loss within nptl_pthread_exit_hack_handler 8
+ Memcheck:Leak
+ fun:calloc
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ obj:*/ld-*.so
+ obj:*/libc-*.so
+ fun:__libc_dlopen_mode
+ fun:pthread_cancel_init
+ fun:_Unwind_ForcedUnwind
+ fun:__pthread_unwind
+ fun:pthread_exit
+ fun:nptl_pthread_exit_hack_handler
+}
+
+#
+# Pthread doesn't free all thread specific memory before program exists
+#
+{
+ pthread allocate_tls memory loss in 2.6.1.
+ Memcheck:Leak
+ fun:calloc
+ obj:*/ld-*.so
+ fun:_dl_allocate_tls
+ fun:pthread_create*
+}
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index 8552eae3974..e9873fb0525 100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -29,7 +29,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_
errors.c hash.c list.c md5.c mf_brkhant.c mf_cache.c mf_dirname.c mf_fn_ext.c
mf_format.c mf_getdate.c mf_iocache.c mf_iocache2.c mf_keycache.c my_safehash.c
mf_keycaches.c mf_loadpath.c mf_pack.c mf_path.c mf_qsort.c mf_qsort2.c
- mf_radix.c mf_same.c mf_sort.c mf_soundex.c mf_strip.c mf_arr_appstr.c mf_tempdir.c
+ mf_radix.c mf_same.c mf_sort.c mf_soundex.c mf_arr_appstr.c mf_tempdir.c
mf_tempfile.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_access.c
my_aes.c my_alarm.c my_alloc.c my_append.c my_bit.c my_bitmap.c my_chmod.c my_chsize.c
my_clock.c my_compress.c my_conio.c my_copy.c my_crc32.c my_create.c my_delete.c
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index f958d1821da..5137566c158 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (C) 2000-2006 MySQL AB
+# Copyright (C) 2000-2006 MySQL AB, 2009 Sun Microsystems, Inc.
#
# 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
@@ -20,32 +20,32 @@ INCLUDES = @ZLIB_INCLUDES@ -I$(top_builddir)/include \
-I$(top_srcdir)/include -I$(srcdir)
pkglib_LIBRARIES = libmysys.a
LDADD = libmysys.a $(top_builddir)/strings/libmystrings.a $(top_builddir)/dbug/libdbug.a
-noinst_HEADERS = mysys_priv.h my_static.h my_handler_errors.h my_safehash.h
+noinst_HEADERS = mysys_priv.h my_static.h my_handler_errors.h \
+ my_safehash.h
libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
mf_path.c mf_loadpath.c my_file.c \
my_open.c my_create.c my_dup.c my_seek.c my_read.c \
my_pread.c my_write.c my_getpagesize.c \
- my_safehash.c \
- mf_keycache.c mf_keycaches.c my_crc32.c \
+ my_crc32.c \
mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \
mf_tempdir.c my_lock.c mf_brkhant.c my_alarm.c \
my_malloc.c my_realloc.c my_once.c mulalloc.c \
my_alloc.c safemalloc.c my_new.cc \
- my_vle.c my_atomic.c lf_hash.c \
- lf_dynarray.c lf_alloc-pin.c \
+ my_vle.c my_atomic.c \
+ my_safehash.c lf_hash.c lf_dynarray.c lf_alloc-pin.c \
+ my_rnd.c my_uuid.c my_chmod.c \
my_fopen.c my_fstream.c my_getsystime.c \
- my_rnd.c my_uuid.c \
my_error.c errors.c my_div.c my_messnc.c \
mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
my_symlink.c my_symlink2.c \
- mf_pack.c mf_unixpath.c mf_strip.c mf_arr_appstr.c \
+ mf_pack.c mf_unixpath.c mf_arr_appstr.c \
mf_wcomp.c mf_wfile.c my_gethwaddr.c \
mf_qsort.c mf_qsort2.c mf_sort.c \
ptr_cmp.c mf_radix.c queues.c my_getncpus.c \
tree.c trie.c list.c hash.c array.c string.c typelib.c \
my_copy.c my_append.c my_lib.c \
my_delete.c my_rename.c my_redel.c \
- my_chsize.c my_chmod.c my_clock.c \
+ my_chsize.c my_clock.c \
my_quick.c my_lockmem.c my_static.c \
my_sync.c my_getopt.c my_mkdir.c \
default_modify.c default.c \
@@ -57,12 +57,19 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
my_memmem.c stacktrace.c \
my_windac.c my_access.c base64.c my_libwrap.c \
wqueue.c
-if THREAD
-libmysys_a_SOURCES+= thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
- thr_mutex.c thr_rwlock.c waiting_threads.c
+
+if NEED_THREAD
+# mf_keycache is used only in the server, so it is safe to leave the file
+# out of the non-threaded library.
+# In fact, it will currently not compile without thread support.
+libmysys_a_SOURCES += mf_keycache.c mf_keycaches.c
endif
-EXTRA_DIST = CMakeLists.txt mf_soundex.c \
+
+EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
+ thr_mutex.c thr_rwlock.c waiting_threads.c \
+ CMakeLists.txt mf_soundex.c \
my_conio.c my_wincond.c my_winthread.c
+libmysys_a_LIBADD = @THREAD_LOBJECTS@
# test_dir_DEPENDENCIES= $(LIBRARIES)
# testhash_DEPENDENCIES= $(LIBRARIES)
# test_charset_DEPENDENCIES= $(LIBRARIES)
@@ -76,6 +83,8 @@ DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\" \
-DDEFAULT_SYSCONFDIR="\"$(sysconfdir)\"" \
@DEFS@
+libmysys_a_DEPENDENCIES= @THREAD_LOBJECTS@
+
# I hope this always does the right thing. Otherwise this is only test programs
FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@
diff --git a/mysys/charset-def.c b/mysys/charset-def.c
index 63bbceef29b..5c68258ada1 100644
--- a/mysys/charset-def.c
+++ b/mysys/charset-def.c
@@ -42,6 +42,7 @@ extern CHARSET_INFO my_charset_ucs2_roman_uca_ci;
extern CHARSET_INFO my_charset_ucs2_persian_uca_ci;
extern CHARSET_INFO my_charset_ucs2_esperanto_uca_ci;
extern CHARSET_INFO my_charset_ucs2_hungarian_uca_ci;
+extern CHARSET_INFO my_charset_ucs2_croatian_uca_ci;
#endif
#ifdef HAVE_CHARSET_utf8
@@ -63,6 +64,7 @@ extern CHARSET_INFO my_charset_utf8_roman_uca_ci;
extern CHARSET_INFO my_charset_utf8_persian_uca_ci;
extern CHARSET_INFO my_charset_utf8_esperanto_uca_ci;
extern CHARSET_INFO my_charset_utf8_hungarian_uca_ci;
+extern CHARSET_INFO my_charset_utf8_croatian_uca_ci;
#ifdef HAVE_UTF8_GENERAL_CS
extern CHARSET_INFO my_charset_utf8_general_cs;
#endif
@@ -152,6 +154,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused)))
add_compiled_collation(&my_charset_ucs2_persian_uca_ci);
add_compiled_collation(&my_charset_ucs2_esperanto_uca_ci);
add_compiled_collation(&my_charset_ucs2_hungarian_uca_ci);
+ add_compiled_collation(&my_charset_ucs2_croatian_uca_ci);
#endif
#endif
@@ -186,6 +189,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused)))
add_compiled_collation(&my_charset_utf8_persian_uca_ci);
add_compiled_collation(&my_charset_utf8_esperanto_uca_ci);
add_compiled_collation(&my_charset_utf8_hungarian_uca_ci);
+ add_compiled_collation(&my_charset_utf8_croatian_uca_ci);
#endif
#endif
diff --git a/mysys/errors.c b/mysys/errors.c
index 7c80fc0f89f..fc63ac9d936 100644
--- a/mysys/errors.c
+++ b/mysys/errors.c
@@ -51,6 +51,7 @@ const char * NEAR globerrs[GLOBERRS]=
"File '%s' not found (Errcode: %d)",
"File '%s' (fileno: %d) was not closed",
"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 +94,7 @@ void init_glob_errs()
EE(EE_FILENOTFOUND) = "File '%s' not found (Errcode: %d)";
EE(EE_FILE_NOT_CLOSED) = "File '%s' (fileno: %d) was not closed";
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)";
}
#endif
diff --git a/mysys/hash.c b/mysys/hash.c
index 136c2854bbe..0e22ddcf215 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -338,13 +338,8 @@ my_bool my_hash_insert(HASH *info, const uchar *record)
{
int flag;
size_t idx,halfbuff,hash_nr,first_index;
- uchar *ptr_to_rec,*ptr_to_rec2;
- HASH_LINK *data,*empty,*gpos,*gpos2,*pos;
-
- LINT_INIT(gpos);
- LINT_INIT(gpos2);
- LINT_INIT(ptr_to_rec);
- LINT_INIT(ptr_to_rec2);
+ uchar *UNINIT_VAR(ptr_to_rec),*UNINIT_VAR(ptr_to_rec2);
+ HASH_LINK *data,*empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos;
if (info->flags & HASH_UNIQUE)
{
diff --git a/mysys/lf_hash.c b/mysys/lf_hash.c
index ce7056af995..6569bafc00d 100644
--- a/mysys/lf_hash.c
+++ b/mysys/lf_hash.c
@@ -124,8 +124,8 @@ retry:
we found a deleted node - be nice, help the other thread
and remove this deleted node
*/
- if (my_atomic_casptr((void **)cursor->prev,
- (void **)&cursor->curr, cursor->next))
+ if (my_atomic_casptr((void **) cursor->prev,
+ (void **)(char*) &cursor->curr, cursor->next))
_lf_alloc_free(pins, cursor->curr);
else
{
@@ -171,7 +171,8 @@ static LF_SLIST *linsert(LF_SLIST * volatile *head, CHARSET_INFO *cs,
node->link= (intptr)cursor.curr;
DBUG_ASSERT(node->link != (intptr)node); /* no circular references */
DBUG_ASSERT(cursor.prev != &node->link); /* no circular references */
- if (my_atomic_casptr((void **)cursor.prev, (void **)&cursor.curr, node))
+ if (my_atomic_casptr((void **) cursor.prev,
+ (void **)(char*) &cursor.curr, node))
{
res= 1; /* inserted ok */
break;
@@ -218,13 +219,13 @@ static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr,
else
{
/* mark the node deleted */
- if (my_atomic_casptr((void **)&(cursor.curr->link),
- (void **)&cursor.next,
+ if (my_atomic_casptr((void **) (char*) &(cursor.curr->link),
+ (void **) (char*) &cursor.next,
(void *)(((intptr)cursor.next) | 1)))
{
/* and remove it from the list */
if (my_atomic_casptr((void **)cursor.prev,
- (void **)&cursor.curr, cursor.next))
+ (void **)(char*)&cursor.curr, cursor.next))
_lf_alloc_free(pins, cursor.curr);
else
{
@@ -493,7 +494,7 @@ static int initialize_bucket(LF_HASH *hash, LF_SLIST * volatile *node,
my_free((void *)dummy, MYF(0));
dummy= cur;
}
- my_atomic_casptr((void **)node, (void **)&tmp, dummy);
+ my_atomic_casptr((void **)node, (void **)(char*) &tmp, dummy);
/*
note that if the CAS above failed (after linsert() succeeded),
it would mean that some other thread has executed linsert() for
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index ece6c35888d..0630d194234 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -13,7 +13,8 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/*
+/**
+ @file
These functions handle keyblock cacheing for ISAM and MyISAM tables.
One cache can handle many files.
@@ -36,7 +37,9 @@
blocks_unused is the sum of never used blocks in the pool and of currently
free blocks. blocks_used is the number of blocks fetched from the pool and
as such gives the maximum number of in-use blocks at any time.
+*/
+/*
Key Cache Locking
=================
@@ -368,8 +371,8 @@ static inline uint next_power(uint value)
*/
int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold)
+ size_t use_mem, uint division_limit,
+ uint age_threshold)
{
ulong blocks, hash_links;
size_t length;
@@ -560,8 +563,8 @@ err:
*/
int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
- size_t use_mem, uint division_limit,
- uint age_threshold)
+ size_t use_mem, uint division_limit,
+ uint age_threshold)
{
int blocks;
DBUG_ENTER("resize_key_cache");
@@ -760,6 +763,13 @@ void end_key_cache(KEY_CACHE *keycache, my_bool cleanup)
(ulong) keycache->global_cache_r_requests,
(ulong) keycache->global_cache_read));
+ /*
+ Reset these values to be able to detect a disabled key cache.
+ See Bug#44068 (RESTORE can disable the MyISAM Key Cache).
+ */
+ keycache->blocks_used= 0;
+ keycache->blocks_unused= 0;
+
if (cleanup)
{
pthread_mutex_destroy(&keycache->cache_lock);
@@ -1343,7 +1353,11 @@ static void unreg_request(KEY_CACHE *keycache,
DBUG_ASSERT(block->prev_changed && *block->prev_changed == block);
DBUG_ASSERT(!block->next_used);
DBUG_ASSERT(!block->prev_used);
- if (! --block->requests)
+ /*
+ Unregister the request, but do not link erroneous blocks into the
+ LRU ring.
+ */
+ if (!--block->requests && !(block->status & BLOCK_ERROR))
{
my_bool hot;
if (block->hits_left)
@@ -1425,8 +1439,7 @@ static void wait_for_readers(KEY_CACHE *keycache,
#ifdef THREAD
struct st_my_thread_var *thread= my_thread_var;
DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
- DBUG_ASSERT(!(block->status & (BLOCK_ERROR | BLOCK_IN_FLUSH |
- BLOCK_CHANGED)));
+ DBUG_ASSERT(!(block->status & (BLOCK_IN_FLUSH | BLOCK_CHANGED)));
DBUG_ASSERT(block->hash_link);
DBUG_ASSERT(block->hash_link->block == block);
/* Linked in file_blocks or changed_blocks hash. */
@@ -1716,6 +1729,7 @@ restart:
- block assigned but not yet read from file (invalid data).
*/
+#ifdef THREAD
if (keycache->in_resize)
{
/* This is a request during a resize operation */
@@ -1957,6 +1971,9 @@ restart:
}
DBUG_RETURN(0);
}
+#else /* THREAD */
+ DBUG_ASSERT(!keycache->in_resize);
+#endif
if (page_status == PAGE_READ &&
(block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH |
@@ -2210,9 +2227,9 @@ restart:
thread might change the block->hash_link value
*/
error= my_pwrite(block->hash_link->file,
- block->buffer+block->offset,
+ block->buffer + block->offset,
block->length - block->offset,
- block->hash_link->diskpos+ block->offset,
+ block->hash_link->diskpos + block->offset,
MYF(MY_NABP | MY_WAIT_IF_FULL));
keycache_pthread_mutex_lock(&keycache->cache_lock);
@@ -2536,7 +2553,6 @@ uchar *key_cache_read(KEY_CACHE *keycache,
reg1 BLOCK_LINK *block;
uint read_length;
uint offset;
- uint status;
int page_st;
/*
@@ -2571,9 +2587,11 @@ uchar *key_cache_read(KEY_CACHE *keycache,
do
{
/* Cache could be disabled in a later iteration. */
-
if (!keycache->can_be_used)
- goto no_key_cache;
+ {
+ KEYCACHE_DBUG_PRINT("key_cache_read", ("keycache cannot be used"));
+ goto no_key_cache;
+ }
/* Start reading at the beginning of the cache block. */
filepos-= offset;
/* Do not read beyond the end of the cache block. */
@@ -2634,7 +2652,7 @@ uchar *key_cache_read(KEY_CACHE *keycache,
}
/* block status may have added BLOCK_ERROR in the above 'if'. */
- if (!((status= block->status) & BLOCK_ERROR))
+ if (!(block->status & BLOCK_ERROR))
{
#ifndef THREAD
if (! return_buffer)
@@ -2660,14 +2678,22 @@ uchar *key_cache_read(KEY_CACHE *keycache,
remove_reader(block);
- /*
- Link the block into the LRU ring if it's the last submitted
- request for the block. This enables eviction for the block.
- */
- unreg_request(keycache, block, 1);
+ /* Error injection for coverage testing. */
+ DBUG_EXECUTE_IF("key_cache_read_block_error",
+ block->status|= BLOCK_ERROR;);
- if (status & BLOCK_ERROR)
+ /* Do not link erroneous blocks into the LRU ring, but free them. */
+ if (!(block->status & BLOCK_ERROR))
+ {
+ /*
+ Link the block into the LRU ring if it's the last submitted
+ request for the block. This enables eviction for the block.
+ */
+ unreg_request(keycache, block, 1);
+ }
+ else
{
+ free_block(keycache, block);
error= 1;
break;
}
@@ -2677,7 +2703,7 @@ uchar *key_cache_read(KEY_CACHE *keycache,
if (return_buffer)
DBUG_RETURN(block->buffer);
#endif
- next_block:
+ next_block:
buff+= read_length;
filepos+= read_length+offset;
offset= 0;
@@ -2685,6 +2711,7 @@ uchar *key_cache_read(KEY_CACHE *keycache,
} while ((length-= read_length));
goto end;
}
+ KEYCACHE_DBUG_PRINT("key_cache_read", ("keycache not initialized"));
no_key_cache:
/* Key cache is not used */
@@ -2705,6 +2732,7 @@ end:
dec_counter_for_resize_op(keycache);
keycache_pthread_mutex_unlock(&keycache->cache_lock);
}
+ DBUG_PRINT("exit", ("error: %d", error ));
DBUG_RETURN(error ? (uchar*) 0 : start);
}
@@ -2913,19 +2941,27 @@ int key_cache_insert(KEY_CACHE *keycache,
DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE));
} /* end of if (!(block->status & BLOCK_ERROR)) */
-
remove_reader(block);
- /*
- Link the block into the LRU ring if it's the last submitted
- request for the block. This enables eviction for the block.
- */
- unreg_request(keycache, block, 1);
-
- error= (block->status & BLOCK_ERROR);
+ /* Error injection for coverage testing. */
+ DBUG_EXECUTE_IF("key_cache_insert_block_error",
+ block->status|= BLOCK_ERROR; errno=EIO;);
- if (error)
+ /* Do not link erroneous blocks into the LRU ring, but free them. */
+ if (!(block->status & BLOCK_ERROR))
+ {
+ /*
+ Link the block into the LRU ring if it's the last submitted
+ request for the block. This enables eviction for the block.
+ */
+ unreg_request(keycache, block, 1);
+ }
+ else
+ {
+ free_block(keycache, block);
+ error= 1;
break;
+ }
buff+= read_length;
filepos+= read_length+offset;
@@ -3206,14 +3242,24 @@ int key_cache_write(KEY_CACHE *keycache,
*/
remove_reader(block);
- /*
- Link the block into the LRU ring if it's the last submitted
- request for the block. This enables eviction for the block.
- */
- unreg_request(keycache, block, 1);
+ /* Error injection for coverage testing. */
+ DBUG_EXECUTE_IF("key_cache_write_block_error",
+ block->status|= BLOCK_ERROR;);
- if (block->status & BLOCK_ERROR)
+ /* Do not link erroneous blocks into the LRU ring, but free them. */
+ if (!(block->status & BLOCK_ERROR))
+ {
+ /*
+ Link the block into the LRU ring if it's the last submitted
+ request for the block. This enables eviction for the block.
+ */
+ unreg_request(keycache, block, 1);
+ }
+ else
{
+ /* Pretend a "clean" block to avoid complications. */
+ block->status&= ~(BLOCK_CHANGED);
+ free_block(keycache, block);
error= 1;
break;
}
@@ -3288,8 +3334,9 @@ static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block)
{
KEYCACHE_THREAD_TRACE("free block");
KEYCACHE_DBUG_PRINT("free_block",
- ("block %u to be freed, hash_link %p",
- BLOCK_NUMBER(block), block->hash_link));
+ ("block %u to be freed, hash_link %p status: %u",
+ BLOCK_NUMBER(block), block->hash_link,
+ block->status));
/*
Assert that the block is not free already. And that it is in a clean
state. Note that the block might just be assigned to a hash_link and
@@ -3371,10 +3418,14 @@ static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block)
if (block->status & BLOCK_IN_EVICTION)
return;
- /* Here the block must be in the LRU ring. Unlink it again. */
- DBUG_ASSERT(block->next_used && block->prev_used &&
- *block->prev_used == block);
- unlink_block(keycache, block);
+ /* Error blocks are not put into the LRU ring. */
+ if (!(block->status & BLOCK_ERROR))
+ {
+ /* Here the block must be in the LRU ring. Unlink it again. */
+ DBUG_ASSERT(block->next_used && block->prev_used &&
+ *block->prev_used == block);
+ unlink_block(keycache, block);
+ }
if (block->temperature == BLOCK_WARM)
keycache->warm_blocks--;
block->temperature= BLOCK_COLD;
@@ -3463,8 +3514,7 @@ static int flush_cached_blocks(KEY_CACHE *keycache,
(BLOCK_READ | BLOCK_IN_FLUSH | BLOCK_CHANGED | BLOCK_IN_USE));
block->status|= BLOCK_IN_FLUSHWRITE;
keycache_pthread_mutex_unlock(&keycache->cache_lock);
- error= my_pwrite(file,
- block->buffer+block->offset,
+ error= my_pwrite(file, block->buffer+block->offset,
block->length - block->offset,
block->hash_link->diskpos+ block->offset,
MYF(MY_NABP | MY_WAIT_IF_FULL));
@@ -3491,7 +3541,6 @@ static int flush_cached_blocks(KEY_CACHE *keycache,
right queue anyway.
*/
link_to_file_list(keycache, block, file, 1);
-
}
block->status&= ~BLOCK_IN_FLUSH;
/*
@@ -3527,7 +3576,7 @@ static int flush_cached_blocks(KEY_CACHE *keycache,
/*
- flush all key blocks for a file to disk, but don't do any mutex locks.
+ Flush all key blocks for a file to disk, but don't do any mutex locks.
SYNOPSIS
flush_key_blocks_int()
@@ -3693,7 +3742,6 @@ restart:
{
/* It's a temporary file */
DBUG_ASSERT(!(block->status & BLOCK_REASSIGNED));
-
/*
free_block() must not be called with BLOCK_CHANGED. Note
that we must not change the BLOCK_CHANGED flag outside of
@@ -4404,8 +4452,8 @@ static void keycache_debug_print(const char * fmt,...)
va_start(args,fmt);
if (keycache_debug_log)
{
- VOID(vfprintf(keycache_debug_log, fmt, args));
- VOID(fputc('\n',keycache_debug_log));
+ (void) vfprintf(keycache_debug_log, fmt, args);
+ (void) fputc('\n',keycache_debug_log);
}
va_end(args);
}
diff --git a/mysys/mf_strip.c b/mysys/mf_strip.c
deleted file mode 100644
index b33620b1b2d..00000000000
--- a/mysys/mf_strip.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright (C) 2000 MySQL 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
- 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 */
-
-/* T|mmer en str{ng p{ slut_space */
-
-#include "mysys_priv.h"
-
-/*
- strip_sp(char * str)
- Strips end-space from string and returns new length.
-*/
-
-size_t strip_sp(register char * str)
-{
- reg2 char * found;
- reg3 char * start;
-
- start=found=str;
-
- while (*str)
- {
- if (*str != ' ')
- {
- while (*++str && *str != ' ') {};
- if (!*str)
- return (size_t) (str-start); /* Return stringlength */
- }
- found=str;
- while (*++str == ' ') {};
- }
- *found= '\0'; /* Stripp at first space */
- return (size_t) (found-start);
-} /* strip_sp */
diff --git a/mysys/my_copy.c b/mysys/my_copy.c
index 62f60e9ce95..adc891358d4 100644
--- a/mysys/my_copy.c
+++ b/mysys/my_copy.c
@@ -89,6 +89,13 @@ int my_copy(const char *from, const char *to, myf MyFlags)
goto err;
}
+ /* sync the destination file */
+ if (MyFlags & MY_SYNC)
+ {
+ if (my_sync(to_file, MyFlags))
+ goto err;
+ }
+
if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags))
DBUG_RETURN(-1); /* Error on close */
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index 3d961c3bcee..98d3b9756ed 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -1017,10 +1017,12 @@ static void init_one_value(const struct my_option *option, uchar* *variable,
case GET_LL:
*((longlong*) variable)= (longlong) getopt_ll_limit_value((longlong) value, option, NULL);
break;
- case GET_ULL: /* Fall through */
- case GET_SET:
+ case GET_ULL:
*((ulonglong*) variable)= (ulonglong) getopt_ull_limit_value((ulonglong) value, option, NULL);
break;
+ case GET_SET:
+ *((ulonglong*) variable)= (ulonglong) value;
+ break;
case GET_DOUBLE:
*((double*) variable)= (double) value;
break;
diff --git a/mysys/my_largepage.c b/mysys/my_largepage.c
index a20111396cb..b50a606c8d8 100644
--- a/mysys/my_largepage.c
+++ b/mysys/my_largepage.c
@@ -121,7 +121,7 @@ uchar* my_large_malloc_int(size_t size, myf my_flags)
DBUG_ENTER("my_large_malloc_int");
/* Align block size to my_large_page_size */
- size = ((size - 1) & ~(my_large_page_size - 1)) + my_large_page_size;
+ size= MY_ALIGN(size, (size_t) my_large_page_size);
shmid = shmget(IPC_PRIVATE, size, SHM_HUGETLB | SHM_R | SHM_W);
if (shmid < 0)
diff --git a/mysys/my_redel.c b/mysys/my_redel.c
index 6b0ceb85950..598a728393d 100644
--- a/mysys/my_redel.c
+++ b/mysys/my_redel.c
@@ -77,9 +77,6 @@ end:
int my_copystat(const char *from, const char *to, int MyFlags)
{
struct stat statbuf;
-#if !defined(__WIN__) && !defined(__NETWARE__)
- int res;
-#endif
if (stat((char*) from, &statbuf))
{
diff --git a/mysys/my_seek.c b/mysys/my_seek.c
index 4e18b510a1e..4ca5393e640 100644
--- a/mysys/my_seek.c
+++ b/mysys/my_seek.c
@@ -14,6 +14,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
+#include "mysys_err.h"
/*
Seek to a position in a file.
@@ -42,8 +43,7 @@
actual error.
*/
-my_off_t my_seek(File fd, my_off_t pos, int whence,
- myf MyFlags __attribute__((unused)))
+my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags)
{
reg1 os_off_t newpos= -1;
DBUG_ENTER("my_seek");
@@ -68,7 +68,9 @@ my_off_t my_seek(File fd, my_off_t pos, int whence,
newpos= lseek(fd, pos, whence);
if (newpos == (os_off_t) -1)
{
- my_errno=errno;
+ my_errno= errno;
+ if (MyFlags & MY_WME)
+ my_error(EE_CANT_SEEK, MYF(0), my_filename(fd), my_errno);
DBUG_PRINT("error",("lseek: %lu errno: %d", (ulong) newpos,errno));
DBUG_RETURN(MY_FILEPOS_ERROR);
}
@@ -83,7 +85,7 @@ my_off_t my_seek(File fd, my_off_t pos, int whence,
/* Tell current position of file */
/* ARGSUSED */
-my_off_t my_tell(File fd, myf MyFlags __attribute__((unused)))
+my_off_t my_tell(File fd, myf MyFlags)
{
os_off_t pos;
DBUG_ENTER("my_tell");
@@ -95,7 +97,11 @@ my_off_t my_tell(File fd, myf MyFlags __attribute__((unused)))
pos=lseek(fd, 0L, MY_SEEK_CUR);
#endif
if (pos == (os_off_t) -1)
- my_errno=errno;
+ {
+ my_errno= errno;
+ if (MyFlags & MY_WME)
+ my_error(EE_CANT_SEEK, MYF(0), my_filename(fd), my_errno);
+ }
DBUG_PRINT("exit",("pos: %lu", (ulong) pos));
DBUG_RETURN((my_off_t) pos);
} /* my_tell */
diff --git a/mysys/my_static.c b/mysys/my_static.c
index c33d05420c9..0ef5656b76f 100644
--- a/mysys/my_static.c
+++ b/mysys/my_static.c
@@ -104,6 +104,13 @@ static const char *proc_info_dummy(void *a __attribute__((unused)),
/* this is to be able to call set_thd_proc_info from the C code */
const char *(*proc_info_hook)(void *, const char *, const char *, const char *,
const unsigned int)= proc_info_dummy;
+#if defined(ENABLED_DEBUG_SYNC)
+/**
+ Global pointer to be set if callback function is defined
+ (e.g. in mysqld). See sql/debug_sync.cc.
+*/
+void (*debug_sync_C_callback_ptr)(const char *, size_t);
+#endif /* defined(ENABLED_DEBUG_SYNC) */
#ifdef __WIN__
/* from my_getsystime.c */
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 716552bc31b..e105b48f386 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -134,10 +134,11 @@ my_bool my_thread_global_init(void)
pthread_attr_t dummy_thread_attr;
pthread_attr_init(&dummy_thread_attr);
- pthread_attr_setdetachstate(&dummy_thread_attr, PTHREAD_CREATE_DETACHED);
+ pthread_attr_setdetachstate(&dummy_thread_attr, PTHREAD_CREATE_JOINABLE);
- pthread_create(&dummy_thread,&dummy_thread_attr,
- nptl_pthread_exit_hack_handler, NULL);
+ if (pthread_create(&dummy_thread,&dummy_thread_attr,
+ nptl_pthread_exit_hack_handler, NULL) == 0)
+ (void)pthread_join(dummy_thread, NULL);
}
#endif /* TARGET_OS_LINUX */
diff --git a/mysys/my_wincond.c b/mysys/my_wincond.c
index 8b548a64079..b869b22bdea 100644
--- a/mysys/my_wincond.c
+++ b/mysys/my_wincond.c
@@ -121,7 +121,6 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
LeaveCriticalSection(&cond->lock_waiting);
LeaveCriticalSection(mutex);
-
result= WaitForMultipleObjects(2, cond->events, FALSE, timeout);
EnterCriticalSection(&cond->lock_waiting);
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index 3eabde85a58..c830c4ed0cc 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -420,6 +420,28 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
my_bool can_deadlock= test(data->owner->info->n_cursors);
DBUG_ENTER("wait_for_lock");
+ /*
+ One can use this to signal when a thread is going to wait for a lock.
+ See debug_sync.cc.
+
+ Beware of waiting for a signal here. The lock has aquired its mutex.
+ While waiting on a signal here, the locking thread could not aquire
+ the mutex to release the lock. One could lock up the table
+ completely.
+
+ In detail it works so: When thr_lock() tries to acquire a table
+ lock, it locks the lock->mutex, checks if it can have the lock, and
+ if not, it calls wait_for_lock(). Here it unlocks the table lock
+ while waiting on a condition. The sync point is located before this
+ wait for condition. If we have a waiting action here, we hold the
+ the table locks mutex all the time. Any attempt to look at the table
+ lock by another thread blocks it immediately on lock->mutex. This
+ can easily become an unexpected and unobvious blockage. So be
+ warned: Do not request a WAIT_FOR action for the 'wait_for_lock'
+ sync point unless you really know what you do.
+ */
+ DEBUG_SYNC_C("wait_for_lock");
+
if (!in_wait_list)
{
(*wait->last)=data; /* Wait for lock */
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index b5abf987461..5ab1e443a88 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -36,6 +36,7 @@
#undef pthread_mutex_init
#undef pthread_mutex_lock
#undef pthread_mutex_unlock
+#undef pthread_mutex_trylock
#undef pthread_mutex_destroy
#undef pthread_cond_wait
#undef pthread_cond_timedwait
@@ -838,31 +839,9 @@ static void print_deadlock_warning(safe_mutex_t *new_mutex,
DBUG_VOID_RETURN;
}
+#elif defined(MY_PTHREAD_FASTMUTEX)
-#endif /* THREAD && SAFE_MUTEX */
-
-#if defined(THREAD) && defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX)
-
-#include "mysys_priv.h"
-#include "my_static.h"
-#include <m_string.h>
-
-#include <m_ctype.h>
-#include <hash.h>
-#include <myisampack.h>
-#include <mysys_err.h>
-#include <my_sys.h>
-
-#undef pthread_mutex_t
-#undef pthread_mutex_init
-#undef pthread_mutex_lock
-#undef pthread_mutex_trylock
-#undef pthread_mutex_unlock
-#undef pthread_mutex_destroy
-#undef pthread_cond_wait
-#undef pthread_cond_timedwait
-
-ulong mutex_delay(ulong delayloops)
+static ulong mutex_delay(ulong delayloops)
{
ulong i;
volatile ulong j;
@@ -943,6 +922,6 @@ void fastmutex_global_init(void)
cpu_count= sysconf(_SC_NPROCESSORS_CONF);
#endif
}
-
-#endif /* SAFE_MUTEX_DEFINED */
+
+#endif /* defined(MY_PTHREAD_FASTMUTEX) */
#endif /* THREAD */
diff --git a/mysys/tree.c b/mysys/tree.c
index ef33f75b7c6..e4854581204 100644
--- a/mysys/tree.c
+++ b/mysys/tree.c
@@ -77,13 +77,13 @@ static void rb_insert(TREE *tree,TREE_ELEMENT ***parent,
static void rb_delete_fixup(TREE *tree,TREE_ELEMENT ***parent);
- /* The actuall code for handling binary trees */
+/* The actual code for handling binary trees */
#ifndef DBUG_OFF
static int test_rb_tree(TREE_ELEMENT *element);
#endif
-void init_tree(TREE *tree, ulong default_alloc_size, ulong memory_limit,
+void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit,
int size, qsort_cmp2 compare, my_bool with_delete,
tree_element_free free_element, void *custom_arg)
{
@@ -96,7 +96,7 @@ void init_tree(TREE *tree, ulong default_alloc_size, ulong memory_limit,
bzero((uchar*) &tree->null_element,sizeof(tree->null_element));
tree->root= &tree->null_element;
tree->compare=compare;
- tree->size_of_element=size > 0 ? (uint) size : 0;
+ tree->size_of_element= size > 0 ? (uint) size : 0;
tree->memory_limit=memory_limit;
tree->free=free_element;
tree->allocated=0;
@@ -127,7 +127,7 @@ void init_tree(TREE *tree, ulong default_alloc_size, ulong memory_limit,
}
if (!(tree->with_delete=with_delete))
{
- init_alloc_root(&tree->mem_root, (uint) default_alloc_size, 0);
+ init_alloc_root(&tree->mem_root, default_alloc_size, 0);
tree->mem_root.min_malloc=(sizeof(TREE_ELEMENT)+tree->size_of_element);
}
DBUG_VOID_RETURN;
diff --git a/mysys/typelib.c b/mysys/typelib.c
index 26bfdaee2c2..97acd476c20 100644
--- a/mysys/typelib.c
+++ b/mysys/typelib.c
@@ -190,7 +190,10 @@ my_ulonglong find_typeset(char *x, TYPELIB *lib, int *err)
{
(*err)++;
i= x;
- while (*x && *x != field_separator) x++;
+ while (*x && *x != field_separator)
+ x++;
+ if (x[0] && x[1]) /* skip separator if found */
+ x++;
if ((find= find_type(i, lib, 2 | 8) - 1) < 0)
DBUG_RETURN(0);
result|= (ULL(1) << find);
diff --git a/plugin/fulltext/plugin_example.c b/plugin/fulltext/plugin_example.c
index 70022da2cc4..ab4f1f178d7 100644
--- a/plugin/fulltext/plugin_example.c
+++ b/plugin/fulltext/plugin_example.c
@@ -169,11 +169,11 @@ static void add_word(MYSQL_FTPARSER_PARAM *param, char *word, size_t len)
static int simple_parser_parse(MYSQL_FTPARSER_PARAM *param)
{
- char *end, *start, *docend= param->doc + param->length;
+ char *end, *start, *docend= (char *)param->doc + param->length;
number_of_calls++;
- for (end= start= param->doc;; end++)
+ for (end= start= (char *)param->doc;; end++)
{
if (end == docend)
{
diff --git a/regex/CMakeLists.txt b/regex/CMakeLists.txt
index a3088c00357..2e3b18c7bb0 100755
--- a/regex/CMakeLists.txt
+++ b/regex/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(REGEX_SOURCES debug.c regcomp.c regerror.c regexec.c regfree.c reginit.c split.c)
+SET(REGEX_SOURCES regcomp.c regerror.c regexec.c regfree.c reginit.c)
IF(NOT SOURCE_SUBLIBS)
ADD_LIBRARY(regex ${REGEX_SOURCES})
diff --git a/regex/engine.c b/regex/engine.c
index 1968ca61a96..a099cfb891d 100644
--- a/regex/engine.c
+++ b/regex/engine.c
@@ -33,11 +33,11 @@ struct match {
struct re_guts *g;
int eflags;
my_regmatch_t *pmatch; /* [nsub+1] (0 element unused) */
- char *offp; /* offsets work from here */
- char *beginp; /* start of string -- virtual NUL precedes */
- char *endp; /* end of string -- virtual NUL here */
- char *coldp; /* can be no match starting before here */
- char **lastpos; /* [nplus+1] */
+ const char *offp; /* offsets work from here */
+ const char *beginp; /* start of string -- virtual NUL precedes */
+ const char *endp; /* end of string -- virtual NUL here */
+ const char *coldp; /* can be no match starting before here */
+ const char **lastpos; /* [nplus+1] */
STATEVARS;
states st; /* current states */
states fresh; /* states for a fresh start */
@@ -66,20 +66,20 @@ static int /* 0 success, REG_NOMATCH failure */
matcher(charset,g, str, nmatch, pmatch, eflags)
CHARSET_INFO *charset;
register struct re_guts *g;
-char *str;
+const char *str;
size_t nmatch;
my_regmatch_t pmatch[];
int eflags;
{
- register char *endp;
+ register const char *endp;
register uint i;
struct match mv;
register struct match *m = &mv;
- register char *dp;
+ register const char *dp;
register const sopno gf = g->firststate+1; /* +1 for OEND */
register const sopno gl = g->laststate;
- char *start;
- char *stop;
+ const char *start;
+ const char *stop;
/* simplify the situation where possible */
if (g->cflags&REG_NOSUB)
@@ -163,7 +163,7 @@ int eflags;
dp = dissect(charset, m, m->coldp, endp, gf, gl);
} else {
if (g->nplus > 0 && m->lastpos == NULL)
- m->lastpos = (char **)malloc((g->nplus+1) *
+ m->lastpos = (const char **)malloc((g->nplus+1) *
sizeof(char *));
if (g->nplus > 0 && m->lastpos == NULL) {
free(m->pmatch);
@@ -235,28 +235,28 @@ int eflags;
== static char *dissect(register struct match *m, char *start, \
== char *stop, sopno startst, sopno stopst);
*/
-static char * /* == stop (success) always */
+static const char * /* == stop (success) always */
dissect(charset, m, start, stop, startst, stopst)
CHARSET_INFO *charset;
register struct match *m;
-char *start;
-char *stop;
+const char *start;
+const char *stop;
sopno startst;
sopno stopst;
{
register uint i;
register sopno ss; /* start sop of current subRE */
register sopno es; /* end sop of current subRE */
- register char *sp; /* start of string matched by it */
- register char *stp; /* string matched by it cannot pass here */
- register char *rest; /* start of rest of string */
- register char *tail; /* string unmatched by rest of RE */
+ register const char *sp; /* start of string matched by it */
+ register const char *stp; /* string matched by it cannot pass here */
+ register const char *rest; /* start of rest of string */
+ register const char *tail; /* string unmatched by rest of RE */
register sopno ssub; /* start sop of subsubRE */
register sopno esub; /* end sop of subsubRE */
- register char *ssp; /* start of string matched by subsubRE */
- register char *sep; /* end of string matched by subsubRE */
- register char *oldssp; /* previous ssp */
- register char *dp; /* used in debug mode to check asserts */
+ 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;
@@ -424,23 +424,23 @@ sopno stopst;
== static char *backref(register struct match *m, char *start, \
== char *stop, sopno startst, sopno stopst, sopno lev);
*/
-static char * /* == stop (success) or NULL (failure) */
+static const char * /* == stop (success) or NULL (failure) */
backref(charset,m, start, stop, startst, stopst, lev)
CHARSET_INFO *charset;
register struct match *m;
-char *start;
-char *stop;
+const char *start;
+const char *stop;
sopno startst;
sopno stopst;
sopno lev; /* PLUS nesting level */
{
register uint i;
register sopno ss; /* start sop of current subRE */
- register char *sp; /* start of string matched by it */
+ register const char *sp; /* start of string matched by it */
register sopno ssub; /* start sop of subsubRE */
register sopno esub; /* end sop of subsubRE */
- register char *ssp; /* start of string matched by subsubRE */
- register char *dp;
+ register const char *ssp; /* start of string matched by subsubRE */
+ register const char *dp;
register size_t len;
register int hard;
register sop s;
@@ -630,24 +630,24 @@ sopno lev; /* PLUS nesting level */
== static char *fast(register struct match *m, char *start, \
== char *stop, sopno startst, sopno stopst);
*/
-static char * /* where tentative match ended, or NULL */
+static const char * /* where tentative match ended, or NULL */
fast(charset, m, start, stop, startst, stopst)
CHARSET_INFO *charset;
register struct match *m;
-char *start;
-char *stop;
+const char *start;
+const char *stop;
sopno startst;
sopno stopst;
{
register states st = m->st;
register states fresh = m->fresh;
register states tmp = m->tmp;
- register char *p = start;
+ register const char *p = start;
register int c = (start == m->beginp) ? OUT : *(start-1);
register int lastc; /* previous c */
register int flagch;
register int i;
- register char *coldp; /* last p after which no match was underway */
+ register const char *coldp; /* last p after which no match was underway */
CLEAR(st);
SET1(st, startst);
@@ -722,24 +722,24 @@ sopno stopst;
== static char *slow(register struct match *m, char *start, \
== char *stop, sopno startst, sopno stopst);
*/
-static char * /* where it ended */
+static const char * /* where it ended */
slow(charset, m, start, stop, startst, stopst)
CHARSET_INFO *charset;
register struct match *m;
-char *start;
-char *stop;
+const char *start;
+const char *stop;
sopno startst;
sopno stopst;
{
register states st = m->st;
register states empty = m->empty;
register states tmp = m->tmp;
- register char *p = start;
+ register const char *p = start;
register int c = (start == m->beginp) ? OUT : *(start-1);
register int lastc; /* previous c */
register int flagch;
register int i;
- register char *matchp; /* last p at which a match ended */
+ register const char *matchp; /* last p at which a match ended */
AT("slow", start, stop, startst, stopst);
CLEAR(st);
diff --git a/regex/engine.ih b/regex/engine.ih
index a9e98abef00..aa0f83e8e2e 100644
--- a/regex/engine.ih
+++ b/regex/engine.ih
@@ -4,11 +4,11 @@ extern "C" {
#endif
/* === engine.c === */
-static int matcher(CHARSET_INFO *charset,register struct re_guts *g, char *string, size_t nmatch, my_regmatch_t pmatch[], int eflags);
-static char *dissect(CHARSET_INFO *charset,register struct match *m, char *start, char *stop, sopno startst, sopno stopst);
-static char *backref(CHARSET_INFO *charset, register struct match *m, char *start, char *stop, sopno startst, sopno stopst, sopno lev);
-static char *fast(CHARSET_INFO *charset, register struct match *m, char *start, char *stop, sopno startst, sopno stopst);
-static char *slow(CHARSET_INFO *charset, register struct match *m, char *start, char *stop, sopno startst, sopno stopst);
+static int matcher(CHARSET_INFO *charset,register struct re_guts *g, const char *string, size_t nmatch, my_regmatch_t pmatch[], int eflags);
+static const char *dissect(CHARSET_INFO *charset,register struct match *m, const char *start, const char *stop, sopno startst, sopno stopst);
+static const char *backref(CHARSET_INFO *charset, register struct match *m, const char *start, const char *stop, sopno startst, sopno stopst, sopno lev);
+static const char *fast(CHARSET_INFO *charset, register struct match *m, const char *start, const char *stop, sopno startst, sopno stopst);
+static const char *slow(CHARSET_INFO *charset, register struct match *m, const char *start, const char *stop, sopno startst, sopno stopst);
static states step(register struct re_guts *g, sopno start, sopno stop, register states bef, int ch, register states aft);
#define BOL (OUT+1)
#define EOL (BOL+1)
diff --git a/scripts/fill_help_tables.sql b/scripts/fill_help_tables.sql
index e8695e7a6a4..868e6c6eb23 100644
--- a/scripts/fill_help_tables.sql
+++ b/scripts/fill_help_tables.sql
@@ -87,7 +87,7 @@ insert into help_topic (help_topic_id,help_category_id,name,description,example,
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (18,25,'SHOW CREATE PROCEDURE','Syntax:\nSHOW CREATE PROCEDURE proc_name\n\nThis statement is a MySQL extension. It returns the exact string that\ncan be used to re-create the named stored procedure. A similar\nstatement, SHOW CREATE FUNCTION, displays information about stored\nfunctions (see [HELP SHOW CREATE FUNCTION]).\n\nBoth statements require that you be the owner of the routine or have\nSELECT access to the mysql.proc table. If you do not have privileges\nfor the routine itself, the value displayed for the Create Procedure or\nCreate Function field will be NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/show-create-procedure.html\n\n','mysql> SHOW CREATE PROCEDURE test.simpleproc\\G\n*************************** 1. row ***************************\n Procedure: simpleproc\n sql_mode:\n Create Procedure: CREATE PROCEDURE `simpleproc`(OUT param1 INT)\n BEGIN\n SELECT COUNT(*) INTO param1 FROM t;\n END\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n\nmysql> SHOW CREATE FUNCTION test.hello\\G\n*************************** 1. row ***************************\n Function: hello\n sql_mode:\n Create Function: CREATE FUNCTION `hello`(s CHAR(20))\n RETURNS CHAR(50)\n RETURN CONCAT(\'Hello, \',s,\'!\')\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n','http://dev.mysql.com/doc/refman/5.1/en/show-create-procedure.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (19,20,'INTEGER','INTEGER[(M)] [UNSIGNED] [ZEROFILL]\n\nThis type is a synonym for INT.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/numeric-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/numeric-type-overview.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (20,35,'LOWER','Syntax:\nLOWER(str)\n\nReturns the string str with all characters changed to lowercase\naccording to the current character set mapping. The default is latin1\n(cp1252 West European).\n\nmysql> SELECT LOWER(\'QUADRATICALLY\');\n -> \'quadratically\'\n\nLOWER() (and UPPER()) are ineffective when applied to binary strings\n(BINARY, VARBINARY, BLOB). To perform lettercase conversion, convert\nthe string to a nonbinary string:\n\nmysql> SET @str = BINARY \'New York\';\nmysql> SELECT LOWER(@str), LOWER(CONVERT(@str USING latin1));\n+-------------+-----------------------------------+\n| LOWER(@str) | LOWER(CONVERT(@str USING latin1)) |\n+-------------+-----------------------------------+\n| New York | new york |\n+-------------+-----------------------------------+\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/string-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/string-functions.html');
-insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (21,25,'SHOW COLUMNS','Syntax:\nSHOW [FULL] COLUMNS {FROM | IN} tbl_name [{FROM | IN} db_name]\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW COLUMNS displays information about the columns in a given table.\nIt also works for views. The LIKE clause, if present, indicates which\ncolumn names to match. The WHERE clause can be given to select rows\nusing more general conditions, as discussed in\nhttp://dev.mysql.com/doc/refman/5.1/en/extended-show.html.\n\nmysql> SHOW COLUMNS FROM City;\n+------------+----------+------+-----+---------+----------------+\n| Field | Type | Null | Key | Default | Extra |\n+------------+----------+------+-----+---------+----------------+\n| Id | int(11) | NO | PRI | NULL | auto_increment |\n| Name | char(35) | NO | | | |\n| Country | char(3) | NO | UNI | | |\n| District | char(20) | YES | MUL | | |\n| Population | int(11) | NO | | 0 | |\n+------------+----------+------+-----+---------+----------------+\n5 rows in set (0.00 sec)\n\nIf the data types differ from what you expect them to be based on a\nCREATE TABLE statement, note that MySQL sometimes changes data types\nwhen you create or alter a table. The conditions under which this\noccurs are described in\nhttp://dev.mysql.com/doc/refman/5.1/en/silent-column-changes.html.\n\nThe FULL keyword causes the output to include the column collation and\ncomments, as well as the privileges you have for each column.\n\nYou can use db_name.tbl_name as an alternative to the tbl_name FROM\ndb_name syntax. In other words, these two statements are equivalent:\n\nmysql> SHOW COLUMNS FROM mytable FROM mydb;\nmysql> SHOW COLUMNS FROM mydb.mytable;\n\nSHOW COLUMNS displays the following values for each table column:\n\nField indicates the column name.\n\nType indicates the column data type.\n\nCollation indicates the collation for nonbinary string columns, or NULL\nfor other columns. This value is displayed only if you use the FULL\nkeyword.\n\nThe Null field contains YES if NULL values can be stored in the column,\nNO if not.\n\nThe Key field indicates whether the column is indexed:\n\no If Key is empty, the column either is not indexed or is indexed only\n as a secondary column in a multiple-column, nonunique index.\n\no If Key is PRI, the column is a PRIMARY KEY or is one of the columns\n in a multiple-column PRIMARY KEY.\n\no If Key is UNI, the column is the first column of a unique-valued\n index that cannot contain NULL values.\n\no If Key is MUL, multiple occurrences of a given value are allowed\n within the column. The column is the first column of a nonunique\n index or a unique-valued index that can contain NULL values.\n\nIf more than one of the Key values applies to a given column of a\ntable, Key displays the one with the highest priority, in the order\nPRI, UNI, MUL.\n\nA UNIQUE index may be displayed as PRI if it cannot contain NULL values\nand there is no PRIMARY KEY in the table. A UNIQUE index may display as\nMUL if several columns form a composite UNIQUE index; although the\ncombination of the columns is unique, each column can still hold\nmultiple occurrences of a given value.\n\nThe Default field indicates the default value that is assigned to the\ncolumn.\n\nThe Extra field contains any additional information that is available\nabout a given column. The value is auto_increment if the column was\ncreated with the AUTO_INCREMENT keyword and empty otherwise.\n\nPrivileges indicates the privileges you have for the column. This value\nis displayed only if you use the FULL keyword.\n\nComment indicates any comment the column has. This value is displayed\nonly if you use the FULL keyword.\n\nSHOW FIELDS is a synonym for SHOW COLUMNS. You can also list a table\'s\ncolumns with the mysqlshow db_name tbl_name command.\n\nThe DESCRIBE statement provides information similar to SHOW COLUMNS.\nSee [HELP DESCRIBE].\n\nThe SHOW CREATE TABLE, SHOW TABLE STATUS, and SHOW INDEX statements\nalso provide information about tables. See [HELP SHOW].\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/show-columns.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/show-columns.html');
+insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (21,25,'SHOW COLUMNS','Syntax:\nSHOW [FULL] COLUMNS {FROM | IN} tbl_name [{FROM | IN} db_name]\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW COLUMNS displays information about the columns in a given table.\nIt also works for views. The LIKE clause, if present, indicates which\ncolumn names to match. The WHERE clause can be given to select rows\nusing more general conditions, as discussed in\nhttp://dev.mysql.com/doc/refman/5.1/en/extended-show.html.\n\nmysql> SHOW COLUMNS FROM City;\n+------------+----------+------+-----+---------+----------------+\n| Field | Type | Null | Key | Default | Extra |\n+------------+----------+------+-----+---------+----------------+\n| Id | int(11) | NO | PRI | NULL | auto_increment |\n| Name | char(35) | NO | | | |\n| Country | char(3) | NO | UNI | | |\n| District | char(20) | YES | MUL | | |\n| Population | int(11) | NO | | 0 | |\n+------------+----------+------+-----+---------+----------------+\n5 rows in set (0.00 sec)\n\nIf the data types differ from what you expect them to be based on a\nCREATE TABLE statement, note that MySQL sometimes changes data types\nwhen you create or alter a table. The conditions under which this\noccurs are described in\nhttp://dev.mysql.com/doc/refman/5.1/en/silent-column-changes.html.\n\nThe FULL keyword causes the output to include the column collation and\ncomments, as well as the privileges you have for each column.\n\nYou can use db_name.tbl_name as an alternative to the tbl_name FROM\ndb_name syntax. In other words, these two statements are equivalent:\n\nmysql> SHOW COLUMNS FROM mytable FROM mydb;\nmysql> SHOW COLUMNS FROM mydb.mytable;\n\nSHOW COLUMNS displays the following values for each table column:\n\nField indicates the column name.\n\nType indicates the column data type.\n\nCollation indicates the collation for nonbinary string columns, or NULL\nfor other columns. This value is displayed only if you use the FULL\nkeyword.\n\nThe Null field contains YES if NULL values can be stored in the column,\nNO if not.\n\nThe Key field indicates whether the column is indexed:\n\no If Key is empty, the column either is not indexed or is indexed only\n as a secondary column in a multiple-column, nonunique index.\n\no If Key is PRI, the column is a PRIMARY KEY or is one of the columns\n in a multiple-column PRIMARY KEY.\n\no If Key is UNI, the column is the first column of a unique-valued\n index that cannot contain NULL values.\n\no If Key is MUL, multiple occurrences of a given value are allowed\n within the column. The column is the first column of a nonunique\n index or a unique-valued index that can contain NULL values.\n\nIf more than one of the Key values applies to a given column of a\ntable, Key displays the one with the highest priority, in the order\nPRI, UNI, MUL.\n\nA UNIQUE index may be displayed as PRI if it cannot contain NULL values\nand there is no PRIMARY KEY in the table. A UNIQUE index may display as\nMUL if several columns form a composite UNIQUE index; although the\ncombination of the columns is unique, each column can still hold\nmultiple occurrences of a given value.\n\nThe Default field indicates the default value that is assigned to the\ncolumn.\n\nThe Extra field contains any additional information that is available\nabout a given column. The value is nonempty in these cases:\nauto_increment for columns that have the AUTO_INCREMENT attribute; as\nof MySQL 5.1.23, on update CURRENT_TIMESTAMP for TIMESTAMP columns that\nhave the ON UPDATE CURRENT_TIMESTAMP attribute.\n\nPrivileges indicates the privileges you have for the column. This value\nis displayed only if you use the FULL keyword.\n\nComment indicates any comment the column has. This value is displayed\nonly if you use the FULL keyword.\n\nSHOW FIELDS is a synonym for SHOW COLUMNS. You can also list a table\'s\ncolumns with the mysqlshow db_name tbl_name command.\n\nThe DESCRIBE statement provides information similar to SHOW COLUMNS.\nSee [HELP DESCRIBE].\n\nThe SHOW CREATE TABLE, SHOW TABLE STATUS, and SHOW INDEX statements\nalso provide information about tables. See [HELP SHOW].\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/show-columns.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/show-columns.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (22,37,'CREATE TRIGGER','Syntax:\nCREATE\n [DEFINER = { user | CURRENT_USER }]\n TRIGGER trigger_name trigger_time trigger_event\n ON tbl_name FOR EACH ROW trigger_stmt\n\nThis statement creates a new trigger. A trigger is a named database\nobject that is associated with a table, and that activates when a\nparticular event occurs for the table. The trigger becomes associated\nwith the table named tbl_name, which must refer to a permanent table.\nYou cannot associate a trigger with a TEMPORARY table or a view.\n\nCREATE TRIGGER requires the TRIGGER privilege for the table associated\nwith the trigger. (Before MySQL 5.1.6, this statement requires the\nSUPER privilege.)\n\nThe DEFINER clause determines the security context to be used when\nchecking access privileges at trigger activation time.\n\ntrigger_time is the trigger action time. It can be BEFORE or AFTER to\nindicate that the trigger activates before or after each row to be\nmodified.\n\ntrigger_event indicates the kind of statement that activates the\ntrigger. The trigger_event can be one of the following:\n\no INSERT: The trigger is activated whenever a new row is inserted into\n the table; for example, through INSERT, LOAD DATA, and REPLACE\n statements.\n\no UPDATE: The trigger is activated whenever a row is modified; for\n example, through UPDATE statements.\n\no DELETE: The trigger is activated whenever a row is deleted from the\n table; for example, through DELETE and REPLACE statements. However,\n DROP TABLE and TRUNCATE statements on the table do not activate this\n trigger, because they do not use DELETE. Dropping a partition does\n not activate DELETE triggers, either. See [HELP TRUNCATE TABLE].\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/create-trigger.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/create-trigger.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (23,30,'MONTH','Syntax:\nMONTH(date)\n\nReturns the month for date, in the range 1 to 12 for January to\nDecember, or 0 for dates such as \'0000-00-00\' or \'2008-00-00\' that have\na zero month part.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html\n\n','mysql> SELECT MONTH(\'2008-02-03\');\n -> 2\n','http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (24,20,'TINYINT','TINYINT[(M)] [UNSIGNED] [ZEROFILL]\n\nA very small integer. The signed range is -128 to 127. The unsigned\nrange is 0 to 255.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/numeric-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/numeric-type-overview.html');
@@ -153,7 +153,7 @@ insert into help_topic (help_topic_id,help_category_id,name,description,example,
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (84,25,'EXECUTE STATEMENT','Syntax:\nEXECUTE stmt_name\n [USING @var_name [, @var_name] ...]\n\nAfter preparing a statement with PREPARE, you execute it with an\nEXECUTE statement that refers to the prepared statement name. If the\nprepared statement contains any parameter markers, you must supply a\nUSING clause that lists user variables containing the values to be\nbound to the parameters. Parameter values can be supplied only by user\nvariables, and the USING clause must name exactly as many variables as\nthe number of parameter markers in the statement.\n\nYou can execute a given prepared statement multiple times, passing\ndifferent variables to it or setting the variables to different values\nbefore each execution.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/execute.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/execute.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (85,37,'DROP INDEX','Syntax:\nDROP [ONLINE|OFFLINE] INDEX index_name ON tbl_name\n\nDROP INDEX drops the index named index_name from the table tbl_name.\nThis statement is mapped to an ALTER TABLE statement to drop the index.\nSee [HELP ALTER TABLE].\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/drop-index.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/drop-index.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (86,35,'MATCH AGAINST','Syntax:\nMATCH (col1,col2,...) AGAINST (expr [search_modifier])\n\nMySQL has support for full-text indexing and searching:\n\no A full-text index in MySQL is an index of type FULLTEXT.\n\no Full-text indexes can be used only with MyISAM tables, and can be\n created only for CHAR, VARCHAR, or TEXT columns.\n\no A FULLTEXT index definition can be given in the CREATE TABLE\n statement when a table is created, or added later using ALTER TABLE\n or CREATE INDEX.\n\no For large data sets, it is much faster to load your data into a table\n that has no FULLTEXT index and then create the index after that, than\n to load data into a table that has an existing FULLTEXT index.\n\nFull-text searching is performed using MATCH() ... AGAINST syntax.\nMATCH() takes a comma-separated list that names the columns to be\nsearched. AGAINST takes a string to search for, and an optional\nmodifier that indicates what type of search to perform. The search\nstring must be a literal string, not a variable or a column name. There\nare three types of full-text searches:\n\no A boolean search interprets the search string using the rules of a\n special query language. The string contains the words to search for.\n It can also contain operators that specify requirements such that a\n word must be present or absent in matching rows, or that it should be\n weighted higher or lower than usual. Common words such as "some" or\n "then" are stopwords and do not match if present in the search\n string. The IN BOOLEAN MODE modifier specifies a boolean search. For\n more information, see\n http://dev.mysql.com/doc/refman/5.1/en/fulltext-boolean.html.\n\no A natural language search interprets the search string as a phrase in\n natural human language (a phrase in free text). There are no special\n operators. The stopword list applies. In addition, words that are\n present in 50% or more of the rows are considered common and do not\n match. Full-text searches are natural language searches if the IN\n NATURAL LANGUAGE MODE modifier is given or if no modifier is given.\n\no A query expansion search is a modification of a natural language\n search. The search string is used to perform a natural language\n search. Then words from the most relevant rows returned by the search\n are added to the search string and the search is done again. The\n query returns the rows from the second search. The IN NATURAL\n LANGUAGE MODE WITH QUERY EXPANSION or WITH QUERY EXPANSION modifier\n specifies a query expansion search. For more information, see\n http://dev.mysql.com/doc/refman/5.1/en/fulltext-query-expansion.html.\n\nThe IN NATURAL LANGUAGE MODE and IN NATURAL LANGUAGE MODE WITH QUERY\nEXPANSION modifiers were added in MySQL 5.1.7.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html\n\n','mysql> SELECT id, body, MATCH (title,body) AGAINST\n -> (\'Security implications of running MySQL as root\'\n -> IN NATURAL LANGUAGE MODE) AS score\n -> FROM articles WHERE MATCH (title,body) AGAINST\n -> (\'Security implications of running MySQL as root\'\n -> IN NATURAL LANGUAGE MODE);\n+----+-------------------------------------+-----------------+\n| id | body | score |\n+----+-------------------------------------+-----------------+\n| 4 | 1. Never run mysqld as root. 2. ... | 1.5219271183014 |\n| 6 | When configured properly, MySQL ... | 1.3114095926285 |\n+----+-------------------------------------+-----------------+\n2 rows in set (0.00 sec)\n','http://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html');
-insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (87,37,'CREATE EVENT','Syntax:\nCREATE\n [DEFINER = { user | CURRENT_USER }]\n EVENT\n [IF NOT EXISTS]\n event_name\n ON SCHEDULE schedule\n [ON COMPLETION [NOT] PRESERVE]\n [ENABLE | DISABLE | DISABLE ON SLAVE]\n [COMMENT \'comment\']\n DO sql_statement;\n\nschedule:\n AT timestamp [+ INTERVAL interval] ...\n | EVERY interval\n [STARTS timestamp [+ INTERVAL interval] ...]\n [ENDS timestamp [+ INTERVAL interval] ...]\n\ninterval:\n quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |\n WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |\n DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}\n\nThis statement creates and schedules a new event. It requires the EVENT\nprivilege for the schema in which the event is to be created.\n\nThe minimum requirements for a valid CREATE EVENT statement are as\nfollows:\n\no The keywords CREATE EVENT plus an event name, which uniquely\n identifies the event in the current schema. (Prior to MySQL 5.1.12,\n the event name needed to be unique only among events created by the\n same user on a given database.)\n\no An ON SCHEDULE clause, which determines when and how often the event\n executes.\n\no A DO clause, which contains the SQL statement to be executed by an\n event.\n\nThis is an example of a minimal CREATE EVENT statement:\n\nCREATE EVENT myevent\n ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR\n DO\n UPDATE myschema.mytable SET mycol = mycol + 1;\n\nThe previous statement creates an event named myevent. This event\nexecutes once --- one hour following its creation --- by running an SQL\nstatement that increments the value of the myschema.mytable table\'s\nmycol column by 1.\n\nThe event_name must be a valid MySQL identifier with a maximum length\nof 64 characters. It may be delimited using back ticks, and may be\nqualified with the name of a database schema. An event is associated\nwith both a MySQL user (the definer) and a schema, and its name must be\nunique among names of events within that schema. In general, the rules\ngoverning event names are the same as those for names of stored\nroutines. See http://dev.mysql.com/doc/refman/5.1/en/identifiers.html.\n\nIf no schema is indicated as part of event_name, the default (current)\nschema is assumed.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/create-event.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/create-event.html');
+insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (87,37,'CREATE EVENT','Syntax:\nCREATE\n [DEFINER = { user | CURRENT_USER }]\n EVENT\n [IF NOT EXISTS]\n event_name\n ON SCHEDULE schedule\n [ON COMPLETION [NOT] PRESERVE]\n [ENABLE | DISABLE | DISABLE ON SLAVE]\n [COMMENT \'comment\']\n DO sql_statement;\n\nschedule:\n AT timestamp [+ INTERVAL interval] ...\n | EVERY interval\n [STARTS timestamp [+ INTERVAL interval] ...]\n [ENDS timestamp [+ INTERVAL interval] ...]\n\ninterval:\n quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |\n WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |\n DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}\n\nThis statement creates and schedules a new event. It requires the EVENT\nprivilege for the schema in which the event is to be created.\n\nThe minimum requirements for a valid CREATE EVENT statement are as\nfollows:\n\no The keywords CREATE EVENT plus an event name, which uniquely\n identifies the event within a database schema. (Prior to MySQL\n 5.1.12, the event name needed to be unique only among events created\n by the same user within a schema.)\n\no An ON SCHEDULE clause, which determines when and how often the event\n executes.\n\no A DO clause, which contains the SQL statement to be executed by an\n event.\n\nThis is an example of a minimal CREATE EVENT statement:\n\nCREATE EVENT myevent\n ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR\n DO\n UPDATE myschema.mytable SET mycol = mycol + 1;\n\nThe previous statement creates an event named myevent. This event\nexecutes once --- one hour following its creation --- by running an SQL\nstatement that increments the value of the myschema.mytable table\'s\nmycol column by 1.\n\nThe event_name must be a valid MySQL identifier with a maximum length\nof 64 characters. Event names are not case sensitive, so you cannot\nhave two events named myevent and MyEvent in the same schema. In\ngeneral, the rules governing event names are the same as those for\nnames of stored routines. See\nhttp://dev.mysql.com/doc/refman/5.1/en/identifiers.html.\n\nAn event is associated with a schema. If no schema is indicated as part\nof event_name, the default (current) schema is assumed. To create an\nevent in a specific schema, qualify the event name with a schema using\nschema_name.event_name syntax.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/create-event.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/create-event.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (88,4,'ABS','Syntax:\nABS(X)\n\nReturns the absolute value of X.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/mathematical-functions.html\n\n','mysql> SELECT ABS(2);\n -> 2\nmysql> SELECT ABS(-32);\n -> 32\n','http://dev.mysql.com/doc/refman/5.1/en/mathematical-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (89,31,'POLYFROMWKB','PolyFromWKB(wkb[,srid]), PolygonFromWKB(wkb[,srid])\n\nConstructs a POLYGON value using its WKB representation and SRID.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/creating-spatial-values.html#gis-wkb-functions\n\n','','http://dev.mysql.com/doc/refman/5.1/en/creating-spatial-values.html#gis-wkb-functions');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (90,35,'NOT LIKE','Syntax:\nexpr NOT LIKE pat [ESCAPE \'escape_char\']\n\nThis is the same as NOT (expr LIKE pat [ESCAPE \'escape_char\']).\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/string-comparison-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/string-comparison-functions.html');
@@ -163,7 +163,7 @@ insert into help_topic (help_topic_id,help_category_id,name,description,example,
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (94,16,'MAX','Syntax:\nMAX([DISTINCT] expr)\n\nReturns the maximum value of expr. MAX() may take a string argument; in\nsuch cases, it returns the maximum string value. See\nhttp://dev.mysql.com/doc/refman/5.1/en/mysql-indexes.html. The DISTINCT\nkeyword can be used to find the maximum of the distinct values of expr,\nhowever, this produces the same result as omitting DISTINCT.\n\nMAX() returns NULL if there were no matching rows.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html\n\n','mysql> SELECT student_name, MIN(test_score), MAX(test_score)\n -> FROM student\n -> GROUP BY student_name;\n','http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (95,21,'CREATE FUNCTION UDF','Syntax:\nCREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|INTEGER|REAL|DECIMAL}\n SONAME shared_library_name\n\nA user-defined function (UDF) is a way to extend MySQL with a new\nfunction that works like a native (built-in) MySQL function such as\nABS() or CONCAT().\n\nfunction_name is the name that should be used in SQL statements to\ninvoke the function. The RETURNS clause indicates the type of the\nfunction\'s return value. DECIMAL is a legal value after RETURNS, but\ncurrently DECIMAL functions return string values and should be written\nlike STRING functions.\n\nshared_library_name is the basename of the shared object file that\ncontains the code that implements the function. The file must be\nlocated in the plugin directory. This directory is given by the value\nof the plugin_dir system variable.\n\n*Note*: This is a change in MySQL 5.1. For earlier versions of MySQL,\nthe shared object can be located in any directory that is searched by\nyour system\'s dynamic linker.\n\nTo create a function, you must have the INSERT privilege for the mysql\ndatabase. This is necessary because CREATE FUNCTION adds a row to the\nmysql.func system table that records the function\'s name, type, and\nshared library name. If you do not have this table, you should run the\nmysql_upgrade command to create it. See\nhttp://dev.mysql.com/doc/refman/5.1/en/mysql-upgrade.html.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/create-function-udf.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/create-function-udf.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (96,4,'*','Syntax:\n*\n\nMultiplication:\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/arithmetic-functions.html\n\n','mysql> SELECT 3*5;\n -> 15\nmysql> SELECT 18014398509481984*18014398509481984.0;\n -> 324518553658426726783156020576256.0\nmysql> SELECT 18014398509481984*18014398509481984;\n -> 0\n','http://dev.mysql.com/doc/refman/5.1/en/arithmetic-functions.html');
-insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (97,20,'TIMESTAMP','TIMESTAMP\n\nA timestamp. The range is \'1970-01-01 00:00:01\' UTC to \'2038-01-09\n03:14:07\' UTC. TIMESTAMP values are stored as the number of seconds\nsince the epoch (\'1970-01-01 00:00:00\' UTC). A TIMESTAMP cannot\nrepresent the value \'1970-01-01 00:00:00\' because that is equivalent to\n0 seconds from the epoch and the value 0 is reserved for representing\n\'0000-00-00 00:00:00\', the "zero" TIMESTAMP value.\n\nA TIMESTAMP column is useful for recording the date and time of an\nINSERT or UPDATE operation. By default, the first TIMESTAMP column in a\ntable is automatically set to the date and time of the most recent\noperation if you do not assign it a value yourself. You can also set\nany TIMESTAMP column to the current date and time by assigning it a\nNULL value. Variations on automatic initialization and update\nproperties are described in\nhttp://dev.mysql.com/doc/refman/5.1/en/timestamp.html.\n\nA TIMESTAMP value is returned as a string in the format \'YYYY-MM-DD\nHH:MM:SS\' with a display width fixed at 19 characters. To obtain the\nvalue as a number, you should add +0 to the timestamp column.\n\n*Note*: The TIMESTAMP format that was used prior to MySQL 4.1 is not\nsupported in MySQL 5.1; see MySQL 3.23, 4.0, 4.1 Reference Manual for\ninformation regarding the old format.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/date-and-time-type-overview.html');
+insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (97,20,'TIMESTAMP','TIMESTAMP\n\nA timestamp. The range is \'1970-01-01 00:00:01\' UTC to \'2038-01-19\n03:14:07\' UTC. TIMESTAMP values are stored as the number of seconds\nsince the epoch (\'1970-01-01 00:00:00\' UTC). A TIMESTAMP cannot\nrepresent the value \'1970-01-01 00:00:00\' because that is equivalent to\n0 seconds from the epoch and the value 0 is reserved for representing\n\'0000-00-00 00:00:00\', the "zero" TIMESTAMP value.\n\nA TIMESTAMP column is useful for recording the date and time of an\nINSERT or UPDATE operation. By default, the first TIMESTAMP column in a\ntable is automatically set to the date and time of the most recent\noperation if you do not assign it a value yourself. You can also set\nany TIMESTAMP column to the current date and time by assigning it a\nNULL value. Variations on automatic initialization and update\nproperties are described in\nhttp://dev.mysql.com/doc/refman/5.1/en/timestamp.html.\n\nA TIMESTAMP value is returned as a string in the format \'YYYY-MM-DD\nHH:MM:SS\' with a display width fixed at 19 characters. To obtain the\nvalue as a number, you should add +0 to the timestamp column.\n\n*Note*: The TIMESTAMP format that was used prior to MySQL 4.1 is not\nsupported in MySQL 5.1; see MySQL 3.23, 4.0, 4.1 Reference Manual for\ninformation regarding the old format.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/date-and-time-type-overview.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (98,11,'DES_DECRYPT','Syntax:\nDES_DECRYPT(crypt_str[,key_str])\n\nDecrypts a string encrypted with DES_ENCRYPT(). If an error occurs,\nthis function returns NULL.\n\nThis function works only if MySQL has been configured with SSL support.\nSee http://dev.mysql.com/doc/refman/5.1/en/secure-connections.html.\n\nIf no key_str argument is given, DES_DECRYPT() examines the first byte\nof the encrypted string to determine the DES key number that was used\nto encrypt the original string, and then reads the key from the DES key\nfile to decrypt the message. For this to work, the user must have the\nSUPER privilege. The key file can be specified with the --des-key-file\nserver option.\n\nIf you pass this function a key_str argument, that string is used as\nthe key for decrypting the message.\n\nIf the crypt_str argument does not appear to be an encrypted string,\nMySQL returns the given crypt_str.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (99,25,'CACHE INDEX','Syntax:\nCACHE INDEX\n tbl_index_list [, tbl_index_list] ...\n IN key_cache_name\n\ntbl_index_list:\n tbl_name [[INDEX|KEY] (index_name[, index_name] ...)]\n\nThe CACHE INDEX statement assigns table indexes to a specific key\ncache. It is used only for MyISAM tables.\n\nThe following statement assigns indexes from the tables t1, t2, and t3\nto the key cache named hot_cache:\n\nmysql> CACHE INDEX t1, t2, t3 IN hot_cache;\n+---------+--------------------+----------+----------+\n| Table | Op | Msg_type | Msg_text |\n+---------+--------------------+----------+----------+\n| test.t1 | assign_to_keycache | status | OK |\n| test.t2 | assign_to_keycache | status | OK |\n| test.t3 | assign_to_keycache | status | OK |\n+---------+--------------------+----------+----------+\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/cache-index.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/cache-index.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (100,12,'ENDPOINT','EndPoint(ls)\n\nReturns the Point that is the endpoint of the LineString value ls.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/geometry-property-functions.html#linestring-property-functions\n\n','mysql> SET @ls = \'LineString(1 1,2 2,3 3)\';\nmysql> SELECT AsText(EndPoint(GeomFromText(@ls)));\n+-------------------------------------+\n| AsText(EndPoint(GeomFromText(@ls))) |\n+-------------------------------------+\n| POINT(3 3) |\n+-------------------------------------+\n','http://dev.mysql.com/doc/refman/5.1/en/geometry-property-functions.html#linestring-property-functions');
@@ -202,7 +202,7 @@ insert into help_topic (help_topic_id,help_category_id,name,description,example,
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (133,25,'SHOW STATUS','Syntax:\nSHOW [GLOBAL | SESSION] STATUS\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW STATUS provides server status information. This information also\ncan be obtained using the mysqladmin extended-status command. The LIKE\nclause, if present, indicates which variable names to match. The WHERE\nclause can be given to select rows using more general conditions, as\ndiscussed in http://dev.mysql.com/doc/refman/5.1/en/extended-show.html.\nThis statement does not require any privilege. It requires only the\nability to connect to the server.\nWith a LIKE clause, the statement displays only rows for those\nvariables with names that match the pattern:\n\nmysql> SHOW STATUS LIKE \'Key%\';\n+--------------------+----------+\n| Variable_name | Value |\n+--------------------+----------+\n| Key_blocks_used | 14955 |\n| Key_read_requests | 96854827 |\n| Key_reads | 162040 |\n| Key_write_requests | 7589728 |\n| Key_writes | 3813196 |\n+--------------------+----------+\n\nWith the GLOBAL modifier, SHOW STATUS displays the status values for\nall connections to MySQL. With SESSION, it displays the status values\nfor the current connection. If no modifier is present, the default is\nSESSION. LOCAL is a synonym for SESSION.\n\nSome status variables have only a global value. For these, you get the\nsame value for both GLOBAL and SESSION. The scope for each status\nvariable is listed at\nhttp://dev.mysql.com/doc/refman/5.1/en/server-status-variables.html.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/show-status.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/show-status.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (134,35,'EXTRACTVALUE','Syntax:\nExtractValue(xml_frag, xpath_expr)\n\nExtractValue() takes two string arguments, a fragment of XML markup\nxml_frag and an XPath expression xpath_expr (also known as a locator);\nit returns the text (CDATA) of the first text node which is a child of\nthe element(s) matched by the XPath expression. It is the equivalent of\nperforming a match using the xpath_expr after appending /text(). In\nother words, ExtractValue(\'<a><b>Sakila</b></a>\', \'/a/b\') and\nExtractValue(\'<a><b>Sakila</b></a>\', \'/a/b/text()\') produce the same\nresult.\n\nIf multiple matches are found, then the content of the first child text\nnode of each matching element is returned (in the order matched) as a\nsingle, space-delimited string.\n\nIf no matching text node is found for the expression (including the\nimplicit /text()) --- for whatever reason, as long as xpath_expr is\nvalid, and xml_frag consists of elements which are properly nested and\nclosed --- an empty string is returned. No distinction is made between\na match on an empty element and no match at all. This is by design.\n\nIf you need to determine whether no matching element was found in\nxml_frag or such an element was found but contained no child text\nnodes, you should test the result of an expression that uses the XPath\ncount() function. For example, both of these statements return an empty\nstring, as shown here:\n\nmysql> SELECT ExtractValue(\'<a><b/></a>\', \'/a/b\');\n+-------------------------------------+\n| ExtractValue(\'<a><b/></a>\', \'/a/b\') |\n+-------------------------------------+\n| |\n+-------------------------------------+\n1 row in set (0.00 sec)\n\nmysql> SELECT ExtractValue(\'<a><c/></a>\', \'/a/b\');\n+-------------------------------------+\n| ExtractValue(\'<a><c/></a>\', \'/a/b\') |\n+-------------------------------------+\n| |\n+-------------------------------------+\n1 row in set (0.00 sec)\n\nHowever, you can determine whether there was actually a matching\nelement using the following:\n\nmysql> SELECT ExtractValue(\'<a><b/></a>\', \'count(/a/b)\');\n+-------------------------------------+\n| ExtractValue(\'<a><b/></a>\', \'count(/a/b)\') |\n+-------------------------------------+\n| 1 |\n+-------------------------------------+\n1 row in set (0.00 sec)\n\nmysql> SELECT ExtractValue(\'<a><c/></a>\', \'count(/a/b)\');\n+-------------------------------------+\n| ExtractValue(\'<a><c/></a>\', \'count(/a/b)\') |\n+-------------------------------------+\n| 0 |\n+-------------------------------------+\n1 row in set (0.01 sec)\n\n*Important*: ExtractValue() returns only CDATA, and does not return any\ntags that might be contained within a matching tag, nor any of their\ncontent (see the result returned as val1 in the following example).\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/xml-functions.html\n\n','mysql> SELECT\n -> ExtractValue(\'<a>ccc<b>ddd</b></a>\', \'/a\') AS val1,\n -> ExtractValue(\'<a>ccc<b>ddd</b></a>\', \'/a/b\') AS val2,\n -> ExtractValue(\'<a>ccc<b>ddd</b></a>\', \'//b\') AS val3,\n -> ExtractValue(\'<a>ccc<b>ddd</b></a>\', \'/b\') AS val4,\n -> ExtractValue(\'<a>ccc<b>ddd</b><b>eee</b></a>\', \'//b\') AS val5;\n\n+------+------+------+------+---------+\n| val1 | val2 | val3 | val4 | val5 |\n+------+------+------+------+---------+\n| ccc | ddd | ddd | | ddd eee |\n+------+------+------+------+---------+\n','http://dev.mysql.com/doc/refman/5.1/en/xml-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (135,11,'OLD_PASSWORD','Syntax:\nOLD_PASSWORD(str)\n\nOLD_PASSWORD() was added to MySQL when the implementation of PASSWORD()\nwas changed to improve security. OLD_PASSWORD() returns the value of\nthe old (pre-4.1) implementation of PASSWORD() as a binary string, and\nis intended to permit you to reset passwords for any pre-4.1 clients\nthat need to connect to your version 5.1 MySQL server without locking\nthem out. See\nhttp://dev.mysql.com/doc/refman/5.1/en/password-hashing.html.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html');
-insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (136,22,'SET VARIABLE','Syntax:\nSET var_name = expr [, var_name = expr] ...\n\nThe SET statement in stored programs is an extended version of the\ngeneral SET statement (see [HELP SET]). Referenced variables may be\nones declared inside a stored program, global system variables, or\nuser-defined variables.\n\nThe SET statement in stored programs is implemented as part of the\npre-existing SET syntax. This allows an extended syntax of SET a=x,\nb=y, ... where different variable types (locally declared variables,\nglobal and session server variables, user-defined variables) can be\nmixed. This also allows combinations of local variables and some\noptions that make sense only for system variables; in that case, the\noptions are recognized but ignored.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/set-statement.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/set-statement.html');
+insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (136,22,'SET VARIABLE','Syntax:\nSET var_name = expr [, var_name = expr] ...\n\nThe SET statement in stored programs is an extended version of the\ngeneral SET statement (see [HELP SET]). Each var_name may refer to a\nlocal variable declared inside a stored program, a system variable, or\na user-defined variable.\n\nThe SET statement in stored programs is implemented as part of the\npre-existing SET syntax. This allows an extended syntax of SET a=x,\nb=y, ... where different variable types (locally declared variables,\nglobal and session system variables, user-defined variables) can be\nmixed. This also allows combinations of local variables and some\noptions that make sense only for system variables; in that case, the\noptions are recognized but ignored.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/set-statement.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/set-statement.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (137,35,'FORMAT','Syntax:\nFORMAT(X,D)\n\nFormats the number X to a format like \'#,###,###.##\', rounded to D\ndecimal places, and returns the result as a string. If D is 0, the\nresult has no decimal point or fractional part.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/string-functions.html\n\n','mysql> SELECT FORMAT(12332.123456, 4);\n -> \'12,332.1235\'\nmysql> SELECT FORMAT(12332.1,4);\n -> \'12,332.1000\'\nmysql> SELECT FORMAT(12332.2,0);\n -> \'12,332\'\n','http://dev.mysql.com/doc/refman/5.1/en/string-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (138,13,'||','Syntax:\nOR, ||\n\nLogical OR. When both operands are non-NULL, the result is 1 if any\noperand is nonzero, and 0 otherwise. With a NULL operand, the result is\n1 if the other operand is nonzero, and NULL otherwise. If both operands\nare NULL, the result is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/logical-operators.html\n\n','mysql> SELECT 1 || 1;\n -> 1\nmysql> SELECT 1 || 0;\n -> 1\nmysql> SELECT 0 || 0;\n -> 0\nmysql> SELECT 0 || NULL;\n -> NULL\nmysql> SELECT 1 || NULL;\n -> 1\n','http://dev.mysql.com/doc/refman/5.1/en/logical-operators.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (139,35,'BIT_LENGTH','Syntax:\nBIT_LENGTH(str)\n\nReturns the length of the string str in bits.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/string-functions.html\n\n','mysql> SELECT BIT_LENGTH(\'text\');\n -> 32\n','http://dev.mysql.com/doc/refman/5.1/en/string-functions.html');
@@ -233,7 +233,7 @@ insert into help_topic (help_topic_id,help_category_id,name,description,example,
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (164,30,'SEC_TO_TIME','Syntax:\nSEC_TO_TIME(seconds)\n\nReturns the seconds argument, converted to hours, minutes, and seconds,\nas a TIME value. The range of the result is constrained to that of the\nTIME data type. A warning occurs if the argument corresponds to a value\noutside that range.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html\n\n','mysql> SELECT SEC_TO_TIME(2378);\n -> \'00:39:38\'\nmysql> SELECT SEC_TO_TIME(2378) + 0;\n -> 3938\n','http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (165,20,'FLOAT','FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]\n\nA small (single-precision) floating-point number. Allowable values are\n-3.402823466E+38 to -1.175494351E-38, 0, and 1.175494351E-38 to\n3.402823466E+38. These are the theoretical limits, based on the IEEE\nstandard. The actual range might be slightly smaller depending on your\nhardware or operating system.\n\nM is the total number of digits and D is the number of digits following\nthe decimal point. If M and D are omitted, values are stored to the\nlimits allowed by the hardware. A single-precision floating-point\nnumber is accurate to approximately 7 decimal places.\n\nUNSIGNED, if specified, disallows negative values.\n\nUsing FLOAT might give you some unexpected problems because all\ncalculations in MySQL are done with double precision. See\nhttp://dev.mysql.com/doc/refman/5.1/en/no-matching-rows.html.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/numeric-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/numeric-type-overview.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (166,35,'LOCATE','Syntax:\nLOCATE(substr,str), LOCATE(substr,str,pos)\n\nThe first syntax returns the position of the first occurrence of\nsubstring substr in string str. The second syntax returns the position\nof the first occurrence of substring substr in string str, starting at\nposition pos. Returns 0 if substr is not in str.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/string-functions.html\n\n','mysql> SELECT LOCATE(\'bar\', \'foobarbar\');\n -> 4\nmysql> SELECT LOCATE(\'xbar\', \'foobar\');\n -> 0\nmysql> SELECT LOCATE(\'bar\', \'foobarbar\', 5);\n -> 7\n','http://dev.mysql.com/doc/refman/5.1/en/string-functions.html');
-insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (167,25,'SHOW EVENTS','Syntax:\nSHOW EVENTS [{FROM | IN} schema_name]\n [LIKE \'pattern\' | WHERE expr]\n\nIn its simplest form, SHOW EVENTS lists all of the events in the\ncurrent schema:\n\nmysql> SELECT CURRENT_USER(), SCHEMA();\n+----------------+----------+\n| CURRENT_USER() | SCHEMA() |\n+----------------+----------+\n| jon@ghidora | myschema |\n+----------------+----------+\n1 row in set (0.00 sec)\n\nmysql> SHOW EVENTS\\G\n*************************** 1. row ***************************\n Db: myschema\n Name: e_daily\n Definer: jon@ghidora\n Time zone: SYSTEM\n Type: RECURRING\n Execute at: NULL\n Interval value: 10\n Interval field: SECOND\n Starts: 2006-02-09 10:41:23\n Ends: 0000-00-00 00:00:00\n Status: ENABLED\n Originator: 0\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n\nThe LIKE clause, if present, indicates which event names to match. The\nWHERE clause can be given to select rows using more general conditions,\nas discussed in\nhttp://dev.mysql.com/doc/refman/5.1/en/extended-show.html.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/show-events.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/show-events.html');
+insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (167,25,'SHOW EVENTS','Syntax:\nSHOW EVENTS [{FROM | IN} schema_name]\n [LIKE \'pattern\' | WHERE expr]\n\nIn its simplest form, SHOW EVENTS lists all of the events in the\ncurrent schema:\n\nmysql> SELECT CURRENT_USER(), SCHEMA();\n+----------------+----------+\n| CURRENT_USER() | SCHEMA() |\n+----------------+----------+\n| jon@ghidora | myschema |\n+----------------+----------+\n1 row in set (0.00 sec)\n\nmysql> SHOW EVENTS\\G\n*************************** 1. row ***************************\n Db: myschema\n Name: e_daily\n Definer: jon@ghidora\n Time zone: SYSTEM\n Type: RECURRING\n Execute at: NULL\n Interval value: 10\n Interval field: SECOND\n Starts: 2006-02-09 10:41:23\n Ends: NULL\n Status: ENABLED\n Originator: 0\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n\nTo see events for a specific schema, use the FROM clause. For example,\nto see events for the test schema, use the following statement:\n\nSHOW EVENTS FROM test;\n\nThe LIKE clause, if present, indicates which event names to match. The\nWHERE clause can be given to select rows using more general conditions,\nas discussed in\nhttp://dev.mysql.com/doc/refman/5.1/en/extended-show.html.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/show-events.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/show-events.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (168,15,'CHARSET','Syntax:\nCHARSET(str)\n\nReturns the character set of the string argument.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/information-functions.html\n\n','mysql> SELECT CHARSET(\'abc\');\n -> \'latin1\'\nmysql> SELECT CHARSET(CONVERT(\'abc\' USING utf8));\n -> \'utf8\'\nmysql> SELECT CHARSET(USER());\n -> \'utf8\'\n','http://dev.mysql.com/doc/refman/5.1/en/information-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (169,30,'SUBDATE','Syntax:\nSUBDATE(date,INTERVAL expr unit), SUBDATE(expr,days)\n\nWhen invoked with the INTERVAL form of the second argument, SUBDATE()\nis a synonym for DATE_SUB(). For information on the INTERVAL unit\nargument, see the discussion for DATE_ADD().\n\nmysql> SELECT DATE_SUB(\'2008-01-02\', INTERVAL 31 DAY);\n -> \'2007-12-02\'\nmysql> SELECT SUBDATE(\'2008-01-02\', INTERVAL 31 DAY);\n -> \'2007-12-02\'\n\nThe second form allows the use of an integer value for days. In such\ncases, it is interpreted as the number of days to be subtracted from\nthe date or datetime expression expr.\n\nmysql> SELECT SUBDATE(\'2008-01-02 12:00:00\', 31);\n -> \'2007-12-02 12:00:00\'\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (170,30,'DAYOFYEAR','Syntax:\nDAYOFYEAR(date)\n\nReturns the day of the year for date, in the range 1 to 366.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html\n\n','mysql> SELECT DAYOFYEAR(\'2007-02-03\');\n -> 34\n','http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html');
@@ -250,7 +250,7 @@ insert into help_topic (help_topic_id,help_category_id,name,description,example,
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (181,24,'NUMGEOMETRIES','NumGeometries(gc)\n\nReturns the number of geometries in the GeometryCollection value gc.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/geometry-property-functions.html#geometrycollection-property-functions\n\n','mysql> SET @gc = \'GeometryCollection(Point(1 1),LineString(2 2, 3 3))\';\nmysql> SELECT NumGeometries(GeomFromText(@gc));\n+----------------------------------+\n| NumGeometries(GeomFromText(@gc)) |\n+----------------------------------+\n| 2 |\n+----------------------------------+\n','http://dev.mysql.com/doc/refman/5.1/en/geometry-property-functions.html#geometrycollection-property-functions');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (182,30,'MONTHNAME','Syntax:\nMONTHNAME(date)\n\nReturns the full name of the month for date. As of MySQL 5.1.12, the\nlanguage used for the name is controlled by the value of the\nlc_time_names system variable\n(http://dev.mysql.com/doc/refman/5.1/en/locale-support.html).\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html\n\n','mysql> SELECT MONTHNAME(\'2008-02-03\');\n -> \'February\'\n','http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (183,36,'PROCEDURE ANALYSE','Syntax:\nANALYSE([max_elements[,max_memory]])\n\nANALYSE() is defined in the sql/sql_analyse.cc source file, which\nserves as an example of how to create a procedure for use with the\nPROCEDURE clause of SELECT statements. ANALYSE() is built in and is\navailable by default; other procedures can be created using the format\ndemonstrated in the source file.\n\nANALYSE() examines the result from a query and returns an analysis of\nthe results that suggests optimal data types for each column that may\nhelp reduce table sizes. To obtain this analysis, append PROCEDURE\nANALYSE to the end of a SELECT statement:\n\nSELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max_elements,[max_memory]])\n\nFor example:\n\nSELECT col1, col2 FROM table1 PROCEDURE ANALYSE(10, 2000);\n\nThe results show some statistics for the values returned by the query,\nand propose an optimal data type for the columns. This can be helpful\nfor checking your existing tables, or after importing new data. You may\nneed to try different settings for the arguments so that PROCEDURE\nANALYSE() does not suggest the ENUM data type when it is not\nappropriate.\n\nThe arguments are optional and are used as follows:\n\no max_elements (default 256) is the maximum number of distinct values\n that ANALYSE() notices per column. This is used by ANALYSE() to check\n whether the optimal data type should be of type ENUM; if there are\n more than max_elements distinct values, then ENUM is not a suggested\n type.\n\no max_memory (default 8192) is the maximum amount of memory that\n ANALYSE() should allocate per column while trying to find all\n distinct values.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/procedure-analyse.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/procedure-analyse.html');
-insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (184,25,'CHANGE MASTER TO','Syntax:\nCHANGE MASTER TO master_def [, master_def] ...\n\nmaster_def:\n MASTER_BIND = \'interface_name\'\n | MASTER_HOST = \'host_name\'\n | MASTER_USER = \'user_name\'\n | MASTER_PASSWORD = \'password\'\n | MASTER_PORT = port_num\n | MASTER_CONNECT_RETRY = interval\n | MASTER_HEARTBEAT_PERIOD = interval\n | MASTER_LOG_FILE = \'master_log_name\'\n | MASTER_LOG_POS = master_log_pos\n | RELAY_LOG_FILE = \'relay_log_name\'\n | RELAY_LOG_POS = relay_log_pos\n | MASTER_SSL = {0|1}\n | MASTER_SSL_CA = \'ca_file_name\'\n | MASTER_SSL_CAPATH = \'ca_directory_name\'\n | MASTER_SSL_CERT = \'cert_file_name\'\n | MASTER_SSL_KEY = \'key_file_name\'\n | MASTER_SSL_CIPHER = \'cipher_list\'\n | MASTER_SSL_VERIFY_SERVER_CERT = {0|1}\n\nCHANGE MASTER TO changes the parameters that the slave server uses for\nconnecting to and communicating with the master server. It also updates\nthe contents of the master.info and relay-log.info files.\n\nMASTER_USER, MASTER_PASSWORD, MASTER_SSL, MASTER_SSL_CA,\nMASTER_SSL_CAPATH, MASTER_SSL_CERT, MASTER_SSL_KEY, MASTER_SSL_CIPHER,\nand MASTER_SSL_VERIFY_SERVER_CERT provide information to the slave\nabout how to connect to its master. MASTER_SSL_VERIFY_SERVER_CERT was\nadded in MySQL 5.1.18. It is used as described for the\n--ssl-verify-server-cert option in\nhttp://dev.mysql.com/doc/refman/5.1/en/ssl-options.html.\n\nMASTER_CONNECT_RETRY specifies how many seconds to wait between connect\nretries. The default is 60. The number of reconnection attempts is\nlimited by the --master-retry-count server option; for more\ninformation, see\nhttp://dev.mysql.com/doc/refman/5.1/en/replication-options.html.\n\nThe SSL options (MASTER_SSL, MASTER_SSL_CA, MASTER_SSL_CAPATH,\nMASTER_SSL_CERT, MASTER_SSL_KEY, MASTER_SSL_CIPHER), and\nMASTER_SSL_VERIFY_SERVER_CERT can be changed even on slaves that are\ncompiled without SSL support. They are saved to the master.info file,\nbut are ignored unless you use a server that has SSL support enabled.\n\nIf you don\'t specify a given parameter, it keeps its old value, except\nas indicated in the following discussion. For example, if the password\nto connect to your MySQL master has changed, you just need to issue\nthese statements to tell the slave about the new password:\n\nSTOP SLAVE; -- if replication was running\nCHANGE MASTER TO MASTER_PASSWORD=\'new3cret\';\nSTART SLAVE; -- if you want to restart replication\n\nThere is no need to specify the parameters that do not change (host,\nport, user, and so forth).\n\nMASTER_HOST and MASTER_PORT are the host name (or IP address) of the\nmaster host and its TCP/IP port.\n\nThe next two options are available only in MySQL Cluster NDB 6.3 and\n6.4; they are not supported in mainline MySQL 5.1:\n\no MASTER_BIND is for use on replication slaves having multiple network\n interfaces, and determines which of the slave\'s network interfaces is\n chosen for connecting to the master. It is also possible to determine\n which network interface is to be used in such cases by starting the\n slave mysqld process with the --master-bind option.\n\n The ability to bind a replication slave to specific network interface\n was added in MySQL Cluster NDB 6.3.4.\n\no MASTER_HEARTBEAT_PERIOD is used to set the interval in seconds\n between replication heartbeats. Whenever the master\'s binlog is\n updated with an event, the waiting period for the next heartbeat is\n reset. interval is a decimal value having the range 0 to 4294967\n seconds and a resolution to hundredths of a second; the smallest\n nonzero value is 0.001. Heartbeats are sent by the master only if\n there are no unsent events in the binlog file for a period longer\n than interval.\n\n Setting interval to 0 disables heartbeats altogether. The default\n value for interval is equal to the value of slave_net_timeout divided\n by 2.\n\n *Note*: Setting @@global.slave_net_timeout to a value less than that\n of the current heartbeat interval results in a warning being issued.\n\n Issuing RESET SLAVE resets the heartbeat interval to the default.\n\n MASTER_HEARTBEAT_PERIOD was added in MySQL Cluster NDB 6.3.4.\n\n*Note*: Replication cannot use Unix socket files. You must be able to\nconnect to the master MySQL server using TCP/IP.\n\nIf you specify MASTER_HOST or MASTER_PORT, the slave assumes that the\nmaster server is different from before (even if you specify a host or\nport value that is the same as the current value.) In this case, the\nold values for the master binary log name and position are considered\nno longer applicable, so if you do not specify MASTER_LOG_FILE and\nMASTER_LOG_POS in the statement, MASTER_LOG_FILE=\'\' and\nMASTER_LOG_POS=4 are silently appended to it.\n\nSetting MASTER_HOST=\'\' --- that is, setting its value explicitly to an\nempty string --- is not the same as not setting it at all. Setting this\noption to an empty string causes START SLAVE subsequently to fail. This\nissue is addressed in MySQL 6.0. (Bug#28796\n(http://bugs.mysql.com/28796))\n\nMASTER_LOG_FILE and MASTER_LOG_POS are the coordinates at which the\nslave I/O thread should begin reading from the master the next time the\nthread starts. If you specify either of them, you cannot specify\nRELAY_LOG_FILE or RELAY_LOG_POS. If neither of MASTER_LOG_FILE or\nMASTER_LOG_POS are specified, the slave uses the last coordinates of\nthe slave SQL thread before CHANGE MASTER TO was issued. This ensures\nthat there is no discontinuity in replication, even if the slave SQL\nthread was late compared to the slave I/O thread, when you merely want\nto change, say, the password to use.\n\nCHANGE MASTER TO deletes all relay log files and starts a new one,\nunless you specify RELAY_LOG_FILE or RELAY_LOG_POS. In that case, relay\nlogs are kept; the relay_log_purge global variable is set silently to\n0.\n\nCHANGE MASTER TO is useful for setting up a slave when you have the\nsnapshot of the master and have recorded the log and the offset\ncorresponding to it. After loading the snapshot into the slave, you can\nrun CHANGE MASTER TO MASTER_LOG_FILE=\'log_name_on_master\',\nMASTER_LOG_POS=log_offset_on_master on the slave.\n\nThe following example changes the master and master\'s binary log\ncoordinates. This is used when you want to set up the slave to\nreplicate the master:\n\nCHANGE MASTER TO\n MASTER_HOST=\'master2.mycompany.com\',\n MASTER_USER=\'replication\',\n MASTER_PASSWORD=\'bigs3cret\',\n MASTER_PORT=3306,\n MASTER_LOG_FILE=\'master2-bin.001\',\n MASTER_LOG_POS=4,\n MASTER_CONNECT_RETRY=10;\n\nThe next example shows an operation that is less frequently employed.\nIt is used when the slave has relay logs that you want it to execute\nagain for some reason. To do this, the master need not be reachable.\nYou need only use CHANGE MASTER TO and start the SQL thread (START\nSLAVE SQL_THREAD):\n\nCHANGE MASTER TO\n RELAY_LOG_FILE=\'slave-relay-bin.006\',\n RELAY_LOG_POS=4025;\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/change-master-to.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/change-master-to.html');
+insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (184,25,'CHANGE MASTER TO','Syntax:\nCHANGE MASTER TO master_def [, master_def] ...\n\nmaster_def:\n MASTER_BIND = \'interface_name\'\n | MASTER_HOST = \'host_name\'\n | MASTER_USER = \'user_name\'\n | MASTER_PASSWORD = \'password\'\n | MASTER_PORT = port_num\n | MASTER_CONNECT_RETRY = interval\n | MASTER_HEARTBEAT_PERIOD = interval\n | MASTER_LOG_FILE = \'master_log_name\'\n | MASTER_LOG_POS = master_log_pos\n | RELAY_LOG_FILE = \'relay_log_name\'\n | RELAY_LOG_POS = relay_log_pos\n | MASTER_SSL = {0|1}\n | MASTER_SSL_CA = \'ca_file_name\'\n | MASTER_SSL_CAPATH = \'ca_directory_name\'\n | MASTER_SSL_CERT = \'cert_file_name\'\n | MASTER_SSL_KEY = \'key_file_name\'\n | MASTER_SSL_CIPHER = \'cipher_list\'\n | MASTER_SSL_VERIFY_SERVER_CERT = {0|1}\n\nCHANGE MASTER TO changes the parameters that the slave server uses for\nconnecting to and communicating with the master server. It also updates\nthe contents of the master.info and relay-log.info files.\n\nMASTER_USER, MASTER_PASSWORD, MASTER_SSL, MASTER_SSL_CA,\nMASTER_SSL_CAPATH, MASTER_SSL_CERT, MASTER_SSL_KEY, MASTER_SSL_CIPHER,\nand MASTER_SSL_VERIFY_SERVER_CERT provide information to the slave\nabout how to connect to its master. MASTER_SSL_VERIFY_SERVER_CERT was\nadded in MySQL 5.1.18. It is used as described for the\n--ssl-verify-server-cert option in\nhttp://dev.mysql.com/doc/refman/5.1/en/ssl-options.html.\n\nMASTER_CONNECT_RETRY specifies how many seconds to wait between connect\nretries. The default is 60. The number of reconnection attempts is\nlimited by the --master-retry-count server option; for more\ninformation, see\nhttp://dev.mysql.com/doc/refman/5.1/en/replication-options.html.\n\nThe SSL options (MASTER_SSL, MASTER_SSL_CA, MASTER_SSL_CAPATH,\nMASTER_SSL_CERT, MASTER_SSL_KEY, MASTER_SSL_CIPHER), and\nMASTER_SSL_VERIFY_SERVER_CERT can be changed even on slaves that are\ncompiled without SSL support. They are saved to the master.info file,\nbut are ignored unless you use a server that has SSL support enabled.\n\nIf you do not specify a given parameter, it keeps its old value, except\nas indicated in the following discussion. For example, if the password\nto connect to your MySQL master has changed, you just need to issue\nthese statements to tell the slave about the new password:\n\nSTOP SLAVE; -- if replication was running\nCHANGE MASTER TO MASTER_PASSWORD=\'new3cret\';\nSTART SLAVE; -- if you want to restart replication\n\nThere is no need to specify the parameters that do not change (host,\nport, user, and so forth).\n\nMASTER_HOST and MASTER_PORT are the host name (or IP address) of the\nmaster host and its TCP/IP port.\n\nThe next two options (MASTER_BIND and MASTER_HEARTBEAT_PERIOD) are\navailable in MySQL Cluster NDB 6.3 and later, but are not supported in\nmainline MySQL 5.1:\n\no MASTER_BIND is for use on replication slaves having multiple network\n interfaces, and determines which of the slave\'s network interfaces is\n chosen for connecting to the master. It is also possible to determine\n which network interface is to be used in such cases by starting the\n slave mysqld process with the --master-bind option.\n\n The ability to bind a replication slave to specific network interface\n was added in MySQL Cluster NDB 6.3.4.\n\no MASTER_HEARTBEAT_PERIOD is used to set the interval in seconds\n between replication heartbeats. Whenever the master\'s binlog is\n updated with an event, the waiting period for the next heartbeat is\n reset. interval is a decimal value having the range 0 to 4294967\n seconds and a resolution to hundredths of a second; the smallest\n nonzero value is 0.001. Heartbeats are sent by the master only if\n there are no unsent events in the binlog file for a period longer\n than interval.\n\n Setting interval to 0 disables heartbeats altogether. The default\n value for interval is equal to the value of slave_net_timeout divided\n by 2.\n\n Setting @@global.slave_net_timeout to a value less than that of the\n current heartbeat interval results in a warning being issued. The\n effect of issuing RESET SLAVE on the heartbeat interval is to reset\n it to the default value.\n\n MASTER_HEARTBEAT_PERIOD was added in MySQL Cluster NDB 6.3.4.\n\n*Note*: Replication cannot use Unix socket files. You must be able to\nconnect to the master MySQL server using TCP/IP.\n\nIf you specify MASTER_HOST or MASTER_PORT, the slave assumes that the\nmaster server is different from before (even if you specify a host or\nport value that is the same as the current value.) In this case, the\nold values for the master binary log name and position are considered\nno longer applicable, so if you do not specify MASTER_LOG_FILE and\nMASTER_LOG_POS in the statement, MASTER_LOG_FILE=\'\' and\nMASTER_LOG_POS=4 are silently appended to it.\n\nSetting MASTER_HOST=\'\' --- that is, setting its value explicitly to an\nempty string --- is not the same as not setting it at all. Setting this\noption to an empty string causes START SLAVE subsequently to fail. This\nissue is addressed in MySQL 5.5. (Bug#28796\n(http://bugs.mysql.com/28796))\n\nMASTER_LOG_FILE and MASTER_LOG_POS are the coordinates at which the\nslave I/O thread should begin reading from the master the next time the\nthread starts. If you specify either of them, you cannot specify\nRELAY_LOG_FILE or RELAY_LOG_POS. If neither of MASTER_LOG_FILE or\nMASTER_LOG_POS are specified, the slave uses the last coordinates of\nthe slave SQL thread before CHANGE MASTER TO was issued. This ensures\nthat there is no discontinuity in replication, even if the slave SQL\nthread was late compared to the slave I/O thread, when you merely want\nto change, say, the password to use.\n\nCHANGE MASTER TO deletes all relay log files and starts a new one,\nunless you specify RELAY_LOG_FILE or RELAY_LOG_POS. In that case, relay\nlogs are kept; the relay_log_purge global variable is set silently to\n0.\n\nCHANGE MASTER TO is useful for setting up a slave when you have the\nsnapshot of the master and have recorded the log and the offset\ncorresponding to it. After loading the snapshot into the slave, you can\nrun CHANGE MASTER TO MASTER_LOG_FILE=\'log_name_on_master\',\nMASTER_LOG_POS=log_offset_on_master on the slave.\n\nThe following example changes the master and master\'s binary log\ncoordinates. This is used when you want to set up the slave to\nreplicate the master:\n\nCHANGE MASTER TO\n MASTER_HOST=\'master2.mycompany.com\',\n MASTER_USER=\'replication\',\n MASTER_PASSWORD=\'bigs3cret\',\n MASTER_PORT=3306,\n MASTER_LOG_FILE=\'master2-bin.001\',\n MASTER_LOG_POS=4,\n MASTER_CONNECT_RETRY=10;\n\nThe next example shows an operation that is less frequently employed.\nIt is used when the slave has relay logs that you want it to execute\nagain for some reason. To do this, the master need not be reachable.\nYou need only use CHANGE MASTER TO and start the SQL thread (START\nSLAVE SQL_THREAD):\n\nCHANGE MASTER TO\n RELAY_LOG_FILE=\'slave-relay-bin.006\',\n RELAY_LOG_POS=4025;\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/change-master-to.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/change-master-to.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (185,37,'DROP DATABASE','Syntax:\nDROP {DATABASE | SCHEMA} [IF EXISTS] db_name\n\nDROP DATABASE drops all tables in the database and deletes the\ndatabase. Be very careful with this statement! To use DROP DATABASE,\nyou need the DROP privilege on the database. DROP SCHEMA is a synonym\nfor DROP DATABASE.\n\n*Important*: When a database is dropped, user privileges on the\ndatabase are not automatically dropped. See [HELP GRANT].\n\nIF EXISTS is used to prevent an error from occurring if the database\ndoes not exist.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/drop-database.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/drop-database.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (186,6,'MBREQUAL','MBREqual(g1,g2)\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of\nthe two geometries g1 and g2 are the same.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/relations-on-geometry-mbr.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/relations-on-geometry-mbr.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (187,30,'TIMESTAMP FUNCTION','Syntax:\nTIMESTAMP(expr), TIMESTAMP(expr1,expr2)\n\nWith a single argument, this function returns the date or datetime\nexpression expr as a datetime value. With two arguments, it adds the\ntime expression expr2 to the date or datetime expression expr1 and\nreturns the result as a datetime value.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html\n\n','mysql> SELECT TIMESTAMP(\'2003-12-31\');\n -> \'2003-12-31 00:00:00\'\nmysql> SELECT TIMESTAMP(\'2003-12-31 12:00:00\',\'12:00:00\');\n -> \'2004-01-01 00:00:00\'\n','http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html');
@@ -322,7 +322,7 @@ insert into help_topic (help_topic_id,help_category_id,name,description,example,
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (253,20,'VARCHAR','[NATIONAL] VARCHAR(M) [CHARACTER SET charset_name] [COLLATE\ncollation_name]\n\nA variable-length string. M represents the maximum column length in\ncharacters. The range of M is 0 to 65,535. The effective maximum length\nof a VARCHAR is subject to the maximum row size (65,535 bytes, which is\nshared among all columns) and the character set used. For example, utf8\ncharacters can require up to three bytes per character, so a VARCHAR\ncolumn that uses the utf8 character set can be declared to be a maximum\nof 21,844 characters.\n\nMySQL stores VARCHAR values as a one-byte or two-byte length prefix\nplus data. The length prefix indicates the number of bytes in the\nvalue. A VARCHAR column uses one length byte if values require no more\nthan 255 bytes, two length bytes if values may require more than 255\nbytes.\n\n*Note*: MySQL 5.1 follows the standard SQL specification, and does not\nremove trailing spaces from VARCHAR values.\n\nVARCHAR is shorthand for CHARACTER VARYING. NATIONAL VARCHAR is the\nstandard SQL way to define that a VARCHAR column should use some\npredefined character set. MySQL 4.1 and up uses utf8 as this predefined\ncharacter set.\nhttp://dev.mysql.com/doc/refman/5.1/en/charset-national.html. NVARCHAR\nis shorthand for NATIONAL VARCHAR.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/string-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/string-type-overview.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (254,35,'UNHEX','Syntax:\n\nUNHEX(str)\n\nPerforms the inverse operation of HEX(str). That is, it interprets each\npair of hexadecimal digits in the argument as a number and converts it\nto the character represented by the number. The resulting characters\nare returned as a binary string.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/string-functions.html\n\n','mysql> SELECT UNHEX(\'4D7953514C\');\n -> \'MySQL\'\nmysql> SELECT 0x4D7953514C;\n -> \'MySQL\'\nmysql> SELECT UNHEX(HEX(\'string\'));\n -> \'string\'\nmysql> SELECT HEX(UNHEX(\'1267\'));\n -> \'1267\'\n','http://dev.mysql.com/doc/refman/5.1/en/string-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (255,4,'- UNARY','Syntax:\n-\n\nUnary minus. This operator changes the sign of the argument.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/arithmetic-functions.html\n\n','mysql> SELECT - 2;\n -> -2\n','http://dev.mysql.com/doc/refman/5.1/en/arithmetic-functions.html');
-insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (256,22,'SELECT INTO','Syntax:\nSELECT col_name [, col_name] ...\n INTO var_name [, var_name] ...\n table_expr\n\nSELECT ... INTO syntax enables selected columns to be stored directly\ninto variables. The query should return a single row. If the query\nreturns no rows, a warning with error code 1329 occurs (No data), and\nthe variable values remain unchanged. If the query returns multiple\nrows, error 1172 occurs (Result consisted of more than one row). If it\nis possible that the statement may retrieve multiple rows, you can use\nLIMIT 1 to limit the result set to a single row.\n\nIn the context of such statements that occur as part of events executed\nby the Event Scheduler, diagnostics messages (not only errors, but also\nwarnings) are written to the error log, and, on Windows, to the\napplication event log. For additional information, see\nhttp://dev.mysql.com/doc/refman/5.1/en/events-status-info.html.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/select-into-statement.html\n\n','SELECT id,data INTO x,y FROM test.t1 LIMIT 1;\n','http://dev.mysql.com/doc/refman/5.1/en/select-into-statement.html');
+insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (256,22,'SELECT INTO','Syntax:\nSELECT col_name [, col_name] ...\n INTO var_name [, var_name] ...\n table_expr\n\nSELECT ... INTO syntax enables selected columns to be stored directly\ninto variables. The query should return a single row. If the query\nreturns no rows, a warning with error code 1329 occurs (No data), and\nthe variable values remain unchanged. If the query returns multiple\nrows, error 1172 occurs (Result consisted of more than one row). If it\nis possible that the statement may retrieve multiple rows, you can use\nLIMIT 1 to limit the result set to a single row.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/select-into-statement.html\n\n','SELECT id,data INTO x,y FROM test.t1 LIMIT 1;\n','http://dev.mysql.com/doc/refman/5.1/en/select-into-statement.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (257,16,'STD','Syntax:\nSTD(expr)\n\nReturns the population standard deviation of expr. This is an extension\nto standard SQL. The standard SQL function STDDEV_POP() can be used\ninstead.\n\nThis function returns NULL if there were no matching rows.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (258,4,'COS','Syntax:\nCOS(X)\n\nReturns the cosine of X, where X is given in radians.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/mathematical-functions.html\n\n','mysql> SELECT COS(PI());\n -> -1\n','http://dev.mysql.com/doc/refman/5.1/en/mathematical-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (259,30,'DATE FUNCTION','Syntax:\nDATE(expr)\n\nExtracts the date part of the date or datetime expression expr.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html\n\n','mysql> SELECT DATE(\'2003-12-31 01:02:03\');\n -> \'2003-12-31\'\n','http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html');
@@ -384,7 +384,7 @@ insert into help_topic (help_topic_id,help_category_id,name,description,example,
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (315,15,'FOUND_ROWS','Syntax:\nFOUND_ROWS()\n\nA SELECT statement may include a LIMIT clause to restrict the number of\nrows the server returns to the client. In some cases, it is desirable\nto know how many rows the statement would have returned without the\nLIMIT, but without running the statement again. To obtain this row\ncount, include a SQL_CALC_FOUND_ROWS option in the SELECT statement,\nand then invoke FOUND_ROWS() afterward:\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/information-functions.html\n\n','mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name\n -> WHERE id > 100 LIMIT 10;\nmysql> SELECT FOUND_ROWS();\n','http://dev.mysql.com/doc/refman/5.1/en/information-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (316,15,'SYSTEM_USER','Syntax:\nSYSTEM_USER()\n\nSYSTEM_USER() is a synonym for USER().\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/information-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/information-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (317,29,'CROSSES','Crosses(g1,g2)\n\nReturns 1 if g1 spatially crosses g2. Returns NULL if g1 is a Polygon\nor a MultiPolygon, or if g2 is a Point or a MultiPoint. Otherwise,\nreturns 0.\n\nThe term spatially crosses denotes a spatial relation between two given\ngeometries that has the following properties:\n\no The two geometries intersect\n\no Their intersection results in a geometry that has a dimension that is\n one less than the maximum dimension of the two given geometries\n\no Their intersection is not equal to either of the two given geometries\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/functions-that-test-spatial-relationships-between-geometries.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/functions-that-test-spatial-relationships-between-geometries.html');
-insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (318,26,'TRUNCATE TABLE','Syntax:\nTRUNCATE [TABLE] tbl_name\n\nTRUNCATE TABLE empties a table completely. Logically, this is\nequivalent to a DELETE statement that deletes all rows, but there are\npractical differences under some circumstances.\n\nFor an InnoDB table, InnoDB processes TRUNCATE TABLE by deleting rows\none by one if there are any FOREIGN KEY constraints that reference the\ntable. If there are no FOREIGN KEY constraints, InnoDB performs fast\ntruncation by dropping the original table and creating an empty one\nwith the same definition, which is much faster than deleting rows one\nby one. The AUTO_INCREMENT counter is reset by TRUNCATE TABLE,\nregardless of whether there is a FOREIGN KEY constraint.\n\nIn the case that FOREIGN KEY constraints reference the table, InnoDB\ndeletes rows one by one and processes the constraints on each one. If\nthe FOREIGN KEY constraint specifies DELETE CASCADE, rows from the\nchild (referenced) table are deleted, and the truncated table becomes\nempty. If the FOREIGN KEY constraint does not specify CASCADE, the\nTRUNCATE statement deletes rows one by one and stops if it encounters a\nparent row that is referenced by the child, returning this error:\n\nERROR 1451 (23000): Cannot delete or update a parent row: a foreign\nkey constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1`\nFOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))\n\nThis is the same as a DELETE statement with no WHERE clause.\n\nBeginning with MySQL 5.1.32, TRUNCATE is treated for purposes of binary\nlogging and replication as DROP TABLE followed by CREATE TABLE --- that\nis, as DDL rather than DML. This is due to the fact that, when using\nInnoDB and other transactional storage engines where the transaction\nisolation level does not allow for statement-based logging (READ\nCOMMITTED or READ UNCOMMITTED), the statement was not logged and\nreplicated when using STATEMENT or MIXED logging mode. (Bug#36763\n(http://bugs.mysql.com/36763)) However, it is still applied on\nreplication slaves using InnoDB in the manner described previously.\n\nThe count of rows affected by TRUNCATE TABLE is accurate only when it\nis mapped to a DELETE statement.\n\nFor other storage engines, TRUNCATE TABLE differs from DELETE in the\nfollowing ways in MySQL 5.1:\n\no Truncate operations drop and re-create the table, which is much\n faster than deleting rows one by one, particularly for large tables.\n\no Truncate operations cause an implicit commit.\n\no Truncation operations cannot be performed if the session holds an\n active table lock.\n\no Truncation operations do not return a meaningful value for the number\n of deleted rows. The usual result is "0 rows affected," which should\n be interpreted as "no information."\n\no As long as the table format file tbl_name.frm is valid, the table can\n be re-created as an empty table with TRUNCATE TABLE, even if the data\n or index files have become corrupted.\n\no The table handler does not remember the last used AUTO_INCREMENT\n value, but starts counting from the beginning. This is true even for\n MyISAM and InnoDB, which normally do not reuse sequence values.\n\no When used with partitioned tables, TRUNCATE TABLE preserves the\n partitioning; that is, the data and index files are dropped and\n re-created, while the partition definitions (.par) file is\n unaffected.\n\no Since truncation of a table does not make any use of DELETE, the\n TRUNCATE statement does not invoke ON DELETE triggers.\n\nTRUNCATE TABLE requires the DROP privilege as of MySQL 5.1.16. (Before\n5.1.16, it requires the DELETE privilege.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/truncate.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/truncate.html');
+insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (318,26,'TRUNCATE TABLE','Syntax:\nTRUNCATE [TABLE] tbl_name\n\nTRUNCATE TABLE empties a table completely. It requires the DROP\nprivilege as of MySQL 5.1.16. (Before 5.1.16, it requires the DELETE\nprivilege.\n\nLogically, TRUNCATE TABLE is equivalent to a DELETE statement that\ndeletes all rows, but there are practical differences under some\ncircumstances.\n\nFor an InnoDB table, InnoDB processes TRUNCATE TABLE by deleting rows\none by one if there are any FOREIGN KEY constraints that reference the\ntable. If there are no FOREIGN KEY constraints, InnoDB performs fast\ntruncation by dropping the original table and creating an empty one\nwith the same definition, which is much faster than deleting rows one\nby one. The AUTO_INCREMENT counter is reset by TRUNCATE TABLE,\nregardless of whether there is a FOREIGN KEY constraint.\n\nIn the case that FOREIGN KEY constraints reference the table, InnoDB\ndeletes rows one by one and processes the constraints on each one. If\nthe FOREIGN KEY constraint specifies DELETE CASCADE, rows from the\nchild (referenced) table are deleted, and the truncated table becomes\nempty. If the FOREIGN KEY constraint does not specify CASCADE, the\nTRUNCATE statement deletes rows one by one and stops if it encounters a\nparent row that is referenced by the child, returning this error:\n\nERROR 1451 (23000): Cannot delete or update a parent row: a foreign\nkey constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1`\nFOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`))\n\nThis is the same as a DELETE statement with no WHERE clause.\n\nThe count of rows affected by TRUNCATE TABLE is accurate only when it\nis mapped to a DELETE statement.\n\nFor other storage engines, TRUNCATE TABLE differs from DELETE in the\nfollowing ways in MySQL 5.1:\n\no Truncate operations drop and re-create the table, which is much\n faster than deleting rows one by one, particularly for large tables.\n\no Truncate operations cause an implicit commit.\n\no Truncation operations cannot be performed if the session holds an\n active table lock.\n\no Truncation operations do not return a meaningful value for the number\n of deleted rows. The usual result is "0 rows affected," which should\n be interpreted as "no information."\n\no As long as the table format file tbl_name.frm is valid, the table can\n be re-created as an empty table with TRUNCATE TABLE, even if the data\n or index files have become corrupted.\n\no The table handler does not remember the last used AUTO_INCREMENT\n value, but starts counting from the beginning. This is true even for\n MyISAM and InnoDB, which normally do not reuse sequence values.\n\no When used with partitioned tables, TRUNCATE TABLE preserves the\n partitioning; that is, the data and index files are dropped and\n re-created, while the partition definitions (.par) file is\n unaffected.\n\no Since truncation of a table does not make any use of DELETE, the\n TRUNCATE statement does not invoke ON DELETE triggers.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/truncate.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/truncate.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (319,16,'BIT_XOR','Syntax:\nBIT_XOR(expr)\n\nReturns the bitwise XOR of all bits in expr. The calculation is\nperformed with 64-bit (BIGINT) precision.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (320,30,'CURRENT_DATE','Syntax:\nCURRENT_DATE, CURRENT_DATE()\n\nCURRENT_DATE and CURRENT_DATE() are synonyms for CURDATE().\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (321,25,'START SLAVE','Syntax:\nSTART SLAVE [thread_type [, thread_type] ... ]\nSTART SLAVE [SQL_THREAD] UNTIL\n MASTER_LOG_FILE = \'log_name\', MASTER_LOG_POS = log_pos\nSTART SLAVE [SQL_THREAD] UNTIL\n RELAY_LOG_FILE = \'log_name\', RELAY_LOG_POS = log_pos\n\nthread_type: IO_THREAD | SQL_THREAD\n\nSTART SLAVE with no thread_type options starts both of the slave\nthreads. The I/O thread reads queries from the master server and stores\nthem in the relay log. The SQL thread reads the relay log and executes\nthe queries. START SLAVE requires the SUPER privilege.\n\nIf START SLAVE succeeds in starting the slave threads, it returns\nwithout any error. However, even in that case, it might be that the\nslave threads start and then later stop (for example, because they do\nnot manage to connect to the master or read its binary logs, or some\nother problem). START SLAVE does not warn you about this. You must\ncheck the slave\'s error log for error messages generated by the slave\nthreads, or check that they are running satisfactorily with SHOW SLAVE\nSTATUS.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/start-slave.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/start-slave.html');
@@ -410,7 +410,7 @@ insert into help_topic (help_topic_id,help_category_id,name,description,example,
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (341,22,'LOOP','Syntax:\n[begin_label:] LOOP\n statement_list\nEND LOOP [end_label]\n\nLOOP implements a simple loop construct, enabling repeated execution of\nthe statement list, which consists of one or more statements, each\nterminated by a semicolon (;) statement delimiter. The statements\nwithin the loop are repeated until the loop is exited; usually this is\naccomplished with a LEAVE statement.\n\nA LOOP statement can be labeled. end_label cannot be given unless\nbegin_label also is present. If both are present, they must be the\nsame.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/loop-statement.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/loop-statement.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (342,4,'TRUNCATE','Syntax:\nTRUNCATE(X,D)\n\nReturns the number X, truncated to D decimal places. If D is 0, the\nresult has no decimal point or fractional part. D can be negative to\ncause D digits left of the decimal point of the value X to become zero.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/mathematical-functions.html\n\n','mysql> SELECT TRUNCATE(1.223,1);\n -> 1.2\nmysql> SELECT TRUNCATE(1.999,1);\n -> 1.9\nmysql> SELECT TRUNCATE(1.999,0);\n -> 1\nmysql> SELECT TRUNCATE(-1.999,1);\n -> -1.9\nmysql> SELECT TRUNCATE(122,-2);\n -> 100\nmysql> SELECT TRUNCATE(10.28*100,0);\n -> 1028\n','http://dev.mysql.com/doc/refman/5.1/en/mathematical-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (343,30,'TIMESTAMPADD','Syntax:\nTIMESTAMPADD(unit,interval,datetime_expr)\n\nAdds the integer expression interval to the date or datetime expression\ndatetime_expr. The unit for interval is given by the unit argument,\nwhich should be one of the following values: FRAC_SECOND\n(microseconds), SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, or\nYEAR.\n\nBeginning with MySQL 5.1.24, it is possible to use MICROSECOND in place\nof FRAC_SECOND with this function, and FRAC_SECOND is deprecated.\n\nThe unit value may be specified using one of keywords as shown, or with\na prefix of SQL_TSI_. For example, DAY and SQL_TSI_DAY both are legal.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html\n\n','mysql> SELECT TIMESTAMPADD(MINUTE,1,\'2003-01-02\');\n -> \'2003-01-02 00:01:00\'\nmysql> SELECT TIMESTAMPADD(WEEK,1,\'2003-01-02\');\n -> \'2003-01-09\'\n','http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html');
-insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (344,25,'SHOW','SHOW has many forms that provide information about databases, tables,\ncolumns, or status information about the server. This section describes\nthose following:\n\nSHOW AUTHORS\nSHOW CHARACTER SET [like_or_where]\nSHOW COLLATION [like_or_where]\nSHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [like_or_where]\nSHOW CONTRIBUTORS\nSHOW CREATE DATABASE db_name\nSHOW CREATE EVENT event_name\nSHOW CREATE FUNCTION func_name\nSHOW CREATE PROCEDURE proc_name\nSHOW CREATE TABLE tbl_name\nSHOW CREATE TRIGGER trigger_name\nSHOW CREATE VIEW view_name\nSHOW DATABASES [like_or_where]\nSHOW ENGINE engine_name {STATUS | MUTEX}\nSHOW [STORAGE] ENGINES\nSHOW ERRORS [LIMIT [offset,] row_count]\nSHOW [FULL] EVENTS\nSHOW FUNCTION CODE func_name\nSHOW FUNCTION STATUS [like_or_where]\nSHOW GRANTS FOR user\nSHOW INDEX FROM tbl_name [FROM db_name]\nSHOW INNODB STATUS\nSHOW OPEN TABLES [FROM db_name] [like_or_where]\nSHOW PLUGINS\nSHOW PROCEDURE CODE proc_name\nSHOW PROCEDURE STATUS [like_or_where]\nSHOW PRIVILEGES\nSHOW [FULL] PROCESSLIST\nSHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n]\nSHOW PROFILES\nSHOW SCHEDULER STATUS\nSHOW [GLOBAL | SESSION] STATUS [like_or_where]\nSHOW TABLE STATUS [FROM db_name] [like_or_where]\nSHOW TABLES [FROM db_name] [like_or_where]\nSHOW TRIGGERS [FROM db_name] [like_or_where]\nSHOW [GLOBAL | SESSION] VARIABLES [like_or_where]\nSHOW WARNINGS [LIMIT [offset,] row_count]\n\nlike_or_where:\n LIKE \'pattern\'\n | WHERE expr\n\nIf the syntax for a given SHOW statement includes a LIKE \'pattern\'\npart, \'pattern\' is a string that can contain the SQL "%" and "_"\nwildcard characters. The pattern is useful for restricting statement\noutput to matching values.\n\nSeveral SHOW statements also accept a WHERE clause that provides more\nflexibility in specifying which rows to display. See\nhttp://dev.mysql.com/doc/refman/5.1/en/extended-show.html.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/show.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/show.html');
+insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (344,25,'SHOW','SHOW has many forms that provide information about databases, tables,\ncolumns, or status information about the server. This section describes\nthose following:\n\nSHOW AUTHORS\nSHOW CHARACTER SET [like_or_where]\nSHOW COLLATION [like_or_where]\nSHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [like_or_where]\nSHOW CONTRIBUTORS\nSHOW CREATE DATABASE db_name\nSHOW CREATE EVENT event_name\nSHOW CREATE FUNCTION func_name\nSHOW CREATE PROCEDURE proc_name\nSHOW CREATE TABLE tbl_name\nSHOW CREATE TRIGGER trigger_name\nSHOW CREATE VIEW view_name\nSHOW DATABASES [like_or_where]\nSHOW ENGINE engine_name {STATUS | MUTEX}\nSHOW [STORAGE] ENGINES\nSHOW ERRORS [LIMIT [offset,] row_count]\nSHOW EVENTS\nSHOW FUNCTION CODE func_name\nSHOW FUNCTION STATUS [like_or_where]\nSHOW GRANTS FOR user\nSHOW INDEX FROM tbl_name [FROM db_name]\nSHOW INNODB STATUS\nSHOW OPEN TABLES [FROM db_name] [like_or_where]\nSHOW PLUGINS\nSHOW PROCEDURE CODE proc_name\nSHOW PROCEDURE STATUS [like_or_where]\nSHOW PRIVILEGES\nSHOW [FULL] PROCESSLIST\nSHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n]\nSHOW PROFILES\nSHOW SCHEDULER STATUS\nSHOW [GLOBAL | SESSION] STATUS [like_or_where]\nSHOW TABLE STATUS [FROM db_name] [like_or_where]\nSHOW TABLES [FROM db_name] [like_or_where]\nSHOW TRIGGERS [FROM db_name] [like_or_where]\nSHOW [GLOBAL | SESSION] VARIABLES [like_or_where]\nSHOW WARNINGS [LIMIT [offset,] row_count]\n\nlike_or_where:\n LIKE \'pattern\'\n | WHERE expr\n\nIf the syntax for a given SHOW statement includes a LIKE \'pattern\'\npart, \'pattern\' is a string that can contain the SQL "%" and "_"\nwildcard characters. The pattern is useful for restricting statement\noutput to matching values.\n\nSeveral SHOW statements also accept a WHERE clause that provides more\nflexibility in specifying which rows to display. See\nhttp://dev.mysql.com/doc/refman/5.1/en/extended-show.html.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/show.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/show.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (345,17,'GREATEST','Syntax:\nGREATEST(value1,value2,...)\n\nWith two or more arguments, returns the largest (maximum-valued)\nargument. The arguments are compared using the same rules as for\nLEAST().\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html\n\n','mysql> SELECT GREATEST(2,0);\n -> 2\nmysql> SELECT GREATEST(34.0,3.0,5.0,767.0);\n -> 767.0\nmysql> SELECT GREATEST(\'B\',\'A\',\'C\');\n -> \'C\'\n','http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (346,25,'SHOW VARIABLES','Syntax:\nSHOW [GLOBAL | SESSION] VARIABLES\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW VARIABLES shows the values of MySQL system variables. This\ninformation also can be obtained using the mysqladmin variables\ncommand. The LIKE clause, if present, indicates which variable names to\nmatch. The WHERE clause can be given to select rows using more general\nconditions, as discussed in\nhttp://dev.mysql.com/doc/refman/5.1/en/extended-show.html. This\nstatement does not require any privilege. It requires only the ability\nto connect to the server.\n\nWith the GLOBAL modifier, SHOW VARIABLES displays the values that are\nused for new connections to MySQL. With SESSION, it displays the values\nthat are in effect for the current connection. If no modifier is\npresent, the default is SESSION. LOCAL is a synonym for SESSION.\nWith a LIKE clause, the statement displays only rows for those\nvariables with names that match the pattern. To obtain the row for a\nspecific variable, use a LIKE clause as shown:\n\nSHOW VARIABLES LIKE \'max_join_size\';\nSHOW SESSION VARIABLES LIKE \'max_join_size\';\n\nTo get a list of variables whose name match a pattern, use the "%"\nwildcard character in a LIKE clause:\n\nSHOW VARIABLES LIKE \'%size%\';\nSHOW GLOBAL VARIABLES LIKE \'%size%\';\n\nWildcard characters can be used in any position within the pattern to\nbe matched. Strictly speaking, because "_" is a wildcard that matches\nany single character, you should escape it as "\\_" to match it\nliterally. In practice, this is rarely necessary.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/show-variables.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/show-variables.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (347,25,'BINLOG','Syntax:\nBINLOG \'str\'\n\nBINLOG is an internal-use statement. It is generated by the mysqlbinlog\nprogram as the printable representation of certain events in binary log\nfiles. (See http://dev.mysql.com/doc/refman/5.1/en/mysqlbinlog.html.)\nThe \'str\' value is a base 64-encoded string the that server decodes to\ndetermine the data change indicated by the corresponding event. This\nstatement requires the SUPER privilege. It was added in MySQL 5.1.5.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/binlog.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/binlog.html');
@@ -419,7 +419,7 @@ insert into help_topic (help_topic_id,help_category_id,name,description,example,
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (350,4,'ATAN2','Syntax:\nATAN(Y,X), ATAN2(Y,X)\n\nReturns the arc tangent of the two variables X and Y. It is similar to\ncalculating the arc tangent of Y / X, except that the signs of both\narguments are used to determine the quadrant of the result.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/mathematical-functions.html\n\n','mysql> SELECT ATAN(-2,2);\n -> -0.78539816339745\nmysql> SELECT ATAN2(PI(),0);\n -> 1.5707963267949\n','http://dev.mysql.com/doc/refman/5.1/en/mathematical-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (351,6,'MBRCONTAINS','MBRContains(g1,g2)\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangle of g1\ncontains the Minimum Bounding Rectangle of g2. This tests the opposite\nrelationship as MBRWithin().\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/relations-on-geometry-mbr.html\n\n','mysql> SET @g1 = GeomFromText(\'Polygon((0 0,0 3,3 3,3 0,0 0))\');\nmysql> SET @g2 = GeomFromText(\'Point(1 1)\');\nmysql> SELECT MBRContains(@g1,@g2), MBRContains(@g2,@g1);\n----------------------+----------------------+\n| MBRContains(@g1,@g2) | MBRContains(@g2,@g1) |\n+----------------------+----------------------+\n| 1 | 0 |\n+----------------------+----------------------+\n','http://dev.mysql.com/doc/refman/5.1/en/relations-on-geometry-mbr.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (352,30,'HOUR','Syntax:\nHOUR(time)\n\nReturns the hour for time. The range of the return value is 0 to 23 for\ntime-of-day values. However, the range of TIME values actually is much\nlarger, so HOUR can return values greater than 23.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html\n\n','mysql> SELECT HOUR(\'10:05:03\');\n -> 10\nmysql> SELECT HOUR(\'272:59:59\');\n -> 272\n','http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html');
-insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (353,26,'SELECT','Syntax:\nSELECT\n [ALL | DISTINCT | DISTINCTROW ]\n [HIGH_PRIORITY]\n [STRAIGHT_JOIN]\n [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]\n [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]\n select_expr [, select_expr ...]\n [FROM table_references\n [WHERE where_condition]\n [GROUP BY {col_name | expr | position}\n [ASC | DESC], ... [WITH ROLLUP]]\n [HAVING where_condition]\n [ORDER BY {col_name | expr | position}\n [ASC | DESC], ...]\n [LIMIT {[offset,] row_count | row_count OFFSET offset}]\n [PROCEDURE procedure_name(argument_list)]\n [INTO OUTFILE \'file_name\' export_options\n | INTO DUMPFILE \'file_name\'\n | INTO var_name [, var_name]]\n [FOR UPDATE | LOCK IN SHARE MODE]]\n\nSELECT is used to retrieve rows selected from one or more tables, and\ncan include UNION statements and subqueries. See [HELP UNION], and\nhttp://dev.mysql.com/doc/refman/5.1/en/subqueries.html.\n\nThe most commonly used clauses of SELECT statements are these:\n\no Each select_expr indicates a column that you want to retrieve. There\n must be at least one select_expr.\n\no table_references indicates the table or tables from which to retrieve\n rows. Its syntax is described in [HELP JOIN].\n\no The WHERE clause, if given, indicates the condition or conditions\n that rows must satisfy to be selected. where_condition is an\n expression that evaluates to true for each row to be selected. The\n statement selects all rows if there is no WHERE clause.\n\n In the WHERE clause, you can use any of the functions and operators\n that MySQL supports, except for aggregate (summary) functions. See\n http://dev.mysql.com/doc/refman/5.1/en/functions.html.\n\nSELECT can also be used to retrieve rows computed without reference to\nany table.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/select.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/select.html');
+insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (353,26,'SELECT','Syntax:\nSELECT\n [ALL | DISTINCT | DISTINCTROW ]\n [HIGH_PRIORITY]\n [STRAIGHT_JOIN]\n [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]\n [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]\n select_expr [, select_expr ...]\n [FROM table_references\n [WHERE where_condition]\n [GROUP BY {col_name | expr | position}\n [ASC | DESC], ... [WITH ROLLUP]]\n [HAVING where_condition]\n [ORDER BY {col_name | expr | position}\n [ASC | DESC], ...]\n [LIMIT {[offset,] row_count | row_count OFFSET offset}]\n [PROCEDURE procedure_name(argument_list)]\n [INTO OUTFILE \'file_name\'\n [CHARACTER SET charset_name]\n export_options\n | INTO DUMPFILE \'file_name\'\n | INTO var_name [, var_name]]\n [FOR UPDATE | LOCK IN SHARE MODE]]\n\nSELECT is used to retrieve rows selected from one or more tables, and\ncan include UNION statements and subqueries. See [HELP UNION], and\nhttp://dev.mysql.com/doc/refman/5.1/en/subqueries.html.\n\nThe most commonly used clauses of SELECT statements are these:\n\no Each select_expr indicates a column that you want to retrieve. There\n must be at least one select_expr.\n\no table_references indicates the table or tables from which to retrieve\n rows. Its syntax is described in [HELP JOIN].\n\no The WHERE clause, if given, indicates the condition or conditions\n that rows must satisfy to be selected. where_condition is an\n expression that evaluates to true for each row to be selected. The\n statement selects all rows if there is no WHERE clause.\n\n In the WHERE clause, you can use any of the functions and operators\n that MySQL supports, except for aggregate (summary) functions. See\n http://dev.mysql.com/doc/refman/5.1/en/functions.html.\n\nSELECT can also be used to retrieve rows computed without reference to\nany table.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/select.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/select.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (354,4,'COT','Syntax:\nCOT(X)\n\nReturns the cotangent of X.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/mathematical-functions.html\n\n','mysql> SELECT COT(12);\n -> -1.5726734063977\nmysql> SELECT COT(0);\n -> NULL\n','http://dev.mysql.com/doc/refman/5.1/en/mathematical-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (355,25,'SHOW CREATE EVENT','Syntax:\nSHOW CREATE EVENT event_name\n\nThis statement displays the CREATE EVENT statement needed to re-create\na given event. For example (using the same event e_daily defined and\nthen altered in [HELP SHOW EVENTS]):\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/show-create-event.html\n\n','mysql> SHOW CREATE EVENT test.e_daily\\G\n*************************** 1. row ***************************\n Event: e_daily\n sql_mode:\n time_zone: SYSTEM\n Create Event: CREATE EVENT `e_daily`\n ON SCHEDULE EVERY 1 DAY\n STARTS CURRENT_TIMESTAMP + INTERVAL 6 HOUR\n ON COMPLETION NOT PRESERVE\n ENABLE\n COMMENT \'Saves total number of sessions then\n clears the table each day\'\n DO BEGIN\n INSERT INTO site_activity.totals (time, total)\n SELECT CURRENT_TIMESTAMP, COUNT(*)\n FROM site_activity.sessions;\n DELETE FROM site_activity.sessions;\n END\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n','http://dev.mysql.com/doc/refman/5.1/en/show-create-event.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (356,19,'BACKUP TABLE','Syntax:\nBACKUP TABLE tbl_name [, tbl_name] ... TO \'/path/to/backup/directory\'\n\n*Note*: This statement is deprecated. We are working on a better\nreplacement for it that will provide online backup capabilities. In the\nmeantime, the mysqlhotcopy script can be used instead.\n\nBACKUP TABLE copies to the backup directory the minimum number of table\nfiles needed to restore the table, after flushing any buffered changes\nto disk. The statement works only for MyISAM tables. It copies the .frm\ndefinition and .MYD data files. The .MYI index file can be rebuilt from\nthose two files. The directory should be specified as a full path name.\nTo restore the table, use RESTORE TABLE.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/backup-table.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/backup-table.html');
@@ -486,7 +486,7 @@ insert into help_topic (help_topic_id,help_category_id,name,description,example,
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (417,35,'BIN','Syntax:\nBIN(N)\n\nReturns a string representation of the binary value of N, where N is a\nlonglong (BIGINT) number. This is equivalent to CONV(N,10,2). Returns\nNULL if N is NULL.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/string-functions.html\n\n','mysql> SELECT BIN(12);\n -> \'1100\'\n','http://dev.mysql.com/doc/refman/5.1/en/string-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (418,5,'INSTALL PLUGIN','Syntax:\nINSTALL PLUGIN plugin_name SONAME \'plugin_library\'\n\nThis statement installs a plugin.\n\nplugin_name is the name of the plugin as defined in the plugin\ndeclaration structure contained in the library file. Plugin names are\nnot case sensitive. For maximal compatibility, plugin names should be\nlimited to ASCII letters, digits, and underscore, because they are used\nin C source files, shell command lines, M4 and Bourne shell scripts,\nand SQL environments.\n\nplugin_library is the name of the shared library that contains the\nplugin code. The name includes the file name extension (for example,\nlibmyplugin.so or libmyplugin.dylib).\n\nThe shared library must be located in the plugin directory (that is,\nthe directory named by the plugin_dir system variable). The library\nmust be in the plugin directory itself, not in a subdirectory. By\ndefault, plugin_dir is plugin directory under the directory named by\nthe pkglibdir configuration variable, but it can be changed by setting\nthe value of plugin_dir at server startup. For example, set its value\nin a my.cnf file:\n\n[mysqld]\nplugin_dir=/path/to/plugin/directory\n\nIf the value of plugin_dir is a relative path name, it is taken to be\nrelative to the MySQL base directory (the value of the basedir system\nvariable).\n\nINSTALL PLUGIN adds a line to the mysql.plugin table that describes the\nplugin. This table contains the plugin name and library file name.\n\nAs of MySQL 5.1.33, INSTALL PLUGIN causes the server to read option\n(my.cnf) files just as during server startup. This enables the plugin\nto pick up any relevant options from those files. It is possible to add\nplugin options to an option file even before loading a plugin (if the\nloose prefix is used). It is also possible to uninstall a plugin, edit\nmy.cnf, and install the plugin again. Restarting the plugin this way\nenables it to the new option values without a server restart.\n\nBefore MySQL 5.1.33, a plugin is started with each option set to its\ndefault value.\n\nINSTALL PLUGIN also loads and initializes the plugin code to make the\nplugin available for use. A plugin is initialized by executing its\ninitialization function, which handles any setup that the plugin must\nperform before it can be used.\n\nTo use INSTALL PLUGIN, you must have the INSERT privilege for the\nmysql.plugin table.\n\nAt server startup, the server loads and initializes any plugin that is\nlisted in the mysql.plugin table. This means that a plugin is installed\nwith INSTALL PLUGIN only once, not every time the server starts. Plugin\nloading at startup does not occur if the server is started with the\n--skip-grant-tables option.\n\nWhen the server shuts down, it executes the deinitialization function\nfor each plugin that is loaded so that the plugin has a change to\nperform any final cleanup.\n\nFor options that control individual plugin loading at server startup,\nsee http://dev.mysql.com/doc/refman/5.1/en/server-plugin-options.html.\nIf you need to load plugins for a single server startup when the\n--skip-grant-tables option is given (which tells the server not to read\nsystem tables), use the --plugin-load option. See\nhttp://dev.mysql.com/doc/refman/5.1/en/server-options.html.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/install-plugin.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/install-plugin.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (419,22,'DECLARE CURSOR','Syntax:\nDECLARE cursor_name CURSOR FOR select_statement\n\nThis statement declares a cursor. Multiple cursors may be declared in a\nstored program, but each cursor in a given block must have a unique\nname.\n\nThe SELECT statement cannot have an INTO clause.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/declare-cursor.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/declare-cursor.html');
-insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (420,26,'LOAD DATA','Syntax:\nLOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE \'file_name\'\n [REPLACE | IGNORE]\n INTO TABLE tbl_name\n [CHARACTER SET charset_name]\n [{FIELDS | COLUMNS}\n [TERMINATED BY \'string\']\n [[OPTIONALLY] ENCLOSED BY \'char\']\n [ESCAPED BY \'char\']\n ]\n [LINES\n [STARTING BY \'string\']\n [TERMINATED BY \'string\']\n ]\n [IGNORE number LINES]\n [(col_name_or_user_var,...)]\n [SET col_name = expr,...]\n\nThe LOAD DATA INFILE statement reads rows from a text file into a table\nat a very high speed. The file name must be given as a literal string.\n\nLOAD DATA INFILE is the complement of SELECT ... INTO OUTFILE. (See\nhttp://dev.mysql.com/doc/refman/5.1/en/select.html.) To write data from\na table to a file, use SELECT ... INTO OUTFILE. To read the file back\ninto a table, use LOAD DATA INFILE. The syntax of the FIELDS and LINES\nclauses is the same for both statements. Both clauses are optional, but\nFIELDS must precede LINES if both are specified.\n\nFor more information about the efficiency of INSERT versus LOAD DATA\nINFILE and speeding up LOAD DATA INFILE, see\nhttp://dev.mysql.com/doc/refman/5.1/en/insert-speed.html.\n\nThe character set indicated by the character_set_database system\nvariable is used to interpret the information in the file. SET NAMES\nand the setting of character_set_client do not affect interpretation of\ninput. If the contents of the input file use a character set that\ndiffers from the default, it is usually preferable to specify the\ncharacter set of the file by using the CHARACTER SET clause, which is\navailable as of MySQL 5.1.17. A character set of binary specifies "no\nconversion."\n\nLOAD DATA INFILE interprets all fields in the file as having the same\ncharacter set, regardless of the data types of the columns into which\nfield values are loaded. For proper interpretation of file contents,\nyou must ensure that it was written with the correct character set. For\nexample, if you write a data file with mysqldump -T or by issuing a\nSELECT ... INTO OUTFILE statement in mysql, be sure to use a\n--default-character-set option with mysqldump or mysql so that output\nis written in the character set to be used when the file is loaded with\nLOAD DATA INFILE.\n\nNote that it is currently not possible to load data files that use the\nucs2, utf16, or utf32 character set.\n\nAs of MySQL 5.1.6, the character_set_filesystem system variable\ncontrols the interpretation of the file name.\n\nYou can also load data files by using the mysqlimport utility; it\noperates by sending a LOAD DATA INFILE statement to the server. The\n--local option causes mysqlimport to read data files from the client\nhost. You can specify the --compress option to get better performance\nover slow networks if the client and server support the compressed\nprotocol. See http://dev.mysql.com/doc/refman/5.1/en/mysqlimport.html.\n\nIf you use LOW_PRIORITY, execution of the LOAD DATA statement is\ndelayed until no other clients are reading from the table. This affects\nonly storage engines that use only table-level locking (MyISAM, MEMORY,\nMERGE).\n\nIf you specify CONCURRENT with a MyISAM table that satisfies the\ncondition for concurrent inserts (that is, it contains no free blocks\nin the middle), other threads can retrieve data from the table while\nLOAD DATA is executing. Using this option affects the performance of\nLOAD DATA a bit, even if no other thread is using the table at the same\ntime.\n\nCONCURRENT is not replicated when using statement-based replication;\nhowever, it is replicated when using row-based replication. See\nhttp://dev.mysql.com/doc/refman/5.1/en/replication-features-load-data.h\ntml, for more information.\n\n*Note*: Prior to MySQL 5.1.23, LOAD DATA performed very poorly when\nimporting into partitioned tables. The statement now uses buffering to\nimprove performance; however, the buffer uses 130 KB memory per\npartition to achieve this. (Bug#26527 (http://bugs.mysql.com/26527))\n\nThe LOCAL keyword, if specified, is interpreted with respect to the\nclient end of the connection:\n\no If LOCAL is specified, the file is read by the client program on the\n client host and sent to the server. The file can be given as a full\n path name to specify its exact location. If given as a relative path\n name, the name is interpreted relative to the directory in which the\n client program was started.\n\no If LOCAL is not specified, the file must be located on the server\n host and is read directly by the server. The server uses the\n following rules to locate the file:\n\n o If the file name is an absolute path name, the server uses it as\n given.\n\n o If the file name is a relative path name with one or more leading\n components, the server searches for the file relative to the\n server\'s data directory.\n\n o If a file name with no leading components is given, the server\n looks for the file in the database directory of the default\n database.\n\nNote that, in the non-LOCAL case, these rules mean that a file named as\n./myfile.txt is read from the server\'s data directory, whereas the file\nnamed as myfile.txt is read from the database directory of the default\ndatabase. For example, if db1 is the default database, the following\nLOAD DATA statement reads the file data.txt from the database directory\nfor db1, even though the statement explicitly loads the file into a\ntable in the db2 database:\n\nLOAD DATA INFILE \'data.txt\' INTO TABLE db2.my_table;\n\nWindows path names are specified using forward slashes rather than\nbackslashes. If you do use backslashes, you must double them.\n\nFor security reasons, when reading text files located on the server,\nthe files must either reside in the database directory or be readable\nby all. Also, to use LOAD DATA INFILE on server files, you must have\nthe FILE privilege. See\nhttp://dev.mysql.com/doc/refman/5.1/en/privileges-provided.html. For\nnon-LOCAL load operations, if the secure_file_priv system variable is\nset to a nonempty directory name, the file to be loaded must be located\nin that directory.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/load-data.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/load-data.html');
+insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (420,26,'LOAD DATA','Syntax:\nLOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE \'file_name\'\n [REPLACE | IGNORE]\n INTO TABLE tbl_name\n [CHARACTER SET charset_name]\n [{FIELDS | COLUMNS}\n [TERMINATED BY \'string\']\n [[OPTIONALLY] ENCLOSED BY \'char\']\n [ESCAPED BY \'char\']\n ]\n [LINES\n [STARTING BY \'string\']\n [TERMINATED BY \'string\']\n ]\n [IGNORE number LINES]\n [(col_name_or_user_var,...)]\n [SET col_name = expr,...]\n\nThe LOAD DATA INFILE statement reads rows from a text file into a table\nat a very high speed. The file name must be given as a literal string.\n\nLOAD DATA INFILE is the complement of SELECT ... INTO OUTFILE. (See\nhttp://dev.mysql.com/doc/refman/5.1/en/select.html.) To write data from\na table to a file, use SELECT ... INTO OUTFILE. To read the file back\ninto a table, use LOAD DATA INFILE. The syntax of the FIELDS and LINES\nclauses is the same for both statements. Both clauses are optional, but\nFIELDS must precede LINES if both are specified.\n\nFor more information about the efficiency of INSERT versus LOAD DATA\nINFILE and speeding up LOAD DATA INFILE, see\nhttp://dev.mysql.com/doc/refman/5.1/en/insert-speed.html.\n\nThe character set indicated by the character_set_database system\nvariable is used to interpret the information in the file. SET NAMES\nand the setting of character_set_client do not affect interpretation of\ninput. If the contents of the input file use a character set that\ndiffers from the default, it is usually preferable to specify the\ncharacter set of the file by using the CHARACTER SET clause, which is\navailable as of MySQL 5.1.17. A character set of binary specifies "no\nconversion."\n\nLOAD DATA INFILE interprets all fields in the file as having the same\ncharacter set, regardless of the data types of the columns into which\nfield values are loaded. For proper interpretation of file contents,\nyou must ensure that it was written with the correct character set. For\nexample, if you write a data file with mysqldump -T or by issuing a\nSELECT ... INTO OUTFILE statement in mysql, be sure to use a\n--default-character-set option with mysqldump or mysql so that output\nis written in the character set to be used when the file is loaded with\nLOAD DATA INFILE.\n\nNote that it is currently not possible to load data files that use the\nucs2, utf16, or utf32 character set.\n\nAs of MySQL 5.1.6, the character_set_filesystem system variable\ncontrols the interpretation of the file name.\n\nYou can also load data files by using the mysqlimport utility; it\noperates by sending a LOAD DATA INFILE statement to the server. The\n--local option causes mysqlimport to read data files from the client\nhost. You can specify the --compress option to get better performance\nover slow networks if the client and server support the compressed\nprotocol. See http://dev.mysql.com/doc/refman/5.1/en/mysqlimport.html.\n\nIf you use LOW_PRIORITY, execution of the LOAD DATA statement is\ndelayed until no other clients are reading from the table. This affects\nonly storage engines that use only table-level locking (MyISAM, MEMORY,\nMERGE).\n\nIf you specify CONCURRENT with a MyISAM table that satisfies the\ncondition for concurrent inserts (that is, it contains no free blocks\nin the middle), other threads can retrieve data from the table while\nLOAD DATA is executing. Using this option affects the performance of\nLOAD DATA a bit, even if no other thread is using the table at the same\ntime.\n\nCONCURRENT is not replicated when using statement-based replication;\nhowever, it is replicated when using row-based replication. See\nhttp://dev.mysql.com/doc/refman/5.1/en/replication-features-load-data.h\ntml, for more information.\n\n*Note*: Prior to MySQL 5.1.23, LOAD DATA performed very poorly when\nimporting into partitioned tables. The statement now uses buffering to\nimprove performance; however, the buffer uses 130 KB memory per\npartition to achieve this. (Bug#26527 (http://bugs.mysql.com/26527))\n\nThe LOCAL keyword, if specified, is interpreted with respect to the\nclient end of the connection:\n\no If LOCAL is specified, the file is read by the client program on the\n client host and sent to the server. The file can be given as a full\n path name to specify its exact location. If given as a relative path\n name, the name is interpreted relative to the directory in which the\n client program was started.\n\no If LOCAL is not specified, the file must be located on the server\n host and is read directly by the server. The server uses the\n following rules to locate the file:\n\n o If the file name is an absolute path name, the server uses it as\n given.\n\n o If the file name is a relative path name with one or more leading\n components, the server searches for the file relative to the\n server\'s data directory.\n\n o If a file name with no leading components is given, the server\n looks for the file in the database directory of the default\n database.\n\nNote that, in the non-LOCAL case, these rules mean that a file named as\n./myfile.txt is read from the server\'s data directory, whereas the file\nnamed as myfile.txt is read from the database directory of the default\ndatabase. For example, if db1 is the default database, the following\nLOAD DATA statement reads the file data.txt from the database directory\nfor db1, even though the statement explicitly loads the file into a\ntable in the db2 database:\n\nLOAD DATA INFILE \'data.txt\' INTO TABLE db2.my_table;\n\nWindows path names are specified using forward slashes rather than\nbackslashes. If you do use backslashes, you must double them.\n\n*Note*: A regression in MySQL 5.1.40 caused the database referenced in\na fully qualified table name to be ignored by LOAD DATA when using\nreplication with either STATEMENT or MIXED as the binary logging\nformat; this could lead to problems if the table was not in the current\ndatabase. As a workaround, you can specify the correct database with\nthe USE statement prior to executing LOAD DATA. If necessary, you can\nreset the current database with a second USE statement following the\nLOAD DATA statement. This issue was fixed in MySQL 5.1.41. (Bug#48297\n(http://bugs.mysql.com/48297))\n\nFor security reasons, when reading text files located on the server,\nthe files must either reside in the database directory or be readable\nby all. Also, to use LOAD DATA INFILE on server files, you must have\nthe FILE privilege. See\nhttp://dev.mysql.com/doc/refman/5.1/en/privileges-provided.html. For\nnon-LOCAL load operations, if the secure_file_priv system variable is\nset to a nonempty directory name, the file to be loaded must be located\nin that directory.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/load-data.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/load-data.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (421,23,'MULTILINESTRING','MultiLineString(ls1,ls2,...)\n\nConstructs a MultiLineString value using LineString or WKB LineString\narguments.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/creating-spatial-values.html#gis-mysql-specific-functions\n\n','','http://dev.mysql.com/doc/refman/5.1/en/creating-spatial-values.html#gis-mysql-specific-functions');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (422,30,'LOCALTIME','Syntax:\nLOCALTIME, LOCALTIME()\n\nLOCALTIME and LOCALTIME() are synonyms for NOW().\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (423,3,'MPOINTFROMTEXT','MPointFromText(wkt[,srid]), MultiPointFromText(wkt[,srid])\n\nConstructs a MULTIPOINT value using its WKT representation and SRID.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/creating-spatial-values.html#gis-wkt-functions\n\n','','http://dev.mysql.com/doc/refman/5.1/en/creating-spatial-values.html#gis-wkt-functions');
@@ -497,7 +497,7 @@ insert into help_topic (help_topic_id,help_category_id,name,description,example,
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (428,20,'CHAR','[NATIONAL] CHAR[(M)] [CHARACTER SET charset_name] [COLLATE\ncollation_name]\n\nA fixed-length string that is always right-padded with spaces to the\nspecified length when stored. M represents the column length in\ncharacters. The range of M is 0 to 255. If M is omitted, the length is\n1.\n\n*Note*: Trailing spaces are removed when CHAR values are retrieved\nunless the PAD_CHAR_TO_FULL_LENGTH SQL mode is enabled.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/string-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/string-type-overview.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (429,30,'UTC_DATE','Syntax:\nUTC_DATE, UTC_DATE()\n\nReturns the current UTC date as a value in \'YYYY-MM-DD\' or YYYYMMDD\nformat, depending on whether the function is used in a string or\nnumeric context.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html\n\n','mysql> SELECT UTC_DATE(), UTC_DATE() + 0;\n -> \'2003-08-14\', 20030814\n','http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (430,34,'DIMENSION','Dimension(g)\n\nReturns the inherent dimension of the geometry value g. The result can\nbe -1, 0, 1, or 2. The meaning of these values is given in\nhttp://dev.mysql.com/doc/refman/5.1/en/gis-class-geometry.html.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/geometry-property-functions.html#general-geometry-property-functions\n\n','mysql> SELECT Dimension(GeomFromText(\'LineString(1 1,2 2)\'));\n+------------------------------------------------+\n| Dimension(GeomFromText(\'LineString(1 1,2 2)\')) |\n+------------------------------------------------+\n| 1 |\n+------------------------------------------------+\n','http://dev.mysql.com/doc/refman/5.1/en/geometry-property-functions.html#general-geometry-property-functions');
-insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (431,16,'COUNT DISTINCT','Syntax:\nCOUNT(DISTINCT expr,[expr...])\n\nReturns a count of the number of different non-NULL values.\n\nCOUNT(DISTINCT) returns 0 if there were no matching rows.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html\n\n','mysql> SELECT COUNT(DISTINCT results) FROM student;\n','http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html');
+insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (431,16,'COUNT DISTINCT','Syntax:\nCOUNT(DISTINCT expr,[expr...])\n\nReturns a count of the number of rows with different non-NULL expr\nvalues.\n\nCOUNT(DISTINCT) returns 0 if there were no matching rows.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html\n\n','mysql> SELECT COUNT(DISTINCT results) FROM student;\n','http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (432,20,'BIT','BIT[(M)]\n\nA bit-field type. M indicates the number of bits per value, from 1 to\n64. The default is 1 if M is omitted.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/numeric-type-overview.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/numeric-type-overview.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (433,29,'EQUALS','Equals(g1,g2)\n\nReturns 1 or 0 to indicate whether g1 is spatially equal to g2.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/functions-that-test-spatial-relationships-between-geometries.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/functions-that-test-spatial-relationships-between-geometries.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (434,25,'SHOW CREATE VIEW','Syntax:\nSHOW CREATE VIEW view_name\n\nThis statement shows a CREATE VIEW statement that creates the given\nview.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/show-create-view.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/show-create-view.html');
@@ -532,7 +532,7 @@ insert into help_topic (help_topic_id,help_category_id,name,description,example,
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (463,37,'MERGE','The MERGE storage engine, also known as the MRG_MyISAM engine, is a\ncollection of identical MyISAM tables that can be used as one.\n"Identical" means that all tables have identical column and index\ninformation. You cannot merge MyISAM tables in which the columns are\nlisted in a different order, do not have exactly the same columns, or\nhave the indexes in different order. However, any or all of the MyISAM\ntables can be compressed with myisampack. See\nhttp://dev.mysql.com/doc/refman/5.1/en/myisampack.html. Differences in\ntable options such as AVG_ROW_LENGTH, MAX_ROWS, or PACK_KEYS do not\nmatter.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/merge-storage-engine.html\n\n','mysql> CREATE TABLE t1 (\n -> a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,\n -> message CHAR(20)) ENGINE=MyISAM;\nmysql> CREATE TABLE t2 (\n -> a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,\n -> message CHAR(20)) ENGINE=MyISAM;\nmysql> INSERT INTO t1 (message) VALUES (\'Testing\'),(\'table\'),(\'t1\');\nmysql> INSERT INTO t2 (message) VALUES (\'Testing\'),(\'table\'),(\'t2\');\nmysql> CREATE TABLE total (\n -> a INT NOT NULL AUTO_INCREMENT,\n -> message CHAR(20), INDEX(a))\n -> ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;\n','http://dev.mysql.com/doc/refman/5.1/en/merge-storage-engine.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (464,37,'CREATE TABLE','Syntax:\nCREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name\n (create_definition,...)\n [table_options]\n [partition_options]\n\nOr:\n\nCREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name\n [(create_definition,...)]\n [table_options]\n [partition_options]\n select_statement\n\nOr:\n\nCREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name\n { LIKE old_tbl_name | (LIKE old_tbl_name) }\n\ncreate_definition:\n col_name column_definition\n | [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...)\n [index_option] ...\n | {INDEX|KEY} [index_name] [index_type] (index_col_name,...)\n [index_option] ...\n | [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY]\n [index_name] [index_type] (index_col_name,...)\n [index_option] ...\n | {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (index_col_name,...)\n [index_option] ...\n | [CONSTRAINT [symbol]] FOREIGN KEY\n [index_name] (index_col_name,...) reference_definition\n | CHECK (expr)\n\ncolumn_definition:\n data_type [NOT NULL | NULL] [DEFAULT default_value]\n [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY]\n [COMMENT \'string\']\n [COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}]\n [STORAGE {DISK|MEMORY|DEFAULT}]\n [reference_definition]\n\ndata_type:\n BIT[(length)]\n | TINYINT[(length)] [UNSIGNED] [ZEROFILL]\n | SMALLINT[(length)] [UNSIGNED] [ZEROFILL]\n | MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]\n | INT[(length)] [UNSIGNED] [ZEROFILL]\n | INTEGER[(length)] [UNSIGNED] [ZEROFILL]\n | BIGINT[(length)] [UNSIGNED] [ZEROFILL]\n | REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]\n | DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]\n | FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]\n | DECIMAL[(length[,decimals])] [UNSIGNED] [ZEROFILL]\n | NUMERIC[(length[,decimals])] [UNSIGNED] [ZEROFILL]\n | DATE\n | TIME\n | TIMESTAMP\n | DATETIME\n | YEAR\n | CHAR[(length)]\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | VARCHAR(length)\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | BINARY[(length)]\n | VARBINARY(length)\n | TINYBLOB\n | BLOB\n | MEDIUMBLOB\n | LONGBLOB\n | TINYTEXT [BINARY]\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | TEXT [BINARY]\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | MEDIUMTEXT [BINARY]\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | LONGTEXT [BINARY]\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | ENUM(value1,value2,value3,...)\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | SET(value1,value2,value3,...)\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | spatial_type\n\nindex_col_name:\n col_name [(length)] [ASC | DESC]\n\nindex_type:\n USING {BTREE | HASH | RTREE}\n\nindex_option:\n KEY_BLOCK_SIZE [=] value\n | index_type\n | WITH PARSER parser_name\n\nreference_definition:\n REFERENCES tbl_name (index_col_name,...)\n [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]\n [ON DELETE reference_option]\n [ON UPDATE reference_option]\n\nreference_option:\n RESTRICT | CASCADE | SET NULL | NO ACTION\n\ntable_options:\n table_option [[,] table_option] ...\n\ntable_option:\n ENGINE [=] engine_name\n | AUTO_INCREMENT [=] value\n | AVG_ROW_LENGTH [=] value\n | [DEFAULT] CHARACTER SET [=] charset_name\n | CHECKSUM [=] {0 | 1}\n | [DEFAULT] COLLATE [=] collation_name\n | COMMENT [=] \'string\'\n | CONNECTION [=] \'connect_string\'\n | DATA DIRECTORY [=] \'absolute path to directory\'\n | DELAY_KEY_WRITE [=] {0 | 1}\n | INDEX DIRECTORY [=] \'absolute path to directory\'\n | INSERT_METHOD [=] { NO | FIRST | LAST }\n | KEY_BLOCK_SIZE [=] value\n | MAX_ROWS [=] value\n | MIN_ROWS [=] value\n | PACK_KEYS [=] {0 | 1 | DEFAULT}\n | PASSWORD [=] \'string\'\n | ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}\n | TABLESPACE tablespace_name [STORAGE {DISK|MEMORY|DEFAULT}]\n | UNION [=] (tbl_name[,tbl_name]...)\n\npartition_options:\n PARTITION BY\n { [LINEAR] HASH(expr)\n | [LINEAR] KEY(column_list)\n | RANGE(expr)\n | LIST(expr) }\n [PARTITIONS num]\n [SUBPARTITION BY\n { [LINEAR] HASH(expr)\n | [LINEAR] KEY(column_list) }\n [SUBPARTITIONS num]\n ]\n [(partition_definition [, partition_definition] ...)]\n\npartition_definition:\n PARTITION partition_name\n [VALUES {LESS THAN {(expr) | MAXVALUE} | IN (value_list)}]\n [[STORAGE] ENGINE [=] engine_name]\n [COMMENT [=] \'comment_text\' ]\n [DATA DIRECTORY [=] \'data_dir\']\n [INDEX DIRECTORY [=] \'index_dir\']\n [MAX_ROWS [=] max_number_of_rows]\n [MIN_ROWS [=] min_number_of_rows]\n [TABLESPACE [=] tablespace_name]\n [NODEGROUP [=] node_group_id]\n [(subpartition_definition [, subpartition_definition] ...)]\n\nsubpartition_definition:\n SUBPARTITION logical_name\n [[STORAGE] ENGINE [=] engine_name]\n [COMMENT [=] \'comment_text\' ]\n [DATA DIRECTORY [=] \'data_dir\']\n [INDEX DIRECTORY [=] \'index_dir\']\n [MAX_ROWS [=] max_number_of_rows]\n [MIN_ROWS [=] min_number_of_rows]\n [TABLESPACE [=] tablespace_name]\n [NODEGROUP [=] node_group_id]\n\nselect_statement:\n [IGNORE | REPLACE] [AS] SELECT ... (Some legal select statement)\n\nCREATE TABLE creates a table with the given name. You must have the\nCREATE privilege for the table.\n\nRules for allowable table names are given in\nhttp://dev.mysql.com/doc/refman/5.1/en/identifiers.html. By default,\nthe table is created in the default database. An error occurs if the\ntable exists, if there is no default database, or if the database does\nnot exist.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/create-table.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/create-table.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (465,17,'>','Syntax:\n>\n\nGreater than:\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html\n\n','mysql> SELECT 2 > 2;\n -> 0\n','http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html');
-insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (466,19,'ANALYZE TABLE','Syntax:\nANALYZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE\n tbl_name [, tbl_name] ...\n\nANALYZE TABLE analyzes and stores the key distribution for a table.\nDuring the analysis, the table is locked with a read lock for MyISAM.\nFor InnoDB the table is locked with a write lock. This statement works\nwith MyISAM, and InnoDB tables. For MyISAM tables, this statement is\nequivalent to using myisamchk --analyze.\n\nFor more information on how the analysis works within InnoDB, see\nhttp://dev.mysql.com/doc/refman/5.1/en/innodb-restrictions.html.\n\nMySQL uses the stored key distribution to decide the order in which\ntables should be joined when you perform a join on something other than\na constant. In addition, key distributions can be used when deciding\nwhich indexes to use for a specific table within a query.\n\nThis statement requires SELECT and INSERT privileges for the table.\n\nBeginning with MySQL 5.1.27, ANALYZE TABLE is also supported for\npartitioned tables. Also beginning with MySQL 5.1.27, you can use ALTER\nTABLE ... ANALYZE PARTITION to analyze one or more partitions; for more\ninformation, see [HELP ALTER TABLE], and\nhttp://dev.mysql.com/doc/refman/5.1/en/partitioning-maintenance.html.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/analyze-table.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/analyze-table.html');
+insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (466,19,'ANALYZE TABLE','Syntax:\nANALYZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE\n tbl_name [, tbl_name] ...\n\nANALYZE TABLE analyzes and stores the key distribution for a table.\nDuring the analysis, the table is locked with a read lock for MyISAM.\nFor InnoDB the table is locked with a write lock. This statement works\nwith MyISAM and InnoDB tables. For MyISAM tables, this statement is\nequivalent to using myisamchk --analyze.\n\nFor more information on how the analysis works within InnoDB, see\nhttp://dev.mysql.com/doc/refman/5.1/en/innodb-restrictions.html.\n\nMySQL uses the stored key distribution to decide the order in which\ntables should be joined when you perform a join on something other than\na constant. In addition, key distributions can be used when deciding\nwhich indexes to use for a specific table within a query.\n\nThis statement requires SELECT and INSERT privileges for the table.\n\nBeginning with MySQL 5.1.27, ANALYZE TABLE is also supported for\npartitioned tables. Also beginning with MySQL 5.1.27, you can use ALTER\nTABLE ... ANALYZE PARTITION to analyze one or more partitions; for more\ninformation, see [HELP ALTER TABLE], and\nhttp://dev.mysql.com/doc/refman/5.1/en/partitioning-maintenance.html.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/analyze-table.html\n\n','','http://dev.mysql.com/doc/refman/5.1/en/analyze-table.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (467,30,'MICROSECOND','Syntax:\nMICROSECOND(expr)\n\nReturns the microseconds from the time or datetime expression expr as a\nnumber in the range from 0 to 999999.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html\n\n','mysql> SELECT MICROSECOND(\'12:00:00.123456\');\n -> 123456\nmysql> SELECT MICROSECOND(\'2009-12-31 23:59:59.000010\');\n -> 10\n','http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (468,37,'CONSTRAINT','InnoDB supports foreign key constraints. The syntax for a foreign key\nconstraint definition in InnoDB looks like this:\n\n[CONSTRAINT [symbol]] FOREIGN KEY\n [index_name] (index_col_name, ...)\n REFERENCES tbl_name (index_col_name,...)\n [ON DELETE reference_option]\n [ON UPDATE reference_option]\n\nreference_option:\n RESTRICT | CASCADE | SET NULL | NO ACTION\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html\n\n','CREATE TABLE product (category INT NOT NULL, id INT NOT NULL,\n price DECIMAL,\n PRIMARY KEY(category, id)) ENGINE=INNODB;\nCREATE TABLE customer (id INT NOT NULL,\n PRIMARY KEY (id)) ENGINE=INNODB;\nCREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT,\n product_category INT NOT NULL,\n product_id INT NOT NULL,\n customer_id INT NOT NULL,\n PRIMARY KEY(no),\n INDEX (product_category, product_id),\n FOREIGN KEY (product_category, product_id)\n REFERENCES product(category, id)\n ON UPDATE CASCADE ON DELETE RESTRICT,\n INDEX (customer_id),\n FOREIGN KEY (customer_id)\n REFERENCES customer(id)) ENGINE=INNODB;\n','http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (469,37,'CREATE SERVER','Syntax:\nCREATE SERVER server_name\n FOREIGN DATA WRAPPER wrapper_name\n OPTIONS (option [, option] ...)\n\noption:\n { HOST character-literal\n | DATABASE character-literal\n | USER character-literal\n | PASSWORD character-literal\n | SOCKET character-literal\n | OWNER character-literal\n | PORT numeric-literal }\n\nThis statement creates the definition of a server for use with the\nFEDERATED storage engine. The CREATE SERVER statement creates a new row\nwithin the servers table within the mysql database. This statement\nrequires the SUPER privilege.\n\nThe server_name should be a unique reference to the server. Server\ndefinitions are global within the scope of the server, it is not\npossible to qualify the server definition to a specific database.\nserver_name has a maximum length of 64 characters (names longer than 64\ncharacters are silently truncated), and is case insensitive. You may\nspecify the name as a quoted string.\n\nThe wrapper_name should be mysql, and may be quoted with single quotes.\nOther values for wrapper_name are not currently supported.\n\nFor each option you must specify either a character literal or numeric\nliteral. Character literals are UTF-8, support a maximum length of 64\ncharacters and default to a blank (empty) string. String literals are\nsilently truncated to 64 characters. Numeric literals must be a number\nbetween 0 and 9999, default value is 0.\n\n*Note*: Note that the OWNER option is currently not applied, and has no\neffect on the ownership or operation of the server connection that is\ncreated.\n\nThe CREATE SERVER statement creates an entry in the mysql.server table\nthat can later be used with the CREATE TABLE statement when creating a\nFEDERATED table. The options that you specify will be used to populate\nthe columns in the mysql.server table. The table columns are\nServer_name, Host, Db, Username, Password, Port and Socket.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/create-server.html\n\n','CREATE SERVER s\nFOREIGN DATA WRAPPER mysql\nOPTIONS (USER \'Remote\', HOST \'192.168.1.106\', DATABASE \'test\');\n','http://dev.mysql.com/doc/refman/5.1/en/create-server.html');
@@ -567,7 +567,7 @@ insert into help_topic (help_topic_id,help_category_id,name,description,example,
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (498,4,'RADIANS','Syntax:\nRADIANS(X)\n\nReturns the argument X, converted from degrees to radians. (Note that\nπ radians equals 180 degrees.)\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/mathematical-functions.html\n\n','mysql> SELECT RADIANS(90);\n -> 1.5707963267949\n','http://dev.mysql.com/doc/refman/5.1/en/mathematical-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (499,15,'COLLATION','Syntax:\nCOLLATION(str)\n\nReturns the collation of the string argument.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/information-functions.html\n\n','mysql> SELECT COLLATION(\'abc\');\n -> \'latin1_swedish_ci\'\nmysql> SELECT COLLATION(_utf8\'abc\');\n -> \'utf8_general_ci\'\n','http://dev.mysql.com/doc/refman/5.1/en/information-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (500,17,'COALESCE','Syntax:\nCOALESCE(value,...)\n\nReturns the first non-NULL value in the list, or NULL if there are no\nnon-NULL values.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html\n\n','mysql> SELECT COALESCE(NULL,1);\n -> 1\nmysql> SELECT COALESCE(NULL,NULL,NULL);\n -> NULL\n','http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html');
-insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (501,15,'VERSION','Syntax:\nVERSION()\n\nReturns a string that indicates the MySQL server version. The string\nuses the utf8 character set.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/information-functions.html\n\n','mysql> SELECT VERSION();\n -> \'5.1.39-standard\'\n','http://dev.mysql.com/doc/refman/5.1/en/information-functions.html');
+insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (501,15,'VERSION','Syntax:\nVERSION()\n\nReturns a string that indicates the MySQL server version. The string\nuses the utf8 character set.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/information-functions.html\n\n','mysql> SELECT VERSION();\n -> \'5.1.41-standard\'\n','http://dev.mysql.com/doc/refman/5.1/en/information-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (502,35,'MAKE_SET','Syntax:\nMAKE_SET(bits,str1,str2,...)\n\nReturns a set value (a string containing substrings separated by ","\ncharacters) consisting of the strings that have the corresponding bit\nin bits set. str1 corresponds to bit 0, str2 to bit 1, and so on. NULL\nvalues in str1, str2, ... are not appended to the result.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/string-functions.html\n\n','mysql> SELECT MAKE_SET(1,\'a\',\'b\',\'c\');\n -> \'a\'\nmysql> SELECT MAKE_SET(1 | 4,\'hello\',\'nice\',\'world\');\n -> \'hello,world\'\nmysql> SELECT MAKE_SET(1 | 4,\'hello\',\'nice\',NULL,\'world\');\n -> \'hello\'\nmysql> SELECT MAKE_SET(0,\'a\',\'b\',\'c\');\n -> \'\'\n','http://dev.mysql.com/doc/refman/5.1/en/string-functions.html');
insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (503,35,'FIND_IN_SET','Syntax:\nFIND_IN_SET(str,strlist)\n\nReturns a value in the range of 1 to N if the string str is in the\nstring list strlist consisting of N substrings. A string list is a\nstring composed of substrings separated by "," characters. If the first\nargument is a constant string and the second is a column of type SET,\nthe FIND_IN_SET() function is optimized to use bit arithmetic. Returns\n0 if str is not in strlist or if strlist is the empty string. Returns\nNULL if either argument is NULL. This function does not work properly\nif the first argument contains a comma (",") character.\n\nURL: http://dev.mysql.com/doc/refman/5.1/en/string-functions.html\n\n','mysql> SELECT FIND_IN_SET(\'b\',\'a,b,c,d\');\n -> 2\n','http://dev.mysql.com/doc/refman/5.1/en/string-functions.html');
@@ -1293,6 +1293,7 @@ insert into help_relation (help_topic_id,help_keyword_id) values (81,115);
insert into help_relation (help_topic_id,help_keyword_id) values (143,115);
insert into help_relation (help_topic_id,help_keyword_id) values (468,115);
insert into help_relation (help_topic_id,help_keyword_id) values (180,115);
+insert into help_relation (help_topic_id,help_keyword_id) values (353,115);
insert into help_relation (help_topic_id,help_keyword_id) values (420,115);
insert into help_relation (help_topic_id,help_keyword_id) values (473,115);
insert into help_relation (help_topic_id,help_keyword_id) values (197,116);
@@ -1550,11 +1551,12 @@ insert into help_relation (help_topic_id,help_keyword_id) values (184,237);
insert into help_relation (help_topic_id,help_keyword_id) values (383,238);
insert into help_relation (help_topic_id,help_keyword_id) values (330,239);
insert into help_relation (help_topic_id,help_keyword_id) values (344,239);
-insert into help_relation (help_topic_id,help_keyword_id) values (253,239);
insert into help_relation (help_topic_id,help_keyword_id) values (152,239);
insert into help_relation (help_topic_id,help_keyword_id) values (428,239);
insert into help_relation (help_topic_id,help_keyword_id) values (464,239);
+insert into help_relation (help_topic_id,help_keyword_id) values (253,239);
insert into help_relation (help_topic_id,help_keyword_id) values (209,239);
+insert into help_relation (help_topic_id,help_keyword_id) values (353,239);
insert into help_relation (help_topic_id,help_keyword_id) values (420,239);
insert into help_relation (help_topic_id,help_keyword_id) values (184,240);
insert into help_relation (help_topic_id,help_keyword_id) values (273,241);
diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist
index 0380d7f8c32..11f627b4276 100755
--- a/scripts/make_win_bin_dist
+++ b/scripts/make_win_bin_dist
@@ -350,6 +350,7 @@ fi
mkdir $DESTDIR/mysql-test
cp mysql-test/mysql-test-run.pl $DESTDIR/mysql-test/
+cp mysql-test/mysql-stress-test.pl $DESTDIR/mysql-test/
cp mysql-test/README $DESTDIR/mysql-test/
cp -R mysql-test/{t,r,include,suite,std_data,lib} $DESTDIR/mysql-test/
diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql
index 67e18517915..923497b0ab2 100644
--- a/scripts/mysql_system_tables.sql
+++ b/scripts/mysql_system_tables.sql
@@ -62,7 +62,7 @@ CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint sign
CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
-CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
+CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
-- Create general_log if CSV is enabled.
diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql
index a6497f57f0a..1844860c84d 100644
--- a/scripts/mysql_system_tables_fix.sql
+++ b/scripts/mysql_system_tables_fix.sql
@@ -337,6 +337,10 @@ ALTER TABLE procs_priv
MODIFY Proc_priv set('Execute','Alter Routine','Grant')
COLLATE utf8_general_ci DEFAULT '' NOT NULL;
+ALTER IGNORE TABLE procs_priv
+ MODIFY Routine_name char(64)
+ COLLATE utf8_general_ci DEFAULT '' NOT NULL;
+
ALTER TABLE procs_priv
ADD Routine_type enum('FUNCTION','PROCEDURE')
COLLATE utf8_general_ci NOT NULL AFTER Routine_name;
diff --git a/sql-common/client.c b/sql-common/client.c
index c290525a1c0..9a8444a84e9 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -389,7 +389,7 @@ HANDLE create_named_pipe(MYSQL *mysql, uint connect_timeout, char **arg_host,
0,
NULL,
OPEN_EXISTING,
- 0,
+ FILE_FLAG_OVERLAPPED,
NULL )) != INVALID_HANDLE_VALUE)
break;
if (GetLastError() != ERROR_PIPE_BUSY)
@@ -623,7 +623,7 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
err2:
if (error_allow == 0)
{
- net->vio= vio_new_win32shared_memory(net,handle_file_map,handle_map,
+ net->vio= vio_new_win32shared_memory(handle_file_map,handle_map,
event_server_wrote,
event_server_read,event_client_wrote,
event_client_read,event_conn_closed);
@@ -2033,7 +2033,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
}
else
{
- net->vio=vio_new_win32pipe(hPipe);
+ net->vio= vio_new_win32pipe(hPipe);
my_snprintf(host_info=buff, sizeof(buff)-1,
ER(CR_NAMEDPIPE_CONNECTION), unix_socket);
}
diff --git a/sql-common/my_time.c b/sql-common/my_time.c
index 2ec1fc253a7..95078a50097 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -165,7 +165,7 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
uint add_hours= 0, start_loop;
ulong not_zero_date, allow_space;
my_bool is_internal_format;
- const char *pos, *last_field_pos;
+ const char *pos, *UNINIT_VAR(last_field_pos);
const char *end=str+length;
const uchar *format_position;
my_bool found_delimitier= 0, found_space= 0;
@@ -174,7 +174,6 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
DBUG_PRINT("ENTER",("str: %.*s",length,str));
LINT_INIT(field_length);
- LINT_INIT(last_field_pos);
*was_cut= 0;
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 58ba26782f9..e50da7b88d3 100755
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -65,6 +65,7 @@ SET (SQL_SOURCE
sql_error.cc sql_handler.cc sql_help.cc sql_insert.cc sql_lex.cc
sql_list.cc sql_load.cc sql_manager.cc sql_map.cc sql_parse.cc
sql_partition.cc sql_plugin.cc sql_prepare.cc sql_rename.cc
+ debug_sync.cc debug_sync.h
sql_repl.cc sql_select.cc sql_show.cc sql_state.c sql_string.cc
sql_table.cc sql_test.cc sql_trigger.cc sql_udf.cc sql_union.cc
sql_update.cc sql_view.cc strfunc.cc table.cc thr_malloc.cc
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 00342f7034e..af34e961480 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -59,6 +59,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
ha_ndbcluster.h ha_ndbcluster_cond.h \
ha_ndbcluster_binlog.h ha_ndbcluster_tables.h \
ha_partition.h rpl_constants.h \
+ debug_sync.h \
opt_range.h protocol.h rpl_tblmap.h rpl_utility.h \
rpl_reporting.h \
log.h log_slow.h sql_show.h rpl_rli.h rpl_mi.h \
@@ -103,6 +104,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
discover.cc time.cc opt_range.cc opt_sum.cc \
records.cc filesort.cc handler.cc \
ha_partition.cc \
+ debug_sync.cc \
sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc \
sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \
sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \
diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc
new file mode 100644
index 00000000000..2580d526b52
--- /dev/null
+++ b/sql/debug_sync.cc
@@ -0,0 +1,1906 @@
+/* Copyright (C) 2008 MySQL AB, 2008 - 2009 Sun Microsystems, Inc.
+
+ 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 */
+
+/**
+ == Debug Sync Facility ==
+
+ The Debug Sync Facility allows placement of synchronization points in
+ the server code by using the DEBUG_SYNC macro:
+
+ open_tables(...)
+
+ DEBUG_SYNC(thd, "after_open_tables");
+
+ lock_tables(...)
+
+ When activated, a sync point can
+
+ - Emit a signal and/or
+ - Wait for a signal
+
+ Nomenclature:
+
+ - signal: A value of a global variable that persists
+ until overwritten by a new signal. The global
+ variable can also be seen as a "signal post"
+ or "flag mast". Then the signal is what is
+ attached to the "signal post" or "flag mast".
+
+ - emit a signal: Assign the value (the signal) to the global
+ variable ("set a flag") and broadcast a
+ global condition to wake those waiting for
+ a signal.
+
+ - wait for a signal: Loop over waiting for the global condition until
+ the global value matches the wait-for signal.
+
+ By default, all sync points are inactive. They do nothing (except to
+ burn a couple of CPU cycles for checking if they are active).
+
+ A sync point becomes active when an action is requested for it.
+ To do so, put a line like this in the test case file:
+
+ SET DEBUG_SYNC= 'after_open_tables SIGNAL opened WAIT_FOR flushed';
+
+ This activates the sync point 'after_open_tables'. It requests it to
+ emit the signal 'opened' and wait for another thread to emit the signal
+ 'flushed' when the thread's execution runs through the sync point.
+
+ For every sync point there can be one action per thread only. Every
+ thread can request multiple actions, but only one per sync point. In
+ other words, a thread can activate multiple sync points.
+
+ Here is an example how to activate and use the sync points:
+
+ --connection conn1
+ SET DEBUG_SYNC= 'after_open_tables SIGNAL opened WAIT_FOR flushed';
+ send INSERT INTO t1 VALUES(1);
+ --connection conn2
+ SET DEBUG_SYNC= 'now WAIT_FOR opened';
+ SET DEBUG_SYNC= 'after_abort_locks SIGNAL flushed';
+ FLUSH TABLE t1;
+
+ When conn1 runs through the INSERT statement, it hits the sync point
+ 'after_open_tables'. It notices that it is active and executes its
+ action. It emits the signal 'opened' and waits for another thread to
+ emit the signal 'flushed'.
+
+ conn2 waits immediately at the special sync point 'now' for another
+ thread to emit the 'opened' signal.
+
+ A signal remains in effect until it is overwritten. If conn1 signals
+ 'opened' before conn2 reaches 'now', conn2 will still find the 'opened'
+ signal. It does not wait in this case.
+
+ When conn2 reaches 'after_abort_locks', it signals 'flushed', which lets
+ conn1 awake.
+
+ Normally the activation of a sync point is cleared when it has been
+ executed. Sometimes it is necessary to keep the sync point active for
+ another execution. You can add an execute count to the action:
+
+ SET DEBUG_SYNC= 'name SIGNAL sig EXECUTE 3';
+
+ This sets the signal point's activation counter to 3. Each execution
+ decrements the counter. After the third execution the sync point
+ becomes inactive.
+
+ One of the primary goals of this facility is to eliminate sleeps from
+ the test suite. In most cases it should be possible to rewrite test
+ cases so that they do not need to sleep. (But this facility cannot
+ synchronize multiple processes.) However, to support test development,
+ and as a last resort, sync point waiting times out. There is a default
+ timeout, but it can be overridden:
+
+ SET DEBUG_SYNC= 'name WAIT_FOR sig TIMEOUT 10 EXECUTE 2';
+
+ TIMEOUT 0 is special: If the signal is not present, the wait times out
+ immediately.
+
+ When a wait timed out (even on TIMEOUT 0), a warning is generated so
+ that it shows up in the test result.
+
+ You can throw an error message and kill the query when a synchronization
+ point is hit a certain number of times:
+
+ SET DEBUG_SYNC= 'name HIT_LIMIT 3';
+
+ Or combine it with signal and/or wait:
+
+ SET DEBUG_SYNC= 'name SIGNAL sig EXECUTE 2 HIT_LIMIT 3';
+
+ Here the first two hits emit the signal, the third hit returns the error
+ message and kills the query.
+
+ For cases where you are not sure that an action is taken and thus
+ cleared in any case, you can force to clear (deactivate) a sync point:
+
+ SET DEBUG_SYNC= 'name CLEAR';
+
+ If you want to clear all actions and clear the global signal, use:
+
+ SET DEBUG_SYNC= 'RESET';
+
+ This is the only way to reset the global signal to an empty string.
+
+ For testing of the facility itself you can execute a sync point just
+ as if it had been hit:
+
+ SET DEBUG_SYNC= 'name TEST';
+
+
+ === Formal Syntax ===
+
+ The string to "assign" to the DEBUG_SYNC variable can contain:
+
+ {RESET |
+ <sync point name> TEST |
+ <sync point name> CLEAR |
+ <sync point name> {{SIGNAL <signal name> |
+ WAIT_FOR <signal name> [TIMEOUT <seconds>]}
+ [EXECUTE <count>] &| HIT_LIMIT <count>}
+
+ Here '&|' means 'and/or'. This means that one of the sections
+ separated by '&|' must be present or both of them.
+
+
+ === Activation/Deactivation ===
+
+ The facility is an optional part of the MySQL server.
+ It is enabled in a debug server by default.
+
+ ./configure --enable-debug-sync
+
+ The Debug Sync Facility, when compiled in, is disabled by default. It
+ can be enabled by a mysqld command line option:
+
+ --debug-sync-timeout[=default_wait_timeout_value_in_seconds]
+
+ 'default_wait_timeout_value_in_seconds' is the default timeout for the
+ WAIT_FOR action. If set to zero, the facility stays disabled.
+
+ The facility is enabled by default in the test suite, but can be
+ disabled with:
+
+ mysql-test-run.pl ... --debug-sync-timeout=0 ...
+
+ Likewise the default wait timeout can be set:
+
+ mysql-test-run.pl ... --debug-sync-timeout=10 ...
+
+ The command line option influences the readable value of the system
+ variable 'debug_sync'.
+
+ * If the facility is not compiled in, the system variable does not exist.
+
+ * If --debug-sync-timeout=0 the value of the variable reads as "OFF".
+
+ * Otherwise the value reads as "ON - current signal: " followed by the
+ current signal string, which can be empty.
+
+ The readable variable value is the same, regardless if read as global
+ or session value.
+
+ Setting the 'debug-sync' system variable requires 'SUPER' privilege.
+ You can never read back the string that you assigned to the variable,
+ unless you assign the value that the variable does already have. But
+ that would give a parse error. A syntactically correct string is
+ parsed into a debug sync action and stored apart from the variable value.
+
+
+ === Implementation ===
+
+ Pseudo code for a sync point:
+
+ #define DEBUG_SYNC(thd, sync_point_name)
+ if (unlikely(opt_debug_sync_timeout))
+ debug_sync(thd, STRING_WITH_LEN(sync_point_name))
+
+ The sync point performs a binary search in a sorted array of actions
+ for this thread.
+
+ The SET DEBUG_SYNC statement adds a requested action to the array or
+ overwrites an existing action for the same sync point. When it adds a
+ new action, the array is sorted again.
+
+
+ === A typical synchronization pattern ===
+
+ There are quite a few places in MySQL, where we use a synchronization
+ pattern like this:
+
+ pthread_mutex_lock(&mutex);
+ thd->enter_cond(&condition_variable, &mutex, new_message);
+ #if defined(ENABLE_DEBUG_SYNC)
+ if (!thd->killed && !end_of_wait_condition)
+ DEBUG_SYNC(thd, "sync_point_name");
+ #endif
+ while (!thd->killed && !end_of_wait_condition)
+ pthread_cond_wait(&condition_variable, &mutex);
+ thd->exit_cond(old_message);
+
+ Here some explanations:
+
+ thd->enter_cond() is used to register the condition variable and the
+ mutex in thd->mysys_var. This is done to allow the thread to be
+ interrupted (killed) from its sleep. Another thread can find the
+ condition variable to signal and mutex to use for synchronization in
+ this thread's THD::mysys_var.
+
+ thd->enter_cond() requires the mutex to be acquired in advance.
+
+ thd->exit_cond() unregisters the condition variable and mutex and
+ releases the mutex.
+
+ If you want to have a Debug Sync point with the wait, please place it
+ behind enter_cond(). Only then you can safely decide, if the wait will
+ be taken. Also you will have THD::proc_info correct when the sync
+ point emits a signal. DEBUG_SYNC sets its own proc_info, but restores
+ the previous one before releasing its internal mutex. As soon as
+ another thread sees the signal, it does also see the proc_info from
+ before entering the sync point. In this case it will be "new_message",
+ which is associated with the wait that is to be synchronized.
+
+ In the example above, the wait condition is repeated before the sync
+ point. This is done to skip the sync point, if no wait takes place.
+ The sync point is before the loop (not inside the loop) to have it hit
+ once only. It is possible that the condition variable is signaled
+ multiple times without the wait condition to be true.
+
+ A bit off-topic: At some places, the loop is taken around the whole
+ synchronization pattern:
+
+ while (!thd->killed && !end_of_wait_condition)
+ {
+ pthread_mutex_lock(&mutex);
+ thd->enter_cond(&condition_variable, &mutex, new_message);
+ if (!thd->killed [&& !end_of_wait_condition])
+ {
+ [DEBUG_SYNC(thd, "sync_point_name");]
+ pthread_cond_wait(&condition_variable, &mutex);
+ }
+ thd->exit_cond(old_message);
+ }
+
+ Note that it is important to repeat the test for thd->killed after
+ enter_cond(). Otherwise the killing thread may kill this thread after
+ it tested thd->killed in the loop condition and before it registered
+ the condition variable and mutex in enter_cond(). In this case, the
+ killing thread does not know that this thread is going to wait on a
+ condition variable. It would just set THD::killed. But if we would not
+ test it again, we would go asleep though we are killed. If the killing
+ thread would kill us when we are after the second test, but still
+ before sleeping, we hold the mutex, which is registered in mysys_var.
+ The killing thread would try to acquire the mutex before signaling
+ the condition variable. Since the mutex is only released implicitly in
+ pthread_cond_wait(), the signaling happens at the right place. We
+ have a safe synchronization.
+
+ === Co-work with the DBUG facility ===
+
+ When running the MySQL test suite with the --debug command line
+ option, the Debug Sync Facility writes trace messages to the DBUG
+ trace. The following shell commands proved very useful in extracting
+ relevant information:
+
+ egrep 'query:|debug_sync_exec:' mysql-test/var/log/mysqld.1.trace
+
+ It shows all executed SQL statements and all actions executed by
+ synchronization points.
+
+ Sometimes it is also useful to see, which synchronization points have
+ been run through (hit) with or without executing actions. Then add
+ "|debug_sync_point:" to the egrep pattern.
+
+ === Further reading ===
+
+ For a discussion of other methods to synchronize threads see
+ http://forge.mysql.com/wiki/MySQL_Internals_Test_Synchronization
+
+ For complete syntax tests, functional tests, and examples see the test
+ case debug_sync.test.
+
+ See also worklog entry WL#4259 - Test Synchronization Facility
+*/
+
+#include "debug_sync.h"
+
+#if defined(ENABLED_DEBUG_SYNC)
+
+/*
+ Due to weaknesses in our include files, we need to include
+ mysql_priv.h here. To have THD declared, we need to include
+ sql_class.h. This includes log_event.h, which in turn requires
+ declarations from mysql_priv.h (e.g. OPTION_AUTO_IS_NULL).
+ mysql_priv.h includes almost everything, so is sufficient here.
+*/
+#include "mysql_priv.h"
+
+/*
+ Action to perform at a synchronization point.
+ NOTE: This structure is moved around in memory by realloc(), qsort(),
+ and memmove(). Do not add objects with non-trivial constuctors
+ or destructors, which might prevent moving of this structure
+ with these functions.
+*/
+struct st_debug_sync_action
+{
+ ulong activation_count; /* max(hit_limit, execute) */
+ ulong hit_limit; /* hits before kill query */
+ ulong execute; /* executes before self-clear */
+ ulong timeout; /* wait_for timeout */
+ String signal; /* signal to emit */
+ String wait_for; /* signal to wait for */
+ String sync_point; /* sync point name */
+ bool need_sort; /* if new action, array needs sort */
+};
+
+/* Debug sync control. Referenced by THD. */
+struct st_debug_sync_control
+{
+ st_debug_sync_action *ds_action; /* array of actions */
+ uint ds_active; /* # active actions */
+ uint ds_allocated; /* # allocated actions */
+ ulonglong dsp_hits; /* statistics */
+ ulonglong dsp_executed; /* statistics */
+ ulonglong dsp_max_active; /* statistics */
+ /*
+ thd->proc_info points at unsynchronized memory.
+ It must not go away as long as the thread exists.
+ */
+ char ds_proc_info[80]; /* proc_info string */
+};
+
+
+/**
+ Definitions for the debug sync facility.
+ 1. Global string variable to hold a "signal" ("signal post", "flag mast").
+ 2. Global condition variable for signaling and waiting.
+ 3. Global mutex to synchronize access to the above.
+*/
+struct st_debug_sync_globals
+{
+ String ds_signal; /* signal variable */
+ pthread_cond_t ds_cond; /* condition variable */
+ pthread_mutex_t ds_mutex; /* mutex variable */
+ ulonglong dsp_hits; /* statistics */
+ ulonglong dsp_executed; /* statistics */
+ ulonglong dsp_max_active; /* statistics */
+};
+static st_debug_sync_globals debug_sync_global; /* All globals in one object */
+
+/**
+ Callback pointer for C files.
+*/
+extern "C" void (*debug_sync_C_callback_ptr)(const char *, size_t);
+
+
+/**
+ Callback for debug sync, to be used by C files. See thr_lock.c for example.
+
+ @description
+
+ We cannot place a sync point directly in C files (like those in mysys or
+ certain storage engines written mostly in C like MyISAM or Maria). Because
+ they are C code and do not include mysql_priv.h. So they do not know the
+ macro DEBUG_SYNC(thd, sync_point_name). The macro needs a 'thd' argument.
+ Hence it cannot be used in files outside of the sql/ directory.
+
+ The workaround is to call back simple functions like this one from
+ non-sql/ files.
+
+ We want to allow modules like thr_lock to be used without sql/ and
+ especially without Debug Sync. So we cannot just do a simple call
+ of the callback function. Instead we provide a global pointer in
+ the other file, which is to be set to the callback by Debug Sync.
+ If the pointer is not set, no call back will be done. If Debug
+ Sync sets the pointer to a callback function like this one, it will
+ be called. That way thr_lock.c does not have an undefined reference
+ to Debug Sync and can be used without it. Debug Sync, in contrast,
+ has an undefined reference to that pointer and thus requires
+ thr_lock to be linked too. But this is not a problem as it is part
+ of the MySQL server anyway.
+
+ @note
+ The callback pointer in C files is set only if debug sync is
+ initialized. And this is done only if opt_debug_sync_timeout is set.
+*/
+
+static void debug_sync_C_callback(const char *sync_point_name,
+ size_t name_len)
+{
+ if (unlikely(opt_debug_sync_timeout))
+ debug_sync(current_thd, sync_point_name, name_len);
+}
+
+
+/**
+ Initialize the debug sync facility at server start.
+
+ @return status
+ @retval 0 ok
+ @retval != 0 error
+*/
+
+int debug_sync_init(void)
+{
+ DBUG_ENTER("debug_sync_init");
+
+ if (opt_debug_sync_timeout)
+ {
+ int rc;
+
+ /* Initialize the global variables. */
+ debug_sync_global.ds_signal.length(0);
+ if ((rc= pthread_cond_init(&debug_sync_global.ds_cond, NULL)) ||
+ (rc= pthread_mutex_init(&debug_sync_global.ds_mutex,
+ MY_MUTEX_INIT_FAST)))
+ DBUG_RETURN(rc); /* purecov: inspected */
+
+ /* Set the call back pointer in C files. */
+ debug_sync_C_callback_ptr= debug_sync_C_callback;
+ }
+
+ DBUG_RETURN(0);
+}
+
+
+/**
+ End the debug sync facility.
+
+ @description
+ This is called at server shutdown or after a thread initialization error.
+*/
+
+void debug_sync_end(void)
+{
+ DBUG_ENTER("debug_sync_end");
+
+ /* End the facility only if it had been initialized. */
+ if (debug_sync_C_callback_ptr)
+ {
+ /* Clear the call back pointer in C files. */
+ debug_sync_C_callback_ptr= NULL;
+
+ /* Destroy the global variables. */
+ debug_sync_global.ds_signal.free();
+ (void) pthread_cond_destroy(&debug_sync_global.ds_cond);
+ (void) pthread_mutex_destroy(&debug_sync_global.ds_mutex);
+
+ /* Print statistics. */
+ {
+ char llbuff[22];
+ sql_print_information("Debug sync points hit: %22s",
+ llstr(debug_sync_global.dsp_hits, llbuff));
+ sql_print_information("Debug sync points executed: %22s",
+ llstr(debug_sync_global.dsp_executed, llbuff));
+ sql_print_information("Debug sync points max active per thread: %22s",
+ llstr(debug_sync_global.dsp_max_active, llbuff));
+ }
+ }
+
+ DBUG_VOID_RETURN;
+}
+
+
+/* purecov: begin tested */
+
+/**
+ Disable the facility after lack of memory if no error can be returned.
+
+ @note
+ Do not end the facility here because the global variables can
+ be in use by other threads.
+*/
+
+static void debug_sync_emergency_disable(void)
+{
+ DBUG_ENTER("debug_sync_emergency_disable");
+
+ opt_debug_sync_timeout= 0;
+
+ DBUG_PRINT("debug_sync",
+ ("Debug Sync Facility disabled due to lack of memory."));
+ sql_print_error("Debug Sync Facility disabled due to lack of memory.");
+
+ DBUG_VOID_RETURN;
+}
+
+/* purecov: end */
+
+
+/**
+ Initialize the debug sync facility at thread start.
+
+ @param[in] thd thread handle
+*/
+
+void debug_sync_init_thread(THD *thd)
+{
+ DBUG_ENTER("debug_sync_init_thread");
+ DBUG_ASSERT(thd);
+
+ if (opt_debug_sync_timeout)
+ {
+ thd->debug_sync_control= (st_debug_sync_control*)
+ my_malloc(sizeof(st_debug_sync_control), MYF(MY_WME | MY_ZEROFILL));
+ if (!thd->debug_sync_control)
+ {
+ /*
+ Error is reported by my_malloc().
+ We must disable the facility. We have no way to return an error.
+ */
+ debug_sync_emergency_disable(); /* purecov: tested */
+ }
+ }
+
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ End the debug sync facility at thread end.
+
+ @param[in] thd thread handle
+*/
+
+void debug_sync_end_thread(THD *thd)
+{
+ DBUG_ENTER("debug_sync_end_thread");
+ DBUG_ASSERT(thd);
+
+ if (thd->debug_sync_control)
+ {
+ st_debug_sync_control *ds_control= thd->debug_sync_control;
+
+ /*
+ This synchronization point can be used to synchronize on thread end.
+ This is the latest point in a THD's life, where this can be done.
+ */
+ DEBUG_SYNC(thd, "thread_end");
+
+ if (ds_control->ds_action)
+ {
+ st_debug_sync_action *action= ds_control->ds_action;
+ st_debug_sync_action *action_end= action + ds_control->ds_allocated;
+ for (; action < action_end; action++)
+ {
+ action->signal.free();
+ action->wait_for.free();
+ action->sync_point.free();
+ }
+ my_free(ds_control->ds_action, MYF(0));
+ }
+
+ /* Statistics. */
+ pthread_mutex_lock(&debug_sync_global.ds_mutex);
+ debug_sync_global.dsp_hits+= ds_control->dsp_hits;
+ debug_sync_global.dsp_executed+= ds_control->dsp_executed;
+ if (debug_sync_global.dsp_max_active < ds_control->dsp_max_active)
+ debug_sync_global.dsp_max_active= ds_control->dsp_max_active;
+ pthread_mutex_unlock(&debug_sync_global.ds_mutex);
+
+ my_free(ds_control, MYF(0));
+ thd->debug_sync_control= NULL;
+ }
+
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ Move a string by length.
+
+ @param[out] to buffer for the resulting string
+ @param[in] to_end end of buffer
+ @param[in] from source string
+ @param[in] length number of bytes to copy
+
+ @return pointer to end of copied string
+*/
+
+static char *debug_sync_bmove_len(char *to, char *to_end,
+ const char *from, size_t length)
+{
+ DBUG_ASSERT(to);
+ DBUG_ASSERT(to_end);
+ DBUG_ASSERT(!length || from);
+ set_if_smaller(length, (size_t) (to_end - to));
+ memcpy(to, from, length);
+ return (to + length);
+}
+
+
+#if !defined(DBUG_OFF)
+
+/**
+ Create a string that describes an action.
+
+ @param[out] result buffer for the resulting string
+ @param[in] size size of result buffer
+ @param[in] action action to describe
+*/
+
+static void debug_sync_action_string(char *result, uint size,
+ st_debug_sync_action *action)
+{
+ char *wtxt= result;
+ char *wend= wtxt + size - 1; /* Allow emergency '\0'. */
+ DBUG_ASSERT(result);
+ DBUG_ASSERT(action);
+
+ /* If an execute count is present, signal or wait_for are needed too. */
+ DBUG_ASSERT(!action->execute ||
+ action->signal.length() || action->wait_for.length());
+
+ if (action->execute)
+ {
+ if (action->signal.length())
+ {
+ wtxt= debug_sync_bmove_len(wtxt, wend, STRING_WITH_LEN("SIGNAL "));
+ wtxt= debug_sync_bmove_len(wtxt, wend, action->signal.ptr(),
+ action->signal.length());
+ }
+ if (action->wait_for.length())
+ {
+ if ((wtxt == result) && (wtxt < wend))
+ *(wtxt++)= ' ';
+ wtxt= debug_sync_bmove_len(wtxt, wend, STRING_WITH_LEN(" WAIT_FOR "));
+ wtxt= debug_sync_bmove_len(wtxt, wend, action->wait_for.ptr(),
+ action->wait_for.length());
+
+ if (action->timeout != opt_debug_sync_timeout)
+ {
+ wtxt+= my_snprintf(wtxt, wend - wtxt, " TIMEOUT %lu", action->timeout);
+ }
+ }
+ if (action->execute != 1)
+ {
+ wtxt+= my_snprintf(wtxt, wend - wtxt, " EXECUTE %lu", action->execute);
+ }
+ }
+ if (action->hit_limit)
+ {
+ wtxt+= my_snprintf(wtxt, wend - wtxt, "%sHIT_LIMIT %lu",
+ (wtxt == result) ? "" : " ", action->hit_limit);
+ }
+
+ /*
+ If (wtxt == wend) string may not be terminated.
+ There is one byte left for an emergency termination.
+ */
+ *wtxt= '\0';
+}
+
+
+/**
+ Print actions.
+
+ @param[in] thd thread handle
+*/
+
+static void debug_sync_print_actions(THD *thd)
+{
+ st_debug_sync_control *ds_control= thd->debug_sync_control;
+ uint idx;
+ DBUG_ENTER("debug_sync_print_actions");
+ DBUG_ASSERT(thd);
+
+ if (!ds_control)
+ DBUG_VOID_RETURN;
+
+ for (idx= 0; idx < ds_control->ds_active; idx++)
+ {
+ const char *dsp_name= ds_control->ds_action[idx].sync_point.c_ptr();
+ char action_string[256];
+
+ debug_sync_action_string(action_string, sizeof(action_string),
+ ds_control->ds_action + idx);
+ DBUG_PRINT("debug_sync_list", ("%s %s", dsp_name, action_string));
+ }
+
+ DBUG_VOID_RETURN;
+}
+
+#endif /* !defined(DBUG_OFF) */
+
+
+/**
+ Compare two actions by sync point name length, string.
+
+ @param[in] arg1 reference to action1
+ @param[in] arg2 reference to action2
+
+ @return difference
+ @retval == 0 length1/string1 is same as length2/string2
+ @retval < 0 length1/string1 is smaller
+ @retval > 0 length1/string1 is bigger
+*/
+
+static int debug_sync_qsort_cmp(const void* arg1, const void* arg2)
+{
+ st_debug_sync_action *action1= (st_debug_sync_action*) arg1;
+ st_debug_sync_action *action2= (st_debug_sync_action*) arg2;
+ int diff;
+ DBUG_ASSERT(action1);
+ DBUG_ASSERT(action2);
+
+ if (!(diff= action1->sync_point.length() - action2->sync_point.length()))
+ diff= memcmp(action1->sync_point.ptr(), action2->sync_point.ptr(),
+ action1->sync_point.length());
+
+ return diff;
+}
+
+
+/**
+ Find a debug sync action.
+
+ @param[in] actionarr array of debug sync actions
+ @param[in] quantity number of actions in array
+ @param[in] dsp_name name of debug sync point to find
+ @param[in] name_len length of name of debug sync point
+
+ @return action
+ @retval != NULL found sync point in array
+ @retval NULL not found
+
+ @description
+ Binary search. Array needs to be sorted by length, sync point name.
+*/
+
+static st_debug_sync_action *debug_sync_find(st_debug_sync_action *actionarr,
+ int quantity,
+ const char *dsp_name,
+ uint name_len)
+{
+ st_debug_sync_action *action;
+ int low ;
+ int high ;
+ int mid ;
+ int diff ;
+ DBUG_ASSERT(actionarr);
+ DBUG_ASSERT(dsp_name);
+ DBUG_ASSERT(name_len);
+
+ low= 0;
+ high= quantity;
+
+ while (low < high)
+ {
+ mid= (low + high) / 2;
+ action= actionarr + mid;
+ if (!(diff= name_len - action->sync_point.length()) &&
+ !(diff= memcmp(dsp_name, action->sync_point.ptr(), name_len)))
+ return action;
+ if (diff > 0)
+ low= mid + 1;
+ else
+ high= mid - 1;
+ }
+
+ if (low < quantity)
+ {
+ action= actionarr + low;
+ if ((name_len == action->sync_point.length()) &&
+ !memcmp(dsp_name, action->sync_point.ptr(), name_len))
+ return action;
+ }
+
+ return NULL;
+}
+
+
+/**
+ Reset the debug sync facility.
+
+ @param[in] thd thread handle
+
+ @description
+ Remove all actions of this thread.
+ Clear the global signal.
+*/
+
+static void debug_sync_reset(THD *thd)
+{
+ st_debug_sync_control *ds_control= thd->debug_sync_control;
+ DBUG_ENTER("debug_sync_reset");
+ DBUG_ASSERT(thd);
+ DBUG_ASSERT(ds_control);
+
+ /* Remove all actions of this thread. */
+ ds_control->ds_active= 0;
+
+ /* Clear the global signal. */
+ pthread_mutex_lock(&debug_sync_global.ds_mutex);
+ debug_sync_global.ds_signal.length(0);
+ pthread_mutex_unlock(&debug_sync_global.ds_mutex);
+
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ Remove a debug sync action.
+
+ @param[in] ds_control control object
+ @param[in] action action to be removed
+
+ @description
+ Removing an action mainly means to decrement the ds_active counter.
+ But if the action is between other active action in the array, then
+ the array needs to be shrinked. The active actions above the one to
+ be removed have to be moved down by one slot.
+*/
+
+static void debug_sync_remove_action(st_debug_sync_control *ds_control,
+ st_debug_sync_action *action)
+{
+ uint dsp_idx= action - ds_control->ds_action;
+ DBUG_ENTER("debug_sync_remove_action");
+ DBUG_ASSERT(ds_control);
+ DBUG_ASSERT(ds_control == current_thd->debug_sync_control);
+ DBUG_ASSERT(action);
+ DBUG_ASSERT(dsp_idx < ds_control->ds_active);
+
+ /* Decrement the number of currently active actions. */
+ ds_control->ds_active--;
+
+ /*
+ If this was not the last active action in the array, we need to
+ shift remaining active actions down to keep the array gap-free.
+ Otherwise binary search might fail or take longer than necessary at
+ least. Also new actions are always put to the end of the array.
+ */
+ if (ds_control->ds_active > dsp_idx)
+ {
+ /*
+ Do not make save_action an object of class st_debug_sync_action.
+ Its destructor would tamper with the String pointers.
+ */
+ uchar save_action[sizeof(st_debug_sync_action)];
+
+ /*
+ Copy the to-be-removed action object to temporary storage before
+ the shift copies the string pointers over. Do not use assignment
+ because it would use assignment operator methods for the Strings.
+ This would copy the strings. The shift below overwrite the string
+ pointers without freeing them first. By using memmove() we save
+ the pointers, which are overwritten by the shift.
+ */
+ memmove(save_action, action, sizeof(st_debug_sync_action));
+
+ /* Move actions down. */
+ memmove(ds_control->ds_action + dsp_idx,
+ ds_control->ds_action + dsp_idx + 1,
+ (ds_control->ds_active - dsp_idx) *
+ sizeof(st_debug_sync_action));
+
+ /*
+ Copy back the saved action object to the now free array slot. This
+ replaces the double references of String pointers that have been
+ produced by the shift. Again do not use an assignment operator to
+ avoid string allocation/copy.
+ */
+ memmove(ds_control->ds_action + ds_control->ds_active, save_action,
+ sizeof(st_debug_sync_action));
+ }
+
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ Get a debug sync action.
+
+ @param[in] thd thread handle
+ @param[in] dsp_name debug sync point name
+ @param[in] name_len length of sync point name
+
+ @return action
+ @retval != NULL ok
+ @retval NULL error
+
+ @description
+ Find the debug sync action for a debug sync point or make a new one.
+*/
+
+static st_debug_sync_action *debug_sync_get_action(THD *thd,
+ const char *dsp_name,
+ uint name_len)
+{
+ st_debug_sync_control *ds_control= thd->debug_sync_control;
+ st_debug_sync_action *action;
+ DBUG_ENTER("debug_sync_get_action");
+ DBUG_ASSERT(thd);
+ DBUG_ASSERT(dsp_name);
+ DBUG_ASSERT(name_len);
+ DBUG_ASSERT(ds_control);
+ DBUG_PRINT("debug_sync", ("sync_point: '%.*s'", (int) name_len, dsp_name));
+ DBUG_PRINT("debug_sync", ("active: %u allocated: %u",
+ ds_control->ds_active, ds_control->ds_allocated));
+
+ /* There cannot be more active actions than allocated. */
+ DBUG_ASSERT(ds_control->ds_active <= ds_control->ds_allocated);
+ /* If there are active actions, the action array must be present. */
+ DBUG_ASSERT(!ds_control->ds_active || ds_control->ds_action);
+
+ /* Try to reuse existing action if there is one for this sync point. */
+ if (ds_control->ds_active &&
+ (action= debug_sync_find(ds_control->ds_action, ds_control->ds_active,
+ dsp_name, name_len)))
+ {
+ /* Reuse an already active sync point action. */
+ DBUG_ASSERT((uint)(action - ds_control->ds_action) < ds_control->ds_active);
+ DBUG_PRINT("debug_sync", ("reuse action idx: %ld",
+ (long) (action - ds_control->ds_action)));
+ }
+ else
+ {
+ /* Create a new action. */
+ int dsp_idx= ds_control->ds_active++;
+ set_if_bigger(ds_control->dsp_max_active, ds_control->ds_active);
+ if (ds_control->ds_active > ds_control->ds_allocated)
+ {
+ uint new_alloc= ds_control->ds_active + 3;
+ void *new_action= my_realloc(ds_control->ds_action,
+ new_alloc * sizeof(st_debug_sync_action),
+ MYF(MY_WME | MY_ALLOW_ZERO_PTR));
+ if (!new_action)
+ {
+ /* Error is reported by my_malloc(). */
+ goto err; /* purecov: tested */
+ }
+ ds_control->ds_action= (st_debug_sync_action*) new_action;
+ ds_control->ds_allocated= new_alloc;
+ /* Clear memory as we do not run string constructors here. */
+ bzero((uchar*) (ds_control->ds_action + dsp_idx),
+ (new_alloc - dsp_idx) * sizeof(st_debug_sync_action));
+ }
+ DBUG_PRINT("debug_sync", ("added action idx: %u", dsp_idx));
+ action= ds_control->ds_action + dsp_idx;
+ if (action->sync_point.copy(dsp_name, name_len, system_charset_info))
+ {
+ /* Error is reported by my_malloc(). */
+ goto err; /* purecov: tested */
+ }
+ action->need_sort= TRUE;
+ }
+ DBUG_ASSERT(action >= ds_control->ds_action);
+ DBUG_ASSERT(action < ds_control->ds_action + ds_control->ds_active);
+ DBUG_PRINT("debug_sync", ("action: 0x%lx array: 0x%lx count: %u",
+ (long) action, (long) ds_control->ds_action,
+ ds_control->ds_active));
+
+ DBUG_RETURN(action);
+
+ /* purecov: begin tested */
+ err:
+ DBUG_RETURN(NULL);
+ /* purecov: end */
+}
+
+
+/**
+ Set a debug sync action.
+
+ @param[in] thd thread handle
+ @param[in] action synchronization action
+
+ @return status
+ @retval FALSE ok
+ @retval TRUE error
+
+ @description
+ This is called from the debug sync parser. It arms the action for
+ the requested sync point. If the action parsed into an empty action,
+ it is removed instead.
+
+ Setting an action for a sync point means to make the sync point
+ active. When it is hit it will execute this action.
+
+ Before parsing, we "get" an action object. This is placed at the
+ end of the thread's action array unless the requested sync point
+ has an action already.
+
+ Then the parser fills the action object from the request string.
+
+ Finally the action is "set" for the sync point. If it was parsed
+ to be empty, it is removed from the array. If it did belong to a
+ sync point before, the sync point becomes inactive. If the action
+ became non-empty and it did not belong to a sync point before (it
+ was added at the end of the action array), the action array needs
+ to be sorted by sync point.
+
+ If the sync point name is "now", it is executed immediately.
+*/
+
+static bool debug_sync_set_action(THD *thd, st_debug_sync_action *action)
+{
+ st_debug_sync_control *ds_control= thd->debug_sync_control;
+ bool is_dsp_now= FALSE;
+ DBUG_ENTER("debug_sync_set_action");
+ DBUG_ASSERT(thd);
+ DBUG_ASSERT(action);
+ DBUG_ASSERT(ds_control);
+
+ action->activation_count= max(action->hit_limit, action->execute);
+ if (!action->activation_count)
+ {
+ debug_sync_remove_action(ds_control, action);
+ DBUG_PRINT("debug_sync", ("action cleared"));
+ }
+ else
+ {
+ const char *dsp_name= action->sync_point.c_ptr();
+ DBUG_EXECUTE("debug_sync", {
+ /* Functions as DBUG_PRINT args can change keyword and line nr. */
+ const char *sig_emit= action->signal.c_ptr();
+ const char *sig_wait= action->wait_for.c_ptr();
+ DBUG_PRINT("debug_sync",
+ ("sync_point: '%s' activation_count: %lu hit_limit: %lu "
+ "execute: %lu timeout: %lu signal: '%s' wait_for: '%s'",
+ dsp_name, action->activation_count,
+ action->hit_limit, action->execute, action->timeout,
+ sig_emit, sig_wait));});
+
+ /* Check this before sorting the array. action may move. */
+ is_dsp_now= !my_strcasecmp(system_charset_info, dsp_name, "now");
+
+ if (action->need_sort)
+ {
+ action->need_sort= FALSE;
+ /* Sort actions by (name_len, name). */
+ my_qsort(ds_control->ds_action, ds_control->ds_active,
+ sizeof(st_debug_sync_action), debug_sync_qsort_cmp);
+ }
+ }
+ DBUG_EXECUTE("debug_sync_list", debug_sync_print_actions(thd););
+
+ /* Execute the special sync point 'now' if activated above. */
+ if (is_dsp_now)
+ {
+ DEBUG_SYNC(thd, "now");
+ /*
+ If HIT_LIMIT for sync point "now" was 1, the execution of the sync
+ point decremented it to 0. In this case the following happened:
+
+ - an error message was reported with my_error() and
+ - the statement was killed with thd->killed= THD::KILL_QUERY.
+
+ If a statement reports an error, it must not call send_ok().
+ The calling functions will not call send_ok(), if we return TRUE
+ from this function.
+
+ thd->killed is also set if the wait is interrupted from a
+ KILL or KILL QUERY statement. In this case, no error is reported
+ and shall not be reported as a result of SET DEBUG_SYNC.
+ Hence, we check for the first condition above.
+ */
+ if (thd->is_error())
+ DBUG_RETURN(TRUE);
+ }
+
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
+ Extract a token from a string.
+
+ @param[out] token_p returns start of token
+ @param[out] token_length_p returns length of token
+ @param[in,out] ptr current string pointer, adds '\0' terminators
+
+ @return string pointer or NULL
+ @retval != NULL ptr behind token terminator or at string end
+ @retval NULL no token found in remainder of string
+
+ @note
+ This function assumes that the string is in system_charset_info,
+ that this charset is single byte for ASCII NUL ('\0'), that no
+ character except of ASCII NUL ('\0') contains a byte with value 0,
+ and that ASCII NUL ('\0') is used as the string terminator.
+
+ This function needs to return tokens that are terminated with ASCII
+ NUL ('\0'). The tokens are used in my_strcasecmp(). Unfortunately
+ there is no my_strncasecmp().
+
+ To return the last token without copying it, we require the input
+ string to be nul terminated.
+
+ @description
+ This function skips space characters at string begin.
+
+ It returns a pointer to the first non-space character in *token_p.
+
+ If no non-space character is found before the string terminator
+ ASCII NUL ('\0'), the function returns NULL. *token_p and
+ *token_length_p remain unchanged in this case (they are not set).
+
+ The function takes a space character or an ASCII NUL ('\0') as a
+ terminator of the token. The space character could be multi-byte.
+
+ It returns the length of the token in bytes, excluding the
+ terminator, in *token_length_p.
+
+ If the terminator of the token is ASCII NUL ('\0'), it returns a
+ pointer to the terminator (string end).
+
+ If the terminator is a space character, it replaces the the first
+ byte of the terminator character by ASCII NUL ('\0'), skips the (now
+ corrupted) terminator character, and skips all following space
+ characters. It returns a pointer to the next non-space character or
+ to the string terminator ASCII NUL ('\0').
+*/
+
+static char *debug_sync_token(char **token_p, uint *token_length_p, char *ptr)
+{
+ DBUG_ASSERT(token_p);
+ DBUG_ASSERT(token_length_p);
+ DBUG_ASSERT(ptr);
+
+ /* Skip leading space */
+ while (my_isspace(system_charset_info, *ptr))
+ ptr+= my_mbcharlen(system_charset_info, (uchar) *ptr);
+
+ if (!*ptr)
+ {
+ ptr= NULL;
+ goto end;
+ }
+
+ /* Get token start. */
+ *token_p= ptr;
+
+ /* Find token end. */
+ while (*ptr && !my_isspace(system_charset_info, *ptr))
+ ptr+= my_mbcharlen(system_charset_info, (uchar) *ptr);
+
+ /* Get token length. */
+ *token_length_p= ptr - *token_p;
+
+ /* If necessary, terminate token. */
+ if (*ptr)
+ {
+ /* Get terminator character length. */
+ uint mbspacelen= my_mbcharlen(system_charset_info, (uchar) *ptr);
+
+ /* Terminate token. */
+ *ptr= '\0';
+
+ /* Skip the terminator. */
+ ptr+= mbspacelen;
+
+ /* Skip trailing space */
+ while (my_isspace(system_charset_info, *ptr))
+ ptr+= my_mbcharlen(system_charset_info, (uchar) *ptr);
+ }
+
+ end:
+ return ptr;
+}
+
+
+/**
+ Extract a number from a string.
+
+ @param[out] number_p returns number
+ @param[in] actstrptr current pointer in action string
+
+ @return string pointer or NULL
+ @retval != NULL ptr behind token terminator or at string end
+ @retval NULL no token found or token is not valid number
+
+ @note
+ The same assumptions about charset apply as for debug_sync_token().
+
+ @description
+ This function fetches a token from the string and converts it
+ into a number.
+
+ If there is no token left in the string, or the token is not a valid
+ decimal number, NULL is returned. The result in *number_p is
+ undefined in this case.
+*/
+
+static char *debug_sync_number(ulong *number_p, char *actstrptr)
+{
+ char *ptr;
+ char *ept;
+ char *token;
+ uint token_length;
+ DBUG_ASSERT(number_p);
+ DBUG_ASSERT(actstrptr);
+
+ /* Get token from string. */
+ if (!(ptr= debug_sync_token(&token, &token_length, actstrptr)))
+ goto end;
+
+ *number_p= strtoul(token, &ept, 10);
+ if (*ept)
+ ptr= NULL;
+
+ end:
+ return ptr;
+}
+
+
+/**
+ Evaluate a debug sync action string.
+
+ @param[in] thd thread handle
+ @param[in,out] action_str action string to receive '\0' terminators
+
+ @return status
+ @retval FALSE ok
+ @retval TRUE error
+
+ @description
+ This is called when the DEBUG_SYNC system variable is set.
+ Parse action string, build a debug sync action, activate it.
+
+ Before parsing, we "get" an action object. This is placed at the
+ end of the thread's action array unless the requested sync point
+ has an action already.
+
+ Then the parser fills the action object from the request string.
+
+ Finally the action is "set" for the sync point. This means that the
+ sync point becomes active or inactive, depending on the action
+ values.
+
+ @note
+ The input string needs to be ASCII NUL ('\0') terminated. We split
+ nul-terminated tokens in it without copy.
+
+ @see the function comment of debug_sync_token() for more constraints
+ for the string.
+*/
+
+static bool debug_sync_eval_action(THD *thd, char *action_str)
+{
+ st_debug_sync_action *action= NULL;
+ const char *errmsg;
+ char *ptr;
+ char *token;
+ uint token_length= 0;
+ DBUG_ENTER("debug_sync_eval_action");
+ DBUG_ASSERT(thd);
+ DBUG_ASSERT(action_str);
+
+ /*
+ Get debug sync point name. Or a special command.
+ */
+ if (!(ptr= debug_sync_token(&token, &token_length, action_str)))
+ {
+ errmsg= "Missing synchronization point name";
+ goto err;
+ }
+
+ /*
+ If there is a second token, the first one is the sync point name.
+ */
+ if (*ptr)
+ {
+ /* Get an action object to collect the requested action parameters. */
+ action= debug_sync_get_action(thd, token, token_length);
+ if (!action)
+ {
+ /* Error message is sent. */
+ DBUG_RETURN(TRUE); /* purecov: tested */
+ }
+ }
+
+ /*
+ Get kind of action to be taken at sync point.
+ */
+ if (!(ptr= debug_sync_token(&token, &token_length, ptr)))
+ {
+ /* No action present. Try special commands. Token unchanged. */
+
+ /*
+ Try RESET.
+ */
+ if (!my_strcasecmp(system_charset_info, token, "RESET"))
+ {
+ /* It is RESET. Reset all actions and global signal. */
+ debug_sync_reset(thd);
+ goto end;
+ }
+
+ /* Token unchanged. It still contains sync point name. */
+ errmsg= "Missing action after synchronization point name '%.*s'";
+ goto err;
+ }
+
+ /*
+ Check for pseudo actions first. Start with actions that work on
+ an existing action.
+ */
+ DBUG_ASSERT(action);
+
+ /*
+ Try TEST.
+ */
+ if (!my_strcasecmp(system_charset_info, token, "TEST"))
+ {
+ /* It is TEST. Nothing must follow it. */
+ if (*ptr)
+ {
+ errmsg= "Nothing must follow action TEST";
+ goto err;
+ }
+
+ /* Execute sync point. */
+ debug_sync(thd, action->sync_point.ptr(), action->sync_point.length());
+ /* Fix statistics. This was not a real hit of the sync point. */
+ thd->debug_sync_control->dsp_hits--;
+ goto end;
+ }
+
+ /*
+ Now check for actions that define a new action.
+ Initialize action. Do not use bzero(). Strings may have malloced.
+ */
+ action->activation_count= 0;
+ action->hit_limit= 0;
+ action->execute= 0;
+ action->timeout= 0;
+ action->signal.length(0);
+ action->wait_for.length(0);
+
+ /*
+ Try CLEAR.
+ */
+ if (!my_strcasecmp(system_charset_info, token, "CLEAR"))
+ {
+ /* It is CLEAR. Nothing must follow it. */
+ if (*ptr)
+ {
+ errmsg= "Nothing must follow action CLEAR";
+ goto err;
+ }
+
+ /* Set (clear/remove) action. */
+ goto set_action;
+ }
+
+ /*
+ Now check for real sync point actions.
+ */
+
+ /*
+ Try SIGNAL.
+ */
+ if (!my_strcasecmp(system_charset_info, token, "SIGNAL"))
+ {
+ /* It is SIGNAL. Signal name must follow. */
+ if (!(ptr= debug_sync_token(&token, &token_length, ptr)))
+ {
+ errmsg= "Missing signal name after action SIGNAL";
+ goto err;
+ }
+ if (action->signal.copy(token, token_length, system_charset_info))
+ {
+ /* Error is reported by my_malloc(). */
+ /* purecov: begin tested */
+ errmsg= NULL;
+ goto err;
+ /* purecov: end */
+ }
+
+ /* Set default for EXECUTE option. */
+ action->execute= 1;
+
+ /* Get next token. If none follows, set action. */
+ if (!(ptr= debug_sync_token(&token, &token_length, ptr)))
+ goto set_action;
+ }
+
+ /*
+ Try WAIT_FOR.
+ */
+ if (!my_strcasecmp(system_charset_info, token, "WAIT_FOR"))
+ {
+ /* It is WAIT_FOR. Wait_for signal name must follow. */
+ if (!(ptr= debug_sync_token(&token, &token_length, ptr)))
+ {
+ errmsg= "Missing signal name after action WAIT_FOR";
+ goto err;
+ }
+ if (action->wait_for.copy(token, token_length, system_charset_info))
+ {
+ /* Error is reported by my_malloc(). */
+ /* purecov: begin tested */
+ errmsg= NULL;
+ goto err;
+ /* purecov: end */
+ }
+
+ /* Set default for EXECUTE and TIMEOUT options. */
+ action->execute= 1;
+ action->timeout= opt_debug_sync_timeout;
+
+ /* Get next token. If none follows, set action. */
+ if (!(ptr= debug_sync_token(&token, &token_length, ptr)))
+ goto set_action;
+
+ /*
+ Try TIMEOUT.
+ */
+ if (!my_strcasecmp(system_charset_info, token, "TIMEOUT"))
+ {
+ /* It is TIMEOUT. Number must follow. */
+ if (!(ptr= debug_sync_number(&action->timeout, ptr)))
+ {
+ errmsg= "Missing valid number after TIMEOUT";
+ goto err;
+ }
+
+ /* Get next token. If none follows, set action. */
+ if (!(ptr= debug_sync_token(&token, &token_length, ptr)))
+ goto set_action;
+ }
+ }
+
+ /*
+ Try EXECUTE.
+ */
+ if (!my_strcasecmp(system_charset_info, token, "EXECUTE"))
+ {
+ /*
+ EXECUTE requires either SIGNAL and/or WAIT_FOR to be present.
+ In this case action->execute has been preset to 1.
+ */
+ if (!action->execute)
+ {
+ errmsg= "Missing action before EXECUTE";
+ goto err;
+ }
+
+ /* Number must follow. */
+ if (!(ptr= debug_sync_number(&action->execute, ptr)))
+ {
+ errmsg= "Missing valid number after EXECUTE";
+ goto err;
+ }
+
+ /* Get next token. If none follows, set action. */
+ if (!(ptr= debug_sync_token(&token, &token_length, ptr)))
+ goto set_action;
+ }
+
+ /*
+ Try HIT_LIMIT.
+ */
+ if (!my_strcasecmp(system_charset_info, token, "HIT_LIMIT"))
+ {
+ /* Number must follow. */
+ if (!(ptr= debug_sync_number(&action->hit_limit, ptr)))
+ {
+ errmsg= "Missing valid number after HIT_LIMIT";
+ goto err;
+ }
+
+ /* Get next token. If none follows, set action. */
+ if (!(ptr= debug_sync_token(&token, &token_length, ptr)))
+ goto set_action;
+ }
+
+ errmsg= "Illegal or out of order stuff: '%.*s'";
+
+ err:
+ if (errmsg)
+ {
+ /*
+ NOTE: errmsg must either have %.*s or none % at all.
+ It can be NULL if an error message is already reported
+ (e.g. by my_malloc()).
+ */
+ set_if_smaller(token_length, 64); /* Limit error message length. */
+ my_printf_error(ER_PARSE_ERROR, errmsg, MYF(0), token_length, token);
+ }
+ if (action)
+ debug_sync_remove_action(thd->debug_sync_control, action);
+ DBUG_RETURN(TRUE);
+
+ set_action:
+ DBUG_RETURN(debug_sync_set_action(thd, action));
+
+ end:
+ DBUG_RETURN(FALSE);
+}
+
+
+/**
+ Check if the system variable 'debug_sync' can be set.
+
+ @param[in] thd thread handle
+ @param[in] var set variable request
+
+ @return status
+ @retval FALSE ok, variable can be set
+ @retval TRUE error, variable cannot be set
+*/
+
+bool sys_var_debug_sync::check(THD *thd, set_var *var)
+{
+ DBUG_ENTER("sys_var_debug_sync::check");
+ DBUG_ASSERT(thd);
+ DBUG_ASSERT(var);
+
+ /*
+ Variable can be set for the session only.
+
+ This could be changed later. Then we need to have a global array of
+ actions in addition to the thread local ones. SET GLOBAL would
+ manage the global array, SET [SESSION] the local array. A sync point
+ would need to look for a local and a global action. Setting and
+ executing of global actions need to be protected by a mutex.
+
+ The purpose of global actions could be to allow synchronizing with
+ connectionless threads that cannot execute SET statements.
+ */
+ if (var->type == OPT_GLOBAL)
+ {
+ my_error(ER_LOCAL_VARIABLE, MYF(0), name);
+ DBUG_RETURN(TRUE);
+ }
+
+ /*
+ Do not check for disabled facility. Test result should not
+ unnecessarily differ from enabled facility.
+ */
+
+ /*
+ Facility requires SUPER privilege. Sync points could be inside
+ global mutexes (e.g. LOCK_open). Waiting there forever would
+ stall the whole server.
+ */
+ DBUG_RETURN(check_global_access(thd, SUPER_ACL));
+}
+
+
+/**
+ Set the system variable 'debug_sync'.
+
+ @param[in] thd thread handle
+ @param[in] var set variable request
+
+ @return status
+ @retval FALSE ok, variable is set
+ @retval TRUE error, variable could not be set
+
+ @note
+ "Setting" of the system variable 'debug_sync' does not mean to
+ assign a value to it as usual. Instead a debug sync action is parsed
+ from the input string and stored apart from the variable value.
+
+ @note
+ For efficiency reasons, the action string parser places '\0'
+ terminators in the string. So we need to take a copy here.
+*/
+
+bool sys_var_debug_sync::update(THD *thd, set_var *var)
+{
+ char *val_str;
+ String *val_ptr;
+ String val_buf;
+ DBUG_ENTER("sys_var_debug_sync::update");
+ DBUG_ASSERT(thd);
+
+ /*
+ Depending on the value type (string literal, user variable, ...)
+ val_buf receives a copy of the value or not. But we always need
+ a copy. So we take a copy, if it is not done by val_str().
+ If val_str() puts a copy into val_buf, then it returns &val_buf,
+ otherwise it returns a pointer to the string object that we need
+ to copy.
+ */
+ val_ptr= var ? var->value->val_str(&val_buf) : &val_buf;
+ if (val_ptr != &val_buf)
+ {
+ val_buf.copy(*val_ptr);
+ }
+ val_str= val_buf.c_ptr();
+ DBUG_PRINT("debug_sync", ("set action: '%s'", val_str));
+
+ /*
+ debug_sync_eval_action() places '\0' in the string, which itself
+ must be '\0' terminated.
+ */
+ DBUG_RETURN(opt_debug_sync_timeout ?
+ debug_sync_eval_action(thd, val_str) :
+ FALSE);
+}
+
+
+/**
+ Retrieve the value of the system variable 'debug_sync'.
+
+ @param[in] thd thread handle
+ @param[in] type variable type, unused
+ @param[in] base variable base, unused
+
+ @return string
+ @retval != NULL ok, string pointer
+ @retval NULL memory allocation error
+
+ @note
+ The value of the system variable 'debug_sync' reflects if
+ the facility is enabled ("ON") or disabled (default, "OFF").
+
+ When "ON", the current signal is added.
+*/
+
+uchar *sys_var_debug_sync::value_ptr(THD *thd,
+ enum_var_type type __attribute__((unused)),
+ LEX_STRING *base __attribute__((unused)))
+{
+ char *value;
+ DBUG_ENTER("sys_var_debug_sync::value_ptr");
+ DBUG_ASSERT(thd);
+
+ if (opt_debug_sync_timeout)
+ {
+ static char on[]= "ON - current signal: '";
+
+ // Ensure exclusive access to debug_sync_global.ds_signal
+ pthread_mutex_lock(&debug_sync_global.ds_mutex);
+
+ size_t lgt= (sizeof(on) /* includes '\0' */ +
+ debug_sync_global.ds_signal.length() + 1 /* for '\'' */);
+ char *vend;
+ char *vptr;
+
+ if ((value= (char*) alloc_root(thd->mem_root, lgt)))
+ {
+ vend= value + lgt - 1; /* reserve space for '\0'. */
+ vptr= debug_sync_bmove_len(value, vend, STRING_WITH_LEN(on));
+ vptr= debug_sync_bmove_len(vptr, vend, debug_sync_global.ds_signal.ptr(),
+ debug_sync_global.ds_signal.length());
+ if (vptr < vend)
+ *(vptr++)= '\'';
+ *vptr= '\0'; /* We have one byte reserved for the worst case. */
+ }
+ pthread_mutex_unlock(&debug_sync_global.ds_mutex);
+ }
+ else
+ {
+ /* purecov: begin tested */
+ value= strmake_root(thd->mem_root, STRING_WITH_LEN("OFF"));
+ /* purecov: end */
+ }
+
+ DBUG_RETURN((uchar*) value);
+}
+
+
+/**
+ Execute requested action at a synchronization point.
+
+ @param[in] thd thread handle
+ @param[in] action action to be executed
+
+ @note
+ This is to be called only if activation count > 0.
+*/
+
+static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
+{
+ IF_DBUG(const char *dsp_name= action->sync_point.c_ptr());
+ IF_DBUG(const char *sig_emit= action->signal.c_ptr());
+ IF_DBUG(const char *sig_wait= action->wait_for.c_ptr());
+ DBUG_ENTER("debug_sync_execute");
+ DBUG_ASSERT(thd);
+ DBUG_ASSERT(action);
+ DBUG_PRINT("debug_sync",
+ ("sync_point: '%s' activation_count: %lu hit_limit: %lu "
+ "execute: %lu timeout: %lu signal: '%s' wait_for: '%s'",
+ dsp_name, action->activation_count, action->hit_limit,
+ action->execute, action->timeout, sig_emit, sig_wait));
+
+ DBUG_ASSERT(action->activation_count);
+ action->activation_count--;
+
+ if (action->execute)
+ {
+ const char *old_proc_info;
+
+ action->execute--;
+
+ /*
+ If we will be going to wait, set proc_info for the PROCESSLIST table.
+ Do this before emitting the signal, so other threads can see it
+ if they awake before we enter_cond() below.
+ */
+ if (action->wait_for.length())
+ {
+ st_debug_sync_control *ds_control= thd->debug_sync_control;
+ strxnmov(ds_control->ds_proc_info, sizeof(ds_control->ds_proc_info)-1,
+ "debug sync point: ", action->sync_point.c_ptr(), NullS);
+ old_proc_info= thd->proc_info;
+ thd_proc_info(thd, ds_control->ds_proc_info);
+ }
+
+ /*
+ Take mutex to ensure that only one thread access
+ debug_sync_global.ds_signal at a time. Need to take mutex for
+ read access too, to create a memory barrier in order to avoid that
+ threads just reads an old cached version of the signal.
+ */
+ pthread_mutex_lock(&debug_sync_global.ds_mutex);
+
+ if (action->signal.length())
+ {
+ /* Copy the signal to the global variable. */
+ if (debug_sync_global.ds_signal.copy(action->signal))
+ {
+ /*
+ Error is reported by my_malloc().
+ We must disable the facility. We have no way to return an error.
+ */
+ debug_sync_emergency_disable(); /* purecov: tested */
+ }
+ /* Wake threads waiting in a sync point. */
+ pthread_cond_broadcast(&debug_sync_global.ds_cond);
+ DBUG_PRINT("debug_sync_exec", ("signal '%s' at: '%s'",
+ sig_emit, dsp_name));
+ } /* end if (action->signal.length()) */
+
+ if (action->wait_for.length())
+ {
+ pthread_mutex_t *old_mutex;
+ pthread_cond_t *old_cond;
+ int error= 0;
+ struct timespec abstime;
+
+ /*
+ We don't use enter_cond()/exit_cond(). They do not save old
+ mutex and cond. This would prohibit the use of DEBUG_SYNC
+ between other places of enter_cond() and exit_cond().
+ */
+ old_mutex= thd->mysys_var->current_mutex;
+ old_cond= thd->mysys_var->current_cond;
+ thd->mysys_var->current_mutex= &debug_sync_global.ds_mutex;
+ thd->mysys_var->current_cond= &debug_sync_global.ds_cond;
+
+ set_timespec(abstime, action->timeout);
+ DBUG_EXECUTE("debug_sync_exec", {
+ /* Functions as DBUG_PRINT args can change keyword and line nr. */
+ const char *sig_glob= debug_sync_global.ds_signal.c_ptr();
+ DBUG_PRINT("debug_sync_exec",
+ ("wait for '%s' at: '%s' curr: '%s'",
+ sig_wait, dsp_name, sig_glob));});
+
+ /*
+ Wait until global signal string matches the wait_for string.
+ Interrupt when thread or query is killed or facility disabled.
+ The facility can become disabled when some thread cannot get
+ the required dynamic memory allocated.
+ */
+ while (stringcmp(&debug_sync_global.ds_signal, &action->wait_for) &&
+ !thd->killed && opt_debug_sync_timeout)
+ {
+ error= pthread_cond_timedwait(&debug_sync_global.ds_cond,
+ &debug_sync_global.ds_mutex,
+ &abstime);
+ DBUG_EXECUTE("debug_sync", {
+ /* Functions as DBUG_PRINT args can change keyword and line nr. */
+ const char *sig_glob= debug_sync_global.ds_signal.c_ptr();
+ DBUG_PRINT("debug_sync",
+ ("awoke from %s global: %s error: %d",
+ sig_wait, sig_glob, error));});
+ if (error == ETIMEDOUT || error == ETIME)
+ {
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_DEBUG_SYNC_TIMEOUT, ER(ER_DEBUG_SYNC_TIMEOUT));
+ break;
+ }
+ error= 0;
+ }
+ DBUG_EXECUTE("debug_sync_exec",
+ if (thd->killed)
+ DBUG_PRINT("debug_sync_exec",
+ ("killed %d from '%s' at: '%s'",
+ thd->killed, sig_wait, dsp_name));
+ else
+ DBUG_PRINT("debug_sync_exec",
+ ("%s from '%s' at: '%s'",
+ error ? "timeout" : "resume",
+ sig_wait, dsp_name)););
+
+ /*
+ We don't use enter_cond()/exit_cond(). They do not save old
+ mutex and cond. This would prohibit the use of DEBUG_SYNC
+ between other places of enter_cond() and exit_cond(). The
+ protected mutex must always unlocked _before_ mysys_var->mutex
+ is locked. (See comment in THD::exit_cond().)
+ */
+ pthread_mutex_unlock(&debug_sync_global.ds_mutex);
+ pthread_mutex_lock(&thd->mysys_var->mutex);
+ thd->mysys_var->current_mutex= old_mutex;
+ thd->mysys_var->current_cond= old_cond;
+ thd_proc_info(thd, old_proc_info);
+ pthread_mutex_unlock(&thd->mysys_var->mutex);
+
+ }
+ else
+ {
+ /* In case we don't wait, we just release the mutex. */
+ pthread_mutex_unlock(&debug_sync_global.ds_mutex);
+ } /* end if (action->wait_for.length()) */
+
+ } /* end if (action->execute) */
+
+ /* hit_limit is zero for infinite. Don't decrement unconditionally. */
+ if (action->hit_limit)
+ {
+ if (!--action->hit_limit)
+ {
+ thd->killed= THD::KILL_QUERY;
+ my_error(ER_DEBUG_SYNC_HIT_LIMIT, MYF(0));
+ }
+ DBUG_PRINT("debug_sync_exec", ("hit_limit: %lu at: '%s'",
+ action->hit_limit, dsp_name));
+ }
+
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ Execute requested action at a synchronization point.
+
+ @param[in] thd thread handle
+ @param[in] sync_point_name name of synchronization point
+ @param[in] name_len length of sync point name
+*/
+
+void debug_sync(THD *thd, const char *sync_point_name, size_t name_len)
+{
+ st_debug_sync_control *ds_control= thd->debug_sync_control;
+ st_debug_sync_action *action;
+ DBUG_ENTER("debug_sync");
+ DBUG_ASSERT(thd);
+ DBUG_ASSERT(sync_point_name);
+ DBUG_ASSERT(name_len);
+ DBUG_ASSERT(ds_control);
+ DBUG_PRINT("debug_sync_point", ("hit: '%s'", sync_point_name));
+
+ /* Statistics. */
+ ds_control->dsp_hits++;
+
+ if (ds_control->ds_active &&
+ (action= debug_sync_find(ds_control->ds_action, ds_control->ds_active,
+ sync_point_name, name_len)) &&
+ action->activation_count)
+ {
+ /* Sync point is active (action exists). */
+ debug_sync_execute(thd, action);
+
+ /* Statistics. */
+ ds_control->dsp_executed++;
+
+ /* If action became inactive, remove it to shrink the search array. */
+ if (!action->activation_count)
+ debug_sync_remove_action(ds_control, action);
+ }
+
+ DBUG_VOID_RETURN;
+}
+
+#endif /* defined(ENABLED_DEBUG_SYNC) */
diff --git a/sql/debug_sync.h b/sql/debug_sync.h
new file mode 100644
index 00000000000..f4cd0b364cf
--- /dev/null
+++ b/sql/debug_sync.h
@@ -0,0 +1,60 @@
+#ifndef DEBUG_SYNC_INCLUDED
+#define DEBUG_SYNC_INCLUDED
+
+/* Copyright (C) 2008 Sun Microsystems, Inc.
+
+ 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 */
+
+/**
+ @file
+
+ Declarations for the Debug Sync Facility. See debug_sync.cc for details.
+*/
+
+#ifdef USE_PRAGMA_INTERFACE
+#pragma interface /* gcc class implementation */
+#endif
+
+#include <my_global.h>
+
+class THD;
+
+#if defined(ENABLED_DEBUG_SYNC)
+
+/* Macro to be put in the code at synchronization points. */
+#define DEBUG_SYNC(_thd_, _sync_point_name_) \
+ do { if (unlikely(opt_debug_sync_timeout)) \
+ debug_sync(_thd_, STRING_WITH_LEN(_sync_point_name_)); \
+ } while (0)
+
+/* Command line option --debug-sync-timeout. See mysqld.cc. */
+extern uint opt_debug_sync_timeout;
+
+/* Default WAIT_FOR timeout if command line option is given without argument. */
+#define DEBUG_SYNC_DEFAULT_WAIT_TIMEOUT 300
+
+/* Debug Sync prototypes. See debug_sync.cc. */
+extern int debug_sync_init(void);
+extern void debug_sync_end(void);
+extern void debug_sync_init_thread(THD *thd);
+extern void debug_sync_end_thread(THD *thd);
+extern void debug_sync(THD *thd, const char *sync_point_name, size_t name_len);
+
+#else /* defined(ENABLED_DEBUG_SYNC) */
+
+#define DEBUG_SYNC(_thd_, _sync_point_name_) /* disabled DEBUG_SYNC */
+
+#endif /* defined(ENABLED_DEBUG_SYNC) */
+
+#endif /* DEBUG_SYNC_INCLUDED */
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index e09d18ac62d..ea444b83f63 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -1432,7 +1432,7 @@ Event_job_data::execute(THD *thd, bool drop)
thd->set_query(sp_sql.c_ptr_safe(), sp_sql.length());
{
- Parser_state parser_state(thd, thd->query, thd->query_length);
+ Parser_state parser_state(thd, thd->query(), thd->query_length());
lex_start(thd);
if (parse_sql(thd, & parser_state, creation_ctx))
diff --git a/sql/events.cc b/sql/events.cc
index 026d096e2a3..49c7adbaa8e 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -464,7 +464,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
if (!dropped)
{
/* Binlog the create event. */
- DBUG_ASSERT(thd->query && thd->query_length);
+ DBUG_ASSERT(thd->query() && thd->query_length());
String log_query;
if (create_query_string(thd, &log_query))
{
@@ -594,8 +594,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data,
event_queue->update_event(thd, parse_data->dbname, parse_data->name,
new_element);
/* Binlog the alter event. */
- DBUG_ASSERT(thd->query && thd->query_length);
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ DBUG_ASSERT(thd->query() && thd->query_length());
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
}
pthread_mutex_unlock(&LOCK_event_metadata);
@@ -669,8 +669,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
if (event_queue)
event_queue->drop_event(thd, dbname, name);
/* Binlog the drop event. */
- DBUG_ASSERT(thd->query && thd->query_length);
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ DBUG_ASSERT(thd->query() && thd->query_length());
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
pthread_mutex_unlock(&LOCK_event_metadata);
DBUG_RETURN(ret);
diff --git a/sql/field.cc b/sql/field.cc
index 591a2bcbbb9..b10f9f88022 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1,4 +1,4 @@
-/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
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
@@ -2482,97 +2482,12 @@ Field_new_decimal::Field_new_decimal(uint32 len_arg,
{
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
- DBUG_ASSERT(precision >= dec);
DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION) &&
(dec <= DECIMAL_MAX_SCALE));
bin_size= my_decimal_get_binary_size(precision, dec);
}
-/**
- Create a field to hold a decimal value from an item.
-
- @remark The MySQL DECIMAL data type has a characteristic that needs to be
- taken into account when deducing the type from a Item_decimal.
-
- But first, let's briefly recap what is the new MySQL DECIMAL type:
-
- The declaration syntax for a decimal is DECIMAL(M,D), where:
-
- * M is the maximum number of digits (the precision).
- It has a range of 1 to 65.
- * D is the number of digits to the right of the decimal separator (the scale).
- It has a range of 0 to 30 and must be no larger than M.
-
- D and M are used to determine the storage requirements for the integer
- and fractional parts of each value. The integer part is to the left of
- the decimal separator and to the right is the fractional part. Hence:
-
- M is the number of digits for the integer and fractional part.
- D is the number of digits for the fractional part.
-
- Consequently, M - D is the number of digits for the integer part. For
- example, a DECIMAL(20,10) column has ten digits on either side of
- the decimal separator.
-
- The characteristic that needs to be taken into account is that the
- backing type for Item_decimal is a my_decimal that has a higher
- precision (DECIMAL_MAX_POSSIBLE_PRECISION, see my_decimal.h) than
- DECIMAL.
-
- Drawing a comparison between my_decimal and DECIMAL:
-
- * M has a range of 1 to 81.
- * D has a range of 0 to 81.
-
- There can be a difference in range if the decimal contains a integer
- part. This is because the fractional part must always be on a group
- boundary, leaving at least one group for the integer part. Since each
- group is 9 (DIG_PER_DEC1) digits and there are 9 (DECIMAL_BUFF_LENGTH)
- groups, the fractional part is limited to 72 digits if there is at
- least one digit in the integral part.
-
- Although the backing type for a DECIMAL is also my_decimal, every
- time a my_decimal is stored in a DECIMAL field, the precision and
- scale are explicitly capped at 65 (DECIMAL_MAX_PRECISION) and 30
- (DECIMAL_MAX_SCALE) digits, following my_decimal truncation procedure
- (FIX_INTG_FRAC_ERROR).
-*/
-
-Field_new_decimal *
-Field_new_decimal::new_decimal_field(const Item *item)
-{
- uint32 len;
- uint intg= item->decimal_int_part(), scale= item->decimals;
-
- DBUG_ASSERT(item->decimal_precision() >= item->decimals);
-
- /*
- Employ a procedure along the lines of the my_decimal truncation process:
- - If the integer part is equal to or bigger than the maximum precision:
- Truncate integer part to fit and the fractional becomes zero.
- - Otherwise:
- Truncate fractional part to fit.
- */
- if (intg >= DECIMAL_MAX_PRECISION)
- {
- intg= DECIMAL_MAX_PRECISION;
- scale= 0;
- }
- else
- {
- uint room= min(DECIMAL_MAX_PRECISION - intg, DECIMAL_MAX_SCALE);
- if (scale > room)
- scale= room;
- }
-
- len= my_decimal_precision_to_length(intg + scale, scale, item->unsigned_flag);
-
- return new Field_new_decimal(len, item->maybe_null, item->name, scale,
- item->unsigned_flag);
-}
-
-
int Field_new_decimal::reset(void)
{
store_value(&decimal_zero);
@@ -6556,20 +6471,9 @@ uint Field::is_equal(Create_field *new_field)
}
-/* If one of the fields is binary and the other one isn't return 1 else 0 */
-
-bool Field_str::compare_str_field_flags(Create_field *new_field, uint32 flag_arg)
-{
- return (((new_field->flags & (BINCMP_FLAG | BINARY_FLAG)) &&
- !(flag_arg & (BINCMP_FLAG | BINARY_FLAG))) ||
- (!(new_field->flags & (BINCMP_FLAG | BINARY_FLAG)) &&
- (flag_arg & (BINCMP_FLAG | BINARY_FLAG))));
-}
-
-
uint Field_str::is_equal(Create_field *new_field)
{
- if (compare_str_field_flags(new_field, flags))
+ if (field_flags_are_binary() != new_field->field_flags_are_binary())
return 0;
return ((new_field->sql_type == real_type()) &&
@@ -8335,7 +8239,7 @@ uint Field_blob::max_packed_col_length(uint max_length)
uint Field_blob::is_equal(Create_field *new_field)
{
- if (compare_str_field_flags(new_field, flags))
+ if (field_flags_are_binary() != new_field->field_flags_are_binary())
return 0;
return ((new_field->sql_type == get_blob_type_from_length(max_data_length()))
@@ -8839,38 +8743,81 @@ bool Field::eq_def(Field *field)
/**
+ Compare the first t1::count type names.
+
+ @return TRUE if the type names of t1 match those of t2. FALSE otherwise.
+*/
+
+static bool compare_type_names(CHARSET_INFO *charset, TYPELIB *t1, TYPELIB *t2)
+{
+ for (uint i= 0; i < t1->count; i++)
+ if (my_strnncoll(charset,
+ (const uchar*) t1->type_names[i],
+ t1->type_lengths[i],
+ (const uchar*) t2->type_names[i],
+ t2->type_lengths[i]))
+ return FALSE;
+ return TRUE;
+}
+
+/**
@return
returns 1 if the fields are equally defined
*/
bool Field_enum::eq_def(Field *field)
{
+ TYPELIB *values;
+
if (!Field::eq_def(field))
- return 0;
- return compare_enum_values(((Field_enum*) field)->typelib);
-}
+ return FALSE;
+ values= ((Field_enum*) field)->typelib;
-bool Field_enum::compare_enum_values(TYPELIB *values)
-{
+ /* Definition must be strictly equal. */
if (typelib->count != values->count)
return FALSE;
- for (uint i= 0; i < typelib->count; i++)
- if (my_strnncoll(field_charset,
- (const uchar*) typelib->type_names[i],
- typelib->type_lengths[i],
- (const uchar*) values->type_names[i],
- values->type_lengths[i]))
- return FALSE;
- return TRUE;
+
+ return compare_type_names(field_charset, typelib, values);
}
+/**
+ Check whether two fields can be considered 'equal' for table
+ alteration purposes. Fields are equal if they retain the same
+ pack length and if new members are added to the end of the list.
+
+ @return IS_EQUAL_YES if fields are compatible.
+ IS_EQUAL_NO otherwise.
+*/
+
uint Field_enum::is_equal(Create_field *new_field)
{
- if (!Field_str::is_equal(new_field))
- return 0;
- return compare_enum_values(new_field->interval);
+ TYPELIB *values= new_field->interval;
+
+ /*
+ The fields are compatible if they have the same flags,
+ type, charset and have the same underlying length.
+ */
+ if (new_field->field_flags_are_binary() != field_flags_are_binary() ||
+ new_field->sql_type != real_type() ||
+ new_field->charset != field_charset ||
+ new_field->pack_length != pack_length())
+ return IS_EQUAL_NO;
+
+ /*
+ Changing the definition of an ENUM or SET column by adding a new
+ enumeration or set members to the end of the list of valid member
+ values only alters table metadata and not table data.
+ */
+ if (typelib->count > values->count)
+ return IS_EQUAL_NO;
+
+ /* Check whether there are modification before the end. */
+ if (! compare_type_names(field_charset, typelib, new_field->interval))
+ return IS_EQUAL_NO;
+
+ return IS_EQUAL_YES;
}
@@ -9608,13 +9555,13 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
interval_list.empty();
comment= *fld_comment;
- vcol_info= fld_vcol_info;
stored_in_db= TRUE;
/* Initialize data for a computed field */
if ((uchar)fld_type == (uchar)MYSQL_TYPE_VIRTUAL)
{
DBUG_ASSERT(vcol_info && vcol_info->expr_item);
+ vcol_info= fld_vcol_info;
stored_in_db= vcol_info->is_stored();
/*
Walk through the Item tree checking if all items are valid
@@ -9634,6 +9581,8 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
*/
sql_type= fld_type= vcol_info->get_real_type();
}
+ else
+ vcol_info= NULL;
/*
Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and
@@ -9654,7 +9603,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
}
if (length == 0)
- fld_length= 0; /* purecov: inspected */
+ fld_length= NULL; /* purecov: inspected */
}
sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1;
@@ -9806,8 +9755,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
case MYSQL_TYPE_TIMESTAMP:
if (fld_length == NULL)
{
- /* Compressed date YYYYMMDDHHMMSS */
- length= MAX_DATETIME_COMPRESSED_WIDTH;
+ length= MAX_DATETIME_WIDTH;
}
else if (length != MAX_DATETIME_WIDTH)
{
@@ -9871,7 +9819,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
sql_type= MYSQL_TYPE_NEWDATE;
/* fall trough */
case MYSQL_TYPE_NEWDATE:
- length= 10;
+ length= MAX_DATE_WIDTH;
break;
case MYSQL_TYPE_TIME:
length= 10;
@@ -9952,6 +9900,17 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
DBUG_RETURN(TRUE);
}
+ switch (fld_type) {
+ case MYSQL_TYPE_DATE:
+ case MYSQL_TYPE_NEWDATE:
+ case MYSQL_TYPE_TIME:
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_TIMESTAMP:
+ charset= &my_charset_bin;
+ flags|= BINCMP_FLAG;
+ default: break;
+ }
+
DBUG_RETURN(FALSE); /* success */
}
diff --git a/sql/field.h b/sql/field.h
index b597da93c3c..5c36bf80252 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1,4 +1,4 @@
-/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+/* Copyright 2000-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
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
@@ -559,6 +559,13 @@ public:
/* maximum possible display length */
virtual uint32 max_display_length()= 0;
+ /**
+ Whether a field being created is compatible with a existing one.
+
+ Used by the ALTER TABLE code to evaluate whether the new definition
+ of a table is compatible with the old definition so that it can
+ determine if data needs to be copied over (table data change).
+ */
virtual uint is_equal(Create_field *new_field);
/* convert decimal to longlong with overflow check */
longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag,
@@ -690,15 +697,17 @@ protected:
handle_int64(to, from, low_byte_first_from, table->s->db_low_byte_first);
return from + sizeof(int64);
}
+
+ bool field_flags_are_binary()
+ {
+ return (flags & (BINCMP_FLAG | BINARY_FLAG)) != 0;
+ }
+
};
class Field_num :public Field {
public:
- /**
- The scale of the Field's value, i.e. the number of digits to the right
- of the decimal point.
- */
const uint8 dec;
bool zerofill,unsigned_flag; // Purify cannot handle bit fields
Field_num(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
@@ -749,7 +758,6 @@ public:
friend class Create_field;
my_decimal *val_decimal(my_decimal *);
virtual bool str_needs_quotes() { return TRUE; }
- bool compare_str_field_flags(Create_field *new_field, uint32 flags);
uint is_equal(Create_field *new_field);
};
@@ -857,11 +865,6 @@ public:
Field_new_decimal(uint32 len_arg, bool maybe_null_arg,
const char *field_name_arg, uint8 dec_arg,
bool unsigned_arg);
- /*
- Create a field to hold a decimal value from an item.
- Truncates the precision and/or scale if necessary.
- */
- static Field_new_decimal *new_decimal_field(const Item *item);
enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
Item_result result_type () const { return DECIMAL_RESULT; }
@@ -1364,12 +1367,12 @@ public:
Field_date(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
CHARSET_INFO *cs)
- :Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg,
+ :Field_str(ptr_arg, MAX_DATE_WIDTH, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, cs)
{}
Field_date(bool maybe_null_arg, const char *field_name_arg,
CHARSET_INFO *cs)
- :Field_str((uchar*) 0,10, maybe_null_arg ? (uchar*) "": 0,0,
+ :Field_str((uchar*) 0, MAX_DATE_WIDTH, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, cs) {}
enum_field_types type() const { return MYSQL_TYPE_DATE;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
@@ -1479,12 +1482,12 @@ public:
Field_datetime(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
CHARSET_INFO *cs)
- :Field_str(ptr_arg, 19, null_ptr_arg, null_bit_arg,
+ :Field_str(ptr_arg, MAX_DATETIME_WIDTH, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, cs)
{}
Field_datetime(bool maybe_null_arg, const char *field_name_arg,
CHARSET_INFO *cs)
- :Field_str((uchar*) 0,19, maybe_null_arg ? (uchar*) "": 0,0,
+ :Field_str((uchar*) 0, MAX_DATETIME_WIDTH, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, cs) {}
enum_field_types type() const { return MYSQL_TYPE_DATETIME;}
#ifdef HAVE_LONG_LONG
@@ -1949,7 +1952,6 @@ public:
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
private:
int do_save_field_metadata(uchar *first_byte);
- bool compare_enum_values(TYPELIB *values);
uint is_equal(Create_field *new_field);
};
@@ -2172,6 +2174,11 @@ public:
List<String> *interval_list, CHARSET_INFO *cs,
uint uint_geom_type,
Virtual_column_info *vcol_info);
+
+ bool field_flags_are_binary()
+ {
+ return (flags & (BINCMP_FLAG | BINARY_FLAG)) != 0;
+ }
};
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index c6b48c5b744..a3b04ca51da 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -5527,7 +5527,7 @@ int ha_ndbcluster::create(const char *name,
if (share && !do_event_op)
share->flags|= NSF_NO_BINLOG;
ndbcluster_log_schema_op(thd, share,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
share->db, share->table_name,
m_table->getObjectId(),
m_table->getObjectVersion(),
@@ -5969,7 +5969,8 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
*/
if (!is_old_table_tmpfile)
ndbcluster_log_schema_op(current_thd, share,
- current_thd->query, current_thd->query_length,
+ current_thd->query(),
+ current_thd->query_length(),
old_dbname, m_tabname,
ndb_table_id, ndb_table_version,
SOT_RENAME_TABLE,
@@ -6164,7 +6165,7 @@ retry_temporary_error1:
current_thd->lex->sql_command != SQLCOM_TRUNCATE)
{
ndbcluster_log_schema_op(thd, share,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
share->db, share->table_name,
ndb_table_id, ndb_table_version,
SOT_DROP_TABLE, 0, 0, 1);
@@ -6887,7 +6888,7 @@ static void ndbcluster_drop_database(handlerton *hton, char *path)
THD *thd= current_thd;
ha_ndbcluster::set_dbname(path, db);
ndbcluster_log_schema_op(thd, 0,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
db, "", 0, 0, SOT_DROP_DB, 0, 0, 0);
#endif
DBUG_VOID_RETURN;
@@ -9429,9 +9430,11 @@ ndb_util_thread_fail:
pthread_cond_signal(&COND_ndb_util_ready);
pthread_mutex_unlock(&LOCK_ndb_util_thread);
DBUG_PRINT("exit", ("ndb_util_thread"));
+
+ DBUG_LEAVE; // Must match DBUG_ENTER()
my_thread_end();
pthread_exit(0);
- DBUG_RETURN(NULL);
+ return NULL; // Avoid compiler warnings
}
/*
@@ -10254,13 +10257,13 @@ int ndbcluster_alter_tablespace(handlerton *hton,
#ifdef HAVE_NDB_BINLOG
if (is_tablespace)
ndbcluster_log_schema_op(thd, 0,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
"", alter_info->tablespace_name,
0, 0,
SOT_TABLESPACE, 0, 0, 0);
else
ndbcluster_log_schema_op(thd, 0,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
"", alter_info->logfile_group_name,
0, 0,
SOT_LOGFILE_GROUP, 0, 0, 0);
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index baca22dffc7..b24b17106c6 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -241,8 +241,8 @@ static void dbug_print_table(const char *info, TABLE *table)
static void run_query(THD *thd, char *buf, char *end,
const int *no_print_error, my_bool disable_binlog)
{
- ulong save_thd_query_length= thd->query_length;
- char *save_thd_query= thd->query;
+ ulong save_thd_query_length= thd->query_length();
+ char *save_thd_query= thd->query();
ulong save_thread_id= thd->variables.pseudo_thread_id;
struct system_status_var save_thd_status_var= thd->status_var;
THD_TRANS save_thd_transaction_all= thd->transaction.all;
@@ -259,12 +259,12 @@ static void run_query(THD *thd, char *buf, char *end,
if (disable_binlog)
thd->options&= ~OPTION_BIN_LOG;
- DBUG_PRINT("query", ("%s", thd->query));
+ DBUG_PRINT("query", ("%s", thd->query()));
DBUG_ASSERT(!thd->in_sub_stmt);
DBUG_ASSERT(!thd->prelocked_mode);
- mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
+ mysql_parse(thd, thd->query(), thd->query_length(), &found_semicolon);
if (no_print_error && thd->is_slave_error)
{
@@ -3665,9 +3665,11 @@ pthread_handler_t ndb_binlog_thread_func(void *arg)
ndb_binlog_thread_running= -1;
pthread_mutex_unlock(&injector_mutex);
pthread_cond_signal(&injector_cond);
+
+ DBUG_LEAVE; // Must match DBUG_ENTER()
my_thread_end();
pthread_exit(0);
- DBUG_RETURN(NULL);
+ return NULL; // Avoid compiler warnings
}
lex_start(thd);
@@ -4378,10 +4380,11 @@ err:
(void) pthread_cond_signal(&injector_cond);
DBUG_PRINT("exit", ("ndb_binlog_thread"));
- my_thread_end();
+ DBUG_LEAVE; // Must match DBUG_ENTER()
+ my_thread_end();
pthread_exit(0);
- DBUG_RETURN(NULL);
+ return NULL; // Avoid compiler warnings
}
bool
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index ccde0c45815..ebf8ad85410 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -239,6 +239,7 @@ void ha_partition::init_handler_variables()
m_curr_key_info[0]= NULL;
m_curr_key_info[1]= NULL;
is_clone= FALSE,
+ m_part_func_monotonicity_info= NON_MONOTONIC;
auto_increment_lock= FALSE;
auto_increment_safe_stmt_log_lock= FALSE;
/*
@@ -705,6 +706,7 @@ int ha_partition::rename_partitions(const char *path)
if (m_is_sub_partitioned)
{
List_iterator<partition_element> sub_it(part_elem->subpartitions);
+ j= 0;
do
{
sub_elem= sub_it++;
@@ -1278,10 +1280,10 @@ void ha_partition::cleanup_new_partition(uint part_count)
m_file= m_added_file;
m_added_file= NULL;
+ external_lock(ha_thd(), F_UNLCK);
/* delete_table also needed, a bit more complex */
close();
- m_added_file= m_file;
m_file= save_m_file;
}
DBUG_VOID_RETURN;
@@ -2464,11 +2466,18 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
}
}
+ /* Initialize the bitmap we use to minimize ha_start_bulk_insert calls */
+ if (bitmap_init(&m_bulk_insert_started, NULL, m_tot_parts + 1, FALSE))
+ DBUG_RETURN(1);
+ bitmap_clear_all(&m_bulk_insert_started);
/* Initialize the bitmap we use to determine what partitions are used */
if (!is_clone)
{
if (bitmap_init(&(m_part_info->used_partitions), NULL, m_tot_parts, TRUE))
+ {
+ bitmap_free(&m_bulk_insert_started);
DBUG_RETURN(1);
+ }
bitmap_set_all(&(m_part_info->used_partitions));
}
@@ -2552,12 +2561,18 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
calling open on all individual handlers.
*/
m_handler_status= handler_opened;
+ if (m_part_info->part_expr)
+ m_part_func_monotonicity_info=
+ m_part_info->part_expr->get_monotonicity_info();
+ else if (m_part_info->list_of_part_fields)
+ m_part_func_monotonicity_info= MONOTONIC_STRICT_INCREASING;
info(HA_STATUS_VARIABLE | HA_STATUS_CONST);
DBUG_RETURN(0);
err_handler:
while (file-- != m_file)
(*file)->close();
+ bitmap_free(&m_bulk_insert_started);
if (!is_clone)
bitmap_free(&(m_part_info->used_partitions));
@@ -2605,6 +2620,7 @@ int ha_partition::close(void)
DBUG_ASSERT(table->s == table_share);
delete_queue(&m_queue);
+ bitmap_free(&m_bulk_insert_started);
if (!is_clone)
bitmap_free(&(m_part_info->used_partitions));
file= m_file;
@@ -3021,10 +3037,12 @@ int ha_partition::write_row(uchar * buf)
}
m_last_part= part_id;
DBUG_PRINT("info", ("Insert in partition %d", part_id));
+ start_part_bulk_insert(thd, part_id);
+
tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */
error= m_file[part_id]->ha_write_row(buf);
if (have_auto_increment && !table->s->next_number_keypart)
- set_auto_increment_if_higher(table->next_number_field->val_int());
+ set_auto_increment_if_higher(table->next_number_field);
reenable_binlog(thd);
exit:
table->timestamp_field_type= orig_timestamp_type;
@@ -3083,6 +3101,7 @@ int ha_partition::update_row(const uchar *old_data, uchar *new_data)
}
m_last_part= new_part_id;
+ start_part_bulk_insert(thd, new_part_id);
if (new_part_id == old_part_id)
{
DBUG_PRINT("info", ("Update in partition %d", new_part_id));
@@ -3128,7 +3147,7 @@ exit:
HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data;
if (!ha_data->auto_inc_initialized)
info(HA_STATUS_AUTO);
- set_auto_increment_if_higher(table->found_next_number_field->val_int());
+ set_auto_increment_if_higher(table->found_next_number_field);
}
table->timestamp_field_type= orig_timestamp_type;
DBUG_RETURN(error);
@@ -3247,23 +3266,112 @@ int ha_partition::delete_all_rows()
DESCRIPTION
rows == 0 means we will probably insert many rows
*/
-
void ha_partition::start_bulk_insert(ha_rows rows)
{
- handler **file;
DBUG_ENTER("ha_partition::start_bulk_insert");
- rows= rows ? rows/m_tot_parts + 1 : 0;
- file= m_file;
- do
- {
- (*file)->ha_start_bulk_insert(rows);
- } while (*(++file));
+ m_bulk_inserted_rows= 0;
+ bitmap_clear_all(&m_bulk_insert_started);
+ /* use the last bit for marking if bulk_insert_started was called */
+ bitmap_set_bit(&m_bulk_insert_started, m_tot_parts);
DBUG_VOID_RETURN;
}
/*
+ Check if start_bulk_insert has been called for this partition,
+ if not, call it and mark it called
+*/
+void ha_partition::start_part_bulk_insert(THD *thd, uint part_id)
+{
+ long old_buffer_size;
+ if (!bitmap_is_set(&m_bulk_insert_started, part_id) &&
+ bitmap_is_set(&m_bulk_insert_started, m_tot_parts))
+ {
+ old_buffer_size= thd->variables.read_buff_size;
+ /* Update read_buffer_size for this partition */
+ thd->variables.read_buff_size= estimate_read_buffer_size(old_buffer_size);
+ m_file[part_id]->ha_start_bulk_insert(guess_bulk_insert_rows());
+ bitmap_set_bit(&m_bulk_insert_started, part_id);
+ thd->variables.read_buff_size= old_buffer_size;
+ }
+ m_bulk_inserted_rows++;
+}
+
+/*
+ Estimate the read buffer size for each partition.
+ SYNOPSIS
+ ha_partition::estimate_read_buffer_size()
+ original_size read buffer size originally set for the server
+ RETURN VALUE
+ estimated buffer size.
+ DESCRIPTION
+ If the estimated number of rows to insert is less than 10 (but not 0)
+ the new buffer size is same as original buffer size.
+ In case of first partition of when partition function is monotonic
+ new buffer size is same as the original buffer size.
+ For rest of the partition total buffer of 10*original_size is divided
+ equally if number of partition is more than 10 other wise each partition
+ will be allowed to use original buffer size.
+*/
+long ha_partition::estimate_read_buffer_size(long original_size)
+{
+ /*
+ If number of rows to insert is less than 10, but not 0,
+ return original buffer size.
+ */
+ if (estimation_rows_to_insert && (estimation_rows_to_insert < 10))
+ return (original_size);
+ /*
+ If first insert/partition and monotonic partition function,
+ allow using buffer size originally set.
+ */
+ if (!m_bulk_inserted_rows &&
+ m_part_func_monotonicity_info != NON_MONOTONIC &&
+ m_tot_parts > 1)
+ return original_size;
+ /*
+ Allow total buffer used in all partition to go up to 10*read_buffer_size.
+ 11*read_buffer_size in case of monotonic partition function.
+ */
+
+ if (m_tot_parts < 10)
+ return original_size;
+ return (original_size * 10 / m_tot_parts);
+}
+
+/*
+ Try to predict the number of inserts into this partition.
+
+ If less than 10 rows (including 0 which means Unknown)
+ just give that as a guess
+ If monotonic partitioning function was used
+ guess that 50 % of the inserts goes to the first partition
+ For all other cases, guess on equal distribution between the partitions
+*/
+ha_rows ha_partition::guess_bulk_insert_rows()
+{
+ DBUG_ENTER("guess_bulk_insert_rows");
+
+ if (estimation_rows_to_insert < 10)
+ DBUG_RETURN(estimation_rows_to_insert);
+
+ /* If first insert/partition and monotonic partition function, guess 50%. */
+ if (!m_bulk_inserted_rows &&
+ m_part_func_monotonicity_info != NON_MONOTONIC &&
+ m_tot_parts > 1)
+ DBUG_RETURN(estimation_rows_to_insert / 2);
+
+ /* Else guess on equal distribution (+1 is to avoid returning 0/Unknown) */
+ if (m_bulk_inserted_rows < estimation_rows_to_insert)
+ DBUG_RETURN(((estimation_rows_to_insert - m_bulk_inserted_rows)
+ / m_tot_parts) + 1);
+ /* The estimation was wrong, must say 'Unknown' */
+ DBUG_RETURN(0);
+}
+
+
+/*
Finish a large batch of insert rows
SYNOPSIS
@@ -3273,21 +3381,29 @@ void ha_partition::start_bulk_insert(ha_rows rows)
RETURN VALUE
>0 Error code
0 Success
+
+ Note: end_bulk_insert can be called without start_bulk_insert
+ being called, see bug¤44108.
+
*/
int ha_partition::end_bulk_insert(bool abort)
{
int error= 0;
- handler **file;
+ uint i;
DBUG_ENTER("ha_partition::end_bulk_insert");
- file= m_file;
- do
+ if (!bitmap_is_set(&m_bulk_insert_started, m_tot_parts))
+ DBUG_RETURN(error);
+
+ for (i= 0; i < m_tot_parts; i++)
{
int tmp;
- if ((tmp= (*file)->ha_end_bulk_insert(abort)))
+ if (bitmap_is_set(&m_bulk_insert_started, i) &&
+ (tmp= m_file[i]->ha_end_bulk_insert(abort)))
error= tmp;
- } while (*(++file));
+ }
+ bitmap_clear_all(&m_bulk_insert_started);
DBUG_RETURN(error);
}
@@ -4935,8 +5051,9 @@ int ha_partition::info(uint flag)
If the handler doesn't support statistics, it should set all of the
above to 0.
- We will allow the first handler to set the rec_per_key and use
- this as an estimate on the total table.
+ We first scans through all partitions to get the one holding most rows.
+ We will then allow the handler with the most rows to set
+ the rec_per_key and use this as an estimate on the total table.
max_data_file_length: Maximum data file length
We ignore it, is only used in
@@ -4948,14 +5065,33 @@ int ha_partition::info(uint flag)
ref_length: We set this to the value calculated
and stored in local object
create_time: Creation time of table
- Set by first handler
- So we calculate these constants by using the variables on the first
- handler.
+ So we calculate these constants by using the variables from the
+ handler with most rows.
*/
- handler *file;
+ handler *file, **file_array;
+ ulonglong max_records= 0;
+ uint32 i= 0;
+ uint32 handler_instance= 0;
+
+ file_array= m_file;
+ do
+ {
+ file= *file_array;
+ /* Get variables if not already done */
+ if (!(flag & HA_STATUS_VARIABLE) ||
+ !bitmap_is_set(&(m_part_info->used_partitions),
+ (file_array - m_file)))
+ file->info(HA_STATUS_VARIABLE);
+ if (file->stats.records > max_records)
+ {
+ max_records= file->stats.records;
+ handler_instance= i;
+ }
+ i++;
+ } while (*(++file_array));
- file= m_file[0];
+ file= m_file[handler_instance];
file->info(HA_STATUS_CONST);
stats.create_time= file->stats.create_time;
ref_length= m_ref_length;
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index d52cb4ba5b0..7b2e72bd9db 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -176,6 +176,11 @@ private:
This to ensure it will work with statement based replication.
*/
bool auto_increment_safe_stmt_log_lock;
+ /** For optimizing ha_start_bulk_insert calls */
+ MY_BITMAP m_bulk_insert_started;
+ ha_rows m_bulk_inserted_rows;
+ /** used for prediction of start_bulk_insert rows */
+ enum_monotonicity_info m_part_func_monotonicity_info;
public:
handler *clone(MEM_ROOT *mem_root);
virtual void set_part_info(partition_info *part_info)
@@ -354,7 +359,6 @@ public:
Bulk inserts are supported if all underlying handlers support it.
start_bulk_insert and end_bulk_insert is called before and after a
number of calls to write_row.
- Not yet though.
*/
virtual int write_row(uchar * buf);
virtual int update_row(const uchar * old_data, uchar * new_data);
@@ -362,6 +366,11 @@ public:
virtual int delete_all_rows(void);
virtual void start_bulk_insert(ha_rows rows);
virtual int end_bulk_insert(bool);
+private:
+ ha_rows guess_bulk_insert_rows();
+ void start_part_bulk_insert(THD *thd, uint part_id);
+ long estimate_read_buffer_size(long original_size);
+public:
virtual bool is_fatal_error(int error, uint flags)
{
@@ -765,10 +774,10 @@ public:
if (m_handler_status < handler_initialized ||
m_handler_status >= handler_closed)
DBUG_RETURN(PARTITION_ENABLED_TABLE_FLAGS);
- else
- DBUG_RETURN((m_file[0]->ha_table_flags() &
- ~(PARTITION_DISABLED_TABLE_FLAGS)) |
- (PARTITION_ENABLED_TABLE_FLAGS));
+
+ DBUG_RETURN((m_file[0]->ha_table_flags() &
+ ~(PARTITION_DISABLED_TABLE_FLAGS)) |
+ (PARTITION_ENABLED_TABLE_FLAGS));
}
/*
@@ -937,9 +946,11 @@ private:
auto_increment_lock= FALSE;
}
}
- virtual void set_auto_increment_if_higher(const ulonglong nr)
+ virtual void set_auto_increment_if_higher(Field *field)
{
HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data;
+ ulonglong nr= (((Field_num*) field)->unsigned_flag ||
+ field->val_int() > 0) ? field->val_int() : 0;
lock_auto_increment();
DBUG_ASSERT(ha_data->auto_inc_initialized == TRUE);
/* must check when the mutex is taken */
diff --git a/sql/handler.cc b/sql/handler.cc
index 3ff9a63b76e..d511aa154ce 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1317,7 +1317,8 @@ int ha_rollback_trans(THD *thd, bool all)
}
trans->ha_list= 0;
trans->no_2pc=0;
- if (is_real_trans && thd->transaction_rollback_request)
+ if (is_real_trans && thd->transaction_rollback_request &&
+ thd->transaction.xid_state.xa_state != XA_NOTR)
thd->transaction.xid_state.rm_error= thd->main_da.sql_errno();
if (all)
thd->variables.tx_isolation=thd->session_tx_isolation;
@@ -1891,12 +1892,42 @@ bool ha_flush_logs(handlerton *db_type)
return FALSE;
}
+
+/**
+ @brief make canonical filename
+
+ @param[in] file table handler
+ @param[in] path original path
+ @param[out] tmp_path buffer for canonized path
+
+ @details Lower case db name and table name path parts for
+ non file based tables when lower_case_table_names
+ is 2 (store as is, compare in lower case).
+ Filesystem path prefix (mysql_data_home or tmpdir)
+ is left intact.
+
+ @note tmp_path may be left intact if no conversion was
+ performed.
+
+ @retval canonized path
+
+ @todo This may be done more efficiently when table path
+ gets built. Convert this function to something like
+ ASSERT_CANONICAL_FILENAME.
+*/
const char *get_canonical_filename(handler *file, const char *path,
char *tmp_path)
{
+ uint i;
if (lower_case_table_names != 2 || (file->ha_table_flags() & HA_FILE_BASED))
return path;
+ for (i= 0; i <= mysql_tmpdir_list.max; i++)
+ {
+ if (is_prefix(path, mysql_tmpdir_list.list[i]))
+ return path;
+ }
+
/* Ensure that table handler get path in lower case */
if (tmp_path != path)
strmov(tmp_path, path);
@@ -3483,14 +3514,10 @@ int handler::index_next_same(uchar *buf, const uchar *key, uint keylen)
if (!(error=index_next(buf)))
{
my_ptrdiff_t ptrdiff= buf - table->record[0];
- uchar *save_record_0;
- KEY *key_info;
- KEY_PART_INFO *key_part;
- KEY_PART_INFO *key_part_end;
- LINT_INIT(save_record_0);
- LINT_INIT(key_info);
- LINT_INIT(key_part);
- LINT_INIT(key_part_end);
+ uchar *UNINIT_VAR(save_record_0);
+ KEY *UNINIT_VAR(key_info);
+ KEY_PART_INFO *UNINIT_VAR(key_part);
+ KEY_PART_INFO *UNINIT_VAR(key_part_end);
/*
key_cmp_if_same() compares table->record[0] against 'key'.
diff --git a/sql/handler.h b/sql/handler.h
index cfea6175733..61ff5fca565 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -402,7 +402,6 @@ struct xid_t {
my_xid get_my_xid()
{
return gtrid_length == MYSQL_XID_GTRID_LEN && bqual_length == 0 &&
- !memcmp(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id)) &&
!memcmp(data, MYSQL_XID_PREFIX, MYSQL_XID_PREFIX_LEN) ?
quick_get_my_xid() : 0;
}
@@ -925,6 +924,15 @@ typedef struct st_ha_create_information
ulong key_block_size;
SQL_LIST merge_list;
handlerton *db_type;
+ /**
+ Row type of the table definition.
+
+ Defaults to ROW_TYPE_DEFAULT for all non-ALTER statements.
+ For ALTER TABLE defaults to ROW_TYPE_NOT_USED (means "keep the current").
+
+ Can be changed either explicitly by the parser.
+ If nothing speficied inherits the value of the original table (if present).
+ */
enum row_type row_type;
uint null_bits; /* NULL bits at start of record */
uint options; /* OR of HA_CREATE_ options */
diff --git a/sql/item.cc b/sql/item.cc
index f1025fa2c9c..36918a0804e 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -433,26 +433,17 @@ Item::Item(THD *thd, Item *item):
}
-/**
- Decimal precision of the item.
-
- @remark The precision must not be capped as it can be used in conjunction
- with Item::decimals to determine the size of the integer part when
- constructing a decimal data type.
-
- @see Item::decimal_int_part()
- @see Item::decimals
-*/
-
uint Item::decimal_precision() const
{
- uint precision= max_length;
Item_result restype= result_type();
if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT))
- precision= my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
-
- return precision;
+ {
+ uint prec=
+ my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
+ return min(prec, DECIMAL_MAX_PRECISION);
+ }
+ return min(max_length, DECIMAL_MAX_PRECISION);
}
@@ -4947,7 +4938,9 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length)
switch (field_type()) {
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
- field= Field_new_decimal::new_decimal_field(this);
+ field= new Field_new_decimal((uchar*) 0, max_length, null_ptr, 0,
+ Field::NONE, name, decimals, 0,
+ unsigned_flag);
break;
case MYSQL_TYPE_TINY:
field= new Field_tiny((uchar*) 0, max_length, null_ptr, 0, Field::NONE,
@@ -6370,9 +6363,26 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
/* view fild reference must be defined */
DBUG_ASSERT(*ref);
/* (*ref)->check_cols() will be made in Item_direct_ref::fix_fields */
- if (!(*ref)->fixed &&
- ((*ref)->fix_fields(thd, ref)))
+ if ((*ref)->fixed)
+ {
+ Item *ref_item= (*ref)->real_item();
+ if (ref_item->type() == Item::FIELD_ITEM)
+ {
+ /*
+ In some cases we need to update table read set(see bug#47150).
+ If ref item is FIELD_ITEM and fixed then field and table
+ have proper values. So we can use them for update.
+ */
+ Field *fld= ((Item_field*) ref_item)->field;
+ DBUG_ASSERT(fld && fld->table);
+ if (thd->mark_used_columns == MARK_COLUMNS_READ)
+ bitmap_set_bit(fld->table->read_set, fld->field_index);
+ }
+ }
+ else if (!(*ref)->fixed &&
+ ((*ref)->fix_fields(thd, ref)))
return TRUE;
+
return Item_direct_ref::fix_fields(thd, reference);
}
@@ -6888,52 +6898,61 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
}
/**
- Compare the value stored in field, with the original item.
+ Compare the value stored in field with the expression from the query.
- @param field field which the item is converted and stored in
- @param item original item
+ @param field Field which the Item is stored in after conversion
+ @param item Original expression from query
- @return Return an integer greater than, equal to, or less than 0 if
- the value stored in the field is greater than, equal to,
- or less than the original item
+ @return Returns an integer greater than, equal to, or less than 0 if
+ the value stored in the field is greater than, equal to,
+ or less than the original Item. A 0 may also be returned if
+ out of memory.
@note We only use this on the range optimizer/partition pruning,
because in some cases we can't store the value in the field
without some precision/character loss.
*/
-int stored_field_cmp_to_item(Field *field, Item *item)
+int stored_field_cmp_to_item(THD *thd, Field *field, Item *item)
{
-
Item_result res_type=item_cmp_type(field->result_type(),
item->result_type());
if (res_type == STRING_RESULT)
{
char item_buff[MAX_FIELD_WIDTH];
char field_buff[MAX_FIELD_WIDTH];
- String item_tmp(item_buff,sizeof(item_buff),&my_charset_bin),*item_result;
+
+ String item_tmp(item_buff,sizeof(item_buff),&my_charset_bin);
String field_tmp(field_buff,sizeof(field_buff),&my_charset_bin);
- enum_field_types field_type;
- item_result=item->val_str(&item_tmp);
+ String *item_result= item->val_str(&item_tmp);
+ /*
+ Some implementations of Item::val_str(String*) actually modify
+ the field Item::null_value, hence we can't check it earlier.
+ */
if (item->null_value)
return 0;
- field->val_str(&field_tmp);
+ String *field_result= field->val_str(&field_tmp);
- /*
- If comparing DATE with DATETIME, append the time-part to the DATE.
- So that the strings are equally formatted.
- A DATE converted to string is 10 characters, and a DATETIME converted
- to string is 19 characters.
- */
- field_type= field->type();
- if (field_type == MYSQL_TYPE_DATE &&
- item_result->length() == 19)
- field_tmp.append(" 00:00:00");
- else if (field_type == MYSQL_TYPE_DATETIME &&
- item_result->length() == 10)
- item_result->append(" 00:00:00");
-
- return stringcmp(&field_tmp,item_result);
+ enum_field_types field_type= field->type();
+
+ if (field_type == MYSQL_TYPE_DATE || field_type == MYSQL_TYPE_DATETIME)
+ {
+ enum_mysql_timestamp_type type= MYSQL_TIMESTAMP_ERROR;
+
+ if (field_type == MYSQL_TYPE_DATE)
+ type= MYSQL_TIMESTAMP_DATE;
+
+ if (field_type == MYSQL_TYPE_DATETIME)
+ type= MYSQL_TIMESTAMP_DATETIME;
+
+ const char *field_name= field->field_name;
+ MYSQL_TIME field_time, item_time;
+ get_mysql_time_from_str(thd, field_result, type, field_name, &field_time);
+ get_mysql_time_from_str(thd, item_result, type, field_name, &item_time);
+
+ return my_time_compare(&field_time, &item_time);
+ }
+ return stringcmp(field_result, item_result);
}
if (res_type == INT_RESULT)
return 0; // Both are of type int
diff --git a/sql/item.h b/sql/item.h
index 82fb3f3a3e0..aeec1e92b4e 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -784,10 +784,9 @@ public:
virtual cond_result eq_cmp_result() const { return COND_OK; }
inline uint float_length(uint decimals_par) const
{ return decimals != NOT_FIXED_DEC ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
- /** Returns the uncapped decimal precision of this item. */
virtual uint decimal_precision() const;
inline int decimal_int_part() const
- { return decimal_precision() - decimals; }
+ { return my_decimal_int_part(decimal_precision(), decimals); }
/*
Returns true if this is constant (during query execution, i.e. its value
will not change until next fix_fields) and its value is known.
@@ -3263,4 +3262,4 @@ void mark_select_range_as_dependent(THD *thd,
extern Cached_item *new_Cached_item(THD *thd, Item *item);
extern Item_result item_cmp_type(Item_result a,Item_result b);
extern void resolve_const_item(THD *thd, Item **ref, Item *cmp_item);
-extern int stored_field_cmp_to_item(Field *field, Item *item);
+extern int stored_field_cmp_to_item(THD *thd, Field *field, Item *item);
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index d351fe7d7dc..1844c14a07e 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -189,6 +189,7 @@ enum_field_types agg_field_type(Item **items, uint nitems)
collect_cmp_types()
items Array of items to collect types from
nitems Number of items in the array
+ skip_nulls Don't collect types of NULL items if TRUE
DESCRIPTION
This function collects different result types for comparison of the first
@@ -199,7 +200,7 @@ enum_field_types agg_field_type(Item **items, uint nitems)
Bitmap of collected types - otherwise
*/
-static uint collect_cmp_types(Item **items, uint nitems)
+static uint collect_cmp_types(Item **items, uint nitems, bool skip_nulls= FALSE)
{
uint i;
uint found_types;
@@ -208,6 +209,8 @@ static uint collect_cmp_types(Item **items, uint nitems)
found_types= 0;
for (i= 1; i < nitems ; i++)
{
+ if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
+ continue; // Skip NULL constant items
if ((left_result == ROW_RESULT ||
items[i]->result_type() == ROW_RESULT) &&
cmp_row_type(items[0], items[i]))
@@ -215,6 +218,12 @@ static uint collect_cmp_types(Item **items, uint nitems)
found_types|= 1<< (uint)item_cmp_type(left_result,
items[i]->result_type());
}
+ /*
+ Even if all right-hand items are NULLs and we are skipping them all, we need
+ at least one type bit in the found_type bitmask.
+ */
+ if (skip_nulls && !found_types)
+ found_types= 1 << (uint)left_result;
return found_types;
}
@@ -627,56 +636,51 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
return 0;
}
-
/**
- @brief Convert date provided in a string to the int representation.
-
- @param[in] thd thread handle
- @param[in] str a string to convert
- @param[in] warn_type type of the timestamp for issuing the warning
- @param[in] warn_name field name for issuing the warning
- @param[out] error_arg could not extract a DATE or DATETIME
-
- @details Convert date provided in the string str to the int
- representation. If the string contains wrong date or doesn't
- contain it at all then a warning is issued. The warn_type and
- the warn_name arguments are used as the name and the type of the
- field when issuing the warning. If any input was discarded
- (trailing or non-timestampy characters), was_cut will be non-zero.
- was_type will return the type str_to_datetime() could correctly
- extract.
-
- @return
- converted value. 0 on error and on zero-dates -- check 'failure'
+ Parse date provided in a string to a MYSQL_TIME.
+
+ @param[in] thd Thread handle
+ @param[in] str A string to convert
+ @param[in] warn_type Type of the timestamp for issuing the warning
+ @param[in] warn_name Field name for issuing the warning
+ @param[out] l_time The MYSQL_TIME objects is initialized.
+
+ Parses a date provided in the string str into a MYSQL_TIME object. If the
+ string contains an incorrect date or doesn't correspond to a date at all
+ then a warning is issued. The warn_type and the warn_name arguments are used
+ as the name and the type of the field when issuing the warning. If any input
+ was discarded (trailing or non-timestamp-y characters), return value will be
+ TRUE.
+
+ @return Status flag
+ @retval FALSE Success.
+ @retval True Indicates failure.
*/
-static ulonglong
-get_date_from_str(THD *thd, String *str, timestamp_type warn_type,
- char *warn_name, bool *error_arg)
+bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
+ const char *warn_name, MYSQL_TIME *l_time)
{
- ulonglong value= 0;
+ bool value;
int error;
- MYSQL_TIME l_time;
- enum_mysql_timestamp_type ret;
+ enum_mysql_timestamp_type timestamp_type;
- ret= str_to_datetime(str->ptr(), str->length(), &l_time,
- (TIME_FUZZY_DATE | MODE_INVALID_DATES |
- (thd->variables.sql_mode &
- (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))),
- &error);
+ timestamp_type=
+ str_to_datetime(str->ptr(), str->length(), l_time,
+ (TIME_FUZZY_DATE | MODE_INVALID_DATES |
+ (thd->variables.sql_mode &
+ (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))),
+ &error);
- if (ret == MYSQL_TIMESTAMP_DATETIME || ret == MYSQL_TIMESTAMP_DATE)
- {
+ if (timestamp_type == MYSQL_TIMESTAMP_DATETIME ||
+ timestamp_type == MYSQL_TIMESTAMP_DATE)
/*
Do not return yet, we may still want to throw a "trailing garbage"
warning.
*/
- *error_arg= FALSE;
- value= TIME_to_ulonglong_datetime(&l_time);
- }
+ value= FALSE;
else
{
- *error_arg= TRUE;
+ value= TRUE;
error= 1; /* force warning */
}
@@ -689,6 +693,37 @@ get_date_from_str(THD *thd, String *str, timestamp_type warn_type,
}
+/**
+ @brief Convert date provided in a string to the int representation.
+
+ @param[in] thd thread handle
+ @param[in] str a string to convert
+ @param[in] warn_type type of the timestamp for issuing the warning
+ @param[in] warn_name field name for issuing the warning
+ @param[out] error_arg could not extract a DATE or DATETIME
+
+ @details Convert date provided in the string str to the int
+ representation. If the string contains wrong date or doesn't
+ contain it at all then a warning is issued. The warn_type and
+ the warn_name arguments are used as the name and the type of the
+ field when issuing the warning.
+
+ @return
+ converted value. 0 on error and on zero-dates -- check 'failure'
+*/
+static ulonglong get_date_from_str(THD *thd, String *str,
+ timestamp_type warn_type,
+ const char *warn_name, bool *error_arg)
+{
+ MYSQL_TIME l_time;
+ *error_arg= get_mysql_time_from_str(thd, str, warn_type, warn_name, &l_time);
+
+ if (*error_arg)
+ return 0;
+ return TIME_to_ulonglong_datetime(&l_time);
+}
+
+
/*
Check whether compare_datetime() can be used to compare items.
@@ -1549,61 +1584,73 @@ longlong Item_in_optimizer::val_int()
if (cache->null_value)
{
+ /*
+ We're evaluating
+ "<outer_value_list> [NOT] IN (SELECT <inner_value_list>...)"
+ where one or more of the outer values is NULL.
+ */
if (((Item_in_subselect*)args[1])->is_top_level_item())
{
/*
- We're evaluating "NULL IN (SELECT ...)". The result can be NULL or
- FALSE, and we can return one instead of another. Just return NULL.
+ We're evaluating a top level item, e.g.
+ "<outer_value_list> IN (SELECT <inner_value_list>...)",
+ and in this case a NULL value in the outer_value_list means
+ that the result shall be NULL/FALSE (makes no difference for
+ top level items). The cached value is NULL, so just return
+ NULL.
*/
null_value= 1;
}
else
{
- if (!((Item_in_subselect*)args[1])->is_correlated &&
- result_for_null_param != UNKNOWN)
+ /*
+ We're evaluating an item where a NULL value in either the
+ outer or inner value list does not automatically mean that we
+ can return NULL/FALSE. An example of such a query is
+ "<outer_value_list> NOT IN (SELECT <inner_value_list>...)"
+ The result when there is at least one NULL value is: NULL if the
+ SELECT evaluated over the non-NULL values produces at least
+ one row, FALSE otherwise
+ */
+ Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
+ bool all_left_cols_null= true;
+ const uint ncols= cache->cols();
+
+ /*
+ Turn off the predicates that are based on column compares for
+ which the left part is currently NULL
+ */
+ for (uint i= 0; i < ncols; i++)
{
- /* Use cached value from previous execution */
- null_value= result_for_null_param;
+ if (cache->element_index(i)->null_value)
+ item_subs->set_cond_guard_var(i, FALSE);
+ else
+ all_left_cols_null= false;
}
- else
+
+ if (!((Item_in_subselect*)args[1])->is_correlated &&
+ all_left_cols_null && result_for_null_param != UNKNOWN)
{
- /*
- We're evaluating "NULL IN (SELECT ...)". The result is:
- FALSE if SELECT produces an empty set, or
- NULL otherwise.
- We disable the predicates we've pushed down into subselect, run the
- subselect and see if it has produced any rows.
+ /*
+ This is a non-correlated subquery, all values in the outer
+ value list are NULL, and we have already evaluated the
+ subquery for all NULL values: Return the same result we
+ did last time without evaluating the subquery.
*/
- Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
- if (cache->cols() == 1)
- {
- item_subs->set_cond_guard_var(0, FALSE);
- (void) args[1]->val_bool_result();
- result_for_null_param= null_value= !item_subs->engine->no_rows();
- item_subs->set_cond_guard_var(0, TRUE);
- }
- else
- {
- uint i;
- uint ncols= cache->cols();
- /*
- Turn off the predicates that are based on column compares for
- which the left part is currently NULL
- */
- for (i= 0; i < ncols; i++)
- {
- if (cache->element_index(i)->null_value)
- item_subs->set_cond_guard_var(i, FALSE);
- }
-
- (void) args[1]->val_bool_result();
- result_for_null_param= null_value= !item_subs->engine->no_rows();
-
- /* Turn all predicates back on */
- for (i= 0; i < ncols; i++)
- item_subs->set_cond_guard_var(i, TRUE);
- }
+ null_value= result_for_null_param;
+ }
+ else
+ {
+ /* The subquery has to be evaluated */
+ (void) args[1]->val_bool_result();
+ null_value= !item_subs->engine->no_rows();
+ if (all_left_cols_null)
+ result_for_null_param= null_value;
}
+
+ /* Turn all predicates back on */
+ for (uint i= 0; i < ncols; i++)
+ item_subs->set_cond_guard_var(i, TRUE);
}
return 0;
}
@@ -2181,7 +2228,7 @@ uint Item_func_ifnull::decimal_precision() const
int arg1_int_part= args[1]->decimal_int_part();
int max_int_part= max(arg0_int_part, arg1_int_part);
int precision= max_int_part + decimals;
- return precision;
+ return min(precision, DECIMAL_MAX_PRECISION);
}
@@ -2365,7 +2412,7 @@ uint Item_func_if::decimal_precision() const
int arg1_prec= args[1]->decimal_int_part();
int arg2_prec= args[2]->decimal_int_part();
int precision=max(arg1_prec,arg2_prec) + decimals;
- return precision;
+ return min(precision, DECIMAL_MAX_PRECISION);
}
@@ -2782,7 +2829,7 @@ uint Item_func_case::decimal_precision() const
if (else_expr_num != -1)
set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
- return max_int_part + decimals;
+ return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
}
@@ -3523,7 +3570,7 @@ void Item_func_in::fix_length_and_dec()
uint type_cnt= 0, i;
Item_result cmp_type= STRING_RESULT;
left_result_type= args[0]->result_type();
- if (!(found_types= collect_cmp_types(args, arg_count)))
+ if (!(found_types= collect_cmp_types(args, arg_count, true)))
return;
for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
@@ -3701,9 +3748,11 @@ void Item_func_in::fix_length_and_dec()
uint j=0;
for (uint i=1 ; i < arg_count ; i++)
{
- array->set(j,args[i]);
if (!args[i]->null_value) // Skip NULL values
+ {
+ array->set(j,args[i]);
j++;
+ }
else
have_null= 1;
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 23f505182dd..618167a2bd0 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1722,3 +1722,6 @@ inline Item *and_conds(Item *a, Item *b)
}
Item *and_expressions(Item *a, Item *b, Item **org_item);
+
+bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
+ const char *warn_name, MYSQL_TIME *l_time);
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 90745e0fbe5..7dbf07ab86f 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -435,8 +435,7 @@ bool Item_func::eq(const Item *item, bool binary_cmp) const
Field *Item_func::tmp_table_field(TABLE *table)
{
- Field *field;
- LINT_INIT(field);
+ Field *field= NULL;
switch (result_type()) {
case INT_RESULT:
@@ -451,8 +450,45 @@ Field *Item_func::tmp_table_field(TABLE *table)
case STRING_RESULT:
return make_string_field(table);
case DECIMAL_RESULT:
- field= Field_new_decimal::new_decimal_field(this);
+ {
+ uint8 dec= decimals;
+ uint8 intg= decimal_precision() - dec;
+ uint32 len= max_length;
+
+ /*
+ Trying to put too many digits overall in a DECIMAL(prec,dec)
+ will always throw a warning. We must limit dec to
+ DECIMAL_MAX_SCALE however to prevent an assert() later.
+ */
+
+ if (dec > 0)
+ {
+ int overflow;
+
+ dec= min(dec, DECIMAL_MAX_SCALE);
+
+ /*
+ If the value still overflows the field with the corrected dec,
+ we'll throw out decimals rather than integers. This is still
+ bad and of course throws a truncation warning.
+ */
+
+ const int required_length=
+ my_decimal_precision_to_length(intg + dec, dec,
+ unsigned_flag);
+
+ overflow= required_length - len;
+
+ if (overflow > 0)
+ dec= max(0, dec - overflow); // too long, discard fract
+ else
+ /* Corrected value fits. */
+ len= required_length;
+ }
+
+ field= new Field_new_decimal(len, maybe_null, name, dec, unsigned_flag);
break;
+ }
case ROW_RESULT:
default:
// This case should never be chosen
@@ -4259,9 +4295,8 @@ void Item_func_set_user_var::save_item_result(Item *item)
bool
Item_func_set_user_var::update()
{
- bool res;
+ bool res= 0;
DBUG_ENTER("Item_func_set_user_var::update");
- LINT_INIT(res);
switch (cached_result_type) {
case REAL_RESULT:
@@ -4764,19 +4799,6 @@ void Item_func_get_user_var::fix_length_and_dec()
}
-uint Item_func_get_user_var::decimal_precision() const
-{
- uint precision= max_length;
- Item_result restype= result_type();
-
- /* Default to maximum as the precision is unknown a priori. */
- if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT))
- precision= DECIMAL_MAX_PRECISION;
-
- return precision;
-}
-
-
bool Item_func_get_user_var::const_item() const
{
return (!var_entry || current_thd->query_id != var_entry->update_query_id);
diff --git a/sql/item_func.h b/sql/item_func.h
index 46ca2187558..8231963dfd8 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1431,7 +1431,6 @@ public:
table_map used_tables() const
{ return const_item() ? 0 : RAND_TABLE_BIT; }
bool eq(const Item *item, bool binary_cmp) const;
- uint decimal_precision() const;
private:
bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index a34204b7181..3c5990eb359 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -84,7 +84,9 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
if (args[0]->field_type() == MYSQL_TYPE_GEOMETRY)
{
- return args[0]->val_str(str);
+ String *str_ret= args[0]->val_str(str);
+ null_value= args[0]->null_value;
+ return str_ret;
}
wkb= args[0]->val_str(&arg_val);
@@ -94,7 +96,10 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
str->set_charset(&my_charset_bin);
if (str->reserve(SRID_SIZE, 512))
- return 0;
+ {
+ null_value= TRUE; /* purecov: inspected */
+ return 0; /* purecov: inspected */
+ }
str->length(0);
str->q_append(srid);
if ((null_value=
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 8efc3c98328..5e2c161bbe2 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -632,6 +632,7 @@ String *Item_func_concat_ws::val_str(String *str)
String tmp_sep_str(tmp_str_buff, sizeof(tmp_str_buff),default_charset_info),
*sep_str, *res, *res2,*use_as_buff;
uint i;
+ bool is_const= 0;
null_value=0;
if (!(sep_str= args[0]->val_str(&tmp_sep_str)))
@@ -645,7 +646,11 @@ String *Item_func_concat_ws::val_str(String *str)
// If not, return the empty string
for (i=1; i < arg_count; i++)
if ((res= args[i]->val_str(str)))
+ {
+ is_const= args[i]->const_item() || !args[i]->used_tables();
break;
+ }
+
if (i == arg_count)
return &my_empty_string;
@@ -663,7 +668,7 @@ String *Item_func_concat_ws::val_str(String *str)
current_thd->variables.max_allowed_packet);
goto null;
}
- if (res->alloced_length() >=
+ if (!is_const && res->alloced_length() >=
res->length() + sep_str->length() + res2->length())
{ // Use old buffer
res->append(*sep_str); // res->length() > 0 always
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 38b47a244cb..cc5021612bf 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -159,17 +159,14 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
return TRUE;
in_fix_fields++;
- res= engine->prepare();
- // all transformation is done (used by prepared statements)
- changed= 1;
-
- if (!res)
+ if (!(res= engine->prepare()))
{
+ // all transformation is done (used by prepared statements)
+ changed= 1;
+
if (substitution)
{
- int ret= 0;
-
// did we changed top item of WHERE condition
if (unit->outer_select()->where == (*ref))
unit->outer_select()->where= substitution; // correct WHERE for PS
@@ -183,22 +180,20 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
substitution= 0;
thd->where= "checking transformed subquery";
if (!(*ref)->fixed)
- ret= (*ref)->fix_fields(thd, ref);
- thd->where= save_where;
- in_fix_fields--;
- return ret;
+ res= (*ref)->fix_fields(thd, ref);
+ goto end;
}
// Is it one field subselect?
if (engine->cols() > max_columns)
{
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
- in_fix_fields--;
- return TRUE;
+ res= 1;
+ goto end;
}
fix_length_and_dec();
}
else
- goto err;
+ goto end;
if ((uncacheable= engine->uncacheable()))
{
@@ -208,7 +203,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
}
fixed= 1;
-err:
+end:
in_fix_fields--;
thd->where= save_where;
return res;
@@ -339,9 +334,14 @@ void Item_subselect::update_used_tables()
void Item_subselect::print(String *str, enum_query_type query_type)
{
- str->append('(');
- engine->print(str, query_type);
- str->append(')');
+ if (engine)
+ {
+ str->append('(');
+ engine->print(str, query_type);
+ str->append(')');
+ }
+ else
+ str->append("(...)");
}
@@ -1977,6 +1977,7 @@ int subselect_single_select_engine::exec()
tab->read_record.record= tab->table->record[0];
tab->read_record.thd= join->thd;
tab->read_record.ref_length= tab->table->file->ref_length;
+ tab->read_record.unlock_row= rr_unlock_row;
*(last_changed_tab++)= tab;
break;
}
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index ff70c2aedfc..ab2da503209 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -517,7 +517,8 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table,
name, table->s, collation.collation);
break;
case DECIMAL_RESULT:
- field= Field_new_decimal::new_decimal_field(this);
+ field= new Field_new_decimal(max_length, maybe_null, name,
+ decimals, unsigned_flag);
break;
case ROW_RESULT:
default:
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 33a00cdd8c0..67929de5073 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -278,9 +278,9 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
int strict_week_number_year= -1;
int frac_part;
bool usa_time= 0;
- bool sunday_first_n_first_week_non_iso;
- bool strict_week_number;
- bool strict_week_number_year_type;
+ bool UNINIT_VAR(sunday_first_n_first_week_non_iso);
+ bool UNINIT_VAR(strict_week_number);
+ bool UNINIT_VAR(strict_week_number_year_type);
const char *val_begin= val;
const char *val_end= val + length;
const char *ptr= format->format.str;
@@ -1350,15 +1350,11 @@ bool get_interval_value(Item *args,interval_type int_type,
String *str_value, INTERVAL *interval)
{
ulonglong array[5];
- longlong value;
- const char *str;
- size_t length;
+ longlong UNINIT_VAR(value);
+ const char *UNINIT_VAR(str);
+ size_t UNINIT_VAR(length);
CHARSET_INFO *cs=str_value->charset();
- LINT_INIT(value);
- LINT_INIT(str);
- LINT_INIT(length);
-
bzero((char*) interval,sizeof(*interval));
if ((int) int_type <= INTERVAL_MICROSECOND)
{
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index f2e33dc2d44..15165a9c435 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -1363,8 +1363,7 @@ my_xpath_lex_scan(MY_XPATH *xpath,
MY_XPATH_LEX *lex, const char *beg, const char *end)
{
int ch, ctype, length;
- for ( ; beg < end && *beg == ' ' ; beg++) // skip leading spaces
- ;
+ for ( ; beg < end && *beg == ' ' ; beg++) ; // skip leading spaces
lex->beg= beg;
if (beg >= end)
@@ -1433,8 +1432,7 @@ my_xpath_lex_scan(MY_XPATH *xpath,
if (my_xdigit(ch)) // a sequence of digits
{
- for ( ; beg < end && my_xdigit(*beg) ; beg++)
- ;
+ for ( ; beg < end && my_xdigit(*beg) ; beg++) ;
lex->end= beg;
lex->term= MY_XPATH_LEX_DIGITS;
return;
@@ -1442,8 +1440,7 @@ my_xpath_lex_scan(MY_XPATH *xpath,
if (ch == '"' || ch == '\'') // a string: either '...' or "..."
{
- for ( ; beg < end && *beg != ch ; beg++)
- ;
+ for ( ; beg < end && *beg != ch ; beg++) ;
if (beg < end)
{
lex->end= beg+1;
diff --git a/sql/log.cc b/sql/log.cc
index d94b1e57b23..4b8efc45cb0 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -153,7 +153,7 @@ private:
class binlog_trx_data {
public:
binlog_trx_data()
- : at_least_one_stmt(0), incident(FALSE), m_pending(0),
+ : at_least_one_stmt_committed(0), incident(FALSE), m_pending(0),
before_stmt_pos(MY_OFF_T_UNDEF)
{
trans_log.end_of_file= max_binlog_cache_size;
@@ -182,7 +182,10 @@ public:
{
DBUG_PRINT("info", ("truncating to position %lu", (ulong) pos));
DBUG_PRINT("info", ("before_stmt_pos=%lu", (ulong) pos));
- delete pending();
+ if (pending())
+ {
+ delete pending();
+ }
set_pending(0);
reinit_io_cache(&trans_log, WRITE_CACHE, pos, 0, 0);
trans_log.end_of_file= max_binlog_cache_size;
@@ -192,12 +195,12 @@ public:
/*
The only valid positions that can be truncated to are at the
beginning of a statement. We are relying on this fact to be able
- to set the at_least_one_stmt flag correctly. In other word, if
+ to set the at_least_one_stmt_committed flag correctly. In other word, if
we are truncating to the beginning of the transaction cache,
there will be no statements in the cache, otherwhise, we will
have at least one statement in the transaction cache.
*/
- at_least_one_stmt= (pos > 0);
+ at_least_one_stmt_committed= (pos > 0);
}
/*
@@ -239,7 +242,7 @@ public:
Boolean that is true if there is at least one statement in the
transaction cache.
*/
- bool at_least_one_stmt;
+ bool at_least_one_stmt_committed;
bool incident;
private:
@@ -1057,14 +1060,10 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
Log_event_handler **current_handler= general_log_handler_list;
char user_host_buff[MAX_USER_HOST_SIZE + 1];
Security_context *sctx= thd->security_ctx;
- ulong id;
uint user_host_len= 0;
time_t current_time;
- if (thd)
- id= thd->thread_id; /* Normal thread */
- else
- id= 0; /* Log from connect handler */
+ DBUG_ASSERT(thd);
lock_shared();
if (!opt_log)
@@ -1083,7 +1082,7 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
while (*current_handler)
error|= (*current_handler++)->
log_general(thd, current_time, user_host_buff,
- user_host_len, id,
+ user_host_len, thd->thread_id,
command_name[(uint) command].str,
command_name[(uint) command].length,
query, query_length,
@@ -1309,7 +1308,7 @@ static bool stmt_has_updated_trans_table(THD *thd)
{
Ha_trx_info *ha_info;
- for (ha_info= thd->transaction.stmt.ha_list; ha_info; ha_info= ha_info->next())
+ for (ha_info= thd->transaction.stmt.ha_list; ha_info && ha_info->is_started(); ha_info= ha_info->next())
{
if (ha_info->is_trx_read_write() && ha_info->ht() != binlog_hton)
return (TRUE);
@@ -1557,9 +1556,9 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
/*
We commit the transaction if:
- - We are not in a transaction and committing a statement, or
+ - We are not in a transaction and committing a statement, or
- - We are in a transaction and a full transaction is committed
+ - We are in a transaction and a full transaction is committed
Otherwise, we accumulate the statement
*/
@@ -1572,21 +1571,18 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
YESNO(in_transaction),
YESNO(thd->transaction.all.modified_non_trans_table),
YESNO(thd->transaction.stmt.modified_non_trans_table)));
- if (thd->options & OPTION_BIN_LOG)
- {
- if (!in_transaction || all)
- {
- Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0);
- error= binlog_end_trans(thd, trx_data, &qev, all);
- goto end;
- }
- }
- else
+
+ if (!in_transaction || all ||
+ (!all && !trx_data->at_least_one_stmt_committed &&
+ !stmt_has_updated_trans_table(thd) &&
+ thd->transaction.stmt.modified_non_trans_table))
{
- trx_data->reset();
+ Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0);
+ error= binlog_end_trans(thd, trx_data, &qev, all);
}
-end:
+ trx_data->at_least_one_stmt_committed = my_b_tell(&trx_data->trans_log) > 0;
+
if (!all)
trx_data->before_stmt_pos = MY_OFF_T_UNDEF; // part of the stmt commit
DBUG_RETURN(error);
@@ -1652,15 +1648,18 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
{
/*
We flush the cache with a rollback, wrapped in a beging/rollback if:
- . aborting a transcation that modified a non-transactional table or;
+ . aborting a transaction that modified a non-transactional table;
. aborting a statement that modified both transactional and
- non-transctional tables but which is not in the boundaries of any
- transaction;
+ non-transactional tables but which is not in the boundaries of any
+ transaction or there was no early change;
. the OPTION_KEEP_LOG is activate.
*/
if ((all && thd->transaction.all.modified_non_trans_table) ||
(!all && thd->transaction.stmt.modified_non_trans_table &&
!(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT))) ||
+ (!all && thd->transaction.stmt.modified_non_trans_table &&
+ !trx_data->at_least_one_stmt_committed &&
+ thd->current_stmt_binlog_row_based) ||
((thd->options & OPTION_KEEP_LOG)))
{
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, TRUE, 0);
@@ -1752,7 +1751,7 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv)
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
int const error=
thd->binlog_query(THD::STMT_QUERY_TYPE,
- thd->query, thd->query_length, TRUE, FALSE, errcode);
+ thd->query(), thd->query_length(), TRUE, FALSE, errcode);
DBUG_RETURN(error);
}
@@ -1771,7 +1770,7 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
int error=
thd->binlog_query(THD::STMT_QUERY_TYPE,
- thd->query, thd->query_length, TRUE, FALSE, errcode);
+ thd->query(), thd->query_length(), TRUE, FALSE, errcode);
DBUG_RETURN(error);
}
binlog_trans_log_truncate(thd, *(my_off_t*)sv);
@@ -3663,7 +3662,7 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
}
old_name=name;
name=0; // Don't free name
- close(LOG_CLOSE_TO_BE_OPENED);
+ close(LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX);
/*
Note that at this point, log_state != LOG_CLOSED (important for is_open()).
@@ -3678,8 +3677,10 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
trigger temp tables deletion on slaves.
*/
- open(old_name, log_type, new_name_ptr,
- io_cache_type, no_auto_events, max_size, 1);
+ /* reopen index binlog file, BUG#34582 */
+ if (!open_index_file(index_file_name, 0))
+ open(old_name, log_type, new_name_ptr,
+ io_cache_type, no_auto_events, max_size, 1);
my_free(old_name,MYF(0));
end:
@@ -4120,7 +4121,7 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
*/
const char *local_db= event_info->get_db();
if ((!(thd->options & OPTION_BIN_LOG)) ||
- (!binlog_filter->db_ok(local_db)))
+ (!binlog_filter->db_ok(local_db)))
{
VOID(pthread_mutex_unlock(&LOCK_log));
DBUG_RETURN(0);
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 3a5f7f514ee..80a6c2585cf 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1851,6 +1851,7 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
{
const uchar *value0= value;
const uchar *null_bits= value;
+ uint null_bit_index= 0;
char typestr[64]= "";
value+= (m_width + 7) / 8;
@@ -1859,7 +1860,8 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
for (size_t i= 0; i < td->size(); i ++)
{
- int is_null= (null_bits[i / 8] >> (i % 8)) & 0x01;
+ int is_null= (null_bits[null_bit_index / 8]
+ >> (null_bit_index % 8)) & 0x01;
if (bitmap_is_set(cols_bitmap, i) == 0)
continue;
@@ -1896,6 +1898,8 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
}
my_b_printf(file, "\n");
+
+ null_bit_index++;
}
return value - value0;
}
@@ -2133,8 +2137,8 @@ void Query_log_event::pack_info(Protocol *protocol)
/**
Utility function for the next method (Query_log_event::write()) .
*/
-static void write_str_with_code_and_len(char **dst, const char *src,
- int len, uint code)
+static void write_str_with_code_and_len(uchar **dst, const char *src,
+ uint len, uint code)
{
/*
only 1 byte to store the length of catalog, so it should not
@@ -2142,7 +2146,7 @@ static void write_str_with_code_and_len(char **dst, const char *src,
*/
DBUG_ASSERT(len <= 255);
DBUG_ASSERT(src);
- *((*dst)++)= code;
+ *((*dst)++)= (uchar) code;
*((*dst)++)= (uchar) len;
bmove(*dst, src, len);
(*dst)+= len;
@@ -2229,7 +2233,7 @@ bool Query_log_event::write(IO_CACHE* file)
}
if (catalog_len) // i.e. this var is inited (false for 4.0 events)
{
- write_str_with_code_and_len((char **)(&start),
+ write_str_with_code_and_len(&start,
catalog, catalog_len, Q_CATALOG_NZ_CODE);
/*
In 5.0.x where x<4 masters we used to store the end zero here. This was
@@ -2267,7 +2271,7 @@ bool Query_log_event::write(IO_CACHE* file)
{
/* In the TZ sys table, column Name is of length 64 so this should be ok */
DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
- write_str_with_code_and_len((char **)(&start),
+ write_str_with_code_and_len(&start,
time_zone_str, time_zone_len, Q_TIME_ZONE_CODE);
}
if (lc_time_names_number)
@@ -3038,7 +3042,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
thd->query_id = next_query_id();
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thd->variables.pseudo_thread_id= thread_id; // for temp tables
- DBUG_PRINT("query",("%s",thd->query));
+ DBUG_PRINT("query",("%s", thd->query()));
if (ignored_error_code((expected_error= error_code)) ||
!unexpected_error_code(expected_error))
@@ -3132,7 +3136,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
/* Execute the query (note that we bypass dispatch_command()) */
const char* found_semicolon= NULL;
- mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
+ mysql_parse(thd, thd->query(), thd->query_length(), &found_semicolon);
log_slow_statement(thd);
}
else
@@ -3144,7 +3148,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
we exit gracefully; otherwise we warn about the bad error and tell DBA
to check/fix it.
*/
- if (mysql_test_parse_for_slave(thd, thd->query, thd->query_length))
+ if (mysql_test_parse_for_slave(thd, thd->query(), thd->query_length()))
clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
else
{
@@ -3154,7 +3158,7 @@ Query partially completed on the master (error on master: %d) \
and was aborted. There is a chance that your master is inconsistent at this \
point. If you are sure that your master is ok, run this query manually on the \
slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
-START SLAVE; . Query: '%s'", expected_error, thd->query);
+START SLAVE; . Query: '%s'", expected_error, thd->query());
thd->is_slave_error= 1;
}
goto end;
@@ -3162,7 +3166,7 @@ START SLAVE; . Query: '%s'", expected_error, thd->query);
/* If the query was not ignored, it is printed to the general log */
if (!thd->is_error() || thd->main_da.sql_errno() != ER_SLAVE_IGNORED_TABLE)
- general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
+ general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
compare_errors:
@@ -3854,6 +3858,7 @@ bool Format_description_log_event::write(IO_CACHE* file)
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
{
+ int ret= 0;
DBUG_ENTER("Format_description_log_event::do_apply_event");
#ifdef USING_TRANSACTIONS
@@ -3895,17 +3900,21 @@ int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
0, then 96, then jump to first really asked event (which is
>96). So this is ok.
*/
- DBUG_RETURN(Start_log_event_v3::do_apply_event(rli));
+ ret= Start_log_event_v3::do_apply_event(rli);
}
- DBUG_RETURN(0);
+
+ if (!ret)
+ {
+ /* Save the information describing this binlog */
+ delete rli->relay_log.description_event_for_exec;
+ const_cast<Relay_log_info *>(rli)->relay_log.description_event_for_exec= this;
+ }
+
+ DBUG_RETURN(ret);
}
int Format_description_log_event::do_update_pos(Relay_log_info *rli)
{
- /* save the information describing this binlog */
- delete rli->relay_log.description_event_for_exec;
- rli->relay_log.description_event_for_exec= this;
-
if (server_id == (uint32) ::server_id)
{
/*
@@ -4009,7 +4018,7 @@ uint Load_log_event::get_query_buffer_length()
}
-void Load_log_event::print_query(bool need_db, char *buf,
+void Load_log_event::print_query(bool need_db, const char *cs, char *buf,
char **end, char **fn_start, char **fn_end)
{
char *pos= buf;
@@ -4033,9 +4042,9 @@ void Load_log_event::print_query(bool need_db, char *buf,
pos= strmov(pos+fname_len, "' ");
if (sql_ex.opt_flags & REPLACE_FLAG)
- pos= strmov(pos, " REPLACE ");
+ pos= strmov(pos, "REPLACE ");
else if (sql_ex.opt_flags & IGNORE_FLAG)
- pos= strmov(pos, " IGNORE ");
+ pos= strmov(pos, "IGNORE ");
pos= strmov(pos ,"INTO");
@@ -4046,8 +4055,16 @@ void Load_log_event::print_query(bool need_db, char *buf,
memcpy(pos, table_name, table_name_len);
pos+= table_name_len;
- /* We have to create all optinal fields as the default is not empty */
- pos= strmov(pos, "` FIELDS TERMINATED BY ");
+ if (cs != NULL)
+ {
+ pos= strmov(pos ,"` CHARACTER SET ");
+ pos= strmov(pos , cs);
+ }
+ else
+ pos= strmov(pos, "`");
+
+ /* We have to create all optional fields as the default is not empty */
+ pos= strmov(pos, " FIELDS TERMINATED BY ");
pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
pos= strmov(pos, " OPTIONALLY ");
@@ -4101,7 +4118,7 @@ void Load_log_event::pack_info(Protocol *protocol)
if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
return;
- print_query(TRUE, buf, &end, 0, 0);
+ print_query(TRUE, NULL, buf, &end, 0, 0);
protocol->store(buf, end-buf, &my_charset_bin);
my_free(buf, MYF(0));
}
@@ -4366,9 +4383,9 @@ void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname);
if (sql_ex.opt_flags & REPLACE_FLAG)
- my_b_printf(&cache," REPLACE ");
+ my_b_printf(&cache,"REPLACE ");
else if (sql_ex.opt_flags & IGNORE_FLAG)
- my_b_printf(&cache," IGNORE ");
+ my_b_printf(&cache,"IGNORE ");
my_b_printf(&cache, "INTO TABLE `%s`", table_name);
my_b_printf(&cache, " FIELDS TERMINATED BY ");
@@ -4480,8 +4497,8 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
new_db.length= db_len;
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
thd->set_db(new_db.str, new_db.length);
- DBUG_ASSERT(thd->query == 0);
- thd->query_length= 0; // Should not be needed
+ DBUG_ASSERT(thd->query() == 0);
+ thd->set_query_inner(NULL, 0); // Should not be needed
thd->is_slave_error= 0;
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
@@ -4492,6 +4509,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
as the present method does not call mysql_parse().
*/
lex_start(thd);
+ thd->lex->local_file= local_fname;
mysql_reset_thd_for_next_command(thd, 0);
if (!use_rli_only_for_errors)
@@ -4576,8 +4594,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
goto error;
}
- print_query(FALSE, load_data_query, &end, (char **)&thd->lex->fname_start,
- (char **)&thd->lex->fname_end);
+ print_query(FALSE, NULL, load_data_query, &end, NULL, NULL);
*end= 0;
thd->set_query(load_data_query, (uint) (end - load_data_query));
@@ -6734,7 +6751,7 @@ void Execute_load_query_log_event::print(FILE* file,
my_b_printf(&cache, "\'");
if (dup_handling == LOAD_DUP_REPLACE)
my_b_printf(&cache, " REPLACE");
- my_b_printf(&cache, " INTO ");
+ my_b_printf(&cache, " INTO");
my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
}
@@ -7497,6 +7514,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
thd->reset_current_stmt_binlog_row_based();
const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error);
thd->is_slave_error= 1;
+ DBUG_RETURN(error);
}
/*
This code would ideally be placed in do_update_pos() instead, but
@@ -7525,6 +7543,14 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
const_cast<Relay_log_info*>(rli)->last_event_start_time= my_time(0);
}
+ if (get_flags(STMT_END_F))
+ if ((error= rows_event_stmt_cleanup(rli, thd)))
+ rli->report(ERROR_LEVEL, error,
+ "Error in %s event: commit of row events failed, "
+ "table `%s`.`%s`",
+ get_type_str(), m_table->s->db.str,
+ m_table->s->table_name.str);
+
DBUG_RETURN(error);
}
@@ -7623,33 +7649,19 @@ Rows_log_event::do_update_pos(Relay_log_info *rli)
if (get_flags(STMT_END_F))
{
- if ((error= rows_event_stmt_cleanup(rli, thd)) == 0)
- {
- /*
- Indicate that a statement is finished.
- Step the group log position if we are not in a transaction,
- otherwise increase the event log position.
- */
- rli->stmt_done(log_pos, when);
-
- /*
- Clear any errors pushed in thd->net.last_err* if for example "no key
- found" (as this is allowed). This is a safety measure; apparently
- those errors (e.g. when executing a Delete_rows_log_event of a
- non-existing row, like in rpl_row_mystery22.test,
- thd->net.last_error = "Can't find record in 't1'" and last_errno=1032)
- do not become visible. We still prefer to wipe them out.
- */
- thd->clear_error();
- }
- else
- {
- rli->report(ERROR_LEVEL, error,
- "Error in %s event: commit of row events failed, "
- "table `%s`.`%s`",
- get_type_str(), m_table->s->db.str,
- m_table->s->table_name.str);
- }
+ /*
+ Indicate that a statement is finished.
+ Step the group log position if we are not in a transaction,
+ otherwise increase the event log position.
+ */
+ rli->stmt_done(log_pos, when);
+ /*
+ Clear any errors in thd->net.last_err*. It is not known if this is
+ needed or not. It is believed that any errors that may exist in
+ thd->net.last_err* are allowed. Examples of errors are "key not
+ found", which is produced in the test case rpl_row_conflicts.test
+ */
+ thd->clear_error();
}
else
{
@@ -8419,6 +8431,16 @@ Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability
/* Honor next number column if present */
m_table->next_number_field= m_table->found_next_number_field;
+ /*
+ * Fixed Bug#45999, In RBR, Store engine of Slave auto-generates new
+ * sequence numbers for auto_increment fields if the values of them are 0.
+ * If generateing a sequence number is decided by the values of
+ * table->auto_increment_field_not_null and SQL_MODE(if includes
+ * MODE_NO_AUTO_VALUE_ON_ZERO) in update_auto_increment function.
+ * SQL_MODE of slave sql thread is always consistency with master's.
+ * In RBR, auto_increment fields never are NULL.
+ */
+ m_table->auto_increment_field_not_null= TRUE;
return error;
}
@@ -8428,6 +8450,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 ||
m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER)
{
@@ -8932,11 +8955,11 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
*/
store_record(table,record[1]);
- if (table->s->keys > 0)
+ if (table->s->keys > 0 && table->s->keys_in_use.is_set(0))
{
DBUG_PRINT("info",("locating record using primary key (index_read)"));
- /* We have a key: search the table using the index */
+ /* The 0th key is active: search the table using the index */
if (!table->file->inited && (error= table->file->ha_index_init(0, FALSE)))
{
DBUG_PRINT("info",("ha_index_init returns error %d",error));
diff --git a/sql/log_event.h b/sql/log_event.h
index 41451a618a7..e4bc699b9ca 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -1972,15 +1972,15 @@ private:
class Load_log_event: public Log_event
{
private:
- uint get_query_buffer_length();
- void print_query(bool need_db, char *buf, char **end,
- char **fn_start, char **fn_end);
protected:
int copy_log_event(const char *buf, ulong event_len,
int body_offset,
const Format_description_log_event* description_event);
public:
+ uint get_query_buffer_length();
+ void print_query(bool need_db, const char *cs, char *buf, char **end,
+ char **fn_start, char **fn_end);
ulong thread_id;
ulong slave_proxy_id;
uint32 table_name_len;
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index 36cae2c839c..2ba76c45f85 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -1815,33 +1815,6 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
const_cast<Relay_log_info*>(rli)->last_event_start_time= my_time(0);
}
- DBUG_RETURN(0);
-}
-
-
-Log_event::enum_skip_reason
-Old_rows_log_event::do_shall_skip(Relay_log_info *rli)
-{
- /*
- If the slave skip counter is 1 and this event does not end a
- statement, then we should not start executing on the next event.
- Otherwise, we defer the decision to the normal skipping logic.
- */
- if (rli->slave_skip_counter == 1 && !get_flags(STMT_END_F))
- return Log_event::EVENT_SKIP_IGNORE;
- else
- return Log_event::do_shall_skip(rli);
-}
-
-int
-Old_rows_log_event::do_update_pos(Relay_log_info *rli)
-{
- DBUG_ENTER("Old_rows_log_event::do_update_pos");
- int error= 0;
-
- DBUG_PRINT("info", ("flags: %s",
- get_flags(STMT_END_F) ? "STMT_END_F " : ""));
-
if (get_flags(STMT_END_F))
{
/*
@@ -1870,7 +1843,12 @@ Old_rows_log_event::do_update_pos(Relay_log_info *rli)
are involved, commit the transaction and flush the pending event to the
binlog.
*/
- error= ha_autocommit_or_rollback(thd, 0);
+ if ((error= ha_autocommit_or_rollback(thd, 0)))
+ rli->report(ERROR_LEVEL, error,
+ "Error in %s event: commit of row events failed, "
+ "table `%s`.`%s`",
+ get_type_str(), m_table->s->db.str,
+ m_table->s->table_name.str);
/*
Now what if this is not a transactional engine? we still need to
@@ -1883,33 +1861,51 @@ Old_rows_log_event::do_update_pos(Relay_log_info *rli)
*/
thd->reset_current_stmt_binlog_row_based();
- rli->cleanup_context(thd, 0);
- if (error == 0)
- {
- /*
- Indicate that a statement is finished.
- Step the group log position if we are not in a transaction,
- otherwise increase the event log position.
- */
- rli->stmt_done(log_pos, when);
+ const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 0);
+ }
- /*
- Clear any errors pushed in thd->net.client_last_err* if for
- example "no key found" (as this is allowed). This is a safety
- measure; apparently those errors (e.g. when executing a
- Delete_rows_log_event_old of a non-existing row, like in
- rpl_row_mystery22.test, thd->net.last_error = "Can't
- find record in 't1'" and last_errno=1032) do not become
- visible. We still prefer to wipe them out.
- */
- thd->clear_error();
- }
- else
- rli->report(ERROR_LEVEL, error,
- "Error in %s event: commit of row events failed, "
- "table `%s`.`%s`",
- get_type_str(), m_table->s->db.str,
- m_table->s->table_name.str);
+ DBUG_RETURN(error);
+}
+
+
+Log_event::enum_skip_reason
+Old_rows_log_event::do_shall_skip(Relay_log_info *rli)
+{
+ /*
+ If the slave skip counter is 1 and this event does not end a
+ statement, then we should not start executing on the next event.
+ Otherwise, we defer the decision to the normal skipping logic.
+ */
+ if (rli->slave_skip_counter == 1 && !get_flags(STMT_END_F))
+ return Log_event::EVENT_SKIP_IGNORE;
+ else
+ return Log_event::do_shall_skip(rli);
+}
+
+int
+Old_rows_log_event::do_update_pos(Relay_log_info *rli)
+{
+ DBUG_ENTER("Old_rows_log_event::do_update_pos");
+ int error= 0;
+
+ DBUG_PRINT("info", ("flags: %s",
+ get_flags(STMT_END_F) ? "STMT_END_F " : ""));
+
+ if (get_flags(STMT_END_F))
+ {
+ /*
+ Indicate that a statement is finished.
+ Step the group log position if we are not in a transaction,
+ otherwise increase the event log position.
+ */
+ rli->stmt_done(log_pos, when);
+ /*
+ Clear any errors in thd->net.last_err*. It is not known if this is
+ needed or not. It is believed that any errors that may exist in
+ thd->net.last_err* are allowed. Examples of errors are "key not
+ found", which is produced in the test case rpl_row_conflicts.test
+ */
+ thd->clear_error();
}
else
{
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index d991dd1c54c..d736bad9a4b 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -48,12 +48,10 @@ C_MODE_END
digits * number of decimal digits in one our big digit - number of decimal
digits in one our big digit decreased by 1 (because we always put decimal
point on the border of our big digits))
-
- This value is 65 due to historical reasons partly due to it being used
- as the maximum allowed precision and not the actual maximum precision.
*/
#define DECIMAL_MAX_PRECISION (DECIMAL_MAX_POSSIBLE_PRECISION - 8*2)
#define DECIMAL_MAX_SCALE 30
+#define DECIMAL_NOT_SPECIFIED 31
/**
maximum length of string representation (number of maximum decimal
@@ -77,6 +75,12 @@ inline uint my_decimal_size(uint precision, uint scale)
}
+inline int my_decimal_int_part(uint precision, uint decimals)
+{
+ return precision - ((decimals == DECIMAL_NOT_SPECIFIED) ? 0 : decimals);
+}
+
+
/**
my_decimal class limits 'decimal_t' type to what we need in MySQL.
@@ -180,7 +184,7 @@ inline uint my_decimal_length_to_precision(uint length, uint scale,
}
inline uint32 my_decimal_precision_to_length_no_truncation(uint precision,
- uint scale,
+ uint8 scale,
bool unsigned_flag)
{
/*
@@ -192,7 +196,7 @@ inline uint32 my_decimal_precision_to_length_no_truncation(uint precision,
(unsigned_flag || !precision ? 0 : 1));
}
-inline uint32 my_decimal_precision_to_length(uint precision, uint scale,
+inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale,
bool unsigned_flag)
{
/*
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 77f55db145a..e335712a3f7 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -2331,10 +2331,9 @@ enum enum_explain_filename_mode
{
EXPLAIN_ALL_VERBOSE= 0,
EXPLAIN_PARTITIONS_VERBOSE,
- EXPLAIN_PARTITIONS_AS_COMMENT,
- EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING
+ EXPLAIN_PARTITIONS_AS_COMMENT
};
-uint explain_filename(const char *from, char *to, uint to_length,
+uint explain_filename(THD* thd, const char *from, char *to, uint to_length,
enum_explain_filename_mode explain_mode);
uint filename_to_tablename(const char *from, char *to, uint to_length);
uint tablename_to_filename(const char *from, char *to, uint to_length);
@@ -2488,6 +2487,7 @@ inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
table->tablenr= tablenr;
table->map= (table_map) 1 << tablenr;
table->force_index= table_list->force_index;
+ table->force_index_order= table->force_index_group= 0;
table->covering_keys= table->s->keys_for_keyread;
table->merge_keys.clear_all();
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 81f02157ee0..750a221a785 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -28,6 +28,7 @@
#include "mysys_err.h"
#include "events.h"
#include <waiting_threads.h>
+#include "debug_sync.h"
#include "../storage/myisam/ha_myisam.h"
@@ -498,6 +499,9 @@ my_bool lower_case_file_system= 0;
my_bool opt_large_pages= 0;
my_bool opt_myisam_use_mmap= 0;
uint opt_large_page_size= 0;
+#if defined(ENABLED_DEBUG_SYNC)
+uint opt_debug_sync_timeout= 0;
+#endif /* defined(ENABLED_DEBUG_SYNC) */
my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
/*
True if there is at least one per-hour limit for some user, so we should
@@ -962,6 +966,7 @@ static void close_connections(void)
tmp->killed= THD::KILL_CONNECTION;
thread_scheduler.post_kill_notification(tmp);
+ pthread_mutex_lock(&tmp->LOCK_thd_data);
if (tmp->mysys_var)
{
tmp->mysys_var->abort=1;
@@ -984,6 +989,7 @@ static void close_connections(void)
}
pthread_mutex_unlock(&tmp->mysys_var->mutex);
}
+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
}
(void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
@@ -1141,13 +1147,13 @@ void kill_mysql(void)
#if defined(__NETWARE__)
extern "C" void kill_server(int sig_ptr)
-#define RETURN_FROM_KILL_SERVER DBUG_VOID_RETURN
+#define RETURN_FROM_KILL_SERVER return
#elif !defined(__WIN__)
static void *kill_server(void *sig_ptr)
-#define RETURN_FROM_KILL_SERVER DBUG_RETURN(0)
+#define RETURN_FROM_KILL_SERVER return 0
#else
static void __cdecl kill_server(int sig_ptr)
-#define RETURN_FROM_KILL_SERVER DBUG_VOID_RETURN
+#define RETURN_FROM_KILL_SERVER return
#endif
{
DBUG_ENTER("kill_server");
@@ -1155,7 +1161,10 @@ static void __cdecl kill_server(int sig_ptr)
int sig=(int) (long) sig_ptr; // This is passed a int
// if there is a signal during the kill in progress, ignore the other
if (kill_in_progress) // Safety
+ {
+ DBUG_LEAVE;
RETURN_FROM_KILL_SERVER;
+ }
kill_in_progress=TRUE;
abort_loop=1; // This should be set
if (sig != 0) // 0 is not a valid signal number
@@ -1190,12 +1199,19 @@ static void __cdecl kill_server(int sig_ptr)
pthread_join(select_thread, NULL); // wait for main thread
#endif /* __NETWARE__ */
+ DBUG_LEAVE; // Must match DBUG_ENTER()
my_thread_end();
pthread_exit(0);
/* purecov: end */
-#endif /* EMBEDDED_LIBRARY */
+ RETURN_FROM_KILL_SERVER; // Avoid compiler warnings
+
+#else /* EMBEDDED_LIBRARY*/
+
+ DBUG_LEAVE;
RETURN_FROM_KILL_SERVER;
+
+#endif /* EMBEDDED_LIBRARY */
}
@@ -1363,6 +1379,10 @@ void clean_up(bool print_message)
#ifdef USE_REGEX
my_regex_end();
#endif
+#if defined(ENABLED_DEBUG_SYNC)
+ /* End the debug sync facility. See debug_sync.cc. */
+ debug_sync_end();
+#endif /* defined(ENABLED_DEBUG_SYNC) */
#if !defined(EMBEDDED_LIBRARY)
if (!opt_bootstrap)
@@ -1791,7 +1811,7 @@ static void network_init(void)
saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
saPipeSecurity.bInheritHandle = FALSE;
if ((hPipe= CreateNamedPipe(pipe_name,
- PIPE_ACCESS_DUPLEX,
+ PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE |
PIPE_READMODE_BYTE |
PIPE_WAIT,
@@ -2026,8 +2046,9 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
my_thread_end();
(void) pthread_cond_broadcast(&COND_thread_count);
+ DBUG_LEAVE; // Must match DBUG_ENTER()
pthread_exit(0);
- DBUG_RETURN(0); // Impossible
+ return 0; // Avoid compiler warnings
}
@@ -2594,7 +2615,7 @@ terribly wrong...\n");
}
fprintf(stderr, "Trying to get some variables.\n\
Some pointers may be invalid and cause the dump to abort...\n");
- my_safe_print_str("thd->query", thd->query, 1024);
+ my_safe_print_str("thd->query", thd->query(), 1024);
fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id);
fprintf(stderr, "thd->killed=%s\n", kreason);
}
@@ -2851,7 +2872,9 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
my_thread_end();
signal_thread_in_use= 0;
+ DBUG_LEAVE; // Must match DBUG_ENTER()
pthread_exit(0); // Safety
+ return 0; // Avoid compiler warnings
}
switch (sig) {
case SIGTERM:
@@ -3575,6 +3598,12 @@ static int init_common_variables(const char *conf_file_name, int argc,
sys_var_slow_log_path.value= my_strdup(s, MYF(0));
sys_var_slow_log_path.value_length= strlen(s);
+#if defined(ENABLED_DEBUG_SYNC)
+ /* Initialize the debug sync facility. See debug_sync.cc. */
+ if (debug_sync_init())
+ return 1; /* purecov: tested */
+#endif /* defined(ENABLED_DEBUG_SYNC) */
+
#if (ENABLE_TEMP_POOL)
if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
return 1;
@@ -4938,10 +4967,10 @@ static bool read_init_file(char *file_name)
DBUG_ENTER("read_init_file");
DBUG_PRINT("enter",("name: %s",file_name));
if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME))))
- DBUG_RETURN(1);
+ DBUG_RETURN(TRUE);
bootstrap(file);
(void) my_fclose(file,MYF(MY_WME));
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
@@ -4995,7 +5024,7 @@ void create_thread_to_handle_connection(THD *thd)
handle_one_connection,
(void*) thd)))
{
- /* purify: begin inspected */
+ /* purecov: begin inspected */
DBUG_PRINT("error",
("Can't create thread to handle request (error %d)",
error));
@@ -5354,17 +5383,26 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
pthread_handler_t handle_connections_namedpipes(void *arg)
{
HANDLE hConnectedPipe;
- BOOL fConnected;
+ OVERLAPPED connectOverlapped = {0};
THD *thd;
my_thread_init();
DBUG_ENTER("handle_connections_namedpipes");
- (void) my_pthread_getprio(pthread_self()); // For debugging
+ connectOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
DBUG_PRINT("general",("Waiting for named pipe connections."));
while (!abort_loop)
{
/* wait for named pipe connection */
- fConnected = ConnectNamedPipe(hPipe, NULL);
+ BOOL fConnected= ConnectNamedPipe(hPipe, &connectOverlapped);
+ if (!fConnected && (GetLastError() == ERROR_IO_PENDING))
+ {
+ /*
+ ERROR_IO_PENDING says async IO has started but not yet finished.
+ GetOverlappedResult will wait for completion.
+ */
+ DWORD bytes;
+ fConnected= GetOverlappedResult(hPipe, &connectOverlapped,&bytes, TRUE);
+ }
if (abort_loop)
break;
if (!fConnected)
@@ -5373,7 +5411,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
{
CloseHandle(hPipe);
if ((hPipe= CreateNamedPipe(pipe_name,
- PIPE_ACCESS_DUPLEX,
+ PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE |
PIPE_READMODE_BYTE |
PIPE_WAIT,
@@ -5393,7 +5431,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
hConnectedPipe = hPipe;
/* create new pipe for new connection */
if ((hPipe = CreateNamedPipe(pipe_name,
- PIPE_ACCESS_DUPLEX,
+ PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE |
PIPE_READMODE_BYTE |
PIPE_WAIT,
@@ -5415,7 +5453,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
CloseHandle(hConnectedPipe);
continue;
}
- if (!(thd->net.vio = vio_new_win32pipe(hConnectedPipe)) ||
+ if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) ||
my_net_init(&thd->net, thd->net.vio))
{
close_connection(thd, ER_OUT_OF_RESOURCES, 1);
@@ -5426,7 +5464,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
thd->security_ctx->host= my_strdup(my_localhost, MYF(0));
create_new_thread(thd);
}
-
+ CloseHandle(connectOverlapped.hEvent);
decrement_handler_count();
DBUG_RETURN(0);
}
@@ -5603,8 +5641,7 @@ pthread_handler_t handle_connections_shared_memory(void *arg)
errmsg= "Could not set client to read mode";
goto errorconn;
}
- if (!(thd->net.vio= vio_new_win32shared_memory(&thd->net,
- handle_client_file_map,
+ if (!(thd->net.vio= vio_new_win32shared_memory(handle_client_file_map,
handle_client_map,
event_client_wrote,
event_client_read,
@@ -5844,6 +5881,9 @@ enum options_mysqld
OPT_LOG_SLOW_SLAVE_STATEMENTS,
OPT_DEBUG_CRC, OPT_DEBUG_ON, OPT_OLD_MODE,
OPT_TEST_IGNORE_WRONG_OPTIONS,
+#if defined(ENABLED_DEBUG_SYNC)
+ OPT_DEBUG_SYNC_TIMEOUT,
+#endif /* defined(ENABLED_DEBUG_SYNC) */
OPT_SLAVE_EXEC_MODE,
OPT_DEADLOCK_SEARCH_DEPTH_SHORT,
OPT_DEADLOCK_SEARCH_DEPTH_LONG,
@@ -6665,6 +6705,14 @@ log and this option does nothing anymore.",
"Decision to use in heuristic recover process. Possible values are COMMIT or ROLLBACK.",
(uchar**) &opt_tc_heuristic_recover, (uchar**) &opt_tc_heuristic_recover,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#if defined(ENABLED_DEBUG_SYNC)
+ {"debug-sync-timeout", OPT_DEBUG_SYNC_TIMEOUT,
+ "Enable the debug sync facility "
+ "and optionally specify a default wait timeout in seconds. "
+ "A zero value keeps the facility disabled.",
+ (uchar**) &opt_debug_sync_timeout, 0,
+ 0, GET_UINT, OPT_ARG, 0, 0, UINT_MAX, 0, 0, 0},
+#endif /* defined(ENABLED_DEBUG_SYNC) */
{"temp-pool", OPT_TEMP_POOL,
#if (ENABLE_TEMP_POOL)
"Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.",
@@ -7888,6 +7936,9 @@ static int mysql_init_variables(void)
bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
bzero((char *) &global_status_var, sizeof(global_status_var));
opt_large_pages= 0;
+#if defined(ENABLED_DEBUG_SYNC)
+ opt_debug_sync_timeout= 0;
+#endif /* defined(ENABLED_DEBUG_SYNC) */
key_map_full.set_all();
/* Character sets */
@@ -8701,6 +8752,22 @@ mysqld_get_one_option(int optid,
/* Used for testing options */
opt_ignore_wrong_options= 1;
break;
+#if defined(ENABLED_DEBUG_SYNC)
+ case OPT_DEBUG_SYNC_TIMEOUT:
+ /*
+ Debug Sync Facility. See debug_sync.cc.
+ Default timeout for WAIT_FOR action.
+ Default value is zero (facility disabled).
+ If option is given without an argument, supply a non-zero value.
+ */
+ if (!argument)
+ {
+ /* purecov: begin tested */
+ opt_debug_sync_timeout= DEBUG_SYNC_DEFAULT_WAIT_TIMEOUT;
+ /* purecov: end */
+ }
+ break;
+#endif /* defined(ENABLED_DEBUG_SYNC) */
}
return 0;
}
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index adb5a7c8c96..8d431b16c66 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -5710,6 +5710,27 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
!(conf_func->compare_collation()->state & MY_CS_BINSORT))
goto end;
+ if (key_part->image_type == Field::itMBR)
+ {
+ switch (type) {
+ case Item_func::SP_EQUALS_FUNC:
+ case Item_func::SP_DISJOINT_FUNC:
+ case Item_func::SP_INTERSECTS_FUNC:
+ case Item_func::SP_TOUCHES_FUNC:
+ case Item_func::SP_CROSSES_FUNC:
+ case Item_func::SP_WITHIN_FUNC:
+ case Item_func::SP_CONTAINS_FUNC:
+ case Item_func::SP_OVERLAPS_FUNC:
+ break;
+ default:
+ /*
+ We cannot involve spatial indexes for queries that
+ don't use MBREQUALS(), MBRDISJOINT(), etc. functions.
+ */
+ goto end;
+ }
+ }
+
if (param->using_real_indexes)
optimize_range= field->optimize_range(param->real_keynr[key_part->key],
key_part->part);
@@ -5877,6 +5898,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
if (type == Item_func::LT_FUNC && (value->val_int() > 0))
type = Item_func::LE_FUNC;
else if (type == Item_func::GT_FUNC &&
+ (field->type() != FIELD_TYPE_BIT) &&
!((Field_num*)field)->unsigned_flag &&
!((Item_int*)value)->unsigned_flag &&
(value->val_int() < 0))
@@ -5891,6 +5913,17 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
goto end;
}
field->table->in_use->variables.sql_mode= orig_sql_mode;
+
+ /*
+ Any sargable predicate except "<=>" involving NULL as a constant is always
+ FALSE
+ */
+ if (type != Item_func::EQUAL_FUNC && field->is_real_null())
+ {
+ tree= &null_element;
+ goto end;
+ }
+
str= (uchar*) alloc_root(alloc, key_part->store_length+1);
if (!str)
goto end;
@@ -5914,7 +5947,9 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
*/
if (field->result_type() == INT_RESULT &&
value->result_type() == INT_RESULT &&
- ((Field_num*)field)->unsigned_flag && !((Item_int*)value)->unsigned_flag)
+ ((field->type() == FIELD_TYPE_BIT ||
+ ((Field_num *) field)->unsigned_flag) &&
+ !((Item_int*) value)->unsigned_flag))
{
longlong item_val= value->val_int();
if (item_val < 0)
@@ -5934,7 +5969,7 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
switch (type) {
case Item_func::LT_FUNC:
- if (stored_field_cmp_to_item(field,value) == 0)
+ if (stored_field_cmp_to_item(param->thd, field, value) == 0)
tree->max_flag=NEAR_MAX;
/* fall through */
case Item_func::LE_FUNC:
@@ -5949,14 +5984,14 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field,
case Item_func::GT_FUNC:
/* Don't use open ranges for partial key_segments */
if ((!(key_part->flag & HA_PART_KEY_SEG)) &&
- (stored_field_cmp_to_item(field, value) <= 0))
+ (stored_field_cmp_to_item(param->thd, field, value) <= 0))
tree->min_flag=NEAR_MIN;
tree->max_flag= NO_MAX_RANGE;
break;
case Item_func::GE_FUNC:
/* Don't use open ranges for partial key_segments */
if ((!(key_part->flag & HA_PART_KEY_SEG)) &&
- (stored_field_cmp_to_item(field,value) < 0))
+ (stored_field_cmp_to_item(param->thd, field, value) < 0))
tree->min_flag= NEAR_MIN;
tree->max_flag=NO_MAX_RANGE;
break;
@@ -6510,6 +6545,63 @@ get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1)
}
+/**
+ Combine two range expression under a common OR. On a logical level, the
+ transformation is key_or( expr1, expr2 ) => expr1 OR expr2.
+
+ Both expressions are assumed to be in the SEL_ARG format. In a logic sense,
+ theformat is reminiscent of DNF, since an expression such as the following
+
+ ( 1 < kp1 < 10 AND p1 ) OR ( 10 <= kp2 < 20 AND p2 )
+
+ where there is a key consisting of keyparts ( kp1, kp2, ..., kpn ) and p1
+ and p2 are valid SEL_ARG expressions over keyparts kp2 ... kpn, is a valid
+ SEL_ARG condition. The disjuncts appear ordered by the minimum endpoint of
+ the first range and ranges must not overlap. It follows that they are also
+ ordered by maximum endpoints. Thus
+
+ ( 1 < kp1 <= 2 AND ( kp2 = 2 OR kp2 = 3 ) ) OR kp1 = 3
+
+ Is a a valid SER_ARG expression for a key of at least 2 keyparts.
+
+ For simplicity, we will assume that expr2 is a single range predicate,
+ i.e. on the form ( a < x < b AND ... ). It is easy to generalize to a
+ disjunction of several predicates by subsequently call key_or for each
+ disjunct.
+
+ The algorithm iterates over each disjunct of expr1, and for each disjunct
+ where the first keypart's range overlaps with the first keypart's range in
+ expr2:
+
+ If the predicates are equal for the rest of the keyparts, or if there are
+ no more, the range in expr2 has its endpoints copied in, and the SEL_ARG
+ node in expr2 is deallocated. If more ranges became connected in expr1, the
+ surplus is also dealocated. If they differ, two ranges are created.
+
+ - The range leading up to the overlap. Empty if endpoints are equal.
+
+ - The overlapping sub-range. May be the entire range if they are equal.
+
+ Finally, there may be one more range if expr2's first keypart's range has a
+ greater maximum endpoint than the last range in expr1.
+
+ For the overlapping sub-range, we recursively call key_or. Thus in order to
+ compute key_or of
+
+ (1) ( 1 < kp1 < 10 AND 1 < kp2 < 10 )
+
+ (2) ( 2 < kp1 < 20 AND 4 < kp2 < 20 )
+
+ We create the ranges 1 < kp <= 2, 2 < kp1 < 10, 10 <= kp1 < 20. For the
+ first one, we simply hook on the condition for the second keypart from (1)
+ : 1 < kp2 < 10. For the second range 2 < kp1 < 10, key_or( 1 < kp2 < 10, 4
+ < kp2 < 20 ) is called, yielding 1 < kp2 < 20. For the last range, we reuse
+ the range 4 < kp2 < 20 from (2) for the second keypart. The result is thus
+
+ ( 1 < kp1 <= 2 AND 1 < kp2 < 10 ) OR
+ ( 2 < kp1 < 10 AND 1 < kp2 < 20 ) OR
+ ( 10 <= kp1 < 20 AND 4 < kp2 < 20 )
+*/
static SEL_ARG *
key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
{
@@ -6661,7 +6753,21 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
key1=key1->tree_delete(save);
}
last->copy_min(tmp);
- if (last->copy_min(key2) || last->copy_max(key2))
+ bool full_range= last->copy_min(key2);
+ if (!full_range)
+ {
+ if (last->next && key2->cmp_max_to_min(last->next) >= 0)
+ {
+ last->max_value= last->next->min_value;
+ if (last->next->min_flag & NEAR_MIN)
+ last->max_flag&= ~NEAR_MAX;
+ else
+ last->max_flag|= NEAR_MAX;
+ }
+ else
+ full_range= last->copy_max(key2);
+ }
+ if (full_range)
{ // Full range
key1->free_tree();
for (; key2 ; key2=key2->next)
@@ -6671,8 +6777,6 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
return 0;
}
}
- key2=key2->next;
- continue;
}
if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 1d84d838145..cefb507a61e 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -97,7 +97,8 @@ static ulonglong get_exact_record_count(TABLE_LIST *tables)
@note
This function is only called for queries with sum functions and no
- GROUP BY part.
+ GROUP BY part. This means that the result set shall contain a single
+ row only
@retval
0 no errors
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 8fc9e584789..e7d3e842903 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -483,10 +483,8 @@ static bool check_engine_condition(partition_element *p_elem,
{
DBUG_RETURN(TRUE);
}
- else
- {
- DBUG_RETURN(FALSE);
- }
+
+ DBUG_RETURN(FALSE);
}
diff --git a/sql/records.cc b/sql/records.cc
index c562c305e77..e2a1ea9b4af 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -57,10 +57,12 @@ void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
{
empty_record(table);
bzero((char*) info,sizeof(*info));
+ info->thd= thd;
info->table= table;
info->file= table->file;
info->record= table->record[0];
info->print_error= print_error;
+ info->unlock_row= rr_unlock_row;
table->status=0; /* And it's always found */
if (!table->file->inited)
@@ -186,6 +188,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
}
info->select=select;
info->print_error=print_error;
+ info->unlock_row= rr_unlock_row;
info->ignore_not_found_rows= 0;
table->status=0; /* And it's always found */
@@ -292,6 +295,12 @@ void end_read_record(READ_RECORD *info)
static int rr_handle_error(READ_RECORD *info, int error)
{
+ if (info->thd->killed)
+ {
+ info->thd->send_kill_message();
+ return 1;
+ }
+
if (error == HA_ERR_END_OF_FILE)
error= -1;
else
@@ -312,12 +321,7 @@ static int rr_quick(READ_RECORD *info)
int tmp;
while ((tmp= info->select->quick->get_next()))
{
- if (info->thd->killed)
- {
- my_error(ER_SERVER_SHUTDOWN, MYF(0));
- return 1;
- }
- if (tmp != HA_ERR_RECORD_DELETED)
+ if (info->thd->killed || (tmp != HA_ERR_RECORD_DELETED))
{
tmp= rr_handle_error(info, tmp);
break;
@@ -381,16 +385,11 @@ int rr_sequential(READ_RECORD *info)
int tmp;
while ((tmp= info->file->ha_rnd_next(info->record)))
{
- if (info->thd->killed)
- {
- info->thd->send_kill_message();
- return 1;
- }
/*
rnd_next can return RECORD_DELETED for MyISAM when one thread is
reading and another deleting without locks.
*/
- if (tmp != HA_ERR_RECORD_DELETED)
+ if (info->thd->killed || (tmp != HA_ERR_RECORD_DELETED))
{
tmp= rr_handle_error(info, tmp);
break;
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index 582348608de..312499bb4ee 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -638,9 +638,11 @@ err:
if (recovery_captain)
mysql_close(recovery_captain);
delete thd;
+
+ DBUG_LEAVE; // Must match DBUG_ENTER()
my_thread_end();
pthread_exit(0);
- DBUG_RETURN(0);
+ return 0; // Avoid compiler warnings
}
#endif
diff --git a/sql/rpl_filter.cc b/sql/rpl_filter.cc
index 55dc71e3405..ffae94f733a 100644
--- a/sql/rpl_filter.cc
+++ b/sql/rpl_filter.cc
@@ -157,8 +157,10 @@ Rpl_filter::db_ok(const char* db)
and db was not selected, do not replicate.
*/
if (!db)
+ {
+ DBUG_PRINT("exit", ("Don't replicate"));
DBUG_RETURN(0);
-
+ }
if (!do_db.is_empty()) // if the do's are not empty
{
I_List_iterator<i_string> it(do_db);
@@ -169,6 +171,7 @@ Rpl_filter::db_ok(const char* db)
if (!strcmp(tmp->ptr, db))
DBUG_RETURN(1); // match
}
+ DBUG_PRINT("exit", ("Don't replicate"));
DBUG_RETURN(0);
}
else // there are some elements in the don't, otherwise we cannot get here
@@ -179,7 +182,10 @@ Rpl_filter::db_ok(const char* db)
while ((tmp=it++))
{
if (!strcmp(tmp->ptr, db))
+ {
+ DBUG_PRINT("exit", ("Don't replicate"));
DBUG_RETURN(0); // match
+ }
}
DBUG_RETURN(1);
}
diff --git a/sql/scheduler.cc b/sql/scheduler.cc
index e0a7837de8e..5b8f834aecc 100644
--- a/sql/scheduler.cc
+++ b/sql/scheduler.cc
@@ -235,9 +235,7 @@ void thd_scheduler::thread_detach()
if (thread_attached)
{
THD* thd = (THD*)list.data;
- pthread_mutex_lock(&thd->LOCK_thd_data);
- thd->mysys_var= NULL;
- pthread_mutex_unlock(&thd->LOCK_thd_data);
+ thd->reset_globals();
thread_attached= FALSE;
#ifndef DBUG_OFF
/*
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 7eec4c3e41b..3a63e46399a 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -556,11 +556,11 @@ static sys_var_const sys_skip_networking(&vars, "skip_networking",
static sys_var_const sys_skip_show_database(&vars, "skip_show_database",
OPT_GLOBAL, SHOW_BOOL,
(uchar*) &opt_skip_show_db);
-#ifdef HAVE_SYS_UN_H
+
static sys_var_const sys_socket(&vars, "socket",
OPT_GLOBAL, SHOW_CHAR_PTR,
(uchar*) &mysqld_unix_port);
-#endif
+
#ifdef HAVE_THR_SETCONCURRENCY
/* purecov: begin tested */
static sys_var_const sys_thread_concurrency(&vars, "thread_concurrency",
@@ -652,6 +652,12 @@ static sys_var_long_ptr sys_table_cache_size(&vars, "table_open_cache",
&table_cache_size);
static sys_var_long_ptr sys_table_lock_wait_timeout(&vars, "table_lock_wait_timeout",
&table_lock_wait_timeout);
+
+#if defined(ENABLED_DEBUG_SYNC)
+/* Debug Sync Facility. Implemented in debug_sync.cc. */
+static sys_var_debug_sync sys_debug_sync(&vars, "debug_sync");
+#endif /* defined(ENABLED_DEBUG_SYNC) */
+
static sys_var_long_ptr sys_thread_cache_size(&vars, "thread_cache_size",
&thread_cache_size);
#if HAVE_POOL_OF_THREADS == 1
@@ -3449,8 +3455,7 @@ int set_var_init()
uint count= 0;
DBUG_ENTER("set_var_init");
- for (sys_var *var=vars.first; var; var= var->next, count++)
- ;
+ for (sys_var *var=vars.first; var; var= var->next, count++) ;
if (hash_init(&system_variable_hash, system_charset_info, count, 0,
0, (hash_get_key) get_sys_var_length, 0, HASH_UNIQUE))
@@ -4258,6 +4263,7 @@ end_with_read_lock:
}
+#ifndef DBUG_OFF
/* even session variable here requires SUPER, because of -#o,file */
bool sys_var_thd_dbug::check(THD *thd, set_var *var)
{
@@ -4305,6 +4311,8 @@ uchar *sys_var_thd_dbug::value_ptr(THD *thd, enum_var_type type, LEX_STRING *b)
}
return (uchar*) thd->strdup(buf);
}
+#endif /* DBUG_OFF */
+
#ifdef HAVE_EVENT_SCHEDULER
bool sys_var_event_scheduler::check(THD *thd, set_var *var)
diff --git a/sql/set_var.h b/sql/set_var.h
index f2c7c0ba30f..5b4760589af 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -634,6 +634,7 @@ public:
uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
};
+#ifndef DBUG_OFF
class sys_var_thd_dbug :public sys_var_thd
{
public:
@@ -647,8 +648,23 @@ public:
void set_default(THD *thd, enum_var_type type) { DBUG_POP(); }
uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *b);
};
+#endif /* DBUG_OFF */
-
+#if defined(ENABLED_DEBUG_SYNC)
+/* Debug Sync Facility. Implemented in debug_sync.cc. */
+class sys_var_debug_sync :public sys_var_thd
+{
+public:
+ sys_var_debug_sync(sys_var_chain *chain, const char *name_arg)
+ :sys_var_thd(name_arg)
+ { chain_sys_var(chain); }
+ bool check(THD *thd, set_var *var);
+ bool update(THD *thd, set_var *var);
+ SHOW_TYPE show_type() { return SHOW_CHAR; }
+ bool check_update_type(Item_result type) { return type != STRING_RESULT; }
+ uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+};
+#endif /* defined(ENABLED_DEBUG_SYNC) */
/* some variables that require special handling */
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 3a876899964..a8839425aa7 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -4702,7 +4702,7 @@ ER_NOT_SUPPORTED_YET 42000
swe "Denna version av MySQL kan ännu inte utföra '%s'"
ER_MASTER_FATAL_ERROR_READING_BINLOG
nla "Kreeg fatale fout %d: '%-.128s' van master tijdens lezen van data uit binaire log"
- eng "Got fatal error %d: '%-.128s' from master when reading data from binary log"
+ eng "Got fatal error %d from master when reading data from binary log: '%-.128s'"
ger "Schwerer Fehler %d: '%-.128s vom Master beim Lesen des binären Logs"
ita "Errore fatale %d: '%-.128s' dal master leggendo i dati dal log binario"
por "Obteve fatal erro %d: '%-.128s' do master quando lendo dados do binary log"
@@ -6233,3 +6233,10 @@ ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN
ER_CONST_EXPR_IN_VCOL
eng "Constant expression in computed column function is not allowed."
+
+ER_DEBUG_SYNC_TIMEOUT
+ eng "debug sync point wait timed out"
+ ger "Debug Sync Point Wartezeit überschritten"
+ER_DEBUG_SYNC_HIT_LIMIT
+ eng "debug sync point hit limit reached"
+ ger "Debug Sync Point Hit Limit erreicht"
diff --git a/sql/slave.cc b/sql/slave.cc
index 1595c5372cc..94e20b594fb 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1238,7 +1238,8 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
thd->db = (char*)db;
DBUG_ASSERT(thd->db != 0);
thd->db_length= strlen(thd->db);
- mysql_parse(thd, thd->query, packet_len, &found_semicolon); // run create table
+ /* run create table */
+ mysql_parse(thd, thd->query(), packet_len, &found_semicolon);
thd->db = save_db; // leave things the way the were before
thd->db_length= save_db_length;
thd->options = save_options;
@@ -2033,8 +2034,7 @@ static int has_temporary_error(THD *thd)
@retval 2 No error calling ev->apply_event(), but error calling
ev->update_pos().
*/
-int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
- bool skip)
+int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli)
{
int exec_res= 0;
@@ -2079,37 +2079,33 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
ev->when= my_time(0);
ev->thd = thd; // because up to this point, ev->thd == 0
- if (skip)
- {
- int reason= ev->shall_skip(rli);
- if (reason == Log_event::EVENT_SKIP_COUNT)
- --rli->slave_skip_counter;
- pthread_mutex_unlock(&rli->data_lock);
- if (reason == Log_event::EVENT_SKIP_NOT)
- exec_res= ev->apply_event(rli);
+ int reason= ev->shall_skip(rli);
+ if (reason == Log_event::EVENT_SKIP_COUNT)
+ --rli->slave_skip_counter;
+ pthread_mutex_unlock(&rli->data_lock);
+ if (reason == Log_event::EVENT_SKIP_NOT)
+ exec_res= ev->apply_event(rli);
+
#ifndef DBUG_OFF
- /*
- This only prints information to the debug trace.
+ /*
+ This only prints information to the debug trace.
- TODO: Print an informational message to the error log?
- */
- static const char *const explain[] = {
- // EVENT_SKIP_NOT,
- "not skipped",
- // EVENT_SKIP_IGNORE,
- "skipped because event should be ignored",
- // EVENT_SKIP_COUNT
- "skipped because event skip counter was non-zero"
- };
- DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d",
- thd->options & OPTION_BEGIN ? 1 : 0,
- rli->get_flag(Relay_log_info::IN_STMT)));
- DBUG_PRINT("skip_event", ("%s event was %s",
- ev->get_type_str(), explain[reason]));
+ TODO: Print an informational message to the error log?
+ */
+ static const char *const explain[] = {
+ // EVENT_SKIP_NOT,
+ "not skipped",
+ // EVENT_SKIP_IGNORE,
+ "skipped because event should be ignored",
+ // EVENT_SKIP_COUNT
+ "skipped because event skip counter was non-zero"
+ };
+ DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d",
+ thd->options & OPTION_BEGIN ? 1 : 0,
+ rli->get_flag(Relay_log_info::IN_STMT)));
+ DBUG_PRINT("skip_event", ("%s event was %s",
+ ev->get_type_str(), explain[reason]));
#endif
- }
- else
- exec_res= ev->apply_event(rli);
DBUG_PRINT("info", ("apply_event error = %d", exec_res));
if (exec_res == 0)
@@ -2229,7 +2225,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
delete ev;
DBUG_RETURN(1);
}
- exec_res= apply_event_and_update_pos(ev, thd, rli, TRUE);
+ exec_res= apply_event_and_update_pos(ev, thd, rli);
/*
Format_description_log_event should not be deleted because it will be
@@ -2629,15 +2625,19 @@ Log entry on master is longer than max_allowed_packet (%ld) on \
slave. If the entry is correct, restart the server with a higher value of \
max_allowed_packet",
thd->variables.max_allowed_packet);
+ mi->report(ERROR_LEVEL, ER_NET_PACKET_TOO_LARGE,
+ "%s", ER(ER_NET_PACKET_TOO_LARGE));
goto err;
case ER_MASTER_FATAL_ERROR_READING_BINLOG:
- sql_print_error(ER(mysql_error_number), mysql_error_number,
- mysql_error(mysql));
+ mi->report(ERROR_LEVEL, ER_MASTER_FATAL_ERROR_READING_BINLOG,
+ ER(ER_MASTER_FATAL_ERROR_READING_BINLOG),
+ mysql_error_number, mysql_error(mysql));
goto err;
- case EE_OUTOFMEMORY:
- case ER_OUTOFMEMORY:
+ case ER_OUT_OF_RESOURCES:
sql_print_error("\
Stopping slave I/O thread due to out-of-memory error from master");
+ mi->report(ERROR_LEVEL, ER_OUT_OF_RESOURCES,
+ "%s", ER(ER_OUT_OF_RESOURCES));
goto err;
}
if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
@@ -2746,9 +2746,11 @@ err:
pthread_cond_broadcast(&mi->stop_cond); // tell the world we are done
DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
pthread_mutex_unlock(&mi->run_lock);
+
+ DBUG_LEAVE; // Must match DBUG_ENTER()
my_thread_end();
pthread_exit(0);
- DBUG_RETURN(0); // Can't return anything here
+ return 0; // Avoid compiler warnings
}
/*
@@ -3104,10 +3106,11 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
pthread_cond_broadcast(&rli->stop_cond);
DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
pthread_mutex_unlock(&rli->run_lock); // tell the world we are done
-
+
+ DBUG_LEAVE; // Must match DBUG_ENTER()
my_thread_end();
pthread_exit(0);
- DBUG_RETURN(0); // Can't return anything here
+ return 0; // Avoid compiler warnings
}
@@ -3705,7 +3708,7 @@ extern "C" void slave_io_thread_detach_vio()
{
#ifdef SIGNAL_WITH_VIO_CLOSE
THD *thd= current_thd;
- if (thd->slave_thread)
+ if (thd && thd->slave_thread)
thd->clear_active_vio();
#endif
}
diff --git a/sql/slave.h b/sql/slave.h
index fe9694c2392..1a1cfcebd9b 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -191,8 +191,7 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset,
void set_slave_thread_options(THD* thd);
void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli);
void rotate_relay_log(Master_info* mi);
-int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
- bool skip);
+int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli);
pthread_handler_t handle_slave_io(void *arg);
pthread_handler_t handle_slave_sql(void *arg);
diff --git a/sql/sp.cc b/sql/sp.cc
index e281285b2e0..d4626dde38f 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -998,7 +998,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name)
if (ret == SP_OK)
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
sp_cache_invalidate();
}
@@ -1068,7 +1068,7 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
if (ret == SP_OK)
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
sp_cache_invalidate();
}
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 6656520b6ef..580ed900d8a 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -334,16 +334,18 @@ bool
sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
{
Item *expr_item;
+ enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
+ bool save_abort_on_warning= thd->abort_on_warning;
+ bool save_stmt_modified_non_trans_table=
+ thd->transaction.stmt.modified_non_trans_table;
DBUG_ENTER("sp_eval_expr");
if (!*expr_item_ptr)
- DBUG_RETURN(TRUE);
+ goto error;
if (!(expr_item= sp_prepare_func_item(thd, expr_item_ptr)))
- DBUG_RETURN(TRUE);
-
- bool err_status= FALSE;
+ goto error;
/*
Set THD flags to emit warnings/errors in case of overflow/type errors
@@ -352,10 +354,6 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
Save original values and restore them after save.
*/
- enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
- bool save_abort_on_warning= thd->abort_on_warning;
- bool save_stmt_modified_non_trans_table= thd->transaction.stmt.modified_non_trans_table;
-
thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
thd->abort_on_warning=
thd->variables.sql_mode &
@@ -370,13 +368,18 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
thd->abort_on_warning= save_abort_on_warning;
thd->transaction.stmt.modified_non_trans_table= save_stmt_modified_non_trans_table;
- if (thd->is_error())
- {
- /* Return error status if something went wrong. */
- err_status= TRUE;
- }
+ if (!thd->is_error())
+ DBUG_RETURN(FALSE);
- DBUG_RETURN(err_status);
+error:
+ /*
+ In case of error during evaluation, leave the result field set to NULL.
+ Sic: we can't do it in the beginning of the function because the
+ result field might be needed for its own re-evaluation, e.g. case of
+ set x = x + 1;
+ */
+ result_field->set_null();
+ DBUG_RETURN (TRUE);
}
@@ -1926,9 +1929,10 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (spvar->mode == sp_param_out)
{
Item_null *null_item= new Item_null();
+ Item *tmp_item= null_item;
if (!null_item ||
- nctx->set_variable(thd, i, (Item **)&null_item))
+ nctx->set_variable(thd, i, &tmp_item))
{
err_status= TRUE;
break;
@@ -2827,8 +2831,8 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
DBUG_ENTER("sp_instr_stmt::execute");
DBUG_PRINT("info", ("command: %d", m_lex_keeper.sql_command()));
- query= thd->query;
- query_length= thd->query_length;
+ query= thd->query();
+ query_length= thd->query_length();
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
/* This s-p instr is profilable and will be captured. */
thd->profiling.set_query_source(m_query.str, m_query.length);
@@ -2841,10 +2845,11 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
queries with SP vars can't be cached)
*/
if (unlikely((thd->options & OPTION_LOG_OFF)==0))
- general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
+ general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
if (query_cache_send_result_to_client(thd,
- thd->query, thd->query_length) <= 0)
+ thd->query(),
+ thd->query_length()) <= 0)
{
res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 5b6f7df7347..c9f107cd0bb 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -263,8 +263,7 @@ my_bool acl_init(bool dont_read_acl_tables)
acl_cache= new hash_filo(ACL_CACHE_SIZE, 0, 0,
(hash_get_key) acl_entry_get_key,
(hash_free_key) free,
- lower_case_file_system ?
- system_charset_info : &my_charset_bin);
+ &my_charset_utf8_bin);
if (dont_read_acl_tables)
{
DBUG_RETURN(0); /* purecov: tested */
@@ -2252,10 +2251,13 @@ public:
ulong sort;
size_t key_length;
GRANT_NAME(const char *h, const char *d,const char *u,
- const char *t, ulong p);
- GRANT_NAME (TABLE *form);
+ const char *t, ulong p, bool is_routine);
+ GRANT_NAME (TABLE *form, bool is_routine);
virtual ~GRANT_NAME() {};
virtual bool ok() { return privs != 0; }
+ void set_user_details(const char *h, const char *d,
+ const char *u, const char *t,
+ bool is_routine);
};
@@ -2273,38 +2275,48 @@ public:
};
-
-GRANT_NAME::GRANT_NAME(const char *h, const char *d,const char *u,
- const char *t, ulong p)
- :privs(p)
+void GRANT_NAME::set_user_details(const char *h, const char *d,
+ const char *u, const char *t,
+ bool is_routine)
{
/* Host given by user */
update_hostname(&host, strdup_root(&memex, h));
- db = strdup_root(&memex,d);
+ if (db != d)
+ {
+ db= strdup_root(&memex, d);
+ if (lower_case_table_names)
+ my_casedn_str(files_charset_info, db);
+ }
user = strdup_root(&memex,u);
sort= get_sort(3,host.hostname,db,user);
- tname= strdup_root(&memex,t);
- if (lower_case_table_names)
+ if (tname != t)
{
- my_casedn_str(files_charset_info, db);
- my_casedn_str(files_charset_info, tname);
+ tname= strdup_root(&memex, t);
+ if (lower_case_table_names || is_routine)
+ my_casedn_str(files_charset_info, tname);
}
key_length= strlen(d) + strlen(u)+ strlen(t)+3;
hash_key= (char*) alloc_root(&memex,key_length);
strmov(strmov(strmov(hash_key,user)+1,db)+1,tname);
}
+GRANT_NAME::GRANT_NAME(const char *h, const char *d,const char *u,
+ const char *t, ulong p, bool is_routine)
+ :db(0), tname(0), privs(p)
+{
+ set_user_details(h, d, u, t, is_routine);
+}
GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u,
const char *t, ulong p, ulong c)
- :GRANT_NAME(h,d,u,t,p), cols(c)
+ :GRANT_NAME(h,d,u,t,p, FALSE), cols(c)
{
(void) hash_init2(&hash_columns,4,system_charset_info,
0,0,0, (hash_get_key) get_key_column,0,0);
}
-GRANT_NAME::GRANT_NAME(TABLE *form)
+GRANT_NAME::GRANT_NAME(TABLE *form, bool is_routine)
{
update_hostname(&host, get_field(&memex, form->field[0]));
db= get_field(&memex,form->field[1]);
@@ -2322,6 +2334,9 @@ GRANT_NAME::GRANT_NAME(TABLE *form)
if (lower_case_table_names)
{
my_casedn_str(files_charset_info, db);
+ }
+ if (lower_case_table_names || is_routine)
+ {
my_casedn_str(files_charset_info, tname);
}
key_length= (strlen(db) + strlen(user) + strlen(tname) + 3);
@@ -2333,7 +2348,7 @@ GRANT_NAME::GRANT_NAME(TABLE *form)
GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs)
- :GRANT_NAME(form)
+ :GRANT_NAME(form, FALSE)
{
uchar key[MAX_KEY_LENGTH];
@@ -3186,7 +3201,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
if (!result) /* success */
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
rw_unlock(&LOCK_grant);
@@ -3329,7 +3344,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
}
grant_name= new GRANT_NAME(Str->host.str, db_name,
Str->user.str, table_name,
- rights);
+ rights, TRUE);
if (!grant_name)
{
result= TRUE;
@@ -3351,7 +3366,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
if (write_to_binlog)
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
rw_unlock(&LOCK_grant);
@@ -3463,7 +3478,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
if (!result)
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
rw_unlock(&LOCK_grant);
@@ -3540,10 +3555,10 @@ static my_bool grant_load_procs_priv(TABLE *p_table)
MEM_ROOT **save_mem_root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**,
THR_MALLOC);
DBUG_ENTER("grant_load_procs_priv");
- (void) hash_init(&proc_priv_hash,system_charset_info,
+ (void) hash_init(&proc_priv_hash, &my_charset_utf8_bin,
0,0,0, (hash_get_key) get_grant_table,
0,0);
- (void) hash_init(&func_priv_hash,system_charset_info,
+ (void) hash_init(&func_priv_hash, &my_charset_utf8_bin,
0,0,0, (hash_get_key) get_grant_table,
0,0);
p_table->file->ha_index_init(0, 1);
@@ -3557,7 +3572,7 @@ static my_bool grant_load_procs_priv(TABLE *p_table)
{
GRANT_NAME *mem_check;
HASH *hash;
- if (!(mem_check=new (memex_ptr) GRANT_NAME(p_table)))
+ if (!(mem_check=new (memex_ptr) GRANT_NAME(p_table, TRUE)))
{
/* This could only happen if we are out memory */
goto end_unlock;
@@ -3641,7 +3656,7 @@ static my_bool grant_load(THD *thd, TABLE_LIST *tables)
thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
- (void) hash_init(&column_priv_hash,system_charset_info,
+ (void) hash_init(&column_priv_hash, &my_charset_utf8_bin,
0,0,0, (hash_get_key) get_grant_table,
(hash_free_key) free_grant_table,0);
@@ -4076,8 +4091,7 @@ bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
db_name= table_ref->view_db.str;
table_name= table_ref->view_name.str;
if (table_ref->belong_to_view &&
- (thd->lex->sql_command == SQLCOM_SHOW_FIELDS ||
- thd->lex->sql_command == SQLCOM_SHOW_CREATE))
+ thd->lex->sql_command == SQLCOM_SHOW_FIELDS)
{
view_privs= get_column_grant(thd, grant, db_name, table_name, name);
if (view_privs & VIEW_ANY_ACL)
@@ -5441,9 +5455,21 @@ static int handle_grant_struct(uint struct_no, bool drop,
case 2:
case 3:
- grant_name->user= strdup_root(&mem, user_to->user.str);
- update_hostname(&grant_name->host,
- strdup_root(&mem, user_to->host.str));
+ /*
+ Update the grant structure with the new user name and
+ host name
+ */
+ grant_name->set_user_details(user_to->host.str, grant_name->db,
+ user_to->user.str, grant_name->tname,
+ TRUE);
+
+ /*
+ Since username is part of the hash key, when the user name
+ is renamed, the hash key is changed. Update the hash to
+ ensure that the position matches the new hash key value
+ */
+ hash_update(&column_priv_hash, (uchar*) grant_name,
+ (uchar*) grant_name->hash_key, grant_name->key_length);
break;
}
}
@@ -5666,7 +5692,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr_safe());
if (some_users_created)
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
@@ -5739,7 +5765,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe());
if (some_users_deleted)
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
@@ -5824,7 +5850,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe());
if (some_users_renamed && mysql_bin_log.is_open())
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
@@ -6006,7 +6032,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
VOID(pthread_mutex_unlock(&acl_cache->lock));
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
@@ -6120,7 +6146,7 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
for (counter= 0, revoked= 0 ; counter < hash->records ; )
{
GRANT_NAME *grant_proc= (GRANT_NAME*) hash_element(hash, counter);
- if (!my_strcasecmp(system_charset_info, grant_proc->db, sp_db) &&
+ if (!my_strcasecmp(&my_charset_utf8_bin, grant_proc->db, sp_db) &&
!my_strcasecmp(system_charset_info, grant_proc->tname, sp_name))
{
LEX_USER lex_user;
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index b6b8377ccc9..580a6f7246f 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -17,6 +17,7 @@
/* Basic functions needed by many modules */
#include "mysql_priv.h"
+#include "debug_sync.h"
#include "sql_select.h"
#include "sp_head.h"
#include "sp.h"
@@ -24,6 +25,7 @@
#include <m_ctype.h>
#include <my_dir.h>
#include <hash.h>
+#include "rpl_filter.h"
#ifdef __WIN__
#include <io.h>
#endif
@@ -106,7 +108,7 @@ static bool open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias,
static void close_old_data_files(THD *thd, TABLE *table, bool morph_locks,
bool send_refresh);
static bool
-has_two_write_locked_tables_with_auto_increment(TABLE_LIST *tables);
+has_write_table_with_auto_increment(TABLE_LIST *tables);
extern "C" uchar *table_cache_key(const uchar *record, size_t *length,
@@ -950,6 +952,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
close_old_data_files(thd,thd->open_tables,1,1);
mysql_ha_flush(thd);
+ DEBUG_SYNC(thd, "after_flush_unlock");
bool found=1;
/* Wait until all threads has closed all the tables we had locked */
@@ -1551,6 +1554,7 @@ void close_temporary_tables(THD *thd)
s_query.length() - 1 /* to remove trailing ',' */,
0, FALSE, 0);
qinfo.db= db.ptr();
+ qinfo.db_len= db.length();
thd->variables.character_set_client= cs_save;
mysql_bin_log.write(&qinfo);
thd->variables.pseudo_thread_id= save_pseudo_thread_id;
@@ -2319,7 +2323,8 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list, bool link_in)
table->tablenr=thd->current_tablenr++;
table->used_fields=0;
table->const_table=0;
- table->null_row= table->maybe_null= table->force_index= 0;
+ table->null_row= table->maybe_null= 0;
+ table->force_index= table->force_index_order= table->force_index_group= 0;
table->status=STATUS_NO_RECORD;
DBUG_RETURN(FALSE);
}
@@ -2977,7 +2982,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
table->tablenr=thd->current_tablenr++;
table->used_fields=0;
table->const_table=0;
- table->null_row= table->maybe_null= table->force_index= 0;
+ table->null_row= table->maybe_null= 0;
+ table->force_index= table->force_index_order= table->force_index_group= 0;
table->status=STATUS_NO_RECORD;
table->insert_values= 0;
table->fulltext_searched= 0;
@@ -5125,7 +5131,16 @@ static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table)
int decide_logging_format(THD *thd, TABLE_LIST *tables)
{
- if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
+ /*
+ In SBR mode, we are only proceeding if we are binlogging this
+ statement, ie, the filtering rules won't later filter this out.
+
+ This check here is needed to prevent some spurious error to be
+ raised in some cases (See BUG#42829).
+ */
+ if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG) &&
+ (thd->variables.binlog_format != BINLOG_FORMAT_STMT ||
+ binlog_filter->db_ok(thd->db)))
{
/*
Compute the starting vectors for the computations by creating a
@@ -5308,18 +5323,22 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
thd->in_lock_tables=1;
thd->options|= OPTION_TABLE_LOCK;
/*
- If we have >= 2 different tables to update with auto_inc columns,
- statement-based binlogging won't work. We can solve this problem in
- mixed mode by switching to row-based binlogging:
+ A query that modifies autoinc column in sub-statement can make the
+ master and slave inconsistent.
+ We can solve these problems in mixed mode by switching to binlogging
+ if at least one updated table is used by sub-statement
*/
- if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED &&
- has_two_write_locked_tables_with_auto_increment(tables))
+ /* The BINLOG_FORMAT_MIXED judgement is saved for suppressing
+ warnings, but it will be removed by fixing bug#45827 */
+ if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED && tables &&
+ has_write_table_with_auto_increment(thd->lex->first_not_own_table()))
{
thd->lex->set_stmt_unsafe();
- thd->set_current_stmt_binlog_row_based_if_mixed();
}
}
+ DEBUG_SYNC(thd, "before_lock_tables_takes_lock");
+
if (! (thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start),
lock_flag, need_reopen)))
{
@@ -5839,6 +5858,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
{
/* This is a base table. */
DBUG_ASSERT(nj_col->view_field == NULL);
+ Item *ref= 0;
/*
This fix_fields is not necessary (initially this item is fixed by
the Item_field constructor; after reopen_tables the Item_func_eq
@@ -5846,12 +5866,13 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
reopening for columns that was dropped by the concurrent connection.
*/
if (!nj_col->table_field->fixed &&
- nj_col->table_field->fix_fields(thd, (Item **)&nj_col->table_field))
+ nj_col->table_field->fix_fields(thd, &ref))
{
DBUG_PRINT("info", ("column '%s' was dropped by the concurrent connection",
nj_col->table_field->name));
DBUG_RETURN(NULL);
}
+ DBUG_ASSERT(ref == 0); // Should not have changed
DBUG_ASSERT(nj_col->table_ref->table == nj_col->table_field->field->table);
found_field= nj_col->table_field->field;
update_field_dependencies(thd, found_field, nj_col->table_ref->table);
@@ -8973,47 +8994,31 @@ void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table
/*
- Tells if two (or more) tables have auto_increment columns and we want to
- lock those tables with a write lock.
+ Check if one (or more) write tables have auto_increment columns.
- SYNOPSIS
- has_two_write_locked_tables_with_auto_increment
- tables Table list
+ @param[in] tables Table list
+
+ @retval 0 if at least one write tables has an auto_increment column
+ @retval 1 otherwise
NOTES:
Call this function only when you have established the list of all tables
which you'll want to update (including stored functions, triggers, views
inside your statement).
-
- RETURN
- 0 No
- 1 Yes
*/
static bool
-has_two_write_locked_tables_with_auto_increment(TABLE_LIST *tables)
+has_write_table_with_auto_increment(TABLE_LIST *tables)
{
- char *first_table_name= NULL, *first_db;
- LINT_INIT(first_db);
-
for (TABLE_LIST *table= tables; table; table= table->next_global)
{
/* we must do preliminary checks as table->table may be NULL */
if (!table->placeholder() &&
table->table->found_next_number_field &&
(table->lock_type >= TL_WRITE_ALLOW_WRITE))
- {
- if (first_table_name == NULL)
- {
- first_table_name= table->table_name;
- first_db= table->db;
- DBUG_ASSERT(first_db);
- }
- else if (strcmp(first_db, table->db) ||
- strcmp(first_table_name, table->table_name))
- return 1;
- }
+ return 1;
}
+
return 0;
}
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index 67f2912fe7b..07972d9b3e4 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -56,17 +56,20 @@ void mysql_client_binlog_statement(THD* thd)
Format_description_event.
*/
my_bool have_fd_event= TRUE;
- if (!thd->rli_fake)
+ int err;
+ Relay_log_info *rli;
+ rli= thd->rli_fake;
+ if (!rli)
{
- thd->rli_fake= new Relay_log_info;
+ rli= thd->rli_fake= new Relay_log_info;
#ifdef HAVE_valgrind
- thd->rli_fake->is_fake= TRUE;
+ rli->is_fake= TRUE;
#endif
have_fd_event= FALSE;
}
- if (thd->rli_fake && !thd->rli_fake->relay_log.description_event_for_exec)
+ if (rli && !rli->relay_log.description_event_for_exec)
{
- thd->rli_fake->relay_log.description_event_for_exec=
+ rli->relay_log.description_event_for_exec=
new Format_description_log_event(4);
have_fd_event= FALSE;
}
@@ -78,16 +81,16 @@ void mysql_client_binlog_statement(THD* thd)
/*
Out of memory check
*/
- if (!(thd->rli_fake &&
- thd->rli_fake->relay_log.description_event_for_exec &&
+ if (!(rli &&
+ rli->relay_log.description_event_for_exec &&
buf))
{
my_error(ER_OUTOFMEMORY, MYF(0), 1); /* needed 1 bytes */
goto end;
}
- thd->rli_fake->sql_thd= thd;
- thd->rli_fake->no_storage= TRUE;
+ rli->sql_thd= thd;
+ rli->no_storage= TRUE;
for (char const *strptr= thd->lex->comment.str ;
strptr < thd->lex->comment.str + thd->lex->comment.length ; )
@@ -170,8 +173,7 @@ void mysql_client_binlog_statement(THD* thd)
}
ev= Log_event::read_log_event(bufptr, event_len, &error,
- thd->rli_fake->relay_log.
- description_event_for_exec);
+ rli->relay_log.description_event_for_exec);
DBUG_PRINT("info",("binlog base64 err=%s", error));
if (!ev)
@@ -209,18 +211,10 @@ void mysql_client_binlog_statement(THD* thd)
reporting.
*/
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
- if (apply_event_and_update_pos(ev, thd, thd->rli_fake, FALSE))
- {
- delete ev;
- /*
- TODO: Maybe a better error message since the BINLOG statement
- now contains several events.
- */
- my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement");
- goto end;
- }
+ err= ev->apply_event(rli);
+#else
+ err= 0;
#endif
-
/*
Format_description_log_event should not be deleted because it
will be used to read info about the relay log's format; it
@@ -228,8 +222,17 @@ void mysql_client_binlog_statement(THD* thd)
i.e. when this thread terminates.
*/
if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
- delete ev;
+ delete ev;
ev= 0;
+ if (err)
+ {
+ /*
+ TODO: Maybe a better error message since the BINLOG statement
+ now contains several events.
+ */
+ my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement");
+ goto end;
+ }
}
}
@@ -238,7 +241,7 @@ void mysql_client_binlog_statement(THD* thd)
my_ok(thd);
end:
- thd->rli_fake->clear_tables_to_lock();
+ rli->clear_tables_to_lock();
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
DBUG_VOID_RETURN;
}
diff --git a/sql/sql_builtin.cc.in b/sql/sql_builtin.cc.in
index 3becdbaccfe..7ecd4918d7b 100644
--- a/sql/sql_builtin.cc.in
+++ b/sql/sql_builtin.cc.in
@@ -13,6 +13,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+#include <my_global.h>
#include <mysql/plugin.h>
typedef struct st_mysql_plugin builtin_plugin[];
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 3465362da01..f995b51ae68 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1119,8 +1119,8 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
DBUG_VOID_RETURN;
uint8 tables_type= 0;
- if ((local_tables= is_cacheable(thd, thd->query_length,
- thd->query, thd->lex, tables_used,
+ if ((local_tables= is_cacheable(thd, thd->query_length(),
+ thd->query(), thd->lex, tables_used,
&tables_type)))
{
NET *net= &thd->net;
@@ -1210,7 +1210,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
/* Key is query + database + flag */
if (thd->db_length)
{
- memcpy(thd->query+thd->query_length+1, thd->db, thd->db_length);
+ memcpy(thd->query() + thd->query_length() + 1, thd->db,
+ thd->db_length);
DBUG_PRINT("qcache", ("database: %s length: %u",
thd->db, (unsigned) thd->db_length));
}
@@ -1218,24 +1219,24 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
{
DBUG_PRINT("qcache", ("No active database"));
}
- tot_length= thd->query_length + thd->db_length + 1 +
+ tot_length= thd->query_length() + thd->db_length + 1 +
QUERY_CACHE_FLAGS_SIZE;
/*
We should only copy structure (don't use it location directly)
because of alignment issue
*/
- memcpy((void *)(thd->query + (tot_length - QUERY_CACHE_FLAGS_SIZE)),
+ memcpy((void*) (thd->query() + (tot_length - QUERY_CACHE_FLAGS_SIZE)),
&flags, QUERY_CACHE_FLAGS_SIZE);
/* Check if another thread is processing the same query? */
Query_cache_block *competitor = (Query_cache_block *)
- hash_search(&queries, (uchar*) thd->query, tot_length);
+ hash_search(&queries, (uchar*) thd->query(), tot_length);
DBUG_PRINT("qcache", ("competitor 0x%lx", (ulong) competitor));
if (competitor == 0)
{
/* Query is not in cache and no one is working with it; Store it */
Query_cache_block *query_block;
- query_block= write_block_data(tot_length, (uchar*) thd->query,
+ query_block= write_block_data(tot_length, (uchar*) thd->query(),
ALIGN_SIZE(sizeof(Query_cache_query)),
Query_cache_block::QUERY, local_tables);
if (query_block != 0)
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 6e876bb3a96..83108f58c68 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -42,6 +42,7 @@
#include "sp_rcontext.h"
#include "sp_cache.h"
+#include "debug_sync.h"
/*
The following is used to initialise Table_ident with a internal
@@ -431,14 +432,14 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length,
str.append(proc_info);
}
- if (thd->query)
+ if (thd->query())
{
if (max_query_len < 1)
- len= thd->query_length;
+ len= thd->query_length();
else
- len= min(thd->query_length, max_query_len);
+ len= min(thd->query_length(), max_query_len);
str.append('\n');
- str.append(thd->query, len);
+ str.append(thd->query(), len);
}
if (str.c_ptr_safe() == buffer)
return buffer;
@@ -455,6 +456,31 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length,
return buffer;
}
+
+/**
+ Implementation of Drop_table_error_handler::handle_error().
+ The reason in having this implementation is to silence technical low-level
+ warnings during DROP TABLE operation. Currently we don't want to expose
+ the following warnings during DROP TABLE:
+ - Some of table files are missed or invalid (the table is going to be
+ deleted anyway, so why bother that something was missed);
+ - A trigger associated with the table does not have DEFINER (One of the
+ MySQL specifics now is that triggers are loaded for the table being
+ dropped. So, we may have a warning that trigger does not have DEFINER
+ attribute during DROP TABLE operation).
+
+ @return TRUE if the condition is handled.
+*/
+bool Drop_table_error_handler::handle_error(uint sql_errno,
+ const char *message,
+ MYSQL_ERROR::enum_warning_level level,
+ THD *thd)
+{
+ return ((sql_errno == EE_DELETE && my_errno == ENOENT) ||
+ sql_errno == ER_TRG_NO_DEFINER);
+}
+
+
/**
Clear this diagnostics area.
@@ -617,6 +643,9 @@ THD::THD()
derived_tables_processing(FALSE),
spcont(NULL),
m_parser_state(NULL)
+#if defined(ENABLED_DEBUG_SYNC)
+ , debug_sync_control(0)
+#endif /* defined(ENABLED_DEBUG_SYNC) */
{
ulong tmp;
@@ -756,17 +785,13 @@ void THD::push_internal_handler(Internal_error_handler *handler)
bool THD::handle_error(uint sql_errno, const char *message,
MYSQL_ERROR::enum_warning_level level)
{
- if (!m_internal_handler)
- return FALSE;
-
for (Internal_error_handler *error_handler= m_internal_handler;
error_handler;
error_handler= m_internal_handler->m_prev_internal_handler)
{
if (error_handler->handle_error(sql_errno, message, level, this))
- return TRUE;
+ return TRUE;
}
-
return FALSE;
}
@@ -877,6 +902,10 @@ void THD::init(void)
/* Set to handle counting of aborted connections */
userstat_running= opt_userstat_running;
last_global_update_time= current_connect_time= time(NULL);
+#if defined(ENABLED_DEBUG_SYNC)
+ /* Initialize the Debug Sync Facility. See debug_sync.cc. */
+ debug_sync_init_thread(this);
+#endif /* defined(ENABLED_DEBUG_SYNC) */
}
@@ -1008,6 +1037,12 @@ void THD::cleanup(void)
close_thread_tables(this);
}
wt_thd_destroy(&transaction.wt);
+
+#if defined(ENABLED_DEBUG_SYNC)
+ /* End the Debug Sync Facility. See debug_sync.cc. */
+ debug_sync_end_thread(this);
+#endif /* defined(ENABLED_DEBUG_SYNC) */
+
mysql_ha_cleanup(this);
delete_dynamic(&user_var_events);
hash_free(&user_vars);
@@ -1291,6 +1326,19 @@ bool THD::store_globals()
}
+/**
+ Untie THD from current thread
+
+ Used when using --thread-handling=pool-of-threads
+*/
+
+void THD::reset_globals()
+{
+ pthread_mutex_lock(&LOCK_thd_data);
+ mysys_var= 0;
+ pthread_mutex_unlock(&LOCK_thd_data);
+}
+
/*
Cleanup after query.
@@ -2574,12 +2622,12 @@ Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
id(id_arg),
mark_used_columns(MARK_COLUMNS_READ),
lex(lex_arg),
- query(0),
- query_length(0),
cursor(0),
db(NULL),
db_length(0)
{
+ query_string.length= 0;
+ query_string.str= NULL;
name.str= NULL;
}
@@ -2595,8 +2643,7 @@ void Statement::set_statement(Statement *stmt)
id= stmt->id;
mark_used_columns= stmt->mark_used_columns;
lex= stmt->lex;
- query= stmt->query;
- query_length= stmt->query_length;
+ query_string= stmt->query_string;
cursor= stmt->cursor;
}
@@ -2620,6 +2667,15 @@ void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
}
+/** Assign a new value to thd->query. */
+
+void Statement::set_query_inner(char *query_arg, uint32 query_length_arg)
+{
+ query_string.str= query_arg;
+ query_string.length= query_length_arg;
+}
+
+
void THD::end_statement()
{
/* Cleanup SQL processing state to reuse this statement in next query. */
@@ -2855,9 +2911,11 @@ bool select_dumpvar::send_data(List<Item> &items)
else
{
Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item);
- suv->fix_fields(thd, 0);
+ if (suv->fix_fields(thd, 0))
+ DBUG_RETURN (1);
suv->save_item_result(item);
- suv->update();
+ if (suv->update())
+ DBUG_RETURN (1);
}
}
DBUG_RETURN(thd->is_error());
@@ -3134,9 +3192,24 @@ extern "C" struct charset_info_st *thd_charset(MYSQL_THD thd)
return(thd->charset());
}
+/**
+ OBSOLETE : there's no way to ensure the string is null terminated.
+ Use thd_query_string instead()
+*/
extern "C" char **thd_query(MYSQL_THD thd)
{
- return(&thd->query);
+ return(&thd->query_string.str);
+}
+
+/**
+ Get the current query string for the thread.
+
+ @param The MySQL internal thread pointer
+ @return query string and length. May be non-null-terminated.
+*/
+extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd)
+{
+ return(&thd->query_string);
}
extern "C" int thd_slave_thread(const MYSQL_THD thd)
@@ -3161,6 +3234,11 @@ extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all)
{
mark_transaction_to_rollback(thd, all);
}
+
+extern "C" bool thd_binlog_filter_ok(const MYSQL_THD thd)
+{
+ return binlog_filter->db_ok(thd->db);
+}
#endif // INNODB_COMPATIBILITY_HOOKS */
/****************************************************************************
@@ -3317,8 +3395,7 @@ void THD::set_statement(Statement *stmt)
void THD::set_query(char *query_arg, uint32 query_length_arg)
{
pthread_mutex_lock(&LOCK_thd_data);
- query= query_arg;
- query_length= query_length_arg;
+ set_query_inner(query_arg, query_length_arg);
pthread_mutex_unlock(&LOCK_thd_data);
}
@@ -3336,6 +3413,16 @@ void mark_transaction_to_rollback(THD *thd, bool all)
{
thd->is_fatal_sub_stmt_error= TRUE;
thd->transaction_rollback_request= all;
+ /*
+ Aborted transactions can not be IGNOREd.
+ Switch off the IGNORE flag for the current
+ SELECT_LEX. This should allow my_error()
+ to report the error and abort the execution
+ flow, even in presence
+ of IGNORE clause.
+ */
+ if (thd->lex->current_select)
+ thd->lex->current_select->no_error= FALSE;
}
}
/***************************************************************************
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 72fd927cc1e..2508a0bb0a9 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -95,6 +95,8 @@ extern char internal_table_name[2];
extern char empty_c_string[1];
extern MYSQL_PLUGIN_IMPORT const char **errmesg;
+extern bool volatile shutdown_in_progress;
+
#define TC_LOG_PAGE_SIZE 8192
#define TC_LOG_MIN_SIZE (3*TC_LOG_PAGE_SIZE)
@@ -661,10 +663,13 @@ public:
This printing is needed at least in SHOW PROCESSLIST and SHOW
ENGINE INNODB STATUS.
*/
- char *query;
- uint32 query_length; // current query length
+ LEX_STRING query_string;
Server_side_cursor *cursor;
+ inline char *query() { return query_string.str; }
+ inline uint32 query_length() { return query_string.length; }
+ void set_query_inner(char *query_arg, uint32 query_length_arg);
+
/**
Name of the current (default) database.
@@ -1112,6 +1117,31 @@ public:
/**
+ This class is an internal error handler implementation for
+ DROP TABLE statements. The thing is that there may be warnings during
+ execution of these statements, which should not be exposed to the user.
+ This class is intended to silence such warnings.
+*/
+
+class Drop_table_error_handler : public Internal_error_handler
+{
+public:
+ Drop_table_error_handler(Internal_error_handler *err_handler)
+ :m_err_handler(err_handler)
+ { }
+
+public:
+ bool handle_error(uint sql_errno,
+ const char *message,
+ MYSQL_ERROR::enum_warning_level level,
+ THD *thd);
+
+private:
+ Internal_error_handler *m_err_handler;
+};
+
+
+/**
Stores status of the currently executed statement.
Cleared at the beginning of the statement, and then
can hold either OK, ERROR, or EOF status.
@@ -1915,6 +1945,11 @@ public:
partition_info *work_part_info;
#endif
+#if defined(ENABLED_DEBUG_SYNC)
+ /* Debug Sync facility. See debug_sync.cc. */
+ struct st_debug_sync_control *debug_sync_control;
+#endif /* defined(ENABLED_DEBUG_SYNC) */
+
THD();
~THD();
@@ -1935,6 +1970,7 @@ public:
void cleanup(void);
void cleanup_after_query();
bool store_globals();
+ void reset_globals();
#ifdef SIGNAL_WITH_VIO_CLOSE
inline void set_active_vio(Vio* vio)
{
@@ -2153,7 +2189,11 @@ public:
{
int err= killed_errno();
if (err)
+ {
+ if ((err == KILL_CONNECTION) && !shutdown_in_progress)
+ err = KILL_QUERY;
my_message(err, ER(err), MYF(0));
+ }
}
/* return TRUE if we will abort query if we make a warning now */
inline bool really_abort_on_warning()
@@ -2669,7 +2709,32 @@ public:
ENGINE_COLUMNDEF *recinfo, *start_recinfo;
KEY *keyinfo;
ha_rows end_write_records;
- uint field_count,sum_func_count,func_count;
+ /**
+ Number of normal fields in the query, including those referred to
+ from aggregate functions. Hence, "SELECT `field1`,
+ SUM(`field2`) from t1" sets this counter to 2.
+
+ @see count_field_types
+ */
+ uint field_count;
+ /**
+ Number of fields in the query that have functions. Includes both
+ aggregate functions (e.g., SUM) and non-aggregates (e.g., RAND).
+ Also counts functions referred to from aggregate functions, i.e.,
+ "SELECT SUM(RAND())" sets this counter to 2.
+
+ @see count_field_types
+ */
+ uint func_count;
+ /**
+ Number of fields in the query that have aggregate functions. Note
+ that the optimizer may choose to optimize away these fields by
+ replacing them with constants, in which case sum_func_count will
+ need to be updated.
+
+ @see opt_sum_query, count_field_types
+ */
+ uint sum_func_count;
uint hidden_field_count;
uint group_parts,group_length,group_null_parts;
uint quick_group;
@@ -2934,7 +2999,8 @@ public:
bool send_data(List<Item> &items);
bool initialize_tables (JOIN *join);
void send_error(uint errcode,const char *err);
- int do_deletes();
+ int do_deletes();
+ int do_table_deletes(TABLE *table, bool ignore);
bool send_eof();
virtual void abort();
};
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 82f5bf48166..adc1aab9976 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -703,7 +703,7 @@ not_silent:
char *query;
uint query_length;
- if (!thd->query) // Only in replication
+ if (!thd->query()) // Only in replication
{
query= tmp_query;
query_length= (uint) (strxmov(tmp_query,"create database `",
@@ -711,8 +711,8 @@ not_silent:
}
else
{
- query= thd->query;
- query_length= thd->query_length;
+ query= thd->query();
+ query_length= thd->query_length();
}
ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB,
@@ -805,13 +805,13 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
}
ha_binlog_log_query(thd, 0, LOGCOM_ALTER_DB,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
db, "");
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, TRUE);
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0,
+ Query_log_event qinfo(thd, thd->query(), thd->query_length(), 0,
/* suppress_use */ TRUE, errcode);
/*
@@ -907,6 +907,9 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
remove_db_from_cache(db);
pthread_mutex_unlock(&LOCK_open);
+ Drop_table_error_handler err_handler(thd->get_internal_handler());
+ thd->push_internal_handler(&err_handler);
+
error= -1;
/*
We temporarily disable the binary log while dropping the objects
@@ -939,12 +942,13 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
error = 0;
reenable_binlog(thd);
}
+ thd->pop_internal_handler();
}
if (!silent && deleted>=0)
{
const char *query;
ulong query_length;
- if (!thd->query)
+ if (!thd->query())
{
/* The client used the old obsolete mysql_drop_db() call */
query= path;
@@ -953,8 +957,8 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
}
else
{
- query =thd->query;
- query_length= thd->query_length;
+ query= thd->query();
+ query_length= thd->query_length();
}
if (mysql_bin_log.is_open())
{
@@ -1444,7 +1448,7 @@ static inline bool
cmp_db_names(const char *db1_name,
const char *db2_name)
{
- return ((!db1_name && !db2_name) || /* db1 is NULL and db2 is NULL */
+ return ((!db1_name && !db2_name) ||
(db1_name && db2_name &&
my_strcasecmp(system_charset_info, db1_name, db2_name) == 0));
}
@@ -1956,7 +1960,7 @@ bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db)
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, TRUE);
- Query_log_event qinfo(thd, thd->query, thd->query_length,
+ Query_log_event qinfo(thd, thd->query(), thd->query_length(),
0, TRUE, errcode);
thd->clear_error();
mysql_bin_log.write(&qinfo);
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 8a5afa8da17..b6f45a08fe1 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -413,7 +413,7 @@ cleanup:
therefore be treated as a DDL.
*/
int log_result= thd->binlog_query(query_type,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
is_trans, FALSE, errcode);
if (log_result)
@@ -850,7 +850,7 @@ void multi_delete::abort()
{
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
transactional_tables, FALSE, errcode);
}
thd->transaction.all.modified_non_trans_table= true;
@@ -860,22 +860,19 @@ void multi_delete::abort()
-/*
+/**
Do delete from other tables.
- Returns values:
- 0 ok
- 1 error
+
+ @retval 0 ok
+ @retval 1 error
+
+ @todo Is there any reason not use the normal nested-loops join? If not, and
+ there is no documentation supporting it, this method and callee should be
+ removed and there should be hooks within normal execution.
*/
int multi_delete::do_deletes()
{
- int local_error= 0, counter= 0, tmp_error;
- bool will_batch;
- /*
- If the IGNORE option is used all non fatal errors will be translated
- to warnings and we should not break the row-by-row iteration
- */
- bool ignore= thd->lex->current_select->no_error;
DBUG_ENTER("do_deletes");
DBUG_ASSERT(do_delete);
@@ -886,79 +883,108 @@ int multi_delete::do_deletes()
table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
delete_tables);
- for (; table_being_deleted;
+ for (uint counter= 0; table_being_deleted;
table_being_deleted= table_being_deleted->next_local, counter++)
{
- ha_rows last_deleted= deleted;
TABLE *table = table_being_deleted->table;
if (tempfiles[counter]->get(table))
+ DBUG_RETURN(1);
+
+ int local_error=
+ do_table_deletes(table, thd->lex->current_select->no_error);
+
+ if (thd->killed && !local_error)
+ DBUG_RETURN(1);
+
+ if (local_error == -1) // End of file
+ local_error = 0;
+
+ if (local_error)
+ DBUG_RETURN(local_error);
+ }
+ DBUG_RETURN(0);
+}
+
+
+/**
+ Implements the inner loop of nested-loops join within multi-DELETE
+ execution.
+
+ @param table The table from which to delete.
+
+ @param ignore If used, all non fatal errors will be translated
+ to warnings and we should not break the row-by-row iteration.
+
+ @return Status code
+
+ @retval 0 All ok.
+ @retval 1 Triggers or handler reported error.
+ @retval -1 End of file from handler.
+*/
+int multi_delete::do_table_deletes(TABLE *table, bool ignore)
+{
+ int local_error= 0;
+ READ_RECORD info;
+ ha_rows last_deleted= deleted;
+ DBUG_ENTER("do_deletes_for_table");
+ init_read_record(&info, thd, table, NULL, 0, 1, FALSE);
+ /*
+ Ignore any rows not found in reference tables as they may already have
+ been deleted by foreign key handling
+ */
+ info.ignore_not_found_rows= 1;
+ bool will_batch= !table->file->start_bulk_delete();
+ while (!(local_error= info.read_record(&info)) && !thd->killed)
+ {
+ if (table->triggers &&
+ table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
+ TRG_ACTION_BEFORE, FALSE))
{
- local_error=1;
+ local_error= 1;
break;
}
-
- READ_RECORD info;
- init_read_record(&info, thd, table, NULL, 0, 1, FALSE);
+
+ local_error= table->file->ha_delete_row(table->record[0]);
+ if (local_error && !ignore)
+ {
+ table->file->print_error(local_error, MYF(0));
+ break;
+ }
+
/*
- Ignore any rows not found in reference tables as they may already have
- been deleted by foreign key handling
+ Increase the reported number of deleted rows only if no error occurred
+ during ha_delete_row.
+ Also, don't execute the AFTER trigger if the row operation failed.
*/
- info.ignore_not_found_rows= 1;
- will_batch= !table->file->start_bulk_delete();
- while (!(local_error=info.read_record(&info)) && !thd->killed)
+ if (!local_error)
{
+ deleted++;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
- TRG_ACTION_BEFORE, FALSE))
+ TRG_ACTION_AFTER, FALSE))
{
local_error= 1;
break;
}
-
- local_error= table->file->ha_delete_row(table->record[0]);
- if (local_error && !ignore)
- {
- table->file->print_error(local_error,MYF(0));
- break;
- }
-
- /*
- Increase the reported number of deleted rows only if no error occurred
- during ha_delete_row.
- Also, don't execute the AFTER trigger if the row operation failed.
- */
- if (!local_error)
- {
- deleted++;
- if (table->triggers &&
- table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
- TRG_ACTION_AFTER, FALSE))
- {
- local_error= 1;
- break;
- }
- }
}
- if (will_batch && (tmp_error= table->file->end_bulk_delete()))
+ }
+ if (will_batch)
+ {
+ int tmp_error= table->file->end_bulk_delete();
+ if (tmp_error && !local_error)
{
- if (!local_error)
- {
- local_error= tmp_error;
- table->file->print_error(local_error,MYF(0));
- }
+ local_error= tmp_error;
+ table->file->print_error(local_error, MYF(0));
}
- if (last_deleted != deleted && !table->file->has_transactions())
- thd->transaction.stmt.modified_non_trans_table= TRUE;
- end_read_record(&info);
- if (thd->killed && !local_error)
- local_error= 1;
- if (local_error == -1) // End of file
- local_error = 0;
}
+ if (last_deleted != deleted && !table->file->has_transactions())
+ thd->transaction.stmt.modified_non_trans_table= TRUE;
+
+ end_read_record(&info);
+
DBUG_RETURN(local_error);
}
-
/*
Send ok to the client
@@ -998,7 +1024,7 @@ bool multi_delete::send_eof()
else
errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
transactional_tables, FALSE, errcode) &&
!normal_tables)
{
@@ -1073,8 +1099,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
/* If it is a temporary table, close and regenerate it */
if (!dont_send_ok && (table= find_temporary_table(thd, table_list)))
{
- handlerton *table_type= table->s->db_type();
TABLE_SHARE *share= table->s;
+ handlerton *table_type= share->db_type();
if (!ha_check_storage_engine_flag(table_type, HTON_CAN_RECREATE))
goto trunc_by_del;
@@ -1088,7 +1114,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
if ((error= (int) !(open_temporary_table(thd, share->path.str,
share->db.str,
share->table_name.str, 1))))
- (void) rm_temporary_table(table_type, path);
+ (void) rm_temporary_table(table_type, share->path.str);
else
thd->thread_specific_used= TRUE;
@@ -1144,7 +1170,7 @@ end:
TRUNCATE must always be statement-based binlogged (not row-based) so
we don't test current_stmt_binlog_row_based.
*/
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
my_ok(thd); // This should return record count
}
VOID(pthread_mutex_lock(&LOCK_open));
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 8edf4f0d266..2f3ce99ab9c 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -422,16 +422,13 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
String buffer(buff, sizeof(buff), system_charset_info);
int error, keyno= -1;
uint num_rows;
- uchar *key;
- uint key_len;
+ uchar *UNINIT_VAR(key);
+ uint UNINIT_VAR(key_len);
bool need_reopen;
DBUG_ENTER("mysql_ha_read");
DBUG_PRINT("enter",("'%s'.'%s' as '%s'",
tables->db, tables->table_name, tables->alias));
- LINT_INIT(key);
- LINT_INIT(key_len);
-
thd->lex->select_lex.context.resolve_in_table_list_only(tables);
list.push_front(new Item_field(&thd->lex->select_lex.context,
NULL, NULL, "*"));
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index f22c39d403e..278d0485c45 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -592,7 +592,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
Name_resolution_context *context;
Name_resolution_context_state ctx_state;
#ifndef EMBEDDED_LIBRARY
- char *query= thd->query;
+ char *query= thd->query();
/*
log_on is about delayed inserts only.
By default, both logs are enabled (this won't cause problems if the server
@@ -829,7 +829,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
#ifndef EMBEDDED_LIBRARY
if (lock_type == TL_WRITE_DELAYED)
{
- LEX_STRING const st_query = { query, thd->query_length };
+ LEX_STRING const st_query = { query, thd->query_length() };
error=write_delayed(thd, table, duplic, st_query, ignore, log_on);
query=0;
}
@@ -922,7 +922,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
*/
DBUG_ASSERT(thd->killed != THD::KILL_BAD_DATA || error > 0);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
transactional_table, FALSE,
errcode))
{
@@ -1795,7 +1795,7 @@ public:
pthread_cond_destroy(&cond);
pthread_cond_destroy(&cond_client);
thd.unlink(); // Must be unlinked under lock
- x_free(thd.query);
+ x_free(thd.query());
thd.security_ctx->user= thd.security_ctx->host=0;
thread_count--;
delayed_insert_threads--;
@@ -1941,7 +1941,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
pthread_mutex_unlock(&LOCK_thread_count);
di->thd.set_db(table_list->db, (uint) strlen(table_list->db));
di->thd.set_query(my_strdup(table_list->table_name, MYF(MY_WME)), 0);
- if (di->thd.db == NULL || di->thd.query == NULL)
+ if (di->thd.db == NULL || di->thd.query() == NULL)
{
/* The error is reported */
delete di;
@@ -1950,7 +1950,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
}
di->table_list= *table_list; // Needed to open table
/* Replace volatile strings with local copies */
- di->table_list.alias= di->table_list.table_name= di->thd.query;
+ di->table_list.alias= di->table_list.table_name= di->thd.query();
di->table_list.db= di->thd.db;
di->lock();
pthread_mutex_lock(&di->mutex);
@@ -2283,6 +2283,7 @@ void kill_delayed_threads(void)
while ((di= it++))
{
di->thd.killed= THD::KILL_CONNECTION;
+ pthread_mutex_lock(&di->thd.LOCK_thd_data);
if (di->thd.mysys_var)
{
pthread_mutex_lock(&di->thd.mysys_var->mutex);
@@ -2301,49 +2302,15 @@ void kill_delayed_threads(void)
}
pthread_mutex_unlock(&di->thd.mysys_var->mutex);
}
+ pthread_mutex_unlock(&di->thd.LOCK_thd_data);
}
VOID(pthread_mutex_unlock(&LOCK_delayed_insert)); // For unlink from list
}
-/*
- * Create a new delayed insert thread
-*/
-
-pthread_handler_t handle_delayed_insert(void *arg)
+static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
{
- Delayed_insert *di=(Delayed_insert*) arg;
- THD *thd= &di->thd;
-
- pthread_detach_this_thread();
- /* Add thread to THD list so that's it's visible in 'show processlist' */
- pthread_mutex_lock(&LOCK_thread_count);
- thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
- thd->set_current_time();
- threads.append(thd);
- thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED;
- pthread_mutex_unlock(&LOCK_thread_count);
-
- /*
- Wait until the client runs into pthread_cond_wait(),
- where we free it after the table is opened and di linked in the list.
- If we did not wait here, the client might detect the opened table
- before it is linked to the list. It would release LOCK_delayed_create
- and allow another thread to create another handler for the same table,
- since it does not find one in the list.
- */
- pthread_mutex_lock(&di->mutex);
-#if !defined( __WIN__) /* Win32 calls this in pthread_create */
- if (my_thread_init())
- {
- /* Can't use my_error since store_globals has not yet been called */
- thd->main_da.set_error_status(thd, ER_OUT_OF_RESOURCES,
- ER(ER_OUT_OF_RESOURCES));
- goto end;
- }
-#endif
-
- DBUG_ENTER("handle_delayed_insert");
+ DBUG_ENTER("handle_delayed_insert_impl");
thd->thread_stack= (char*) &thd;
if (init_thr_lock() || thd->store_globals())
{
@@ -2532,6 +2499,49 @@ err:
*/
ha_autocommit_or_rollback(thd, 1);
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ * Create a new delayed insert thread
+*/
+
+pthread_handler_t handle_delayed_insert(void *arg)
+{
+ Delayed_insert *di=(Delayed_insert*) arg;
+ THD *thd= &di->thd;
+
+ pthread_detach_this_thread();
+ /* Add thread to THD list so that's it's visible in 'show processlist' */
+ pthread_mutex_lock(&LOCK_thread_count);
+ thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
+ thd->set_current_time();
+ threads.append(thd);
+ thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED;
+ pthread_mutex_unlock(&LOCK_thread_count);
+
+ /*
+ Wait until the client runs into pthread_cond_wait(),
+ where we free it after the table is opened and di linked in the list.
+ If we did not wait here, the client might detect the opened table
+ before it is linked to the list. It would release LOCK_delayed_create
+ and allow another thread to create another handler for the same table,
+ since it does not find one in the list.
+ */
+ pthread_mutex_lock(&di->mutex);
+#if !defined( __WIN__) /* Win32 calls this in pthread_create */
+ if (my_thread_init())
+ {
+ /* Can't use my_error since store_globals has not yet been called */
+ thd->main_da.set_error_status(thd, ER_OUT_OF_RESOURCES,
+ ER(ER_OUT_OF_RESOURCES));
+ goto end;
+ }
+#endif
+
+ handle_delayed_insert_impl(thd, di);
+
#ifndef __WIN__
end:
#endif
@@ -2556,7 +2566,8 @@ end:
my_thread_end();
pthread_exit(0);
- DBUG_RETURN(0);
+
+ return 0;
}
@@ -3273,7 +3284,7 @@ bool select_insert::send_eof()
else
errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
trans_table, FALSE, errcode);
}
table->file->ha_release_auto_increment();
@@ -3343,7 +3354,8 @@ void select_insert::abort() {
if (mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
- thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
+ thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(),
+ thd->query_length(),
transactional_table, FALSE, errcode);
}
if (!thd->current_stmt_binlog_row_based && !can_rollback_data())
@@ -3441,10 +3453,12 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
Create_field *cr_field;
Field *field, *def_field;
if (item->type() == Item::FUNC_ITEM)
+ {
if (item->result_type() != STRING_RESULT)
field= item->tmp_table_field(&tmp_table);
else
field= item->tmp_table_field_from_field_type(&tmp_table, 0);
+ }
else
field= create_tmp_field(thd, &tmp_table, item, item->type(),
(Item ***) 0, &tmp_field, &def_field, 0, 0, 0, 0,
@@ -3635,7 +3649,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
DBUG_EXECUTE_IF("sleep_create_select_before_check_if_exists", my_sleep(6000000););
if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
- create_table->table->db_stat)
+ (create_table->table && create_table->table->db_stat))
{
/* Table already exists and was open at open_and_lock_tables() stage. */
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 0b57a442746..e67be64c847 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1746,13 +1746,6 @@ typedef struct st_lex : public Query_tables_list
const char *stmt_definition_end;
- /*
- Pointers to part of LOAD DATA statement that should be rewritten
- during replication ("LOCAL 'filename' REPLACE INTO" part).
- */
- const char *fname_start;
- const char *fname_end;
-
/**
During name resolution search only in the table list given by
Name_resolution_context::first_name_resolution_table and
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 1929c233f23..2467116d8dc 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -83,10 +83,13 @@ static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
String &enclosed, ulong skip_lines,
bool ignore_check_option_errors);
#ifndef EMBEDDED_LIBRARY
-static bool write_execute_load_query_log_event(THD *thd,
- bool duplicates, bool ignore,
- bool transactional_table,
- int errcode);
+static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
+ const char* db_arg, /* table's database */
+ const char* table_name_arg,
+ enum enum_duplicates duplicates,
+ bool ignore,
+ bool transactional_table,
+ int errocode);
#endif /* EMBEDDED_LIBRARY */
/*
@@ -497,8 +500,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
if (thd->transaction.stmt.modified_non_trans_table)
- write_execute_load_query_log_event(thd, handle_duplicates,
- ignore, transactional_table,
+ write_execute_load_query_log_event(thd, ex,
+ table_list->db,
+ table_list->table_name,
+ handle_duplicates, ignore,
+ transactional_table,
errcode);
else
{
@@ -542,8 +548,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (lf_info.wrote_create_file)
{
int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
- write_execute_load_query_log_event(thd, handle_duplicates, ignore,
- transactional_table, errcode);
+ write_execute_load_query_log_event(thd, ex,
+ table_list->db, table_list->table_name,
+ handle_duplicates, ignore,
+ transactional_table,
+ errcode);
}
}
}
@@ -564,15 +573,113 @@ err:
#ifndef EMBEDDED_LIBRARY
/* Not a very useful function; just to avoid duplication of code */
-static bool write_execute_load_query_log_event(THD *thd,
- bool duplicates, bool ignore,
- bool transactional_table,
+static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
+ const char* db_arg, /* table's database */
+ const char* table_name_arg,
+ enum enum_duplicates duplicates,
+ bool ignore,
+ bool transactional_table,
int errcode)
{
+ char *load_data_query,
+ *end,
+ *fname_start,
+ *fname_end,
+ *p= NULL;
+ size_t pl= 0;
+ List<Item> fv;
+ Item *item, *val;
+ String pfield, pfields;
+ int n;
+ const char *tbl= table_name_arg;
+ const char *tdb= (thd->db != NULL ? thd->db : db_arg);
+ String string_buf;
+
+ if (!thd->db || strcmp(db_arg, thd->db))
+ {
+ /*
+ If used database differs from table's database,
+ prefix table name with database name so that it
+ becomes a FQ name.
+ */
+ string_buf.set_charset(system_charset_info);
+ string_buf.append(db_arg);
+ string_buf.append("`");
+ string_buf.append(".");
+ string_buf.append("`");
+ string_buf.append(table_name_arg);
+ tbl= string_buf.c_ptr_safe();
+ }
+
+ Load_log_event lle(thd, ex, tdb, tbl, fv, duplicates,
+ ignore, transactional_table);
+
+ /*
+ force in a LOCAL if there was one in the original.
+ */
+ if (thd->lex->local_file)
+ lle.set_fname_outside_temp_buf(ex->file_name, strlen(ex->file_name));
+
+ /*
+ prepare fields-list and SET if needed; print_query won't do that for us.
+ */
+ if (!thd->lex->field_list.is_empty())
+ {
+ List_iterator<Item> li(thd->lex->field_list);
+
+ pfields.append(" (");
+ n= 0;
+
+ while ((item= li++))
+ {
+ if (n++)
+ pfields.append(", ");
+ if (item->name)
+ pfields.append(item->name);
+ else
+ item->print(&pfields, QT_ORDINARY);
+ }
+ pfields.append(")");
+ }
+
+ if (!thd->lex->update_list.is_empty())
+ {
+ List_iterator<Item> lu(thd->lex->update_list);
+ List_iterator<Item> lv(thd->lex->value_list);
+
+ pfields.append(" SET ");
+ n= 0;
+
+ while ((item= lu++))
+ {
+ val= lv++;
+ if (n++)
+ pfields.append(", ");
+ pfields.append(item->name);
+ pfields.append("=");
+ val->print(&pfields, QT_ORDINARY);
+ }
+ }
+
+ p= pfields.c_ptr_safe();
+ pl= strlen(p);
+
+ if (!(load_data_query= (char *)thd->alloc(lle.get_query_buffer_length() + 1 + pl)))
+ return TRUE;
+
+ lle.print_query(FALSE, (const char *) ex->cs?ex->cs->csname:NULL,
+ load_data_query, &end,
+ (char **)&fname_start, (char **)&fname_end);
+
+ strcpy(end, p);
+ end += pl;
+
+ thd->set_query_inner(load_data_query, end - load_data_query);
+
Execute_load_query_log_event
- e(thd, thd->query, thd->query_length,
- (uint) ((char*)thd->lex->fname_start - (char*)thd->query),
- (uint) ((char*)thd->lex->fname_end - (char*)thd->query),
+ e(thd, thd->query(), thd->query_length(),
+ (uint) ((char*) fname_start - (char*) thd->query() - 1),
+ (uint) ((char*) fname_end - (char*) thd->query()),
(duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
(ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
transactional_table, FALSE, errcode);
diff --git a/sql/sql_locale.cc b/sql/sql_locale.cc
index 3def9864c29..5ddf65cd1b7 100644
--- a/sql/sql_locale.cc
+++ b/sql/sql_locale.cc
@@ -1309,9 +1309,9 @@ static const char *my_locale_month_names_ro_RO[13] =
static const char *my_locale_ab_month_names_ro_RO[13] =
{"ian","feb","mar","apr","mai","iun","iul","aug","sep","oct","nov","dec", NullS };
static const char *my_locale_day_names_ro_RO[8] =
- {"Luni","Marţi","Miercuri","Joi","Vineri","SîmbĂtĂ","DuminicĂ", NullS };
+ {"Luni","Marţi","Miercuri","Joi","Vineri","Sâmbătă","Duminică", NullS };
static const char *my_locale_ab_day_names_ro_RO[8] =
- {"Lu","Ma","Mi","Jo","Vi","Sî","Du", NullS };
+ {"Lu","Ma","Mi","Jo","Vi","Sâ","Du", NullS };
static TYPELIB my_locale_typelib_month_names_ro_RO =
{ array_elements(my_locale_month_names_ro_RO)-1, "", my_locale_month_names_ro_RO, NULL };
static TYPELIB my_locale_typelib_ab_month_names_ro_RO =
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 5754b823a91..739ac692772 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -126,6 +126,14 @@ static bool xa_trans_rolled_back(XID_STATE *xid_state)
*/
static bool xa_trans_rollback(THD *thd)
{
+ /*
+ Resource Manager error is meaningless at this point, as we perform
+ explicit rollback request by user. We must reset rm_error before
+ calling ha_rollback(), so thd->transaction.xid structure gets reset
+ by ha_rollback()/THD::transaction::cleanup().
+ */
+ thd->transaction.xid_state.rm_error= 0;
+
bool status= test(ha_rollback(thd));
thd->options&= ~(ulong) OPTION_BEGIN;
@@ -133,7 +141,6 @@ static bool xa_trans_rollback(THD *thd)
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
xid_cache_delete(&thd->transaction.xid_state);
thd->transaction.xid_state.xa_state= XA_NOTR;
- thd->transaction.xid_state.rm_error= 0;
return status;
}
@@ -419,29 +426,12 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
}
-/**
- Execute commands from bootstrap_file.
-
- Used when creating the initial grant tables.
-*/
-
-pthread_handler_t handle_bootstrap(void *arg)
+static void handle_bootstrap_impl(THD *thd)
{
- THD *thd=(THD*) arg;
FILE *file=bootstrap_file;
char *buff;
const char* found_semicolon= NULL;
- /* The following must be called before DBUG_ENTER */
- thd->thread_stack= (char*) &thd;
- if (my_thread_init() || thd->store_globals())
- {
-#ifndef EMBEDDED_LIBRARY
- close_connection(thd, ER_OUT_OF_RESOURCES, 1);
-#endif
- thd->fatal_error();
- goto end;
- }
DBUG_ENTER("handle_bootstrap");
#ifndef EMBEDDED_LIBRARY
@@ -468,7 +458,7 @@ pthread_handler_t handle_bootstrap(void *arg)
thd->init_for_queries();
while (fgets(buff, thd->net.max_packet, file))
{
- char *query, *res;
+ char *query;
/* strlen() can't be deleted because fgets() doesn't return length */
ulong length= (ulong) strlen(buff);
while (buff[length-1] != '\n' && !feof(file))
@@ -509,10 +499,10 @@ pthread_handler_t handle_bootstrap(void *arg)
thd->db_length + 1 +
QUERY_CACHE_FLAGS_SIZE);
thd->set_query(query, length);
- DBUG_PRINT("query",("%-.4096s",thd->query));
+ DBUG_PRINT("query",("%-.4096s", thd->query()));
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
thd->profiling.start_new_query();
- thd->profiling.set_query_source(thd->query, length);
+ thd->profiling.set_query_source(thd->query(), length);
#endif
/*
@@ -521,7 +511,7 @@ pthread_handler_t handle_bootstrap(void *arg)
*/
thd->query_id=next_query_id();
thd->set_time();
- mysql_parse(thd, thd->query, length, & found_semicolon);
+ mysql_parse(thd, thd->query(), length, & found_semicolon);
close_thread_tables(thd); // Free tables
bootstrap_error= thd->is_error();
@@ -540,6 +530,33 @@ pthread_handler_t handle_bootstrap(void *arg)
#endif
}
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ Execute commands from bootstrap_file.
+
+ Used when creating the initial grant tables.
+*/
+
+pthread_handler_t handle_bootstrap(void *arg)
+{
+ THD *thd=(THD*) arg;
+
+ /* The following must be called before DBUG_ENTER */
+ thd->thread_stack= (char*) &thd;
+ if (my_thread_init() || thd->store_globals())
+ {
+#ifndef EMBEDDED_LIBRARY
+ close_connection(thd, ER_OUT_OF_RESOURCES, 1);
+#endif
+ thd->fatal_error();
+ goto end;
+ }
+
+ handle_bootstrap_impl(thd);
+
end:
net_end(&thd->net);
thd->cleanup();
@@ -554,7 +571,8 @@ end:
my_thread_end();
pthread_exit(0);
#endif
- DBUG_RETURN(0);
+
+ return 0;
}
/**
@@ -1216,20 +1234,20 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
if (alloc_query(thd, packet, packet_length))
break; // fatal error is set
- char *packet_end= thd->query + thd->query_length;
+ char *packet_end= thd->query() + thd->query_length();
/* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */
const char* end_of_stmt= NULL;
- general_log_write(thd, command, thd->query, thd->query_length);
- DBUG_PRINT("query",("%-.4096s",thd->query));
+ general_log_write(thd, command, thd->query(), thd->query_length());
+ DBUG_PRINT("query",("%-.4096s",thd->query()));
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
- thd->profiling.set_query_source(thd->query, thd->query_length);
+ thd->profiling.set_query_source(thd->query(), thd->query_length());
#endif
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
- mysql_parse(thd, thd->query, thd->query_length, &end_of_stmt);
+ mysql_parse(thd, thd->query(), thd->query_length(), &end_of_stmt);
while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
{
@@ -1441,7 +1459,28 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (check_global_access(thd,RELOAD_ACL))
break;
general_log_print(thd, command, NullS);
- if (!reload_acl_and_cache(thd, options, (TABLE_LIST*) 0, &not_used))
+#ifndef DBUG_OFF
+ bool debug_simulate= FALSE;
+ DBUG_EXECUTE_IF("simulate_detached_thread_refresh", debug_simulate= TRUE;);
+ if (debug_simulate)
+ {
+ /*
+ Simulate a reload without a attached thread session.
+ Provides a environment similar to that of when the
+ server receives a SIGHUP signal and reloads caches
+ and flushes tables.
+ */
+ bool res;
+ my_pthread_setspecific_ptr(THR_THD, NULL);
+ res= reload_acl_and_cache(NULL, options | REFRESH_FAST,
+ NULL, &not_used);
+ my_pthread_setspecific_ptr(THR_THD, thd);
+ if (!res)
+ my_ok(thd);
+ break;
+ }
+#endif
+ if (!reload_acl_and_cache(thd, options, NULL, &not_used))
my_ok(thd);
break;
}
@@ -1680,7 +1719,8 @@ void log_slow_statement(THD *thd)
{
thd_proc_info(thd, "logging slow query");
thd->status_var.long_query_count++;
- slow_log_print(thd, thd->query, thd->query_length, end_utime_of_query);
+ slow_log_print(thd, thd->query(), thd->query_length(),
+ end_utime_of_query);
}
}
DBUG_VOID_RETURN;
@@ -3008,7 +3048,7 @@ end_with_restore_list:
/*
Presumably, REPAIR and binlog writing doesn't require synchronization
*/
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
select_lex->table_list.first= (uchar*) first_table;
lex->query_tables=all_tables;
@@ -3042,7 +3082,7 @@ end_with_restore_list:
/*
Presumably, ANALYZE and binlog writing doesn't require synchronization
*/
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
select_lex->table_list.first= (uchar*) first_table;
lex->query_tables=all_tables;
@@ -3066,7 +3106,7 @@ end_with_restore_list:
/*
Presumably, OPTIMIZE and binlog writing doesn't require synchronization
*/
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
select_lex->table_list.first= (uchar*) first_table;
lex->query_tables=all_tables;
@@ -4018,7 +4058,7 @@ end_with_restore_list:
*/
if (!lex->no_write_to_binlog && write_to_binlog)
{
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
}
my_ok(thd);
}
@@ -4595,7 +4635,7 @@ create_sp_error:
case SP_KEY_NOT_FOUND:
if (lex->drop_if_exists)
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
SP_COM_STRING(lex), lex->spname->m_name.str);
@@ -5129,8 +5169,6 @@ bool check_single_table_access(THD *thd, ulong privilege,
/* Show only 1 table for check_grant */
if (!(all_tables->belong_to_view &&
(thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) &&
- !(all_tables->view &&
- all_tables->effective_algorithm == VIEW_ALGORITHM_TMPTABLE) &&
check_grant(thd, privilege, all_tables, 0, 1, no_errors))
goto deny;
@@ -6012,9 +6050,10 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
PROCESSLIST.
Note that we don't need LOCK_thread_count to modify query_length.
*/
- if (*found_semicolon &&
- (thd->query_length= (ulong)(*found_semicolon - thd->query)))
- thd->query_length--;
+ if (*found_semicolon && (ulong) (*found_semicolon - thd->query()))
+ thd->set_query_inner(thd->query(),
+ (uint32) (*found_semicolon -
+ thd->query() - 1));
/* Actually execute the query */
if (*found_semicolon)
{
@@ -6322,6 +6361,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->table_name_length=table->table.length;
ptr->lock_type= lock_type;
ptr->updating= test(table_options & TL_OPTION_UPDATING);
+ /* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */
ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
ptr->derived= table->sel;
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 0a15cac2cca..076ff96ca88 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -4078,7 +4078,7 @@ static int fast_end_partition(THD *thd, ulonglong copied,
if ((!is_empty) && (!written_bin_log) &&
(!thd->lex->no_write_to_binlog))
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
(ulong) (copied + deleted),
@@ -6236,7 +6236,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_CRASH("crash_drop_partition_5") ||
((!thd->lex->no_write_to_binlog) &&
(write_bin_log(thd, FALSE,
- thd->query, thd->query_length), FALSE)) ||
+ thd->query(), thd->query_length()), FALSE)) ||
ERROR_INJECT_CRASH("crash_drop_partition_6") ||
((frm_install= TRUE), FALSE) ||
mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) ||
@@ -6303,7 +6303,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_CRASH("crash_add_partition_5") ||
((!thd->lex->no_write_to_binlog) &&
(write_bin_log(thd, FALSE,
- thd->query, thd->query_length), FALSE)) ||
+ thd->query(), thd->query_length()), FALSE)) ||
ERROR_INJECT_CRASH("crash_add_partition_6") ||
write_log_rename_frm(lpt) ||
(not_completed= FALSE) ||
@@ -6393,7 +6393,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_CRASH("crash_change_partition_6") ||
((!thd->lex->no_write_to_binlog) &&
(write_bin_log(thd, FALSE,
- thd->query, thd->query_length), FALSE)) ||
+ thd->query(), thd->query_length()), FALSE)) ||
ERROR_INJECT_CRASH("crash_change_partition_7") ||
mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) ||
ERROR_INJECT_CRASH("crash_change_partition_8") ||
@@ -7210,4 +7210,3 @@ void create_subpartition_name(char *out, const char *in1,
"#SP#", transl_subpart_name, "#REN#", NullS);
}
#endif
-
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 28b7a4b2bb5..646cb2e8563 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1536,7 +1536,7 @@ error:
void plugin_shutdown(void)
{
- uint i, count= plugin_array.elements, free_slots= 0;
+ uint i, count= plugin_array.elements;
struct st_plugin_int **plugins, *plugin;
struct st_plugin_dl **dl;
DBUG_ENTER("plugin_shutdown");
@@ -1557,18 +1557,13 @@ void plugin_shutdown(void)
while (reap_needed && (count= plugin_array.elements))
{
reap_plugins();
- for (i= free_slots= 0; i < count; i++)
+ for (i= 0; i < count; i++)
{
plugin= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
- switch (plugin->state) {
- case PLUGIN_IS_READY:
+ if (plugin->state == PLUGIN_IS_READY)
+ {
plugin->state= PLUGIN_IS_DELETED;
reap_needed= true;
- break;
- case PLUGIN_IS_FREED:
- case PLUGIN_IS_UNINITIALIZED:
- free_slots++;
- break;
}
}
if (!reap_needed)
@@ -1581,9 +1576,6 @@ void plugin_shutdown(void)
}
}
- if (count > free_slots && global_system_variables.log_warnings > 1)
- sql_print_warning("Forcing shutdown of %d plugins", count - free_slots);
-
plugins= (struct st_plugin_int **) my_alloca(sizeof(void*) * (count+1));
/*
@@ -1605,8 +1597,8 @@ void plugin_shutdown(void)
if (!(plugins[i]->state & (PLUGIN_IS_UNINITIALIZED | PLUGIN_IS_FREED |
PLUGIN_IS_DISABLED)))
{
- sql_print_information("Plugin '%s' will be forced to shutdown",
- plugins[i]->name.str);
+ sql_print_warning("Plugin '%s' will be forced to shutdown",
+ plugins[i]->name.str);
/*
We are forcing deinit on plugins so we don't want to do a ref_count
check until we have processed all the plugins.
@@ -2090,7 +2082,7 @@ static int check_func_set(THD *thd, struct st_mysql_sys_var *var,
const char *strvalue= "NULL", *str;
TYPELIB *typelib;
ulonglong result;
- uint error_len;
+ uint error_len= 0; // init as only set on error
bool not_used;
int length;
@@ -2689,7 +2681,9 @@ uchar* sys_var_pluginvar::value_ptr(THD *thd, enum_var_type type,
{
if (!(value & mask))
continue;
- str.append(typelib->type_names[i], typelib->type_lengths[i]);
+ str.append(typelib->type_names[i], typelib->type_lengths
+ ? typelib->type_lengths[i]
+ : strlen(typelib->type_names[i]));
str.append(',');
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 07604b7974f..56f8311e1f6 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -752,7 +752,7 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array,
const String *res;
DBUG_ENTER("insert_params_with_log");
- if (query->copy(stmt->query, stmt->query_length, default_charset_info))
+ if (query->copy(stmt->query(), stmt->query_length(), default_charset_info))
DBUG_RETURN(1);
for (Item_param **it= begin; it < end; ++it)
@@ -914,7 +914,7 @@ static bool emb_insert_params_with_log(Prepared_statement *stmt,
DBUG_ENTER("emb_insert_params_with_log");
- if (query->copy(stmt->query, stmt->query_length, default_charset_info))
+ if (query->copy(stmt->query(), stmt->query_length(), default_charset_info))
DBUG_RETURN(1);
for (; it < end; ++it, ++client_param)
@@ -1065,7 +1065,7 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
DBUG_ENTER("insert_params_from_vars");
- if (query->copy(stmt->query, stmt->query_length, default_charset_info))
+ if (query->copy(stmt->query(), stmt->query_length(), default_charset_info))
DBUG_RETURN(1);
for (Item_param **it= begin; it < end; ++it)
@@ -2346,6 +2346,9 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
/* Fix ORDER list */
for (order= (ORDER *)sl->order_list.first; order; order= order->next)
order->item= &order->item_ptr;
+
+ /* clear the no_error flag for INSERT/UPDATE IGNORE */
+ sl->no_error= FALSE;
}
{
SELECT_LEX_UNIT *unit= sl->master_unit();
@@ -2461,9 +2464,9 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
}
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
- thd->profiling.set_query_source(stmt->query, stmt->query_length);
+ thd->profiling.set_query_source(stmt->query(), stmt->query_length());
#endif
- DBUG_PRINT("exec_query", ("%s", stmt->query));
+ DBUG_PRINT("exec_query", ("%s", stmt->query()));
DBUG_PRINT("info",("stmt: 0x%lx", (long) stmt));
sp_cache_flush_obsolete(&thd->sp_proc_cache);
@@ -3033,7 +3036,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
old_stmt_arena= thd->stmt_arena;
thd->stmt_arena= this;
- Parser_state parser_state(thd, thd->query, thd->query_length);
+ Parser_state parser_state(thd, thd->query(), thd->query_length());
parser_state.m_lip.stmt_prepare_mode= TRUE;
lex_start(thd);
@@ -3122,7 +3125,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
the general log.
*/
if (thd->spcont == NULL)
- general_log_write(thd, COM_STMT_PREPARE, query, query_length);
+ general_log_write(thd, COM_STMT_PREPARE, query(), query_length());
}
DBUG_RETURN(error);
}
@@ -3313,7 +3316,7 @@ Prepared_statement::reprepare()
return TRUE;
error= ((name.str && copy.set_name(&name)) ||
- copy.prepare(query, query_length) ||
+ copy.prepare(query(), query_length()) ||
validate_metadata(&copy));
if (cur_db_changed)
@@ -3551,8 +3554,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
to point at it even after we restore from backup. This is ok, as
expanded query was allocated in thd->mem_root.
*/
- stmt_backup.query= thd->query;
- stmt_backup.query_length= thd->query_length;
+ stmt_backup.set_query_inner(thd->query(), thd->query_length());
/*
At first execution of prepared statement we may perform logical
@@ -3577,8 +3579,8 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
Note that multi-statements cannot exist here (they are not supported in
prepared statements).
*/
- if (query_cache_send_result_to_client(thd, thd->query,
- thd->query_length) <= 0)
+ if (query_cache_send_result_to_client(thd, thd->query(),
+ thd->query_length()) <= 0)
{
error= mysql_execute_command(thd);
}
@@ -3623,7 +3625,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
the general log.
*/
if (error == 0 && thd->spcont == NULL)
- general_log_write(thd, COM_STMT_EXECUTE, thd->query, thd->query_length);
+ general_log_write(thd, COM_STMT_EXECUTE, thd->query(), thd->query_length());
error:
flags&= ~ (uint) IS_IN_USE;
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 0e0b8eb60b9..dac96f2e9c4 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -177,7 +177,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
/* Lets hope this doesn't fail as the result will be messy */
if (!silent && !error)
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
my_ok(thd);
}
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 06489d8bbd3..f05147d4146 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -623,7 +623,7 @@ impossible position";
*/
{
log.error=0;
- bool read_packet = 0, fatal_error = 0;
+ bool read_packet = 0;
#ifndef DBUG_OFF
if (max_binlog_dump_events && !left_events--)
@@ -645,7 +645,7 @@ impossible position";
*/
pthread_mutex_lock(log_lock);
- switch (Log_event::read_log_event(&log, packet, (pthread_mutex_t*)0)) {
+ switch (error= Log_event::read_log_event(&log, packet, (pthread_mutex_t*) 0)) {
case 0:
/* we read successfully, so we'll need to send it to the slave */
pthread_mutex_unlock(log_lock);
@@ -671,8 +671,8 @@ impossible position";
default:
pthread_mutex_unlock(log_lock);
- fatal_error = 1;
- break;
+ test_for_non_eof_log_read_errors(error, &errmsg);
+ goto err;
}
if (read_packet)
@@ -701,12 +701,6 @@ impossible position";
*/
}
- if (fatal_error)
- {
- errmsg = "error reading log entry";
- my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
- goto err;
- }
log.error=0;
}
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index f903c193270..014402733c7 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -159,6 +159,7 @@ static int join_read_const_table(JOIN_TAB *tab, POSITION *pos);
static int join_read_system(JOIN_TAB *tab);
static int join_read_const(JOIN_TAB *tab);
static int join_read_key(JOIN_TAB *tab);
+static void join_read_key_unlock_row(st_join_table *tab);
static int join_read_always_key(JOIN_TAB *tab);
static int join_read_last_key(JOIN_TAB *tab);
static int join_no_more_records(READ_RECORD *info);
@@ -643,6 +644,18 @@ JOIN::prepare(Item ***rref_pointer_array,
MYF(0)); /* purecov: inspected */
goto err; /* purecov: inspected */
}
+ if (thd->lex->derived_tables)
+ {
+ my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE",
+ thd->lex->derived_tables & DERIVED_VIEW ?
+ "view" : "subquery");
+ goto err;
+ }
+ if (thd->lex->sql_command != SQLCOM_SELECT)
+ {
+ my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "non-SELECT");
+ goto err;
+ }
}
if (!procedure && result && result->prepare(fields_list, unit_arg))
@@ -654,8 +667,11 @@ JOIN::prepare(Item ***rref_pointer_array,
this->group= group_list != 0;
unit= unit_arg;
+ if (tmp_table_param.sum_func_count && !group_list)
+ implicit_grouping= TRUE;
+
#ifdef RESTRICTED_GROUP
- if (sum_func_count && !group_list && (func_count || field_count))
+ if (implicit_grouping)
{
my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
goto err;
@@ -891,15 +907,23 @@ JOIN::optimize()
}
#endif
- /* Optimize count(*), min() and max() */
- if (tables_list && tmp_table_param.sum_func_count && ! group_list)
+ /*
+ Try to optimize count(*), min() and max() to const fields if
+ there is implicit grouping (aggregate functions but no
+ group_list). In this case, the result set shall only contain one
+ row.
+ */
+ if (tables_list && implicit_grouping)
{
int res;
/*
opt_sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
to the WHERE conditions,
- or 1 if all items were resolved,
+ or 1 if all items were resolved (optimized away),
or 0, or an error number HA_ERR_...
+
+ If all items were resolved by opt_sum_query, there is no need to
+ open any tables.
*/
if ((res=opt_sum_query(select_lex->leaf_tables, all_fields, conds)))
{
@@ -968,6 +992,12 @@ JOIN::optimize()
DBUG_RETURN(1);
}
+ if (select_lex->olap == ROLLUP_TYPE && rollup_process_const_fields())
+ {
+ DBUG_PRINT("error", ("Error: rollup_process_fields() failed"));
+ DBUG_RETURN(1);
+ }
+
/* Remove distinct if only const tables */
select_distinct= select_distinct && (const_tables != tables);
thd_proc_info(thd, "preparing");
@@ -1098,7 +1128,7 @@ JOIN::optimize()
join_tab[const_tables].select->quick->get_type() !=
QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX))
{
- if (group_list &&
+ if (group_list && rollup.state == ROLLUP::STATE_NONE &&
list_contains_unique_index(join_tab[const_tables].table,
find_field_in_order_list,
(void *) group_list))
@@ -1142,7 +1172,8 @@ JOIN::optimize()
if (! hidden_group_fields && rollup.state == ROLLUP::STATE_NONE)
select_distinct=0;
}
- else if (select_distinct && tables - const_tables == 1)
+ else if (select_distinct && tables - const_tables == 1 &&
+ rollup.state == ROLLUP::STATE_NONE)
{
/*
We are only using one table. In this case we change DISTINCT to a
@@ -1241,13 +1272,22 @@ JOIN::optimize()
(!group_list && tmp_table_param.sum_func_count))
order=0;
- // Can't use sort on head table if using row cache
+ // Can't use sort on head table if using join buffering
if (full_join)
{
- if (group_list)
- simple_group=0;
- if (order)
- simple_order=0;
+ TABLE *stable= (sort_by_table == (TABLE *) 1 ?
+ join_tab[const_tables].table : sort_by_table);
+ /*
+ FORCE INDEX FOR ORDER BY can be used to prevent join buffering when
+ sorting on the first table.
+ */
+ if (!stable || !stable->force_index_order)
+ {
+ if (group_list)
+ simple_group= 0;
+ if (order)
+ simple_order= 0;
+ }
}
/*
@@ -1533,12 +1573,8 @@ JOIN::optimize()
}
}
- /*
- If this join belongs to an uncacheable subquery save
- the original join
- */
- if (select_lex->uncacheable && !is_top_level_join() &&
- init_save_join_tab())
+ /* If this join belongs to an uncacheable query save the original join */
+ if (select_lex->uncacheable && init_save_join_tab())
DBUG_RETURN(-1); /* purecov: inspected */
}
@@ -2039,7 +2075,8 @@ JOIN::exec()
count_field_types(select_lex, &curr_join->tmp_table_param,
*curr_all_fields, 0);
- if (curr_join->group || curr_join->tmp_table_param.sum_func_count ||
+ if (curr_join->group || curr_join->implicit_grouping ||
+ curr_join->tmp_table_param.sum_func_count ||
(procedure && (procedure->flags & PROC_GROUP)))
{
if (make_group_fields(this, curr_join))
@@ -2274,7 +2311,7 @@ JOIN::destroy()
tab->cleanup();
}
tmp_join->tmp_join= 0;
- tmp_table_param.copy_field=0;
+ tmp_table_param.cleanup();
DBUG_RETURN(tmp_join->destroy());
}
cond_equal= 0;
@@ -3379,12 +3416,12 @@ add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
@retval FALSE it's something else
*/
-inline static bool
+static bool
is_local_field (Item *field)
{
- field= field->real_item();
- return field->type() == Item::FIELD_ITEM &&
- !((Item_field *)field)->depended_from;
+ return field->real_item()->type() == Item::FIELD_ITEM
+ && !(field->used_tables() & OUTER_REF_TABLE_BIT)
+ && !((Item_field *)field->real_item())->depended_from;
}
@@ -3586,8 +3623,9 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
{
if (!field->eq(item->field))
{
+ Item *tmp_item= item;
add_key_field(key_fields, *and_level, cond_func, field,
- TRUE, (Item **) &item, 1, usable_tables,
+ TRUE, &tmp_item, 1, usable_tables,
sargables);
}
}
@@ -3629,7 +3667,7 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
{
if (!(form->keys_in_use_for_query.is_set(key)))
continue;
- if (form->key_info[key].flags & HA_FULLTEXT)
+ if (form->key_info[key].flags & (HA_FULLTEXT | HA_SPATIAL))
continue; // ToDo: ft-keys in non-ft queries. SerG
uint key_parts= (uint) form->key_info[key].key_parts;
@@ -5677,7 +5715,9 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
}
j->ref.key_buff2=j->ref.key_buff+ALIGN_SIZE(length);
j->ref.key_err=1;
+ j->ref.has_record= FALSE;
j->ref.null_rejecting= 0;
+ j->ref.use_count= 0;
keyuse=org_keyuse;
store_key **ref_key= j->ref.key_copy;
@@ -6511,6 +6551,20 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
DBUG_RETURN(0);
}
+
+/**
+ The default implementation of unlock-row method of READ_RECORD,
+ used in all access methods.
+*/
+
+void rr_unlock_row(st_join_table *tab)
+{
+ READ_RECORD *info= &tab->read_record;
+ info->file->unlock_row();
+}
+
+
+
static void
make_join_readinfo(JOIN *join, ulonglong options)
{
@@ -6526,6 +6580,7 @@ make_join_readinfo(JOIN *join, ulonglong options)
TABLE *table=tab->table;
tab->read_record.table= table;
tab->read_record.file=table->file;
+ tab->read_record.unlock_row= rr_unlock_row;
tab->next_select=sub_select; /* normal select */
/*
@@ -6571,6 +6626,7 @@ make_join_readinfo(JOIN *join, ulonglong options)
delete tab->quick;
tab->quick=0;
tab->read_first_record= join_read_key;
+ tab->read_record.unlock_row= join_read_key_unlock_row;
tab->read_record.read_record= join_no_more_records;
if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread)
@@ -8882,7 +8938,7 @@ static uint reset_nj_counters(JOIN *join, List<TABLE_LIST> *join_list)
// ~join->eliminated_tables);
nested_join->n_tables= reset_nj_counters(join, &nested_join->join_list);
}
- if (table->table && (table->table->map & ~join->eliminated_tables))
+ if (!table->table || (table->table->map & ~join->eliminated_tables))
n++;
}
DBUG_RETURN(n);
@@ -9046,7 +9102,10 @@ static void restore_prev_nj_state(JOIN_TAB *last)
join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
else if (last_emb->nested_join->n_tables-1 ==
last_emb->nested_join->counter)
+ {
join->cur_embedding_map|= last_emb->nested_join->nj_map;
+ break;
+ }
else
break;
last_emb= last_emb->embedding;
@@ -9493,8 +9552,47 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
new_field->set_derivation(item->collation.derivation);
break;
case DECIMAL_RESULT:
- new_field= Field_new_decimal::new_decimal_field(item);
+ {
+ uint8 dec= item->decimals;
+ uint8 intg= ((Item_decimal *) item)->decimal_precision() - dec;
+ uint32 len= item->max_length;
+
+ /*
+ Trying to put too many digits overall in a DECIMAL(prec,dec)
+ will always throw a warning. We must limit dec to
+ DECIMAL_MAX_SCALE however to prevent an assert() later.
+ */
+
+ if (dec > 0)
+ {
+ signed int overflow;
+
+ dec= min(dec, DECIMAL_MAX_SCALE);
+
+ /*
+ If the value still overflows the field with the corrected dec,
+ we'll throw out decimals rather than integers. This is still
+ bad and of course throws a truncation warning.
+ +1: for decimal point
+ */
+
+ const int required_length=
+ my_decimal_precision_to_length(intg + dec, dec,
+ item->unsigned_flag);
+
+ overflow= required_length - len;
+
+ if (overflow > 0)
+ dec= max(0, dec - overflow); // too long, discard fract
+ else
+ /* Corrected value fits. */
+ len= required_length;
+ }
+
+ new_field= new Field_new_decimal(len, maybe_null, item->name,
+ dec, item->unsigned_flag);
break;
+ }
case ROW_RESULT:
default:
// This case should never be choosen
@@ -10307,6 +10405,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
for (; cur_group ; cur_group= cur_group->next, key_part_info++)
{
Field *field=(*cur_group->item)->get_tmp_table_field();
+ DBUG_ASSERT(field->table == table);
bool maybe_null=(*cur_group->item)->maybe_null;
key_part_info->null_bit=0;
key_part_info->field= field;
@@ -11067,6 +11166,12 @@ Next_select_func setup_end_select_func(JOIN *join)
}
else
{
+ /*
+ Choose method for presenting result to user. Use end_send_group
+ if the query requires grouping (has a GROUP BY clause and/or one or
+ more aggregate functions). Use end_send if the query should not
+ be grouped.
+ */
if ((join->sort_and_group ||
(join->procedure && join->procedure->flags & PROC_GROUP)) &&
!tmp_tbl->precomputed_group_by)
@@ -11435,6 +11540,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
bool not_used_in_distinct=join_tab->not_used_in_distinct;
ha_rows found_records=join->found_records;
COND *select_cond= join_tab->select_cond;
+ bool select_cond_result= TRUE;
if (error > 0 || (join->thd->is_error())) // Fatal error
return NESTED_LOOP_ERROR;
@@ -11446,8 +11552,19 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
return NESTED_LOOP_KILLED; /* purecov: inspected */
}
DBUG_PRINT("info", ("select cond 0x%lx", (ulong)select_cond));
- update_virtual_fields(join_tab->table);
- if (!select_cond || select_cond->val_int())
+
+ update_virtual_fields(join_tab->table);
+
+ if (select_cond)
+ {
+ select_cond_result= test(select_cond->val_int());
+
+ /* check for errors evaluating the condition */
+ if (join->thd->is_error())
+ return NESTED_LOOP_ERROR;
+ }
+
+ if (!select_cond || select_cond_result)
{
/*
There is no select condition or the attached pushed down
@@ -11531,7 +11648,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
return NESTED_LOOP_NO_MORE_ROWS;
}
else
- join_tab->read_record.file->unlock_row();
+ join_tab->read_record.unlock_row(join_tab);
}
else
{
@@ -11541,7 +11658,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
*/
join->examined_rows++;
join->thd->row_count++;
- join_tab->read_record.file->unlock_row();
+ join_tab->read_record.unlock_row(join_tab);
}
return NESTED_LOOP_OK;
}
@@ -11925,18 +12042,55 @@ join_read_key(JOIN_TAB *tab)
table->status=STATUS_NOT_FOUND;
return -1;
}
+ /*
+ Moving away from the current record. Unlock the row
+ in the handler if it did not match the partial WHERE.
+ */
+ if (tab->ref.has_record && tab->ref.use_count == 0)
+ {
+ tab->read_record.file->unlock_row();
+ tab->ref.has_record= FALSE;
+ }
error= table->file->ha_index_read_map(table->record[0],
tab->ref.key_buff,
make_prev_keypart_map(tab->ref.key_parts),
HA_READ_KEY_EXACT);
if (error && error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
return report_error(table, error);
+
+ if (! error)
+ {
+ tab->ref.has_record= TRUE;
+ tab->ref.use_count= 1;
+ }
+ }
+ else if (table->status == 0)
+ {
+ DBUG_ASSERT(tab->ref.has_record);
+ tab->ref.use_count++;
}
table->null_row=0;
return table->status ? -1 : 0;
}
+/**
+ Since join_read_key may buffer a record, do not unlock
+ it if it was not used in this invocation of join_read_key().
+ Only count locks, thus remembering if the record was left unused,
+ and unlock already when pruning the current value of
+ TABLE_REF buffer.
+ @sa join_read_key()
+*/
+
+static void
+join_read_key_unlock_row(st_join_table *tab)
+{
+ DBUG_ASSERT(tab->ref.use_count);
+ if (tab->ref.use_count)
+ tab->ref.use_count--;
+}
+
/*
ref access method implementation: "read_first" function
@@ -14006,7 +14160,10 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
if (error)
{
if (error == HA_ERR_RECORD_DELETED)
- continue;
+ {
+ error= file->ha_rnd_next(record);
+ continue;
+ }
if (error == HA_ERR_END_OF_FILE)
break;
goto err;
@@ -15760,7 +15917,11 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
DBUG_RETURN(TRUE);
if (!cond->fixed)
- cond->fix_fields(thd, (Item**)&cond);
+ {
+ Item *tmp_item= (Item*) cond;
+ cond->fix_fields(thd, &tmp_item);
+ DBUG_ASSERT(cond == tmp_item);
+ }
if (join_tab->select)
{
error=(int) cond->add(join_tab->select->cond);
@@ -15935,32 +16096,7 @@ bool JOIN::rollup_init()
{
item->maybe_null= 1;
found_in_group= 1;
- if (item->const_item())
- {
- /*
- For ROLLUP queries each constant item referenced in GROUP BY list
- is wrapped up into an Item_func object yielding the same value
- as the constant item. The objects of the wrapper class are never
- considered as constant items and besides they inherit all
- properties of the Item_result_field class.
- This wrapping allows us to ensure writing constant items
- into temporary tables whenever the result of the ROLLUP
- operation has to be written into a temporary table, e.g. when
- ROLLUP is used together with DISTINCT in the SELECT list.
- Usually when creating temporary tables for a intermidiate
- result we do not include fields for constant expressions.
- */
- Item* new_item= new Item_func_rollup_const(item);
- if (!new_item)
- return 1;
- new_item->fix_fields(thd, (Item **) 0);
- thd->change_item_tree(it.ref(), new_item);
- for (ORDER *tmp= group_tmp; tmp; tmp= tmp->next)
- {
- if (*tmp->item == item)
- thd->change_item_tree(tmp->item, new_item);
- }
- }
+ break;
}
}
if (item->type() == Item::FUNC_ITEM && !found_in_group)
@@ -15979,6 +16115,59 @@ bool JOIN::rollup_init()
}
return 0;
}
+
+/**
+ Wrap all constant Items in GROUP BY list.
+
+ For ROLLUP queries each constant item referenced in GROUP BY list
+ is wrapped up into an Item_func object yielding the same value
+ as the constant item. The objects of the wrapper class are never
+ considered as constant items and besides they inherit all
+ properties of the Item_result_field class.
+ This wrapping allows us to ensure writing constant items
+ into temporary tables whenever the result of the ROLLUP
+ operation has to be written into a temporary table, e.g. when
+ ROLLUP is used together with DISTINCT in the SELECT list.
+ Usually when creating temporary tables for a intermidiate
+ result we do not include fields for constant expressions.
+
+ @retval
+ 0 if ok
+ @retval
+ 1 on error
+*/
+
+bool JOIN::rollup_process_const_fields()
+{
+ ORDER *group_tmp;
+ Item *item;
+ List_iterator<Item> it(all_fields);
+
+ for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
+ {
+ if (!(*group_tmp->item)->const_item())
+ continue;
+ while ((item= it++))
+ {
+ if (*group_tmp->item == item)
+ {
+ Item* new_item= new Item_func_rollup_const(item);
+ if (!new_item)
+ return 1;
+ new_item->fix_fields(thd, (Item **) 0);
+ thd->change_item_tree(it.ref(), new_item);
+ for (ORDER *tmp= group_tmp; tmp; tmp= tmp->next)
+ {
+ if (*tmp->item == item)
+ thd->change_item_tree(tmp->item, new_item);
+ }
+ break;
+ }
+ }
+ it.rewind();
+ }
+ return 0;
+}
/**
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 271c88ebf66..d8f1769397c 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -58,6 +58,8 @@ class store_key;
typedef struct st_table_ref
{
bool key_err;
+ /** True if something was read into buffer in join_read_key. */
+ bool has_record;
uint key_parts; ///< num of ...
uint key_length; ///< length of key_buff
int key; ///< key no
@@ -85,6 +87,11 @@ typedef struct st_table_ref
table_map depend_map; ///< Table depends on these tables.
/* null byte position in the key_buf. Used for REF_OR_NULL optimization */
uchar *null_ref_key;
+ /*
+ The number of times the record associated with this key was used
+ in the join.
+ */
+ ha_rows use_count;
} TABLE_REF;
@@ -278,7 +285,14 @@ public:
TABLE **table,**all_tables,*sort_by_table;
uint tables,const_tables;
uint send_group_parts;
- bool sort_and_group,first_record,full_join,group, no_field_update;
+ /**
+ Indicates that grouping will be performed on the result set during
+ query execution. This field belongs to query execution.
+
+ @see make_group_fields, alloc_group_fields, JOIN::exec
+ */
+ bool sort_and_group;
+ bool first_record,full_join,group, no_field_update;
bool do_send_rows;
/**
TRUE when we want to resume nested loop iterations when
@@ -365,6 +379,8 @@ public:
simple_xxxxx is set if ORDER/GROUP BY doesn't include any references
to other tables than the first non-constant table in the JOIN.
It's also set if ORDER/GROUP BY is empty.
+ Used for deciding for or against using a temporary table to compute
+ GROUP/ORDER BY.
*/
bool simple_order, simple_group;
/**
@@ -435,6 +451,7 @@ public:
const_tables= 0;
eliminated_tables= 0;
join_list= 0;
+ implicit_grouping= FALSE;
sort_and_group= 0;
first_record= 0;
do_send_rows= 1;
@@ -511,6 +528,7 @@ public:
}
bool rollup_init();
+ bool rollup_process_const_fields();
bool rollup_make_fields(List<Item> &all_fields, List<Item> &fields,
Item_sum ***func);
int rollup_send_data(uint idx);
@@ -544,6 +562,11 @@ public:
return (table_map(1) << tables) - 1;
}
private:
+ /**
+ TRUE if the query contains an aggregate function but has no GROUP
+ BY clause.
+ */
+ bool implicit_grouping;
bool make_simple_join(JOIN *join, TABLE *tmp_table);
};
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index de139badc77..0e05d25af18 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -583,6 +583,126 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db,
}
+/**
+ An Internal_error_handler that suppresses errors regarding views'
+ underlying tables that occur during privilege checking within SHOW CREATE
+ VIEW commands. This happens in the cases when
+
+ - A view's underlying table (e.g. referenced in its SELECT list) does not
+ exist. There should not be an error as no attempt was made to access it
+ per se.
+
+ - Access is denied for some table, column, function or stored procedure
+ such as mentioned above. This error gets raised automatically, since we
+ can't untangle its access checking from that of the view itself.
+ */
+class Show_create_error_handler : public Internal_error_handler {
+
+ TABLE_LIST *m_top_view;
+ bool m_handling;
+ Security_context *m_sctx;
+
+ char m_view_access_denied_message[MYSQL_ERRMSG_SIZE];
+ char *m_view_access_denied_message_ptr;
+
+public:
+
+ /**
+ Creates a new Show_create_error_handler for the particular security
+ context and view.
+
+ @thd Thread context, used for security context information if needed.
+ @top_view The view. We do not verify at this point that top_view is in
+ fact a view since, alas, these things do not stay constant.
+ */
+ explicit Show_create_error_handler(THD *thd, TABLE_LIST *top_view) :
+ m_top_view(top_view), m_handling(FALSE),
+ m_view_access_denied_message_ptr(NULL)
+ {
+
+ m_sctx = test(m_top_view->security_ctx) ?
+ m_top_view->security_ctx : thd->security_ctx;
+ }
+
+ /**
+ Lazy instantiation of 'view access denied' message. The purpose of the
+ Show_create_error_handler is to hide details of underlying tables for
+ which we have no privileges behind ER_VIEW_INVALID messages. But this
+ obviously does not apply if we lack privileges on the view itself.
+ Unfortunately the information about for which table privilege checking
+ failed is not available at this point. The only way for us to check is by
+ reconstructing the actual error message and see if it's the same.
+ */
+ char* get_view_access_denied_message()
+ {
+ if (!m_view_access_denied_message_ptr)
+ {
+ m_view_access_denied_message_ptr= m_view_access_denied_message;
+ my_snprintf(m_view_access_denied_message, MYSQL_ERRMSG_SIZE,
+ ER(ER_TABLEACCESS_DENIED_ERROR), "SHOW VIEW",
+ m_sctx->priv_user,
+ m_sctx->host_or_ip, m_top_view->get_table_name());
+ }
+ return m_view_access_denied_message_ptr;
+ }
+
+ bool handle_error(uint sql_errno, const char *message,
+ MYSQL_ERROR::enum_warning_level level, THD *thd) {
+ /*
+ The handler does not handle the errors raised by itself.
+ At this point we know if top_view is really a view.
+ */
+ if (m_handling || !m_top_view->view)
+ return FALSE;
+
+ m_handling= TRUE;
+
+ bool is_handled;
+
+ switch (sql_errno)
+ {
+ case ER_TABLEACCESS_DENIED_ERROR:
+ if (!strcmp(get_view_access_denied_message(), message))
+ {
+ /* Access to top view is not granted, don't interfere. */
+ is_handled= FALSE;
+ break;
+ }
+ case ER_COLUMNACCESS_DENIED_ERROR:
+ case ER_VIEW_NO_EXPLAIN: /* Error was anonymized, ignore all the same. */
+ case ER_PROCACCESS_DENIED_ERROR:
+ is_handled= TRUE;
+ break;
+
+ case ER_NO_SUCH_TABLE:
+ /* Established behavior: warn if underlying tables are missing. */
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_VIEW_INVALID,
+ ER(ER_VIEW_INVALID),
+ m_top_view->get_db_name(),
+ m_top_view->get_table_name());
+ is_handled= TRUE;
+ break;
+
+ case ER_SP_DOES_NOT_EXIST:
+ /* Established behavior: warn if underlying functions are missing. */
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_VIEW_INVALID,
+ ER(ER_VIEW_INVALID),
+ m_top_view->get_db_name(),
+ m_top_view->get_table_name());
+ is_handled= TRUE;
+ break;
+ default:
+ is_handled= FALSE;
+ }
+
+ m_handling= FALSE;
+ return is_handled;
+ }
+};
+
+
bool
mysqld_show_create(THD *thd, TABLE_LIST *table_list)
{
@@ -596,26 +716,13 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
/* We want to preserve the tree for views. */
thd->lex->view_prepare_mode= TRUE;
- /* Only one table for now, but VIEW can involve several tables */
- if (open_normal_and_derived_tables(thd, table_list, 0))
{
- if (!table_list->view ||
- (thd->is_error() && thd->main_da.sql_errno() != ER_VIEW_INVALID))
+ Show_create_error_handler view_error_suppressor(thd, table_list);
+ thd->push_internal_handler(&view_error_suppressor);
+ bool error= open_normal_and_derived_tables(thd, table_list, 0);
+ thd->pop_internal_handler();
+ if (error && thd->main_da.is_error())
DBUG_RETURN(TRUE);
-
- /*
- Clear all messages with 'error' level status and
- issue a warning with 'warning' level status in
- case of invalid view and last error is ER_VIEW_INVALID
- */
- mysql_reset_errors(thd, true);
- thd->clear_error();
-
- push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_VIEW_INVALID,
- ER(ER_VIEW_INVALID),
- table_list->view_db.str,
- table_list->view_name.str);
}
/* TODO: add environment variables show when it become possible */
@@ -1762,6 +1869,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
if ((thd_info->db=tmp->db)) // Safe test
thd_info->db=thd->strdup(thd_info->db);
thd_info->command=(int) tmp->command;
+ pthread_mutex_lock(&tmp->LOCK_thd_data);
if ((mysys_var= tmp->mysys_var))
pthread_mutex_lock(&mysys_var->mutex);
thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
@@ -1781,20 +1889,16 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
#endif
if (mysys_var)
pthread_mutex_unlock(&mysys_var->mutex);
+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
thd_info->start_time= tmp->start_time;
thd_info->query=0;
/* Lock THD mutex that protects its data when looking at it. */
pthread_mutex_lock(&tmp->LOCK_thd_data);
- if (tmp->query)
+ if (tmp->query())
{
- /*
- query_length is always set to 0 when we set query = NULL; see
- the comment in sql_class.h why this prevents crashes in possible
- races with query_length
- */
- uint length= min(max_query_length, tmp->query_length);
- thd_info->query=(char*) thd->strmake(tmp->query,length);
+ uint length= min(max_query_length, tmp->query_length());
+ thd_info->query= (char*) thd->strmake(tmp->query(),length);
}
pthread_mutex_unlock(&tmp->LOCK_thd_data);
thread_infos.append(thd_info);
@@ -1907,7 +2011,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
tmp->mysys_var->current_cond ?
"Waiting on cond" : NullS);
#else
- val= (char *) "Writing to net";
+ val= (char *) (tmp->proc_info ? tmp->proc_info : NullS);
#endif
if (val)
{
@@ -1919,11 +2023,11 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
pthread_mutex_unlock(&mysys_var->mutex);
/* INFO */
- if (tmp->query)
+ if (tmp->query())
{
- table->field[7]->store(tmp->query,
+ table->field[7]->store(tmp->query(),
min(PROCESS_LIST_INFO_WIDTH,
- tmp->query_length), cs);
+ tmp->query_length()), cs);
table->field[7]->set_notnull();
}
@@ -3876,7 +3980,9 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
TABLE_SHARE *share= show_table->s;
handler *file= show_table->file;
handlerton *tmp_db_type= share->db_type();
+#ifdef WITH_PARTITION_STORAGE_ENGINE
bool is_partitioned= FALSE;
+#endif
if (share->tmp_table == SYSTEM_TMP_TABLE)
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
else if (share->tmp_table)
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 9d3d78f5b7e..6e938583965 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -70,15 +70,21 @@ static void wait_for_kill_signal(THD *thd)
/**
@brief Helper function for explain_filename
+ @param thd Thread handle
+ @param to_p Explained name in system_charset_info
+ @param end_p End of the to_p buffer
+ @param name Name to be converted
+ @param name_len Length of the name, in bytes
*/
-static char* add_identifier(char *to_p, const char * end_p,
- const char* name, uint name_len, bool add_quotes)
+static char* add_identifier(THD* thd, char *to_p, const char * end_p,
+ const char* name, uint name_len)
{
uint res;
uint errors;
const char *conv_name;
char tmp_name[FN_REFLEN];
char conv_string[FN_REFLEN];
+ int quote;
DBUG_ENTER("add_identifier");
if (!name[name_len])
@@ -102,19 +108,21 @@ static char* add_identifier(char *to_p, const char * end_p,
conv_name= conv_string;
}
- if (add_quotes && (end_p - to_p > 2))
+ quote = thd ? get_quote_char_for_identifier(thd, conv_name, res - 1) : '"';
+
+ if (quote != EOF && (end_p - to_p > 2))
{
- *(to_p++)= '`';
+ *(to_p++)= (char) quote;
while (*conv_name && (end_p - to_p - 1) > 0)
{
uint length= my_mbcharlen(system_charset_info, *conv_name);
if (!length)
length= 1;
- if (length == 1 && *conv_name == '`')
+ if (length == 1 && *conv_name == (char) quote)
{
if ((end_p - to_p) < 3)
break;
- *(to_p++)= '`';
+ *(to_p++)= (char) quote;
*(to_p++)= *(conv_name++);
}
else if (((long) length) < (end_p - to_p))
@@ -125,7 +133,11 @@ static char* add_identifier(char *to_p, const char * end_p,
else
break; /* string already filled */
}
- to_p= strnmov(to_p, "`", end_p - to_p);
+ if (end_p > to_p) {
+ *(to_p++)= (char) quote;
+ if (end_p > to_p)
+ *to_p= 0; /* terminate by NUL, but do not include it in the count */
+ }
}
else
to_p= strnmov(to_p, conv_name, end_p - to_p);
@@ -145,6 +157,7 @@ static char* add_identifier(char *to_p, const char * end_p,
diagnostic, error etc. when it would be useful to know what a particular
file [and directory] means. Such as SHOW ENGINE STATUS, error messages etc.
+ @param thd Thread handle
@param from Path name in my_charset_filename
Null terminated in my_charset_filename, normalized
to use '/' as directory separation character.
@@ -161,13 +174,12 @@ static char* add_identifier(char *to_p, const char * end_p,
[,[ Temporary| Renamed] Partition `p`
[, Subpartition `sp`]] *|
(| is really a /, and it is all in one line)
- EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING ->
- same as above but no quotes are added.
@retval Length of returned string
*/
-uint explain_filename(const char *from,
+uint explain_filename(THD* thd,
+ const char *from,
char *to,
uint to_length,
enum_explain_filename_mode explain_mode)
@@ -281,14 +293,12 @@ uint explain_filename(const char *from,
{
to_p= strnmov(to_p, ER(ER_DATABASE_NAME), end_p - to_p);
*(to_p++)= ' ';
- to_p= add_identifier(to_p, end_p, db_name, db_name_len, 1);
+ to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
to_p= strnmov(to_p, ", ", end_p - to_p);
}
else
{
- to_p= add_identifier(to_p, end_p, db_name, db_name_len,
- (explain_mode !=
- EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
+ to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
to_p= strnmov(to_p, ".", end_p - to_p);
}
}
@@ -296,16 +306,13 @@ uint explain_filename(const char *from,
{
to_p= strnmov(to_p, ER(ER_TABLE_NAME), end_p - to_p);
*(to_p++)= ' ';
- to_p= add_identifier(to_p, end_p, table_name, table_name_len, 1);
+ to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
}
else
- to_p= add_identifier(to_p, end_p, table_name, table_name_len,
- (explain_mode !=
- EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
+ to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
if (part_name)
{
- if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT ||
- explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING)
+ if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
to_p= strnmov(to_p, " /* ", end_p - to_p);
else if (explain_mode == EXPLAIN_PARTITIONS_VERBOSE)
to_p= strnmov(to_p, " ", end_p - to_p);
@@ -321,20 +328,15 @@ uint explain_filename(const char *from,
}
to_p= strnmov(to_p, ER(ER_PARTITION_NAME), end_p - to_p);
*(to_p++)= ' ';
- to_p= add_identifier(to_p, end_p, part_name, part_name_len,
- (explain_mode !=
- EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
+ to_p= add_identifier(thd, to_p, end_p, part_name, part_name_len);
if (subpart_name)
{
to_p= strnmov(to_p, ", ", end_p - to_p);
to_p= strnmov(to_p, ER(ER_SUBPARTITION_NAME), end_p - to_p);
*(to_p++)= ' ';
- to_p= add_identifier(to_p, end_p, subpart_name, subpart_name_len,
- (explain_mode !=
- EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
+ to_p= add_identifier(thd, to_p, end_p, subpart_name, subpart_name_len);
}
- if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT ||
- explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING)
+ if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
to_p= strnmov(to_p, " */", end_p - to_p);
}
DBUG_PRINT("exit", ("to '%s'", to));
@@ -1772,6 +1774,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
my_bool drop_temporary)
{
bool error= FALSE, need_start_waiters= FALSE;
+ Drop_table_error_handler err_handler(thd->get_internal_handler());
DBUG_ENTER("mysql_rm_table");
/* mark for close and remove all cached entries */
@@ -1792,7 +1795,10 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
LOCK_open during wait_if_global_read_lock(), other threads could not
close their tables. This would make a pretty deadlock.
*/
+ thd->push_internal_handler(&err_handler);
error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
+ thd->pop_internal_handler();
+
if (need_start_waiters)
start_waiting_global_read_lock(thd);
@@ -1894,9 +1900,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
DBUG_RETURN(1);
}
- /* Don't give warnings for not found errors, as we already generate notes */
- thd->no_warnings_for_error= 1;
-
for (table= tables; table; table= table->next_local)
{
char *db=table->db;
@@ -1948,7 +1951,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
being built. The string always end in a comma and the comma
will be chopped off before being written to the binary log.
*/
- if (thd->current_stmt_binlog_row_based && !dont_log_query)
+ if (!drop_temporary && thd->current_stmt_binlog_row_based && !dont_log_query)
{
non_temp_tables_count++;
/*
@@ -2086,7 +2089,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
tables). In this case, we can write the original query into
the binary log.
*/
- write_bin_log(thd, !error, thd->query, thd->query_length);
+ write_bin_log(thd, !error, thd->query(), thd->query_length());
}
else if (thd->current_stmt_binlog_row_based &&
tmp_table_deleted)
@@ -2145,7 +2148,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
err_with_placeholders:
unlock_table_names(thd, tables, (TABLE_LIST*) 0);
pthread_mutex_unlock(&LOCK_open);
- thd->no_warnings_for_error= 0;
DBUG_RETURN(error);
}
@@ -2487,6 +2489,10 @@ int prepare_create_field(Create_field *sql_field,
(sql_field->decimals << FIELDFLAG_DEC_SHIFT));
break;
}
+ if (sql_field->flags & NOT_NULL_FLAG)
+ DBUG_PRINT("info", ("1"));
+ if (sql_field->vcol_info)
+ DBUG_PRINT("info", ("2"));
if (!(sql_field->flags & NOT_NULL_FLAG) ||
(sql_field->vcol_info)) /* Make virtual columns allow NULL values */
sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
@@ -3584,7 +3590,7 @@ static inline void write_create_table_bin_log(THD *thd,
(!thd->current_stmt_binlog_row_based ||
(thd->current_stmt_binlog_row_based &&
!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
@@ -5258,6 +5264,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
char tmp_path[FN_REFLEN];
#endif
char ts_name[FN_LEN + 1];
+ myf flags= MY_DONT_OVERWRITE_FILE;
DBUG_ENTER("mysql_create_like_table");
@@ -5314,8 +5321,12 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
DBUG_EXECUTE_IF("sleep_create_like_before_copy", my_sleep(6000000););
+ if (opt_sync_frm && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
+ flags|= MY_SYNC;
+
/*
Create a new table by copying from source table
+ and sync the new table if the flag MY_SYNC is set
Altough exclusive name-lock on target table protects us from concurrent
DML and DDL operations on it we still want to wrap .FRM creation and call
@@ -5336,7 +5347,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
goto err;
}
}
- else if (my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)))
+ else if (my_copy(src_path, dst_path, flags))
{
if (my_errno == ENOENT)
my_error(ER_BAD_DB_ERROR,MYF(0),db);
@@ -5461,14 +5472,14 @@ binlog:
write_bin_log(thd, TRUE, query.ptr(), query.length());
}
else // Case 1
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
/*
Case 3 and 4 does nothing under RBR
*/
}
else
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
res= FALSE;
@@ -5556,7 +5567,7 @@ mysql_discard_or_import_tablespace(THD *thd,
error=1;
if (error)
goto err;
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
err:
ha_autocommit_or_rollback(thd, error);
@@ -6605,7 +6616,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length,
+ Query_log_event qinfo(thd, thd->query(), thd->query_length(),
0, FALSE, 0);
mysql_bin_log.write(&qinfo);
}
@@ -6732,10 +6743,21 @@ view_err:
goto err;
}
+ /*
+ If this is an ALTER TABLE and no explicit row type specified reuse
+ the table's row type.
+ Note: this is the same as if the row type was specified explicitly and
+ we must thus set HA_CREATE_USED_ROW_FORMAT!
+ */
if (create_info->row_type == ROW_TYPE_NOT_USED)
{
+ /* ALTER TABLE without explicit row type */
create_info->row_type= table->s->row_type;
- create_info->used_fields |= HA_CREATE_USED_ROW_FORMAT;
+ /*
+ We have to mark the row type as used, as otherwise the engine may
+ change the row format in update_create_info().
+ */
+ create_info->used_fields|= HA_CREATE_USED_ROW_FORMAT;
}
DBUG_PRINT("info", ("old type: %s new type: %s",
@@ -6849,7 +6871,7 @@ view_err:
if (!error)
{
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
my_ok(thd);
}
else if (error > 0)
@@ -7265,14 +7287,18 @@ view_err:
/* Add the indexes. */
if ((error= table->file->add_index(table, key_info, index_add_count)))
{
- /*
- Exchange the key_info for the error message. If we exchange
- key number by key name in the message later, we need correct info.
- */
- KEY *save_key_info= table->key_info;
- table->key_info= key_info;
- table->file->print_error(error, MYF(0));
- table->key_info= save_key_info;
+ /* Only report error if handler has not already reported an error */
+ if (!thd->main_da.is_error())
+ {
+ /*
+ Exchange the key_info for the error message. If we exchange
+ key number by key name in the message later, we need correct info.
+ */
+ KEY *save_key_info= table->key_info;
+ table->key_info= key_info;
+ table->file->print_error(error, MYF(0));
+ table->key_info= save_key_info;
+ }
goto err1;
}
}
@@ -7338,7 +7364,7 @@ view_err:
goto err1;
/* We don't replicate alter table statement on temporary tables */
if (!thd->current_stmt_binlog_row_based)
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
goto end_temporary;
}
@@ -7495,13 +7521,13 @@ view_err:
DBUG_EXECUTE_IF("sleep_alter_before_main_binlog", my_sleep(6000000););
ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
db, table_name);
DBUG_ASSERT(!(mysql_bin_log.is_open() &&
thd->current_stmt_binlog_row_based &&
(create_info->options & HA_LEX_CREATE_TMP_TABLE)));
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
{
@@ -7975,10 +8001,11 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
for (uint i= 0; i < t->s->fields; i++ )
{
Field *f= t->field[i];
+ enum_field_types field_type= f->type();
+
if (! thd->variables.old_mode &&
f->is_real_null(0))
continue;
- enum_field_types field_type= f->type();
/*
BLOB and VARCHAR have pointers in their field, we must convert
to string; GEOMETRY is implemented on top of BLOB.
diff --git a/sql/sql_tablespace.cc b/sql/sql_tablespace.cc
index 14b29452750..aec54bda13e 100644
--- a/sql/sql_tablespace.cc
+++ b/sql/sql_tablespace.cc
@@ -67,6 +67,6 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info)
hton_name(hton)->str,
"TABLESPACE or LOGFILE GROUP");
}
- write_bin_log(thd, FALSE, thd->query, thd->query_length);
+ write_bin_log(thd, FALSE, thd->query(), thd->query_length());
DBUG_RETURN(FALSE);
}
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index c055268ecca..a251a533622 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -409,7 +409,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
*/
result= FALSE;
/* Still, we need to log the query ... */
- stmt_query.append(thd->query, thd->query_length);
+ stmt_query.append(thd->query(), thd->query_length());
goto end;
}
}
@@ -918,7 +918,7 @@ bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables,
List_iterator<LEX_STRING> it_connection_cl_name(connection_cl_names);
List_iterator<LEX_STRING> it_db_cl_name(db_cl_names);
- stmt_query->append(thd->query, thd->query_length);
+ stmt_query->append(thd->query(), thd->query_length());
while ((name= it_name++))
{
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 96e2523169e..b2008baf644 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -506,7 +506,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
rw_unlock(&THR_LOCK_udf);
/* Binlog the create function. */
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
DBUG_RETURN(0);
@@ -581,7 +581,7 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name)
rw_unlock(&THR_LOCK_udf);
/* Binlog the drop function. */
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
DBUG_RETURN(0);
err:
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 6ded059b59f..a983e64c01d 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -810,7 +810,7 @@ int mysql_update(THD *thd,
errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
transactional_table, FALSE, errcode))
{
error=1; // Rollback update
@@ -1696,6 +1696,11 @@ bool multi_update::send_data(List<Item> &not_used_values)
TRG_EVENT_UPDATE))
DBUG_RETURN(1);
+ /*
+ Reset the table->auto_increment_field_not_null as it is valid for
+ only one row.
+ */
+ table->auto_increment_field_not_null= FALSE;
found++;
if (!can_compare_record || compare_record(table))
{
@@ -1860,7 +1865,7 @@ void multi_update::abort()
*/
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
transactional_tables, FALSE, errcode);
}
thd->transaction.all.modified_non_trans_table= TRUE;
@@ -2093,7 +2098,7 @@ bool multi_update::send_eof()
else
errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query, thd->query_length,
+ thd->query(), thd->query_length(),
transactional_tables, FALSE, errcode))
{
local_error= 1; // Rollback update
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 43d0b9fade0..ae3af0640a3 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1652,7 +1652,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
/* if something goes wrong, bin-log with possible error code,
otherwise bin-log with error code cleared.
*/
- write_bin_log(thd, !something_wrong, thd->query, thd->query_length);
+ write_bin_log(thd, !something_wrong, thd->query(), thd->query_length());
}
VOID(pthread_mutex_unlock(&LOCK_open));
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index a481ffee2aa..976d130b26b 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -8043,7 +8043,13 @@ udf_expr:
$2->is_autogenerated_name= FALSE;
$2->set_name($4.str, $4.length, system_charset_info);
}
- else
+ /*
+ A field has to have its proper name in order for name
+ resolution to work, something we are only guaranteed if we
+ parse it out. If we hijack the input stream with
+ remember_name we may get quoted or escaped names.
+ */
+ else if ($2->type() != Item::FIELD_ITEM)
$2->set_name($1, (uint) ($3 - $1), YYTHD->charset());
$$= $2;
}
@@ -9203,8 +9209,7 @@ procedure_clause:
MYSQL_YYABORT;
}
- if (&lex->select_lex != lex->current_select ||
- lex->select_lex.get_table_list()->derived)
+ if (&lex->select_lex != lex->current_select)
{
my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery");
MYSQL_YYABORT;
@@ -10584,14 +10589,12 @@ load:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
- Lex_input_stream *lip= YYLIP;
if (lex->sphead)
{
my_error(ER_SP_BADSTATEMENT, MYF(0), "LOAD DATA");
MYSQL_YYABORT;
}
- lex->fname_start= lip->get_ptr();
}
load_data
{}
@@ -10623,14 +10626,10 @@ load_data:
if (!(lex->exchange= new sql_exchange($4.str, 0)))
MYSQL_YYABORT;
}
- opt_duplicate INTO
- {
- Lex->fname_end= YYLIP->get_ptr();
- }
- TABLE_SYM table_ident
+ opt_duplicate INTO TABLE_SYM table_ident
{
LEX *lex=Lex;
- if (!Select->add_table_to_list(YYTHD, $10, NULL, TL_OPTION_UPDATING,
+ if (!Select->add_table_to_list(YYTHD, $9, NULL, TL_OPTION_UPDATING,
lex->lock_option))
MYSQL_YYABORT;
lex->field_list.empty();
@@ -10638,7 +10637,7 @@ load_data:
lex->value_list.empty();
}
opt_load_data_charset
- { Lex->exchange->cs= $12; }
+ { Lex->exchange->cs= $11; }
opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec
opt_load_data_set_spec
{}
@@ -10889,7 +10888,7 @@ param_marker:
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
MYSQL_YYABORT;
}
- item= new (thd->mem_root) Item_param((uint) (lip->get_tok_start() - thd->query));
+ item= new (thd->mem_root) Item_param((uint) (lip->get_tok_start() - thd->query()));
if (!($$= item) || lex->param_list.push_back(item))
{
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
diff --git a/sql/structs.h b/sql/structs.h
index 3a090fd203f..0772cb4ff1d 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -118,16 +118,22 @@ typedef struct st_reginfo { /* Extra info about reg */
} REGINFO;
-struct st_read_record; /* For referense later */
class SQL_SELECT;
class THD;
class handler;
+struct st_join_table;
+
+void rr_unlock_row(st_join_table *tab);
-typedef struct st_read_record { /* Parameter to read_record */
+struct READ_RECORD { /* Parameter to read_record */
+ typedef int (*Read_func)(READ_RECORD*);
+ typedef void (*Unlock_row_func)(st_join_table *);
struct st_table *table; /* Head-form */
handler *file;
struct st_table **forms; /* head and ref forms */
- int (*read_record)(struct st_read_record *);
+
+ Read_func read_record;
+ Unlock_row_func unlock_row;
THD *thd;
SQL_SELECT *select;
uint cache_records;
@@ -139,7 +145,7 @@ typedef struct st_read_record { /* Parameter to read_record */
uchar *cache,*cache_pos,*cache_end,*read_positions;
IO_CACHE *io_cache;
bool print_error, ignore_not_found_rows;
-} READ_RECORD;
+};
/*
diff --git a/sql/table.cc b/sql/table.cc
index 1c10958fdef..0f3f388a199 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -2500,8 +2500,9 @@ ulong get_form_pos(File file, uchar *head, TYPELIB *save_names)
else
{
char *str;
+ const char **tmp = (const char**) buf;
str=(char *) (buf+a_length);
- fix_type_pointers((const char ***) &buf,save_names,1,&str);
+ fix_type_pointers(&tmp, save_names, 1, &str);
}
DBUG_RETURN(ret_value);
}
@@ -3761,7 +3762,12 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
/**
- Hide errors which show view underlying table information
+ Hide errors which show view underlying table information.
+ There are currently two mechanisms at work that handle errors for views,
+ this one and a more general mechanism based on an Internal_error_handler,
+ see Show_create_error_handler. The latter handles errors encountered during
+ execution of SHOW CREATE VIEW, while the machanism using this method is
+ handles SELECT from views. The two methods should not clash.
@param[in,out] thd thread handler
@@ -3770,6 +3776,8 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
void TABLE_LIST::hide_view_error(THD *thd)
{
+ if (thd->get_internal_handler())
+ return;
/* Hide "Unknown column" or "Unknown function" error */
DBUG_ASSERT(thd->is_error());
@@ -5154,7 +5162,8 @@ Item_subselect *TABLE_LIST::containing_subselect()
(TABLE_LIST::index_hints). Using the information in this tagged list
this function sets the members st_table::keys_in_use_for_query,
st_table::keys_in_use_for_group_by, st_table::keys_in_use_for_order_by,
- st_table::force_index and st_table::covering_keys.
+ st_table::force_index, st_table::force_index_order,
+ st_table::force_index_group and st_table::covering_keys.
Current implementation of the runtime does not allow mixing FORCE INDEX
and USE INDEX, so this is checked here. Then the FORCE INDEX list
@@ -5282,14 +5291,28 @@ bool TABLE_LIST::process_index_hints(TABLE *tbl)
}
/* process FORCE INDEX as USE INDEX with a flag */
+ if (!index_order[INDEX_HINT_FORCE].is_clear_all())
+ {
+ tbl->force_index_order= TRUE;
+ index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
+ }
+
+ if (!index_group[INDEX_HINT_FORCE].is_clear_all())
+ {
+ tbl->force_index_group= TRUE;
+ index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
+ }
+
+ /*
+ TODO: get rid of tbl->force_index (on if any FORCE INDEX is specified) and
+ create tbl->force_index_join instead.
+ Then use the correct force_index_XX instead of the global one.
+ */
if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
- !index_order[INDEX_HINT_FORCE].is_clear_all() ||
- !index_group[INDEX_HINT_FORCE].is_clear_all())
+ tbl->force_index_group || tbl->force_index_order)
{
tbl->force_index= TRUE;
index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
- index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
- index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
}
/* apply USE INDEX */
diff --git a/sql/table.h b/sql/table.h
index ffd3ba05fc9..7315e48718b 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -761,6 +761,18 @@ struct st_table {
bytes, it would take up 4.
*/
my_bool force_index;
+
+ /**
+ Flag set when the statement contains FORCE INDEX FOR ORDER BY
+ See TABLE_LIST::process_index_hints().
+ */
+ my_bool force_index_order;
+
+ /**
+ Flag set when the statement contains FORCE INDEX FOR GROUP BY
+ See TABLE_LIST::process_index_hints().
+ */
+ my_bool force_index_group;
my_bool distinct,const_table,no_rows;
/**
diff --git a/sql/time.cc b/sql/time.cc
index 44672eb4278..c4f6c3c9539 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -965,20 +965,22 @@ calc_time_diff(MYSQL_TIME *l_time1, MYSQL_TIME *l_time2, int l_sign, longlong *s
0 - a == b
1 - a > b
- NOTES
- TIME.second_part is not considered during comparison
*/
-int
-my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b)
+int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b)
{
- my_ulonglong a_t= TIME_to_ulonglong_datetime(a);
- my_ulonglong b_t= TIME_to_ulonglong_datetime(b);
+ ulonglong a_t= TIME_to_ulonglong_datetime(a);
+ ulonglong b_t= TIME_to_ulonglong_datetime(b);
+ if (a_t < b_t)
+ return -1;
if (a_t > b_t)
return 1;
- else if (a_t < b_t)
+
+ if (a->second_part < b->second_part)
return -1;
+ if (a->second_part > b->second_part)
+ return 1;
return 0;
}
diff --git a/sql/udf_example.c b/sql/udf_example.c
index 9b8f65a4a74..788582e32b6 100644
--- a/sql/udf_example.c
+++ b/sql/udf_example.c
@@ -139,12 +139,12 @@ typedef long long longlong;
#include <mysql.h>
#include <ctype.h>
+#ifdef HAVE_DLOPEN
+
#if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_SOLARIS_STYLE_GETHOST)
static pthread_mutex_t LOCK_hostname;
#endif
-#ifdef HAVE_DLOPEN
-
/* These must be right or mysqld will not find the symbol! */
my_bool metaphon_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
diff --git a/sql/unireg.cc b/sql/unireg.cc
index cb1e343ff7d..78d375e663a 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -411,10 +411,10 @@ int rea_create_table(THD *thd, const char *path,
DBUG_ASSERT(*fn_rext(frm_name));
if (thd->variables.keep_files_on_create)
create_info->options|= HA_CREATE_KEEP_FILES;
- if (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG, create_info))
- goto err_handler;
- if (!create_info->frm_only && ha_create_table(thd, path, db, table_name,
- create_info,0))
+ if (!create_info->frm_only &&
+ (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG,
+ create_info) ||
+ ha_create_table(thd, path, db, table_name, create_info, 0)))
goto err_handler;
DBUG_RETURN(0);
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 86dcbf8d732..ed6ff18f980 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -522,8 +522,8 @@ int ha_archive::open(const char *name, int mode, uint open_options)
{
DBUG_RETURN(0);
}
- else
- DBUG_RETURN(rc);
+
+ DBUG_RETURN(rc);
}
@@ -993,6 +993,7 @@ int ha_archive::rnd_init(bool scan)
/* We rewind the file so that we can read from the beginning if scan */
if (scan)
{
+ scan_rows= stats.records;
DBUG_PRINT("info", ("archive will retrieve %llu rows",
(unsigned long long) scan_rows));
@@ -1461,7 +1462,6 @@ int ha_archive::info(uint flag)
stats.records= share->rows_recorded;
pthread_mutex_unlock(&share->mutex);
- scan_rows= stats.records;
stats.deleted= 0;
DBUG_PRINT("ha_archive", ("Stats rows is %d\n", (int)stats.records));
@@ -1472,11 +1472,12 @@ int ha_archive::info(uint flag)
VOID(my_stat(share->data_file_name, &file_stat, MYF(MY_WME)));
- stats.mean_rec_length= table->s->reclength + buffer.alloced_length();
stats.data_file_length= file_stat.st_size;
stats.create_time= (ulong) file_stat.st_ctime;
stats.update_time= (ulong) file_stat.st_mtime;
- stats.max_data_file_length= share->rows_recorded * stats.mean_rec_length;
+ stats.mean_rec_length= stats.records ?
+ stats.data_file_length / stats.records : table->s->reclength;
+ stats.max_data_file_length= MAX_FILE_SIZE;
}
stats.delete_length= 0;
stats.index_file_length=0;
@@ -1574,10 +1575,8 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt)
share->crashed= FALSE;
DBUG_RETURN(HA_ADMIN_CORRUPT);
}
- else
- {
- DBUG_RETURN(HA_ADMIN_OK);
- }
+
+ DBUG_RETURN(HA_ADMIN_OK);
}
/*
diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc
index 357496fe095..e3ba111043b 100644
--- a/storage/blackhole/ha_blackhole.cc
+++ b/storage/blackhole/ha_blackhole.cc
@@ -105,7 +105,7 @@ int ha_blackhole::update_row(const uchar *old_data, uchar *new_data)
{
DBUG_ENTER("ha_blackhole::update_row");
THD *thd= ha_thd();
- if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL)
+ if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
DBUG_RETURN(0);
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
@@ -114,7 +114,7 @@ int ha_blackhole::delete_row(const uchar *buf)
{
DBUG_ENTER("ha_blackhole::delete_row");
THD *thd= ha_thd();
- if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL)
+ if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
DBUG_RETURN(0);
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
@@ -130,7 +130,7 @@ int ha_blackhole::rnd_next(uchar *buf)
{
DBUG_ENTER("ha_blackhole::rnd_next");
THD *thd= ha_thd();
- if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL)
+ if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
DBUG_RETURN(0);
DBUG_RETURN(HA_ERR_END_OF_FILE);
}
@@ -212,7 +212,7 @@ int ha_blackhole::index_read_map(uchar * buf, const uchar * key,
{
DBUG_ENTER("ha_blackhole::index_read");
THD *thd= ha_thd();
- if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL)
+ if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
DBUG_RETURN(0);
DBUG_RETURN(HA_ERR_END_OF_FILE);
}
@@ -224,7 +224,7 @@ int ha_blackhole::index_read_idx_map(uchar * buf, uint idx, const uchar * key,
{
DBUG_ENTER("ha_blackhole::index_read_idx");
THD *thd= ha_thd();
- if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL)
+ if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
DBUG_RETURN(0);
DBUG_RETURN(HA_ERR_END_OF_FILE);
}
@@ -235,7 +235,7 @@ int ha_blackhole::index_read_last_map(uchar * buf, const uchar * key,
{
DBUG_ENTER("ha_blackhole::index_read_last");
THD *thd= ha_thd();
- if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL)
+ if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
DBUG_RETURN(0);
DBUG_RETURN(HA_ERR_END_OF_FILE);
}
diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc
index ad536d40002..3fda2239b34 100644
--- a/storage/csv/ha_tina.cc
+++ b/storage/csv/ha_tina.cc
@@ -1606,8 +1606,8 @@ int ha_tina::check(THD* thd, HA_CHECK_OPT* check_opt)
share->crashed= TRUE;
DBUG_RETURN(HA_ADMIN_CORRUPT);
}
- else
- DBUG_RETURN(HA_ADMIN_OK);
+
+ DBUG_RETURN(HA_ADMIN_OK);
}
diff --git a/storage/federatedx/Makefile.am b/storage/federatedx/Makefile.am
index 6dbeff1207a..ad1328247ec 100644
--- a/storage/federatedx/Makefile.am
+++ b/storage/federatedx/Makefile.am
@@ -22,7 +22,6 @@ pkgplugin_LTLIBRARIES = @plugin_federated_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_SOURCES = ha_federatedx.cc
EXTRA_LIBRARIES = libfederatedx.a
diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc
index 4d4b25da058..308215fe839 100644
--- a/storage/federatedx/ha_federatedx.cc
+++ b/storage/federatedx/ha_federatedx.cc
@@ -390,8 +390,8 @@ int federatedx_db_init(void *p)
DBUG_ENTER("federatedx_db_init");
handlerton *federatedx_hton= (handlerton *)p;
federatedx_hton->state= SHOW_OPTION_YES;
- /* This is no longer needed for plugin storage engines */
- federatedx_hton->db_type= DB_TYPE_DEFAULT;
+ /* Needed to work with old .frm files */
+ federatedx_hton->db_type= DB_TYPE_FEDERATED_DB;
federatedx_hton->savepoint_offset= sizeof(ulong);
federatedx_hton->close_connection= ha_federatedx::disconnect;
federatedx_hton->savepoint_set= ha_federatedx::savepoint_set;
@@ -1785,14 +1785,22 @@ int ha_federatedx::close(void)
if (stored_result)
retval= free_result();
- /* Disconnect from mysql */
- if ((txn= get_txn(thd, true)))
+ /* Disconnect from mysql. thd may be null during refresh */
+ txn= thd ? get_txn(thd, true) : new federatedx_txn();
+
+ if (txn)
+ {
txn->release(&io);
+
+ DBUG_ASSERT(io == NULL);
- DBUG_ASSERT(io == NULL);
+ if ((error= free_share(txn, share)))
+ retval= error;
+
+ if (!thd)
+ delete txn;
- if ((error= free_share(txn, share)))
- retval= error;
+ }
DBUG_RETURN(retval);
}
diff --git a/storage/heap/hp_write.c b/storage/heap/hp_write.c
index 29701f8ecbe..4e8fa7e3580 100644
--- a/storage/heap/hp_write.c
+++ b/storage/heap/hp_write.c
@@ -196,13 +196,10 @@ int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
HP_SHARE *share = info->s;
int flag;
ulong halfbuff,hashnr,first_index;
- uchar *ptr_to_rec,*ptr_to_rec2;
- HASH_INFO *empty,*gpos,*gpos2,*pos;
+ uchar *UNINIT_VAR(ptr_to_rec),*UNINIT_VAR(ptr_to_rec2);
+ HASH_INFO *empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos;
DBUG_ENTER("hp_write_key");
- LINT_INIT(gpos); LINT_INIT(gpos2);
- LINT_INIT(ptr_to_rec); LINT_INIT(ptr_to_rec2);
-
flag=0;
if (!(empty= hp_find_free_hash(share,&keyinfo->block,share->records)))
DBUG_RETURN(-1); /* No more memory */
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index 8cb196bf983..b8251a99105 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -1268,7 +1268,7 @@ dict_col_name_is_reserved(
ulint i;
for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) {
- if (strcmp(name, reserved_names[i]) == 0) {
+ if (innobase_strcasecmp(name, reserved_names[i]) == 0) {
return(TRUE);
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 6e1e68d94f0..94f7cf7b38b 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -41,7 +41,7 @@ have disabled the InnoDB inlining in this file. */
#include <mysql/plugin.h>
#ifndef MYSQL_SERVER
-/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
+/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
extern pthread_mutex_t LOCK_thread_count;
#endif /* MYSQL_SERVER */
@@ -54,6 +54,7 @@ static ulong commit_threads = 0;
static pthread_mutex_t commit_threads_m;
static pthread_cond_t commit_cond;
static pthread_mutex_t commit_cond_m;
+static pthread_mutex_t analyze_mutex;
static bool innodb_inited = 0;
/*
@@ -155,17 +156,36 @@ static void free_share(INNOBASE_SHARE *share);
static int innobase_close_connection(handlerton *hton, THD* thd);
static int innobase_commit(handlerton *hton, THD* thd, bool all);
static int innobase_rollback(handlerton *hton, THD* thd, bool all);
-static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
+static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
void *savepoint);
static int innobase_savepoint(handlerton *hton, THD* thd, void *savepoint);
-static int innobase_release_savepoint(handlerton *hton, THD* thd,
+static int innobase_release_savepoint(handlerton *hton, THD* thd,
void *savepoint);
static handler *innobase_create_handler(handlerton *hton,
TABLE_SHARE *table,
MEM_ROOT *mem_root);
+/***********************************************************************
+This function checks each index name for a table against reserved
+system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
+this function pushes an error message to the client, and returns true. */
+static
+bool
+innobase_index_name_is_reserved(
+/*============================*/
+ /* out: true if index name matches a
+ reserved name */
+ const trx_t* trx, /* in: InnoDB transaction handle */
+ const TABLE* form, /* in: information on table
+ columns and indexes */
+ const char* norm_name); /* in: table name */
+
static const char innobase_hton_name[]= "InnoDB";
+/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
+system primary index. */
+static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX";
+
/** @brief Initialize the default value of innodb_commit_concurrency.
Once InnoDB is running, the innodb_commit_concurrency must not change
@@ -818,7 +838,22 @@ innobase_get_cset_width(
*mbminlen = cs->mbminlen;
*mbmaxlen = cs->mbmaxlen;
} else {
- ut_a(cset == 0);
+ if (current_thd
+ && (thd_sql_command(current_thd) == SQLCOM_DROP_TABLE)) {
+
+ /* Fix bug#46256: allow tables to be dropped if the
+ collation is not found, but issue a warning. */
+ if ((global_system_variables.log_warnings)
+ && (cset != 0)){
+
+ sql_print_warning(
+ "Unknown collation #%lu.", cset);
+ }
+ } else {
+
+ ut_a(cset == 0);
+ }
+
*mbminlen = *mbmaxlen = 0;
}
}
@@ -1908,6 +1943,7 @@ innobase_init(
pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&analyze_mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&commit_cond, NULL);
innodb_inited= 1;
@@ -1947,6 +1983,7 @@ innobase_end(handlerton *hton, ha_panic_function type)
pthread_mutex_destroy(&prepare_commit_mutex);
pthread_mutex_destroy(&commit_threads_m);
pthread_mutex_destroy(&commit_cond_m);
+ pthread_mutex_destroy(&analyze_mutex);
pthread_cond_destroy(&commit_cond);
}
@@ -2191,6 +2228,8 @@ innobase_rollback(
innobase_release_stat_resources(trx);
+ trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
+
/* If we had reserved the auto-inc lock for some table (if
we come here to roll back the latest SQL statement) we
release it now before a possibly lengthy rollback */
@@ -2525,12 +2564,28 @@ ha_innobase::innobase_initialize_autoinc()
dict_table_autoinc_initialize(innodb_table, auto_inc);
- } else {
+ } else if (error == DB_RECORD_NOT_FOUND) {
ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Error: (%lu) Couldn't read "
- "the MAX(%s) autoinc value from the "
- "index (%s).\n", error, col_name, index->name);
- }
+ fprintf(stderr, " InnoDB: MySQL and InnoDB data "
+ "dictionaries are out of sync.\n"
+ "InnoDB: Unable to find the AUTOINC column %s in the "
+ "InnoDB table %s.\n"
+ "InnoDB: We set the next AUTOINC column value to the "
+ "maximum possible value,\n"
+ "InnoDB: in effect disabling the AUTOINC next value "
+ "generation.\n"
+ "InnoDB: You can either set the next AUTOINC value "
+ "explicitly using ALTER TABLE\n"
+ "InnoDB: or fix the data dictionary by recreating "
+ "the table.\n",
+ col_name, index->table->name);
+
+ auto_inc = 0xFFFFFFFFFFFFFFFFULL;
+
+ dict_table_autoinc_initialize(innodb_table, auto_inc);
+
+ error = DB_SUCCESS;
+ } /* else other errors are still fatal */
return(ulong(error));
}
@@ -2741,7 +2796,6 @@ retry:
if (dict_table_autoinc_read(prebuilt->table) == 0) {
error = innobase_initialize_autoinc();
- /* Should always succeed! */
ut_a(error == DB_SUCCESS);
}
@@ -3201,7 +3255,10 @@ ha_innobase::store_key_val_for_row(
} else if (mysql_type == MYSQL_TYPE_TINY_BLOB
|| mysql_type == MYSQL_TYPE_MEDIUM_BLOB
|| mysql_type == MYSQL_TYPE_BLOB
- || mysql_type == MYSQL_TYPE_LONG_BLOB) {
+ || mysql_type == MYSQL_TYPE_LONG_BLOB
+ /* MYSQL_TYPE_GEOMETRY data is treated
+ as BLOB data in innodb. */
+ || mysql_type == MYSQL_TYPE_GEOMETRY) {
CHARSET_INFO* cs;
ulint key_len;
@@ -5153,6 +5210,28 @@ create_table_def(
}
}
+ /* First check whether the column to be added has a
+ system reserved name. */
+ if (dict_col_name_is_reserved(field->field_name)){
+ push_warning_printf(
+ (THD*) trx->mysql_thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_CANT_CREATE_TABLE,
+ "Error creating table '%s' with "
+ "column name '%s'. '%s' is a "
+ "reserved name. Please try to "
+ "re-create the table with a "
+ "different column name.",
+ table->name, (char*) field->field_name,
+ (char*) field->field_name);
+
+ dict_mem_table_free(table);
+ trx_commit_for_mysql(trx);
+
+ error = DB_ERROR;
+ goto error_ret;
+ }
+
dict_mem_table_add_col(table, table->heap,
(char*) field->field_name,
col_type,
@@ -5168,6 +5247,7 @@ create_table_def(
innodb_check_for_record_too_big_error(flags & DICT_TF_COMPACT, error);
+error_ret:
error = convert_error_code_to_mysql(error, NULL);
DBUG_RETURN(error);
@@ -5205,6 +5285,9 @@ create_index(
n_fields = key->key_parts;
+ /* Assert that "GEN_CLUST_INDEX" cannot be used as non-primary index */
+ ut_a(innobase_strcasecmp(key->name, innobase_index_reserve_name) != 0);
+
ind_type = 0;
if (key_num == form->s->primary_key) {
@@ -5317,8 +5400,8 @@ create_clustered_index_when_no_primary(
/* We pass 0 as the space id, and determine at a lower level the space
id where to store the table */
-
- index = dict_mem_index_create(table_name, "GEN_CLUST_INDEX",
+ index = dict_mem_index_create(table_name,
+ innobase_index_reserve_name,
0, DICT_CLUSTERED, 0);
error = row_create_index_for_mysql(index, trx, NULL);
@@ -5379,13 +5462,15 @@ ha_innobase::create(
1. <database_name>/<table_name>: for normal table creation
2. full path: for temp table creation, or sym link
- When srv_file_per_table is on, check for full path pattern, i.e.
+ When srv_file_per_table is on and mysqld_embedded is off,
+ check for full path pattern, i.e.
X:\dir\..., X is a driver letter, or
\\dir1\dir2\..., UNC path
returns error if it is in full path format, but not creating a temp.
table. Currently InnoDB does not support symbolic link on Windows. */
if (srv_file_per_table
+ && !mysqld_embedded
&& (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) {
if ((name[1] == ':')
@@ -5450,14 +5535,6 @@ ha_innobase::create(
flags |= DICT_TF_COMPACT;
}
- error = create_table_def(trx, form, norm_name,
- create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
- flags);
-
- if (error) {
- goto cleanup;
- }
-
/* Look for a primary key */
primary_key_no= (form->s->primary_key != MAX_KEY ?
@@ -5469,6 +5546,22 @@ ha_innobase::create(
DBUG_ASSERT(primary_key_no == -1 || primary_key_no == 0);
+ /* Check for name conflicts (with reserved name) for
+ any user indices to be created. */
+ if (innobase_index_name_is_reserved(trx, form, norm_name)) {
+ error = -1;
+ goto cleanup;
+ }
+
+ error = create_table_def(trx, form, norm_name,
+ create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
+ flags);
+
+ if (error) {
+ goto cleanup;
+ }
+
+
/* Create the keys */
if (form->s->keys == 0 || primary_key_no == -1) {
@@ -5533,18 +5626,22 @@ ha_innobase::create(
setup at this stage and so we use thd. */
/* We need to copy the AUTOINC value from the old table if
- this is an ALTER TABLE. */
+ this is an ALTER TABLE or CREATE INDEX because CREATE INDEX
+ does a table copy too. */
if (((create_info->used_fields & HA_CREATE_USED_AUTO)
- || thd_sql_command(thd) == SQLCOM_ALTER_TABLE)
- && create_info->auto_increment_value != 0) {
-
- /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
- CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
- definition from the dictionary and get the current value
- of the auto increment field. Set a new value to the
- auto increment field if the value is greater than the
- maximum value in the column. */
+ || thd_sql_command(thd) == SQLCOM_ALTER_TABLE
+ || thd_sql_command(thd) == SQLCOM_CREATE_INDEX)
+ && create_info->auto_increment_value > 0) {
+
+ /* Query was one of :
+ CREATE TABLE ...AUTO_INCREMENT = x; or
+ ALTER TABLE...AUTO_INCREMENT = x; or
+ CREATE INDEX x on t(...);
+ Find out a table definition from the dictionary and get
+ the current value of the auto increment field. Set a new
+ value to the auto increment field if the value is greater
+ than the maximum value in the column. */
auto_inc_value = create_info->auto_increment_value;
@@ -6366,9 +6463,15 @@ ha_innobase::analyze(
THD* thd, /* in: connection thread handle */
HA_CHECK_OPT* check_opt) /* in: currently ignored */
{
+ /* Serialize ANALYZE TABLE inside InnoDB, see
+ Bug#38996 Race condition in ANALYZE TABLE */
+ pthread_mutex_lock(&analyze_mutex);
+
/* Simply call ::info() with all the flags */
info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
+ pthread_mutex_unlock(&analyze_mutex);
+
return(0);
}
@@ -6965,8 +7068,9 @@ ha_innobase::external_lock(
{
ulong const binlog_format= thd_binlog_format(thd);
ulong const tx_isolation = thd_tx_isolation(current_thd);
- if (tx_isolation <= ISO_READ_COMMITTED &&
- binlog_format == BINLOG_FORMAT_STMT)
+ if (tx_isolation <= ISO_READ_COMMITTED
+ && binlog_format == BINLOG_FORMAT_STMT
+ && thd_binlog_filter_ok(thd))
{
char buf[256];
my_snprintf(buf, sizeof(buf),
@@ -7803,6 +7907,7 @@ ha_innobase::get_auto_increment(
AUTOINC counter after attempting to insert the row. */
if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
ulonglong need;
+ ulonglong current;
ulonglong next_value;
ulonglong col_max_value;
@@ -7811,11 +7916,12 @@ ha_innobase::get_auto_increment(
col_max_value = innobase_get_int_col_max_value(
table->next_number_field);
+ current = *first_value > col_max_value ? autoinc : *first_value;
need = *nb_reserved_values * increment;
/* Compute the last value in the interval */
next_value = innobase_next_autoinc(
- *first_value, need, offset, col_max_value);
+ current, need, offset, col_max_value);
prebuilt->autoinc_last_value = next_value;
@@ -8415,6 +8521,46 @@ static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff)
return 0;
}
+/***********************************************************************
+This function checks each index name for a table against reserved
+system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
+this function pushes an error message to the client, and returns true. */
+static
+bool
+innobase_index_name_is_reserved(
+/*============================*/
+ /* out: true if an index name
+ matches the reserved name */
+ const trx_t* trx, /* in: InnoDB transaction handle */
+ const TABLE* form, /* in: information on table
+ columns and indexes */
+ const char* norm_name) /* in: table name */
+{
+ KEY* key;
+ uint key_num; /* index number */
+
+ for (key_num = 0; key_num < form->s->keys; key_num++) {
+ key = form->key_info + key_num;
+
+ if (innobase_strcasecmp(key->name,
+ innobase_index_reserve_name) == 0) {
+ /* Push warning to mysql */
+ push_warning_printf((THD*) trx->mysql_thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_CANT_CREATE_TABLE,
+ "Cannot Create Index with name "
+ "'%s'. The name is reserved "
+ "for the system default primary "
+ "index.",
+ innobase_index_reserve_name);
+
+ return(true);
+ }
+ }
+
+ return(false);
+}
+
static SHOW_VAR innodb_status_variables_export[]= {
{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
{NullS, NullS, SHOW_LONG}
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index f6410af2587..6d66b6456fb 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -253,4 +253,11 @@ int thd_binlog_format(const MYSQL_THD thd);
@param all TRUE <=> rollback main transaction.
*/
void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
+
+/**
+ Check if binary logging is filtered for thread's current db.
+ @param thd Thread handle
+ @retval 1 the query is not filtered, 0 otherwise.
+*/
+bool thd_binlog_filter_ok(const MYSQL_THD thd);
}
diff --git a/storage/innobase/os/os0proc.c b/storage/innobase/os/os0proc.c
index a99fe8b6a0e..f00475fc528 100644
--- a/storage/innobase/os/os0proc.c
+++ b/storage/innobase/os/os0proc.c
@@ -591,6 +591,7 @@ os_mem_alloc_large(
fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to"
" attach shared memory segment, errno %d\n",
errno);
+ ptr = NULL;
}
/* Remove the shared memory segment so that it will be
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index 6ec466cf995..4fcb1fbf9f2 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -1788,7 +1788,6 @@ row_create_table_for_mysql(
const char* table_name;
ulint table_name_len;
ulint err;
- ulint i;
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
#ifdef UNIV_SYNC_DEBUG
@@ -1827,18 +1826,6 @@ row_create_table_for_mysql(
return(DB_ERROR);
}
- /* Check that no reserved column names are used. */
- for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
- if (dict_col_name_is_reserved(
- dict_table_get_col_name(table, i))) {
-
- dict_mem_table_free(table);
- trx_commit_for_mysql(trx);
-
- return(DB_ERROR);
- }
- }
-
trx_start_if_not_started(trx);
/* The table name is prefixed with the database name and a '/'.
@@ -2102,7 +2089,7 @@ 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.
Each foreign key constraint must be accompanied with indexes in
-bot participating tables. The indexes are allowed to contain more
+both participating tables. The indexes are allowed to contain more
fields than mentioned in the constraint. Check also that foreign key
constraints which reference this table are ok. */
diff --git a/storage/innodb_plugin/CMakeLists.txt b/storage/innodb_plugin/CMakeLists.txt
index a4de7fd1a2a..36e157ae736 100644
--- a/storage/innodb_plugin/CMakeLists.txt
+++ b/storage/innodb_plugin/CMakeLists.txt
@@ -18,14 +18,20 @@
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
+
+# Starting at 5.1.38, MySQL CMake files are simplified. But the plugin
+# CMakeLists.txt still needs to work with previous versions of MySQL.
+IF (MYSQL_VERSION_ID GREATER "50137")
+ INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
+ENDIF (MYSQL_VERSION_ID GREATER "50137")
+
IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
SET(WIN64 TRUE)
ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8)
# Include directories under innodb_plugin
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/innodb_plugin/include
- ${CMAKE_SOURCE_DIR}/storage/innodfb_plugin/handler)
+ ${CMAKE_SOURCE_DIR}/storage/innodb_plugin/handler)
# Include directories under mysql
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
@@ -36,10 +42,10 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
# Removing compiler optimizations for innodb/mem/* files on 64-bit Windows
# due to 64-bit compiler error, See MySQL Bug #19424, #36366, #34297
-IF(MSVC AND $(WIN64))
+IF (MSVC AND $(WIN64))
SET_SOURCE_FILES_PROPERTIES(mem/mem0mem.c mem/mem0pool.c
PROPERTIES COMPILE_FLAGS -Od)
-ENDIF(MSVC AND $(WIN64))
+ENDIF (MSVC AND $(WIN64))
SET(INNODB_PLUGIN_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c
@@ -74,7 +80,7 @@ SET(INNODB_PLUGIN_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea
usr/usr0sess.c
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
ut/ut0list.c ut/ut0wqueue.c)
-ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DINNODB_RW_LOCKS_USE_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION)
+ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION)
#Disable storage engine, as we are using XtraDB
#MYSQL_STORAGE_ENGINE(INNODB_PLUGIN)
diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog
index 2b04c06f0e8..70225ffd9d9 100644
--- a/storage/innodb_plugin/ChangeLog
+++ b/storage/innodb_plugin/ChangeLog
@@ -1,3 +1,229 @@
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,
+ mysql-test/innodb-autoinc.test:
+ Fix Bug#47125 auto_increment start value is ignored if an index is
+ created and engine=innodb
+
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_bug47777.result,
+ mysql-test/innodb_bug47777.test:
+ Fix Bug#47777 innodb dies with spatial pk: Failing assertion: buf <=
+ original_buf + buf_len
+
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#38996 Race condition in ANALYZE TABLE
+
+2009-10-29 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix bug#42383: Can't create table 'test.bug39438'
+
+2009-10-29 The InnoDB Team
+
+ * os/os0proc.c:
+ Fix Bug#48237 Error handling in os_mem_alloc_large appears to
+ be incorrect
+
+2009-10-29 The InnoDB Team
+
+ * buf/buf0buf.c, buf/buf0lru.c, include/buf0buf.h, include/buf0buf.ic:
+ Fix corruption of the buf_pool->LRU_old list and improve debug
+ assertions.
+
+2009-10-28 The InnoDB Team
+
+ * srv/srv0start.c:
+ Fix Bug#41490 After enlargement of InnoDB page size, the error message
+ become inaccurate
+
+2009-10-26 The InnoDB Team
+
+ * row/row0ins.c:
+ When allocating a data tuple, zero out the system fields in order
+ to avoid Valgrind warnings about uninitialized fields in
+ dtuple_validate().
+
+2009-10-22 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb-zip.result,
+ mysql-test/innodb-zip.test, mysql-test/innodb_bug44369.result,
+ mysql-test/innodb_bug44369.test:
+ Fix Bug#47233 Innodb calls push_warning(MYSQL_ERROR::WARN_LEVEL_ERROR)
+
+2009-10-19 The InnoDB Team
+
+ * mysql-test/innodb_information_schema.test:
+ Fix Bug#47808 innodb_information_schema.test fails when run under
+ valgrind
+
+2009-10-15 The InnoDB Team
+
+ * include/page0page.ic:
+ Fix Bug#47058 Failure to compile innodb_plugin on solaris 10u7 + spro
+ cc/CC 5.10
+
+2009-10-05 The InnoDB Team
+
+ * buf/buf0buf.c:
+ Do not invalidate buffer pool while an LRU batch is active. Added code
+ to buf_pool_invalidate() to wait for the running batches to finish.
+
+2009-10-01 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#47763 typo in error message: Failed to open table %s after %lu
+ attemtps.
+
+2009-10-01 The InnoDB Team
+
+ * fsp/fsp0fsp.c, row/row0merge.c:
+ Clean up after a crash during DROP INDEX. When InnoDB crashes
+ while dropping an index, ensure that the index will be completely
+ dropped during crash recovery. The MySQL .frm file may still
+ contain the dropped index, but there is little that we can do
+ about it.
+
+2009-09-28 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ When a secondary index exists in the MySQL .frm file but not in
+ the InnoDB data dictionary, return an error instead of letting an
+ assertion fail in index_read.
+
+2009-09-28 The InnoDB Team
+
+ * btr/btr0btr.c, buf/buf0buf.c, include/page0page.h,
+ include/page0zip.h, page/page0cur.c, page/page0page.c,
+ page/page0zip.c:
+ Do not write to PAGE_INDEX_ID when restoring an uncompressed page
+ after a compression failure. The field should only be written
+ when creating a B-tree page. This fix addresses a race condition
+ in a debug assertion.
+
+2009-09-28 The InnoDB Team
+
+ * fil/fil0fil.c:
+ Try to prevent the reuse of tablespace identifiers after InnoDB
+ has crashed during table creation. Also, refuse to start if files
+ with duplicate tablespace identifiers are encountered.
+
+2009-09-25 The InnoDB Team
+
+ * include/os0file.h, os/os0file.c:
+ Fix Bug#47055 unconditional exit(1) on ERROR_WORKING_SET_QUOTA
+ 1453 (0x5AD) for InnoDB backend
+
+2009-09-19 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb-consistent-master.opt,
+ mysql-test/innodb-consistent.result,
+ mysql-test/innodb-consistent.test:
+ Fix Bug#37232 Innodb might get too many read locks for DML with
+ repeatable-read
+
+2009-09-19 The InnoDB Team
+
+ * fsp/fsp0fsp.c:
+ Fix Bug#31183 Tablespace full problems not reported in error log,
+ error message unclear
+
+2009-09-17 The InnoDB Team
+
+ * mysql-test/innodb-zip.result, mysql-test/innodb-zip.test:
+ Make the test pass with zlib 1.2.3.3. Apparently, the definition
+ of compressBound() has changed between zlib versions, and the
+ maximum record size of a table with 1K compressed page size has
+ been reduced by one byte. This is an arbitrary test. In practical
+ applications, for good write performance, the compressed page size
+ should be chosen to be bigger than the absolute minimum.
+
+2009-09-16 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#46256 drop table with unknown collation crashes innodb
+
+2009-09-16 The InnoDB Team
+
+ * dict/dict0dict.c, handler/ha_innodb.cc,
+ mysql-test/innodb_bug44369.result, mysql-test/innodb_bug44369.test,
+ row/row0mysql.c:
+ Fix Bug#44369 InnoDB: Does not uniformly disallow disallowed column
+ names
+
+2009-09-16 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/db0err.h,
+ mysql-test/innodb_bug46000.result, mysql-test/innodb_bug46000.test:
+ Fix Bug#46000 using index called GEN_CLUST_INDEX crashes server
+
+2009-09-02 The InnoDB Team
+
+ * include/lock0lock.h, include/row0mysql.h, lock/lock0lock.c,
+ row/row0mysql.c:
+ Fix a regression introduced by the fix for MySQL bug#26316. We check
+ whether a transaction holds any AUTOINC locks before we acquire
+ the kernel mutex and release those locks.
+
+2009-08-27 The InnoDB Team
+
+ * dict/dict0dict.c, include/dict0dict.h,
+ mysql-test/innodb_bug44571.result, mysql-test/innodb_bug44571.test:
+ Fix Bug#44571 InnoDB Plugin crashes on ADD INDEX
+
+2009-08-27 The InnoDB Team
+
+ * row/row0merge.c:
+ Fix a bug in the merge sort that can corrupt indexes in fast index
+ creation. Add some consistency checks. Check that the number of
+ records remains constant in every merge sort pass.
+
+2009-08-27 The InnoDB Team
+
+ * buf/buf0buf.c, buf/buf0lru.c, buf/buf0rea.c, handler/ha_innodb.cc,
+ include/buf0buf.h, include/buf0buf.ic, include/buf0lru.h,
+ include/ut0ut.h, ut/ut0ut.c:
+ Make it possible to tune the buffer pool LRU eviction policy to be
+ more resistant against index scans. Introduce the settable global
+ variables innodb_old_blocks_pct and innodb_old_blocks_time for
+ controlling the buffer pool eviction policy. The parameter
+ innodb_old_blocks_pct (5..95) controls the desired amount of "old"
+ blocks in the LRU list. The default is 37, corresponding to the
+ old fixed ratio of 3/8. Each time a block is accessed, it will be
+ moved to the "new" blocks if its first access was at least
+ innodb_old_blocks_time milliseconds ago (default 0, meaning every
+ block). The idea is that in index scans, blocks will be accessed
+ a few times within innodb_old_blocks_time, and they will remain in
+ the "old" section of the LRU list. Thus, when innodb_old_blocks_time
+ is nonzero, blocks retrieved for one-time index scans will be more
+ likely candidates for eviction than blocks that are accessed in
+ random patterns.
+
+2009-08-26 The InnoDB Team
+
+ * handler/ha_innodb.cc, os/os0file.c:
+ Fix Bug#42885 buf_read_ahead_random, buf_read_ahead_linear counters,
+ thread wakeups
+
+2009-08-20 The InnoDB Team
+
+ * lock/lock0lock.c:
+ Fix Bug#46650 Innodb assertion autoinc_lock == lock in
+ lock_table_remove_low on INSERT SELECT
+
+2009-08-13 The InnoDB Team
+
+ * handler/handler0alter.cc:
+ Fix Bug#46657 InnoDB plugin: invalid read in index_merge_innodb test
+ (Valgrind)
+
+2009-08-11 The InnoDB Team
+
+ InnoDB Plugin 1.0.4 released
+
2009-07-20 The InnoDB Team
* buf/buf0rea.c, handler/ha_innodb.cc, include/srv0srv.h,
diff --git a/storage/innodb_plugin/Makefile.am b/storage/innodb_plugin/Makefile.am
index 50a3c1e6cab..5c71fe18d14 100644
--- a/storage/innodb_plugin/Makefile.am
+++ b/storage/innodb_plugin/Makefile.am
@@ -31,7 +31,6 @@ DEFS= @DEFS@
noinst_HEADERS= \
handler/ha_innodb.h \
- handler/handler0vars.h \
handler/i_s.h \
include/btr0btr.h \
include/btr0btr.ic \
diff --git a/storage/innodb_plugin/README b/storage/innodb_plugin/README
deleted file mode 100644
index 56aa8058224..00000000000
--- a/storage/innodb_plugin/README
+++ /dev/null
@@ -1,29 +0,0 @@
-This is the source of the InnoDB Plugin 1.0.4 for MySQL 5.1
-===========================================================
-
-Instructions for compiling the plugin:
---------------------------------------
-
-1. Get the latest MySQL 5.1 sources from
- http://dev.mysql.com/downloads/mysql/5.1.html#source
-
-2. Replace the contents of the mysql-5.1.N/storage/innobase/ directory
- with the contents of this directory.
-
-3. Optional (only necessary if you are going to run tests from the
- mysql-test suite): cd into the innobase directory and run ./setup.sh
-
-4. Compile MySQL as usual.
-
-5. Enjoy!
-
-See the online documentation for more detailed instructions:
-http://www.innodb.com/doc/innodb_plugin-1.0/innodb-plugin-installation.html
-
-For more information about InnoDB visit
-http://www.innodb.com
-
-Please report any problems or issues with the plugin in the InnoDB Forums
-http://forums.innodb.com/ or in the MySQL Bugs database http://bugs.mysql.com
-
-Thank you for using the InnoDB plugin!
diff --git a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0btr.c
index 6ba9b36207b..94b34ecece1 100644
--- a/storage/innodb_plugin/btr/btr0btr.c
+++ b/storage/innodb_plugin/btr/btr0btr.c
@@ -797,7 +797,7 @@ btr_create(
buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
}
- /* Create a new index page on the the allocated segment page */
+ /* Create a new index page on the allocated segment page */
page_zip = buf_block_get_page_zip(block);
if (UNIV_LIKELY_NULL(page_zip)) {
@@ -1011,7 +1011,26 @@ btr_page_reorganize_low(
(!page_zip_compress(page_zip, page, index, NULL))) {
/* Restore the old page and exit. */
- buf_frame_copy(page, temp_page);
+
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+ /* Check that the bytes that we skip are identical. */
+ ut_a(!memcmp(page, temp_page, PAGE_HEADER));
+ ut_a(!memcmp(PAGE_HEADER + PAGE_N_RECS + page,
+ PAGE_HEADER + PAGE_N_RECS + temp_page,
+ PAGE_DATA - (PAGE_HEADER + PAGE_N_RECS)));
+ ut_a(!memcmp(UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + page,
+ UNIV_PAGE_SIZE - FIL_PAGE_DATA_END + temp_page,
+ FIL_PAGE_DATA_END));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+
+ memcpy(PAGE_HEADER + page, PAGE_HEADER + temp_page,
+ PAGE_N_RECS - PAGE_N_DIR_SLOTS);
+ memcpy(PAGE_DATA + page, PAGE_DATA + temp_page,
+ UNIV_PAGE_SIZE - PAGE_DATA - FIL_PAGE_DATA_END);
+
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+ ut_a(!memcmp(page, temp_page, UNIV_PAGE_SIZE));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
goto func_exit;
}
@@ -1902,7 +1921,7 @@ func_start:
n_uniq, &heap);
/* If the new record is less than the existing record
- the the split in the middle will copy the existing
+ the split in the middle will copy the existing
record to the new node. */
if (cmp_dtuple_rec(tuple, first_rec, offsets) < 0) {
split_rec = page_get_middle_rec(page);
diff --git a/storage/innodb_plugin/btr/btr0sea.c b/storage/innodb_plugin/btr/btr0sea.c
index faa1c13897e..0a80c61a58d 100644
--- a/storage/innodb_plugin/btr/btr0sea.c
+++ b/storage/innodb_plugin/btr/btr0sea.c
@@ -957,7 +957,7 @@ btr_search_guess_on_hash(
/* Increment the page get statistics though we did not really
fix the page: for user info only */
- buf_pool->n_page_gets++;
+ buf_pool->stat.n_page_gets++;
return(TRUE);
diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c
index 0008fcb1271..ff31457d200 100644
--- a/storage/innodb_plugin/buf/buf0buf.c
+++ b/storage/innodb_plugin/buf/buf0buf.c
@@ -837,16 +837,35 @@ buf_chunk_not_freed(
block = chunk->blocks;
for (i = chunk->size; i--; block++) {
- mutex_enter(&block->mutex);
-
- if (buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE
- && !buf_flush_ready_for_replace(&block->page)) {
+ ibool ready;
+ switch (buf_block_get_state(block)) {
+ case BUF_BLOCK_ZIP_FREE:
+ case BUF_BLOCK_ZIP_PAGE:
+ case BUF_BLOCK_ZIP_DIRTY:
+ /* The uncompressed buffer pool should never
+ contain compressed block descriptors. */
+ ut_error;
+ break;
+ case BUF_BLOCK_NOT_USED:
+ case BUF_BLOCK_READY_FOR_USE:
+ case BUF_BLOCK_MEMORY:
+ case BUF_BLOCK_REMOVE_HASH:
+ /* Skip blocks that are not being used for
+ file pages. */
+ break;
+ case BUF_BLOCK_FILE_PAGE:
+ mutex_enter(&block->mutex);
+ ready = buf_flush_ready_for_replace(&block->page);
mutex_exit(&block->mutex);
- return(block);
- }
- mutex_exit(&block->mutex);
+ if (!ready) {
+
+ return(block);
+ }
+
+ break;
+ }
}
return(NULL);
@@ -966,8 +985,6 @@ buf_pool_init(void)
buf_pool->no_flush[i] = os_event_create(NULL);
}
- buf_pool->ulint_clock = 1;
-
/* 3. Initialize LRU fields
--------------------------- */
/* All fields are initialized by mem_zalloc(). */
@@ -1146,10 +1163,15 @@ buf_relocate(
#ifdef UNIV_LRU_DEBUG
/* buf_pool->LRU_old must be the first item in the LRU list
whose "old" flag is set. */
+ ut_a(buf_pool->LRU_old->old);
ut_a(!UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)
|| !UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)->old);
ut_a(!UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
+ } else {
+ /* Check that the "old" flag is consistent in
+ the block and its neighbours. */
+ buf_page_set_old(dpage, buf_page_is_old(dpage));
#endif /* UNIV_LRU_DEBUG */
}
@@ -1471,33 +1493,8 @@ buf_pool_resize(void)
}
/********************************************************************//**
-Moves the block to the start of the LRU list if there is a danger
-that the block would drift out of the buffer pool. */
-UNIV_INLINE
-void
-buf_block_make_young(
-/*=================*/
- buf_page_t* bpage) /*!< in: block to make younger */
-{
- ut_ad(!buf_pool_mutex_own());
-
- /* Note that we read freed_page_clock's without holding any mutex:
- this is allowed since the result is used only in heuristics */
-
- if (buf_page_peek_if_too_old(bpage)) {
-
- buf_pool_mutex_enter();
- /* There has been freeing activity in the LRU list:
- best to move to the head of the LRU list */
-
- buf_LRU_make_block_young(bpage);
- buf_pool_mutex_exit();
- }
-}
-
-/********************************************************************//**
Moves a page to the start of the buffer pool LRU list. This high-level
-function can be used to prevent an important page from from slipping out of
+function can be used to prevent an important page from slipping out of
the buffer pool. */
UNIV_INTERN
void
@@ -1515,6 +1512,36 @@ buf_page_make_young(
}
/********************************************************************//**
+Sets the time of the first access of a page and moves a page to the
+start of the buffer pool LRU list if it is too old. This high-level
+function can be used to prevent an important page from slipping
+out of the buffer pool. */
+static
+void
+buf_page_set_accessed_make_young(
+/*=============================*/
+ buf_page_t* bpage, /*!< in/out: buffer block of a
+ file page */
+ unsigned access_time) /*!< in: bpage->access_time
+ read under mutex protection,
+ or 0 if unknown */
+{
+ ut_ad(!buf_pool_mutex_own());
+ ut_a(buf_page_in_file(bpage));
+
+ if (buf_page_peek_if_too_old(bpage)) {
+ buf_pool_mutex_enter();
+ buf_LRU_make_block_young(bpage);
+ buf_pool_mutex_exit();
+ } else if (!access_time) {
+ ulint time_ms = ut_time_ms();
+ buf_pool_mutex_enter();
+ buf_page_set_accessed(bpage, time_ms);
+ buf_pool_mutex_exit();
+ }
+}
+
+/********************************************************************//**
Resets the check_index_page_at_flush field of a page if found in the buffer
pool. */
UNIV_INTERN
@@ -1645,11 +1672,12 @@ buf_page_get_zip(
buf_page_t* bpage;
mutex_t* block_mutex;
ibool must_read;
+ unsigned access_time;
#ifndef UNIV_LOG_DEBUG
ut_ad(!ibuf_inside());
#endif
- buf_pool->n_page_gets++;
+ buf_pool->stat.n_page_gets++;
for (;;) {
buf_pool_mutex_enter();
@@ -1712,14 +1740,13 @@ err_exit:
got_block:
must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
+ access_time = buf_page_is_accessed(bpage);
buf_pool_mutex_exit();
- buf_page_set_accessed(bpage, TRUE);
-
mutex_exit(block_mutex);
- buf_block_make_young(bpage);
+ buf_page_set_accessed_make_young(bpage, access_time);
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(!bpage->file_page_was_freed);
@@ -1812,7 +1839,7 @@ buf_zip_decompress(
switch (fil_page_get_type(frame)) {
case FIL_PAGE_INDEX:
if (page_zip_decompress(&block->page.zip,
- block->frame)) {
+ block->frame, TRUE)) {
return(TRUE);
}
@@ -2000,7 +2027,7 @@ buf_page_get_gen(
mtr_t* mtr) /*!< in: mini-transaction */
{
buf_block_t* block;
- ibool accessed;
+ unsigned access_time;
ulint fix_type;
ibool must_read;
@@ -2016,7 +2043,7 @@ buf_page_get_gen(
#ifndef UNIV_LOG_DEBUG
ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset, NULL));
#endif
- buf_pool->n_page_gets++;
+ buf_pool->stat.n_page_gets++;
loop:
block = guess;
buf_pool_mutex_enter();
@@ -2243,17 +2270,16 @@ wait_until_unfixed:
UNIV_MEM_ASSERT_RW(&block->page, sizeof block->page);
buf_block_buf_fix_inc(block, file, line);
- buf_pool_mutex_exit();
- /* Check if this is the first access to the page */
+ mutex_exit(&block->mutex);
- accessed = buf_page_is_accessed(&block->page);
+ /* Check if this is the first access to the page */
- buf_page_set_accessed(&block->page, TRUE);
+ access_time = buf_page_is_accessed(&block->page);
- mutex_exit(&block->mutex);
+ buf_pool_mutex_exit();
- buf_block_make_young(&block->page);
+ buf_page_set_accessed_make_young(&block->page, access_time);
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(!block->page.file_page_was_freed);
@@ -2306,7 +2332,7 @@ wait_until_unfixed:
mtr_memo_push(mtr, block, fix_type);
- if (!accessed) {
+ if (!access_time) {
/* In the case of a first access, try to apply linear
read-ahead */
@@ -2336,7 +2362,7 @@ buf_page_optimistic_get_func(
ulint line, /*!< in: line where called */
mtr_t* mtr) /*!< in: mini-transaction */
{
- ibool accessed;
+ unsigned access_time;
ibool success;
ulint fix_type;
@@ -2353,14 +2379,16 @@ buf_page_optimistic_get_func(
}
buf_block_buf_fix_inc(block, file, line);
- accessed = buf_page_is_accessed(&block->page);
- buf_page_set_accessed(&block->page, TRUE);
mutex_exit(&block->mutex);
- buf_block_make_young(&block->page);
+ /* Check if this is the first access to the page.
+ We do a dirty read on purpose, to avoid mutex contention.
+ This field is only used for heuristic purposes; it does not
+ affect correctness. */
- /* Check if this is the first access to the page */
+ access_time = buf_page_is_accessed(&block->page);
+ buf_page_set_accessed_make_young(&block->page, access_time);
ut_ad(!ibuf_inside()
|| ibuf_page(buf_block_get_space(block),
@@ -2412,7 +2440,7 @@ buf_page_optimistic_get_func(
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(block->page.file_page_was_freed == FALSE);
#endif
- if (UNIV_UNLIKELY(!accessed)) {
+ if (UNIV_UNLIKELY(!access_time)) {
/* In the case of a first access, try to apply linear
read-ahead */
@@ -2425,7 +2453,7 @@ buf_page_optimistic_get_func(
ut_a(ibuf_count_get(buf_block_get_space(block),
buf_block_get_page_no(block)) == 0);
#endif
- buf_pool->n_page_gets++;
+ buf_pool->stat.n_page_gets++;
return(TRUE);
}
@@ -2473,8 +2501,20 @@ buf_page_get_known_nowait(
mutex_exit(&block->mutex);
- if (mode == BUF_MAKE_YOUNG) {
- buf_block_make_young(&block->page);
+ if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
+ buf_pool_mutex_enter();
+ buf_LRU_make_block_young(&block->page);
+ buf_pool_mutex_exit();
+ } else if (!buf_page_is_accessed(&block->page)) {
+ /* Above, we do a dirty read on purpose, to avoid
+ mutex contention. The field buf_page_t::access_time
+ is only used for heuristic purposes. Writes to the
+ field must be protected by mutex, however. */
+ ulint time_ms = ut_time_ms();
+
+ buf_pool_mutex_enter();
+ buf_page_set_accessed(&block->page, time_ms);
+ buf_pool_mutex_exit();
}
ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD));
@@ -2513,7 +2553,7 @@ buf_page_get_known_nowait(
|| (ibuf_count_get(buf_block_get_space(block),
buf_block_get_page_no(block)) == 0));
#endif
- buf_pool->n_page_gets++;
+ buf_pool->stat.n_page_gets++;
return(TRUE);
}
@@ -2589,7 +2629,7 @@ buf_page_try_get_func(
#endif /* UNIV_DEBUG_FILE_ACCESSES */
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
- buf_pool->n_page_gets++;
+ buf_pool->stat.n_page_gets++;
#ifdef UNIV_IBUF_COUNT_DEBUG
ut_a(ibuf_count_get(buf_block_get_space(block),
@@ -2608,10 +2648,10 @@ buf_page_init_low(
buf_page_t* bpage) /*!< in: block to init */
{
bpage->flush_type = BUF_FLUSH_LRU;
- bpage->accessed = FALSE;
bpage->io_fix = BUF_IO_NONE;
bpage->buf_fix_count = 0;
bpage->freed_page_clock = 0;
+ bpage->access_time = 0;
bpage->newest_modification = 0;
bpage->oldest_modification = 0;
HASH_INVALIDATE(bpage, hash);
@@ -2907,6 +2947,7 @@ buf_page_create(
buf_frame_t* frame;
buf_block_t* block;
buf_block_t* free_block = NULL;
+ ulint time_ms = ut_time_ms();
ut_ad(mtr);
ut_ad(space || !zip_size);
@@ -2953,7 +2994,7 @@ buf_page_create(
buf_LRU_add_block(&block->page, FALSE);
buf_block_buf_fix_inc(block, __FILE__, __LINE__);
- buf_pool->n_pages_created++;
+ buf_pool->stat.n_pages_created++;
if (zip_size) {
void* data;
@@ -2990,12 +3031,12 @@ buf_page_create(
rw_lock_x_unlock(&block->lock);
}
+ buf_page_set_accessed(&block->page, time_ms);
+
buf_pool_mutex_exit();
mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
- buf_page_set_accessed(&block->page, TRUE);
-
mutex_exit(&block->mutex);
/* Delete possible entries for the page from the insert buffer:
@@ -3201,7 +3242,7 @@ corrupt:
ut_ad(buf_pool->n_pend_reads > 0);
buf_pool->n_pend_reads--;
- buf_pool->n_pages_read++;
+ buf_pool->stat.n_pages_read++;
if (uncompressed) {
rw_lock_x_unlock_gen(&((buf_block_t*) bpage)->lock,
@@ -3221,7 +3262,7 @@ corrupt:
BUF_IO_WRITE);
}
- buf_pool->n_pages_written++;
+ buf_pool->stat.n_pages_written++;
break;
@@ -3251,7 +3292,32 @@ void
buf_pool_invalidate(void)
/*=====================*/
{
- ibool freed;
+ ibool freed;
+ enum buf_flush i;
+
+ buf_pool_mutex_enter();
+
+ for (i = BUF_FLUSH_LRU; i < BUF_FLUSH_N_TYPES; i++) {
+
+ /* As this function is called during startup and
+ during redo application phase during recovery, InnoDB
+ is single threaded (apart from IO helper threads) at
+ this stage. No new write batch can be in intialization
+ stage at this point. */
+ ut_ad(buf_pool->init_flush[i] == FALSE);
+
+ /* However, it is possible that a write batch that has
+ been posted earlier is still not complete. For buffer
+ pool invalidation to proceed we must ensure there is NO
+ write activity happening. */
+ if (buf_pool->n_flush[i] > 0) {
+ buf_pool_mutex_exit();
+ buf_flush_wait_batch_end(i);
+ buf_pool_mutex_enter();
+ }
+ }
+
+ buf_pool_mutex_exit();
ut_ad(buf_all_freed());
@@ -3266,6 +3332,14 @@ buf_pool_invalidate(void)
ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
ut_ad(UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0);
+ buf_pool->freed_page_clock = 0;
+ buf_pool->LRU_old = NULL;
+ buf_pool->LRU_old_len = 0;
+ buf_pool->LRU_flush_ended = 0;
+
+ memset(&buf_pool->stat, 0x00, sizeof(buf_pool->stat));
+ buf_refresh_io_stats();
+
buf_pool_mutex_exit();
}
@@ -3528,6 +3602,7 @@ buf_print(void)
"n pending decompressions %lu\n"
"n pending reads %lu\n"
"n pending flush LRU %lu list %lu single page %lu\n"
+ "pages made young %lu, not young %lu\n"
"pages read %lu, created %lu, written %lu\n",
(ulong) size,
(ulong) UT_LIST_GET_LEN(buf_pool->LRU),
@@ -3538,8 +3613,11 @@ buf_print(void)
(ulong) buf_pool->n_flush[BUF_FLUSH_LRU],
(ulong) buf_pool->n_flush[BUF_FLUSH_LIST],
(ulong) buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE],
- (ulong) buf_pool->n_pages_read, buf_pool->n_pages_created,
- (ulong) buf_pool->n_pages_written);
+ (ulong) buf_pool->stat.n_pages_made_young,
+ (ulong) buf_pool->stat.n_pages_not_made_young,
+ (ulong) buf_pool->stat.n_pages_read,
+ (ulong) buf_pool->stat.n_pages_created,
+ (ulong) buf_pool->stat.n_pages_written);
/* Count the number of blocks belonging to each index in the buffer */
@@ -3744,10 +3822,9 @@ buf_print_io(
{
time_t current_time;
double time_elapsed;
- ulint size;
+ ulint n_gets_diff;
ut_ad(buf_pool);
- size = buf_pool->curr_size;
buf_pool_mutex_enter();
@@ -3755,12 +3832,14 @@ buf_print_io(
"Buffer pool size %lu\n"
"Free buffers %lu\n"
"Database pages %lu\n"
+ "Old database pages %lu\n"
"Modified db pages %lu\n"
"Pending reads %lu\n"
"Pending writes: LRU %lu, flush list %lu, single page %lu\n",
- (ulong) size,
+ (ulong) buf_pool->curr_size,
(ulong) UT_LIST_GET_LEN(buf_pool->free),
(ulong) UT_LIST_GET_LEN(buf_pool->LRU),
+ (ulong) buf_pool->LRU_old_len,
(ulong) UT_LIST_GET_LEN(buf_pool->flush_list),
(ulong) buf_pool->n_pend_reads,
(ulong) buf_pool->n_flush[BUF_FLUSH_LRU]
@@ -3772,37 +3851,66 @@ buf_print_io(
current_time = time(NULL);
time_elapsed = 0.001 + difftime(current_time,
buf_pool->last_printout_time);
- buf_pool->last_printout_time = current_time;
fprintf(file,
+ "Pages made young %lu, not young %lu\n"
+ "%.2f youngs/s, %.2f non-youngs/s\n"
"Pages read %lu, created %lu, written %lu\n"
"%.2f reads/s, %.2f creates/s, %.2f writes/s\n",
- (ulong) buf_pool->n_pages_read,
- (ulong) buf_pool->n_pages_created,
- (ulong) buf_pool->n_pages_written,
- (buf_pool->n_pages_read - buf_pool->n_pages_read_old)
+ (ulong) buf_pool->stat.n_pages_made_young,
+ (ulong) buf_pool->stat.n_pages_not_made_young,
+ (buf_pool->stat.n_pages_made_young
+ - buf_pool->old_stat.n_pages_made_young)
+ / time_elapsed,
+ (buf_pool->stat.n_pages_not_made_young
+ - buf_pool->old_stat.n_pages_not_made_young)
+ / time_elapsed,
+ (ulong) buf_pool->stat.n_pages_read,
+ (ulong) buf_pool->stat.n_pages_created,
+ (ulong) buf_pool->stat.n_pages_written,
+ (buf_pool->stat.n_pages_read
+ - buf_pool->old_stat.n_pages_read)
/ time_elapsed,
- (buf_pool->n_pages_created - buf_pool->n_pages_created_old)
+ (buf_pool->stat.n_pages_created
+ - buf_pool->old_stat.n_pages_created)
/ time_elapsed,
- (buf_pool->n_pages_written - buf_pool->n_pages_written_old)
+ (buf_pool->stat.n_pages_written
+ - buf_pool->old_stat.n_pages_written)
/ time_elapsed);
- if (buf_pool->n_page_gets > buf_pool->n_page_gets_old) {
- fprintf(file, "Buffer pool hit rate %lu / 1000\n",
+ n_gets_diff = buf_pool->stat.n_page_gets - buf_pool->old_stat.n_page_gets;
+
+ if (n_gets_diff) {
+ fprintf(file,
+ "Buffer pool hit rate %lu / 1000,"
+ " young-making rate %lu / 1000 not %lu / 1000\n",
+ (ulong)
+ (1000 - ((1000 * (buf_pool->stat.n_pages_read
+ - buf_pool->old_stat.n_pages_read))
+ / (buf_pool->stat.n_page_gets
+ - buf_pool->old_stat.n_page_gets))),
+ (ulong)
+ (1000 * (buf_pool->stat.n_pages_made_young
+ - buf_pool->old_stat.n_pages_made_young)
+ / n_gets_diff),
(ulong)
- (1000 - ((1000 * (buf_pool->n_pages_read
- - buf_pool->n_pages_read_old))
- / (buf_pool->n_page_gets
- - buf_pool->n_page_gets_old))));
+ (1000 * (buf_pool->stat.n_pages_not_made_young
+ - buf_pool->old_stat.n_pages_not_made_young)
+ / n_gets_diff));
} else {
fputs("No buffer pool page gets since the last printout\n",
file);
}
- buf_pool->n_page_gets_old = buf_pool->n_page_gets;
- buf_pool->n_pages_read_old = buf_pool->n_pages_read;
- buf_pool->n_pages_created_old = buf_pool->n_pages_created;
- buf_pool->n_pages_written_old = buf_pool->n_pages_written;
+ /* Statistics about read ahead algorithm */
+ fprintf(file, "Pages read ahead %.2f/s,"
+ " evicted without access %.2f/s\n",
+ (buf_pool->stat.n_ra_pages_read
+ - buf_pool->old_stat.n_ra_pages_read)
+ / time_elapsed,
+ (buf_pool->stat.n_ra_pages_evicted
+ - buf_pool->old_stat.n_ra_pages_evicted)
+ / time_elapsed);
/* Print some values to help us with visualizing what is
happening with LRU eviction. */
@@ -3814,6 +3922,7 @@ buf_print_io(
buf_LRU_stat_sum.io, buf_LRU_stat_cur.io,
buf_LRU_stat_sum.unzip, buf_LRU_stat_cur.unzip);
+ buf_refresh_io_stats();
buf_pool_mutex_exit();
}
@@ -3825,10 +3934,7 @@ buf_refresh_io_stats(void)
/*======================*/
{
buf_pool->last_printout_time = time(NULL);
- buf_pool->n_page_gets_old = buf_pool->n_page_gets;
- buf_pool->n_pages_read_old = buf_pool->n_pages_read;
- buf_pool->n_pages_created_old = buf_pool->n_pages_created;
- buf_pool->n_pages_written_old = buf_pool->n_pages_written;
+ buf_pool->old_stat = buf_pool->stat;
}
/*********************************************************************//**
diff --git a/storage/innodb_plugin/buf/buf0flu.c b/storage/innodb_plugin/buf/buf0flu.c
index 74dd0c07ca6..8b614ce90e5 100644
--- a/storage/innodb_plugin/buf/buf0flu.c
+++ b/storage/innodb_plugin/buf/buf0flu.c
@@ -304,6 +304,28 @@ buf_flush_write_complete(
}
/********************************************************************//**
+Flush a batch of writes to the datafiles that have already been
+written by the OS. */
+static
+void
+buf_flush_sync_datafiles(void)
+/*==========================*/
+{
+ /* Wake possible simulated aio thread to actually post the
+ writes to the operating system */
+ os_aio_simulated_wake_handler_threads();
+
+ /* Wait that all async writes to tablespaces have been posted to
+ the OS */
+ os_aio_wait_until_no_pending_writes();
+
+ /* Now we flush the data to disk (for example, with fsync) */
+ fil_flush_file_spaces(FIL_TABLESPACE);
+
+ return;
+}
+
+/********************************************************************//**
Flushes possible buffered writes from the doublewrite memory buffer to disk,
and also wakes up the aio thread if simulated aio is used. It is very
important to call this function after a batch of writes has been posted,
@@ -320,8 +342,8 @@ buf_flush_buffered_writes(void)
ulint i;
if (!srv_use_doublewrite_buf || trx_doublewrite == NULL) {
- os_aio_simulated_wake_handler_threads();
-
+ /* Sync the writes to the disk. */
+ buf_flush_sync_datafiles();
return;
}
@@ -529,22 +551,10 @@ flush:
buf_LRU_stat_inc_io();
}
- /* Wake possible simulated aio thread to actually post the
- writes to the operating system */
-
- os_aio_simulated_wake_handler_threads();
-
- /* Wait that all async writes to tablespaces have been posted to
- the OS */
-
- os_aio_wait_until_no_pending_writes();
-
- /* Now we flush the data to disk (for example, with fsync) */
-
- fil_flush_file_spaces(FIL_TABLESPACE);
+ /* Sync the writes to the disk. */
+ buf_flush_sync_datafiles();
/* We can now reuse the doublewrite memory buffer: */
-
trx_doublewrite->first_free = 0;
mutex_exit(&(trx_doublewrite->mutex));
diff --git a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0lru.c
index be53a5f5d9d..4f19fd13fa5 100644
--- a/storage/innodb_plugin/buf/buf0lru.c
+++ b/storage/innodb_plugin/buf/buf0lru.c
@@ -49,18 +49,22 @@ Created 11/5/1995 Heikki Tuuri
#include "log0recv.h"
#include "srv0srv.h"
-/** The number of blocks from the LRU_old pointer onward, including the block
-pointed to, must be 3/8 of the whole LRU list length, except that the
-tolerance defined below is allowed. Note that the tolerance must be small
-enough such that for even the BUF_LRU_OLD_MIN_LEN long LRU list, the
-LRU_old pointer is not allowed to point to either end of the LRU list. */
+/** The number of blocks from the LRU_old pointer onward, including
+the block pointed to, must be buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
+of the whole LRU list length, except that the tolerance defined below
+is allowed. Note that the tolerance must be small enough such that for
+even the BUF_LRU_OLD_MIN_LEN long LRU list, the LRU_old pointer is not
+allowed to point to either end of the LRU list. */
#define BUF_LRU_OLD_TOLERANCE 20
-/** The whole LRU list length is divided by this number to determine an
-initial segment in buf_LRU_get_recent_limit */
-
-#define BUF_LRU_INITIAL_RATIO 8
+/** The minimum amount of non-old blocks when the LRU_old list exists
+(that is, when there are more than BUF_LRU_OLD_MIN_LEN blocks).
+@see buf_LRU_old_adjust_len */
+#define BUF_LRU_NON_OLD_MIN_LEN 5
+#if BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN
+# error "BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN"
+#endif
/** When dropping the search hash index entries before deleting an ibd
file, we build a local array of pages belonging to that tablespace
@@ -107,6 +111,15 @@ UNIV_INTERN buf_LRU_stat_t buf_LRU_stat_sum;
/* @} */
+/** @name Heuristics for detecting index scan @{ */
+/** Reserve this much/BUF_LRU_OLD_RATIO_DIV of the buffer pool for
+"old" blocks. Protected by buf_pool_mutex. */
+UNIV_INTERN uint buf_LRU_old_ratio;
+/** Move blocks to "new" LRU list only if the first access was at
+least this many milliseconds ago. Not protected by any mutex or latch. */
+UNIV_INTERN uint buf_LRU_old_threshold_ms;
+/* @} */
+
/******************************************************************//**
Takes a block out of the LRU list and page hash table.
If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
@@ -428,42 +441,6 @@ next_page:
}
}
-/******************************************************************//**
-Gets the minimum LRU_position field for the blocks in an initial segment
-(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
-guaranteed to be precise, because the ulint_clock may wrap around.
-@return the limit; zero if could not determine it */
-UNIV_INTERN
-ulint
-buf_LRU_get_recent_limit(void)
-/*==========================*/
-{
- const buf_page_t* bpage;
- ulint len;
- ulint limit;
-
- buf_pool_mutex_enter();
-
- len = UT_LIST_GET_LEN(buf_pool->LRU);
-
- if (len < BUF_LRU_OLD_MIN_LEN) {
- /* The LRU list is too short to do read-ahead */
-
- buf_pool_mutex_exit();
-
- return(0);
- }
-
- bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
-
- limit = buf_page_get_LRU_position(bpage);
- len /= BUF_LRU_INITIAL_RATIO;
-
- buf_pool_mutex_exit();
-
- return(limit > len ? (limit - len) : 0);
-}
-
/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
UNIV_INTERN
@@ -594,6 +571,7 @@ buf_LRU_free_from_common_LRU_list(
bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
enum buf_lru_free_block_status freed;
+ unsigned accessed;
mutex_t* block_mutex
= buf_page_get_mutex(bpage);
@@ -601,11 +579,18 @@ buf_LRU_free_from_common_LRU_list(
ut_ad(bpage->in_LRU_list);
mutex_enter(block_mutex);
+ accessed = buf_page_is_accessed(bpage);
freed = buf_LRU_free_block(bpage, TRUE, NULL);
mutex_exit(block_mutex);
switch (freed) {
case BUF_LRU_FREED:
+ /* Keep track of pages that are evicted without
+ ever being accessed. This gives us a measure of
+ the effectiveness of readahead */
+ if (!accessed) {
+ ++buf_pool->stat.n_ra_pages_evicted;
+ }
return(TRUE);
case BUF_LRU_NOT_FREED:
@@ -953,8 +938,10 @@ buf_LRU_old_adjust_len(void)
ut_a(buf_pool->LRU_old);
ut_ad(buf_pool_mutex_own());
-#if 3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5
-# error "3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5"
+ ut_ad(buf_LRU_old_ratio >= BUF_LRU_OLD_RATIO_MIN);
+ ut_ad(buf_LRU_old_ratio <= BUF_LRU_OLD_RATIO_MAX);
+#if BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)
+# error "BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)"
#endif
#ifdef UNIV_LRU_DEBUG
/* buf_pool->LRU_old must be the first item in the LRU list
@@ -966,34 +953,39 @@ buf_LRU_old_adjust_len(void)
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
#endif /* UNIV_LRU_DEBUG */
+ old_len = buf_pool->LRU_old_len;
+ new_len = ut_min(UT_LIST_GET_LEN(buf_pool->LRU)
+ * buf_LRU_old_ratio / BUF_LRU_OLD_RATIO_DIV,
+ UT_LIST_GET_LEN(buf_pool->LRU)
+ - (BUF_LRU_OLD_TOLERANCE
+ + BUF_LRU_NON_OLD_MIN_LEN));
+
for (;;) {
- old_len = buf_pool->LRU_old_len;
- new_len = 3 * (UT_LIST_GET_LEN(buf_pool->LRU) / 8);
+ buf_page_t* LRU_old = buf_pool->LRU_old;
- ut_ad(buf_pool->LRU_old->in_LRU_list);
- ut_a(buf_pool->LRU_old);
+ ut_a(LRU_old);
+ ut_ad(LRU_old->in_LRU_list);
#ifdef UNIV_LRU_DEBUG
- ut_a(buf_pool->LRU_old->old);
+ ut_a(LRU_old->old);
#endif /* UNIV_LRU_DEBUG */
/* Update the LRU_old pointer if necessary */
- if (old_len < new_len - BUF_LRU_OLD_TOLERANCE) {
+ if (old_len + BUF_LRU_OLD_TOLERANCE < new_len) {
- buf_pool->LRU_old = UT_LIST_GET_PREV(
- LRU, buf_pool->LRU_old);
+ buf_pool->LRU_old = LRU_old = UT_LIST_GET_PREV(
+ LRU, LRU_old);
#ifdef UNIV_LRU_DEBUG
- ut_a(!buf_pool->LRU_old->old);
+ ut_a(!LRU_old->old);
#endif /* UNIV_LRU_DEBUG */
- buf_page_set_old(buf_pool->LRU_old, TRUE);
- buf_pool->LRU_old_len++;
+ old_len = ++buf_pool->LRU_old_len;
+ buf_page_set_old(LRU_old, TRUE);
} else if (old_len > new_len + BUF_LRU_OLD_TOLERANCE) {
- buf_page_set_old(buf_pool->LRU_old, FALSE);
- buf_pool->LRU_old = UT_LIST_GET_NEXT(
- LRU, buf_pool->LRU_old);
- buf_pool->LRU_old_len--;
+ buf_pool->LRU_old = UT_LIST_GET_NEXT(LRU, LRU_old);
+ old_len = --buf_pool->LRU_old_len;
+ buf_page_set_old(LRU_old, FALSE);
} else {
return;
}
@@ -1017,12 +1009,13 @@ buf_LRU_old_init(void)
the adjust function to move the LRU_old pointer to the right
position */
- bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
-
- while (bpage != NULL) {
+ for (bpage = UT_LIST_GET_LAST(buf_pool->LRU); bpage != NULL;
+ bpage = UT_LIST_GET_PREV(LRU, bpage)) {
ut_ad(bpage->in_LRU_list);
- buf_page_set_old(bpage, TRUE);
- bpage = UT_LIST_GET_NEXT(LRU, bpage);
+ ut_ad(buf_page_in_file(bpage));
+ /* This loop temporarily violates the
+ assertions of buf_page_set_old(). */
+ bpage->old = TRUE;
}
buf_pool->LRU_old = UT_LIST_GET_FIRST(buf_pool->LRU);
@@ -1075,16 +1068,19 @@ buf_LRU_remove_block(
if (UNIV_UNLIKELY(bpage == buf_pool->LRU_old)) {
- /* Below: the previous block is guaranteed to exist, because
- the LRU_old pointer is only allowed to differ by the
- tolerance value from strict 3/8 of the LRU list length. */
+ /* Below: the previous block is guaranteed to exist,
+ because the LRU_old pointer is only allowed to differ
+ by BUF_LRU_OLD_TOLERANCE from strict
+ buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV of the LRU
+ list length. */
+ buf_page_t* prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
- buf_pool->LRU_old = UT_LIST_GET_PREV(LRU, bpage);
- ut_a(buf_pool->LRU_old);
+ ut_a(prev_bpage);
#ifdef UNIV_LRU_DEBUG
- ut_a(!buf_pool->LRU_old->old);
+ ut_a(!prev_bpage->old);
#endif /* UNIV_LRU_DEBUG */
- buf_page_set_old(buf_pool->LRU_old, TRUE);
+ buf_pool->LRU_old = prev_bpage;
+ buf_page_set_old(prev_bpage, TRUE);
buf_pool->LRU_old_len++;
}
@@ -1095,10 +1091,19 @@ buf_LRU_remove_block(
buf_unzip_LRU_remove_block_if_needed(bpage);
- /* If the LRU list is so short that LRU_old not defined, return */
+ /* If the LRU list is so short that LRU_old is not defined,
+ clear the "old" flags and return */
if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN) {
+ for (bpage = UT_LIST_GET_FIRST(buf_pool->LRU); bpage != NULL;
+ bpage = UT_LIST_GET_NEXT(LRU, bpage)) {
+ /* This loop temporarily violates the
+ assertions of buf_page_set_old(). */
+ bpage->old = FALSE;
+ }
+
buf_pool->LRU_old = NULL;
+ buf_pool->LRU_old_len = 0;
return;
}
@@ -1149,39 +1154,24 @@ buf_LRU_add_block_to_end_low(
/*=========================*/
buf_page_t* bpage) /*!< in: control block */
{
- buf_page_t* last_bpage;
-
ut_ad(buf_pool);
ut_ad(bpage);
ut_ad(buf_pool_mutex_own());
ut_a(buf_page_in_file(bpage));
- last_bpage = UT_LIST_GET_LAST(buf_pool->LRU);
-
- if (last_bpage) {
- bpage->LRU_position = last_bpage->LRU_position;
- } else {
- bpage->LRU_position = buf_pool_clock_tic();
- }
-
ut_ad(!bpage->in_LRU_list);
UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
ut_d(bpage->in_LRU_list = TRUE);
- buf_page_set_old(bpage, TRUE);
-
- if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
-
- buf_pool->LRU_old_len++;
- }
-
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
ut_ad(buf_pool->LRU_old);
/* Adjust the length of the old block list if necessary */
+ buf_page_set_old(bpage, TRUE);
+ buf_pool->LRU_old_len++;
buf_LRU_old_adjust_len();
} else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) {
@@ -1190,6 +1180,8 @@ buf_LRU_add_block_to_end_low(
defined: init it */
buf_LRU_old_init();
+ } else {
+ buf_page_set_old(bpage, buf_pool->LRU_old != NULL);
}
/* If this is a zipped block with decompressed frame as well
@@ -1222,7 +1214,6 @@ buf_LRU_add_block_low(
UT_LIST_ADD_FIRST(LRU, buf_pool->LRU, bpage);
- bpage->LRU_position = buf_pool_clock_tic();
bpage->freed_page_clock = buf_pool->freed_page_clock;
} else {
#ifdef UNIV_LRU_DEBUG
@@ -1237,23 +1228,17 @@ buf_LRU_add_block_low(
UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU, buf_pool->LRU_old,
bpage);
buf_pool->LRU_old_len++;
-
- /* We copy the LRU position field of the previous block
- to the new block */
-
- bpage->LRU_position = (buf_pool->LRU_old)->LRU_position;
}
ut_d(bpage->in_LRU_list = TRUE);
- buf_page_set_old(bpage, old);
-
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
ut_ad(buf_pool->LRU_old);
/* Adjust the length of the old block list if necessary */
+ buf_page_set_old(bpage, old);
buf_LRU_old_adjust_len();
} else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) {
@@ -1262,6 +1247,8 @@ buf_LRU_add_block_low(
defined: init it */
buf_LRU_old_init();
+ } else {
+ buf_page_set_old(bpage, buf_pool->LRU_old != NULL);
}
/* If this is a zipped block with decompressed frame as well
@@ -1295,6 +1282,12 @@ buf_LRU_make_block_young(
/*=====================*/
buf_page_t* bpage) /*!< in: control block */
{
+ ut_ad(buf_pool_mutex_own());
+
+ if (bpage->old) {
+ buf_pool->stat.n_pages_made_young++;
+ }
+
buf_LRU_remove_block(bpage);
buf_LRU_add_block_low(bpage, FALSE);
}
@@ -1453,15 +1446,6 @@ alloc:
buf_pool->LRU_old = b;
}
-#ifdef UNIV_LRU_DEBUG
- ut_a(prev_b->old
- || !UT_LIST_GET_NEXT(LRU, b)
- || UT_LIST_GET_NEXT(LRU, b)->old);
- } else {
- ut_a(!prev_b->old
- || !UT_LIST_GET_NEXT(LRU, b)
- || !UT_LIST_GET_NEXT(LRU, b)->old);
-#endif /* UNIV_LRU_DEBUG */
}
lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
@@ -1477,6 +1461,11 @@ alloc:
defined: init it */
buf_LRU_old_init();
}
+#ifdef UNIV_LRU_DEBUG
+ /* Check that the "old" flag is consistent
+ in the block and its neighbours. */
+ buf_page_set_old(b, buf_page_is_old(b));
+#endif /* UNIV_LRU_DEBUG */
} else {
ut_d(b->in_LRU_list = FALSE);
buf_LRU_add_block_low(b, buf_page_is_old(b));
@@ -1847,6 +1836,50 @@ buf_LRU_block_free_hashed_page(
buf_LRU_block_free_non_file_page(block);
}
+/**********************************************************************//**
+Updates buf_LRU_old_ratio.
+@return updated old_pct */
+UNIV_INTERN
+uint
+buf_LRU_old_ratio_update(
+/*=====================*/
+ uint old_pct,/*!< in: Reserve this percentage of
+ the buffer pool for "old" blocks. */
+ ibool adjust) /*!< in: TRUE=adjust the LRU list;
+ FALSE=just assign buf_LRU_old_ratio
+ during the initialization of InnoDB */
+{
+ uint ratio;
+
+ ratio = old_pct * BUF_LRU_OLD_RATIO_DIV / 100;
+ if (ratio < BUF_LRU_OLD_RATIO_MIN) {
+ ratio = BUF_LRU_OLD_RATIO_MIN;
+ } else if (ratio > BUF_LRU_OLD_RATIO_MAX) {
+ ratio = BUF_LRU_OLD_RATIO_MAX;
+ }
+
+ if (adjust) {
+ buf_pool_mutex_enter();
+
+ if (ratio != buf_LRU_old_ratio) {
+ buf_LRU_old_ratio = ratio;
+
+ if (UT_LIST_GET_LEN(buf_pool->LRU)
+ >= BUF_LRU_OLD_MIN_LEN) {
+ buf_LRU_old_adjust_len();
+ }
+ }
+
+ buf_pool_mutex_exit();
+ } else {
+ buf_LRU_old_ratio = ratio;
+ }
+
+ /* the reverse of
+ ratio = old_pct * BUF_LRU_OLD_RATIO_DIV / 100 */
+ return((uint) (ratio * 100 / (double) BUF_LRU_OLD_RATIO_DIV + 0.5));
+}
+
/********************************************************************//**
Update the historical stats that we are collecting for LRU eviction
policy at the end of each interval. */
@@ -1896,7 +1929,6 @@ buf_LRU_validate(void)
buf_block_t* block;
ulint old_len;
ulint new_len;
- ulint LRU_pos;
ut_ad(buf_pool);
buf_pool_mutex_enter();
@@ -1905,7 +1937,11 @@ buf_LRU_validate(void)
ut_a(buf_pool->LRU_old);
old_len = buf_pool->LRU_old_len;
- new_len = 3 * (UT_LIST_GET_LEN(buf_pool->LRU) / 8);
+ new_len = ut_min(UT_LIST_GET_LEN(buf_pool->LRU)
+ * buf_LRU_old_ratio / BUF_LRU_OLD_RATIO_DIV,
+ UT_LIST_GET_LEN(buf_pool->LRU)
+ - (BUF_LRU_OLD_TOLERANCE
+ + BUF_LRU_NON_OLD_MIN_LEN));
ut_a(old_len >= new_len - BUF_LRU_OLD_TOLERANCE);
ut_a(old_len <= new_len + BUF_LRU_OLD_TOLERANCE);
}
@@ -1936,28 +1972,24 @@ buf_LRU_validate(void)
}
if (buf_page_is_old(bpage)) {
- old_len++;
- }
+ const buf_page_t* prev
+ = UT_LIST_GET_PREV(LRU, bpage);
+ const buf_page_t* next
+ = UT_LIST_GET_NEXT(LRU, bpage);
- if (buf_pool->LRU_old && (old_len == 1)) {
- ut_a(buf_pool->LRU_old == bpage);
- }
+ if (!old_len++) {
+ ut_a(buf_pool->LRU_old == bpage);
+ } else {
+ ut_a(!prev || buf_page_is_old(prev));
+ }
- LRU_pos = buf_page_get_LRU_position(bpage);
+ ut_a(!next || buf_page_is_old(next));
+ }
bpage = UT_LIST_GET_NEXT(LRU, bpage);
-
- if (bpage) {
- /* If the following assert fails, it may
- not be an error: just the buf_pool clock
- has wrapped around */
- ut_a(LRU_pos >= buf_page_get_LRU_position(bpage));
- }
}
- if (buf_pool->LRU_old) {
- ut_a(buf_pool->LRU_old_len == old_len);
- }
+ ut_a(buf_pool->LRU_old_len == old_len);
UT_LIST_VALIDATE(list, buf_page_t, buf_pool->free,
ut_ad(ut_list_node_313->in_free_list));
@@ -2000,9 +2032,6 @@ buf_LRU_print(void)
ut_ad(buf_pool);
buf_pool_mutex_enter();
- fprintf(stderr, "Pool ulint clock %lu\n",
- (ulong) buf_pool->ulint_clock);
-
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
while (bpage != NULL) {
@@ -2033,18 +2062,16 @@ buf_LRU_print(void)
const byte* frame;
case BUF_BLOCK_FILE_PAGE:
frame = buf_block_get_frame((buf_block_t*) bpage);
- fprintf(stderr, "\nLRU pos %lu type %lu"
+ fprintf(stderr, "\ntype %lu"
" index id %lu\n",
- (ulong) buf_page_get_LRU_position(bpage),
(ulong) fil_page_get_type(frame),
(ulong) ut_dulint_get_low(
btr_page_get_index_id(frame)));
break;
case BUF_BLOCK_ZIP_PAGE:
frame = bpage->zip.data;
- fprintf(stderr, "\nLRU pos %lu type %lu size %lu"
+ fprintf(stderr, "\ntype %lu size %lu"
" index id %lu\n",
- (ulong) buf_page_get_LRU_position(bpage),
(ulong) fil_page_get_type(frame),
(ulong) buf_page_get_zip_size(bpage),
(ulong) ut_dulint_get_low(
@@ -2052,8 +2079,7 @@ buf_LRU_print(void)
break;
default:
- fprintf(stderr, "\nLRU pos %lu !state %lu!\n",
- (ulong) buf_page_get_LRU_position(bpage),
+ fprintf(stderr, "\n!state %lu!\n",
(ulong) buf_page_get_state(bpage));
break;
}
diff --git a/storage/innodb_plugin/buf/buf0rea.c b/storage/innodb_plugin/buf/buf0rea.c
index 319d6b2a522..dd98ea17eb5 100644
--- a/storage/innodb_plugin/buf/buf0rea.c
+++ b/storage/innodb_plugin/buf/buf0rea.c
@@ -38,14 +38,6 @@ Created 11/5/1995 Heikki Tuuri
#include "srv0start.h"
#include "srv0srv.h"
-/** The size in blocks of the area where the random read-ahead algorithm counts
-the accessed pages when deciding whether to read-ahead */
-#define BUF_READ_AHEAD_RANDOM_AREA BUF_READ_AHEAD_AREA
-
-/** There must be at least this many pages in buf_pool in the area to start
-a random read-ahead */
-#define BUF_READ_AHEAD_RANDOM_THRESHOLD (1 + BUF_READ_AHEAD_RANDOM_AREA / 2)
-
/** The linear read-ahead area size */
#define BUF_READ_AHEAD_LINEAR_AREA BUF_READ_AHEAD_AREA
@@ -62,7 +54,8 @@ flag is cleared and the x-lock released by an i/o-handler thread.
@return 1 if a read request was queued, 0 if the page already resided
in buf_pool, or if the page is in the doublewrite buffer blocks in
which case it is never read into the pool, or if the tablespace does
-not exist or is being dropped */
+not exist or is being dropped
+@return 1 if read request is issued. 0 if it is not */
static
ulint
buf_read_page_low(
@@ -165,174 +158,13 @@ buf_read_page_low(
}
/********************************************************************//**
-Applies a random read-ahead in buf_pool if there are at least a threshold
-value of accessed pages from the random read-ahead area. Does not read any
-page, not even the one at the position (space, offset), if the read-ahead
-mechanism is not activated. NOTE 1: the calling thread may own latches on
-pages: to avoid deadlocks this function must be written such that it cannot
-end up waiting for these latches! NOTE 2: the calling thread must want
-access to the page given: this rule is set to prevent unintended read-aheads
-performed by ibuf routines, a situation which could result in a deadlock if
-the OS does not support asynchronous i/o.
-@return number of page read requests issued; NOTE that if we read ibuf
-pages, it may happen that the page at the given page number does not
-get read even if we return a positive value! */
-static
-ulint
-buf_read_ahead_random(
-/*==================*/
- ulint space, /*!< in: space id */
- ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
- ulint offset) /*!< in: page number of a page which the current thread
- wants to access */
-{
- ib_int64_t tablespace_version;
- ulint recent_blocks = 0;
- ulint count;
- ulint LRU_recent_limit;
- ulint ibuf_mode;
- ulint low, high;
- ulint err;
- ulint i;
- ulint buf_read_ahead_random_area;
-
- /* We have currently disabled random readahead */
- return(0);
-
- if (srv_startup_is_before_trx_rollback_phase) {
- /* No read-ahead to avoid thread deadlocks */
- return(0);
- }
-
- if (ibuf_bitmap_page(zip_size, offset)
- || trx_sys_hdr_page(space, offset)) {
-
- /* If it is an ibuf bitmap page or trx sys hdr, we do
- no read-ahead, as that could break the ibuf page access
- order */
-
- return(0);
- }
-
- /* Remember the tablespace version before we ask te tablespace size
- below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
- do not try to read outside the bounds of the tablespace! */
-
- tablespace_version = fil_space_get_version(space);
-
- buf_read_ahead_random_area = BUF_READ_AHEAD_RANDOM_AREA;
-
- low = (offset / buf_read_ahead_random_area)
- * buf_read_ahead_random_area;
- high = (offset / buf_read_ahead_random_area + 1)
- * buf_read_ahead_random_area;
- if (high > fil_space_get_size(space)) {
-
- high = fil_space_get_size(space);
- }
-
- /* Get the minimum LRU_position field value for an initial segment
- of the LRU list, to determine which blocks have recently been added
- to the start of the list. */
-
- LRU_recent_limit = buf_LRU_get_recent_limit();
-
- buf_pool_mutex_enter();
-
- if (buf_pool->n_pend_reads
- > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
- buf_pool_mutex_exit();
-
- return(0);
- }
-
- /* Count how many blocks in the area have been recently accessed,
- that is, reside near the start of the LRU list. */
-
- for (i = low; i < high; i++) {
- const buf_page_t* bpage = buf_page_hash_get(space, i);
-
- if (bpage
- && buf_page_is_accessed(bpage)
- && (buf_page_get_LRU_position(bpage) > LRU_recent_limit)) {
-
- recent_blocks++;
-
- if (recent_blocks >= BUF_READ_AHEAD_RANDOM_THRESHOLD) {
-
- buf_pool_mutex_exit();
- goto read_ahead;
- }
- }
- }
-
- buf_pool_mutex_exit();
- /* Do nothing */
- return(0);
-
-read_ahead:
- /* Read all the suitable blocks within the area */
-
- if (ibuf_inside()) {
- ibuf_mode = BUF_READ_IBUF_PAGES_ONLY;
- } else {
- ibuf_mode = BUF_READ_ANY_PAGE;
- }
-
- count = 0;
-
- for (i = low; i < high; i++) {
- /* It is only sensible to do read-ahead in the non-sync aio
- mode: hence FALSE as the first parameter */
-
- if (!ibuf_bitmap_page(zip_size, i)) {
- count += buf_read_page_low(
- &err, FALSE,
- ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
- space, zip_size, FALSE,
- tablespace_version, i);
- if (err == DB_TABLESPACE_DELETED) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Warning: in random"
- " readahead trying to access\n"
- "InnoDB: tablespace %lu page %lu,\n"
- "InnoDB: but the tablespace does not"
- " exist or is just being dropped.\n",
- (ulong) space, (ulong) i);
- }
- }
- }
-
- /* In simulated aio we wake the aio handler threads only after
- queuing all aio requests, in native aio the following call does
- nothing: */
-
- os_aio_simulated_wake_handler_threads();
-
-#ifdef UNIV_DEBUG
- if (buf_debug_prints && (count > 0)) {
- fprintf(stderr,
- "Random read-ahead space %lu offset %lu pages %lu\n",
- (ulong) space, (ulong) offset,
- (ulong) count);
- }
-#endif /* UNIV_DEBUG */
-
- ++srv_read_ahead_rnd;
- return(count);
-}
-
-/********************************************************************//**
High-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
-released by the i/o-handler thread. Does a random read-ahead if it seems
-sensible.
-@return number of page read requests issued: this can be greater than
-1 if read-ahead occurred */
+released by the i/o-handler thread.
+@return TRUE if page has been read in, FALSE in case of failure */
UNIV_INTERN
-ulint
+ibool
buf_read_page(
/*==========*/
ulint space, /*!< in: space id */
@@ -341,20 +173,17 @@ buf_read_page(
{
ib_int64_t tablespace_version;
ulint count;
- ulint count2;
ulint err;
tablespace_version = fil_space_get_version(space);
- count = buf_read_ahead_random(space, zip_size, offset);
-
/* We do the i/o in the synchronous aio mode to save thread
switches: hence TRUE */
- count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
- zip_size, FALSE,
- tablespace_version, offset);
- srv_buf_pool_reads+= count2;
+ count = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
+ zip_size, FALSE,
+ tablespace_version, offset);
+ srv_buf_pool_reads += count;
if (err == DB_TABLESPACE_DELETED) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -371,14 +200,14 @@ buf_read_page(
/* Increment number of I/O operations used for LRU policy. */
buf_LRU_stat_inc_io();
- return(count + count2);
+ return(count > 0);
}
/********************************************************************//**
Applies linear read-ahead if in the buf_pool the page is a border page of
a linear read-ahead area and all the pages in the area have been accessed.
Does not read any page if the read-ahead mechanism is not activated. Note
-that the the algorithm looks at the 'natural' adjacent successor and
+that the algorithm looks at the 'natural' adjacent successor and
predecessor of the page, which on the leaf level of a B-tree are the next
and previous page in the chain of leaves. To know these, the page specified
in (space, offset) must already be present in the buf_pool. Thus, the
@@ -498,9 +327,17 @@ buf_read_ahead_linear(
fail_count++;
} else if (pred_bpage) {
- int res = (ut_ulint_cmp(
- buf_page_get_LRU_position(bpage),
- buf_page_get_LRU_position(pred_bpage)));
+ /* Note that buf_page_is_accessed() returns
+ the time of the first access. If some blocks
+ of the extent existed in the buffer pool at
+ the time of a linear access pattern, the first
+ access times may be nonmonotonic, even though
+ the latest access times were linear. The
+ threshold (srv_read_ahead_factor) should help
+ a little against this. */
+ int res = ut_ulint_cmp(
+ buf_page_is_accessed(bpage),
+ buf_page_is_accessed(pred_bpage));
/* Accesses not in the right order */
if (res != 0 && res != asc_or_desc) {
fail_count++;
@@ -643,7 +480,7 @@ buf_read_ahead_linear(
LRU policy decision. */
buf_LRU_stat_inc_io();
- ++srv_read_ahead_seq;
+ buf_pool->stat.n_ra_pages_read += count;
return(count);
}
diff --git a/storage/innodb_plugin/dict/dict0crea.c b/storage/innodb_plugin/dict/dict0crea.c
index 7bad4d2057e..96a9bd8152e 100644
--- a/storage/innodb_plugin/dict/dict0crea.c
+++ b/storage/innodb_plugin/dict/dict0crea.c
@@ -1379,7 +1379,7 @@ dict_create_add_foreign_field_to_dictionary(
Add a single foreign key definition to the data dictionary tables in the
database. We also generate names to constraints that were not named by the
user. A generated constraint has a name of the format
-databasename/tablename_ibfk_<number>, where the numbers start from 1, and
+databasename/tablename_ibfk_NUMBER, where the numbers start from 1, and
are given locally for this table, that is, the number is not global, as in
the old format constraints < 4.0.18 it used to be.
@return error code or DB_SUCCESS */
diff --git a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/dict0dict.c
index d1f0e0ffc19..aedaf7cec1d 100644
--- a/storage/innodb_plugin/dict/dict0dict.c
+++ b/storage/innodb_plugin/dict/dict0dict.c
@@ -82,9 +82,10 @@ static char dict_ibfk[] = "_ibfk_";
/*******************************************************************//**
Tries to find column names for the index and sets the col field of the
-index. */
+index.
+@return TRUE if the column names were found */
static
-void
+ibool
dict_index_find_cols(
/*=================*/
dict_table_t* table, /*!< in: table */
@@ -1169,7 +1170,7 @@ dict_col_name_is_reserved(
ulint i;
for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) {
- if (strcmp(name, reserved_names[i]) == 0) {
+ if (innobase_strcasecmp(name, reserved_names[i]) == 0) {
return(TRUE);
}
@@ -1431,7 +1432,7 @@ add_field_size:
/**********************************************************************//**
Adds an index to the dictionary cache.
-@return DB_SUCCESS or DB_TOO_BIG_RECORD */
+@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
UNIV_INTERN
ulint
dict_index_add_to_cache(
@@ -1457,7 +1458,10 @@ dict_index_add_to_cache(
ut_a(!dict_index_is_clust(index)
|| UT_LIST_GET_LEN(table->indexes) == 0);
- dict_index_find_cols(table, index);
+ if (!dict_index_find_cols(table, index)) {
+
+ return(DB_CORRUPTION);
+ }
/* Build the cache internal representation of the index,
containing also the added system fields */
@@ -1665,9 +1669,10 @@ dict_index_remove_from_cache(
/*******************************************************************//**
Tries to find column names for the index and sets the col field of the
-index. */
+index.
+@return TRUE if the column names were found */
static
-void
+ibool
dict_index_find_cols(
/*=================*/
dict_table_t* table, /*!< in: table */
@@ -1692,17 +1697,21 @@ dict_index_find_cols(
}
}
+#ifdef UNIV_DEBUG
/* It is an error not to find a matching column. */
fputs("InnoDB: Error: no matching column for ", stderr);
ut_print_name(stderr, NULL, FALSE, field->name);
fputs(" in ", stderr);
dict_index_name_print(stderr, NULL, index);
fputs("!\n", stderr);
- ut_error;
+#endif /* UNIV_DEBUG */
+ return(FALSE);
found:
;
}
+
+ return(TRUE);
}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c
index 96e60b0128f..ba6f2f8666f 100644
--- a/storage/innodb_plugin/fil/fil0fil.c
+++ b/storage/innodb_plugin/fil/fil0fil.c
@@ -594,6 +594,11 @@ fil_node_create(
UT_LIST_ADD_LAST(chain, space->chain, node);
+ if (id < SRV_LOG_SPACE_FIRST_ID && fil_system->max_assigned_id < id) {
+
+ fil_system->max_assigned_id = id;
+ }
+
mutex_exit(&fil_system->mutex);
}
@@ -613,12 +618,10 @@ fil_node_open_file(
ulint size_high;
ibool ret;
ibool success;
-#ifndef UNIV_HOTBACKUP
byte* buf2;
byte* page;
ulint space_id;
ulint flags;
-#endif /* !UNIV_HOTBACKUP */
ut_ad(mutex_own(&(system->mutex)));
ut_a(node->n_pending == 0);
@@ -654,9 +657,12 @@ fil_node_open_file(
size_bytes = (((ib_int64_t)size_high) << 32)
+ (ib_int64_t)size_low;
#ifdef UNIV_HOTBACKUP
- node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
- /* TODO: adjust to zip_size, like below? */
-#else
+ if (space->id == 0) {
+ node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
+ os_file_close(node->handle);
+ goto add_size;
+ }
+#endif /* UNIV_HOTBACKUP */
ut_a(space->purpose != FIL_LOG);
ut_a(space->id != 0);
@@ -735,7 +741,10 @@ fil_node_open_file(
(size_bytes
/ dict_table_flags_to_zip_size(flags));
}
-#endif
+
+#ifdef UNIV_HOTBACKUP
+add_size:
+#endif /* UNIV_HOTBACKUP */
space->size += node->size;
}
@@ -955,7 +964,7 @@ close_more:
" while the maximum\n"
"InnoDB: allowed value would be %lu.\n"
"InnoDB: You may need to raise the value of"
- " innodb_max_files_open in\n"
+ " innodb_open_files in\n"
"InnoDB: my.cnf.\n",
(ulong) fil_system->n_open,
(ulong) fil_system->max_n_open);
@@ -1535,7 +1544,7 @@ fil_open_log_and_system_tablespace_files(void)
fprintf(stderr,
"InnoDB: Warning: you must"
" raise the value of"
- " innodb_max_open_files in\n"
+ " innodb_open_files in\n"
"InnoDB: my.cnf! Remember that"
" InnoDB keeps all log files"
" and all system\n"
@@ -2923,7 +2932,6 @@ fil_open_single_table_tablespace(
byte* page;
ulint space_id;
ulint space_flags;
- ibool ret = TRUE;
filepath = fil_make_ibd_name(name, FALSE);
@@ -3001,7 +3009,7 @@ fil_open_single_table_tablespace(
(ulong) space_id, (ulong) space_flags,
(ulong) id, (ulong) flags);
- ret = FALSE;
+ success = FALSE;
goto func_exit;
}
@@ -3021,7 +3029,7 @@ func_exit:
os_file_close(file);
mem_free(filepath);
- return(ret);
+ return(success);
}
#endif /* !UNIV_HOTBACKUP */
@@ -3237,7 +3245,7 @@ fil_load_single_table_tablespace(
fprintf(stderr,
"InnoDB: Renaming tablespace %s of id %lu,\n"
"InnoDB: to %s_ibbackup_old_vers_<timestamp>\n"
- "InnoDB: because its size %lld is too small"
+ "InnoDB: because its size %" PRId64 " is too small"
" (< 4 pages 16 kB each),\n"
"InnoDB: or the space id in the file header"
" is not sensible.\n"
@@ -3299,7 +3307,17 @@ fil_load_single_table_tablespace(
if (!success) {
- goto func_exit;
+ if (srv_force_recovery > 0) {
+ fprintf(stderr,
+ "InnoDB: innodb_force_recovery"
+ " was set to %lu. Continuing crash recovery\n"
+ "InnoDB: even though the tablespace creation"
+ " of this table failed.\n",
+ srv_force_recovery);
+ goto func_exit;
+ }
+
+ exit(1);
}
/* We do not use the size information we have about the file, because
diff --git a/storage/innodb_plugin/fsp/fsp0fsp.c b/storage/innodb_plugin/fsp/fsp0fsp.c
index ce14723ba18..3cc4318fc06 100644
--- a/storage/innodb_plugin/fsp/fsp0fsp.c
+++ b/storage/innodb_plugin/fsp/fsp0fsp.c
@@ -232,6 +232,9 @@ the extent are free and which contain old tuple version to clean. */
#define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
#ifndef UNIV_HOTBACKUP
+/* Flag to indicate if we have printed the tablespace full error. */
+static ibool fsp_tbs_full_error_printed = FALSE;
+
/**********************************************************************//**
Returns an extent to the free list of a space. */
static
@@ -1099,7 +1102,7 @@ fsp_header_inc_size(
/**********************************************************************//**
Gets the current free limit of the system tablespace. The free limit
-means the place of the first page which has never been put to the the
+means the place of the first page which has never been put to the
free list for allocation. The space above that address is initialized
to zero. Sets also the global variable log_fsp_current_free_limit.
@return free limit in megabytes */
@@ -1218,6 +1221,19 @@ fsp_try_extend_data_file(
if (space == 0 && !srv_auto_extend_last_data_file) {
+ /* We print the error message only once to avoid
+ spamming the error log. Note that we don't need
+ to reset the flag to FALSE as dealing with this
+ error requires server restart. */
+ if (fsp_tbs_full_error_printed == FALSE) {
+ fprintf(stderr,
+ "InnoDB: Error: Data file(s) ran"
+ " out of space.\n"
+ "Please add another data file or"
+ " use \'autoextend\' for the last"
+ " data file.\n");
+ fsp_tbs_full_error_printed = TRUE;
+ }
return(FALSE);
}
@@ -1832,6 +1848,8 @@ fsp_seg_inode_page_find_used(
if (!ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) {
/* This is used */
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
return(i);
}
}
@@ -1863,6 +1881,9 @@ fsp_seg_inode_page_find_free(
return(i);
}
+
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
}
return(ULINT_UNDEFINED);
@@ -1981,6 +2002,8 @@ fsp_alloc_seg_inode(
page + FSEG_INODE_PAGE_NODE, mtr);
}
+ ut_ad(ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))
+ || mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
return(inode);
}
@@ -2018,7 +2041,7 @@ fsp_free_seg_inode(
}
mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr);
- mlog_write_ulint(inode + FSEG_MAGIC_N, 0, MLOG_4BYTES, mtr);
+ mlog_write_ulint(inode + FSEG_MAGIC_N, 0xfa051ce3, MLOG_4BYTES, mtr);
if (ULINT_UNDEFINED
== fsp_seg_inode_page_find_used(page, zip_size, mtr)) {
@@ -2034,11 +2057,11 @@ fsp_free_seg_inode(
/**********************************************************************//**
Returns the file segment inode, page x-latched.
-@return segment inode, page x-latched */
+@return segment inode, page x-latched; NULL if the inode is free */
static
fseg_inode_t*
-fseg_inode_get(
-/*===========*/
+fseg_inode_try_get(
+/*===============*/
fseg_header_t* header, /*!< in: segment header */
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size in bytes
@@ -2054,12 +2077,38 @@ fseg_inode_get(
inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr);
- ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
+ if (UNIV_UNLIKELY
+ (ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID)))) {
+
+ inode = NULL;
+ } else {
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
+ }
return(inode);
}
/**********************************************************************//**
+Returns the file segment inode, page x-latched.
+@return segment inode, page x-latched */
+static
+fseg_inode_t*
+fseg_inode_get(
+/*===========*/
+ fseg_header_t* header, /*!< in: segment header */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
+ or 0 for uncompressed pages */
+ mtr_t* mtr) /*!< in: mtr handle */
+{
+ fseg_inode_t* inode
+ = fseg_inode_try_get(header, space, zip_size, mtr);
+ ut_a(inode);
+ return(inode);
+}
+
+/**********************************************************************//**
Gets the page number from the nth fragment page slot.
@return page number, FIL_NULL if not in use */
UNIV_INLINE
@@ -2073,6 +2122,7 @@ fseg_get_nth_frag_page_no(
ut_ad(inode && mtr);
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
return(mach_read_from_4(inode + FSEG_FRAG_ARR
+ n * FSEG_FRAG_SLOT_SIZE));
}
@@ -2091,6 +2141,7 @@ fseg_set_nth_frag_page_no(
ut_ad(inode && mtr);
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX));
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
mlog_write_ulint(inode + FSEG_FRAG_ARR + n * FSEG_FRAG_SLOT_SIZE,
page_no, MLOG_4BYTES, mtr);
@@ -2451,6 +2502,8 @@ fseg_fill_free_list(
xdes_set_state(descr, XDES_FSEG, mtr);
seg_id = mtr_read_dulint(inode + FSEG_ID, mtr);
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
mlog_write_dulint(descr + XDES_ID, seg_id, mtr);
flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr);
@@ -2479,6 +2532,7 @@ fseg_alloc_free_extent(
fil_addr_t first;
ut_ad(!((page_offset(inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
if (flst_get_len(inode + FSEG_FREE, mtr) > 0) {
/* Segment free list is not empty, allocate from it */
@@ -3136,6 +3190,8 @@ fseg_mark_page_used(
ut_ad(seg_inode && mtr);
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE));
+ ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
descr = xdes_get_descriptor(space, zip_size, page, mtr);
@@ -3373,6 +3429,8 @@ fseg_free_extent(
ut_a(xdes_get_state(descr, mtr) == XDES_FSEG);
ut_a(0 == ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, mtr),
mtr_read_dulint(seg_inode + FSEG_ID, mtr)));
+ ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N)
+ == FSEG_MAGIC_N_VALUE);
first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
@@ -3463,7 +3521,13 @@ fseg_free_step(
ut_a(descr);
ut_a(xdes_get_bit(descr, XDES_FREE_BIT,
header_page % FSP_EXTENT_SIZE, mtr) == FALSE);
- inode = fseg_inode_get(header, space, zip_size, mtr);
+ inode = fseg_inode_try_get(header, space, zip_size, mtr);
+
+ if (UNIV_UNLIKELY(inode == NULL)) {
+ fprintf(stderr, "double free of inode from %u:%u\n",
+ (unsigned) space, (unsigned) header_page);
+ return(TRUE);
+ }
descr = fseg_get_first_extent(inode, space, zip_size, mtr);
@@ -3587,6 +3651,7 @@ fseg_get_first_extent(
ut_ad(inode && mtr);
ut_ad(space == page_get_space_id(page_align(inode)));
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
first = fil_addr_null;
@@ -3801,6 +3866,7 @@ fseg_print_low(
(ulong) reserved, (ulong) used, (ulong) n_full,
(ulong) n_frag, (ulong) n_free, (ulong) n_not_full,
(ulong) n_used);
+ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
}
#ifdef UNIV_BTR_PRINT
diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
index 682004407c7..ac710ea2b15 100644
--- a/storage/innodb_plugin/handler/ha_innodb.cc
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
@@ -72,6 +72,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
/* Include necessary InnoDB headers */
extern "C" {
#include "univ.i"
+#include "buf0lru.h"
#include "btr0sea.h"
#include "os0file.h"
#include "os0thread.h"
@@ -106,7 +107,10 @@ extern "C" {
#include "i_s.h"
#ifndef MYSQL_SERVER
-/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
+# ifndef MYSQL_PLUGIN_IMPORT
+# define MYSQL_PLUGIN_IMPORT /* nothing */
+# endif /* MYSQL_PLUGIN_IMPORT */
+/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
is defined the same in both builds: the MySQL server and the InnoDB plugin. */
extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count;
@@ -125,6 +129,7 @@ static ulong commit_threads = 0;
static pthread_mutex_t commit_threads_m;
static pthread_cond_t commit_cond;
static pthread_mutex_t commit_cond_m;
+static pthread_mutex_t analyze_mutex;
static bool innodb_inited = 0;
#define INSIDE_HA_INNOBASE_CC
@@ -152,6 +157,10 @@ static ulong innobase_write_io_threads;
static long long innobase_buffer_pool_size, innobase_log_file_size;
+/** Percentage of the buffer pool to reserve for 'old' blocks.
+Connected to buf_LRU_old_ratio. */
+static uint innobase_old_blocks_pct;
+
/* The default values for the following char* start-up parameters
are determined in innobase_init below: */
@@ -166,9 +175,7 @@ file formats in the configuration file, but can only be set to any
of the supported file formats during runtime. */
static char* innobase_file_format_check = NULL;
-/* The following has a misleading name: starting from 4.0.5, this also
-affects Windows: */
-static char* innobase_unix_file_flush_method = NULL;
+static char* innobase_file_flush_method = NULL;
/* Below we have boolean-valued start-up parameters, and their default
values */
@@ -214,15 +221,19 @@ static void free_share(INNOBASE_SHARE *share);
static int innobase_close_connection(handlerton *hton, THD* thd);
static int innobase_commit(handlerton *hton, THD* thd, bool all);
static int innobase_rollback(handlerton *hton, THD* thd, bool all);
-static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
+static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
void *savepoint);
static int innobase_savepoint(handlerton *hton, THD* thd, void *savepoint);
-static int innobase_release_savepoint(handlerton *hton, THD* thd,
+static int innobase_release_savepoint(handlerton *hton, THD* thd,
void *savepoint);
static handler *innobase_create_handler(handlerton *hton,
TABLE_SHARE *table,
MEM_ROOT *mem_root);
+/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
+system primary index. */
+static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX";
+
/** @brief Initialize the default value of innodb_commit_concurrency.
Once InnoDB is running, the innodb_commit_concurrency must not change
@@ -492,10 +503,10 @@ static SHOW_VAR innodb_status_variables[]= {
(char*) &export_vars.innodb_buffer_pool_pages_misc, SHOW_LONG},
{"buffer_pool_pages_total",
(char*) &export_vars.innodb_buffer_pool_pages_total, SHOW_LONG},
- {"buffer_pool_read_ahead_rnd",
- (char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
- {"buffer_pool_read_ahead_seq",
- (char*) &export_vars.innodb_buffer_pool_read_ahead_seq, SHOW_LONG},
+ {"buffer_pool_read_ahead",
+ (char*) &export_vars.innodb_buffer_pool_read_ahead, SHOW_LONG},
+ {"buffer_pool_read_ahead_evicted",
+ (char*) &export_vars.innodb_buffer_pool_read_ahead_evicted, SHOW_LONG},
{"buffer_pool_read_requests",
(char*) &export_vars.innodb_buffer_pool_read_requests, SHOW_LONG},
{"buffer_pool_reads",
@@ -865,17 +876,14 @@ convert_error_code_to_mysql(
return(ER_PRIMARY_CANT_HAVE_NULL);
case DB_TOO_MANY_CONCURRENT_TRXS:
- /* Once MySQL add the appropriate code to errmsg.txt then
- we can get rid of this #ifdef. NOTE: The code checked by
- the #ifdef is the suggested name for the error condition
- and the actual error code name could very well be different.
- This will require some monitoring, ie. the status
- of this request on our part.*/
-#ifdef ER_TOO_MANY_CONCURRENT_TRXS
- return(ER_TOO_MANY_CONCURRENT_TRXS);
-#else
+ /* New error code HA_ERR_TOO_MANY_CONCURRENT_TRXS is only
+ available in 5.1.38 and later, but the plugin should still
+ work with previous versions of MySQL. */
+#ifdef HA_ERR_TOO_MANY_CONCURRENT_TRXS
+ return(HA_ERR_TOO_MANY_CONCURRENT_TRXS);
+#else /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
return(HA_ERR_RECORD_FILE_FULL);
-#endif
+#endif /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */
case DB_UNSUPPORTED:
return(HA_ERR_UNSUPPORTED);
}
@@ -949,7 +957,23 @@ innobase_get_cset_width(
*mbminlen = cs->mbminlen;
*mbmaxlen = cs->mbmaxlen;
} else {
- ut_a(cset == 0);
+ THD* thd = current_thd;
+
+ if (thd && thd_sql_command(thd) == SQLCOM_DROP_TABLE) {
+
+ /* Fix bug#46256: allow tables to be dropped if the
+ collation is not found, but issue a warning. */
+ if ((global_system_variables.log_warnings)
+ && (cset != 0)){
+
+ sql_print_warning(
+ "Unknown collation #%lu.", cset);
+ }
+ } else {
+
+ ut_a(cset == 0);
+ }
+
*mbminlen = *mbmaxlen = 0;
}
}
@@ -2151,7 +2175,7 @@ innobase_change_buffering_inited_ok:
/* --------------------------------------------------*/
- srv_file_flush_method_str = innobase_unix_file_flush_method;
+ srv_file_flush_method_str = innobase_file_flush_method;
srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
srv_n_log_files = (ulint) innobase_log_files_in_group;
@@ -2206,6 +2230,9 @@ innobase_change_buffering_inited_ok:
ut_a(0 == strcmp(my_charset_latin1.name, "latin1_swedish_ci"));
srv_latin1_ordering = my_charset_latin1.sort_order;
+ innobase_old_blocks_pct = buf_LRU_old_ratio_update(
+ innobase_old_blocks_pct, FALSE);
+
innobase_commit_concurrency_init_default();
/* Since we in this module access directly the fields of a trx
@@ -2225,6 +2252,7 @@ innobase_change_buffering_inited_ok:
pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&analyze_mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&commit_cond, NULL);
innodb_inited= 1;
#ifdef MYSQL_DYNAMIC_PLUGIN
@@ -2279,6 +2307,7 @@ innobase_end(
pthread_mutex_destroy(&prepare_commit_mutex);
pthread_mutex_destroy(&commit_threads_m);
pthread_mutex_destroy(&commit_cond_m);
+ pthread_mutex_destroy(&analyze_mutex);
pthread_cond_destroy(&commit_cond);
}
@@ -2459,6 +2488,19 @@ retry:
}
}
+ /* The following calls to read the MySQL binary log
+ file name and the position return consistent results:
+ 1) Other InnoDB transactions cannot intervene between
+ these calls as we are holding prepare_commit_mutex.
+ 2) Binary logging of other engines is not relevant
+ to InnoDB as all InnoDB requires is that committing
+ InnoDB transactions appear in the same order in the
+ MySQL binary log as they appear in InnoDB logs.
+ 3) A MySQL log file rotation cannot happen because
+ MySQL protects against this by having a counter of
+ transactions in prepared state and it only allows
+ a rotation when the counter drops to zero. See
+ LOCK_prep_xids and COND_prep_xids in log.cc. */
trx->mysql_log_file_name = mysql_bin_log_file_name();
trx->mysql_log_offset = (ib_int64_t) mysql_bin_log_file_pos();
@@ -2544,6 +2586,8 @@ innobase_rollback(
innobase_release_stat_resources(trx);
+ trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
+
/* If we had reserved the auto-inc lock for some table (if
we come here to roll back the latest SQL statement) we
release it now before a possibly lengthy rollback */
@@ -3105,7 +3149,7 @@ retry:
if (is_part) {
sql_print_error("Failed to open table %s after "
- "%lu attemtps.\n", norm_name,
+ "%lu attempts.\n", norm_name,
retries);
}
@@ -3704,7 +3748,10 @@ ha_innobase::store_key_val_for_row(
} else if (mysql_type == MYSQL_TYPE_TINY_BLOB
|| mysql_type == MYSQL_TYPE_MEDIUM_BLOB
|| mysql_type == MYSQL_TYPE_BLOB
- || mysql_type == MYSQL_TYPE_LONG_BLOB) {
+ || mysql_type == MYSQL_TYPE_LONG_BLOB
+ /* MYSQL_TYPE_GEOMETRY data is treated
+ as BLOB data in innodb. */
+ || mysql_type == MYSQL_TYPE_GEOMETRY) {
CHARSET_INFO* cs;
ulint key_len;
@@ -5006,6 +5053,11 @@ ha_innobase::index_read(
index = prebuilt->index;
+ if (UNIV_UNLIKELY(index == NULL)) {
+ prebuilt->index_usable = FALSE;
+ DBUG_RETURN(HA_ERR_CRASHED);
+ }
+
/* Note that if the index for which the search template is built is not
necessarily prebuilt->index, but can also be the clustered index */
@@ -5165,6 +5217,7 @@ ha_innobase::change_active_index(
if (UNIV_UNLIKELY(!prebuilt->index)) {
sql_print_warning("InnoDB: change_active_index(%u) failed",
keynr);
+ prebuilt->index_usable = FALSE;
DBUG_RETURN(1);
}
@@ -5628,7 +5681,7 @@ create_table_def(
number fits in one byte in prtype */
push_warning_printf(
(THD*) trx->mysql_thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_CANT_CREATE_TABLE,
"In InnoDB, charset-collation codes"
" must be below 256."
@@ -5657,6 +5710,28 @@ create_table_def(
}
}
+ /* First check whether the column to be added has a
+ system reserved name. */
+ if (dict_col_name_is_reserved(field->field_name)){
+ push_warning_printf(
+ (THD*) trx->mysql_thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_CANT_CREATE_TABLE,
+ "Error creating table '%s' with "
+ "column name '%s'. '%s' is a "
+ "reserved name. Please try to "
+ "re-create the table with a "
+ "different column name.",
+ table->name, (char*) field->field_name,
+ (char*) field->field_name);
+
+ dict_mem_table_free(table);
+ trx_commit_for_mysql(trx);
+
+ error = DB_ERROR;
+ goto error_ret;
+ }
+
dict_mem_table_add_col(table, table->heap,
(char*) field->field_name,
col_type,
@@ -5670,6 +5745,7 @@ create_table_def(
error = row_create_table_for_mysql(table, trx);
+error_ret:
error = convert_error_code_to_mysql(error, flags, NULL);
DBUG_RETURN(error);
@@ -5708,6 +5784,9 @@ create_index(
n_fields = key->key_parts;
+ /* Assert that "GEN_CLUST_INDEX" cannot be used as non-primary index */
+ ut_a(innobase_strcasecmp(key->name, innobase_index_reserve_name) != 0);
+
ind_type = 0;
if (key_num == form->s->primary_key) {
@@ -5816,8 +5895,8 @@ create_clustered_index_when_no_primary(
/* We pass 0 as the space id, and determine at a lower level the space
id where to store the table */
-
- index = dict_mem_index_create(table_name, "GEN_CLUST_INDEX",
+ index = dict_mem_index_create(table_name,
+ innobase_index_reserve_name,
0, DICT_CLUSTERED, 0);
error = row_create_index_for_mysql(index, trx, NULL);
@@ -5870,7 +5949,7 @@ create_options_are_valid(
/* Valid value. */
break;
default:
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: invalid"
" KEY_BLOCK_SIZE = %lu."
@@ -5884,7 +5963,7 @@ create_options_are_valid(
/* If KEY_BLOCK_SIZE was specified, check for its
dependencies. */
if (kbs_specified && !srv_file_per_table) {
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: KEY_BLOCK_SIZE"
" requires innodb_file_per_table.");
@@ -5892,7 +5971,7 @@ create_options_are_valid(
}
if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) {
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: KEY_BLOCK_SIZE"
" requires innodb_file_format >"
@@ -5916,7 +5995,7 @@ create_options_are_valid(
if (!srv_file_per_table) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: ROW_FORMAT=%s"
" requires innodb_file_per_table.",
@@ -5928,7 +6007,7 @@ create_options_are_valid(
if (srv_file_format < DICT_TF_FORMAT_ZIP) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: ROW_FORMAT=%s"
" requires innodb_file_format >"
@@ -5945,7 +6024,7 @@ create_options_are_valid(
&& form->s->row_type == ROW_TYPE_DYNAMIC) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: cannot specify"
" ROW_FORMAT = DYNAMIC with"
@@ -5969,7 +6048,7 @@ create_options_are_valid(
if (kbs_specified) {
push_warning_printf(
thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: cannot specify"
" ROW_FORMAT = %s with"
@@ -5982,7 +6061,7 @@ create_options_are_valid(
default:
push_warning(thd,
- MYSQL_ERROR::WARN_LEVEL_ERROR,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: invalid ROW_FORMAT specifier.");
ret = FALSE;
@@ -6046,13 +6125,15 @@ ha_innobase::create(
1. <database_name>/<table_name>: for normal table creation
2. full path: for temp table creation, or sym link
- When srv_file_per_table is on, check for full path pattern, i.e.
+ When srv_file_per_table is on and mysqld_embedded is off,
+ check for full path pattern, i.e.
X:\dir\..., X is a driver letter, or
\\dir1\dir2\..., UNC path
returns error if it is in full path format, but not creating a temp.
table. Currently InnoDB does not support symbolic link on Windows. */
if (srv_file_per_table
+ && !mysqld_embedded
&& (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) {
if ((name[1] == ':')
@@ -6243,14 +6324,6 @@ ha_innobase::create(
flags = DICT_TF_COMPACT;
}
- error = create_table_def(trx, form, norm_name,
- create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
- flags);
-
- if (error) {
- goto cleanup;
- }
-
/* Look for a primary key */
primary_key_no= (form->s->primary_key != MAX_KEY ?
@@ -6262,6 +6335,23 @@ ha_innobase::create(
ut_a(primary_key_no == -1 || primary_key_no == 0);
+ /* Check for name conflicts (with reserved name) for
+ any user indices to be created. */
+ if (innobase_index_name_is_reserved(trx, form->key_info,
+ form->s->keys)) {
+ error = -1;
+ goto cleanup;
+ }
+
+ error = create_table_def(trx, form, norm_name,
+ create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
+ flags);
+
+ if (error) {
+ goto cleanup;
+ }
+
+
/* Create the keys */
if (form->s->keys == 0 || primary_key_no == -1) {
@@ -6335,18 +6425,22 @@ ha_innobase::create(
setup at this stage and so we use thd. */
/* We need to copy the AUTOINC value from the old table if
- this is an ALTER TABLE. */
+ this is an ALTER TABLE or CREATE INDEX because CREATE INDEX
+ does a table copy too. */
if (((create_info->used_fields & HA_CREATE_USED_AUTO)
- || thd_sql_command(thd) == SQLCOM_ALTER_TABLE)
- && create_info->auto_increment_value != 0) {
-
- /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
- CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
- definition from the dictionary and get the current value
- of the auto increment field. Set a new value to the
- auto increment field if the value is greater than the
- maximum value in the column. */
+ || thd_sql_command(thd) == SQLCOM_ALTER_TABLE
+ || thd_sql_command(thd) == SQLCOM_CREATE_INDEX)
+ && create_info->auto_increment_value > 0) {
+
+ /* Query was one of :
+ CREATE TABLE ...AUTO_INCREMENT = x; or
+ ALTER TABLE...AUTO_INCREMENT = x; or
+ CREATE INDEX x on t(...);
+ Find out a table definition from the dictionary and get
+ the current value of the auto increment field. Set a new
+ value to the auto increment field if the value is greater
+ than the maximum value in the column. */
auto_inc_value = create_info->auto_increment_value;
@@ -7200,9 +7294,15 @@ ha_innobase::analyze(
THD* thd, /*!< in: connection thread handle */
HA_CHECK_OPT* check_opt) /*!< in: currently ignored */
{
+ /* Serialize ANALYZE TABLE inside InnoDB, see
+ Bug#38996 Race condition in ANALYZE TABLE */
+ pthread_mutex_lock(&analyze_mutex);
+
/* Simply call ::info() with all the flags */
info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
+ pthread_mutex_unlock(&analyze_mutex);
+
return(0);
}
@@ -7797,8 +7897,9 @@ ha_innobase::external_lock(
{
ulong const binlog_format= thd_binlog_format(thd);
ulong const tx_isolation = thd_tx_isolation(ha_thd());
- if (tx_isolation <= ISO_READ_COMMITTED &&
- binlog_format == BINLOG_FORMAT_STMT)
+ if (tx_isolation <= ISO_READ_COMMITTED
+ && binlog_format == BINLOG_FORMAT_STMT
+ && thd_binlog_filter_ok(thd))
{
char buf[256];
my_snprintf(buf, sizeof(buf),
@@ -8446,6 +8547,7 @@ ha_innobase::store_lock(
&& isolation_level != TRX_ISO_SERIALIZABLE
&& (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
&& (sql_command == SQLCOM_INSERT_SELECT
+ || sql_command == SQLCOM_REPLACE_SELECT
|| sql_command == SQLCOM_UPDATE
|| sql_command == SQLCOM_CREATE_TABLE)) {
@@ -8453,10 +8555,11 @@ ha_innobase::store_lock(
option set or this session is using READ COMMITTED
isolation level and isolation level of the transaction
is not set to serializable and MySQL is doing
- INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
- CREATE ... SELECT... without FOR UPDATE or
- IN SHARE MODE in select, then we use consistent
- read for select. */
+ INSERT INTO...SELECT or REPLACE INTO...SELECT
+ or UPDATE ... = (SELECT ...) or CREATE ...
+ SELECT... without FOR UPDATE or IN SHARE
+ MODE in select, then we use consistent read
+ for select. */
prebuilt->select_lock_type = LOCK_NONE;
prebuilt->stored_select_lock_type = LOCK_NONE;
@@ -8676,6 +8779,7 @@ ha_innobase::get_auto_increment(
AUTOINC counter after attempting to insert the row. */
if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
ulonglong need;
+ ulonglong current;
ulonglong next_value;
ulonglong col_max_value;
@@ -8684,11 +8788,12 @@ ha_innobase::get_auto_increment(
col_max_value = innobase_get_int_col_max_value(
table->next_number_field);
+ current = *first_value > col_max_value ? autoinc : *first_value;
need = *nb_reserved_values * increment;
/* Compute the last value in the interval */
next_value = innobase_next_autoinc(
- *first_value, need, offset, col_max_value);
+ current, need, offset, col_max_value);
prebuilt->autoinc_last_value = next_value;
@@ -9612,6 +9717,25 @@ innodb_adaptive_hash_index_update(
}
}
+/****************************************************************//**
+Update the system variable innodb_old_blocks_pct using the "saved"
+value. This function is registered as a callback with MySQL. */
+static
+void
+innodb_old_blocks_pct_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 */
+{
+ innobase_old_blocks_pct = buf_LRU_old_ratio_update(
+ *static_cast<const uint*>(save), TRUE);
+}
+
/*************************************************************//**
Check if it is a valid value of innodb_change_buffering. This function is
registered as a callback with MySQL.
@@ -9685,6 +9809,49 @@ static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff)
return 0;
}
+/***********************************************************************
+This function checks each index name for a table against reserved
+system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
+this function pushes an warning message to the client, and returns true. */
+extern "C" UNIV_INTERN
+bool
+innobase_index_name_is_reserved(
+/*============================*/
+ /* out: true if an index name
+ matches the reserved name */
+ const trx_t* trx, /* in: InnoDB transaction handle */
+ const KEY* key_info, /* in: Indexes to be created */
+ ulint num_of_keys) /* in: Number of indexes to
+ be created. */
+{
+ const KEY* key;
+ uint key_num; /* index number */
+
+ for (key_num = 0; key_num < num_of_keys; key_num++) {
+ key = &key_info[key_num];
+
+ if (innobase_strcasecmp(key->name,
+ innobase_index_reserve_name) == 0) {
+ /* Push warning to mysql */
+ push_warning_printf((THD*) trx->mysql_thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_NAME_FOR_INDEX,
+ "Cannot Create Index with name "
+ "'%s'. The name is reserved "
+ "for the system default primary "
+ "index.",
+ innobase_index_reserve_name);
+
+ my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
+ innobase_index_reserve_name);
+
+ return(true);
+ }
+ }
+
+ return(false);
+}
+
static SHOW_VAR innodb_status_variables_export[]= {
{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
{NullS, NullS, SHOW_LONG}
@@ -9753,7 +9920,7 @@ static MYSQL_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
" or 2 (write at commit, flush once per second).",
NULL, NULL, 1, 0, 2, 0);
-static MYSQL_SYSVAR_STR(flush_method, innobase_unix_file_flush_method,
+static MYSQL_SYSVAR_STR(flush_method, innobase_file_flush_method,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"With which method to flush data.", NULL, NULL, NULL);
@@ -9849,7 +10016,7 @@ static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
NULL, NULL, 500L, 1L, ~0L, 0);
static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR,
"Number of file I/O threads in InnoDB.",
NULL, NULL, 4, 4, 64, 0);
@@ -9888,6 +10055,18 @@ static MYSQL_SYSVAR_LONG(mirrored_log_groups, innobase_mirrored_log_groups,
"Number of identical copies of log groups we keep for the database. Currently this should be set to 1.",
NULL, NULL, 1, 1, 10, 0);
+static MYSQL_SYSVAR_UINT(old_blocks_pct, innobase_old_blocks_pct,
+ PLUGIN_VAR_RQCMDARG,
+ "Percentage of the buffer pool to reserve for 'old' blocks.",
+ NULL, innodb_old_blocks_pct_update, 100 * 3 / 8, 5, 95, 0);
+
+static MYSQL_SYSVAR_UINT(old_blocks_time, buf_LRU_old_threshold_ms,
+ PLUGIN_VAR_RQCMDARG,
+ "Move blocks to the 'new' end of the buffer pool if the first access"
+ " was at least this many milliseconds ago."
+ " The timeout is disabled if 0 (the default).",
+ NULL, NULL, 0, 0, UINT_MAX32, 0);
+
static MYSQL_SYSVAR_LONG(open_files, innobase_open_files,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"How many files at the maximum InnoDB keeps open at the same time.",
@@ -9986,6 +10165,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(adaptive_flushing),
MYSQL_SYSVAR(max_purge_lag),
MYSQL_SYSVAR(mirrored_log_groups),
+ MYSQL_SYSVAR(old_blocks_pct),
+ MYSQL_SYSVAR(old_blocks_time),
MYSQL_SYSVAR(open_files),
MYSQL_SYSVAR(rollback_on_timeout),
MYSQL_SYSVAR(stats_on_metadata),
diff --git a/storage/innodb_plugin/handler/ha_innodb.h b/storage/innodb_plugin/handler/ha_innodb.h
index cc98003f8ff..4779651ee27 100644
--- a/storage/innodb_plugin/handler/ha_innodb.h
+++ b/storage/innodb_plugin/handler/ha_innodb.h
@@ -257,6 +257,13 @@ int thd_binlog_format(const MYSQL_THD thd);
@param all TRUE <=> rollback main transaction.
*/
void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
+
+/**
+ Check if binary logging is filtered for thread's current db.
+ @param thd Thread handle
+ @retval 1 the query is not filtered, 0 otherwise.
+*/
+bool thd_binlog_filter_ok(const MYSQL_THD thd);
}
typedef struct trx_struct trx_t;
@@ -282,3 +289,21 @@ trx_t*
innobase_trx_allocate(
/*==================*/
MYSQL_THD thd); /*!< in: user thread handle */
+
+
+/*********************************************************************//**
+This function checks each index name for a table against reserved
+system default primary index name 'GEN_CLUST_INDEX'. If a name
+matches, this function pushes an warning message to the client,
+and returns true. */
+extern "C"
+bool
+innobase_index_name_is_reserved(
+/*============================*/
+ /* out: true if the index name
+ matches the reserved name */
+ const trx_t* trx, /* in: InnoDB transaction handle */
+ const KEY* key_info, /* in: Indexes to be created */
+ ulint num_of_keys); /* in: Number of indexes to
+ be created. */
+
diff --git a/storage/innodb_plugin/handler/handler0alter.cc b/storage/innodb_plugin/handler/handler0alter.cc
index d1f64a1985c..37aed06b28a 100644
--- a/storage/innodb_plugin/handler/handler0alter.cc
+++ b/storage/innodb_plugin/handler/handler0alter.cc
@@ -628,7 +628,7 @@ ha_innobase::add_index(
ulint num_created = 0;
ibool dict_locked = FALSE;
ulint new_primary;
- ulint error;
+ int error;
DBUG_ENTER("ha_innobase::add_index");
ut_a(table);
@@ -656,14 +656,18 @@ ha_innobase::add_index(
innodb_table = indexed_table
= dict_table_get(prebuilt->table->name, FALSE);
- /* Check that index keys are sensible */
-
- error = innobase_check_index_keys(key_info, num_of_keys);
+ /* Check if the index name is reserved. */
+ if (innobase_index_name_is_reserved(trx, key_info, num_of_keys)) {
+ error = -1;
+ } else {
+ /* Check that index keys are sensible */
+ error = innobase_check_index_keys(key_info, num_of_keys);
+ }
if (UNIV_UNLIKELY(error)) {
err_exit:
mem_heap_free(heap);
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx_free_for_mysql(trx);
trx_commit_for_mysql(prebuilt->trx);
DBUG_RETURN(error);
@@ -801,7 +805,7 @@ error_handling:
alter table t drop index b, add index (b);
The fix will have to parse the SQL and note that the index
- being added has the same name as the the one being dropped and
+ being added has the same name as the one being dropped and
ignore that in the dup index check.*/
//dict_table_check_for_dup_indexes(prebuilt->table);
#endif
@@ -863,6 +867,7 @@ error_handling:
indexed_table->n_mysql_handles_opened++;
error = row_merge_drop_table(trx, innodb_table);
+ innodb_table = indexed_table;
goto convert_error;
case DB_TOO_BIG_RECORD:
diff --git a/storage/innodb_plugin/handler/handler0vars.h b/storage/innodb_plugin/handler/handler0vars.h
deleted file mode 100644
index e0f8f75e34d..00000000000
--- a/storage/innodb_plugin/handler/handler0vars.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2008, 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
-
-*****************************************************************************/
-
-/*******************************************************************//**
-@file handler/handler0vars.h
-This file contains accessor functions for dynamic plugin on Windows.
-***********************************************************************/
-
-#if defined __WIN__ && defined MYSQL_DYNAMIC_PLUGIN
-/*******************************************************************//**
-This is a list of externals that can not be resolved by delay loading.
-They have to be resolved indirectly via their addresses in the .map file.
-All of them are external variables. */
-extern CHARSET_INFO* wdl_my_charset_bin;
-extern CHARSET_INFO* wdl_my_charset_latin1;
-extern CHARSET_INFO* wdl_my_charset_filename;
-extern CHARSET_INFO** wdl_system_charset_info;
-extern CHARSET_INFO** wdl_default_charset_info;
-extern CHARSET_INFO** wdl_all_charsets;
-extern system_variables* wdl_global_system_variables;
-extern char* wdl_mysql_real_data_home;
-extern char** wdl_mysql_data_home;
-extern char** wdl_tx_isolation_names;
-extern char** wdl_binlog_format_names;
-extern char* wdl_reg_ext;
-extern pthread_mutex_t* wdl_LOCK_thread_count;
-extern key_map* wdl_key_map_full;
-extern MY_TMPDIR* wdl_mysql_tmpdir_list;
-extern bool* wdl_mysqld_embedded;
-extern uint* wdl_lower_case_table_names;
-extern ulong* wdl_specialflag;
-extern int* wdl_my_umask;
-
-#define my_charset_bin (*wdl_my_charset_bin)
-#define my_charset_latin1 (*wdl_my_charset_latin1)
-#define my_charset_filename (*wdl_my_charset_filename)
-#define system_charset_info (*wdl_system_charset_info)
-#define default_charset_info (*wdl_default_charset_info)
-#define all_charsets (wdl_all_charsets)
-#define global_system_variables (*wdl_global_system_variables)
-#define mysql_real_data_home (wdl_mysql_real_data_home)
-#define mysql_data_home (*wdl_mysql_data_home)
-#define tx_isolation_names (wdl_tx_isolation_names)
-#define binlog_format_names (wdl_binlog_format_names)
-#define reg_ext (wdl_reg_ext)
-#define LOCK_thread_count (*wdl_LOCK_thread_count)
-#define key_map_full (*wdl_key_map_full)
-#define mysql_tmpdir_list (*wdl_mysql_tmpdir_list)
-#define mysqld_embedded (*wdl_mysqld_embedded)
-#define lower_case_table_names (*wdl_lower_case_table_names)
-#define specialflag (*wdl_specialflag)
-#define my_umask (*wdl_my_umask)
-
-#endif
diff --git a/storage/innodb_plugin/handler/win_delay_loader.cc b/storage/innodb_plugin/handler/win_delay_loader.cc
deleted file mode 100644
index 9b92f6a9cf2..00000000000
--- a/storage/innodb_plugin/handler/win_delay_loader.cc
+++ /dev/null
@@ -1,1024 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2008, 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
-
-*****************************************************************************/
-
-/*******************************************************************//**
-@file handler/win_delay_loader.cc
-This file contains functions that implement the delay loader on Windows.
-
-This is a customized version of delay loader with limited functionalities.
-It does not support:
-
-* (manual) unloading
-* multiple delay loaded DLLs
-* multiple loading of the same DLL
-
-This delay loader is used only by the InnoDB plugin. Other components (DLLs)
-can still use the default delay loader, provided by MSVC.
-
-Several acronyms used by Microsoft:
- * IAT: import address table
- * INT: import name table
- * RVA: Relative Virtual Address
-
-See http://msdn.microsoft.com/en-us/magazine/bb985992.aspx for details of
-PE format.
-***********************************************************************/
-#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-# include <delayimp.h>
-# include <mysql_priv.h>
-
-extern "C" {
-# include "univ.i"
-# include "hash0hash.h"
-}
-
-/*******************************************************************//**
-This following contains a list of externals that can not be resolved by
-delay loading. They have to be resolved indirectly via their addresses
-in the .map file. All of them are external variables. */
-CHARSET_INFO* wdl_my_charset_bin;
-CHARSET_INFO* wdl_my_charset_latin1;
-CHARSET_INFO* wdl_my_charset_filename;
-CHARSET_INFO** wdl_system_charset_info;
-CHARSET_INFO** wdl_default_charset_info;
-CHARSET_INFO** wdl_all_charsets;
-system_variables* wdl_global_system_variables;
-char* wdl_mysql_real_data_home;
-char** wdl_mysql_data_home;
-char** wdl_tx_isolation_names;
-char** wdl_binlog_format_names;
-char* wdl_reg_ext;
-pthread_mutex_t* wdl_LOCK_thread_count;
-key_map* wdl_key_map_full;
-MY_TMPDIR* wdl_mysql_tmpdir_list;
-bool* wdl_mysqld_embedded;
-uint* wdl_lower_case_table_names;
-ulong* wdl_specialflag;
-int* wdl_my_umask;
-
-/*******************************************************************//**
-The preferred load-address defined in PE (portable executable format). */
-#if defined(_M_IA64)
-#pragma section(".base", long, read)
-extern "C"
-__declspec(allocate(".base"))
-const IMAGE_DOS_HEADER __ImageBase;
-#else
-extern "C"
-const IMAGE_DOS_HEADER __ImageBase;
-#endif
-
-/*******************************************************************//**
-A template function for converting a relative address (RVA) to an
-absolute address (VA). This is due to the pointers in the delay
-descriptor (ImgDelayDescr in delayimp.h) have been changed from
-VAs to RVAs to work on both 32- and 64-bit platforms.
-@return absolute virtual address */
-template <class X>
-X PFromRva(
-/*=======*/
- RVA rva) /*!< in: relative virtual address */
-{
- return X(PBYTE(&__ImageBase) + rva);
-}
-
-/*******************************************************************//**
-Convert to the old format for convenience. The structure as well as its
-element names follow the definition of ImgDelayDescr in delayimp.h. */
-struct InternalImgDelayDescr
-{
- DWORD grAttrs; /*!< attributes */
- LPCSTR szName; /*!< pointer to dll name */
- HMODULE* phmod; /*!< address of module handle */
- PImgThunkData pIAT; /*!< address of the IAT */
- PCImgThunkData pINT; /*!< address of the INT */
- PCImgThunkData pBoundIAT; /*!< address of the optional bound IAT */
- PCImgThunkData pUnloadIAT; /*!< address of optional copy of
- original IAT */
- DWORD dwTimeStamp; /*!< 0 if not bound,
- otherwise date/time stamp of DLL
- bound to (Old BIND) */
-};
-
-typedef struct map_hash_chain_struct map_hash_chain_t;
-
-struct map_hash_chain_struct {
- char* symbol; /*!< pointer to a symbol */
- ulint value; /*!< address of the symbol */
- map_hash_chain_t* next; /*!< pointer to the next cell
- in the same folder. */
- map_hash_chain_t* chain; /*!< a linear chain used for
- cleanup. */
-};
-
-static HMODULE my_hmod = 0;
-static struct hash_table_struct* m_htbl = NULL ;
-static map_hash_chain_t* chain_header = NULL;
-static ibool wdl_init = FALSE;
-const ulint MAP_HASH_CELLS_NUM = 10000;
-
-#ifndef DBUG_OFF
-/*******************************************************************//**
-In the dynamic plugin, it is required to call the following dbug functions
-in the server:
- _db_pargs_
- _db_doprnt_
- _db_enter_
- _db_return_
- _db_dump_
-
-The plugin will get those function pointers during the initialization. */
-typedef void (__cdecl* pfn_db_enter_)(
- const char* _func_,
- const char* _file_,
- uint _line_,
- const char** _sfunc_,
- const char** _sfile_,
- uint* _slevel_,
- char***);
-
-typedef void (__cdecl* pfn_db_return_)(
- uint _line_,
- const char** _sfunc_,
- const char** _sfile_,
- uint* _slevel_);
-
-typedef void (__cdecl* pfn_db_pargs_)(
- uint _line_,
- const char* keyword);
-
-typedef void (__cdecl* pfn_db_doprnt_)(
- const char* format,
- ...);
-
-typedef void (__cdecl* pfn_db_dump_)(
- uint _line_,
- const char* keyword,
- const unsigned char* memory,
- size_t length);
-
-static pfn_db_enter_ wdl_db_enter_;
-static pfn_db_return_ wdl_db_return_;
-static pfn_db_pargs_ wdl_db_pargs_;
-static pfn_db_doprnt_ wdl_db_doprnt_;
-static pfn_db_dump_ wdl_db_dump_;
-#endif /* !DBUG_OFF */
-
-/*************************************************************//**
-Creates a hash table with >= n array cells. The actual number of cells is
-chosen to be a prime number slightly bigger than n.
-
-This is the same function as hash_create in hash0hash.c, except the
-memory allocation. This function is invoked before the engine is
-initialized, and buffer pools are not ready yet.
-@return own: created hash table */
-static
-hash_table_t*
-wdl_hash_create(
-/*============*/
- ulint n) /*!< in: number of array cells */
-{
- hash_cell_t* array;
- ulint prime;
- hash_table_t* table;
-
- prime = ut_find_prime(n);
-
- table = (hash_table_t*) malloc(sizeof(hash_table_t));
- if (table == NULL) {
- return(NULL);
- }
-
- array = (hash_cell_t*) malloc(sizeof(hash_cell_t) * prime);
- if (array == NULL) {
- free(table);
- return(NULL);
- }
-
- table->array = array;
- table->n_cells = prime;
- table->n_mutexes = 0;
- table->mutexes = NULL;
- table->heaps = NULL;
- table->heap = NULL;
- table->magic_n = HASH_TABLE_MAGIC_N;
-
- /* Initialize the cell array */
- hash_table_clear(table);
-
- return(table);
-}
-
-/*************************************************************//**
-Frees a hash table. */
-static
-void
-wdl_hash_table_free(
-/*================*/
- hash_table_t* table) /*!< in, own: hash table */
-{
- ut_a(table != NULL);
- ut_a(table->mutexes == NULL);
-
- free(table->array);
- free(table);
-}
-
-/*******************************************************************//**
-Function for calculating the count of imports given the base of the IAT.
-@return number of imports */
-static
-ulint
-wdl_import_count(
-/*=============*/
- PCImgThunkData pitd_base) /*!< in: base of the IAT */
-{
- ulint ret = 0;
- PCImgThunkData pitd = pitd_base;
-
- while (pitd->u1.Function) {
- pitd++;
- ret++;
- }
-
- return(ret);
-}
-
-/*******************************************************************//**
-Read Mapfile to a hashtable for faster access
-@return TRUE if the mapfile is loaded successfully. */
-static
-ibool
-wdl_load_mapfile(
-/*=============*/
- const char* filename) /*!< in: name of the mapfile. */
-{
- FILE* fp;
- const size_t nSize = 256;
- char tmp_buf[nSize];
- char* func_name;
- char* func_addr;
- ulint load_addr = 0;
- ibool valid_load_addr = FALSE;
-#ifdef _WIN64
- const char* tmp_string = " Preferred load address is %16llx";
-#else
- const char* tmp_string = " Preferred load address is %08x";
-#endif
-
- fp = fopen(filename, "r");
- if (fp == NULL) {
-
- return(FALSE);
- }
-
- /* Check whether to create the hashtable */
- if (m_htbl == NULL) {
-
- m_htbl = wdl_hash_create(MAP_HASH_CELLS_NUM);
-
- if (m_htbl == NULL) {
-
- fclose(fp);
- return(FALSE);
- }
- }
-
- /* Search start of symbol list and get the preferred load address */
- while (fgets(tmp_buf, sizeof(tmp_buf), fp)) {
-
- if (sscanf(tmp_buf, tmp_string, &load_addr) == 1) {
-
- valid_load_addr = TRUE;
- }
-
- if (strstr(tmp_buf, "Rva+Base") != NULL) {
-
- break;
- }
- }
-
- if (valid_load_addr == FALSE) {
-
- /* No "Preferred load address", the map file is wrong. */
- fclose(fp);
- return(FALSE);
- }
-
- /* Read symbol list */
- while (fgets(tmp_buf, sizeof(tmp_buf), fp))
- {
- map_hash_chain_t* map_cell;
- ulint map_fold;
-
- if (*tmp_buf == 0) {
-
- continue;
- }
-
- func_name = strtok(tmp_buf, " ");
- func_name = strtok(NULL, " ");
- func_addr = strtok(NULL, " ");
-
- if (func_name && func_addr) {
-
- ut_snprintf(tmp_buf, nSize, "0x%s", func_addr);
- if (*func_name == '_') {
-
- func_name++;
- }
-
- map_cell = (map_hash_chain_t*)
- malloc(sizeof(map_hash_chain_t));
- if (map_cell == NULL) {
- return(FALSE);
- }
-
- /* Chain all cells together */
- map_cell->chain = chain_header;
- chain_header = map_cell;
-
- map_cell->symbol = strdup(func_name);
- map_cell->value = (ulint) _strtoui64(tmp_buf, NULL, 0)
- - load_addr;
- map_fold = ut_fold_string(map_cell->symbol);
-
- HASH_INSERT(map_hash_chain_t,
- next,
- m_htbl,
- map_fold,
- map_cell);
- }
- }
-
- fclose(fp);
-
- return(TRUE);
-}
-
-/*************************************************************//**
-Cleanup.during DLL unload */
-static
-void
-wdl_cleanup(void)
-/*=============*/
-{
- while (chain_header != NULL) {
- map_hash_chain_t* tmp;
-
- tmp = chain_header->chain;
- free(chain_header->symbol);
- free(chain_header);
- chain_header = tmp;
- }
-
- if (m_htbl != NULL) {
-
- wdl_hash_table_free(m_htbl);
- }
-}
-
-/*******************************************************************//**
-Load the mapfile mysqld.map.
-@return the module handle */
-static
-HMODULE
-wdl_get_mysqld_mapfile(void)
-/*========================*/
-{
- char file_name[MAX_PATH];
- char* ext;
- ulint err;
-
- if (my_hmod == 0) {
-
- size_t nSize = MAX_PATH - strlen(".map") -1;
-
- /* First find out the name of current executable */
- my_hmod = GetModuleHandle(NULL);
- if (my_hmod == 0) {
-
- return(my_hmod);
- }
-
- err = GetModuleFileName(my_hmod, file_name, nSize);
- if (err == 0) {
-
- my_hmod = 0;
- return(my_hmod);
- }
-
- ext = strrchr(file_name, '.');
- if (ext != NULL) {
-
- *ext = 0;
- strcat(file_name, ".map");
-
- err = wdl_load_mapfile(file_name);
- if (err == 0) {
-
- my_hmod = 0;
- }
- } else {
-
- my_hmod = 0;
- }
- }
-
- return(my_hmod);
-}
-
-/*******************************************************************//**
-Retrieves the address of an exported function. It follows the convention
-of GetProcAddress().
-@return address of exported function. */
-static
-FARPROC
-wdl_get_procaddr_from_map(
-/*======================*/
- HANDLE m_handle, /*!< in: module handle */
- const char* import_proc) /*!< in: procedure name */
-{
- map_hash_chain_t* hash_chain;
- ulint map_fold;
-
- map_fold = ut_fold_string(import_proc);
- HASH_SEARCH(
- next,
- m_htbl,
- map_fold,
- map_hash_chain_t*,
- hash_chain,
- ,
- (ut_strcmp(hash_chain->symbol, import_proc) == 0));
-
- if (hash_chain == NULL) {
-
-#ifdef _WIN64
- /* On Win64, the leading '_' may not be taken out. In this
- case, search again without the leading '_'. */
- if (*import_proc == '_') {
-
- import_proc++;
- }
-
- map_fold = ut_fold_string(import_proc);
- HASH_SEARCH(
- next,
- m_htbl,
- map_fold,
- map_hash_chain_t*,
- hash_chain,
- ,
- (ut_strcmp(hash_chain->symbol, import_proc) == 0));
-
- if (hash_chain == NULL) {
-#endif
- if (wdl_init == TRUE) {
-
- sql_print_error(
- "InnoDB: the procedure pointer of %s"
- " is not found.",
- import_proc);
- }
-
- return(0);
-#ifdef _WIN64
- }
-#endif
- }
-
- return((FARPROC) ((ulint) m_handle + hash_chain->value));
-}
-
-/*******************************************************************//**
-Retrieves the address of an exported variable.
-Note: It does not follow the Windows call convention FARPROC.
-@return address of exported variable. */
-static
-void*
-wdl_get_varaddr_from_map(
-/*=====================*/
- HANDLE m_handle, /*!< in: module handle */
- const char* import_variable) /*!< in: variable name */
-{
- map_hash_chain_t* hash_chain;
- ulint map_fold;
-
- map_fold = ut_fold_string(import_variable);
- HASH_SEARCH(
- next,
- m_htbl,
- map_fold,
- map_hash_chain_t*,
- hash_chain,
- ,
- (ut_strcmp(hash_chain->symbol, import_variable) == 0));
-
- if (hash_chain == NULL) {
-
-#ifdef _WIN64
- /* On Win64, the leading '_' may not be taken out. In this
- case, search again without the leading '_'. */
- if (*import_variable == '_') {
-
- import_variable++;
- }
-
- map_fold = ut_fold_string(import_variable);
- HASH_SEARCH(
- next,
- m_htbl,
- map_fold,
- map_hash_chain_t*,
- hash_chain,
- ,
- (ut_strcmp(hash_chain->symbol, import_variable) == 0));
-
- if (hash_chain == NULL) {
-#endif
- if (wdl_init == TRUE) {
-
- sql_print_error(
- "InnoDB: the variable address of %s"
- " is not found.",
- import_variable);
- }
-
- return(0);
-#ifdef _WIN64
- }
-#endif
- }
-
- return((void*) ((ulint) m_handle + hash_chain->value));
-}
-
-/*******************************************************************//**
-Bind all unresolved external variables from the MySQL executable.
-@return TRUE if successful */
-static
-bool
-wdl_get_external_variables(void)
-/*============================*/
-{
- HMODULE hmod = wdl_get_mysqld_mapfile();
-
- if (hmod == 0) {
-
- return(FALSE);
- }
-
-#define GET_SYM(sym, var, type) \
- var = (type*) wdl_get_varaddr_from_map(hmod, sym); \
- if (var == NULL) return(FALSE)
-#ifdef _WIN64
-#define GET_SYM2(sym1, sym2, var, type) \
- var = (type*) wdl_get_varaddr_from_map(hmod, sym1); \
- if (var == NULL) return(FALSE)
-#else
-#define GET_SYM2(sym1, sym2, var, type) \
- var = (type*) wdl_get_varaddr_from_map(hmod, sym2); \
- if (var == NULL) return(FALSE)
-#endif // (_WIN64)
-#define GET_C_SYM(sym, type) GET_SYM(#sym, wdl_##sym, type)
-#define GET_PROC_ADDR(sym) \
- wdl##sym = (pfn##sym) wdl_get_procaddr_from_map(hmod, #sym)
-
- GET_C_SYM(my_charset_bin, CHARSET_INFO);
- GET_C_SYM(my_charset_latin1, CHARSET_INFO);
- GET_C_SYM(my_charset_filename, CHARSET_INFO);
- GET_C_SYM(default_charset_info, CHARSET_INFO*);
- GET_C_SYM(all_charsets, CHARSET_INFO*);
- GET_C_SYM(my_umask, int);
-
- GET_SYM("?global_system_variables@@3Usystem_variables@@A",
- wdl_global_system_variables, struct system_variables);
- GET_SYM("?mysql_real_data_home@@3PADA",
- wdl_mysql_real_data_home, char);
- GET_SYM("?reg_ext@@3PADA", wdl_reg_ext, char);
- GET_SYM("?LOCK_thread_count@@3U_RTL_CRITICAL_SECTION@@A",
- wdl_LOCK_thread_count, pthread_mutex_t);
- GET_SYM("?key_map_full@@3V?$Bitmap@$0EA@@@A",
- wdl_key_map_full, key_map);
- GET_SYM("?mysql_tmpdir_list@@3Ust_my_tmpdir@@A",
- wdl_mysql_tmpdir_list, MY_TMPDIR);
- GET_SYM("?mysqld_embedded@@3_NA",
- wdl_mysqld_embedded, bool);
- GET_SYM("?lower_case_table_names@@3IA",
- wdl_lower_case_table_names, uint);
- GET_SYM("?specialflag@@3KA", wdl_specialflag, ulong);
-
- GET_SYM2("?system_charset_info@@3PEAUcharset_info_st@@EA",
- "?system_charset_info@@3PAUcharset_info_st@@A",
- wdl_system_charset_info, CHARSET_INFO*);
- GET_SYM2("?mysql_data_home@@3PEADEA",
- "?mysql_data_home@@3PADA",
- wdl_mysql_data_home, char*);
- GET_SYM2("?tx_isolation_names@@3PAPEBDA",
- "?tx_isolation_names@@3PAPBDA",
- wdl_tx_isolation_names, char*);
- GET_SYM2("?binlog_format_names@@3PAPEBDA",
- "?binlog_format_names@@3PAPBDA",
- wdl_binlog_format_names, char*);
-
-#ifndef DBUG_OFF
- GET_PROC_ADDR(_db_enter_);
- GET_PROC_ADDR(_db_return_);
- GET_PROC_ADDR(_db_pargs_);
- GET_PROC_ADDR(_db_doprnt_);
- GET_PROC_ADDR(_db_dump_);
-
- /* If any of the dbug functions is not available, just make them
- all invalid. This is the case when working with a non-debug
- version of the server. */
- if (wdl_db_enter_ == NULL || wdl_db_return_ == NULL
- || wdl_db_pargs_ == NULL || wdl_db_doprnt_ == NULL
- || wdl_db_dump_ == NULL) {
-
- wdl_db_enter_ = NULL;
- wdl_db_return_ = NULL;
- wdl_db_pargs_ = NULL;
- wdl_db_doprnt_ = NULL;
- wdl_db_dump_ = NULL;
- }
-#endif /* !DBUG_OFF */
-
- wdl_init = TRUE;
- return(TRUE);
-
-#undef GET_SYM
-#undef GET_SYM2
-#undef GET_C_SYM
-#undef GET_PROC_ADDR
-}
-
-/*******************************************************************//**
-The DLL Delayed Loading Helper Function for resolving externals.
-
-The function may fail due to one of the three reasons:
-
-* Invalid parameter, which happens if the attributes in pidd aren't
- specified correctly.
-* Failed to load the map file mysqld.map.
-* Failed to find an external name in the map file mysqld.map.
-
-Note: this function is called by run-time as well as __HrLoadAllImportsForDll.
-So, it has to follow Windows call convention.
-@return the address of the imported function */
-extern "C"
-FARPROC WINAPI
-__delayLoadHelper2(
-/*===============*/
- PCImgDelayDescr pidd, /*!< in: a const pointer to a
- ImgDelayDescr, see delayimp.h. */
- FARPROC* iat_entry) /*!< in/out: A pointer to the slot in
- the delay load import address table
- to be updated with the address of the
- imported function. */
-{
- ulint iIAT, iINT;
- HMODULE hmod;
- PCImgThunkData pitd;
- FARPROC fun = NULL;
-
- /* Set up data used for the hook procs */
- InternalImgDelayDescr idd = {
- pidd->grAttrs,
- PFromRva<LPCSTR>(pidd->rvaDLLName),
- PFromRva<HMODULE*>(pidd->rvaHmod),
- PFromRva<PImgThunkData>(pidd->rvaIAT),
- PFromRva<PCImgThunkData>(pidd->rvaINT),
- PFromRva<PCImgThunkData>(pidd->rvaBoundIAT),
- PFromRva<PCImgThunkData>(pidd->rvaUnloadIAT),
- pidd->dwTimeStamp
- };
-
- DelayLoadInfo dli = {
- sizeof(DelayLoadInfo),
- pidd,
- iat_entry,
- idd.szName,
- {0},
- 0,
- 0,
- 0
- };
-
- /* Check the Delay Load Attributes, log an error of invalid
- parameter, which happens if the attributes in pidd are not
- specified correctly. */
- if ((idd.grAttrs & dlattrRva) == 0) {
-
- sql_print_error("InnoDB: invalid parameter for delay loader.");
- return(0);
- }
-
- hmod = *idd.phmod;
-
- /* Calculate the index for the IAT entry in the import address table.
- The INT entries are ordered the same as the IAT entries so the
- calculation can be done on the IAT side. */
- iIAT = (PCImgThunkData) iat_entry - idd.pIAT;
- iINT = iIAT;
-
- pitd = &(idd.pINT[iINT]);
-
- dli.dlp.fImportByName = !IMAGE_SNAP_BY_ORDINAL(pitd->u1.Ordinal);
-
- if (dli.dlp.fImportByName) {
-
- dli.dlp.szProcName = (LPCSTR) (PFromRva<PIMAGE_IMPORT_BY_NAME>
- ((RVA) ((UINT_PTR) pitd->u1.AddressOfData))->Name);
- } else {
-
- dli.dlp.dwOrdinal = (ulint) IMAGE_ORDINAL(pitd->u1.Ordinal);
- }
-
- /* Now, load the mapfile, if it has not been done yet */
- if (hmod == 0) {
-
- hmod = wdl_get_mysqld_mapfile();
- }
-
- if (hmod == 0) {
- /* LoadLibrary failed. */
- PDelayLoadInfo rgpdli[1] = {&dli};
-
- dli.dwLastError = ::GetLastError();
-
- sql_print_error(
- "InnoDB: failed to load mysqld.map with error %d.",
- dli.dwLastError);
-
- return(0);
- }
-
- /* Store the library handle. */
- idd.phmod = &hmod;
-
- /* Go for the procedure now. */
- dli.hmodCur = hmod;
-
- if (pidd->rvaBoundIAT && pidd->dwTimeStamp) {
-
- /* Bound imports exist, check the timestamp from the target
- image */
- PIMAGE_NT_HEADERS pinh;
-
- pinh = (PIMAGE_NT_HEADERS) ((byte*) hmod
- + ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
-
- if (pinh->Signature == IMAGE_NT_SIGNATURE
- && pinh->FileHeader.TimeDateStamp == idd.dwTimeStamp
- && (DWORD) hmod == pinh->OptionalHeader.ImageBase) {
-
- /* We have a decent address in the bound IAT. */
- fun = (FARPROC) (UINT_PTR)
- idd.pBoundIAT[iIAT].u1.Function;
-
- if (fun) {
-
- *iat_entry = fun;
- return(fun);
- }
- }
- }
-
- fun = wdl_get_procaddr_from_map(hmod, dli.dlp.szProcName);
-
- if (fun == 0) {
-
- return(0);
- }
-
- *iat_entry = fun;
- return(fun);
-}
-
-/*******************************************************************//**
-Unload a DLL that was delay loaded. This function is called by run-time.
-@return TRUE is returned if the DLL is found and the IAT matches the
-original one. */
-extern "C"
-BOOL WINAPI
-__FUnloadDelayLoadedDLL2(
-/*=====================*/
- LPCSTR module_name) /*!< in: DLL name */
-{
- return(TRUE);
-}
-
-/**************************************************************//**
-Load all imports from a DLL that was specified with the /delayload linker
-option.
-Note: this function is called by run-time. So, it has to follow Windows call
-convention.
-@return S_OK if the DLL matches, otherwise ERROR_MOD_NOT_FOUND is returned. */
-extern "C"
-HRESULT WINAPI
-__HrLoadAllImportsForDll(
-/*=====================*/
- LPCSTR module_name) /*!< in: DLL name */
-{
- PIMAGE_NT_HEADERS img;
- PCImgDelayDescr pidd;
- IMAGE_DATA_DIRECTORY* image_data;
- LPCSTR current_module;
- HRESULT ret = ERROR_MOD_NOT_FOUND;
- HMODULE hmod = (HMODULE) &__ImageBase;
-
- img = (PIMAGE_NT_HEADERS) ((byte*) hmod
- + ((PIMAGE_DOS_HEADER) hmod)->e_lfanew);
- image_data =
- &img->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
-
- /* Scan the delay load IAT/INT for the DLL */
- if (image_data->Size) {
-
- pidd = PFromRva<PCImgDelayDescr>(image_data->VirtualAddress);
-
- /* Check all of the listed DLLs we want to load. */
- while (pidd->rvaDLLName) {
-
- current_module = PFromRva<LPCSTR>(pidd->rvaDLLName);
-
- if (stricmp(module_name, current_module) == 0) {
-
- /* Found it, break out with pidd and
- current_module set appropriately */
- break;
- }
-
- /* To the next delay import descriptor */
- pidd++;
- }
-
- if (pidd->rvaDLLName) {
-
- /* Found a matching DLL, now process it. */
- FARPROC* iat_entry;
- size_t count;
-
- iat_entry = PFromRva<FARPROC*>(pidd->rvaIAT);
- count = wdl_import_count((PCImgThunkData) iat_entry);
-
- /* now load all the imports from the DLL */
- while (count > 0) {
-
- /* No need to check the return value */
- __delayLoadHelper2(pidd, iat_entry);
- iat_entry++;
- count--;
- }
-
- ret = S_OK;
- }
- }
-
- return ret;
-}
-
-/**************************************************************//**
-The main function of a DLL
-@return TRUE if the call succeeds */
-BOOL
-WINAPI
-DllMain(
-/*====*/
- HINSTANCE hinstDLL, /*!< in: handle to the DLL module */
- DWORD fdwReason, /*!< Reason code that indicates why the
- DLL entry-point function is being
- called.*/
- LPVOID lpvReserved) /*!< in: additional parameter based on
- fdwReason */
-{
- BOOL success = TRUE;
-
- switch (fdwReason) {
-
- case DLL_PROCESS_ATTACH:
- success = wdl_get_external_variables();
- break;
-
- case DLL_PROCESS_DETACH:
- wdl_cleanup();
- break;
- }
-
- return(success);
-}
-
-#ifndef DBUG_OFF
-/**************************************************************//**
-Process entry point to user function. It makes the call to _db_enter_
-in mysqld.exe. The DBUG functions are defined in my_dbug.h. */
-extern "C" UNIV_INTERN
-void
-_db_enter_(
- const char* _func_, /*!< in: current function name */
- const char* _file_, /*!< in: current file name */
- uint _line_, /*!< in: current source line number */
- const char** _sfunc_, /*!< out: previous _func_ */
- const char** _sfile_, /*!< out: previous _file_ */
- uint* _slevel_, /*!< out: previous nesting level */
- char*** _sframep_) /*!< out: previous frame pointer */
-{
- if (wdl_db_enter_ != NULL) {
-
- wdl_db_enter_(_func_, _file_, _line_, _sfunc_, _sfile_,
- _slevel_, _sframep_);
- }
-}
-
-/**************************************************************//**
-Process exit from user function. It makes the call to _db_return_()
-in the server. */
-extern "C" UNIV_INTERN
-void
-_db_return_(
- uint _line_, /*!< in: current source line number */
- const char** _sfunc_, /*!< out: previous _func_ */
- const char** _sfile_, /*!< out: previous _file_ */
- uint* _slevel_) /*!< out: previous level */
-{
- if (wdl_db_return_ != NULL) {
-
- wdl_db_return_(_line_, _sfunc_, _sfile_, _slevel_);
- }
-}
-
-/**************************************************************//**
-Log arguments for subsequent use. It makes the call to _db_pargs_()
-in the server. */
-extern "C" UNIV_INTERN
-void
-_db_pargs_(
- uint _line_, /*!< in: current source line number */
- const char* keyword) /*!< in: keyword for current macro */
-{
- if (wdl_db_pargs_ != NULL) {
-
- wdl_db_pargs_(_line_, keyword);
- }
-}
-
-/**************************************************************//**
-Handle print of debug lines. It saves the text into a buffer first,
-then makes the call to _db_doprnt_() in the server. The text is
-truncated to the size of buffer. */
-extern "C" UNIV_INTERN
-void
-_db_doprnt_(
- const char* format, /*!< in: the format string */
- ...) /*!< in: list of arguments */
-{
- va_list argp;
- char buffer[512];
-
- if (wdl_db_doprnt_ != NULL) {
-
- va_start(argp, format);
- /* it is ok to ignore the trunction. */
- _vsnprintf(buffer, sizeof(buffer), format, argp);
- wdl_db_doprnt_(buffer);
- va_end(argp);
- }
-}
-
-/**************************************************************//**
-Dump a string in hex. It makes the call to _db_dump_() in the server. */
-extern "C" UNIV_INTERN
-void
-_db_dump_(
- uint _line_, /*!< in: current source line
- number */
- const char* keyword, /*!< in: keyword list */
- const unsigned char* memory, /*!< in: memory to dump */
- size_t length) /*!< in: bytes to dump */
-{
- if (wdl_db_dump_ != NULL) {
-
- wdl_db_dump_(_line_, keyword, memory, length);
- }
-}
-
-#endif /* !DBUG_OFF */
-#endif /* defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) */
diff --git a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/include/buf0buf.h
index 65ad42c895a..927ff893e39 100644
--- a/storage/innodb_plugin/include/buf0buf.h
+++ b/storage/innodb_plugin/include/buf0buf.h
@@ -346,7 +346,7 @@ buf_page_release(
mtr_t* mtr); /*!< in: mtr */
/********************************************************************//**
Moves a page to the start of the buffer pool LRU list. This high-level
-function can be used to prevent an important page from from slipping out of
+function can be used to prevent an important page from slipping out of
the buffer pool. */
UNIV_INTERN
void
@@ -707,15 +707,6 @@ buf_page_belongs_to_unzip_LRU(
/*==========================*/
const buf_page_t* bpage) /*!< in: pointer to control block */
__attribute__((pure));
-/*********************************************************************//**
-Determine the approximate LRU list position of a block.
-@return LRU list position */
-UNIV_INLINE
-ulint
-buf_page_get_LRU_position(
-/*======================*/
- const buf_page_t* bpage) /*!< in: control block */
- __attribute__((pure));
/*********************************************************************//**
Gets the mutex of a block.
@@ -816,14 +807,14 @@ buf_page_set_old(
buf_page_t* bpage, /*!< in/out: control block */
ibool old); /*!< in: old */
/*********************************************************************//**
-Determine if a block has been accessed in the buffer pool.
-@return TRUE if accessed */
+Determine the time of first access of a block in the buffer pool.
+@return ut_time_ms() at the time of first access, 0 if not accessed */
UNIV_INLINE
-ibool
+unsigned
buf_page_is_accessed(
/*=================*/
const buf_page_t* bpage) /*!< in: control block */
- __attribute__((pure));
+ __attribute__((nonnull, pure));
/*********************************************************************//**
Flag a block accessed. */
UNIV_INLINE
@@ -831,7 +822,8 @@ void
buf_page_set_accessed(
/*==================*/
buf_page_t* bpage, /*!< in/out: control block */
- ibool accessed); /*!< in: accessed */
+ ulint time_ms) /*!< in: ut_time_ms() */
+ __attribute__((nonnull));
/*********************************************************************//**
Gets the buf_block_t handle of a buffered file block if an uncompressed
page frame exists, or NULL.
@@ -1017,14 +1009,6 @@ buf_block_hash_get(
/*===============*/
ulint space, /*!< in: space id */
ulint offset);/*!< in: offset of the page within space */
-/*******************************************************************//**
-Increments the pool clock by one and returns its new value. Remember that
-in the 32 bit version the clock wraps around at 4 billion!
-@return new clock value */
-UNIV_INLINE
-ulint
-buf_pool_clock_tic(void);
-/*====================*/
/*********************************************************************//**
Gets the current length of the free list of buffer blocks.
@return length of the free list */
@@ -1064,16 +1048,10 @@ struct buf_page_struct{
flushed to disk, this tells the
flush_type.
@see enum buf_flush */
- unsigned accessed:1; /*!< TRUE if the page has been accessed
- while in the buffer pool: read-ahead
- may read in pages which have not been
- accessed yet; a thread is allowed to
- read this for heuristic purposes
- without holding any mutex or latch */
unsigned io_fix:2; /*!< type of pending I/O operation;
also protected by buf_pool_mutex
@see enum buf_io_fix */
- unsigned buf_fix_count:24;/*!< count of how manyfold this block
+ unsigned buf_fix_count:25;/*!< count of how manyfold this block
is currently bufferfixed */
/* @} */
#endif /* !UNIV_HOTBACKUP */
@@ -1103,7 +1081,16 @@ struct buf_page_struct{
- BUF_BLOCK_FILE_PAGE: flush_list
- BUF_BLOCK_ZIP_DIRTY: flush_list
- BUF_BLOCK_ZIP_PAGE: zip_clean
- - BUF_BLOCK_ZIP_FREE: zip_free[] */
+ - BUF_BLOCK_ZIP_FREE: zip_free[]
+
+ The contents of the list node
+ is undefined if !in_flush_list
+ && state == BUF_BLOCK_FILE_PAGE,
+ or if state is one of
+ BUF_BLOCK_MEMORY,
+ BUF_BLOCK_REMOVE_HASH or
+ BUF_BLOCK_READY_IN_USE. */
+
#ifdef UNIV_DEBUG
ibool in_flush_list; /*!< TRUE if in buf_pool->flush_list;
when buf_pool_mutex is free, the
@@ -1142,18 +1129,8 @@ struct buf_page_struct{
debugging */
#endif /* UNIV_DEBUG */
unsigned old:1; /*!< TRUE if the block is in the old
- blocks in the LRU list */
- unsigned LRU_position:31;/*!< value which monotonically
- decreases (or may stay
- constant if old==TRUE) toward
- the end of the LRU list, if
- buf_pool->ulint_clock has not
- wrapped around: NOTE that this
- value can only be used in
- heuristic algorithms, because
- of the possibility of a
- wrap-around! */
- unsigned freed_page_clock:32;/*!< the value of
+ blocks in buf_pool->LRU_old */
+ unsigned freed_page_clock:31;/*!< the value of
buf_pool->freed_page_clock
when this block was the last
time put to the head of the
@@ -1161,6 +1138,9 @@ struct buf_page_struct{
to read this for heuristic
purposes without holding any
mutex or latch */
+ unsigned access_time:32; /*!< time of first access, or
+ 0 if the block was never accessed
+ in the buffer pool */
/* @} */
# ifdef UNIV_DEBUG_FILE_ACCESSES
ibool file_page_was_freed;
@@ -1305,6 +1285,31 @@ Compute the hash fold value for blocks in buf_pool->zip_hash. */
#define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
/* @} */
+/** @brief The buffer pool statistics structure. */
+struct buf_pool_stat_struct{
+ ulint n_page_gets; /*!< number of page gets performed;
+ also successful searches through
+ the adaptive hash index are
+ counted as page gets; this field
+ is NOT protected by the buffer
+ pool mutex */
+ ulint n_pages_read; /*!< number read operations */
+ ulint n_pages_written;/*!< number write operations */
+ ulint n_pages_created;/*!< number of pages created
+ in the pool with no read */
+ ulint n_ra_pages_read;/*!< number of pages read in
+ as part of read ahead */
+ ulint n_ra_pages_evicted;/*!< number of read ahead
+ pages that are evicted without
+ being accessed */
+ ulint n_pages_made_young; /*!< number of pages made young, in
+ calls to buf_LRU_make_block_young() */
+ ulint n_pages_not_made_young; /*!< number of pages not made
+ young because the first access
+ was not long enough ago, in
+ buf_page_peek_if_too_old() */
+};
+
/** @brief The buffer pool structure.
NOTE! The definition appears here only for other modules of this
@@ -1329,28 +1334,16 @@ struct buf_pool_struct{
ulint n_pend_reads; /*!< number of pending read operations */
ulint n_pend_unzip; /*!< number of pending decompressions */
- time_t last_printout_time; /*!< when buf_print was last time
+ time_t last_printout_time;
+ /*!< when buf_print_io was last time
called */
- ulint n_pages_read; /*!< number read operations */
- ulint n_pages_written;/*!< number write operations */
- ulint n_pages_created;/*!< number of pages created
- in the pool with no read */
- ulint n_page_gets; /*!< number of page gets performed;
- also successful searches through
- the adaptive hash index are
- counted as page gets; this field
- is NOT protected by the buffer
- pool mutex */
- ulint n_page_gets_old;/*!< n_page_gets when buf_print was
- last time called: used to calculate
- hit rate */
- ulint n_pages_read_old;/*!< n_pages_read when buf_print was
- last time called */
- ulint n_pages_written_old;/*!< number write operations */
- ulint n_pages_created_old;/*!< number of pages created in
- the pool with no read */
+ buf_pool_stat_t stat; /*!< current statistics */
+ buf_pool_stat_t old_stat; /*!< old statistics */
+
/* @} */
+
/** @name Page flushing algorithm fields */
+
/* @{ */
UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
@@ -1366,10 +1359,6 @@ struct buf_pool_struct{
/*!< this is in the set state
when there is no flush batch
of the given type running */
- ulint ulint_clock; /*!< a sequence number used to count
- time. NOTE! This counter wraps
- around at 4 billion (if ulint ==
- 32 bits)! */
ulint freed_page_clock;/*!< a sequence number used
to count the number of buffer
blocks removed from the end of
@@ -1393,17 +1382,18 @@ struct buf_pool_struct{
block list */
UT_LIST_BASE_NODE_T(buf_page_t) LRU;
/*!< base node of the LRU list */
- buf_page_t* LRU_old; /*!< pointer to the about 3/8 oldest
- blocks in the LRU list; NULL if LRU
- length less than BUF_LRU_OLD_MIN_LEN;
+ buf_page_t* LRU_old; /*!< pointer to the about
+ buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
+ oldest blocks in the LRU list;
+ NULL if LRU length less than
+ BUF_LRU_OLD_MIN_LEN;
NOTE: when LRU_old != NULL, its length
should always equal LRU_old_len */
ulint LRU_old_len; /*!< length of the LRU list from
the block to which LRU_old points
onward, including that block;
see buf0lru.c for the restrictions
- on this value; not defined if
- LRU_old == NULL;
+ on this value; 0 if LRU_old == NULL;
NOTE: LRU_old_len must be adjusted
whenever LRU_old shrinks or grows! */
diff --git a/storage/innodb_plugin/include/buf0buf.ic b/storage/innodb_plugin/include/buf0buf.ic
index 17064342116..0f92a59a1c7 100644
--- a/storage/innodb_plugin/include/buf0buf.ic
+++ b/storage/innodb_plugin/include/buf0buf.ic
@@ -72,9 +72,30 @@ buf_page_peek_if_too_old(
/*=====================*/
const buf_page_t* bpage) /*!< in: block to make younger */
{
- return(buf_pool->freed_page_clock
- >= buf_page_get_freed_page_clock(bpage)
- + 1 + (buf_pool->curr_size / 4));
+ if (UNIV_UNLIKELY(buf_pool->freed_page_clock == 0)) {
+ /* If eviction has not started yet, do not update the
+ statistics or move blocks in the LRU list. This is
+ either the warm-up phase or an in-memory workload. */
+ return(FALSE);
+ } else if (buf_LRU_old_threshold_ms && bpage->old) {
+ unsigned access_time = buf_page_is_accessed(bpage);
+
+ if (access_time > 0
+ && (ut_time_ms() - access_time)
+ >= buf_LRU_old_threshold_ms) {
+ return(TRUE);
+ }
+
+ buf_pool->stat.n_pages_not_made_young++;
+ return(FALSE);
+ } else {
+ /* FIXME: bpage->freed_page_clock is 31 bits */
+ return((buf_pool->freed_page_clock & ((1UL << 31) - 1))
+ > ((ulint) bpage->freed_page_clock
+ + (buf_pool->curr_size
+ * (BUF_LRU_OLD_RATIO_DIV - buf_LRU_old_ratio)
+ / (BUF_LRU_OLD_RATIO_DIV * 4))));
+ }
}
/*********************************************************************//**
@@ -118,22 +139,6 @@ buf_pool_get_oldest_modification(void)
return(lsn);
}
-
-/*******************************************************************//**
-Increments the buf_pool clock by one and returns its new value. Remember
-that in the 32 bit version the clock wraps around at 4 billion!
-@return new clock value */
-UNIV_INLINE
-ulint
-buf_pool_clock_tic(void)
-/*====================*/
-{
- ut_ad(buf_pool_mutex_own());
-
- buf_pool->ulint_clock++;
-
- return(buf_pool->ulint_clock);
-}
#endif /* !UNIV_HOTBACKUP */
/*********************************************************************//**
@@ -280,21 +285,6 @@ buf_page_belongs_to_unzip_LRU(
}
/*********************************************************************//**
-Determine the approximate LRU list position of a block.
-@return LRU list position */
-UNIV_INLINE
-ulint
-buf_page_get_LRU_position(
-/*======================*/
- const buf_page_t* bpage) /*!< in: control block */
-{
- ut_ad(buf_page_in_file(bpage));
- ut_ad(buf_pool_mutex_own());
-
- return(bpage->LRU_position);
-}
-
-/*********************************************************************//**
Gets the mutex of a block.
@return pointer to mutex protecting bpage */
UNIV_INLINE
@@ -476,10 +466,19 @@ buf_page_set_old(
ut_ad(bpage->in_LRU_list);
#ifdef UNIV_LRU_DEBUG
- if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)
- && UT_LIST_GET_PREV(LRU, bpage)->old
- == UT_LIST_GET_NEXT(LRU, bpage)->old) {
- ut_a(UT_LIST_GET_PREV(LRU, bpage)->old == old);
+ ut_a((buf_pool->LRU_old_len == 0) == (buf_pool->LRU_old == NULL));
+ /* If a block is flagged "old", the LRU_old list must exist. */
+ ut_a(!old || buf_pool->LRU_old);
+
+ if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)) {
+ const buf_page_t* prev = UT_LIST_GET_PREV(LRU, bpage);
+ const buf_page_t* next = UT_LIST_GET_NEXT(LRU, bpage);
+ if (prev->old == next->old) {
+ ut_a(prev->old == old);
+ } else {
+ ut_a(!prev->old);
+ ut_a(buf_pool->LRU_old == (old ? bpage : next));
+ }
}
#endif /* UNIV_LRU_DEBUG */
@@ -487,17 +486,17 @@ buf_page_set_old(
}
/*********************************************************************//**
-Determine if a block has been accessed in the buffer pool.
-@return TRUE if accessed */
+Determine the time of first access of a block in the buffer pool.
+@return ut_time_ms() at the time of first access, 0 if not accessed */
UNIV_INLINE
-ibool
+unsigned
buf_page_is_accessed(
/*=================*/
const buf_page_t* bpage) /*!< in: control block */
{
ut_ad(buf_page_in_file(bpage));
- return(bpage->accessed);
+ return(bpage->access_time);
}
/*********************************************************************//**
@@ -507,12 +506,15 @@ void
buf_page_set_accessed(
/*==================*/
buf_page_t* bpage, /*!< in/out: control block */
- ibool accessed) /*!< in: accessed */
+ ulint time_ms) /*!< in: ut_time_ms() */
{
ut_a(buf_page_in_file(bpage));
- ut_ad(mutex_own(buf_page_get_mutex(bpage)));
+ ut_ad(buf_pool_mutex_own());
- bpage->accessed = accessed;
+ if (!bpage->access_time) {
+ /* Make this the time of the first access. */
+ bpage->access_time = time_ms;
+ }
}
/*********************************************************************//**
diff --git a/storage/innodb_plugin/include/buf0lru.h b/storage/innodb_plugin/include/buf0lru.h
index 463aca0982c..009430af35b 100644
--- a/storage/innodb_plugin/include/buf0lru.h
+++ b/storage/innodb_plugin/include/buf0lru.h
@@ -69,7 +69,7 @@ These are low-level functions
#########################################################################*/
/** Minimum LRU list length for which the LRU_old pointer is defined */
-#define BUF_LRU_OLD_MIN_LEN 80
+#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
/** Maximum LRU list search length in buf_flush_LRU_recommendation() */
#define BUF_LRU_FREE_SEARCH_LEN (5 + 2 * BUF_READ_AHEAD_AREA)
@@ -84,15 +84,6 @@ void
buf_LRU_invalidate_tablespace(
/*==========================*/
ulint id); /*!< in: space id */
-/******************************************************************//**
-Gets the minimum LRU_position field for the blocks in an initial segment
-(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
-guaranteed to be precise, because the ulint_clock may wrap around.
-@return the limit; zero if could not determine it */
-UNIV_INTERN
-ulint
-buf_LRU_get_recent_limit(void);
-/*==========================*/
/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
UNIV_INTERN
@@ -201,6 +192,18 @@ void
buf_LRU_make_block_old(
/*===================*/
buf_page_t* bpage); /*!< in: control block */
+/**********************************************************************//**
+Updates buf_LRU_old_ratio.
+@return updated old_pct */
+UNIV_INTERN
+uint
+buf_LRU_old_ratio_update(
+/*=====================*/
+ uint old_pct,/*!< in: Reserve this percentage of
+ the buffer pool for "old" blocks. */
+ ibool adjust);/*!< in: TRUE=adjust the LRU list;
+ FALSE=just assign buf_LRU_old_ratio
+ during the initialization of InnoDB */
/********************************************************************//**
Update the historical stats that we are collecting for LRU eviction
policy at the end of each interval. */
@@ -227,6 +230,35 @@ buf_LRU_print(void);
/*===============*/
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
+/** @name Heuristics for detecting index scan @{ */
+/** Reserve this much/BUF_LRU_OLD_RATIO_DIV of the buffer pool for
+"old" blocks. Protected by buf_pool_mutex. */
+extern uint buf_LRU_old_ratio;
+/** The denominator of buf_LRU_old_ratio. */
+#define BUF_LRU_OLD_RATIO_DIV 1024
+/** Maximum value of buf_LRU_old_ratio.
+@see buf_LRU_old_adjust_len
+@see buf_LRU_old_ratio_update */
+#define BUF_LRU_OLD_RATIO_MAX BUF_LRU_OLD_RATIO_DIV
+/** Minimum value of buf_LRU_old_ratio.
+@see buf_LRU_old_adjust_len
+@see buf_LRU_old_ratio_update
+The minimum must exceed
+(BUF_LRU_OLD_TOLERANCE + 5) * BUF_LRU_OLD_RATIO_DIV / BUF_LRU_OLD_MIN_LEN. */
+#define BUF_LRU_OLD_RATIO_MIN 51
+
+#if BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX
+# error "BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX"
+#endif
+#if BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV
+# error "BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV"
+#endif
+
+/** Move blocks to "new" LRU list only if the first access was at
+least this many milliseconds ago. Not protected by any mutex or latch. */
+extern uint buf_LRU_old_threshold_ms;
+/* @} */
+
/** @brief Statistics for selecting the LRU list for eviction.
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
diff --git a/storage/innodb_plugin/include/buf0rea.h b/storage/innodb_plugin/include/buf0rea.h
index b4d25e6fde0..093750623d6 100644
--- a/storage/innodb_plugin/include/buf0rea.h
+++ b/storage/innodb_plugin/include/buf0rea.h
@@ -33,12 +33,10 @@ Created 11/5/1995 Heikki Tuuri
High-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
-released by the i/o-handler thread. Does a random read-ahead if it seems
-sensible.
-@return number of page read requests issued: this can be greater than
-1 if read-ahead occurred */
+released by the i/o-handler thread.
+@return TRUE if page has been read in, FALSE in case of failure */
UNIV_INTERN
-ulint
+ibool
buf_read_page(
/*==========*/
ulint space, /*!< in: space id */
@@ -48,7 +46,7 @@ buf_read_page(
Applies linear read-ahead if in the buf_pool the page is a border page of
a linear read-ahead area and all the pages in the area have been accessed.
Does not read any page if the read-ahead mechanism is not activated. Note
-that the the algorithm looks at the 'natural' adjacent successor and
+that the algorithm looks at the 'natural' adjacent successor and
predecessor of the page, which on the leaf level of a B-tree are the next
and previous page in the chain of leaves. To know these, the page specified
in (space, offset) must already be present in the buf_pool. Thus, the
diff --git a/storage/innodb_plugin/include/buf0types.h b/storage/innodb_plugin/include/buf0types.h
index e7167d716a0..bfae6477135 100644
--- a/storage/innodb_plugin/include/buf0types.h
+++ b/storage/innodb_plugin/include/buf0types.h
@@ -34,6 +34,8 @@ typedef struct buf_block_struct buf_block_t;
typedef struct buf_chunk_struct buf_chunk_t;
/** Buffer pool comprising buf_chunk_t */
typedef struct buf_pool_struct buf_pool_t;
+/** Buffer pool statistics struct */
+typedef struct buf_pool_stat_struct buf_pool_stat_t;
/** A buffer frame. @see page_t */
typedef byte buf_frame_t;
diff --git a/storage/innodb_plugin/include/dict0crea.h b/storage/innodb_plugin/include/dict0crea.h
index 3107d771d88..cce1246b789 100644
--- a/storage/innodb_plugin/include/dict0crea.h
+++ b/storage/innodb_plugin/include/dict0crea.h
@@ -110,7 +110,7 @@ dict_create_or_check_foreign_constraint_tables(void);
Adds foreign key definitions to data dictionary tables in the database. We
look at table->foreign_list, and also generate names to constraints that were
not named by the user. A generated constraint has a name of the format
-databasename/tablename_ibfk_<number>, where the numbers start from 1, and are
+databasename/tablename_ibfk_NUMBER, where the numbers start from 1, and are
given locally for this table, that is, the number is not global, as in the
old format constraints < 4.0.18 it used to be.
@return error code or DB_SUCCESS */
diff --git a/storage/innodb_plugin/include/dict0dict.h b/storage/innodb_plugin/include/dict0dict.h
index b2029699e51..d425241a3a2 100644
--- a/storage/innodb_plugin/include/dict0dict.h
+++ b/storage/innodb_plugin/include/dict0dict.h
@@ -712,7 +712,7 @@ dict_index_find_on_id_low(
dulint id); /*!< in: index id */
/**********************************************************************//**
Adds an index to the dictionary cache.
-@return DB_SUCCESS or error code */
+@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
UNIV_INTERN
ulint
dict_index_add_to_cache(
diff --git a/storage/innodb_plugin/include/dict0mem.h b/storage/innodb_plugin/include/dict0mem.h
index 1ee906fbf57..2d001111938 100644
--- a/storage/innodb_plugin/include/dict0mem.h
+++ b/storage/innodb_plugin/include/dict0mem.h
@@ -317,7 +317,7 @@ struct dict_foreign_struct{
char* id; /*!< id of the constraint as a
null-terminated string */
unsigned n_fields:10; /*!< number of indexes' first fields
- for which the the foreign key
+ for which the foreign key
constraint is defined: we allow the
indexes to contain more fields than
mentioned in the constraint, as long
diff --git a/storage/innodb_plugin/include/fsp0fsp.h b/storage/innodb_plugin/include/fsp0fsp.h
index 5f7dc58eedc..7abd3914eda 100644
--- a/storage/innodb_plugin/include/fsp0fsp.h
+++ b/storage/innodb_plugin/include/fsp0fsp.h
@@ -42,7 +42,7 @@ fsp_init(void);
/*==========*/
/**********************************************************************//**
Gets the current free limit of the system tablespace. The free limit
-means the place of the first page which has never been put to the the
+means the place of the first page which has never been put to the
free list for allocation. The space above that address is initialized
to zero. Sets also the global variable log_fsp_current_free_limit.
@return free limit in megabytes */
diff --git a/storage/innodb_plugin/include/lock0lock.h b/storage/innodb_plugin/include/lock0lock.h
index fa5db831d4f..aeabe39e1a9 100644
--- a/storage/innodb_plugin/include/lock0lock.h
+++ b/storage/innodb_plugin/include/lock0lock.h
@@ -630,6 +630,14 @@ lock_number_of_rows_locked(
/*=======================*/
trx_t* trx); /*!< in: transaction */
/*******************************************************************//**
+Check if a transaction holds any autoinc locks.
+@return TRUE if the transaction holds any AUTOINC locks. */
+UNIV_INTERN
+ibool
+lock_trx_holds_autoinc_locks(
+/*=========================*/
+ const trx_t* trx); /*!< in: transaction */
+/*******************************************************************//**
Release all the transaction's autoinc locks. */
UNIV_INTERN
void
diff --git a/storage/innodb_plugin/include/log0log.h b/storage/innodb_plugin/include/log0log.h
index 059f548a085..299b4a05b40 100644
--- a/storage/innodb_plugin/include/log0log.h
+++ b/storage/innodb_plugin/include/log0log.h
@@ -118,10 +118,9 @@ UNIV_INLINE
ib_uint64_t
log_reserve_and_write_fast(
/*=======================*/
- byte* str, /*!< in: string */
+ const void* str, /*!< in: string */
ulint len, /*!< in: string length */
- ib_uint64_t* start_lsn,/*!< out: start lsn of the log record */
- ibool* success);/*!< out: TRUE if success */
+ ib_uint64_t* start_lsn);/*!< out: start lsn of the log record */
/***********************************************************************//**
Releases the log mutex. */
UNIV_INLINE
@@ -283,7 +282,7 @@ log_make_checkpoint_at(
later lsn, if IB_ULONGLONG_MAX, makes
a checkpoint at the latest lsn */
ibool write_always); /*!< in: the function normally checks if
- the the new checkpoint would have a
+ the new checkpoint would have a
greater lsn than the previous one: if
not, then no physical write is done;
by setting this parameter TRUE, a
diff --git a/storage/innodb_plugin/include/log0log.ic b/storage/innodb_plugin/include/log0log.ic
index d071985982a..36d151a3064 100644
--- a/storage/innodb_plugin/include/log0log.ic
+++ b/storage/innodb_plugin/include/log0log.ic
@@ -27,6 +27,7 @@ Created 12/9/1995 Heikki Tuuri
#include "mach0data.h"
#include "mtr0mtr.h"
+#ifdef UNIV_LOG_DEBUG
/******************************************************//**
Checks by parsing that the catenated log segment for a single mtr is
consistent. */
@@ -34,11 +35,12 @@ UNIV_INTERN
ibool
log_check_log_recs(
/*===============*/
- byte* buf, /*!< in: pointer to the start of
+ const byte* buf, /*!< in: pointer to the start of
the log segment in the
log_sys->buf log buffer */
ulint len, /*!< in: segment length in bytes */
ib_uint64_t buf_start_lsn); /*!< in: buffer start lsn */
+#endif /* UNIV_LOG_DEBUG */
/************************************************************//**
Gets a log block flush bit.
@@ -305,55 +307,76 @@ UNIV_INLINE
ib_uint64_t
log_reserve_and_write_fast(
/*=======================*/
- byte* str, /*!< in: string */
+ const void* str, /*!< in: string */
ulint len, /*!< in: string length */
- ib_uint64_t* start_lsn,/*!< out: start lsn of the log record */
- ibool* success)/*!< out: TRUE if success */
+ ib_uint64_t* start_lsn)/*!< out: start lsn of the log record */
{
- log_t* log = log_sys;
ulint data_len;
- ib_uint64_t lsn;
+#ifdef UNIV_LOG_LSN_DEBUG
+ /* length of the LSN pseudo-record */
+ ulint lsn_len = 1
+ + mach_get_compressed_size(log_sys->lsn >> 32)
+ + mach_get_compressed_size(log_sys->lsn & 0xFFFFFFFFUL);
+#endif /* UNIV_LOG_LSN_DEBUG */
- *success = TRUE;
+ mutex_enter(&log_sys->mutex);
- mutex_enter(&(log->mutex));
-
- data_len = len + log->buf_free % OS_FILE_LOG_BLOCK_SIZE;
+ data_len = len
+#ifdef UNIV_LOG_LSN_DEBUG
+ + lsn_len
+#endif /* UNIV_LOG_LSN_DEBUG */
+ + log_sys->buf_free % OS_FILE_LOG_BLOCK_SIZE;
if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
/* The string does not fit within the current log block
or the log block would become full */
- *success = FALSE;
-
- mutex_exit(&(log->mutex));
+ mutex_exit(&log_sys->mutex);
return(0);
}
- *start_lsn = log->lsn;
-
- ut_memcpy(log->buf + log->buf_free, str, len);
+ *start_lsn = log_sys->lsn;
+
+#ifdef UNIV_LOG_LSN_DEBUG
+ {
+ /* Write the LSN pseudo-record. */
+ byte* b = &log_sys->buf[log_sys->buf_free];
+ *b++ = MLOG_LSN | (MLOG_SINGLE_REC_FLAG & *(const byte*) str);
+ /* Write the LSN in two parts,
+ as a pseudo page number and space id. */
+ b += mach_write_compressed(b, log_sys->lsn >> 32);
+ b += mach_write_compressed(b, log_sys->lsn & 0xFFFFFFFFUL);
+ ut_a(b - lsn_len == &log_sys->buf[log_sys->buf_free]);
+
+ memcpy(b, str, len);
+ len += lsn_len;
+ }
+#else /* UNIV_LOG_LSN_DEBUG */
+ memcpy(log_sys->buf + log_sys->buf_free, str, len);
+#endif /* UNIV_LOG_LSN_DEBUG */
- log_block_set_data_len((byte*) ut_align_down(log->buf + log->buf_free,
+ log_block_set_data_len((byte*) ut_align_down(log_sys->buf
+ + log_sys->buf_free,
OS_FILE_LOG_BLOCK_SIZE),
data_len);
#ifdef UNIV_LOG_DEBUG
- log->old_buf_free = log->buf_free;
- log->old_lsn = log->lsn;
+ log_sys->old_buf_free = log_sys->buf_free;
+ log_sys->old_lsn = log_sys->lsn;
#endif
- log->buf_free += len;
+ log_sys->buf_free += len;
- ut_ad(log->buf_free <= log->buf_size);
+ ut_ad(log_sys->buf_free <= log_sys->buf_size);
- lsn = log->lsn += len;
+ log_sys->lsn += len;
#ifdef UNIV_LOG_DEBUG
- log_check_log_recs(log->buf + log->old_buf_free,
- log->buf_free - log->old_buf_free, log->old_lsn);
+ log_check_log_recs(log_sys->buf + log_sys->old_buf_free,
+ log_sys->buf_free - log_sys->old_buf_free,
+ log_sys->old_lsn);
#endif
- return(lsn);
+ return(log_sys->lsn);
}
/***********************************************************************//**
diff --git a/storage/innodb_plugin/include/log0recv.h b/storage/innodb_plugin/include/log0recv.h
index 8468c213bdb..6de735be945 100644
--- a/storage/innodb_plugin/include/log0recv.h
+++ b/storage/innodb_plugin/include/log0recv.h
@@ -433,6 +433,11 @@ are allowed yet: the variable name is misleading. */
extern ibool recv_no_ibuf_operations;
/** TRUE when recv_init_crash_recovery() has been called. */
extern ibool recv_needed_recovery;
+#ifdef UNIV_DEBUG
+/** TRUE if writing to the redo log (mtr_commit) is forbidden.
+Protected by log_sys->mutex. */
+extern ibool recv_no_log_write;
+#endif /* UNIV_DEBUG */
/** TRUE if buf_page_is_corrupted() should check if the log sequence
number (FIL_PAGE_LSN) is in the future. Initially FALSE, and set by
diff --git a/storage/innodb_plugin/include/mtr0mtr.h b/storage/innodb_plugin/include/mtr0mtr.h
index 69a2c03f4cb..bc3f1951be9 100644
--- a/storage/innodb_plugin/include/mtr0mtr.h
+++ b/storage/innodb_plugin/include/mtr0mtr.h
@@ -106,6 +106,9 @@ For 1 - 8 bytes, the flag value must give the length also! @{ */
#define MLOG_IBUF_BITMAP_INIT ((byte)27) /*!< initialize an
ibuf bitmap page */
/*#define MLOG_FULL_PAGE ((byte)28) full contents of a page */
+#ifdef UNIV_LOG_LSN_DEBUG
+# define MLOG_LSN ((byte)28) /* current LSN */
+#endif
#define MLOG_INIT_FILE_PAGE ((byte)29) /*!< this means that a
file page is taken
into use and the prior
@@ -118,7 +121,7 @@ For 1 - 8 bytes, the flag value must give the length also! @{ */
#define MLOG_WRITE_STRING ((byte)30) /*!< write a string to
a page */
#define MLOG_MULTI_REC_END ((byte)31) /*!< if a single mtr writes
- log records for several pages,
+ several log records,
this log record ends the
sequence of these records */
#define MLOG_DUMMY_RECORD ((byte)32) /*!< dummy log record used to
diff --git a/storage/innodb_plugin/include/os0file.h b/storage/innodb_plugin/include/os0file.h
index d8d2f0e5d9e..8535ef092c3 100644
--- a/storage/innodb_plugin/include/os0file.h
+++ b/storage/innodb_plugin/include/os0file.h
@@ -157,6 +157,7 @@ log. */
to become available again */
#define OS_FILE_SHARING_VIOLATION 76
#define OS_FILE_ERROR_NOT_SPECIFIED 77
+#define OS_FILE_INSUFFICIENT_RESOURCE 78
/* @} */
/** Types for aio operations @{ */
diff --git a/storage/innodb_plugin/include/os0sync.h b/storage/innodb_plugin/include/os0sync.h
index 0e0b32e7036..0c22162b900 100644
--- a/storage/innodb_plugin/include/os0sync.h
+++ b/storage/innodb_plugin/include/os0sync.h
@@ -285,44 +285,74 @@ os_fast_mutex_free(
/**********************************************************//**
Atomic compare-and-swap and increment for InnoDB. */
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
+#if defined(HAVE_IB_GCC_ATOMIC_BUILTINS)
+
+#define HAVE_ATOMIC_BUILTINS
+
/**********************************************************//**
Returns true if swapped, ptr is pointer to target, old_val is value to
compare to, new_val is the value to swap in. */
+
# define os_compare_and_swap(ptr, old_val, new_val) \
__sync_bool_compare_and_swap(ptr, old_val, new_val)
+
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
+
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
-# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
+
+# ifdef HAVE_IB_ATOMIC_PTHREAD_T_GCC
+# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
+# define INNODB_RW_LOCKS_USE_ATOMICS
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes and rw_locks use GCC atomic builtins"
+# else /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes use GCC atomic builtins, rw_locks do not"
+# endif /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
+
/**********************************************************//**
Returns the resulting value, ptr is pointer to target, amount is the
amount of increment. */
+
# define os_atomic_increment(ptr, amount) \
__sync_add_and_fetch(ptr, amount)
+
# define os_atomic_increment_lint(ptr, amount) \
os_atomic_increment(ptr, amount)
+
# define os_atomic_increment_ulint(ptr, amount) \
os_atomic_increment(ptr, amount)
+
/**********************************************************//**
Returns the old value of *ptr, atomically sets *ptr to new_val */
+
# define os_atomic_test_and_set_byte(ptr, new_val) \
__sync_lock_test_and_set(ptr, new_val)
+
+#elif defined(HAVE_IB_SOLARIS_ATOMICS)
+
+#define HAVE_ATOMIC_BUILTINS
+
/* If not compiling with GCC or GCC doesn't support the atomic
intrinsics and running on Solaris >= 10 use Solaris atomics */
-#elif defined(HAVE_SOLARIS_ATOMICS)
+
#include <atomic.h>
+
/**********************************************************//**
Returns true if swapped, ptr is pointer to target, old_val is value to
compare to, new_val is the value to swap in. */
+
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
(atomic_cas_ulong(ptr, old_val, new_val) == old_val)
+
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
((lint)atomic_cas_ulong((ulong_t*) ptr, old_val, new_val) == old_val)
-# ifdef INNODB_RW_LOCKS_USE_ATOMICS
-# if SIZEOF_PTHREAD_T == 4
+
+# ifdef HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS
+# if SIZEOF_PTHREAD_T == 4
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
((pthread_t)atomic_cas_32(ptr, old_val, new_val) == old_val)
# elif SIZEOF_PTHREAD_T == 8
@@ -331,21 +361,35 @@ compare to, new_val is the value to swap in. */
# else
# error "SIZEOF_PTHREAD_T != 4 or 8"
# endif /* SIZEOF_PTHREAD_T CHECK */
-# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
+# define INNODB_RW_LOCKS_USE_ATOMICS
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes and rw_locks use Solaris atomic functions"
+# else /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes use Solaris atomic functions, rw_locks do not"
+# endif /* HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS */
/**********************************************************//**
Returns the resulting value, ptr is pointer to target, amount is the
amount of increment. */
+
# define os_atomic_increment_lint(ptr, amount) \
atomic_add_long_nv((ulong_t*) ptr, amount)
+
# define os_atomic_increment_ulint(ptr, amount) \
atomic_add_long_nv(ptr, amount)
+
/**********************************************************//**
Returns the old value of *ptr, atomically sets *ptr to new_val */
+
# define os_atomic_test_and_set_byte(ptr, new_val) \
atomic_swap_uchar(ptr, new_val)
-/* On Windows, use Windows atomics / interlocked */
+
#elif defined(HAVE_WINDOWS_ATOMICS)
+
+#define HAVE_ATOMIC_BUILTINS
+
+/* On Windows, use Windows atomics / interlocked */
# ifdef _WIN64
# define win_cmp_and_xchg InterlockedCompareExchange64
# define win_xchg_and_add InterlockedExchangeAdd64
@@ -353,31 +397,46 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */
# define win_cmp_and_xchg InterlockedCompareExchange
# define win_xchg_and_add InterlockedExchangeAdd
# endif
+
/**********************************************************//**
Returns true if swapped, ptr is pointer to target, old_val is value to
compare to, new_val is the value to swap in. */
+
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
(win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
+
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
(win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
-# ifdef INNODB_RW_LOCKS_USE_ATOMICS
-# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
+
+/* windows thread objects can always be passed to windows atomic functions */
+# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
(InterlockedCompareExchange(ptr, new_val, old_val) == old_val)
-# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
+# define INNODB_RW_LOCKS_USE_ATOMICS
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes and rw_locks use Windows interlocked functions"
+
/**********************************************************//**
Returns the resulting value, ptr is pointer to target, amount is the
amount of increment. */
+
# define os_atomic_increment_lint(ptr, amount) \
(win_xchg_and_add(ptr, amount) + amount)
+
# define os_atomic_increment_ulint(ptr, amount) \
((ulint) (win_xchg_and_add(ptr, amount) + amount))
+
/**********************************************************//**
Returns the old value of *ptr, atomically sets *ptr to new_val.
InterlockedExchange() operates on LONG, and the LONG will be
clobbered */
+
# define os_atomic_test_and_set_byte(ptr, new_val) \
((byte) InterlockedExchange(ptr, new_val))
-#endif /* HAVE_GCC_ATOMIC_BUILTINS */
+
+#else
+# define IB_ATOMICS_STARTUP_MSG \
+ "Mutexes and rw_locks use InnoDB's own implementation"
+#endif
#ifndef UNIV_NONINL
#include "os0sync.ic"
diff --git a/storage/innodb_plugin/include/page0page.h b/storage/innodb_plugin/include/page0page.h
index a4fe069d022..3899499fb6a 100644
--- a/storage/innodb_plugin/include/page0page.h
+++ b/storage/innodb_plugin/include/page0page.h
@@ -76,8 +76,11 @@ typedef byte page_header_t;
header which are set in a page create */
/*----*/
#define PAGE_LEVEL 26 /* level of the node in an index tree; the
- leaf level is the level 0 */
-#define PAGE_INDEX_ID 28 /* index id where the page belongs */
+ leaf level is the level 0. This field should
+ not be written to after page creation. */
+#define PAGE_INDEX_ID 28 /* index id where the page belongs.
+ This field should not be written to after
+ page creation. */
#define PAGE_BTR_SEG_LEAF 36 /* file segment header for the leaf pages in
a B-tree: defined only on the root page of a
B-tree, but not in the root of an ibuf tree */
diff --git a/storage/innodb_plugin/include/page0page.ic b/storage/innodb_plugin/include/page0page.ic
index 318ec1cc1f2..8f794410f20 100644
--- a/storage/innodb_plugin/include/page0page.ic
+++ b/storage/innodb_plugin/include/page0page.ic
@@ -907,7 +907,7 @@ page_get_data_size(
/************************************************************//**
Allocates a block of memory from the free list of an index page. */
-UNIV_INTERN
+UNIV_INLINE
void
page_mem_alloc_free(
/*================*/
diff --git a/storage/innodb_plugin/include/page0zip.h b/storage/innodb_plugin/include/page0zip.h
index 9aaa066306b..574809e5227 100644
--- a/storage/innodb_plugin/include/page0zip.h
+++ b/storage/innodb_plugin/include/page0zip.h
@@ -127,8 +127,12 @@ page_zip_decompress(
/*================*/
page_zip_des_t* page_zip,/*!< in: data, ssize;
out: m_start, m_end, m_nonempty, n_blobs */
- page_t* page) /*!< out: uncompressed page, may be trashed */
- __attribute__((nonnull));
+ page_t* page, /*!< out: uncompressed page, may be trashed */
+ ibool all) /*!< in: TRUE=decompress the whole page;
+ FALSE=verify but do not copy some
+ page header fields that should not change
+ after page creation */
+ __attribute__((nonnull(1,2)));
#ifdef UNIV_DEBUG
/**********************************************************************//**
@@ -385,8 +389,8 @@ IMPORTANT: if page_zip_reorganize() is invoked on a leaf page of a
non-clustered index, the caller must update the insert buffer free
bits in the same mini-transaction in such a way that the modification
will be redo-logged.
-@return TRUE on success, FALSE on failure; page and page_zip will be
-left intact on failure. */
+@return TRUE on success, FALSE on failure; page_zip will be left
+intact on failure, but page will be overwritten. */
UNIV_INTERN
ibool
page_zip_reorganize(
diff --git a/storage/innodb_plugin/include/rem0cmp.h b/storage/innodb_plugin/include/rem0cmp.h
index d30d9f86abe..072f74267ea 100644
--- a/storage/innodb_plugin/include/rem0cmp.h
+++ b/storage/innodb_plugin/include/rem0cmp.h
@@ -89,7 +89,7 @@ cmp_dfield_dfield(
/*************************************************************//**
This function is used to compare a data tuple to a physical record.
Only dtuple->n_fields_cmp first fields are taken into account for
-the the data tuple! If we denote by n = n_fields_cmp, then rec must
+the data tuple! If we denote by n = n_fields_cmp, then rec must
have either m >= n fields, or it must differ from dtuple in some of
the m fields rec has. If rec has an externally stored field we do not
compare it but return with value 0 if such a comparison should be
diff --git a/storage/innodb_plugin/include/rem0rec.ic b/storage/innodb_plugin/include/rem0rec.ic
index 9fe736f9b0b..8e5bd9a7fcd 100644
--- a/storage/innodb_plugin/include/rem0rec.ic
+++ b/storage/innodb_plugin/include/rem0rec.ic
@@ -65,7 +65,7 @@ most significant bytes and bits are written below less significant.
- offset_of_this_record) mod 64Ki,
where mod is the modulo as a non-negative
number;
- we can calculate the the offset of the next
+ we can calculate the offset of the next
record with the formula:
relative_offset + offset_of_this_record
mod UNIV_PAGE_SIZE
diff --git a/storage/innodb_plugin/include/row0ins.h b/storage/innodb_plugin/include/row0ins.h
index 530622e6225..9f93565ddb7 100644
--- a/storage/innodb_plugin/include/row0ins.h
+++ b/storage/innodb_plugin/include/row0ins.h
@@ -45,7 +45,7 @@ row_ins_check_foreign_constraint(
/*=============================*/
ibool check_ref,/*!< in: TRUE If we want to check that
the referenced table is ok, FALSE if we
- want to to check the foreign key table */
+ want to check the foreign key table */
dict_foreign_t* foreign,/*!< in: foreign constraint; NOTE that the
tables mentioned in it must be in the
dictionary cache if they exist at all */
diff --git a/storage/innodb_plugin/include/row0mysql.h b/storage/innodb_plugin/include/row0mysql.h
index 97028622505..b05241f00f8 100644
--- a/storage/innodb_plugin/include/row0mysql.h
+++ b/storage/innodb_plugin/include/row0mysql.h
@@ -177,7 +177,9 @@ row_update_prebuilt_trx(
in MySQL handle */
trx_t* trx); /*!< in: transaction handle */
/*********************************************************************//**
-Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
+Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
+function should be called at the the end of an SQL statement, by the
+connection thread that owns the transaction (trx->mysql_thd). */
UNIV_INTERN
void
row_unlock_table_autoinc_for_mysql(
@@ -754,8 +756,6 @@ struct row_prebuilt_struct {
store it here so that we can return
it to MySQL */
/*----------------------*/
- UT_LIST_NODE_T(row_prebuilt_t) prebuilts;
- /*!< list node of table->prebuilts */
ulint magic_n2; /*!< this should be the same as
magic_n */
};
diff --git a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/include/srv0srv.h
index 499bccfe2b8..23472bd100e 100644
--- a/storage/innodb_plugin/include/srv0srv.h
+++ b/storage/innodb_plugin/include/srv0srv.h
@@ -315,10 +315,6 @@ extern ulint srv_buf_pool_flushed;
/** Number of buffer pool reads that led to the
reading of a disk page */
extern ulint srv_buf_pool_reads;
-/** Number of sequential read-aheads */
-extern ulint srv_read_ahead_seq;
-/** Number of random read-aheads */
-extern ulint srv_read_ahead_rnd;
/** Status variables to be passed to MySQL */
typedef struct export_var_struct export_struc;
@@ -605,13 +601,13 @@ struct export_var_struct{
#ifdef UNIV_DEBUG
ulint innodb_buffer_pool_pages_latched; /*!< Latched pages */
#endif /* UNIV_DEBUG */
- ulint innodb_buffer_pool_read_requests; /*!< buf_pool->n_page_gets */
+ ulint innodb_buffer_pool_read_requests; /*!< buf_pool->stat.n_page_gets */
ulint innodb_buffer_pool_reads; /*!< srv_buf_pool_reads */
ulint innodb_buffer_pool_wait_free; /*!< srv_buf_pool_wait_free */
ulint innodb_buffer_pool_pages_flushed; /*!< srv_buf_pool_flushed */
ulint innodb_buffer_pool_write_requests;/*!< srv_buf_pool_write_requests */
- ulint innodb_buffer_pool_read_ahead_seq;/*!< srv_read_ahead_seq */
- ulint innodb_buffer_pool_read_ahead_rnd;/*!< srv_read_ahead_rnd */
+ ulint innodb_buffer_pool_read_ahead; /*!< srv_read_ahead */
+ ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/
ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */
ulint innodb_dblwr_writes; /*!< srv_dblwr_writes */
ibool innodb_have_atomic_builtins; /*!< HAVE_ATOMIC_BUILTINS */
@@ -623,9 +619,9 @@ struct export_var_struct{
ulint innodb_os_log_pending_writes; /*!< srv_os_log_pending_writes */
ulint innodb_os_log_pending_fsyncs; /*!< fil_n_pending_log_flushes */
ulint innodb_page_size; /*!< UNIV_PAGE_SIZE */
- ulint innodb_pages_created; /*!< buf_pool->n_pages_created */
- ulint innodb_pages_read; /*!< buf_pool->n_pages_read */
- ulint innodb_pages_written; /*!< buf_pool->n_pages_written */
+ ulint innodb_pages_created; /*!< buf_pool->stat.n_pages_created */
+ ulint innodb_pages_read; /*!< buf_pool->stat.n_pages_read */
+ ulint innodb_pages_written; /*!< buf_pool->stat.n_pages_written */
ulint innodb_row_lock_waits; /*!< srv_n_lock_wait_count */
ulint innodb_row_lock_current_waits; /*!< srv_n_lock_wait_current_count */
ib_int64_t innodb_row_lock_time; /*!< srv_n_lock_wait_time
diff --git a/storage/innodb_plugin/include/trx0rec.h b/storage/innodb_plugin/include/trx0rec.h
index 0ae82c33afe..a6e56e963c6 100644
--- a/storage/innodb_plugin/include/trx0rec.h
+++ b/storage/innodb_plugin/include/trx0rec.h
@@ -44,8 +44,8 @@ UNIV_INLINE
trx_undo_rec_t*
trx_undo_rec_copy(
/*==============*/
- trx_undo_rec_t* undo_rec, /*!< in: undo log record */
- mem_heap_t* heap); /*!< in: heap where copied */
+ const trx_undo_rec_t* undo_rec, /*!< in: undo log record */
+ mem_heap_t* heap); /*!< in: heap where copied */
/**********************************************************************//**
Reads the undo log record type.
@return record type */
diff --git a/storage/innodb_plugin/include/trx0rec.ic b/storage/innodb_plugin/include/trx0rec.ic
index 037b5d4f6cf..e7e41d6d9f6 100644
--- a/storage/innodb_plugin/include/trx0rec.ic
+++ b/storage/innodb_plugin/include/trx0rec.ic
@@ -100,8 +100,8 @@ UNIV_INLINE
trx_undo_rec_t*
trx_undo_rec_copy(
/*==============*/
- trx_undo_rec_t* undo_rec, /*!< in: undo log record */
- mem_heap_t* heap) /*!< in: heap where copied */
+ const trx_undo_rec_t* undo_rec, /*!< in: undo log record */
+ mem_heap_t* heap) /*!< in: heap where copied */
{
ulint len;
diff --git a/storage/innodb_plugin/include/trx0roll.h b/storage/innodb_plugin/include/trx0roll.h
index ddca9e9e4ef..1dee5655c8c 100644
--- a/storage/innodb_plugin/include/trx0roll.h
+++ b/storage/innodb_plugin/include/trx0roll.h
@@ -133,6 +133,17 @@ trx_rollback(
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
committed, then we clean up a possible insert undo log. If the
+transaction was not yet committed, then we roll it back. */
+UNIV_INTERN
+void
+trx_rollback_or_clean_recovered(
+/*============================*/
+ ibool all); /*!< in: FALSE=roll back dictionary transactions;
+ TRUE=roll back all non-PREPARED transactions */
+/*******************************************************************//**
+Rollback or clean up any incomplete transactions which were
+encountered in crash recovery. If the transaction already was
+committed, then we clean up a possible insert undo log. If the
transaction was not yet committed, then we roll it back.
Note: this is done in a background thread.
@return a dummy parameter */
@@ -208,9 +219,9 @@ int
trx_general_rollback_for_mysql(
/*===========================*/
trx_t* trx, /*!< in: transaction handle */
- ibool partial,/*!< in: TRUE if partial rollback requested */
trx_savept_t* savept);/*!< in: pointer to savepoint undo number, if
- partial rollback requested */
+ partial rollback requested, or NULL for
+ complete rollback */
/*******************************************************************//**
Rolls back a transaction back to a named savepoint. Modifications after the
savepoint are undone but InnoDB does NOT release the corresponding locks
diff --git a/storage/innodb_plugin/include/trx0sys.ic b/storage/innodb_plugin/include/trx0sys.ic
index 1c7c732751b..820d31d0692 100644
--- a/storage/innodb_plugin/include/trx0sys.ic
+++ b/storage/innodb_plugin/include/trx0sys.ic
@@ -34,11 +34,11 @@ typedef byte trx_sysf_rseg_t;
/* Rollback segment specification slot offsets */
/*-------------------------------------------------------------*/
-#define TRX_SYS_RSEG_SPACE 0 /* space where the the segment
+#define TRX_SYS_RSEG_SPACE 0 /* space where the segment
header is placed; starting with
MySQL/InnoDB 5.1.7, this is
UNIV_UNDEFINED if the slot is unused */
-#define TRX_SYS_RSEG_PAGE_NO 4 /* page number where the the segment
+#define TRX_SYS_RSEG_PAGE_NO 4 /* page number where the segment
header is placed; this is FIL_NULL
if the slot is unused */
/*-------------------------------------------------------------*/
diff --git a/storage/innodb_plugin/include/trx0trx.h b/storage/innodb_plugin/include/trx0trx.h
index 681feeaec94..d2a59740c93 100644
--- a/storage/innodb_plugin/include/trx0trx.h
+++ b/storage/innodb_plugin/include/trx0trx.h
@@ -179,7 +179,7 @@ trx_commit_off_kernel(
/****************************************************************//**
Cleans up a transaction at database startup. The cleanup is needed if
the transaction already got to the middle of a commit when the database
-crashed, andf we cannot roll it back. */
+crashed, and we cannot roll it back. */
UNIV_INTERN
void
trx_cleanup_at_db_startup(
@@ -360,7 +360,7 @@ enum trx_dict_op {
operation modes in crash recovery. */
TRX_DICT_OP_TABLE = 1,
/** The transaction is creating or dropping an index in an
- existing table. In crash recovery, the the data dictionary
+ existing table. In crash recovery, the data dictionary
must be locked, but the table must not be dropped. */
TRX_DICT_OP_INDEX = 2
};
diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i
index 023a6c9cd89..5d0361658af 100644
--- a/storage/innodb_plugin/include/univ.i
+++ b/storage/innodb_plugin/include/univ.i
@@ -46,11 +46,11 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 1
#define INNODB_VERSION_MINOR 0
-#define INNODB_VERSION_BUGFIX 4
+#define INNODB_VERSION_BUGFIX 5
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
-calculated in in make_version_string() in sql/sql_show.cc like this:
+calculated in make_version_string() in sql/sql_show.cc like this:
"version >> 8" . "version & 0xff"
because the version is shown with only one dot, we skip the last
component, i.e. we show M.N.P as M.N */
@@ -78,17 +78,25 @@ the virtual method table (vtable) in GCC 3. */
# define ha_innobase ha_innodb
#endif /* MYSQL_DYNAMIC_PLUGIN */
+/* if any of the following macros is defined at this point this means
+that the code from the "right" plug.in was executed and we do not
+need to include ut0auxconf.h which would either define the same macros
+or will be empty */
+#if !defined(HAVE_IB_GCC_ATOMIC_BUILTINS) \
+ && !defined(HAVE_IB_ATOMIC_PTHREAD_T_GCC) \
+ && !defined(HAVE_IB_SOLARIS_ATOMICS) \
+ && !defined(HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS) \
+ && !defined(SIZEOF_PTHREAD_T) \
+ && !defined(HAVE_IB_PAUSE_INSTRUCTION)
+# include "ut0auxconf.h"
+#endif
+
#if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER) && !defined(__WIN__)
# undef __WIN__
# define __WIN__
# include <windows.h>
-# if defined(HAVE_WINDOWS_ATOMICS)
-/* If atomics are defined we use them in InnoDB mutex implementation */
-# define HAVE_ATOMIC_BUILTINS
-# endif /* HAVE_WINDOWS_ATOMICS */
-
# ifdef _NT_
# define __NT__
# endif
@@ -111,45 +119,17 @@ if we are compiling on Windows. */
# include <sys/mman.h> /* mmap() for os0proc.c */
# endif
-# undef PACKAGE
-# undef VERSION
-
/* Include the header file generated by GNU autoconf */
# ifndef __WIN__
-#ifndef UNIV_HOTBACKUP
-# include "config.h"
-#endif /* UNIV_HOTBACKUP */
+# ifndef UNIV_HOTBACKUP
+# include "config.h"
+# endif /* UNIV_HOTBACKUP */
# endif
# ifdef HAVE_SCHED_H
# include <sched.h>
# endif
-# if defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_SOLARIS_ATOMICS) \
- || defined(HAVE_WINDOWS_ATOMICS)
-/* If atomics are defined we use them in InnoDB mutex implementation */
-# define HAVE_ATOMIC_BUILTINS
-# endif /* (HAVE_GCC_ATOMIC_BUILTINS) || (HAVE_SOLARIS_ATOMICS)
- || (HAVE_WINDOWS_ATOMICS) */
-
-/* For InnoDB rw_locks to work with atomics we need the thread_id
-to be no more than machine word wide. The following enables using
-atomics for InnoDB rw_locks where these conditions are met. */
-#ifdef HAVE_ATOMIC_BUILTINS
-/* if HAVE_ATOMIC_PTHREAD_T is defined at this point that means that
-the code from plug.in has defined it and we do not need to include
-ut0auxconf.h which would either define HAVE_ATOMIC_PTHREAD_T or will
-be empty */
-# ifndef HAVE_ATOMIC_PTHREAD_T
-# include "ut0auxconf.h"
-# endif /* HAVE_ATOMIC_PTHREAD_T */
-/* now HAVE_ATOMIC_PTHREAD_T is eventually defined either by plug.in or
-from Makefile.in->ut0auxconf.h */
-# ifdef HAVE_ATOMIC_PTHREAD_T
-# define INNODB_RW_LOCKS_USE_ATOMICS
-# endif /* HAVE_ATOMIC_PTHREAD_T */
-#endif /* HAVE_ATOMIC_BUILTINS */
-
/* We only try to do explicit inlining of functions with gcc and
Sun Studio */
@@ -196,12 +176,18 @@ command. Not tested on Windows. */
debugging without UNIV_DEBUG */
#define UNIV_DEBUG /* Enable ut_ad() assertions
and disable UNIV_INLINE */
+#define UNIV_DEBUG_LOCK_VALIDATE /* Enable
+ ut_ad(lock_rec_validate_page())
+ assertions. */
#define UNIV_DEBUG_FILE_ACCESSES /* Debug .ibd file access
(field file_page_was_freed
in buf_page_t) */
#define UNIV_LRU_DEBUG /* debug the buffer pool LRU */
#define UNIV_HASH_DEBUG /* debug HASH_ macros */
#define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */
+#define UNIV_LOG_LSN_DEBUG /* write LSN to the redo log;
+this will break redo log file compatibility, but it may be useful when
+debugging redo log application problems. */
#define UNIV_MEM_DEBUG /* detect memory leaks etc */
#define UNIV_IBUF_DEBUG /* debug the insert buffer */
#define UNIV_IBUF_COUNT_DEBUG /* debug the insert buffer;
@@ -251,7 +237,7 @@ by one. */
/* Linkage specifier for non-static InnoDB symbols (variables and functions)
that are only referenced from within InnoDB, not from MySQL */
-#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(UNIV_HOTBACKUP)
+#if defined(__GNUC__) && (__GNUC__ >= 4) || defined(__INTEL_COMPILER)
# define UNIV_INTERN __attribute__((visibility ("hidden")))
#else
# define UNIV_INTERN
@@ -409,7 +395,8 @@ it is read. */
it is read or written. */
# define UNIV_PREFETCH_RW(addr) __builtin_prefetch(addr, 1, 3)
/* Sun Studio includes sun_prefetch.h as of version 5.9 */
-#elif (defined(__SUNPRO_C) && __SUNPRO_C >= 0x590) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
+#elif (defined(__SUNPRO_C) && __SUNPRO_C >= 0x590) \
+ || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
# include <sun_prefetch.h>
#if __SUNPRO_C >= 0x550
# undef UNIV_INTERN
diff --git a/storage/innodb_plugin/include/ut0auxconf.h b/storage/innodb_plugin/include/ut0auxconf.h
index 88fb26f1863..16bcc308392 100644
--- a/storage/innodb_plugin/include/ut0auxconf.h
+++ b/storage/innodb_plugin/include/ut0auxconf.h
@@ -1,14 +1,14 @@
/* Do not remove this file even though it is empty.
This file is included in univ.i and will cause compilation failure
if not present.
-A custom check has been added in the generated
+A custom checks have been added in the generated
storage/innobase/Makefile.in that is shipped with the InnoDB Plugin
-source archive. This check tries to compile a test program and if
-successful then adds "#define HAVE_ATOMIC_PTHREAD_T" to this file.
-This is a hack that has been developed in order to check for pthread_t
-atomicity without the need to regenerate the ./configure script that is
+source archive. These checks eventually define some macros and put
+them in this file.
+This is a hack that has been developed in order to deploy new compile
+time checks without the need to regenerate the ./configure script that is
distributed in the MySQL 5.1 official source archives.
If by any chance Makefile.in and ./configure are regenerated and thus
-the hack from Makefile.in wiped away then the "real" check from plug.in
+the hack from Makefile.in wiped away then the "real" checks from plug.in
will take over.
*/
diff --git a/storage/innodb_plugin/include/ut0byte.h b/storage/innodb_plugin/include/ut0byte.h
index a2687e62f08..f55e2888c60 100644
--- a/storage/innodb_plugin/include/ut0byte.h
+++ b/storage/innodb_plugin/include/ut0byte.h
@@ -219,8 +219,8 @@ UNIV_INLINE
void*
ut_align(
/*=====*/
- void* ptr, /*!< in: pointer */
- ulint align_no); /*!< in: align by this number */
+ const void* ptr, /*!< in: pointer */
+ ulint align_no); /*!< in: align by this number */
/*********************************************************//**
The following function rounds down a pointer to the nearest
aligned address.
diff --git a/storage/innodb_plugin/include/ut0byte.ic b/storage/innodb_plugin/include/ut0byte.ic
index e3beed65138..3dd51890cb4 100644
--- a/storage/innodb_plugin/include/ut0byte.ic
+++ b/storage/innodb_plugin/include/ut0byte.ic
@@ -319,8 +319,8 @@ UNIV_INLINE
void*
ut_align(
/*=====*/
- void* ptr, /*!< in: pointer */
- ulint align_no) /*!< in: align by this number */
+ const void* ptr, /*!< in: pointer */
+ ulint align_no) /*!< in: align by this number */
{
ut_ad(align_no > 0);
ut_ad(((align_no - 1) & align_no) == 0);
diff --git a/storage/innodb_plugin/include/ut0ut.h b/storage/innodb_plugin/include/ut0ut.h
index 80094321041..197b8401428 100644
--- a/storage/innodb_plugin/include/ut0ut.h
+++ b/storage/innodb_plugin/include/ut0ut.h
@@ -34,6 +34,11 @@ Created 1/20/1994 Heikki Tuuri
#define ut0ut_h
#include "univ.i"
+
+#ifndef UNIV_HOTBACKUP
+# include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
+#endif /* UNIV_HOTBACKUP */
+
#include <time.h>
#ifndef MYSQL_SERVER
#include <ctype.h>
@@ -47,7 +52,8 @@ Created 1/20/1994 Heikki Tuuri
/** Time stamp */
typedef time_t ib_time_t;
-#if defined(IB_HAVE_PAUSE_INSTRUCTION)
+#ifndef UNIV_HOTBACKUP
+#if defined(HAVE_IB_PAUSE_INSTRUCTION)
# ifdef WIN32
/* In the Win32 API, the x86 PAUSE instruction is executed by calling
the YieldProcessor macro defined in WinNT.h. It is a CPU architecture-
@@ -84,6 +90,7 @@ do { \
os_thread_sleep(2000 /* 2 ms */); \
} \
} while (0)
+#endif /* !UNIV_HOTBACKUP */
/********************************************************//**
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
@@ -216,6 +223,7 @@ UNIV_INTERN
ib_time_t
ut_time(void);
/*=========*/
+#ifndef UNIV_HOTBACKUP
/**********************************************************//**
Returns system time.
Upon successful completion, the value 0 is returned; otherwise the
@@ -239,6 +247,16 @@ ullint
ut_time_us(
/*=======*/
ullint* tloc); /*!< out: us since epoch, if non-NULL */
+/**********************************************************//**
+Returns the number of milliseconds since some epoch. The
+value may wrap around. It should only be used for heuristic
+purposes.
+@return ms since epoch */
+UNIV_INTERN
+ulint
+ut_time_ms(void);
+/*============*/
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************//**
Returns the difference of two times in seconds.
diff --git a/storage/innodb_plugin/lock/lock0lock.c b/storage/innodb_plugin/lock/lock0lock.c
index fcd8d268331..67b2eac7219 100644
--- a/storage/innodb_plugin/lock/lock0lock.c
+++ b/storage/innodb_plugin/lock/lock0lock.c
@@ -214,7 +214,7 @@ a waiting s-lock request on the next record? If this s-lock was placed
by a read cursor moving in the ascending order in the index, we cannot
do the insert immediately, because when we finally commit our transaction,
the read cursor should see also the new inserted record. So we should
-move the read cursor backward from the the next record for it to pass over
+move the read cursor backward from the next record for it to pass over
the new inserted record. This move backward may be too cumbersome to
implement. If we in this situation just enqueue a second x-lock request
for our transaction on the next record, then the deadlock mechanism
@@ -360,10 +360,9 @@ ibool
lock_rec_validate_page(
/*===================*/
ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
+ or 0 for uncompressed pages */
ulint page_no);/*!< in: page number */
-
-/* Define the following in order to enable lock_rec_validate_page() checks. */
-# undef UNIV_DEBUG_LOCK_VALIDATE
#endif /* UNIV_DEBUG */
/* The lock system */
@@ -2622,6 +2621,7 @@ lock_move_reorganize_page(
#ifdef UNIV_DEBUG_LOCK_VALIDATE
ut_ad(lock_rec_validate_page(buf_block_get_space(block),
+ buf_block_get_zip_size(block),
buf_block_get_page_no(block)));
#endif
}
@@ -2711,8 +2711,10 @@ lock_move_rec_list_end(
#ifdef UNIV_DEBUG_LOCK_VALIDATE
ut_ad(lock_rec_validate_page(buf_block_get_space(block),
+ buf_block_get_zip_size(block),
buf_block_get_page_no(block)));
ut_ad(lock_rec_validate_page(buf_block_get_space(new_block),
+ buf_block_get_zip_size(block),
buf_block_get_page_no(new_block)));
#endif
}
@@ -2822,6 +2824,7 @@ lock_move_rec_list_start(
#ifdef UNIV_DEBUG_LOCK_VALIDATE
ut_ad(lock_rec_validate_page(buf_block_get_space(block),
+ buf_block_get_zip_size(block),
buf_block_get_page_no(block)));
#endif
}
@@ -3574,7 +3577,8 @@ lock_table_remove_low(
and lock_grant()). Therefore it can be empty and we
need to check for that. */
- if (!ib_vector_is_empty(trx->autoinc_locks)) {
+ if (!lock_get_wait(lock)
+ && !ib_vector_is_empty(trx->autoinc_locks)) {
lock_t* autoinc_lock;
autoinc_lock = ib_vector_pop(trx->autoinc_locks);
@@ -3647,8 +3651,10 @@ lock_table_enqueue_waiting(
if (lock_deadlock_occurs(lock, trx)) {
- lock_reset_lock_and_trx_wait(lock);
+ /* The order here is important, we don't want to
+ lose the state of the lock before calling remove. */
lock_table_remove_low(lock);
+ lock_reset_lock_and_trx_wait(lock);
return(DB_DEADLOCK);
}
@@ -4627,6 +4633,10 @@ lock_rec_queue_validate(
next function call: we have to release lock table mutex
to obey the latching order */
+ /* If this thread is holding the file space latch
+ (fil_space_t::latch), the following check WILL break
+ latching order and may cause a deadlock of threads. */
+
impl_trx = lock_sec_rec_some_has_impl_off_kernel(
rec, index, offsets);
@@ -4684,6 +4694,8 @@ ibool
lock_rec_validate_page(
/*===================*/
ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
+ or 0 for uncompressed pages */
ulint page_no)/*!< in: page number */
{
dict_index_t* index;
@@ -4694,7 +4706,6 @@ lock_rec_validate_page(
ulint nth_lock = 0;
ulint nth_bit = 0;
ulint i;
- ulint zip_size;
mtr_t mtr;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
@@ -4705,7 +4716,6 @@ lock_rec_validate_page(
mtr_start(&mtr);
- zip_size = fil_space_get_zip_size(space);
ut_ad(zip_size != ULINT_UNDEFINED);
block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
@@ -4750,6 +4760,11 @@ loop:
lock_mutex_exit_kernel();
+ /* If this thread is holding the file space
+ latch (fil_space_t::latch), the following
+ check WILL break the latching order and may
+ cause a deadlock of threads. */
+
lock_rec_queue_validate(block, rec, index, offsets);
lock_mutex_enter_kernel();
@@ -4840,7 +4855,9 @@ lock_validate(void)
lock_mutex_exit_kernel();
- lock_rec_validate_page(space, page_no);
+ lock_rec_validate_page(space,
+ fil_space_get_zip_size(space),
+ page_no);
lock_mutex_enter_kernel();
@@ -5364,6 +5381,20 @@ lock_release_autoinc_last_lock(
}
/*******************************************************************//**
+Check if a transaction holds any autoinc locks.
+@return TRUE if the transaction holds any AUTOINC locks. */
+UNIV_INTERN
+ibool
+lock_trx_holds_autoinc_locks(
+/*=========================*/
+ const trx_t* trx) /*!< in: transaction */
+{
+ ut_a(trx->autoinc_locks != NULL);
+
+ return(!ib_vector_is_empty(trx->autoinc_locks));
+}
+
+/*******************************************************************//**
Release all the transaction's autoinc locks. */
UNIV_INTERN
void
diff --git a/storage/innodb_plugin/log/log0log.c b/storage/innodb_plugin/log/log0log.c
index 24c828cdf5f..a23dd20772a 100644
--- a/storage/innodb_plugin/log/log0log.c
+++ b/storage/innodb_plugin/log/log0log.c
@@ -241,6 +241,7 @@ log_reserve_and_open(
ut_a(len < log->buf_size / 2);
loop:
mutex_enter(&(log->mutex));
+ ut_ad(!recv_no_log_write);
/* Calculate an upper limit for the space the string may take in the
log buffer */
@@ -309,6 +310,7 @@ log_write_low(
ut_ad(mutex_own(&(log->mutex)));
part_loop:
+ ut_ad(!recv_no_log_write);
/* Calculate a part length */
data_len = (log->buf_free % OS_FILE_LOG_BLOCK_SIZE) + str_len;
@@ -377,6 +379,7 @@ log_close(void)
ib_uint64_t checkpoint_age;
ut_ad(mutex_own(&(log->mutex)));
+ ut_ad(!recv_no_log_write);
lsn = log->lsn;
@@ -668,8 +671,6 @@ log_calc_max_ages(void)
ulint archive_margin;
ulint smallest_archive_margin;
- ut_ad(!mutex_own(&(log_sys->mutex)));
-
mutex_enter(&(log_sys->mutex));
group = UT_LIST_GET_FIRST(log_sys->log_groups);
@@ -1117,6 +1118,7 @@ log_io_complete(
}
mutex_enter(&(log_sys->mutex));
+ ut_ad(!recv_no_log_write);
ut_a(group->n_pending_writes > 0);
ut_a(log_sys->n_pending_writes > 0);
@@ -1148,6 +1150,7 @@ log_group_file_header_flush(
ulint dest_offset;
ut_ad(mutex_own(&(log_sys->mutex)));
+ ut_ad(!recv_no_log_write);
ut_a(nth_file < group->n_files);
buf = *(group->file_header_bufs + nth_file);
@@ -1219,6 +1222,7 @@ log_group_write_buf(
ulint i;
ut_ad(mutex_own(&(log_sys->mutex)));
+ ut_ad(!recv_no_log_write);
ut_a(len % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_a(((ulint) start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
@@ -1361,6 +1365,7 @@ loop:
#endif
mutex_enter(&(log_sys->mutex));
+ ut_ad(!recv_no_log_write);
if (flush_to_disk
&& log_sys->flushed_to_disk_lsn >= lsn) {
@@ -1974,6 +1979,7 @@ log_checkpoint(
mutex_enter(&(log_sys->mutex));
+ ut_ad(!recv_no_log_write);
oldest_lsn = log_buf_pool_get_oldest_modification();
mutex_exit(&(log_sys->mutex));
@@ -2047,7 +2053,7 @@ log_make_checkpoint_at(
later lsn, if IB_ULONGLONG_MAX, makes
a checkpoint at the latest lsn */
ibool write_always) /*!< in: the function normally checks if
- the the new checkpoint would have a
+ the new checkpoint would have a
greater lsn than the previous one: if
not, then no physical write is done;
by setting this parameter TRUE, a
@@ -2086,6 +2092,7 @@ loop:
do_checkpoint = FALSE;
mutex_enter(&(log->mutex));
+ ut_ad(!recv_no_log_write);
if (log->check_flush_or_checkpoint == FALSE) {
mutex_exit(&(log->mutex));
@@ -3035,6 +3042,7 @@ loop:
#endif /* UNIV_LOG_ARCHIVE */
mutex_enter(&(log_sys->mutex));
+ ut_ad(!recv_no_log_write);
if (log_sys->check_flush_or_checkpoint) {
@@ -3234,6 +3242,7 @@ loop:
ut_a(lsn == log_sys->lsn);
}
+#ifdef UNIV_LOG_DEBUG
/******************************************************//**
Checks by parsing that the catenated log segment for a single mtr is
consistent. */
@@ -3241,7 +3250,7 @@ UNIV_INTERN
ibool
log_check_log_recs(
/*===============*/
- byte* buf, /*!< in: pointer to the start of
+ const byte* buf, /*!< in: pointer to the start of
the log segment in the
log_sys->buf log buffer */
ulint len, /*!< in: segment length in bytes */
@@ -3249,8 +3258,8 @@ log_check_log_recs(
{
ib_uint64_t contiguous_lsn;
ib_uint64_t scanned_lsn;
- byte* start;
- byte* end;
+ const byte* start;
+ const byte* end;
byte* buf1;
byte* scan_buf;
@@ -3283,6 +3292,7 @@ log_check_log_recs(
return(TRUE);
}
+#endif /* UNIV_LOG_DEBUG */
/******************************************************//**
Peeks the current lsn.
diff --git a/storage/innodb_plugin/log/log0recv.c b/storage/innodb_plugin/log/log0recv.c
index aea29c78517..81dcc9cd4f8 100644
--- a/storage/innodb_plugin/log/log0recv.c
+++ b/storage/innodb_plugin/log/log0recv.c
@@ -78,6 +78,11 @@ UNIV_INTERN ibool recv_recovery_from_backup_on = FALSE;
#ifndef UNIV_HOTBACKUP
/** TRUE when recv_init_crash_recovery() has been called. */
UNIV_INTERN ibool recv_needed_recovery = FALSE;
+# ifdef UNIV_DEBUG
+/** TRUE if writing to the redo log (mtr_commit) is forbidden.
+Protected by log_sys->mutex. */
+UNIV_INTERN ibool recv_no_log_write = FALSE;
+# endif /* UNIV_DEBUG */
/** TRUE if buf_page_is_corrupted() should check if the log sequence
number (FIL_PAGE_LSN) is in the future. Initially FALSE, and set by
@@ -853,6 +858,11 @@ recv_parse_or_apply_log_rec_body(
}
switch (type) {
+#ifdef UNIV_LOG_LSN_DEBUG
+ case MLOG_LSN:
+ /* The LSN is checked in recv_parse_log_rec(). */
+ break;
+#endif /* UNIV_LOG_LSN_DEBUG */
case MLOG_1BYTE: case MLOG_2BYTES: case MLOG_4BYTES: case MLOG_8BYTES:
#ifdef UNIV_DEBUG
if (page && page_type == FIL_PAGE_TYPE_ALLOCATED
@@ -1269,7 +1279,7 @@ recv_add_to_hash_table(
sizeof(recv_data_t) + len);
*prev_field = recv_data;
- ut_memcpy(((byte*)recv_data) + sizeof(recv_data_t), body, len);
+ memcpy(recv_data + 1, body, len);
prev_field = &(recv_data->next);
@@ -1327,6 +1337,7 @@ recv_recover_page_func(
buf_block_t* block) /*!< in/out: buffer block */
{
page_t* page;
+ page_zip_des_t* page_zip;
recv_addr_t* recv_addr;
recv_t* recv;
byte* buf;
@@ -1376,6 +1387,7 @@ recv_recover_page_func(
mtr_set_log_mode(&mtr, MTR_LOG_NONE);
page = block->frame;
+ page_zip = buf_block_get_page_zip(block);
#ifndef UNIV_HOTBACKUP
if (just_read_in) {
@@ -1436,13 +1448,19 @@ recv_recover_page_func(
if (recv->type == MLOG_INIT_FILE_PAGE) {
page_lsn = page_newest_lsn;
- mach_write_ull(page + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN_OLD_CHKSUM, 0);
- mach_write_ull(page + FIL_PAGE_LSN, 0);
+ memset(FIL_PAGE_LSN + page, 0, 8);
+ memset(UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM
+ + page, 0, 8);
+
+ if (page_zip) {
+ memset(FIL_PAGE_LSN + page_zip->data, 0, 8);
+ }
}
if (recv->start_lsn >= page_lsn) {
+ ib_uint64_t end_lsn;
+
if (!modification_to_page) {
modification_to_page = TRUE;
@@ -1464,11 +1482,17 @@ recv_recover_page_func(
recv_parse_or_apply_log_rec_body(recv->type, buf,
buf + recv->len,
block, &mtr);
- mach_write_ull(page + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN_OLD_CHKSUM,
- recv->start_lsn + recv->len);
- mach_write_ull(page + FIL_PAGE_LSN,
- recv->start_lsn + recv->len);
+
+ end_lsn = recv->start_lsn + recv->len;
+ mach_write_ull(FIL_PAGE_LSN + page, end_lsn);
+ mach_write_ull(UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM
+ + page, end_lsn);
+
+ if (page_zip) {
+ mach_write_ull(FIL_PAGE_LSN
+ + page_zip->data, end_lsn);
+ }
}
if (recv->len > RECV_DATA_BLOCK_SIZE) {
@@ -1686,6 +1710,7 @@ loop:
/* Flush all the file pages to disk and invalidate them in
the buffer pool */
+ ut_d(recv_no_log_write = TRUE);
mutex_exit(&(recv_sys->mutex));
mutex_exit(&(log_sys->mutex));
@@ -1699,6 +1724,7 @@ loop:
mutex_enter(&(log_sys->mutex));
mutex_enter(&(recv_sys->mutex));
+ ut_d(recv_no_log_write = FALSE);
recv_no_ibuf_operations = FALSE;
}
@@ -1910,6 +1936,17 @@ recv_parse_log_rec(
return(0);
}
+#ifdef UNIV_LOG_LSN_DEBUG
+ if (*type == MLOG_LSN) {
+ ib_uint64_t lsn = (ib_uint64_t) *space << 32 | *page_no;
+# ifdef UNIV_LOG_DEBUG
+ ut_a(lsn == log_sys->old_lsn);
+# else /* UNIV_LOG_DEBUG */
+ ut_a(lsn == recv_sys->recovered_lsn);
+# endif /* UNIV_LOG_DEBUG */
+ }
+#endif /* UNIV_LOG_LSN_DEBUG */
+
/* Check that page_no is sensible */
if (UNIV_UNLIKELY(*page_no > 0x8FFFFFFFUL)) {
@@ -2167,6 +2204,12 @@ loop:
#endif
/* In normal mysqld crash recovery we do not try to
replay file operations */
+#ifdef UNIV_LOG_LSN_DEBUG
+ } else if (type == MLOG_LSN) {
+ /* Do not add these records to the hash table.
+ The page number and space id fields are misused
+ for something else. */
+#endif /* UNIV_LOG_LSN_DEBUG */
} else {
recv_add_to_hash_table(type, space, page_no, body,
ptr + len, old_lsn,
@@ -2198,11 +2241,11 @@ loop:
= recv_sys->recovered_offset + total_len;
recv_previous_parsed_rec_is_multi = 1;
- if ((!store_to_hash) && (type != MLOG_MULTI_REC_END)) {
#ifdef UNIV_LOG_DEBUG
+ if ((!store_to_hash) && (type != MLOG_MULTI_REC_END)) {
recv_check_incomplete_log_recs(ptr, len);
-#endif /* UNIV_LOG_DEBUG */
}
+#endif /* UNIV_LOG_DEBUG */
#ifdef UNIV_DEBUG
if (log_debug_writes) {
@@ -2266,7 +2309,11 @@ loop:
break;
}
- if (store_to_hash) {
+ if (store_to_hash
+#ifdef UNIV_LOG_LSN_DEBUG
+ && type != MLOG_LSN
+#endif /* UNIV_LOG_LSN_DEBUG */
+ ) {
recv_add_to_hash_table(type, space, page_no,
body, ptr + len,
old_lsn,
@@ -2415,8 +2462,7 @@ recv_scan_log_recs(
scanned_lsn = start_lsn;
more_data = FALSE;
- while (log_block < buf + len && !finished) {
-
+ do {
no = log_block_get_hdr_no(log_block);
/*
fprintf(stderr, "Log block header no %lu\n", no);
@@ -2546,10 +2592,11 @@ recv_scan_log_recs(
/* Log data for this group ends here */
finished = TRUE;
+ break;
} else {
log_block += OS_FILE_LOG_BLOCK_SIZE;
}
- }
+ } while (log_block < buf + len && !finished);
*group_scanned_lsn = scanned_lsn;
@@ -3104,6 +3151,11 @@ recv_recovery_from_checkpoint_finish(void)
#ifndef UNIV_LOG_DEBUG
recv_sys_free();
#endif
+ /* Roll back any recovered data dictionary transactions, so
+ that the data dictionary tables will be free of any locks.
+ The data dictionary latch should guarantee that there is at
+ most one data dictionary transaction active at a time. */
+ trx_rollback_or_clean_recovered(FALSE);
/* Drop partially created indexes. */
row_merge_drop_temp_indexes();
diff --git a/storage/innodb_plugin/mem/mem0mem.c b/storage/innodb_plugin/mem/mem0mem.c
index e0dc8716f13..ccb2fd8a7b4 100644
--- a/storage/innodb_plugin/mem/mem0mem.c
+++ b/storage/innodb_plugin/mem/mem0mem.c
@@ -475,16 +475,18 @@ mem_heap_block_free(
len = block->len;
block->magic_n = MEM_FREED_BLOCK_MAGIC_N;
+#ifndef UNIV_HOTBACKUP
+ if (!srv_use_sys_malloc) {
#ifdef UNIV_MEM_DEBUG
- /* In the debug version we set the memory to a random combination
- of hex 0xDE and 0xAD. */
+ /* In the debug version we set the memory to a random
+ combination of hex 0xDE and 0xAD. */
- mem_erase_buf((byte*)block, len);
+ mem_erase_buf((byte*)block, len);
#else /* UNIV_MEM_DEBUG */
- UNIV_MEM_ASSERT_AND_FREE(block, len);
+ UNIV_MEM_ASSERT_AND_FREE(block, len);
#endif /* UNIV_MEM_DEBUG */
-#ifndef UNIV_HOTBACKUP
+ }
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
ut_ad(!buf_block);
@@ -495,6 +497,14 @@ mem_heap_block_free(
buf_block_free(buf_block);
}
#else /* !UNIV_HOTBACKUP */
+#ifdef UNIV_MEM_DEBUG
+ /* In the debug version we set the memory to a random
+ combination of hex 0xDE and 0xAD. */
+
+ mem_erase_buf((byte*)block, len);
+#else /* UNIV_MEM_DEBUG */
+ UNIV_MEM_ASSERT_AND_FREE(block, len);
+#endif /* UNIV_MEM_DEBUG */
ut_free(block);
#endif /* !UNIV_HOTBACKUP */
}
diff --git a/storage/innodb_plugin/mtr/mtr0mtr.c b/storage/innodb_plugin/mtr/mtr0mtr.c
index be31c5df801..417e97732bb 100644
--- a/storage/innodb_plugin/mtr/mtr0mtr.c
+++ b/storage/innodb_plugin/mtr/mtr0mtr.c
@@ -35,6 +35,7 @@ Created 11/26/1995 Heikki Tuuri
#include "log0log.h"
#ifndef UNIV_HOTBACKUP
+# include "log0recv.h"
/*****************************************************************//**
Releases the item in the slot given. */
UNIV_INLINE
@@ -115,7 +116,6 @@ mtr_log_reserve_and_write(
dyn_array_t* mlog;
dyn_block_t* block;
ulint data_size;
- ibool success;
byte* first_data;
ut_ad(mtr);
@@ -134,8 +134,8 @@ mtr_log_reserve_and_write(
if (mlog->heap == NULL) {
mtr->end_lsn = log_reserve_and_write_fast(
first_data, dyn_block_get_used(mlog),
- &(mtr->start_lsn), &success);
- if (success) {
+ &mtr->start_lsn);
+ if (mtr->end_lsn) {
return;
}
@@ -182,6 +182,8 @@ mtr_commit(
ut_d(mtr->state = MTR_COMMITTING);
#ifndef UNIV_HOTBACKUP
+ /* This is a dirty read, for debugging. */
+ ut_ad(!recv_no_log_write);
write_log = mtr->modifications && mtr->n_log_recs;
if (write_log) {
diff --git a/storage/innodb_plugin/mysql-test/innodb-analyze.test b/storage/innodb_plugin/mysql-test/innodb-analyze.test
index d5d6d698170..9bdb9db697c 100644
--- a/storage/innodb_plugin/mysql-test/innodb-analyze.test
+++ b/storage/innodb_plugin/mysql-test/innodb-analyze.test
@@ -11,6 +11,7 @@
-- disable_result_log
-- enable_warnings
+let $sample_pages=`select @@innodb_stats_sample_pages`;
SET GLOBAL innodb_stats_sample_pages=0;
# check that the value has been adjusted to 1
@@ -61,3 +62,4 @@ SET GLOBAL innodb_stats_sample_pages=16;
ANALYZE TABLE innodb_analyze;
DROP TABLE innodb_analyze;
+EVAL SET GLOBAL innodb_stats_sample_pages=$sample_pages;
diff --git a/storage/innodb_plugin/mysql-test/innodb-consistent-master.opt b/storage/innodb_plugin/mysql-test/innodb-consistent-master.opt
new file mode 100644
index 00000000000..8cca44767da
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb-consistent-master.opt
@@ -0,0 +1 @@
+--innodb_lock_wait_timeout=2
diff --git a/storage/innodb_plugin/mysql-test/innodb-consistent.result b/storage/innodb_plugin/mysql-test/innodb-consistent.result
new file mode 100644
index 00000000000..9115791b99c
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb-consistent.result
@@ -0,0 +1,35 @@
+drop table if exists t1;
+set session transaction isolation level read committed;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+create table t2 like t1;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7);
+set autocommit=0;
+begin;
+replace into t1 select * from t2;
+set session transaction isolation level read committed;
+set autocommit=0;
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+commit;
+begin;
+insert into t1 select * from t2;
+set session transaction isolation level read committed;
+set autocommit=0;
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+commit;
+select * from t1;
+a
+1
+2
+3
+4
+5
+6
+7
+drop table t1;
+drop table t2;
diff --git a/storage/innodb_plugin/mysql-test/innodb-consistent.test b/storage/innodb_plugin/mysql-test/innodb-consistent.test
new file mode 100644
index 00000000000..791600fc8a7
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb-consistent.test
@@ -0,0 +1,58 @@
+-- source include/not_embedded.inc
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+# REPLACE INTO ... SELECT and INSERT INTO ... SELECT should do
+# a consistent read of the source table.
+
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+connection a;
+set session transaction isolation level read committed;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+create table t2 like t1;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7);
+set autocommit=0;
+
+# REPLACE INTO ... SELECT case
+begin;
+# this should not result in any locks on t2.
+replace into t1 select * from t2;
+
+connection b;
+set session transaction isolation level read committed;
+set autocommit=0;
+# should not cuase a lock wait.
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+connection a;
+commit;
+
+# INSERT INTO ... SELECT case
+begin;
+# this should not result in any locks on t2.
+insert into t1 select * from t2;
+
+connection b;
+set session transaction isolation level read committed;
+set autocommit=0;
+# should not cuase a lock wait.
+delete from t2 where a=5;
+commit;
+delete from t2;
+commit;
+connection a;
+commit;
+
+select * from t1;
+drop table t1;
+drop table t2;
+
+connection default;
+disconnect a;
+disconnect b;
diff --git a/storage/innodb_plugin/mysql-test/innodb-zip.result b/storage/innodb_plugin/mysql-test/innodb-zip.result
index c81401743a5..b26c4112826 100644
--- a/storage/innodb_plugin/mysql-test/innodb-zip.result
+++ b/storage/innodb_plugin/mysql-test/innodb-zip.result
@@ -141,7 +141,7 @@ drop table t1;
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440)))
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
-CREATE TABLE t1(c TEXT, PRIMARY KEY (c(439)))
+CREATE TABLE t1(c TEXT, PRIMARY KEY (c(438)))
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512));
DROP TABLE t1;
diff --git a/storage/innodb_plugin/mysql-test/innodb-zip.test b/storage/innodb_plugin/mysql-test/innodb-zip.test
index ddc39d44487..5bcd0e3c824 100644
--- a/storage/innodb_plugin/mysql-test/innodb-zip.test
+++ b/storage/innodb_plugin/mysql-test/innodb-zip.test
@@ -105,7 +105,7 @@ drop table t1;
--error ER_TOO_BIG_ROWSIZE
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440)))
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
-CREATE TABLE t1(c TEXT, PRIMARY KEY (c(439)))
+CREATE TABLE t1(c TEXT, PRIMARY KEY (c(438)))
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512));
DROP TABLE t1;
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug34300.test b/storage/innodb_plugin/mysql-test/innodb_bug34300.test
index 114bcf98c25..68c385fd72a 100644
--- a/storage/innodb_plugin/mysql-test/innodb_bug34300.test
+++ b/storage/innodb_plugin/mysql-test/innodb_bug34300.test
@@ -9,6 +9,7 @@
-- disable_result_log
# set packet size and reconnect
+let $max_packet=`select @@global.max_allowed_packet`;
SET @@global.max_allowed_packet=16777216;
--connect (newconn, localhost, root,,)
@@ -30,3 +31,4 @@ ALTER TABLE bug34300 ADD COLUMN (f10 INT);
SELECT f4, f8 FROM bug34300;
DROP TABLE bug34300;
+EVAL SET @@global.max_allowed_packet=$max_packet;
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug36169.test b/storage/innodb_plugin/mysql-test/innodb_bug36169.test
index d3566d3eb39..5bf55193b5c 100644
--- a/storage/innodb_plugin/mysql-test/innodb_bug36169.test
+++ b/storage/innodb_plugin/mysql-test/innodb_bug36169.test
@@ -5,6 +5,8 @@
-- source include/have_innodb.inc
+let $file_format=`select @@innodb_file_format`;
+let $file_per_table=`select @@innodb_file_per_table`;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON;
@@ -1153,3 +1155,5 @@ DROP TABLE IF EXISTS table4;
DROP TABLE IF EXISTS table5;
DROP TABLE IF EXISTS table6;
+EVAL SET GLOBAL innodb_file_format=$file_format;
+EVAL SET GLOBAL innodb_file_per_table=$file_per_table;
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug36172.test b/storage/innodb_plugin/mysql-test/innodb_bug36172.test
index 666d4a2f4b7..c6c4e6fae47 100644
--- a/storage/innodb_plugin/mysql-test/innodb_bug36172.test
+++ b/storage/innodb_plugin/mysql-test/innodb_bug36172.test
@@ -14,6 +14,9 @@ SET storage_engine=InnoDB;
-- disable_query_log
-- disable_result_log
+let $file_format=`select @@innodb_file_format`;
+let $file_format_check=`select @@innodb_file_format_check`;
+let $file_per_table=`select @@innodb_file_per_table`;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=on;
@@ -24,3 +27,6 @@ CHECK TABLE table0 EXTENDED;
INSERT IGNORE INTO `table0` SET `col19` = '19940127002709', `col20` = 2383927.9055146948, `col21` = 4293243420.5621204000, `col22` = '20511211123705', `col23` = 4289899778.6573381000, `col24` = 4293449279.0540481000, `col25` = 'emphysemic', `col26` = 'dentally', `col27` = '2347406', `col28` = 'eruct', `col30` = 1222, `col31` = 4294372994.9941406000, `col32` = 4291385574.1173744000, `col33` = 'borrowing\'s', `col34` = 'septics', `col35` = 'ratter\'s', `col36` = 'Kaye', `col37` = 'Florentia', `col38` = 'allium', `col39` = 'barkeep', `col40` = '19510407003441', `col41` = 4293559200.4215522000, `col42` = 22482, `col43` = 'decussate', `col44` = 'Brom\'s', `col45` = 'violated', `col46` = 4925506.4635456400, `col47` = 930549, `col48` = '51296066', `col49` = 'voluminously', `col50` = '29306676', `col51` = -88, `col52` = -2153690, `col53` = 4290250202.1464887000, `col54` = 'expropriation', `col55` = 'Aberdeen\'s', `col56` = 20343, `col58` = '19640415171532', `col59` = 'extern', `col60` = 'Ubana', `col61` = 4290487961.8539081000, `col62` = '2147', `col63` = -24271, `col64` = '20750801194548', `col65` = 'Cunaxa\'s', `col66` = 'pasticcio', `col67` = 2795817, `col68` = 'Indore\'s', `col70` = 6864127, `col71` = '1817832', `col72` = '20540506114211', `col73` = '20040101012300', `col74` = 'rationalized', `col75` = '45522', `col76` = 'indene', `col77` = -6964559, `col78` = 4247535.5266884370, `col79` = '20720416124357', `col80` = '2143', `col81` = 4292060102.4466386000, `col82` = 'striving', `col83` = 'boneblack\'s', `col84` = 'redolent', `col85` = 6489697.9009369183, `col86` = 4287473465.9731131000, `col87` = 7726015, `col88` = 'perplexed', `col89` = '17153791', `col90` = 5478587.1108127078, `col91` = 4287091404.7004304000, `col92` = 'Boulez\'s', `col93` = '2931278';
CHECK TABLE table0 EXTENDED;
DROP TABLE table0;
+EVAL SET GLOBAL innodb_file_format=$file_format;
+EVAL SET GLOBAL innodb_file_format_check=$file_format_check;
+EVAL SET GLOBAL innodb_file_per_table=$file_per_table;
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug44369.result b/storage/innodb_plugin/mysql-test/innodb_bug44369.result
new file mode 100644
index 00000000000..e4b84ecac19
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb_bug44369.result
@@ -0,0 +1,14 @@
+create table bug44369 (DB_ROW_ID int) engine=innodb;
+ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
+create table bug44369 (db_row_id int) engine=innodb;
+ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
+show errors;
+Level Code Message
+Error 1005 Error creating table 'test/bug44369' with column name 'db_row_id'. 'db_row_id' is a reserved name. Please try to re-create the table with a different column name.
+Error 1005 Can't create table 'test.bug44369' (errno: -1)
+create table bug44369 (db_TRX_Id int) engine=innodb;
+ERROR HY000: Can't create table 'test.bug44369' (errno: -1)
+show errors;
+Level Code Message
+Error 1005 Error creating table 'test/bug44369' with column name 'db_TRX_Id'. 'db_TRX_Id' is a reserved name. Please try to re-create the table with a different column name.
+Error 1005 Can't create table 'test.bug44369' (errno: -1)
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug44369.test b/storage/innodb_plugin/mysql-test/innodb_bug44369.test
new file mode 100644
index 00000000000..495059eb5e6
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb_bug44369.test
@@ -0,0 +1,21 @@
+# This is the test for bug 44369. We should
+# block table creation with columns match
+# some innodb internal reserved key words,
+# both case sensitively and insensitely.
+
+--source include/have_innodb.inc
+
+# This create table operation should fail.
+--error ER_CANT_CREATE_TABLE
+create table bug44369 (DB_ROW_ID int) engine=innodb;
+
+# This create should fail as well
+--error ER_CANT_CREATE_TABLE
+create table bug44369 (db_row_id int) engine=innodb;
+
+show errors;
+
+--error ER_CANT_CREATE_TABLE
+create table bug44369 (db_TRX_Id int) engine=innodb;
+
+show errors;
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug44571.result b/storage/innodb_plugin/mysql-test/innodb_bug44571.result
new file mode 100644
index 00000000000..36374edcb3e
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb_bug44571.result
@@ -0,0 +1,9 @@
+CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
+ALTER TABLE bug44571 CHANGE foo bar INT;
+ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
+ERROR 42000: Key column 'foo' doesn't exist in table
+ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
+ERROR HY000: Incorrect key file for table 'bug44571'; try to repair it
+CREATE INDEX bug44571b ON bug44571 (bar);
+ERROR HY000: Incorrect key file for table 'bug44571'; try to repair it
+DROP TABLE bug44571;
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug44571.test b/storage/innodb_plugin/mysql-test/innodb_bug44571.test
new file mode 100644
index 00000000000..685463ceff9
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb_bug44571.test
@@ -0,0 +1,17 @@
+#
+# Bug#44571 InnoDB Plugin crashes on ADD INDEX
+# http://bugs.mysql.com/44571
+#
+-- source include/have_innodb.inc
+
+CREATE TABLE bug44571 (foo INT) ENGINE=InnoDB;
+ALTER TABLE bug44571 CHANGE foo bar INT;
+-- error ER_KEY_COLUMN_DOES_NOT_EXITS
+ALTER TABLE bug44571 ADD INDEX bug44571b (foo);
+# The following will fail, because the CHANGE foo bar was
+# not communicated to InnoDB.
+--error ER_NOT_KEYFILE
+ALTER TABLE bug44571 ADD INDEX bug44571b (bar);
+--error ER_NOT_KEYFILE
+CREATE INDEX bug44571b ON bug44571 (bar);
+DROP TABLE bug44571;
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug46000.result b/storage/innodb_plugin/mysql-test/innodb_bug46000.result
new file mode 100644
index 00000000000..ccff888a48d
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb_bug46000.result
@@ -0,0 +1,17 @@
+create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb;
+ERROR HY000: Can't create table 'test.bug46000' (errno: -1)
+create table bug46000(`id` int, key `GEN_clust_INDEX`(`id`))engine=innodb;
+ERROR HY000: Can't create table 'test.bug46000' (errno: -1)
+show errors;
+Level Code Message
+Error 1005 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index.
+Error 1005 Can't create table 'test.bug46000' (errno: -1)
+create table bug46000(id int) engine=innodb;
+create index GEN_CLUST_INDEX on bug46000(id);
+ERROR HY000: Can't create table '#sql-temporary' (errno: -1)
+show errors;
+Level Code Message
+Error 1005 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index.
+Error 1005 Can't create table '#sql-temporary' (errno: -1)
+create index idx on bug46000(id);
+drop table bug46000;
diff --git a/storage/innodb_plugin/mysql-test/innodb_bug46000.test b/storage/innodb_plugin/mysql-test/innodb_bug46000.test
new file mode 100644
index 00000000000..80c18c58ef0
--- /dev/null
+++ b/storage/innodb_plugin/mysql-test/innodb_bug46000.test
@@ -0,0 +1,34 @@
+# This is the test for bug 46000. We shall
+# block any index creation with the name of
+# "GEN_CLUST_INDEX", which is the reserved
+# name for innodb default primary index.
+
+--source include/have_innodb.inc
+
+# This 'create table' operation should fail because of
+# using the reserve name as its index name.
+--error ER_CANT_CREATE_TABLE
+create table bug46000(`id` int,key `GEN_CLUST_INDEX`(`id`))engine=innodb;
+
+# Mixed upper/lower case of the reserved key words
+--error ER_CANT_CREATE_TABLE
+create table bug46000(`id` int, key `GEN_clust_INDEX`(`id`))engine=innodb;
+
+show errors;
+
+create table bug46000(id int) engine=innodb;
+
+# This 'create index' operation should fail.
+--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
+--error ER_CANT_CREATE_TABLE
+create index GEN_CLUST_INDEX on bug46000(id);
+
+--replace_regex /'[^']*test.#sql-[0-9a-f_]*'/'#sql-temporary'/
+show errors;
+
+# This 'create index' operation should succeed, no
+# temp table left from last failed create index
+# operation.
+create index idx on bug46000(id);
+
+drop table bug46000;
diff --git a/storage/innodb_plugin/mysql-test/innodb_file_format.result b/storage/innodb_plugin/mysql-test/innodb_file_format.result
index 9cfac5f001c..8e9a317308b 100644
--- a/storage/innodb_plugin/mysql-test/innodb_file_format.result
+++ b/storage/innodb_plugin/mysql-test/innodb_file_format.result
@@ -42,3 +42,4 @@ ERROR HY000: Incorrect arguments to SET
select @@innodb_file_format_check;
@@innodb_file_format_check
Barracuda
+set global innodb_file_format_check=antelope;
diff --git a/storage/innodb_plugin/mysql-test/innodb_file_format.test b/storage/innodb_plugin/mysql-test/innodb_file_format.test
index 62ce4157183..d63c9b0228f 100644
--- a/storage/innodb_plugin/mysql-test/innodb_file_format.test
+++ b/storage/innodb_plugin/mysql-test/innodb_file_format.test
@@ -26,3 +26,4 @@ set global innodb_file_format=on;
--error ER_WRONG_ARGUMENTS
set global innodb_file_format=off;
select @@innodb_file_format_check;
+set global innodb_file_format_check=antelope;
diff --git a/storage/innodb_plugin/os/os0file.c b/storage/innodb_plugin/os/os0file.c
index d3bd6465f5f..0cb76d1796f 100644
--- a/storage/innodb_plugin/os/os0file.c
+++ b/storage/innodb_plugin/os/os0file.c
@@ -88,7 +88,9 @@ UNIV_INTERN ibool os_do_not_call_flush_at_each_write = FALSE;
/* We do not call os_file_flush in every os_file_write. */
#endif /* UNIV_DO_FLUSH */
-#ifndef UNIV_HOTBACKUP
+#ifdef UNIV_HOTBACKUP
+# define os_aio_use_native_aio FALSE
+#else /* UNIV_HOTBACKUP */
/* We use these mutexes to protect lseek + file i/o operation, if the
OS does not provide an atomic pread or pwrite, or similar */
#define OS_FILE_N_SEEK_MUTEXES 16
@@ -198,7 +200,7 @@ static ulint os_aio_n_segments = ULINT_UNDEFINED;
/** If the following is TRUE, read i/o handler threads try to
wait until a batch of new read requests have been posted */
static ibool os_aio_recommend_sleep_for_read_threads = FALSE;
-#endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_HOTBACKUP */
UNIV_INTERN ulint os_n_file_reads = 0;
UNIV_INTERN ulint os_bytes_read_since_printout = 0;
@@ -315,6 +317,12 @@ os_file_get_last_error(
" software or another instance\n"
"InnoDB: of MySQL."
" Please close it to get rid of this error.\n");
+ } else if (err == ERROR_WORKING_SET_QUOTA
+ || err == ERROR_NO_SYSTEM_RESOURCES) {
+ fprintf(stderr,
+ "InnoDB: The error means that there are no"
+ " sufficient system resources or quota to"
+ " complete the operation.\n");
} else {
fprintf(stderr,
"InnoDB: Some operating system error numbers"
@@ -336,6 +344,9 @@ os_file_get_last_error(
} else if (err == ERROR_SHARING_VIOLATION
|| err == ERROR_LOCK_VIOLATION) {
return(OS_FILE_SHARING_VIOLATION);
+ } else if (err == ERROR_WORKING_SET_QUOTA
+ || err == ERROR_NO_SYSTEM_RESOURCES) {
+ return(OS_FILE_INSUFFICIENT_RESOURCE);
} else {
return(100 + err);
}
@@ -454,6 +465,10 @@ os_file_handle_error_cond_exit(
os_thread_sleep(10000000); /* 10 sec */
return(TRUE);
+ } else if (err == OS_FILE_INSUFFICIENT_RESOURCE) {
+
+ os_thread_sleep(100000); /* 100 ms */
+ return(TRUE);
} else {
if (name) {
fprintf(stderr, "InnoDB: File name %s\n", name);
@@ -817,6 +832,23 @@ next_file:
ret = stat(full_path, &statinfo);
if (ret) {
+
+ if (errno == ENOENT) {
+ /* readdir() returned a file that does not exist,
+ it must have been deleted in the meantime. Do what
+ would have happened if the file was deleted before
+ readdir() - ignore and go to the next entry.
+ If this is the last entry then info->name will still
+ contain the name of the deleted file when this
+ function returns, but this is not an issue since the
+ caller shouldn't be looking at info when end of
+ directory is returned. */
+
+ ut_free(full_path);
+
+ goto next_file;
+ }
+
os_file_handle_error_no_exit(full_path, "stat");
ut_free(full_path);
@@ -1245,6 +1277,7 @@ try_again:
}
#endif
#ifdef UNIV_NON_BUFFERED_IO
+# ifndef UNIV_HOTBACKUP
if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
/* Do not use unbuffered i/o to log files because
value 2 denotes that we do not flush the log at every
@@ -1253,10 +1286,14 @@ try_again:
== SRV_WIN_IO_UNBUFFERED) {
attributes = attributes | FILE_FLAG_NO_BUFFERING;
}
-#endif
+# else /* !UNIV_HOTBACKUP */
+ attributes = attributes | FILE_FLAG_NO_BUFFERING;
+# endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_NON_BUFFERED_IO */
} else if (purpose == OS_FILE_NORMAL) {
attributes = 0;
#ifdef UNIV_NON_BUFFERED_IO
+# ifndef UNIV_HOTBACKUP
if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
/* Do not use unbuffered i/o to log files because
value 2 denotes that we do not flush the log at every
@@ -1265,7 +1302,10 @@ try_again:
== SRV_WIN_IO_UNBUFFERED) {
attributes = attributes | FILE_FLAG_NO_BUFFERING;
}
-#endif
+# else /* !UNIV_HOTBACKUP */
+ attributes = attributes | FILE_FLAG_NO_BUFFERING;
+# endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_NON_BUFFERED_IO */
} else {
attributes = 0;
ut_error;
@@ -2022,7 +2062,9 @@ os_file_pread(
offset */
{
off_t offs;
+#if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
ssize_t n_bytes;
+#endif /* HAVE_PREAD && !HAVE_BROKEN_PREAD */
ut_a((offset & 0xFFFFFFFFUL) == offset);
@@ -2061,16 +2103,20 @@ os_file_pread(
{
off_t ret_offset;
ssize_t ret;
+#ifndef UNIV_HOTBACKUP
ulint i;
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
+#ifndef UNIV_HOTBACKUP
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
ret_offset = lseek(file, offs, SEEK_SET);
@@ -2080,7 +2126,9 @@ os_file_pread(
ret = read(file, buf, (ssize_t)n);
}
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
@@ -2158,16 +2206,20 @@ os_file_pwrite(
#else
{
off_t ret_offset;
+# ifndef UNIV_HOTBACKUP
ulint i;
+# endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes++;
os_mutex_exit(os_file_count_mutex);
+# ifndef UNIV_HOTBACKUP
/* Protect the seek / write operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
os_mutex_enter(os_file_seek_mutexes[i]);
+# endif /* UNIV_HOTBACKUP */
ret_offset = lseek(file, offs, SEEK_SET);
@@ -2193,7 +2245,9 @@ os_file_pwrite(
# endif /* UNIV_DO_FLUSH */
func_exit:
+# ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+# endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes--;
@@ -2227,7 +2281,9 @@ os_file_read(
DWORD low;
DWORD high;
ibool retry;
+#ifndef UNIV_HOTBACKUP
ulint i;
+#endif /* !UNIV_HOTBACKUP */
ut_a((offset & 0xFFFFFFFFUL) == offset);
@@ -2246,16 +2302,20 @@ try_again:
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
+#ifndef UNIV_HOTBACKUP
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
@@ -2266,7 +2326,9 @@ try_again:
ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
@@ -2275,7 +2337,7 @@ try_again:
if (ret && len == n) {
return(TRUE);
}
-#else
+#else /* __WIN__ */
ibool retry;
ssize_t ret;
@@ -2294,7 +2356,7 @@ try_again:
"InnoDB: Was only able to read %ld.\n",
(ulong)n, (ulong)offset_high,
(ulong)offset, (long)ret);
-#endif
+#endif /* __WIN__ */
#ifdef __WIN__
error_handling:
#endif
@@ -2343,7 +2405,9 @@ os_file_read_no_error_handling(
DWORD low;
DWORD high;
ibool retry;
+#ifndef UNIV_HOTBACKUP
ulint i;
+#endif /* !UNIV_HOTBACKUP */
ut_a((offset & 0xFFFFFFFFUL) == offset);
@@ -2362,16 +2426,20 @@ try_again:
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
+#ifndef UNIV_HOTBACKUP
/* Protect the seek / read operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
@@ -2382,7 +2450,9 @@ try_again:
ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
@@ -2391,7 +2461,7 @@ try_again:
if (ret && len == n) {
return(TRUE);
}
-#else
+#else /* __WIN__ */
ibool retry;
ssize_t ret;
@@ -2404,7 +2474,7 @@ try_again:
return(TRUE);
}
-#endif
+#endif /* __WIN__ */
#ifdef __WIN__
error_handling:
#endif
@@ -2463,9 +2533,11 @@ os_file_write(
DWORD ret2;
DWORD low;
DWORD high;
- ulint i;
ulint n_retries = 0;
ulint err;
+#ifndef UNIV_HOTBACKUP
+ ulint i;
+#endif /* !UNIV_HOTBACKUP */
ut_a((offset & 0xFFFFFFFF) == offset);
@@ -2482,16 +2554,20 @@ retry:
os_n_pending_writes++;
os_mutex_exit(os_file_count_mutex);
+#ifndef UNIV_HOTBACKUP
/* Protect the seek / write operation with a mutex */
i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
os_mutex_enter(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes--;
@@ -2525,7 +2601,9 @@ retry:
}
# endif /* UNIV_DO_FLUSH */
+#ifndef UNIV_HOTBACKUP
os_mutex_exit(os_file_seek_mutexes[i]);
+#endif /* !UNIV_HOTBACKUP */
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes--;
@@ -3371,9 +3449,21 @@ void
os_aio_simulated_put_read_threads_to_sleep(void)
/*============================================*/
{
+
+/* The idea of putting background IO threads to sleep is only for
+Windows when using simulated AIO. Windows XP seems to schedule
+background threads too eagerly to allow for coalescing during
+readahead requests. */
+#ifdef __WIN__
os_aio_array_t* array;
ulint g;
+ if (os_aio_use_native_aio) {
+ /* We do not use simulated aio: do nothing */
+
+ return;
+ }
+
os_aio_recommend_sleep_for_read_threads = TRUE;
for (g = 0; g < os_aio_n_segments; g++) {
@@ -3384,6 +3474,7 @@ os_aio_simulated_put_read_threads_to_sleep(void)
os_event_reset(os_aio_segment_wait_events[g]);
}
}
+#endif /* __WIN__ */
}
/*******************************************************************//**
diff --git a/storage/innodb_plugin/os/os0proc.c b/storage/innodb_plugin/os/os0proc.c
index a0ea9a1b258..48922886f23 100644
--- a/storage/innodb_plugin/os/os0proc.c
+++ b/storage/innodb_plugin/os/os0proc.c
@@ -97,6 +97,7 @@ os_mem_alloc_large(
fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to"
" attach shared memory segment, errno %d\n",
errno);
+ ptr = NULL;
}
/* Remove the shared memory segment so that it will be
diff --git a/storage/innodb_plugin/page/page0cur.c b/storage/innodb_plugin/page/page0cur.c
index 65f3ba67439..f10f16a7dd9 100644
--- a/storage/innodb_plugin/page/page0cur.c
+++ b/storage/innodb_plugin/page/page0cur.c
@@ -1195,7 +1195,7 @@ page_cur_insert_rec_zip_reorg(
}
/* Out of space: restore the page */
- if (!page_zip_decompress(page_zip, page)) {
+ if (!page_zip_decompress(page_zip, page, FALSE)) {
ut_error; /* Memory corrupted? */
}
ut_ad(page_validate(page, index));
diff --git a/storage/innodb_plugin/page/page0page.c b/storage/innodb_plugin/page/page0page.c
index f056ef77bdc..ab2ba60570e 100644
--- a/storage/innodb_plugin/page/page0page.c
+++ b/storage/innodb_plugin/page/page0page.c
@@ -45,7 +45,7 @@ Created 2/2/1994 Heikki Tuuri
==============
The index page consists of a page header which contains the page's
-id and other information. On top of it are the the index records
+id and other information. On top of it are the index records
in a heap linked into a one way linear list according to alphabetic order.
Just below page end is an array of pointers which we call page directory,
@@ -679,7 +679,7 @@ page_copy_rec_list_end(
if (UNIV_UNLIKELY
(!page_zip_decompress(new_page_zip,
- new_page))) {
+ new_page, FALSE))) {
ut_error;
}
ut_ad(page_validate(new_page, index));
@@ -792,7 +792,7 @@ page_copy_rec_list_start(
if (UNIV_UNLIKELY
(!page_zip_decompress(new_page_zip,
- new_page))) {
+ new_page, FALSE))) {
ut_error;
}
ut_ad(page_validate(new_page, index));
diff --git a/storage/innodb_plugin/page/page0zip.c b/storage/innodb_plugin/page/page0zip.c
index 92ba0ec768a..aa5e39ff04a 100644
--- a/storage/innodb_plugin/page/page0zip.c
+++ b/storage/innodb_plugin/page/page0zip.c
@@ -47,8 +47,10 @@ Created June 2005 by Marko Makela
# define buf_LRU_stat_inc_unzip() ((void) 0)
#endif /* !UNIV_HOTBACKUP */
+#ifndef UNIV_HOTBACKUP
/** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */
UNIV_INTERN page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
+#endif /* !UNIV_HOTBACKUP */
/* Please refer to ../include/page0zip.ic for a description of the
compressed page format. */
@@ -1144,7 +1146,9 @@ page_zip_compress(
ulint* offsets = NULL;
ulint n_blobs = 0;
byte* storage;/* storage of uncompressed columns */
+#ifndef UNIV_HOTBACKUP
ullint usec = ut_time_us(NULL);
+#endif /* !UNIV_HOTBACKUP */
#ifdef PAGE_ZIP_COMPRESS_DBG
FILE* logfile = NULL;
#endif
@@ -1208,7 +1212,9 @@ page_zip_compress(
}
}
#endif /* PAGE_ZIP_COMPRESS_DBG */
+#ifndef UNIV_HOTBACKUP
page_zip_stat[page_zip->ssize - 1].compressed++;
+#endif /* !UNIV_HOTBACKUP */
if (UNIV_UNLIKELY(n_dense * PAGE_ZIP_DIR_SLOT_SIZE
>= page_zip_get_size(page_zip))) {
@@ -1345,8 +1351,10 @@ err_exit:
fclose(logfile);
}
#endif /* PAGE_ZIP_COMPRESS_DBG */
+#ifndef UNIV_HOTBACKUP
page_zip_stat[page_zip->ssize - 1].compressed_usec
+= ut_time_us(NULL) - usec;
+#endif /* !UNIV_HOTBACKUP */
return(FALSE);
}
@@ -1404,12 +1412,14 @@ err_exit:
fclose(logfile);
}
#endif /* PAGE_ZIP_COMPRESS_DBG */
+#ifndef UNIV_HOTBACKUP
{
page_zip_stat_t* zip_stat
= &page_zip_stat[page_zip->ssize - 1];
zip_stat->compressed_ok++;
zip_stat->compressed_usec += ut_time_us(NULL) - usec;
}
+#endif /* !UNIV_HOTBACKUP */
return(TRUE);
}
@@ -2811,7 +2821,11 @@ page_zip_decompress(
/*================*/
page_zip_des_t* page_zip,/*!< in: data, ssize;
out: m_start, m_end, m_nonempty, n_blobs */
- page_t* page) /*!< out: uncompressed page, may be trashed */
+ page_t* page, /*!< out: uncompressed page, may be trashed */
+ ibool all) /*!< in: TRUE=decompress the whole page;
+ FALSE=verify but do not copy some
+ page header fields that should not change
+ after page creation */
{
z_stream d_stream;
dict_index_t* index = NULL;
@@ -2820,7 +2834,9 @@ page_zip_decompress(
ulint trx_id_col = ULINT_UNDEFINED;
mem_heap_t* heap;
ulint* offsets;
+#ifndef UNIV_HOTBACKUP
ullint usec = ut_time_us(NULL);
+#endif /* !UNIV_HOTBACKUP */
ut_ad(page_zip_simple_validate(page_zip));
UNIV_MEM_ASSERT_W(page, UNIV_PAGE_SIZE);
@@ -2839,13 +2855,36 @@ page_zip_decompress(
heap = mem_heap_create(n_dense * (3 * sizeof *recs) + UNIV_PAGE_SIZE);
recs = mem_heap_alloc(heap, n_dense * (2 * sizeof *recs));
+ if (all) {
+ /* Copy the page header. */
+ memcpy(page, page_zip->data, PAGE_DATA);
+ } else {
+ /* Check that the bytes that we skip are identical. */
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+ ut_a(!memcmp(FIL_PAGE_TYPE + page,
+ FIL_PAGE_TYPE + page_zip->data,
+ PAGE_HEADER - FIL_PAGE_TYPE));
+ ut_a(!memcmp(PAGE_HEADER + PAGE_LEVEL + page,
+ PAGE_HEADER + PAGE_LEVEL + page_zip->data,
+ PAGE_DATA - (PAGE_HEADER + PAGE_LEVEL)));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+
+ /* Copy the mutable parts of the page header. */
+ memcpy(page, page_zip->data, FIL_PAGE_TYPE);
+ memcpy(PAGE_HEADER + page, PAGE_HEADER + page_zip->data,
+ PAGE_LEVEL - PAGE_N_DIR_SLOTS);
+
+#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+ /* Check that the page headers match after copying. */
+ ut_a(!memcmp(page, page_zip->data, PAGE_DATA));
+#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+ }
+
#ifdef UNIV_ZIP_DEBUG
- /* Clear the page. */
- memset(page, 0x55, UNIV_PAGE_SIZE);
+ /* Clear the uncompressed page, except the header. */
+ memset(PAGE_DATA + page, 0x55, UNIV_PAGE_SIZE - PAGE_DATA);
#endif /* UNIV_ZIP_DEBUG */
- UNIV_MEM_INVALID(page, UNIV_PAGE_SIZE);
- /* Copy the page header. */
- memcpy(page, page_zip->data, PAGE_DATA);
+ UNIV_MEM_INVALID(PAGE_DATA + page, UNIV_PAGE_SIZE - PAGE_DATA);
/* Copy the page directory. */
if (UNIV_UNLIKELY(!page_zip_dir_decode(page_zip, page, recs,
@@ -2976,12 +3015,14 @@ err_exit:
page_zip_fields_free(index);
mem_heap_free(heap);
+#ifndef UNIV_HOTBACKUP
{
page_zip_stat_t* zip_stat
= &page_zip_stat[page_zip->ssize - 1];
zip_stat->decompressed++;
zip_stat->decompressed_usec += ut_time_us(NULL) - usec;
}
+#endif /* !UNIV_HOTBACKUP */
/* Update the stat counter for LRU policy. */
buf_LRU_stat_inc_unzip();
@@ -3084,7 +3125,7 @@ page_zip_validate_low(
#endif /* UNIV_DEBUG_VALGRIND */
temp_page_zip = *page_zip;
- valid = page_zip_decompress(&temp_page_zip, temp_page);
+ valid = page_zip_decompress(&temp_page_zip, temp_page, TRUE);
if (!valid) {
fputs("page_zip_validate(): failed to decompress\n", stderr);
goto func_exit;
@@ -4362,8 +4403,8 @@ IMPORTANT: if page_zip_reorganize() is invoked on a leaf page of a
non-clustered index, the caller must update the insert buffer free
bits in the same mini-transaction in such a way that the modification
will be redo-logged.
-@return TRUE on success, FALSE on failure; page and page_zip will be
-left intact on failure. */
+@return TRUE on success, FALSE on failure; page_zip will be left
+intact on failure, but page will be overwritten. */
UNIV_INTERN
ibool
page_zip_reorganize(
@@ -4428,9 +4469,6 @@ page_zip_reorganize(
if (UNIV_UNLIKELY(!page_zip_compress(page_zip, page, index, mtr))) {
- /* Restore the old page and exit. */
- buf_frame_copy(page, temp_page);
-
#ifndef UNIV_HOTBACKUP
buf_block_free(temp_block);
#endif /* !UNIV_HOTBACKUP */
@@ -4591,7 +4629,8 @@ corrupt:
memcpy(page_zip->data + page_zip_get_size(page_zip)
- trailer_size, ptr + 8 + size, trailer_size);
- if (UNIV_UNLIKELY(!page_zip_decompress(page_zip, page))) {
+ if (UNIV_UNLIKELY(!page_zip_decompress(page_zip, page,
+ TRUE))) {
goto corrupt;
}
diff --git a/storage/innodb_plugin/plug.in.disabled b/storage/innodb_plugin/plug.in.disabled
index 42915ac7426..4ebde50cb35 100644
--- a/storage/innodb_plugin/plug.in.disabled
+++ b/storage/innodb_plugin/plug.in.disabled
@@ -37,33 +37,75 @@ MYSQL_PLUGIN_ACTIONS(innodb_plugin, [
irix*|osf*|sysv5uw7*|openbsd*)
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
*solaris*|*SunOS*)
- # Begin Solaris atomic function checks
- AC_CHECK_FUNCS(atomic_cas_ulong atomic_cas_32 \
- atomic_cas_64 atomic_add_long,
- AC_DEFINE(
- [HAVE_SOLARIS_ATOMICS],
- [1],
- [Define to 1 if Solaris supports \
- atomic functions.]))
- ### End Solaris atomic function checks
-
CFLAGS="$CFLAGS -DUNIV_SOLARIS";;
esac
+
INNODB_DYNAMIC_CFLAGS="-DMYSQL_DYNAMIC_PLUGIN"
- case "$target_cpu---$target_os" in
- x86_64---*)
+
+ case "$target_cpu" in
+ x86_64)
# The AMD64 ABI forbids absolute addresses in shared libraries
;;
- *---solaris*|*---SunOS*)
- # Shared objects must be linked from PIC code on Solaris.
- ;;
- *86---)
+ *86)
# Use absolute addresses on IA-32
INNODB_DYNAMIC_CFLAGS="$INNODB_DYNAMIC_CFLAGS -prefer-non-pic"
;;
esac
AC_SUBST(INNODB_DYNAMIC_CFLAGS)
+
+ AC_MSG_CHECKING(whether GCC atomic builtins are available)
+ # either define HAVE_IB_GCC_ATOMIC_BUILTINS or not
+ AC_TRY_RUN(
+ [
+ int main()
+ {
+ 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);
+ }
+ ],
+ [
+ AC_DEFINE([HAVE_IB_GCC_ATOMIC_BUILTINS], [1],
+ [GCC atomic builtins are available])
+ AC_MSG_RESULT(yes)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ]
+ )
+
AC_MSG_CHECKING(whether pthread_t can be used by GCC atomic builtins)
+ # either define HAVE_IB_ATOMIC_PTHREAD_T_GCC or not
AC_TRY_RUN(
[
#include <pthread.h>
@@ -84,47 +126,73 @@ MYSQL_PLUGIN_ACTIONS(innodb_plugin, [
}
],
[
- AC_DEFINE([HAVE_ATOMIC_PTHREAD_T], [1],
+ AC_DEFINE([HAVE_IB_ATOMIC_PTHREAD_T_GCC], [1],
[pthread_t can be used by GCC atomic builtins])
AC_MSG_RESULT(yes)
],
[
AC_MSG_RESULT(no)
]
- )
+ )
- # Try using solaris atomics on SunOS if GCC atomics are not available
- AC_CHECK_DECLS(
- [HAVE_ATOMIC_PTHREAD_T],
+ AC_MSG_CHECKING(whether Solaris libc atomic functions are available)
+ # either define HAVE_IB_SOLARIS_ATOMICS or not
+ AC_CHECK_FUNCS(atomic_add_long \
+ atomic_cas_32 \
+ atomic_cas_64 \
+ atomic_cas_ulong,
+
+ AC_DEFINE([HAVE_IB_SOLARIS_ATOMICS], [1],
+ [Define to 1 if Solaris libc atomic functions \
+ are available])
+ )
+
+ AC_MSG_CHECKING(whether pthread_t can be used by Solaris libc atomic functions)
+ # either define HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS or not
+ AC_TRY_RUN(
[
- AC_MSG_NOTICE(no need to check pthread_t size)
+ #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);
+ }
],
[
- AC_CHECK_DECLS(
- [HAVE_SOLARIS_ATOMICS],
- [
- AC_MSG_CHECKING(checking if pthread_t size is integral)
- AC_TRY_RUN(
- [
- #include <pthread.h>
- int main()
- {
- pthread_t x = 0;
- return(0);
- }
- ],
- [
- AC_DEFINE([HAVE_ATOMIC_PTHREAD_T], [1],
+ AC_DEFINE([HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS], [1],
[pthread_t can be used by solaris atomics])
- AC_MSG_RESULT(yes)
- # size of pthread_t is needed for typed solaris atomics
- AC_CHECK_SIZEOF([pthread_t], [], [#include <pthread.h>])
- ],
- [
- AC_MSG_RESULT(no)
- ])
- ])
- ])
+ AC_MSG_RESULT(yes)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ]
+ )
+
+ # this is needed to know which one of atomic_cas_32() or atomic_cas_64()
+ # to use in the source
+ AC_CHECK_SIZEOF([pthread_t], [], [#include <pthread.h>])
+
# Check for x86 PAUSE instruction
AC_MSG_CHECKING(for x86 PAUSE instruction)
# We have to actually try running the test program, because of a bug
@@ -141,7 +209,7 @@ MYSQL_PLUGIN_ACTIONS(innodb_plugin, [
}
],
[
- AC_DEFINE([IB_HAVE_PAUSE_INSTRUCTION], [1], [Does x86 PAUSE instruction exist])
+ AC_DEFINE([HAVE_IB_PAUSE_INSTRUCTION], [1], [Does x86 PAUSE instruction exist])
AC_MSG_RESULT(yes)
],
[
diff --git a/storage/innodb_plugin/rem/rem0cmp.c b/storage/innodb_plugin/rem/rem0cmp.c
index b707f2116d6..e6dab0bc66b 100644
--- a/storage/innodb_plugin/rem/rem0cmp.c
+++ b/storage/innodb_plugin/rem/rem0cmp.c
@@ -36,7 +36,7 @@ Created 7/1/1994 Heikki Tuuri
The records are put into alphabetical order in the following
way: let F be the first field where two records disagree.
-If there is a character in some position n where the the
+If there is a character in some position n where the
records disagree, the order is determined by comparison of
the characters at position n, possibly after
collating transformation. If there is no such character,
@@ -76,7 +76,7 @@ cmp_debug_dtuple_rec_with_match(
/*************************************************************//**
This function is used to compare two data fields for which the data type
is such that we must use MySQL code to compare them. The prototype here
-must be a copy of the the one in ha_innobase.cc!
+must be a copy of the one in ha_innobase.cc!
@return 1, 0, -1, if a is greater, equal, less than b, respectively */
extern
int
@@ -399,7 +399,7 @@ next_byte:
/*************************************************************//**
This function is used to compare a data tuple to a physical record.
Only dtuple->n_fields_cmp first fields are taken into account for
-the the data tuple! If we denote by n = n_fields_cmp, then rec must
+the data tuple! If we denote by n = n_fields_cmp, then rec must
have either m >= n fields, or it must differ from dtuple in some of
the m fields rec has. If rec has an externally stored field we do not
compare it but return with value 0 if such a comparison should be
diff --git a/storage/innodb_plugin/revert_gen.sh b/storage/innodb_plugin/revert_gen.sh
new file mode 100755
index 00000000000..231e05a21e0
--- /dev/null
+++ b/storage/innodb_plugin/revert_gen.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+#
+# revert changes to all generated files. this is useful in some situations
+# when merging changes between branches.
+
+set -eu
+
+svn revert include/pars0grm.h pars/pars0grm.h pars/lexyy.c pars/pars0grm.c
diff --git a/storage/innodb_plugin/row/row0ins.c b/storage/innodb_plugin/row/row0ins.c
index 930c9ec1fc7..fe51fce82c4 100644
--- a/storage/innodb_plugin/row/row0ins.c
+++ b/storage/innodb_plugin/row/row0ins.c
@@ -141,7 +141,7 @@ row_ins_alloc_sys_fields(
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- ptr = mem_heap_alloc(heap, DATA_ROW_ID_LEN);
+ ptr = mem_heap_zalloc(heap, DATA_ROW_ID_LEN);
dfield_set_data(dfield, ptr, DATA_ROW_ID_LEN);
@@ -152,7 +152,7 @@ row_ins_alloc_sys_fields(
col = dict_table_get_sys_col(table, DATA_TRX_ID);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- ptr = mem_heap_alloc(heap, DATA_TRX_ID_LEN);
+ ptr = mem_heap_zalloc(heap, DATA_TRX_ID_LEN);
dfield_set_data(dfield, ptr, DATA_TRX_ID_LEN);
@@ -163,7 +163,7 @@ row_ins_alloc_sys_fields(
col = dict_table_get_sys_col(table, DATA_ROLL_PTR);
dfield = dtuple_get_nth_field(row, dict_col_get_no(col));
- ptr = mem_heap_alloc(heap, DATA_ROLL_PTR_LEN);
+ ptr = mem_heap_zalloc(heap, DATA_ROLL_PTR_LEN);
dfield_set_data(dfield, ptr, DATA_ROLL_PTR_LEN);
}
@@ -1191,7 +1191,7 @@ row_ins_check_foreign_constraint(
/*=============================*/
ibool check_ref,/*!< in: TRUE if we want to check that
the referenced table is ok, FALSE if we
- want to to check the foreign key table */
+ want to check the foreign key table */
dict_foreign_t* foreign,/*!< in: foreign constraint; NOTE that the
tables mentioned in it must be in the
dictionary cache if they exist at all */
diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c
index 05a45dc647c..a303a2f3278 100644
--- a/storage/innodb_plugin/row/row0merge.c
+++ b/storage/innodb_plugin/row/row0merge.c
@@ -60,9 +60,19 @@ Completed by Sunny Bains and Marko Makela
#ifdef UNIV_DEBUG
/** Set these in order ot enable debug printout. */
/* @{ */
+/** Log the outcome of each row_merge_cmp() call, comparing records. */
static ibool row_merge_print_cmp;
+/** Log each record read from temporary file. */
static ibool row_merge_print_read;
+/** Log each record write to temporary file. */
static ibool row_merge_print_write;
+/** Log each row_merge_blocks() call, merging two blocks of records to
+a bigger one. */
+static ibool row_merge_print_block;
+/** Log each block read from temporary file. */
+static ibool row_merge_print_block_read;
+/** Log each block read from temporary file. */
+static ibool row_merge_print_block_write;
/* @} */
#endif /* UNIV_DEBUG */
@@ -109,8 +119,9 @@ typedef struct row_merge_buf_struct row_merge_buf_t;
/** Information about temporary files used in merge sort */
struct merge_file_struct {
- int fd; /*!< file descriptor */
- ulint offset; /*!< file offset */
+ int fd; /*!< file descriptor */
+ ulint offset; /*!< file offset (end of file) */
+ ib_uint64_t n_rec; /*!< number of records in the file */
};
/** Information about temporary files used in merge sort */
@@ -682,6 +693,13 @@ row_merge_read(
ib_uint64_t ofs = ((ib_uint64_t) offset) * sizeof *buf;
ibool success;
+#ifdef UNIV_DEBUG
+ if (row_merge_print_block_read) {
+ fprintf(stderr, "row_merge_read fd=%d ofs=%lu\n",
+ fd, (ulong) offset);
+ }
+#endif /* UNIV_DEBUG */
+
success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf,
(ulint) (ofs & 0xFFFFFFFF),
(ulint) (ofs >> 32),
@@ -709,6 +727,13 @@ row_merge_write(
ib_uint64_t ofs = ((ib_uint64_t) offset)
* sizeof(row_merge_block_t);
+#ifdef UNIV_DEBUG
+ if (row_merge_print_block_write) {
+ fprintf(stderr, "row_merge_write fd=%d ofs=%lu\n",
+ fd, (ulong) offset);
+ }
+#endif /* UNIV_DEBUG */
+
return(UNIV_LIKELY(os_file_write("(merge)", OS_FILE_FROM_FD(fd), buf,
(ulint) (ofs & 0xFFFFFFFF),
(ulint) (ofs >> 32),
@@ -718,7 +743,7 @@ row_merge_write(
/********************************************************************//**
Read a merge record.
@return pointer to next record, or NULL on I/O error or end of list */
-static
+static __attribute__((nonnull))
const byte*
row_merge_read_rec(
/*===============*/
@@ -1070,7 +1095,7 @@ row_merge_cmp(
Reads clustered index of the table and create temporary files
containing the index entries for the indexes to be built.
@return DB_SUCCESS or error */
-static
+static __attribute__((nonnull))
ulint
row_merge_read_clustered_index(
/*===========================*/
@@ -1233,6 +1258,7 @@ row_merge_read_clustered_index(
if (UNIV_LIKELY
(row && row_merge_buf_add(buf, row, ext))) {
+ file->n_rec++;
continue;
}
@@ -1274,14 +1300,19 @@ err_exit:
UNIV_MEM_INVALID(block[0], sizeof block[0]);
merge_buf[i] = row_merge_buf_empty(buf);
- /* Try writing the record again, now that
- the buffer has been written out and emptied. */
+ if (UNIV_LIKELY(row != NULL)) {
+ /* Try writing the record again, now
+ that the buffer has been written out
+ and emptied. */
- if (UNIV_UNLIKELY
- (row && !row_merge_buf_add(buf, row, ext))) {
- /* An empty buffer should have enough
- room for at least one record. */
- ut_error;
+ if (UNIV_UNLIKELY
+ (!row_merge_buf_add(buf, row, ext))) {
+ /* An empty buffer should have enough
+ room for at least one record. */
+ ut_error;
+ }
+
+ file->n_rec++;
}
}
@@ -1320,7 +1351,7 @@ func_exit:
b2 = row_merge_write_rec(&block[2], &buf[2], b2, \
of->fd, &of->offset, \
mrec##N, offsets##N); \
- if (UNIV_UNLIKELY(!b2)) { \
+ if (UNIV_UNLIKELY(!b2 || ++of->n_rec > file->n_rec)) { \
goto corrupt; \
} \
b##N = row_merge_read_rec(&block[N], &buf[N], \
@@ -1336,14 +1367,14 @@ func_exit:
} while (0)
/*************************************************************//**
-Merge two blocks of linked lists on disk and write a bigger block.
+Merge two blocks of records on disk and write a bigger block.
@return DB_SUCCESS or error code */
static
ulint
row_merge_blocks(
/*=============*/
const dict_index_t* index, /*!< in: index being created */
- merge_file_t* file, /*!< in/out: file containing
+ const merge_file_t* file, /*!< in: file containing
index entries */
row_merge_block_t* block, /*!< in/out: 3 buffers */
ulint* foffs0, /*!< in/out: offset of first
@@ -1366,6 +1397,17 @@ row_merge_blocks(
ulint* offsets0;/* offsets of mrec0 */
ulint* offsets1;/* offsets of mrec1 */
+#ifdef UNIV_DEBUG
+ if (row_merge_print_block) {
+ fprintf(stderr,
+ "row_merge_blocks fd=%d ofs=%lu + fd=%d ofs=%lu"
+ " = fd=%d ofs=%lu\n",
+ file->fd, (ulong) *foffs0,
+ file->fd, (ulong) *foffs1,
+ of->fd, (ulong) of->offset);
+ }
+#endif /* UNIV_DEBUG */
+
heap = row_merge_heap_create(index, &offsets0, &offsets1);
/* Write a record and read the next record. Split the output
@@ -1438,16 +1480,87 @@ done1:
}
/*************************************************************//**
+Copy a block of index entries.
+@return TRUE on success, FALSE on failure */
+static __attribute__((nonnull))
+ibool
+row_merge_blocks_copy(
+/*==================*/
+ const dict_index_t* index, /*!< in: index being created */
+ const merge_file_t* file, /*!< in: input file */
+ row_merge_block_t* block, /*!< in/out: 3 buffers */
+ ulint* foffs0, /*!< in/out: input file offset */
+ merge_file_t* of) /*!< in/out: output file */
+{
+ mem_heap_t* heap; /*!< memory heap for offsets0, offsets1 */
+
+ mrec_buf_t buf[3]; /*!< buffer for handling
+ split mrec in block[] */
+ const byte* b0; /*!< pointer to block[0] */
+ byte* b2; /*!< pointer to block[2] */
+ const mrec_t* mrec0; /*!< merge rec, points to block[0] */
+ ulint* offsets0;/* offsets of mrec0 */
+ ulint* offsets1;/* dummy offsets */
+
+#ifdef UNIV_DEBUG
+ if (row_merge_print_block) {
+ fprintf(stderr,
+ "row_merge_blocks_copy fd=%d ofs=%lu"
+ " = fd=%d ofs=%lu\n",
+ file->fd, (ulong) foffs0,
+ of->fd, (ulong) of->offset);
+ }
+#endif /* UNIV_DEBUG */
+
+ heap = row_merge_heap_create(index, &offsets0, &offsets1);
+
+ /* Write a record and read the next record. Split the output
+ file in two halves, which can be merged on the following pass. */
+
+ if (!row_merge_read(file->fd, *foffs0, &block[0])) {
+corrupt:
+ mem_heap_free(heap);
+ return(FALSE);
+ }
+
+ b0 = block[0];
+ b2 = block[2];
+
+ b0 = row_merge_read_rec(&block[0], &buf[0], b0, index, file->fd,
+ foffs0, &mrec0, offsets0);
+ if (UNIV_UNLIKELY(!b0 && mrec0)) {
+
+ goto corrupt;
+ }
+
+ if (mrec0) {
+ /* append all mrec0 to output */
+ for (;;) {
+ ROW_MERGE_WRITE_GET_NEXT(0, goto done0);
+ }
+ }
+done0:
+
+ /* The file offset points to the beginning of the last page
+ that has been read. Update it to point to the next block. */
+ (*foffs0)++;
+
+ mem_heap_free(heap);
+ return(row_merge_write_eof(&block[2], b2, of->fd, &of->offset)
+ != NULL);
+}
+
+/*************************************************************//**
Merge disk files.
@return DB_SUCCESS or error code */
-static
+static __attribute__((nonnull))
ulint
row_merge(
/*======*/
const dict_index_t* index, /*!< in: index being created */
merge_file_t* file, /*!< in/out: file containing
index entries */
- ulint half, /*!< in: half the file */
+ 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
@@ -1458,43 +1571,75 @@ row_merge(
ulint foffs1; /*!< second input offset */
ulint error; /*!< error code */
merge_file_t of; /*!< output file */
+ const ulint ihalf = *half;
+ /*!< half the input file */
+ ulint ohalf; /*!< half the output file */
UNIV_MEM_ASSERT_W(block[0], 3 * sizeof block[0]);
- ut_ad(half > 0);
+ ut_ad(ihalf < file->offset);
of.fd = *tmpfd;
of.offset = 0;
+ of.n_rec = 0;
/* Merge blocks to the output file. */
+ ohalf = 0;
foffs0 = 0;
- foffs1 = half;
+ foffs1 = ihalf;
+
+ for (; foffs0 < ihalf && foffs1 < file->offset; foffs0++, foffs1++) {
+ ulint ahalf; /*!< arithmetic half the input file */
- for (; foffs0 < half && foffs1 < file->offset; foffs0++, foffs1++) {
error = row_merge_blocks(index, file, block,
&foffs0, &foffs1, &of, table);
if (error != DB_SUCCESS) {
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 block, if there is one. */
- while (foffs0 < half) {
- if (!row_merge_read(file->fd, foffs0++, block)
- || !row_merge_write(of.fd, of.offset++, block)) {
+ /* Copy the last blocks, if there are any. */
+
+ while (foffs0 < ihalf) {
+ if (!row_merge_blocks_copy(index, file, block, &foffs0, &of)) {
return(DB_CORRUPTION);
}
}
+
+ ut_ad(foffs0 == ihalf);
+
while (foffs1 < file->offset) {
- if (!row_merge_read(file->fd, foffs1++, block)
- || !row_merge_write(of.fd, of.offset++, block)) {
+ if (!row_merge_blocks_copy(index, file, block, &foffs1, &of)) {
return(DB_CORRUPTION);
}
}
+ ut_ad(foffs1 == file->offset);
+
+ if (UNIV_UNLIKELY(of.n_rec != file->n_rec)) {
+ return(DB_CORRUPTION);
+ }
+
/* Swap file descriptors for the next pass. */
*tmpfd = file->fd;
*file = of;
+ *half = ohalf;
UNIV_MEM_INVALID(block[0], 3 * sizeof block[0]);
@@ -1517,20 +1662,25 @@ row_merge_sort(
reporting erroneous key value
if applicable */
{
- ulint blksz; /*!< block size */
+ ulint half = file->offset / 2;
+
+ /* 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);
- for (blksz = 1; blksz < file->offset; blksz *= 2) {
- ulint half;
+ do {
ulint error;
- ut_ad(ut_is_2pow(blksz));
- half = ut_2pow_round((file->offset + (blksz - 1)) / 2, blksz);
- error = row_merge(index, file, half, block, tmpfd, table);
+ error = row_merge(index, file, &half, block, tmpfd, table);
if (error != DB_SUCCESS) {
return(error);
}
- }
+
+ /* 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);
return(DB_SUCCESS);
}
@@ -1797,7 +1947,15 @@ row_merge_drop_index(
static const char str1[] =
"PROCEDURE DROP_INDEX_PROC () IS\n"
"BEGIN\n"
+ /* Rename the index, so that it will be dropped by
+ row_merge_drop_temp_indexes() at crash recovery
+ if the server crashes before this trx is committed. */
+ "UPDATE SYS_INDEXES SET NAME=CONCAT('"
+ TEMP_INDEX_PREFIX_STR "', NAME) WHERE ID = :indexid;\n"
+ "COMMIT WORK;\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. */
"DELETE FROM SYS_INDEXES WHERE ID = :indexid\n"
" AND TABLE_ID = :tableid;\n"
"END;\n";
@@ -1909,6 +2067,7 @@ row_merge_file_create(
{
merge_file->fd = innobase_mysql_tmpfile();
merge_file->offset = 0;
+ merge_file->n_rec = 0;
}
/*********************************************************************//**
@@ -2129,7 +2288,7 @@ row_merge_rename_tables(
if (err != DB_SUCCESS) {
err_exit:
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
}
diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c
index b345bb59624..540a4450045 100644
--- a/storage/innodb_plugin/row/row0mysql.c
+++ b/storage/innodb_plugin/row/row0mysql.c
@@ -510,7 +510,7 @@ handle_new_error:
switch (err) {
case DB_LOCK_WAIT_TIMEOUT:
if (row_rollback_on_timeout) {
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
break;
}
/* fall through */
@@ -526,7 +526,7 @@ handle_new_error:
/* Roll back the latest, possibly incomplete
insertion or update */
- trx_general_rollback_for_mysql(trx, TRUE, savept);
+ trx_general_rollback_for_mysql(trx, savept);
}
/* MySQL will roll back the latest SQL statement */
break;
@@ -548,7 +548,7 @@ handle_new_error:
/* Roll back the whole transaction; this resolution was added
to version 3.23.43 */
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
break;
case DB_MUST_GET_MORE_FILE_SPACE:
@@ -866,18 +866,22 @@ row_update_statistics_if_needed(
}
/*********************************************************************//**
-Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
+Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
+function should be called at the the end of an SQL statement, by the
+connection thread that owns the transaction (trx->mysql_thd). */
UNIV_INTERN
void
row_unlock_table_autoinc_for_mysql(
/*===============================*/
trx_t* trx) /*!< in/out: transaction */
{
- mutex_enter(&kernel_mutex);
+ if (lock_trx_holds_autoinc_locks(trx)) {
+ mutex_enter(&kernel_mutex);
- lock_release_autoinc_locks(trx);
+ lock_release_autoinc_locks(trx);
- mutex_exit(&kernel_mutex);
+ mutex_exit(&kernel_mutex);
+ }
}
/*********************************************************************//**
@@ -1767,7 +1771,6 @@ row_create_table_for_mysql(
const char* table_name;
ulint table_name_len;
ulint err;
- ulint i;
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
#ifdef UNIV_SYNC_DEBUG
@@ -1802,15 +1805,6 @@ err_exit:
goto err_exit;
}
- /* Check that no reserved column names are used. */
- for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
- if (dict_col_name_is_reserved(
- dict_table_get_col_name(table, i))) {
-
- goto err_exit;
- }
- }
-
trx_start_if_not_started(trx);
/* The table name is prefixed with the database name and a '/'.
@@ -1885,7 +1879,7 @@ err_exit:
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
}
switch (err) {
@@ -2053,7 +2047,7 @@ error_handling:
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
row_drop_table_for_mysql(table_name, trx, FALSE);
@@ -2074,7 +2068,7 @@ 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.
Each foreign key constraint must be accompanied with indexes in
-bot participating tables. The indexes are allowed to contain more
+both participating tables. The indexes are allowed to contain more
fields than mentioned in the constraint. Check also that foreign key
constraints which reference this table are ok.
@return error code or DB_SUCCESS */
@@ -2121,7 +2115,7 @@ row_table_add_foreign_constraints(
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
row_drop_table_for_mysql(name, trx, FALSE);
@@ -2488,7 +2482,7 @@ row_discard_tablespace_for_mysql(
if (err != DB_SUCCESS) {
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
} else {
dict_table_change_id_in_cache(table, new_id);
@@ -2497,7 +2491,7 @@ row_discard_tablespace_for_mysql(
if (!success) {
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
err = DB_ERROR;
@@ -2949,7 +2943,7 @@ next_rec:
if (err != DB_SUCCESS) {
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
ut_print_timestamp(stderr);
fputs(" InnoDB: Unable to assign a new identifier to table ",
@@ -3590,7 +3584,7 @@ row_delete_constraint(
if ((err == DB_SUCCESS) && !strchr(id, '/')) {
/* Old format < 4.0.18 constraints have constraint ids
- <number>_<number>. We only try deleting them if the
+ NUMBER_NUMBER. We only try deleting them if the
constraint name does not contain a '/' character, otherwise
deleting a new format constraint named 'foo/bar' from
database 'baz' would remove constraint 'bar' from database
@@ -3854,7 +3848,7 @@ end:
"InnoDB: succeed.\n", stderr);
}
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
} else {
/* The following call will also rename the .ibd data file if
@@ -3863,7 +3857,7 @@ end:
if (!dict_table_rename_in_cache(table, new_name,
!new_is_tmp)) {
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
goto funct_exit;
}
@@ -3903,7 +3897,7 @@ end:
ut_a(dict_table_rename_in_cache(table,
old_name, FALSE));
trx->error_state = DB_SUCCESS;
- trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
}
}
diff --git a/storage/innodb_plugin/scripts/export.sh b/storage/innodb_plugin/scripts/export.sh
new file mode 100755
index 00000000000..2a4355c1e43
--- /dev/null
+++ b/storage/innodb_plugin/scripts/export.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+#
+# export current working directory in a format suitable for sending to MySQL
+# as a snapshot. also generates the actual snapshot and sends it to MySQL.
+
+set -eu
+
+die () {
+ echo $*
+ exit 1
+}
+
+if [ $# -ne 2 ] ; then
+ die "Usage: export.sh revision-number-of-last-snapshot current-revision-number"
+fi
+
+# If we are run from within the scripts/ directory then change directory to
+# one level up so that the relative paths work.
+DIR=`basename $PWD`
+
+if [ "${DIR}" = "scripts" ]; then
+ cd ..
+fi
+
+START_REV=$(($1 + 1))
+END_REV=$2
+
+set +u
+if test -z $EDITOR; then
+ die "\$EDITOR is not set"
+fi
+set -u
+
+rm -rf to-mysql
+mkdir to-mysql{,/storage,/patches,/mysql-test{,/t,/r,/include}}
+svn log -v -r "$START_REV:BASE" > to-mysql/log
+svn export -q . to-mysql/storage/innobase
+
+REV=$START_REV
+while [ $REV -le $END_REV ]
+do
+ PATCH=to-mysql/patches/r$REV.patch
+ svn log -v -r$REV > $PATCH
+ if [ $(wc -c < $PATCH) -gt 73 ]
+ then
+ svn diff -r$(($REV-1)):$REV >> $PATCH
+ else
+ rm $PATCH
+ fi
+ REV=$(($REV + 1))
+done
+
+cd to-mysql/storage/innobase
+
+mv mysql-test/*.test mysql-test/*.opt ../../mysql-test/t
+mv mysql-test/*.result ../../mysql-test/r
+mv mysql-test/*.inc ../../mysql-test/include
+rmdir mysql-test
+
+rm setup.sh export.sh revert_gen.sh compile-innodb-debug compile-innodb
+
+cd ../..
+$EDITOR log
+cd ..
+
+fname="innodb-5.1-ss$2.tar.gz"
+
+rm -f $fname
+tar czf $fname to-mysql
+scp $fname mysql:snapshots
+rm $fname
+rm -rf to-mysql
+
+echo "Sent $fname to MySQL"
diff --git a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
index 79fa08e7cdf..d638b23692e 100644
--- a/storage/innodb_plugin/srv/srv0srv.c
+++ b/storage/innodb_plugin/srv/srv0srv.c
@@ -102,6 +102,7 @@ Created 10/8/1995 Heikki Tuuri
#include "row0mysql.h"
#include "ha_prototypes.h"
#include "trx0i_s.h"
+#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
/* This is set to TRUE if the MySQL user has set it in MySQL; currently
affects only FOREIGN KEY definition parsing */
@@ -292,12 +293,6 @@ UNIV_INTERN ulint srv_buf_pool_flushed = 0;
reading of a disk page */
UNIV_INTERN ulint srv_buf_pool_reads = 0;
-/** Number of sequential read-aheads */
-UNIV_INTERN ulint srv_read_ahead_seq = 0;
-
-/** Number of random read-aheads */
-UNIV_INTERN ulint srv_read_ahead_rnd = 0;
-
/* structure to pass status variables to MySQL */
UNIV_INTERN export_struc export_vars;
@@ -464,8 +459,6 @@ static ulint srv_main_background_loops = 0;
static ulint srv_main_flush_loops = 0;
/* Log writes involving flush. */
static ulint srv_log_writes_and_flush = 0;
-/* Log writes not including flush. */
-static ulint srv_log_buffer_writes = 0;
/* This is only ever touched by the master thread. It records the
time when the last flush of log file has happened. The master
@@ -614,7 +607,7 @@ future, but at the moment we plan to implement a more coarse solution,
which could be called a global priority inheritance. If a thread
has to wait for a long time, say 300 milliseconds, for a resource,
we just guess that it may be waiting for a resource owned by a background
-thread, and boost the the priority of all runnable background threads
+thread, and boost the priority of all runnable background threads
to the normal level. The background threads then themselves adjust
their fixed priority back to background after releasing all resources
they had (or, at some fixed points in their program code).
@@ -714,9 +707,8 @@ srv_print_master_thread_info(
srv_main_1_second_loops, srv_main_sleeps,
srv_main_10_second_loops, srv_main_background_loops,
srv_main_flush_loops);
- fprintf(file, "srv_master_thread log flush and writes: %lu "
- " log writes only: %lu\n",
- srv_log_writes_and_flush, srv_log_buffer_writes);
+ fprintf(file, "srv_master_thread log flush and writes: %lu\n",
+ srv_log_writes_and_flush);
}
/*********************************************************************//**
@@ -1877,14 +1869,16 @@ srv_export_innodb_status(void)
export_vars.innodb_data_reads = os_n_file_reads;
export_vars.innodb_data_writes = os_n_file_writes;
export_vars.innodb_data_written = srv_data_written;
- export_vars.innodb_buffer_pool_read_requests = buf_pool->n_page_gets;
+ export_vars.innodb_buffer_pool_read_requests = buf_pool->stat.n_page_gets;
export_vars.innodb_buffer_pool_write_requests
= srv_buf_pool_write_requests;
export_vars.innodb_buffer_pool_wait_free = srv_buf_pool_wait_free;
export_vars.innodb_buffer_pool_pages_flushed = srv_buf_pool_flushed;
export_vars.innodb_buffer_pool_reads = srv_buf_pool_reads;
- export_vars.innodb_buffer_pool_read_ahead_rnd = srv_read_ahead_rnd;
- export_vars.innodb_buffer_pool_read_ahead_seq = srv_read_ahead_seq;
+ export_vars.innodb_buffer_pool_read_ahead
+ = buf_pool->stat.n_ra_pages_read;
+ export_vars.innodb_buffer_pool_read_ahead_evicted
+ = buf_pool->stat.n_ra_pages_evicted;
export_vars.innodb_buffer_pool_pages_data
= UT_LIST_GET_LEN(buf_pool->LRU);
export_vars.innodb_buffer_pool_pages_dirty
@@ -1915,9 +1909,9 @@ srv_export_innodb_status(void)
export_vars.innodb_log_writes = srv_log_writes;
export_vars.innodb_dblwr_pages_written = srv_dblwr_pages_written;
export_vars.innodb_dblwr_writes = srv_dblwr_writes;
- export_vars.innodb_pages_created = buf_pool->n_pages_created;
- export_vars.innodb_pages_read = buf_pool->n_pages_read;
- export_vars.innodb_pages_written = buf_pool->n_pages_written;
+ export_vars.innodb_pages_created = buf_pool->stat.n_pages_created;
+ export_vars.innodb_pages_read = buf_pool->stat.n_pages_read;
+ export_vars.innodb_pages_written = buf_pool->stat.n_pages_written;
export_vars.innodb_row_lock_waits = srv_n_lock_wait_count;
export_vars.innodb_row_lock_current_waits
= srv_n_lock_wait_current_count;
@@ -2284,12 +2278,6 @@ srv_sync_log_buffer_in_background(void)
log_buffer_sync_in_background(TRUE);
srv_last_log_flush_time = current_time;
srv_log_writes_and_flush++;
- } else {
- /* Actually we don't need to write logs here.
- We are just being extra safe here by forcing
- the log buffer to log file. */
- log_buffer_sync_in_background(FALSE);
- srv_log_buffer_writes++;
}
}
@@ -2340,8 +2328,8 @@ loop:
srv_main_thread_op_info = "reserving kernel mutex";
- n_ios_very_old = log_sys->n_log_ios + buf_pool->n_pages_read
- + buf_pool->n_pages_written;
+ n_ios_very_old = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+ + buf_pool->stat.n_pages_written;
mutex_enter(&kernel_mutex);
/* Store the user activity counter at the start of this loop */
@@ -2361,8 +2349,8 @@ loop:
skip_sleep = FALSE;
for (i = 0; i < 10; i++) {
- n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read
- + buf_pool->n_pages_written;
+ n_ios_old = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+ + buf_pool->stat.n_pages_written;
srv_main_thread_op_info = "sleeping";
srv_main_1_second_loops++;
@@ -2401,8 +2389,8 @@ loop:
n_pend_ios = buf_get_n_pending_ios()
+ log_sys->n_pending_writes;
- n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
- + buf_pool->n_pages_written;
+ n_ios = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+ + buf_pool->stat.n_pages_written;
if (n_pend_ios < SRV_PEND_IO_THRESHOLD
&& (n_ios - n_ios_old < SRV_RECENT_IO_ACTIVITY)) {
srv_main_thread_op_info = "doing insert buffer merge";
@@ -2418,6 +2406,8 @@ loop:
/* Try to keep the number of modified pages in the
buffer pool under the limit wished by the user */
+ srv_main_thread_op_info =
+ "flushing buffer pool pages";
n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
PCT_IO(100),
IB_ULONGLONG_MAX);
@@ -2436,6 +2426,8 @@ loop:
ulint n_flush = buf_flush_get_desired_flush_rate();
if (n_flush) {
+ srv_main_thread_op_info =
+ "flushing buffer pool pages";
n_flush = ut_min(PCT_IO(100), n_flush);
n_pages_flushed =
buf_flush_batch(
@@ -2473,8 +2465,8 @@ loop:
are not required, and may be disabled. */
n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes;
- n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
- + buf_pool->n_pages_written;
+ n_ios = log_sys->n_log_ios + buf_pool->stat.n_pages_read
+ + buf_pool->stat.n_pages_written;
srv_main_10_second_loops++;
if (n_pend_ios < SRV_PEND_IO_THRESHOLD
diff --git a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c
index a942fd439a3..796541a9f1a 100644
--- a/storage/innodb_plugin/srv/srv0start.c
+++ b/storage/innodb_plugin/srv/srv0start.c
@@ -103,6 +103,7 @@ Created 2/16/1996 Heikki Tuuri
# include "row0row.h"
# include "row0mysql.h"
# include "btr0pcur.h"
+# include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
/** Log sequence number immediately after startup */
UNIV_INTERN ib_uint64_t srv_start_lsn;
@@ -1096,6 +1097,10 @@ innobase_start_or_create_for_mysql(void)
"InnoDB: !!!!!!!! UNIV_SEARCH_DEBUG switched on !!!!!!!!!\n");
#endif
+#ifdef UNIV_LOG_LSN_DEBUG
+ fprintf(stderr,
+ "InnoDB: !!!!!!!! UNIV_LOG_LSN_DEBUG switched on !!!!!!!!!\n");
+#endif /* UNIV_LOG_LSN_DEBUG */
#ifdef UNIV_MEM_DEBUG
fprintf(stderr,
"InnoDB: !!!!!!!! UNIV_MEM_DEBUG switched on !!!!!!!!!\n");
@@ -1106,34 +1111,7 @@ innobase_start_or_create_for_mysql(void)
"InnoDB: The InnoDB memory heap is disabled\n");
}
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
-# ifdef INNODB_RW_LOCKS_USE_ATOMICS
- fprintf(stderr,
- "InnoDB: Mutexes and rw_locks use GCC atomic builtins.\n");
-# else /* INNODB_RW_LOCKS_USE_ATOMICS */
- fprintf(stderr,
- "InnoDB: Mutexes use GCC atomic builtins, rw_locks do not.\n");
-# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
-#elif defined(HAVE_SOLARIS_ATOMICS)
-# ifdef INNODB_RW_LOCKS_USE_ATOMICS
- fprintf(stderr,
- "InnoDB: Mutexes and rw_locks use Solaris atomic functions.\n");
-# else
- fprintf(stderr,
- "InnoDB: Mutexes use Solaris atomic functions.\n");
-# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
-#elif HAVE_WINDOWS_ATOMICS
-# ifdef INNODB_RW_LOCKS_USE_ATOMICS
- fprintf(stderr,
- "InnoDB: Mutexes and rw_locks use Windows interlocked functions.\n");
-# else
- fprintf(stderr,
- "InnoDB: Mutexes use Windows interlocked functions.\n");
-# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
-#else /* HAVE_GCC_ATOMIC_BUILTINS */
- fprintf(stderr,
- "InnoDB: Neither mutexes nor rw_locks use GCC atomic builtins.\n");
-#endif /* HAVE_GCC_ATOMIC_BUILTINS */
+ fprintf(stderr, "InnoDB: %s\n", IB_ATOMICS_STARTUP_MSG);
/* Since InnoDB does not currently clean up all its internal data
structures in MySQL Embedded Server Library server_end(), we
@@ -1398,7 +1376,7 @@ innobase_start_or_create_for_mysql(void)
sum_of_new_sizes += srv_data_file_sizes[i];
}
- if (sum_of_new_sizes < 640) {
+ if (sum_of_new_sizes < 10485760 / UNIV_PAGE_SIZE) {
fprintf(stderr,
"InnoDB: Error: tablespace size must be"
" at least 10 MB\n");
@@ -1829,7 +1807,7 @@ innobase_start_or_create_for_mysql(void)
/* Actually, we did not change the undo log format between
4.0 and 4.1.1, and we would not need to run purge to
completion. Note also that the purge algorithm in 4.1.1
- can process the the history list again even after a full
+ can process the history list again even after a full
purge, because our algorithm does not cut the end of the
history list in all cases so that it would become empty
after a full purge. That mean that we may purge 4.0 type
diff --git a/storage/innodb_plugin/sync/sync0rw.c b/storage/innodb_plugin/sync/sync0rw.c
index 0ed114e330c..d231b6acdf7 100644
--- a/storage/innodb_plugin/sync/sync0rw.c
+++ b/storage/innodb_plugin/sync/sync0rw.c
@@ -38,6 +38,7 @@ Created 9/11/1995 Heikki Tuuri
#include "os0thread.h"
#include "mem0mem.h"
#include "srv0srv.h"
+#include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
/*
IMPLEMENTATION OF THE RW_LOCK
diff --git a/storage/innodb_plugin/sync/sync0sync.c b/storage/innodb_plugin/sync/sync0sync.c
index 84ed08e14e7..5ad143075a7 100644
--- a/storage/innodb_plugin/sync/sync0sync.c
+++ b/storage/innodb_plugin/sync/sync0sync.c
@@ -39,6 +39,7 @@ Created 9/5/1995 Heikki Tuuri
#include "buf0buf.h"
#include "srv0srv.h"
#include "buf0types.h"
+#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
/*
REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX
@@ -849,7 +850,8 @@ sync_thread_levels_g(
/*=================*/
sync_level_t* arr, /*!< in: pointer to level array for an OS
thread */
- ulint limit) /*!< in: level limit */
+ ulint limit, /*!< in: level limit */
+ ulint warn) /*!< in: TRUE=display a diagnostic message */
{
sync_level_t* slot;
rw_lock_t* lock;
@@ -863,6 +865,11 @@ sync_thread_levels_g(
if (slot->latch != NULL) {
if (slot->level <= limit) {
+ if (!warn) {
+
+ return(FALSE);
+ }
+
lock = slot->latch;
mutex = slot->latch;
@@ -1100,7 +1107,7 @@ sync_thread_add_level(
case SYNC_DICT_HEADER:
case SYNC_TRX_I_S_RWLOCK:
case SYNC_TRX_I_S_LAST_READ:
- if (!sync_thread_levels_g(array, level)) {
+ if (!sync_thread_levels_g(array, level, TRUE)) {
fprintf(stderr,
"InnoDB: sync_thread_levels_g(array, %lu)"
" does not hold!\n", level);
@@ -1111,36 +1118,44 @@ sync_thread_add_level(
/* Either the thread must own the buffer pool mutex
(buf_pool_mutex), or it is allowed to latch only ONE
buffer block (block->mutex or buf_pool_zip_mutex). */
- if (!sync_thread_levels_g(array, level)) {
- ut_a(sync_thread_levels_g(array, level - 1));
+ if (!sync_thread_levels_g(array, level, FALSE)) {
+ ut_a(sync_thread_levels_g(array, level - 1, TRUE));
ut_a(sync_thread_levels_contain(array, SYNC_BUF_POOL));
}
break;
case SYNC_REC_LOCK:
- ut_a((sync_thread_levels_contain(array, SYNC_KERNEL)
- && sync_thread_levels_g(array, SYNC_REC_LOCK - 1))
- || sync_thread_levels_g(array, SYNC_REC_LOCK));
+ if (sync_thread_levels_contain(array, SYNC_KERNEL)) {
+ ut_a(sync_thread_levels_g(array, SYNC_REC_LOCK - 1,
+ TRUE));
+ } else {
+ ut_a(sync_thread_levels_g(array, SYNC_REC_LOCK, TRUE));
+ }
break;
case SYNC_IBUF_BITMAP:
/* Either the thread must own the master mutex to all
the bitmap pages, or it is allowed to latch only ONE
bitmap page. */
- ut_a((sync_thread_levels_contain(array, SYNC_IBUF_BITMAP_MUTEX)
- && sync_thread_levels_g(array, SYNC_IBUF_BITMAP - 1))
- || sync_thread_levels_g(array, SYNC_IBUF_BITMAP));
+ if (sync_thread_levels_contain(array,
+ SYNC_IBUF_BITMAP_MUTEX)) {
+ ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP - 1,
+ TRUE));
+ } else {
+ ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP,
+ TRUE));
+ }
break;
case SYNC_FSP_PAGE:
ut_a(sync_thread_levels_contain(array, SYNC_FSP));
break;
case SYNC_FSP:
ut_a(sync_thread_levels_contain(array, SYNC_FSP)
- || sync_thread_levels_g(array, SYNC_FSP));
+ || sync_thread_levels_g(array, SYNC_FSP, TRUE));
break;
case SYNC_TRX_UNDO_PAGE:
ut_a(sync_thread_levels_contain(array, SYNC_TRX_UNDO)
|| sync_thread_levels_contain(array, SYNC_RSEG)
|| sync_thread_levels_contain(array, SYNC_PURGE_SYS)
- || sync_thread_levels_g(array, SYNC_TRX_UNDO_PAGE));
+ || sync_thread_levels_g(array, SYNC_TRX_UNDO_PAGE, TRUE));
break;
case SYNC_RSEG_HEADER:
ut_a(sync_thread_levels_contain(array, SYNC_RSEG));
@@ -1152,37 +1167,41 @@ sync_thread_add_level(
case SYNC_TREE_NODE:
ut_a(sync_thread_levels_contain(array, SYNC_INDEX_TREE)
|| sync_thread_levels_contain(array, SYNC_DICT_OPERATION)
- || sync_thread_levels_g(array, SYNC_TREE_NODE - 1));
+ || sync_thread_levels_g(array, SYNC_TREE_NODE - 1, TRUE));
break;
case SYNC_TREE_NODE_NEW:
ut_a(sync_thread_levels_contain(array, SYNC_FSP_PAGE)
|| sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
break;
case SYNC_INDEX_TREE:
- ut_a((sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
- && sync_thread_levels_contain(array, SYNC_FSP)
- && sync_thread_levels_g(array, SYNC_FSP_PAGE - 1))
- || sync_thread_levels_g(array, SYNC_TREE_NODE - 1));
+ if (sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
+ && sync_thread_levels_contain(array, SYNC_FSP)) {
+ ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1,
+ TRUE));
+ } else {
+ ut_a(sync_thread_levels_g(array, SYNC_TREE_NODE - 1,
+ TRUE));
+ }
break;
case SYNC_IBUF_MUTEX:
- ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1));
+ ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1, TRUE));
break;
case SYNC_IBUF_PESS_INSERT_MUTEX:
- ut_a(sync_thread_levels_g(array, SYNC_FSP - 1)
- && !sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
+ ut_a(sync_thread_levels_g(array, SYNC_FSP - 1, TRUE));
+ ut_a(!sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
break;
case SYNC_IBUF_HEADER:
- ut_a(sync_thread_levels_g(array, SYNC_FSP - 1)
- && !sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
- && !sync_thread_levels_contain(
- array, SYNC_IBUF_PESS_INSERT_MUTEX));
+ ut_a(sync_thread_levels_g(array, SYNC_FSP - 1, TRUE));
+ ut_a(!sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
+ ut_a(!sync_thread_levels_contain(array,
+ SYNC_IBUF_PESS_INSERT_MUTEX));
break;
case SYNC_DICT:
#ifdef UNIV_DEBUG
ut_a(buf_debug_prints
- || sync_thread_levels_g(array, SYNC_DICT));
+ || sync_thread_levels_g(array, SYNC_DICT, TRUE));
#else /* UNIV_DEBUG */
- ut_a(sync_thread_levels_g(array, SYNC_DICT));
+ ut_a(sync_thread_levels_g(array, SYNC_DICT, TRUE));
#endif /* UNIV_DEBUG */
break;
default:
diff --git a/storage/innodb_plugin/thr/thr0loc.c b/storage/innodb_plugin/thr/thr0loc.c
index 18f7b0707bd..49275be1d7d 100644
--- a/storage/innodb_plugin/thr/thr0loc.c
+++ b/storage/innodb_plugin/thr/thr0loc.c
@@ -62,7 +62,7 @@ struct thr_local_struct{
os_thread_t handle; /*!< operating system handle to the thread */
ulint slot_no;/*!< the index of the slot in the thread table
for this thread */
- ibool in_ibuf;/*!< TRUE if the the thread is doing an ibuf
+ ibool in_ibuf;/*!< TRUE if the thread is doing an ibuf
operation */
hash_node_t hash; /*!< hash chain node */
ulint magic_n;/*!< magic number (THR_LOCAL_MAGIC_N) */
diff --git a/storage/innodb_plugin/trx/trx0rec.c b/storage/innodb_plugin/trx/trx0rec.c
index 36911c9df85..5097cf18dcd 100644
--- a/storage/innodb_plugin/trx/trx0rec.c
+++ b/storage/innodb_plugin/trx/trx0rec.c
@@ -1333,7 +1333,7 @@ trx_undo_get_undo_rec_low(
ulint rseg_id;
ulint page_no;
ulint offset;
- page_t* undo_page;
+ const page_t* undo_page;
trx_rseg_t* rseg;
ibool is_insert;
mtr_t mtr;
@@ -1572,7 +1572,7 @@ trx_undo_prev_version_build(
/* We have to set the appropriate extern storage bits in the
old version of the record: the extern bits in rec for those
- fields that update does NOT update, as well as the the bits for
+ fields that update does NOT update, as well as the bits for
those fields that update updates to become externally stored
fields. Store the info: */
diff --git a/storage/innodb_plugin/trx/trx0roll.c b/storage/innodb_plugin/trx/trx0roll.c
index 51d17192d5b..c925478cdf4 100644
--- a/storage/innodb_plugin/trx/trx0roll.c
+++ b/storage/innodb_plugin/trx/trx0roll.c
@@ -66,9 +66,9 @@ int
trx_general_rollback_for_mysql(
/*===========================*/
trx_t* trx, /*!< in: transaction handle */
- ibool partial,/*!< in: TRUE if partial rollback requested */
trx_savept_t* savept) /*!< in: pointer to savepoint undo number, if
- partial rollback requested */
+ partial rollback requested, or NULL for
+ complete rollback */
{
mem_heap_t* heap;
que_thr_t* thr;
@@ -85,9 +85,8 @@ trx_general_rollback_for_mysql(
roll_node = roll_node_create(heap);
- roll_node->partial = partial;
-
- if (partial) {
+ if (savept) {
+ roll_node->partial = TRUE;
roll_node->savept = *savept;
}
@@ -145,7 +144,7 @@ trx_rollback_for_mysql(
the transaction object does not have an InnoDB session object, and we
set a dummy session that we use for all MySQL transactions. */
- err = trx_general_rollback_for_mysql(trx, FALSE, NULL);
+ err = trx_general_rollback_for_mysql(trx, NULL);
trx->op_info = "";
@@ -170,8 +169,7 @@ trx_rollback_last_sql_stat_for_mysql(
trx->op_info = "rollback of SQL statement";
- err = trx_general_rollback_for_mysql(trx, TRUE,
- &(trx->last_sql_stat_start));
+ err = trx_general_rollback_for_mysql(trx, &trx->last_sql_stat_start);
/* The following call should not be needed, but we play safe: */
trx_mark_sql_stat_end(trx);
@@ -282,7 +280,7 @@ trx_rollback_to_savepoint_for_mysql(
trx->op_info = "rollback to a savepoint";
- err = trx_general_rollback_for_mysql(trx, TRUE, &(savep->savept));
+ err = trx_general_rollback_for_mysql(trx, &savep->savept);
/* Store the current undo_no of the transaction so that we know where
to roll back if we have to roll back the next SQL statement: */
@@ -534,28 +532,26 @@ trx_rollback_active(
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
committed, then we clean up a possible insert undo log. If the
-transaction was not yet committed, then we roll it back.
-Note: this is done in a background thread.
-@return a dummy parameter */
+transaction was not yet committed, then we roll it back. */
UNIV_INTERN
-os_thread_ret_t
-trx_rollback_or_clean_all_recovered(
-/*================================*/
- void* arg __attribute__((unused)))
- /*!< in: a dummy parameter required by
- os_thread_create */
+void
+trx_rollback_or_clean_recovered(
+/*============================*/
+ ibool all) /*!< in: FALSE=roll back dictionary transactions;
+ TRUE=roll back all non-PREPARED transactions */
{
trx_t* trx;
mutex_enter(&kernel_mutex);
- if (UT_LIST_GET_FIRST(trx_sys->trx_list)) {
+ if (!UT_LIST_GET_FIRST(trx_sys->trx_list)) {
+ goto leave_function;
+ }
+ if (all) {
fprintf(stderr,
"InnoDB: Starting in background the rollback"
" of uncommitted transactions\n");
- } else {
- goto leave_function;
}
mutex_exit(&kernel_mutex);
@@ -584,18 +580,42 @@ loop:
goto loop;
case TRX_ACTIVE:
- mutex_exit(&kernel_mutex);
- trx_rollback_active(trx);
- goto loop;
+ if (all || trx_get_dict_operation(trx)
+ != TRX_DICT_OP_NONE) {
+ mutex_exit(&kernel_mutex);
+ trx_rollback_active(trx);
+ goto loop;
+ }
}
}
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Rollback of non-prepared transactions completed\n");
+ if (all) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Rollback of non-prepared"
+ " transactions completed\n");
+ }
leave_function:
mutex_exit(&kernel_mutex);
+}
+
+/*******************************************************************//**
+Rollback or clean up any incomplete transactions which were
+encountered in crash recovery. If the transaction already was
+committed, then we clean up a possible insert undo log. If the
+transaction was not yet committed, then we roll it back.
+Note: this is done in a background thread.
+@return a dummy parameter */
+UNIV_INTERN
+os_thread_ret_t
+trx_rollback_or_clean_all_recovered(
+/*================================*/
+ void* arg __attribute__((unused)))
+ /*!< in: a dummy parameter required by
+ os_thread_create */
+{
+ trx_rollback_or_clean_recovered(TRUE);
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
diff --git a/storage/innodb_plugin/trx/trx0trx.c b/storage/innodb_plugin/trx/trx0trx.c
index 4d4885062a6..21ba6e481a7 100644
--- a/storage/innodb_plugin/trx/trx0trx.c
+++ b/storage/innodb_plugin/trx/trx0trx.c
@@ -803,7 +803,7 @@ trx_commit_off_kernel(
in exactly the same order as commit lsn's, if the transactions
have different rollback segments. To get exactly the same
order we should hold the kernel mutex up to this point,
- adding to to the contention of the kernel mutex. However, if
+ adding to the contention of the kernel mutex. However, if
a transaction T2 is able to see modifications made by
a transaction T1, T2 will always get a bigger transaction
number and a bigger commit lsn than T1. */
@@ -950,7 +950,7 @@ trx_commit_off_kernel(
/****************************************************************//**
Cleans up a transaction at database startup. The cleanup is needed if
the transaction already got to the middle of a commit when the database
-crashed, andf we cannot roll it back. */
+crashed, and we cannot roll it back. */
UNIV_INTERN
void
trx_cleanup_at_db_startup(
diff --git a/storage/innodb_plugin/ut/ut0auxconf_atomic_pthread_t_solaris.c b/storage/innodb_plugin/ut/ut0auxconf_atomic_pthread_t_solaris.c
index a18a537d1d4..310603c7503 100644
--- a/storage/innodb_plugin/ut/ut0auxconf_atomic_pthread_t_solaris.c
+++ b/storage/innodb_plugin/ut/ut0auxconf_atomic_pthread_t_solaris.c
@@ -17,18 +17,38 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/*****************************************************************************
-If this program compiles, then pthread_t objects can be used as arguments
-to Solaris libc atomic functions.
+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 x = 0;
+ 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/innodb_plugin/ut/ut0auxconf_have_gcc_atomics.c b/storage/innodb_plugin/ut/ut0auxconf_have_gcc_atomics.c
new file mode 100644
index 00000000000..da5c13d7d79
--- /dev/null
+++ b/storage/innodb_plugin/ut/ut0auxconf_have_gcc_atomics.c
@@ -0,0 +1,61 @@
+/*****************************************************************************
+
+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/innodb_plugin/ut/ut0ut.c b/storage/innodb_plugin/ut/ut0ut.c
index e4cc226fbad..498873e290a 100644
--- a/storage/innodb_plugin/ut/ut0ut.c
+++ b/storage/innodb_plugin/ut/ut0ut.c
@@ -132,6 +132,7 @@ ut_time(void)
return(time(NULL));
}
+#ifndef UNIV_HOTBACKUP
/**********************************************************//**
Returns system time.
Upon successful completion, the value 0 is returned; otherwise the
@@ -200,6 +201,24 @@ ut_time_us(
}
/**********************************************************//**
+Returns the number of milliseconds since some epoch. The
+value may wrap around. It should only be used for heuristic
+purposes.
+@return ms since epoch */
+UNIV_INTERN
+ulint
+ut_time_ms(void)
+/*============*/
+{
+ struct timeval tv;
+
+ ut_gettimeofday(&tv, NULL);
+
+ return((ulint) tv.tv_sec * 1000 + tv.tv_usec / 1000);
+}
+#endif /* !UNIV_HOTBACKUP */
+
+/**********************************************************//**
Returns the difference of two times in seconds.
@return time2 - time1 expressed in seconds */
UNIV_INTERN
diff --git a/storage/innodb_plugin/win-plugin/README b/storage/innodb_plugin/win-plugin/README
deleted file mode 100644
index 00f4e996a3f..00000000000
--- a/storage/innodb_plugin/win-plugin/README
+++ /dev/null
@@ -1,22 +0,0 @@
-This directory contains patches that need to be applied to the MySQL
-source tree in order to build the dynamic plugin on Windows --
-HA_INNODB.DLL. Please note the followings when adding the patches:
-
-* The patch must be applied from the mysql top-level source directory.
- patch -p0 < win-plugin.diff
-* The patch filenames end in ".diff".
-* All patches here are expected to apply cleanly to the latest MySQL 5.1
- tree when storage/innobase is replaced with this InnoDB branch.
-
-When applying the patch, the following files will be modified:
-
- * CMakeLists.txt
- * sql/CMakeLists.txt
- * win/configure.js
-
-Also, two new files will be added:
-
- * sql/mysqld.def
- * sql/mysqld_x64.def
-
-You can get "patch" utility for Windows from http://unxutils.sourceforge.net/
diff --git a/storage/innodb_plugin/win-plugin/win-plugin.diff b/storage/innodb_plugin/win-plugin/win-plugin.diff
deleted file mode 100644
index 4b3354ac4de..00000000000
--- a/storage/innodb_plugin/win-plugin/win-plugin.diff
+++ /dev/null
@@ -1,279 +0,0 @@
-diff -Nur CMakeLists.txt.orig CMakeLists.txt
---- CMakeLists.txt.orig 2008-10-03 12:25:41 -05:00
-+++ CMakeLists.txt 2008-09-26 17:32:51 -05:00
-@@ -254,9 +254,9 @@
- IF(WITH_FEDERATED_STORAGE_ENGINE)
- ADD_SUBDIRECTORY(storage/federated)
- ENDIF(WITH_FEDERATED_STORAGE_ENGINE)
--IF(WITH_INNOBASE_STORAGE_ENGINE)
-+IF(WITH_INNOBASE_STORAGE_ENGINE OR INNODB_DYNAMIC_PLUGIN)
- ADD_SUBDIRECTORY(storage/innobase)
--ENDIF(WITH_INNOBASE_STORAGE_ENGINE)
-+ENDIF(WITH_INNOBASE_STORAGE_ENGINE OR INNODB_DYNAMIC_PLUGIN)
- ADD_SUBDIRECTORY(sql)
- ADD_SUBDIRECTORY(server-tools/instance-manager)
- ADD_SUBDIRECTORY(libmysql)
-
-diff -Nur sql/CMakeLists.txt.orig sql/CMakeLists.txt
---- sql/CMakeLists.txt.orig 2008-10-03 12:25:41 -05:00
-+++ sql/CMakeLists.txt 2008-09-24 03:58:19 -05:00
-@@ -98,6 +98,15 @@
- LINK_FLAGS "/PDB:${CMAKE_CFG_INTDIR}/mysqld${MYSQLD_EXE_SUFFIX}.pdb")
- ENDIF(cmake_version EQUAL 20406)
-
-+# Checks for 64-bit version
-+IF(CMAKE_SIZEOF_VOID_P MATCHES 8)
-+SET_TARGET_PROPERTIES(mysqld PROPERTIES
-+ LINK_FLAGS "/def:\"${PROJECT_SOURCE_DIR}/sql/mysqld_x64.def\"")
-+ELSE(CMAKE_SIZEOF_VOID_P MATCHES 8)
-+SET_TARGET_PROPERTIES(mysqld PROPERTIES
-+ LINK_FLAGS "/def:\"${PROJECT_SOURCE_DIR}/sql/mysqld.def\"")
-+ENDIF(CMAKE_SIZEOF_VOID_P MATCHES 8)
-+
- IF(EMBED_MANIFESTS)
- MYSQL_EMBED_MANIFEST("mysqld" "asInvoker")
- ENDIF(EMBED_MANIFESTS)
-
-diff -Nur sql/mysqld.def.orig sql/mysqld.def
---- sql/mysqld.def.orig 1969-12-31 18:00:00 -06:00
-+++ sql/mysqld.def 2009-04-09 02:20:32 -05:00
-@@ -0,0 +1,111 @@
-+EXPORTS
-+ ?use_hidden_primary_key@handler@@UAEXXZ
-+ ?get_dynamic_partition_info@handler@@UAEXPAUPARTITION_INFO@@I@Z
-+ ?read_first_row@handler@@UAEHPAEI@Z
-+ ?read_range_next@handler@@UAEHXZ
-+ ?read_range_first@handler@@UAEHPBUst_key_range@@0_N1@Z
-+ ?read_multi_range_first@handler@@UAEHPAPAUst_key_multi_range@@PAU2@I_NPAUst_handler_buffer@@@Z
-+ ?read_multi_range_next@handler@@UAEHPAPAUst_key_multi_range@@@Z
-+ ?index_read_idx_map@handler@@UAEHPAEIPBEKW4ha_rkey_function@@@Z
-+ ?print_error@handler@@UAEXHH@Z
-+ ?clone@handler@@UAEPAV1@PAUst_mem_root@@@Z
-+ ?get_auto_increment@handler@@UAEX_K00PA_K1@Z
-+ ?index_next_same@handler@@UAEHPAEPBEI@Z
-+ ?get_error_message@handler@@UAE_NHPAVString@@@Z
-+ ?ha_thd@handler@@IBEPAVTHD@@XZ
-+ ?update_auto_increment@handler@@QAEHXZ
-+ ?ha_statistic_increment@handler@@IBEXPQsystem_status_var@@K@Z
-+ ?trans_register_ha@@YAXPAVTHD@@_NPAUhandlerton@@@Z
-+ ?cmp@Field_blob@@QAEHPBEI0I@Z
-+ ?set_time@Field_timestamp@@QAEXXZ
-+ ?sql_print_error@@YAXPBDZZ
-+ ?sql_print_warning@@YAXPBDZZ
-+ ?check_global_access@@YA_NPAVTHD@@K@Z
-+ ?schema_table_store_record@@YA_NPAVTHD@@PAUst_table@@@Z
-+ ?get_quote_char_for_identifier@@YAHPAVTHD@@PBDI@Z
-+ ?copy@String@@QAE_NXZ
-+ ?copy@String@@QAE_NABV1@@Z
-+ ?copy@String@@QAE_NPBDIPAUcharset_info_st@@@Z
-+ ?copy_and_convert@@YAIPADIPAUcharset_info_st@@PBDI1PAI@Z
-+ ?filename_to_tablename@@YAIPBDPADI@Z
-+ ?strconvert@@YAIPAUcharset_info_st@@PBD0PADIPAI@Z
-+ ?calculate_key_len@@YAIPAUst_table@@IPBEK@Z
-+ ?sql_alloc@@YAPAXI@Z
-+ ?localtime_to_TIME@@YAXPAUst_mysql_time@@PAUtm@@@Z
-+ ?push_warning@@YAPAVMYSQL_ERROR@@PAVTHD@@W4enum_warning_level@1@IPBD@Z
-+ ?push_warning_printf@@YAXPAVTHD@@W4enum_warning_level@MYSQL_ERROR@@IPBDZZ
-+ ?drop_table@handler@@EAEXPBD@Z
-+ ?column_bitmaps_signal@handler@@UAEXXZ
-+ ?delete_table@handler@@MAEHPBD@Z
-+ ?rename_table@handler@@MAEHPBD0@Z
-+ ?key_map_empty@@3V?$Bitmap@$0EA@@@B
-+ ?THR_THD@@3PAVTHD@@A
-+ ?end_of_list@@3Ulist_node@@A
-+ ?mysql_tmpdir_list@@3Ust_my_tmpdir@@A
-+ mysql_query_cache_invalidate4
-+ thd_query
-+ thd_sql_command
-+ thd_get_thread_id
-+ thd_get_xid
-+ thd_slave_thread
-+ thd_non_transactional_update
-+ thd_mark_transaction_to_rollback
-+ thd_security_context
-+ thd_charset
-+ thd_test_options
-+ thd_ha_data
-+ thd_killed
-+ thd_tx_isolation
-+ thd_tablespace_op
-+ thd_sql_command
-+ thd_memdup
-+ thd_make_lex_string
-+ thd_in_lock_tables
-+ thd_binlog_format
-+ _my_hash_init
-+ my_hash_free
-+ my_tmpdir
-+ check_if_legal_filename
-+ my_filename
-+ my_sync_dir_by_file
-+ alloc_root
-+ thr_lock_data_init
-+ thr_lock_init
-+ thr_lock_delete
-+ my_multi_malloc
-+ get_charset
-+ unpack_filename
-+ my_hash_insert
-+ my_hash_search
-+ my_hash_delete
-+ mysql_bin_log_file_pos
-+ mysql_bin_log_file_name
-+ mysqld_embedded
-+ my_thread_name
-+ my_malloc
-+ my_no_flags_free
-+ _sanity
-+ _mymalloc
-+ _myfree
-+ _my_strdup
-+ _my_thread_var
-+ my_error
-+ pthread_cond_init
-+ pthread_cond_signal
-+ pthread_cond_wait
-+ pthread_cond_destroy
-+ localtime_r
-+ my_strdup
-+ deflate
-+ deflateEnd
-+ deflateReset
-+ deflateInit2_
-+ inflateEnd
-+ inflateInit_
-+ inflate
-+ compressBound
-+ inflateInit2_
-+ adler32
-+ longlong2str
-+ strend
-+ my_snprintf
-
-diff -Nur sql/mysqld_x64.def.orig sql/mysqld_x64.def
---- sql/mysqld_x64.def.orig 1969-12-31 18:00:00 -06:00
-+++ sql/mysqld_x64.def 2009-04-09 02:22:04 -05:00
-@@ -0,0 +1,111 @@
-+EXPORTS
-+ ?use_hidden_primary_key@handler@@UEAAXXZ
-+ ?get_dynamic_partition_info@handler@@UEAAXPEAUPARTITION_INFO@@I@Z
-+ ?read_first_row@handler@@UEAAHPEAEI@Z
-+ ?read_range_next@handler@@UEAAHXZ
-+ ?read_range_first@handler@@UEAAHPEBUst_key_range@@0_N1@Z
-+ ?read_multi_range_first@handler@@UEAAHPEAPEAUst_key_multi_range@@PEAU2@I_NPEAUst_handler_buffer@@@Z
-+ ?read_multi_range_next@handler@@UEAAHPEAPEAUst_key_multi_range@@@Z
-+ ?index_read_idx_map@handler@@UEAAHPEAEIPEBEKW4ha_rkey_function@@@Z
-+ ?print_error@handler@@UEAAXHH@Z
-+ ?clone@handler@@UEAAPEAV1@PEAUst_mem_root@@@Z
-+ ?get_auto_increment@handler@@UEAAX_K00PEA_K1@Z
-+ ?index_next_same@handler@@UEAAHPEAEPEBEI@Z
-+ ?get_error_message@handler@@UEAA_NHPEAVString@@@Z
-+ ?ha_thd@handler@@IEBAPEAVTHD@@XZ
-+ ?update_auto_increment@handler@@QEAAHXZ
-+ ?ha_statistic_increment@handler@@IEBAXPEQsystem_status_var@@K@Z
-+ ?trans_register_ha@@YAXPEAVTHD@@_NPEAUhandlerton@@@Z
-+ ?cmp@Field_blob@@QEAAHPEBEI0I@Z
-+ ?set_time@Field_timestamp@@QEAAXXZ
-+ ?sql_print_error@@YAXPEBDZZ
-+ ?sql_print_warning@@YAXPEBDZZ
-+ ?check_global_access@@YA_NPEAVTHD@@K@Z
-+ ?schema_table_store_record@@YA_NPEAVTHD@@PEAUst_table@@@Z
-+ ?get_quote_char_for_identifier@@YAHPEAVTHD@@PEBDI@Z
-+ ?copy@String@@QEAA_NXZ
-+ ?copy@String@@QEAA_NAEBV1@@Z
-+ ?copy@String@@QEAA_NPEBDIPEAUcharset_info_st@@@Z
-+ ?copy_and_convert@@YAIPEADIPEAUcharset_info_st@@PEBDI1PEAI@Z
-+ ?filename_to_tablename@@YAIPEBDPEADI@Z
-+ ?strconvert@@YAIPEAUcharset_info_st@@PEBD0PEADIPEAI@Z
-+ ?calculate_key_len@@YAIPEAUst_table@@IPEBEK@Z
-+ ?sql_alloc@@YAPEAX_K@Z
-+ ?localtime_to_TIME@@YAXPEAUst_mysql_time@@PEAUtm@@@Z
-+ ?push_warning@@YAPEAVMYSQL_ERROR@@PEAVTHD@@W4enum_warning_level@1@IPEBD@Z
-+ ?push_warning_printf@@YAXPEAVTHD@@W4enum_warning_level@MYSQL_ERROR@@IPEBDZZ
-+ ?drop_table@handler@@EEAAXPEBD@Z
-+ ?column_bitmaps_signal@handler@@UEAAXXZ
-+ ?delete_table@handler@@MEAAHPEBD@Z
-+ ?rename_table@handler@@MEAAHPEBD0@Z
-+ ?key_map_empty@@3V?$Bitmap@$0EA@@@B
-+ ?THR_THD@@3PEAVTHD@@EA
-+ ?end_of_list@@3Ulist_node@@A
-+ ?mysql_tmpdir_list@@3Ust_my_tmpdir@@A
-+ mysql_query_cache_invalidate4
-+ thd_query
-+ thd_sql_command
-+ thd_get_thread_id
-+ thd_get_xid
-+ thd_slave_thread
-+ thd_non_transactional_update
-+ thd_mark_transaction_to_rollback
-+ thd_security_context
-+ thd_charset
-+ thd_test_options
-+ thd_ha_data
-+ thd_killed
-+ thd_tx_isolation
-+ thd_tablespace_op
-+ thd_sql_command
-+ thd_memdup
-+ thd_make_lex_string
-+ thd_in_lock_tables
-+ thd_binlog_format
-+ _my_hash_init
-+ my_hash_free
-+ my_tmpdir
-+ check_if_legal_filename
-+ my_filename
-+ my_sync_dir_by_file
-+ alloc_root
-+ thr_lock_data_init
-+ thr_lock_init
-+ thr_lock_delete
-+ my_multi_malloc
-+ get_charset
-+ unpack_filename
-+ my_hash_insert
-+ my_hash_search
-+ my_hash_delete
-+ mysql_bin_log_file_pos
-+ mysql_bin_log_file_name
-+ mysqld_embedded
-+ my_thread_name
-+ my_malloc
-+ my_no_flags_free
-+ _sanity
-+ _mymalloc
-+ _myfree
-+ _my_strdup
-+ _my_thread_var
-+ my_error
-+ pthread_cond_init
-+ pthread_cond_signal
-+ pthread_cond_wait
-+ pthread_cond_destroy
-+ localtime_r
-+ my_strdup
-+ deflate
-+ deflateEnd
-+ deflateReset
-+ deflateInit2_
-+ inflateEnd
-+ inflateInit_
-+ inflate
-+ compressBound
-+ inflateInit2_
-+ adler32
-+ longlong2str
-+ strend
-+ my_snprintf
-
-diff -Nur win/configure.js.orig win/configure.js
---- win/configure.js.orig 2008-09-26 21:18:37 -05:00
-+++ win/configure.js 2008-10-01 11:21:27 -05:00
-@@ -50,6 +50,7 @@
- case "EMBED_MANIFESTS":
- case "EXTRA_DEBUG":
- case "WITH_EMBEDDED_SERVER":
-+ case "INNODB_DYNAMIC_PLUGIN":
- configfile.WriteLine("SET (" + args.Item(i) + " TRUE)");
- break;
- case "MYSQL_SERVER_SUFFIX":
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 1b583353126..dc2ba8c43f4 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -665,10 +665,9 @@ int maria_check_definition(MARIA_KEYDEF *t1_keyinfo,
extern "C" {
-volatile int *_ma_killed_ptr(HA_CHECK *param)
+int _ma_killed_ptr(HA_CHECK *param)
{
- /* In theory Unsafe conversion, but should be ok for now */
- return (int*) &(((THD *) (param->thd))->killed);
+ return thd_killed((THD*)param->thd);
}
@@ -1928,8 +1927,7 @@ end:
bool ha_maria::check_and_repair(THD *thd)
{
int error, crashed;
- char *old_query;
- uint old_query_length;
+ LEX_STRING old_query;
HA_CHECK_OPT check_opt;
DBUG_ENTER("ha_maria::check_and_repair");
@@ -1957,11 +1955,9 @@ bool ha_maria::check_and_repair(THD *thd)
if (!file->state->del && (maria_recover_options & HA_RECOVER_QUICK))
check_opt.flags |= T_QUICK;
- old_query= thd->query;
- old_query_length= thd->query_length;
+ old_query= thd->query_string;
pthread_mutex_lock(&LOCK_thread_count);
- thd->query= table->s->table_name.str;
- thd->query_length= table->s->table_name.length;
+ thd->query_string= table->s->table_name;
pthread_mutex_unlock(&LOCK_thread_count);
if (!(crashed= maria_is_crashed(file)))
@@ -1981,8 +1977,7 @@ bool ha_maria::check_and_repair(THD *thd)
error= 1;
}
pthread_mutex_lock(&LOCK_thread_count);
- thd->query= old_query;
- thd->query_length= old_query_length;
+ thd->query_string= old_query;
pthread_mutex_unlock(&LOCK_thread_count);
DBUG_RETURN(error);
}
@@ -2292,7 +2287,7 @@ int ha_maria::delete_all_rows()
{
THD *thd= current_thd;
(void) translog_log_debug_info(file->trn, LOGREC_DEBUG_INFO_QUERY,
- (uchar*) thd->query, thd->query_length);
+ (uchar*) thd->query(), thd->query_length());
if (file->s->now_transactional &&
((table->in_use->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) ||
table->in_use->locked_tables))
@@ -2311,7 +2306,7 @@ int ha_maria::delete_table(const char *name)
{
THD *thd= current_thd;
(void) translog_log_debug_info(0, LOGREC_DEBUG_INFO_QUERY,
- (uchar*) thd->query, thd->query_length);
+ (uchar*) thd->query(), thd->query_length());
return maria_delete_table(name);
}
@@ -2392,7 +2387,8 @@ int ha_maria::external_lock(THD *thd, int lock_type)
trnman_set_flags(trn, trnman_get_flags(trn) | TRN_STATE_INFO_LOGGED |
TRN_STATE_TABLES_CAN_CHANGE);
(void) translog_log_debug_info(trn, LOGREC_DEBUG_INFO_QUERY,
- (uchar*) thd->query, thd->query_length);
+ (uchar*) thd->query(),
+ thd->query_length());
}
#endif
}
@@ -2488,7 +2484,8 @@ int ha_maria::start_stmt(THD *thd, thr_lock_type lock_type)
{
trnman_set_flags(trn, trnman_get_flags(trn) | TRN_STATE_INFO_LOGGED);
(void) translog_log_debug_info(trn, LOGREC_DEBUG_INFO_QUERY,
- (uchar*) thd->query, thd->query_length);
+ (uchar*) thd->query(),
+ thd->query_length());
}
#endif
}
@@ -2769,7 +2766,7 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
create_flags|= HA_CREATE_PAGE_CHECKSUM;
(void) translog_log_debug_info(0, LOGREC_DEBUG_INFO_QUERY,
- (uchar*) thd->query, thd->query_length);
+ (uchar*) thd->query(), thd->query_length());
/* TODO: Check that the following fn_format is really needed */
error=
@@ -2789,7 +2786,7 @@ int ha_maria::rename_table(const char *from, const char *to)
{
THD *thd= current_thd;
(void) translog_log_debug_info(0, LOGREC_DEBUG_INFO_QUERY,
- (uchar*) thd->query, thd->query_length);
+ (uchar*) thd->query(), thd->query_length());
return maria_rename(from, to);
}
@@ -3341,7 +3338,7 @@ mysql_declare_plugin(maria)
MYSQL_STORAGE_ENGINE_PLUGIN,
&maria_storage_engine,
"MARIA",
- "MySQL AB",
+ "Monty Program Ab",
"Crash-safe tables with MyISAM heritage",
PLUGIN_LICENSE_GPL,
ha_maria_init, /* Plugin Init */
diff --git a/storage/maria/lockman.c b/storage/maria/lockman.c
index e7f3c81b0fd..d6d4dcd44e6 100644
--- a/storage/maria/lockman.c
+++ b/storage/maria/lockman.c
@@ -360,7 +360,7 @@ retry:
else
{
if (my_atomic_casptr((void **)cursor->prev,
- (void **)&cursor->curr, cursor->next))
+ (void **)(char*) &cursor->curr, cursor->next))
_lf_alloc_free(pins, cursor->curr);
else
{
@@ -421,7 +421,8 @@ static int lockinsert(LOCK * volatile *head, LOCK *node, LF_PINS *pins,
node->link= (intptr)cursor.curr;
DBUG_ASSERT(node->link != (intptr)node);
DBUG_ASSERT(cursor.prev != &node->link);
- if (!my_atomic_casptr((void **)cursor.prev, (void **)&cursor.curr, node))
+ if (!my_atomic_casptr((void **)cursor.prev,
+ (void **)(char*) &cursor.curr, node))
{
res= REPEAT_ONCE_MORE;
node->flags&= ~ACTIVE;
@@ -498,11 +499,11 @@ static int lockdelete(LOCK * volatile *head, LOCK *node, LF_PINS *pins)
then we can delete. Good news is - this is only required when rolling
back a savepoint.
*/
- if (my_atomic_casptr((void **)&(cursor.curr->link),
- (void **)&cursor.next, 1+(char *)cursor.next))
+ if (my_atomic_casptr((void **)(char*)&(cursor.curr->link),
+ (void **)(char*)&cursor.next, 1+(char *)cursor.next))
{
if (my_atomic_casptr((void **)cursor.prev,
- (void **)&cursor.curr, cursor.next))
+ (void **)(char*)&cursor.curr, cursor.next))
_lf_alloc_free(pins, cursor.curr);
else
lockfind(head, node, &cursor, pins);
@@ -573,7 +574,7 @@ static void initialize_bucket(LOCKMAN *lm, LOCK * volatile *node,
my_free((void *)dummy, MYF(0));
dummy= cur;
}
- my_atomic_casptr((void **)node, (void **)&tmp, dummy);
+ my_atomic_casptr((void **)node, (void **)(char*) &tmp, dummy);
}
static inline uint calc_hash(uint64 resource)
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index e33849bef04..3314a21871a 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -215,7 +215,7 @@ int maria_chk_del(HA_CHECK *param, register MARIA_HA *info,
empty=0;
for (i= share->state.state.del ; i > 0L && next_link != HA_OFFSET_ERROR ; i--)
{
- if (*_ma_killed_ptr(param))
+ if (_ma_killed_ptr(param))
DBUG_RETURN(1);
if (test_flag & T_VERBOSE)
printf(" %9s",llstr(next_link,buff));
@@ -310,7 +310,7 @@ static int check_k_link(HA_CHECK *param, register MARIA_HA *info,
records= (ha_rows) (share->state.state.key_file_length / block_size);
while (next_link != HA_OFFSET_ERROR && records > 0)
{
- if (*_ma_killed_ptr(param))
+ if (_ma_killed_ptr(param))
DBUG_RETURN(1);
if (param->testflag & T_VERBOSE)
printf("%16s",llstr(next_link,llbuff));
@@ -876,10 +876,10 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
tmp_key.data= tmp_key_buff;
for ( ;; )
{
- if (*_ma_killed_ptr(param))
- goto err;
if (nod_flag)
{
+ if (_ma_killed_ptr(param))
+ goto err;
next_page= _ma_kpos(nod_flag,keypos);
if (chk_index_down(param,info,keyinfo,next_page,
temp_buff,keys,key_checksum,level+1))
@@ -1180,7 +1180,7 @@ static int check_static_record(HA_CHECK *param, MARIA_HA *info, int extend,
pos= 0;
while (pos < share->state.state.data_file_length)
{
- if (*_ma_killed_ptr(param))
+ if (_ma_killed_ptr(param))
return -1;
if (my_b_read(&param->read_cache, record,
share->base.pack_reclength))
@@ -1230,7 +1230,7 @@ static int check_dynamic_record(HA_CHECK *param, MARIA_HA *info, int extend,
{
my_bool got_error= 0;
int flag;
- if (*_ma_killed_ptr(param))
+ if (_ma_killed_ptr(param))
DBUG_RETURN(-1);
flag= block_info.second_read=0;
@@ -1451,7 +1451,7 @@ static int check_compressed_record(HA_CHECK *param, MARIA_HA *info, int extend,
pos= share->pack.header_length; /* Skip header */
while (pos < share->state.state.data_file_length)
{
- if (*_ma_killed_ptr(param))
+ if (_ma_killed_ptr(param))
DBUG_RETURN(-1);
if (_ma_read_cache(&param->read_cache, block_info.header, pos,
@@ -1815,7 +1815,7 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
LINT_INIT(row_count);
LINT_INIT(empty_space);
- if (*_ma_killed_ptr(param))
+ if (_ma_killed_ptr(param))
{
_ma_scan_end_block_record(info);
return -1;
@@ -4631,7 +4631,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
char llbuff[22],llbuff2[22];
DBUG_ENTER("sort_get_next_record");
- if (*_ma_killed_ptr(param))
+ if (_ma_killed_ptr(param))
DBUG_RETURN(1);
switch (sort_info->org_data_file_type) {
diff --git a/storage/maria/ma_check_standalone.h b/storage/maria/ma_check_standalone.h
index 3874d722d6c..9b30c96089f 100644
--- a/storage/maria/ma_check_standalone.h
+++ b/storage/maria/ma_check_standalone.h
@@ -30,11 +30,9 @@
Check if check/repair operation was killed by a signal
*/
-static int not_killed= 0;
-
-volatile int *_ma_killed_ptr(HA_CHECK *param __attribute__((unused)))
+int _ma_killed_ptr(HA_CHECK *param __attribute__((unused)))
{
- return &not_killed; /* always NULL */
+ return 0;
}
/* print warnings and errors */
diff --git a/storage/maria/ma_ft_boolean_search.c b/storage/maria/ma_ft_boolean_search.c
index 763b8827a6c..6cd23558784 100644
--- a/storage/maria/ma_ft_boolean_search.c
+++ b/storage/maria/ma_ft_boolean_search.c
@@ -180,7 +180,7 @@ typedef struct st_my_ftb_param
static int ftb_query_add_word(MYSQL_FTPARSER_PARAM *param,
- char *word, int word_len,
+ const uchar *word, mysql_ft_size_t word_len,
MYSQL_FTPARSER_BOOLEAN_INFO *info)
{
MY_FTB_PARAM *ftb_param= param->mysql_ftparam;
@@ -282,24 +282,24 @@ static int ftb_query_add_word(MYSQL_FTPARSER_PARAM *param,
static int ftb_parse_query_internal(MYSQL_FTPARSER_PARAM *param,
- char *query, int len)
+ const uchar *query, mysql_ft_size_t len)
{
MY_FTB_PARAM *ftb_param= param->mysql_ftparam;
MYSQL_FTPARSER_BOOLEAN_INFO info;
CHARSET_INFO *cs= ftb_param->ftb->charset;
- uchar **start= (uchar**) &query;
- uchar *end= (uchar*) query + len;
+ const uchar **start= &query;
+ const uchar *end= query + len;
FT_WORD w;
info.prev= ' ';
info.quot= 0;
while (maria_ft_get_word(cs, start, end, &w, &info))
- param->mysql_add_word(param, (char *) w.pos, w.len, &info);
+ param->mysql_add_word(param, w.pos, w.len, &info);
return(0);
}
-static int _ftb_parse_query(FTB *ftb, uchar *query, uint len,
+static int _ftb_parse_query(FTB *ftb, uchar *query, size_t len,
struct st_mysql_ftparser *parser)
{
MYSQL_FTPARSER_PARAM *param;
@@ -321,7 +321,7 @@ static int _ftb_parse_query(FTB *ftb, uchar *query, uint len,
param->mysql_add_word= ftb_query_add_word;
param->mysql_ftparam= (void *)&ftb_param;
param->cs= ftb->charset;
- param->doc= (char*) query;
+ param->doc= query;
param->length= len;
param->flags= 0;
param->mode= MYSQL_FTPARSER_FULL_BOOLEAN_INFO;
@@ -539,8 +539,8 @@ static void _ftb_init_index_search(FT_INFO *ftb)
FT_INFO * maria_ft_init_boolean_search(MARIA_HA *info, uint keynr,
- uchar *query,
- uint query_len, CHARSET_INFO *cs)
+ uchar *query, size_t query_len,
+ CHARSET_INFO *cs)
{
FTB *ftb;
FTB_EXPR *ftbe;
@@ -615,8 +615,9 @@ typedef struct st_my_ftb_phrase_param
static int ftb_phrase_add_word(MYSQL_FTPARSER_PARAM *param,
- char *word, int word_len,
- MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info __attribute__((unused)))
+ const uchar *word, mysql_ft_size_t word_len,
+ MYSQL_FTPARSER_BOOLEAN_INFO
+ *boolean_info __attribute__((unused)))
{
MY_FTB_PHRASE_PARAM *phrase_param= param->mysql_ftparam;
FT_WORD *w= (FT_WORD *)phrase_param->document->data;
@@ -647,15 +648,16 @@ static int ftb_phrase_add_word(MYSQL_FTPARSER_PARAM *param,
static int ftb_check_phrase_internal(MYSQL_FTPARSER_PARAM *param,
- char *document, int len)
+ const uchar *document,
+ mysql_ft_size_t len)
{
FT_WORD word;
MY_FTB_PHRASE_PARAM *phrase_param= param->mysql_ftparam;
- const uchar *docend= (uchar*) document + len;
- while (maria_ft_simple_get_word(phrase_param->cs, (uchar**) &document,
+ const uchar *docend= document + len;
+ while (maria_ft_simple_get_word(phrase_param->cs, &document,
docend, &word, FALSE))
{
- param->mysql_add_word(param, (char*) word.pos, word.len, 0);
+ param->mysql_add_word(param, word.pos, word.len, 0);
if (phrase_param->match)
break;
}
@@ -678,8 +680,8 @@ static int ftb_check_phrase_internal(MYSQL_FTPARSER_PARAM *param,
-1 is returned if error occurs.
*/
-static int _ftb_check_phrase(FTB *ftb, const uchar *document, uint len,
- FTB_EXPR *ftbe, struct st_mysql_ftparser *parser)
+static int _ftb_check_phrase(FTB *ftb, const uchar *document, size_t len,
+ FTB_EXPR *ftbe, struct st_mysql_ftparser *parser)
{
MY_FTB_PHRASE_PARAM ftb_param;
MYSQL_FTPARSER_PARAM *param;
@@ -699,7 +701,7 @@ static int _ftb_check_phrase(FTB *ftb, const uchar *document, uint len,
param->mysql_add_word= ftb_phrase_add_word;
param->mysql_ftparam= (void *)&ftb_param;
param->cs= ftb->charset;
- param->doc= (char *) document;
+ param->doc= document;
param->length= len;
param->flags= 0;
param->mode= MYSQL_FTPARSER_WITH_STOPWORDS;
@@ -872,8 +874,9 @@ typedef struct st_my_ftb_find_param
static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param,
- char *word, int len,
- MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info __attribute__((unused)))
+ const uchar *word, mysql_ft_size_t len,
+ MYSQL_FTPARSER_BOOLEAN_INFO
+ *boolean_info __attribute__((unused)))
{
MY_FTB_FIND_PARAM *ftb_param= param->mysql_ftparam;
FT_INFO *ftb= ftb_param->ftb;
@@ -933,15 +936,14 @@ static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param,
static int ftb_find_relevance_parse(MYSQL_FTPARSER_PARAM *param,
- char *doc, int len)
+ const uchar *doc, mysql_ft_size_t len)
{
MY_FTB_FIND_PARAM *ftb_param= param->mysql_ftparam;
FT_INFO *ftb= ftb_param->ftb;
- uchar *end= (uchar*) doc + len;
+ const uchar *end= doc + len;
FT_WORD w;
- while (maria_ft_simple_get_word(ftb->charset, (uchar**) &doc,
- end, &w, TRUE))
- param->mysql_add_word(param, (char *) w.pos, w.len, 0);
+ while (maria_ft_simple_get_word(ftb->charset, &doc, end, &w, TRUE))
+ param->mysql_add_word(param, w.pos, w.len, 0);
return(0);
}
@@ -998,7 +1000,7 @@ float maria_ft_boolean_find_relevance(FT_INFO *ftb, uchar *record, uint length)
{
if (!ftsi.pos)
continue;
- param->doc= (char *)ftsi.pos;
+ param->doc= ftsi.pos;
param->length= ftsi.len;
if (unlikely(parser->parse(param)))
return 0;
diff --git a/storage/maria/ma_ft_nlq_search.c b/storage/maria/ma_ft_nlq_search.c
index 1a85c50174e..927f34f8b72 100644
--- a/storage/maria/ma_ft_nlq_search.c
+++ b/storage/maria/ma_ft_nlq_search.c
@@ -51,6 +51,7 @@ typedef struct st_ft_superdoc
double tmp_weight;
} FT_SUPERDOC;
+
static int FT_SUPERDOC_cmp(void* cmp_arg __attribute__((unused)),
FT_SUPERDOC *p1, FT_SUPERDOC *p2)
{
@@ -63,7 +64,8 @@ static int FT_SUPERDOC_cmp(void* cmp_arg __attribute__((unused)),
static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
{
- int subkeys, r;
+ FT_WEIGTH subkeys;
+ int r;
uint doc_cnt;
FT_SUPERDOC sdoc, *sptr;
TREE_ELEMENT *selem;
@@ -90,9 +92,9 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
/* Skip rows inserted by current inserted */
for (r= _ma_search(info, &key, SEARCH_FIND, key_root) ;
!r &&
- (subkeys=ft_sintXkorr(info->last_key.data +
- info->last_key.data_length +
- info->last_key.ref_length - extra)) > 0 &&
+ (subkeys.i= ft_sintXkorr(info->last_key.data +
+ info->last_key.data_length +
+ info->last_key.ref_length - extra)) > 0 &&
info->cur_row.lastpos >= info->state->data_file_length ;
r= _ma_search_next(info, &info->last_key, SEARCH_BIGGER, key_root))
;
@@ -111,7 +113,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
key.data+1, key.data_length-1, 0, 0))
break;
- if (subkeys<0)
+ if (subkeys.i < 0)
{
if (doc_cnt)
DBUG_RETURN(1); /* index is corrupted */
@@ -127,7 +129,8 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
goto do_skip;
}
#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
- tmp_weight=*(float*)&subkeys;
+ /* The weight we read was actually a float */
+ tmp_weight= subkeys.f;
#else
#error
#endif
@@ -162,9 +165,9 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
else
r= _ma_search(info, &info->last_key, SEARCH_BIGGER, key_root);
do_skip:
- while ((subkeys=ft_sintXkorr(info->last_key.data +
- info->last_key.data_length +
- info->last_key.ref_length - extra)) > 0 &&
+ while ((subkeys.i= ft_sintXkorr(info->last_key.data +
+ info->last_key.data_length +
+ info->last_key.ref_length - extra)) > 0 &&
!r && info->cur_row.lastpos >= info->state->data_file_length)
r= _ma_search_next(info, &info->last_key, SEARCH_BIGGER, key_root);
@@ -205,7 +208,7 @@ static int FT_DOC_cmp(void *unused __attribute__((unused)),
FT_INFO *maria_ft_init_nlq_search(MARIA_HA *info, uint keynr, uchar *query,
- uint query_len, uint flags, uchar *record)
+ size_t query_len, uint flags, uchar *record)
{
TREE wtree;
ALL_IN_ONE aio;
diff --git a/storage/maria/ma_ft_parser.c b/storage/maria/ma_ft_parser.c
index bdfbbb936ce..9c988c41c7b 100644
--- a/storage/maria/ma_ft_parser.c
+++ b/storage/maria/ma_ft_parser.c
@@ -109,10 +109,11 @@ my_bool maria_ft_boolean_check_syntax_string(const uchar *str)
3 - right bracket
4 - stopword found
*/
-uchar maria_ft_get_word(CHARSET_INFO *cs, uchar **start, uchar *end,
+uchar maria_ft_get_word(CHARSET_INFO *cs, const uchar **start,
+ const uchar *end,
FT_WORD *word, MYSQL_FTPARSER_BOOLEAN_INFO *param)
{
- uchar *doc=*start;
+ const uchar *doc= *start;
int ctype;
uint mwc, length;
int mbl;
@@ -203,11 +204,11 @@ ret:
return param->type;
}
-uchar maria_ft_simple_get_word(CHARSET_INFO *cs, uchar **start,
+uchar maria_ft_simple_get_word(CHARSET_INFO *cs, const uchar **start,
const uchar *end, FT_WORD *word,
my_bool skip_stopwords)
{
- uchar *doc= *start;
+ const uchar *doc= *start;
uint mwc, length;
int ctype, mbl;
DBUG_ENTER("maria_ft_simple_get_word");
@@ -259,8 +260,9 @@ void maria_ft_parse_init(TREE *wtree, CHARSET_INFO *cs)
static int maria_ft_add_word(MYSQL_FTPARSER_PARAM *param,
- char *word, int word_len,
- MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info __attribute__((unused)))
+ const uchar *word, mysql_ft_size_t word_len,
+ MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info
+ __attribute__((unused)))
{
TREE *wtree;
FT_WORD w;
@@ -276,7 +278,7 @@ static int maria_ft_add_word(MYSQL_FTPARSER_PARAM *param,
w.pos= ptr;
}
else
- w.pos= (uchar *) word;
+ w.pos= word;
w.len= word_len;
if (!tree_insert(wtree, &w, 0, wtree->custom_arg))
{
@@ -288,24 +290,25 @@ static int maria_ft_add_word(MYSQL_FTPARSER_PARAM *param,
static int maria_ft_parse_internal(MYSQL_FTPARSER_PARAM *param,
- char *doc_arg, int doc_len)
+ const uchar *doc_arg,
+ mysql_ft_size_t doc_len)
{
- uchar *doc= (uchar*) doc_arg;
- uchar *end= doc + doc_len;
+ const uchar *doc= doc_arg;
+ const uchar *end= doc + doc_len;
MY_FT_PARSER_PARAM *ft_param=param->mysql_ftparam;
TREE *wtree= ft_param->wtree;
FT_WORD w;
DBUG_ENTER("maria_ft_parse_internal");
while (maria_ft_simple_get_word(wtree->custom_arg, &doc, end, &w, TRUE))
- if (param->mysql_add_word(param, (char *) w.pos, w.len, 0))
+ if (param->mysql_add_word(param, w.pos, w.len, 0))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
-int maria_ft_parse(TREE *wtree, uchar *doc, int doclen,
- struct st_mysql_ftparser *parser,
+int maria_ft_parse(TREE *wtree, uchar *doc, size_t doclen,
+ struct st_mysql_ftparser *parser,
MYSQL_FTPARSER_PARAM *param, MEM_ROOT *mem_root)
{
MY_FT_PARSER_PARAM my_param;
@@ -318,7 +321,7 @@ int maria_ft_parse(TREE *wtree, uchar *doc, int doclen,
param->mysql_add_word= maria_ft_add_word;
param->mysql_ftparam= &my_param;
param->cs= wtree->custom_arg;
- param->doc= (char *) doc;
+ param->doc= doc;
param->length= doclen;
param->mode= MYSQL_FTPARSER_SIMPLE_MODE;
DBUG_RETURN(parser->parse(param));
@@ -378,8 +381,8 @@ MYSQL_FTPARSER_PARAM *maria_ftparser_call_initializer(MARIA_HA *info,
mysql_add_word != 0 - parser is initialized, or no
initialization needed. */
info->ftparser_param[ftparser_nr].mysql_add_word=
- (int (*)(struct st_mysql_ftparser_param *, char *, int,
- MYSQL_FTPARSER_BOOLEAN_INFO *)) 1;
+ (int (*)(struct st_mysql_ftparser_param *, const uchar *,
+ mysql_ft_size_t, MYSQL_FTPARSER_BOOLEAN_INFO *)) 1;
if (parser->init && parser->init(&info->ftparser_param[ftparser_nr]))
return 0;
}
diff --git a/storage/maria/ma_ftdefs.h b/storage/maria/ma_ftdefs.h
index 7e83d774aed..4ce4e9e22ba 100644
--- a/storage/maria/ma_ftdefs.h
+++ b/storage/maria/ma_ftdefs.h
@@ -96,7 +96,7 @@
#define FTB_RQUOT (ft_boolean_syntax[11])
typedef struct st_maria_ft_word {
- uchar * pos;
+ const uchar * pos;
uint len;
double weight;
} FT_WORD;
@@ -106,9 +106,9 @@ int is_stopword(char *word, uint len);
MARIA_KEY *_ma_ft_make_key(MARIA_HA *, MARIA_KEY *, uint , uchar *, FT_WORD *,
my_off_t);
-uchar maria_ft_get_word(CHARSET_INFO *, uchar **, uchar *, FT_WORD *,
- MYSQL_FTPARSER_BOOLEAN_INFO *);
-uchar maria_ft_simple_get_word(CHARSET_INFO *, uchar **, const uchar *,
+uchar maria_ft_get_word(CHARSET_INFO *, const uchar **, const uchar *,
+ FT_WORD *, MYSQL_FTPARSER_BOOLEAN_INFO *);
+uchar maria_ft_simple_get_word(CHARSET_INFO *, const uchar **, const uchar *,
FT_WORD *, my_bool);
typedef struct _st_maria_ft_seg_iterator {
@@ -122,15 +122,17 @@ void _ma_ft_segiterator_dummy_init(const uchar *, uint, FT_SEG_ITERATOR *);
uint _ma_ft_segiterator(FT_SEG_ITERATOR *);
void maria_ft_parse_init(TREE *, CHARSET_INFO *);
-int maria_ft_parse(TREE *, uchar *, int, struct st_mysql_ftparser *parser,
+int maria_ft_parse(TREE *, uchar *, size_t, struct st_mysql_ftparser *parser,
MYSQL_FTPARSER_PARAM *, MEM_ROOT *);
FT_WORD * maria_ft_linearize(TREE *, MEM_ROOT *);
FT_WORD * _ma_ft_parserecord(MARIA_HA *, uint, const uchar *, MEM_ROOT *);
uint _ma_ft_parse(TREE *, MARIA_HA *, uint, const uchar *,
MYSQL_FTPARSER_PARAM *, MEM_ROOT *);
-FT_INFO *maria_ft_init_nlq_search(MARIA_HA *, uint, uchar *, uint, uint, uchar *);
-FT_INFO *maria_ft_init_boolean_search(MARIA_HA *, uint, uchar *, uint, CHARSET_INFO *);
+FT_INFO *maria_ft_init_nlq_search(MARIA_HA *, uint, uchar *, size_t, uint,
+ uchar *);
+FT_INFO *maria_ft_init_boolean_search(MARIA_HA *, uint, uchar *, size_t,
+ CHARSET_INFO *);
extern const struct _ft_vft _ma_ft_vft_nlq;
int maria_ft_nlq_read_next(FT_INFO *, char *);
diff --git a/storage/maria/ma_sort.c b/storage/maria/ma_sort.c
index fa2cbab995a..387563ebaac 100644
--- a/storage/maria/ma_sort.c
+++ b/storage/maria/ma_sort.c
@@ -920,7 +920,6 @@ merge_buffers(MARIA_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
uchar *strpos;
BUFFPEK *buffpek,**refpek;
QUEUE queue;
- volatile int *killed= _ma_killed_ptr(info->sort_info->param);
DBUG_ENTER("merge_buffers");
count=error=0;
@@ -953,10 +952,6 @@ merge_buffers(MARIA_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
{
for (;;)
{
- if (*killed)
- {
- error=1; goto err;
- }
buffpek=(BUFFPEK*) queue_top(&queue);
if (to_file)
{
@@ -976,6 +971,12 @@ merge_buffers(MARIA_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
buffpek->key+=sort_length;
if (! --buffpek->mem_count)
{
+ /* It's enough to check for killedptr before a slow operation */
+ if (_ma_killed_ptr(info->sort_info->param))
+ {
+ error=1;
+ goto err;
+ }
if (!(error=(int) info->read_to_buffer(from_file,buffpek,sort_length)))
{
uchar *base= buffpek->base;
diff --git a/storage/maria/ma_state.c b/storage/maria/ma_state.c
index 0b7fba9f55a..d7ddc73e2b4 100644
--- a/storage/maria/ma_state.c
+++ b/storage/maria/ma_state.c
@@ -528,7 +528,7 @@ void _ma_remove_table_from_trnman(MARIA_SHARE *share, TRN *trn)
safe_mutex_assert_owner(&share->intern_lock);
- for (prev= (MARIA_USED_TABLES**) &trn->used_tables, tables= *prev;
+ for (prev= (MARIA_USED_TABLES**) (char*) &trn->used_tables, tables= *prev;
tables;
tables= *prev)
{
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index ada4ae3f426..ad93d566578 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -1160,7 +1160,7 @@ int _ma_flush_table_files(MARIA_HA *info, uint flush_data_or_index,
Functions needed by _ma_check (are overridden in MySQL/ha_maria.cc).
See ma_check_standalone.h .
*/
-volatile int *_ma_killed_ptr(HA_CHECK *param);
+int _ma_killed_ptr(HA_CHECK *param);
void _ma_check_print_error _VARARGS((HA_CHECK *param, const char *fmt, ...))
ATTRIBUTE_FORMAT(printf, 2, 3);
void _ma_check_print_warning _VARARGS((HA_CHECK *param, const char *fmt, ...))
diff --git a/storage/maria/maria_ftdump.c b/storage/maria/maria_ftdump.c
index 5e3b47b956e..8b545e6e9af 100644
--- a/storage/maria/maria_ftdump.c
+++ b/storage/maria/maria_ftdump.c
@@ -53,7 +53,7 @@ static struct my_option my_long_options[] =
int main(int argc,char *argv[])
{
- int error=0, subkeys;
+ int error=0;
uint keylen, keylen2=0, inx, doc_cnt=0;
float weight= 1.0;
double gws, min_gws=0, avg_gws=0;
@@ -112,11 +112,12 @@ int main(int argc,char *argv[])
while (!(error=maria_rnext(info,NULL,inx)))
{
+ FT_WEIGTH subkeys;
keylen=*(info->lastkey_buff);
- subkeys=ft_sintXkorr(info->lastkey_buff + keylen + 1);
- if (subkeys >= 0)
- weight=*(float*)&subkeys;
+ subkeys.i= ft_sintXkorr(info->lastkey_buff + keylen + 1);
+ if (subkeys.i >= 0)
+ weight= subkeys.f;
#ifdef HAVE_SNPRINTF
snprintf(buf,MAX_LEN,"%.*s",(int) keylen,info->lastkey_buff+1);
@@ -153,14 +154,15 @@ int main(int argc,char *argv[])
keylen2=keylen;
doc_cnt=0;
}
- doc_cnt+= (subkeys >= 0 ? 1 : -subkeys);
+ doc_cnt+= (subkeys.i >= 0 ? 1 : -subkeys.i);
}
if (dump)
{
- if (subkeys>=0)
+ if (subkeys.i >= 0)
printf("%9lx %20.7f %s\n", (long) info->cur_row.lastpos,weight,buf);
else
- printf("%9lx => %17d %s\n",(long) info->cur_row.lastpos,-subkeys,buf);
+ printf("%9lx => %17d %s\n",(long) info->cur_row.lastpos,-subkeys.i,
+ buf);
}
if (verbose && (total%HOW_OFTEN_TO_WRITE)==0)
printf("%10ld\r",total);
diff --git a/storage/maria/trnman.c b/storage/maria/trnman.c
index 43fac68806f..ceb8ad2ae2d 100644
--- a/storage/maria/trnman.c
+++ b/storage/maria/trnman.c
@@ -300,8 +300,8 @@ TRN *trnman_new_trn(WT_THD *wt)
(ABA isn't possible, we're behind a mutex
*/
my_atomic_rwlock_wrlock(&LOCK_pool);
- while (tmp.trn && !my_atomic_casptr((void **)&pool, &tmp.v,
- (void *)tmp.trn->next))
+ while (tmp.trn && !my_atomic_casptr((void **)(char*) &pool, &tmp.v,
+ (void *)tmp.trn->next))
/* no-op */;
my_atomic_rwlock_wrunlock(&LOCK_pool);
@@ -545,7 +545,7 @@ static void trnman_free_trn(TRN *trn)
down after the loop at -O2
*/
*(TRN * volatile *)&(trn->next)= tmp.trn;
- } while (!my_atomic_casptr((void **)&pool, &tmp.v, trn));
+ } while (!my_atomic_casptr((void **)(char*)&pool, &tmp.v, trn));
my_atomic_rwlock_wrunlock(&LOCK_pool);
}
diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c
index ddb932e234e..b09d8c43321 100644
--- a/storage/myisam/ft_boolean_search.c
+++ b/storage/myisam/ft_boolean_search.c
@@ -180,7 +180,7 @@ typedef struct st_my_ftb_param
static int ftb_query_add_word(MYSQL_FTPARSER_PARAM *param,
- char *word, int word_len,
+ const uchar *word, mysql_ft_size_t word_len,
MYSQL_FTPARSER_BOOLEAN_INFO *info)
{
MY_FTB_PARAM *ftb_param= param->mysql_ftparam;
@@ -282,19 +282,19 @@ static int ftb_query_add_word(MYSQL_FTPARSER_PARAM *param,
static int ftb_parse_query_internal(MYSQL_FTPARSER_PARAM *param,
- char *query, int len)
+ const uchar *query, mysql_ft_size_t len)
{
MY_FTB_PARAM *ftb_param= param->mysql_ftparam;
MYSQL_FTPARSER_BOOLEAN_INFO info;
CHARSET_INFO *cs= ftb_param->ftb->charset;
- uchar **start= (uchar**) &query;
- uchar *end= (uchar*) query + len;
+ const uchar **start= &query;
+ const uchar *end= query + len;
FT_WORD w;
info.prev= ' ';
info.quot= 0;
while (ft_get_word(cs, start, end, &w, &info))
- param->mysql_add_word(param, (char*) w.pos, w.len, &info);
+ param->mysql_add_word(param, w.pos, w.len, &info);
return(0);
}
@@ -616,7 +616,7 @@ typedef struct st_my_ftb_phrase_param
static int ftb_phrase_add_word(MYSQL_FTPARSER_PARAM *param,
- char *word, int word_len,
+ const uchar *word, mysql_ft_size_t word_len,
MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info __attribute__((unused)))
{
MY_FTB_PHRASE_PARAM *phrase_param= param->mysql_ftparam;
@@ -648,15 +648,16 @@ static int ftb_phrase_add_word(MYSQL_FTPARSER_PARAM *param,
static int ftb_check_phrase_internal(MYSQL_FTPARSER_PARAM *param,
- char *document, int len)
+ const uchar *document,
+ mysql_ft_size_t len)
{
FT_WORD word;
MY_FTB_PHRASE_PARAM *phrase_param= param->mysql_ftparam;
const uchar *docend= (uchar*) document + len;
- while (ft_simple_get_word(phrase_param->cs, (uchar**) &document, docend,
+ while (ft_simple_get_word(phrase_param->cs, &document, docend,
&word, FALSE))
{
- param->mysql_add_word(param, (char*) word.pos, word.len, 0);
+ param->mysql_add_word(param, word.pos, word.len, 0);
if (phrase_param->match)
break;
}
@@ -874,8 +875,9 @@ typedef struct st_my_ftb_find_param
static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param,
- char *word, int len,
- MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info __attribute__((unused)))
+ const uchar *word, mysql_ft_size_t len,
+ MYSQL_FTPARSER_BOOLEAN_INFO
+ *boolean_info __attribute__((unused)))
{
MY_FTB_FIND_PARAM *ftb_param= param->mysql_ftparam;
FT_INFO *ftb= ftb_param->ftb;
@@ -888,8 +890,8 @@ static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param,
for (a= 0, b= ftb->queue.elements, c= (a+b)/2; b-a>1; c= (a+b)/2)
{
ftbw= ftb->list[c];
- if (ha_compare_text(ftb->charset, (uchar*)word, len,
- (uchar*)ftbw->word+1, ftbw->len-1,
+ if (ha_compare_text(ftb->charset, word, len,
+ ftbw->word+1, ftbw->len-1,
(my_bool) (ftbw->flags & FTB_FLAG_TRUNC), 0) < 0)
b= c;
else
@@ -915,8 +917,8 @@ static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param,
for (; c >= 0; c--)
{
ftbw= ftb->list[c];
- if (ha_compare_text(ftb->charset, (uchar*)word, len,
- (uchar*)ftbw->word + 1,ftbw->len - 1,
+ if (ha_compare_text(ftb->charset, word, len,
+ ftbw->word + 1,ftbw->len - 1,
(my_bool)(ftbw->flags & FTB_FLAG_TRUNC), 0))
{
if (ftb->with_scan & FTB_FLAG_TRUNC)
@@ -935,14 +937,14 @@ static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param,
static int ftb_find_relevance_parse(MYSQL_FTPARSER_PARAM *param,
- char *doc, int len)
+ const uchar *doc, mysql_ft_size_t len)
{
MY_FTB_FIND_PARAM *ftb_param= param->mysql_ftparam;
FT_INFO *ftb= ftb_param->ftb;
- uchar *end= (uchar*) doc + len;
+ const uchar *end= doc + len;
FT_WORD w;
- while (ft_simple_get_word(ftb->charset, (uchar**) &doc, end, &w, TRUE))
- param->mysql_add_word(param, (char*) w.pos, w.len, 0);
+ while (ft_simple_get_word(ftb->charset, &doc, end, &w, TRUE))
+ param->mysql_add_word(param, w.pos, w.len, 0);
return(0);
}
diff --git a/storage/myisam/ft_nlq_search.c b/storage/myisam/ft_nlq_search.c
index eb563638d36..c4d27bcbd8e 100644
--- a/storage/myisam/ft_nlq_search.c
+++ b/storage/myisam/ft_nlq_search.c
@@ -63,7 +63,8 @@ static int FT_SUPERDOC_cmp(void* cmp_arg __attribute__((unused)),
static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
{
- int subkeys, r;
+ FT_WEIGTH subkeys;
+ int r;
uint keylen, doc_cnt;
FT_SUPERDOC sdoc, *sptr;
TREE_ELEMENT *selem;
@@ -90,7 +91,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
/* Skip rows inserted by current inserted */
for (r=_mi_search(info, keyinfo, keybuff, keylen, SEARCH_FIND, key_root) ;
!r &&
- (subkeys=ft_sintXkorr(info->lastkey+info->lastkey_length-extra)) > 0 &&
+ (subkeys.i= ft_sintXkorr(info->lastkey+info->lastkey_length-extra)) > 0 &&
info->lastpos >= info->state->data_file_length ;
r= _mi_search_next(info, keyinfo, info->lastkey,
info->lastkey_length, SEARCH_BIGGER, key_root))
@@ -107,7 +108,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
info->lastkey_length-extra-1, keybuff+1,keylen-1,0,0))
break;
- if (subkeys<0)
+ if (subkeys.i < 0)
{
if (doc_cnt)
DBUG_RETURN(1); /* index is corrupted */
@@ -123,7 +124,8 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
goto do_skip;
}
#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
- tmp_weight=*(float*)&subkeys;
+ /* The weight we read was actually a float */
+ tmp_weight= subkeys.f;
#else
#error
#endif
@@ -160,7 +162,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
r=_mi_search(info, keyinfo, info->lastkey, info->lastkey_length,
SEARCH_BIGGER, key_root);
do_skip:
- while ((subkeys=ft_sintXkorr(info->lastkey+info->lastkey_length-extra)) > 0 &&
+ while ((subkeys.i= ft_sintXkorr(info->lastkey+info->lastkey_length-extra)) > 0 &&
!r && info->lastpos >= info->state->data_file_length)
r= _mi_search_next(info, keyinfo, info->lastkey, info->lastkey_length,
SEARCH_BIGGER, key_root);
diff --git a/storage/myisam/ft_parser.c b/storage/myisam/ft_parser.c
index 4cde3834ed7..e4d500f6d8a 100644
--- a/storage/myisam/ft_parser.c
+++ b/storage/myisam/ft_parser.c
@@ -106,10 +106,10 @@ my_bool ft_boolean_check_syntax_string(const uchar *str)
3 - right bracket
4 - stopword found
*/
-uchar ft_get_word(CHARSET_INFO *cs, uchar **start, uchar *end,
+uchar ft_get_word(CHARSET_INFO *cs, const uchar **start, const uchar *end,
FT_WORD *word, MYSQL_FTPARSER_BOOLEAN_INFO *param)
{
- uchar *doc=*start;
+ const uchar *doc= *start;
int ctype;
uint mwc, length;
int mbl;
@@ -201,10 +201,11 @@ ret:
return param->type;
}
-uchar ft_simple_get_word(CHARSET_INFO *cs, uchar **start, const uchar *end,
- FT_WORD *word, my_bool skip_stopwords)
+uchar ft_simple_get_word(CHARSET_INFO *cs, const uchar **start,
+ const uchar *end, FT_WORD *word,
+ my_bool skip_stopwords)
{
- uchar *doc= *start;
+ const uchar *doc= *start;
uint mwc, length;
int mbl;
int ctype;
@@ -216,7 +217,7 @@ uchar ft_simple_get_word(CHARSET_INFO *cs, uchar **start, const uchar *end,
{
if (doc >= end)
DBUG_RETURN(0);
- mbl= cs->cset->ctype(cs, &ctype, (uchar*)doc, (uchar*)end);
+ mbl= cs->cset->ctype(cs, &ctype, doc, end);
if (true_word_char(ctype, *doc))
break;
}
@@ -225,7 +226,7 @@ uchar ft_simple_get_word(CHARSET_INFO *cs, uchar **start, const uchar *end,
for (word->pos= doc; doc < end; length++,
doc+= (mbl > 0 ? mbl : (mbl < 0 ? -mbl : 1)))
{
- mbl= cs->cset->ctype(cs, &ctype, (uchar*)doc, (uchar*)end);
+ mbl= cs->cset->ctype(cs, &ctype, doc, end);
if (true_word_char(ctype, *doc))
mwc= 0;
else if (!misc_word_char(*doc) || mwc)
@@ -238,7 +239,7 @@ uchar ft_simple_get_word(CHARSET_INFO *cs, uchar **start, const uchar *end,
if (skip_stopwords == FALSE ||
(length >= ft_min_word_len && length < ft_max_word_len &&
- !is_stopword((char*) word->pos, word->len)))
+ !is_stopword(word->pos, word->len)))
{
*start= doc;
DBUG_RETURN(1);
@@ -257,8 +258,9 @@ void ft_parse_init(TREE *wtree, CHARSET_INFO *cs)
static int ft_add_word(MYSQL_FTPARSER_PARAM *param,
- char *word, int word_len,
- MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info __attribute__((unused)))
+ const uchar *word, mysql_ft_size_t word_len,
+ MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info
+ __attribute__((unused)))
{
TREE *wtree;
FT_WORD w;
@@ -286,10 +288,10 @@ static int ft_add_word(MYSQL_FTPARSER_PARAM *param,
static int ft_parse_internal(MYSQL_FTPARSER_PARAM *param,
- char *doc_arg, int doc_len)
+ const uchar *doc_arg, mysql_ft_size_t doc_len)
{
- uchar *doc= (uchar*) doc_arg;
- uchar *end= doc + doc_len;
+ const uchar *doc= doc_arg;
+ const uchar *end= doc + doc_len;
MY_FT_PARSER_PARAM *ft_param=param->mysql_ftparam;
TREE *wtree= ft_param->wtree;
FT_WORD w;
@@ -302,7 +304,7 @@ static int ft_parse_internal(MYSQL_FTPARSER_PARAM *param,
}
-int ft_parse(TREE *wtree, uchar *doc, int doclen,
+int ft_parse(TREE *wtree, const uchar *doc, int doclen,
struct st_mysql_ftparser *parser,
MYSQL_FTPARSER_PARAM *param, MEM_ROOT *mem_root)
{
@@ -377,8 +379,8 @@ MYSQL_FTPARSER_PARAM *ftparser_call_initializer(MI_INFO *info,
mysql_add_word != 0 - parser is initialized, or no
initialization needed. */
info->ftparser_param[ftparser_nr].mysql_add_word=
- (int (*)(struct st_mysql_ftparser_param *, char *, int,
- MYSQL_FTPARSER_BOOLEAN_INFO *)) 1;
+ (int (*)(struct st_mysql_ftparser_param *, const uchar *,
+ mysql_ft_size_t, MYSQL_FTPARSER_BOOLEAN_INFO *)) 1;
if (parser->init && parser->init(&info->ftparser_param[ftparser_nr]))
return 0;
}
diff --git a/storage/myisam/ft_stopwords.c b/storage/myisam/ft_stopwords.c
index 8aefffbee1d..db4cd3b32b6 100644
--- a/storage/myisam/ft_stopwords.c
+++ b/storage/myisam/ft_stopwords.c
@@ -66,7 +66,8 @@ int ft_init_stopwords()
{
File fd;
uint len;
- uchar *buffer, *start, *end;
+ uchar *buffer;
+ const uchar *start, *end;
FT_WORD w;
int error=-1;
@@ -109,7 +110,7 @@ err0:
}
-int is_stopword(char *word, uint len)
+int is_stopword(const uchar *word, size_t len)
{
FT_STOPWORD sw;
sw.pos=word;
diff --git a/storage/myisam/ftdefs.h b/storage/myisam/ftdefs.h
index ddcf1a8dc26..2b4c46c78ad 100644
--- a/storage/myisam/ftdefs.h
+++ b/storage/myisam/ftdefs.h
@@ -96,18 +96,18 @@
#define FTB_RQUOT (ft_boolean_syntax[11])
typedef struct st_ft_word {
- uchar * pos;
+ const uchar *pos;
uint len;
double weight;
} FT_WORD;
-int is_stopword(char *word, uint len);
+int is_stopword(const uchar *word, size_t len);
uint _ft_make_key(MI_INFO *, uint , uchar *, FT_WORD *, my_off_t);
-uchar ft_get_word(CHARSET_INFO *, uchar **, uchar *, FT_WORD *,
+uchar ft_get_word(CHARSET_INFO *, const uchar **, const uchar *, FT_WORD *,
MYSQL_FTPARSER_BOOLEAN_INFO *);
-uchar ft_simple_get_word(CHARSET_INFO *, uchar **, const uchar *,
+uchar ft_simple_get_word(CHARSET_INFO *, const uchar **, const uchar *,
FT_WORD *, my_bool);
typedef struct _st_ft_seg_iterator {
@@ -121,7 +121,7 @@ void _mi_ft_segiterator_dummy_init(const uchar *, uint, FT_SEG_ITERATOR *);
uint _mi_ft_segiterator(FT_SEG_ITERATOR *);
void ft_parse_init(TREE *, CHARSET_INFO *);
-int ft_parse(TREE *, uchar *, int, struct st_mysql_ftparser *parser,
+int ft_parse(TREE *, const uchar *, int, struct st_mysql_ftparser *parser,
MYSQL_FTPARSER_PARAM *, MEM_ROOT *);
FT_WORD * ft_linearize(TREE *, MEM_ROOT *);
FT_WORD * _mi_ft_parserecord(MI_INFO *, uint, const uchar *, MEM_ROOT *);
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index d92a576a5d7..d9ad1d58b5d 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -115,6 +115,10 @@ static void mi_check_print_msg(HA_CHECK *param, const char* msg_type,
Also we likely need to lock mutex here (in both cases with protocol and
push_warning).
*/
+#ifdef THREAD
+ if (param->need_print_msg_lock)
+ pthread_mutex_lock(&param->print_msg_mutex);
+#endif
protocol->prepare_for_resend();
protocol->store(name, length, system_charset_info);
protocol->store(param->op_name, system_charset_info);
@@ -123,6 +127,10 @@ static void mi_check_print_msg(HA_CHECK *param, const char* msg_type,
if (protocol->write())
sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
msgbuf);
+#ifdef THREAD
+ if (param->need_print_msg_lock)
+ pthread_mutex_unlock(&param->print_msg_mutex);
+#endif
return;
}
@@ -497,10 +505,9 @@ int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
extern "C" {
-volatile int *killed_ptr(HA_CHECK *param)
+int killed_ptr(HA_CHECK *param)
{
- /* In theory Unsafe conversion, but should be ok for now */
- return (int*) &(((THD *)(param->thd))->killed);
+ return thd_killed((THD*)param->thd);
}
void mi_check_print_error(HA_CHECK *param, const char *fmt,...)
@@ -1112,22 +1119,6 @@ int ha_myisam::repair(THD *thd, HA_CHECK &param, bool do_optimize)
ha_rows rows= file->state->records;
DBUG_ENTER("ha_myisam::repair");
- /*
- Normally this method is entered with a properly opened table. If the
- repair fails, it can be repeated with more elaborate options. Under
- special circumstances it can happen that a repair fails so that it
- closed the data file and cannot re-open it. In this case file->dfile
- is set to -1. We must not try another repair without an open data
- file. (Bug #25289)
- */
- if (file->dfile == -1)
- {
- sql_print_information("Retrying repair of: '%s' failed. "
- "Please try REPAIR EXTENDED or myisamchk",
- table->s->path.str);
- DBUG_RETURN(HA_ADMIN_FAILED);
- }
-
param.db_name= table->s->db.str;
param.table_name= table->alias;
param.tmpfile_createflag = O_RDWR | O_TRUNC;
@@ -1636,8 +1627,8 @@ bool ha_myisam::check_and_repair(THD *thd)
check_opt.flags|=T_QUICK;
sql_print_warning("Checking table: '%s'",table->s->path.str);
- old_query= thd->query;
- old_query_length= thd->query_length;
+ old_query= thd->query();
+ old_query_length= thd->query_length();
thd->set_query(table->s->table_name.str,
(uint) table->s->table_name.length);
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index c6140e0bcd8..5939e7ea786 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -89,10 +89,10 @@ static void set_data_file_type(MI_SORT_INFO *sort_info, MYISAM_SHARE *share);
void myisamchk_init(HA_CHECK *param)
{
bzero((uchar*) param,sizeof(*param));
+ /* Set all params that are not 0 */
param->opt_follow_links=1;
param->keys_in_use= ~(ulonglong) 0;
param->search_after_block=HA_OFFSET_ERROR;
- param->auto_increment_value= 0;
param->use_buffers=USE_BUFFER_INIT;
param->read_buffer_length=READ_BUFFER_INIT;
param->write_buffer_length=READ_BUFFER_INIT;
@@ -100,7 +100,6 @@ void myisamchk_init(HA_CHECK *param)
param->sort_key_blocks=BUFFERS_WHEN_SORTING;
param->tmpfile_createflag=O_RDWR | O_TRUNC | O_EXCL;
param->myf_rw=MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL);
- param->start_check_pos=0;
param->max_record_length= LONGLONG_MAX;
param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
param->stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
@@ -166,7 +165,7 @@ int chk_del(HA_CHECK *param, register MI_INFO *info, ulonglong test_flag)
empty=0;
for (i= info->state->del ; i > 0L && next_link != HA_OFFSET_ERROR ; i--)
{
- if (*killed_ptr(param))
+ if (killed_ptr(param))
DBUG_RETURN(1);
if (test_flag & T_VERBOSE)
printf(" %9s",llstr(next_link,buff));
@@ -261,7 +260,7 @@ static int check_k_link(HA_CHECK *param, register MI_INFO *info, uint nr)
records= (ha_rows) (info->state->key_file_length / block_size);
while (next_link != HA_OFFSET_ERROR && records > 0)
{
- if (*killed_ptr(param))
+ if (killed_ptr(param))
DBUG_RETURN(1);
if (param->testflag & T_VERBOSE)
printf("%16s",llstr(next_link,llbuff));
@@ -778,7 +777,7 @@ static int chk_index(HA_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
}
for ( ;; )
{
- if (*killed_ptr(param))
+ if (killed_ptr(param))
goto err;
memcpy((char*) info->lastkey,(char*) key,key_length);
info->lastkey_length=key_length;
@@ -990,7 +989,7 @@ int chk_data_link(HA_CHECK *param, MI_INFO *info, my_bool extend)
bzero((char*) key_checksum, info->s->base.keys * sizeof(key_checksum[0]));
while (pos < info->state->data_file_length)
{
- if (*killed_ptr(param))
+ if (killed_ptr(param))
goto err2;
switch (info->s->data_file_type) {
case BLOCK_RECORD:
@@ -1546,6 +1545,8 @@ int mi_repair(HA_CHECK *param, register MI_INFO *info,
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
param->testflag|=T_CALC_CHECKSUM;
+ DBUG_ASSERT(param->use_buffers < SIZE_T_MAX);
+
if (!param->using_global_keycache)
VOID(init_key_cache(dflt_key_cache, param->key_cache_block_size,
(size_t) param->use_buffers, 0, 0));
@@ -2560,8 +2561,9 @@ err:
VOID(my_close(new_file,MYF(0)));
VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks,
MYF(MY_WME)));
- if (info->dfile == new_file)
- info->dfile= -1;
+ if (info->dfile == new_file) /* Retry with key cache */
+ if (unlikely(mi_open_datafile(info, share, name, -1)))
+ param->retry_repair= 0; /* Safety */
}
mi_mark_crashed_on_repair(info);
}
@@ -2701,6 +2703,8 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info,
/* Initialize pthread structures before goto err. */
pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&sort_info.cond, 0);
+ pthread_mutex_init(&param->print_msg_mutex, MY_MUTEX_INIT_FAST);
+ param->need_print_msg_lock= 1;
if (!(sort_info.key_block=
alloc_key_blocks(param, (uint) param->sort_key_blocks,
@@ -3094,8 +3098,9 @@ err:
VOID(my_close(new_file,MYF(0)));
VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks,
MYF(MY_WME)));
- if (info->dfile == new_file)
- info->dfile= -1;
+ if (info->dfile == new_file) /* Retry with key cache */
+ if (unlikely(mi_open_datafile(info, share, name, -1)))
+ param->retry_repair= 0; /* Safety */
}
mi_mark_crashed_on_repair(info);
}
@@ -3105,6 +3110,8 @@ err:
pthread_cond_destroy (&sort_info.cond);
pthread_mutex_destroy(&sort_info.mutex);
+ pthread_mutex_destroy(&param->print_msg_mutex);
+ param->need_print_msg_lock= 0;
my_free((uchar*) sort_info.ft_buf, MYF(MY_ALLOW_ZERO_PTR));
my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
@@ -3247,7 +3254,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
char llbuff[22],llbuff2[22];
DBUG_ENTER("sort_get_next_record");
- if (*killed_ptr(param))
+ if (killed_ptr(param))
DBUG_RETURN(1);
switch (share->data_file_type) {
diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c
index f03311e6ce4..52d2eb6e10c 100644
--- a/storage/myisam/mi_search.c
+++ b/storage/myisam/mi_search.c
@@ -302,7 +302,8 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
uchar *end, *kseg, *vseg;
uchar *sort_order=keyinfo->seg->charset->sort_order;
uchar tt_buff[HA_MAX_KEY_BUFF+2], *t_buff=tt_buff+2;
- uchar *saved_from, *saved_to, *saved_vseg;
+ uchar *UNINIT_VAR(saved_from), *UNINIT_VAR(saved_to);
+ uchar *UNINIT_VAR(saved_vseg);
uint saved_length=0, saved_prefix_len=0;
uint length_pack;
DBUG_ENTER("_mi_prefix_search");
@@ -310,9 +311,6 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
LINT_INIT(length);
LINT_INIT(prefix_len);
LINT_INIT(seg_len_pack);
- LINT_INIT(saved_from);
- LINT_INIT(saved_to);
- LINT_INIT(saved_vseg);
t_buff[0]=0; /* Avoid bugs */
end= page+mi_getint(page);
diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c
index 4cea6bbba85..f2528f2ec60 100644
--- a/storage/myisam/mi_write.c
+++ b/storage/myisam/mi_write.c
@@ -702,11 +702,11 @@ uchar *_mi_find_half_pos(uint nod_flag, MI_KEYDEF *keyinfo, uchar *page,
} /* _mi_find_half_pos */
- /*
- Split buffer at last key
- Returns pointer to the start of the key before the last key
- key will contain the last key
- */
+/*
+ Split buffer at last key
+ Returns pointer to the start of the key before the last key
+ key will contain the last key
+*/
static uchar *_mi_find_last_pos(MI_KEYDEF *keyinfo, uchar *page,
uchar *key, uint *return_key_length,
@@ -717,6 +717,8 @@ static uchar *_mi_find_last_pos(MI_KEYDEF *keyinfo, uchar *page,
uchar key_buff[HA_MAX_KEY_BUFF];
DBUG_ENTER("_mi_find_last_pos");
+ LINT_INIT(last_length);
+
key_ref_length=2;
length=mi_getint(page)-key_ref_length;
page+=key_ref_length;
@@ -732,8 +734,6 @@ static uchar *_mi_find_last_pos(MI_KEYDEF *keyinfo, uchar *page,
DBUG_RETURN(end);
}
- LINT_INIT(prevpos);
- LINT_INIT(last_length);
end=page+length-key_ref_length;
*key='\0';
length=0;
diff --git a/storage/myisam/myisam_ftdump.c b/storage/myisam/myisam_ftdump.c
index 63d954242a0..3eecb08bd99 100644
--- a/storage/myisam/myisam_ftdump.c
+++ b/storage/myisam/myisam_ftdump.c
@@ -53,7 +53,7 @@ static struct my_option my_long_options[] =
int main(int argc,char *argv[])
{
- int error=0, subkeys;
+ int error=0;
uint keylen, keylen2=0, inx, doc_cnt=0;
float weight= 1.0;
double gws, min_gws=0, avg_gws=0;
@@ -109,11 +109,12 @@ int main(int argc,char *argv[])
while (!(error=mi_rnext(info,NULL,inx)))
{
+ FT_WEIGTH subkeys;
keylen=*(info->lastkey);
- subkeys=ft_sintXkorr(info->lastkey+keylen+1);
- if (subkeys >= 0)
- weight=*(float*)&subkeys;
+ subkeys.i =ft_sintXkorr(info->lastkey+keylen+1);
+ if (subkeys.i >= 0)
+ weight= subkeys.f;
#ifdef HAVE_SNPRINTF
snprintf(buf,MAX_LEN,"%.*s",(int) keylen,info->lastkey+1);
@@ -150,14 +151,14 @@ int main(int argc,char *argv[])
keylen2=keylen;
doc_cnt=0;
}
- doc_cnt+= (subkeys >= 0 ? 1 : -subkeys);
+ doc_cnt+= (subkeys.i >= 0 ? 1 : -subkeys.i);
}
if (dump)
{
- if (subkeys>=0)
+ if (subkeys.i >= 0)
printf("%9lx %20.7f %s\n", (long) info->lastpos,weight,buf);
else
- printf("%9lx => %17d %s\n",(long) info->lastpos,-subkeys,buf);
+ printf("%9lx => %17d %s\n",(long) info->lastpos,-subkeys.i,buf);
}
if (verbose && (total%HOW_OFTEN_TO_WRITE)==0)
printf("%10ld\r",total);
diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c
index 6b3ea48e040..f8dd3b9c51f 100644
--- a/storage/myisam/myisamchk.c
+++ b/storage/myisam/myisamchk.c
@@ -302,17 +302,17 @@ static struct my_option my_long_options[] =
(uchar**) &check_param.read_buffer_length,
(uchar**) &check_param.read_buffer_length, 0, GET_ULONG, REQUIRED_ARG,
(long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD,
- (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ INT_MAX32, (long) MALLOC_OVERHEAD, (long) 1L, 0},
{ "write_buffer_size", OPT_WRITE_BUFFER_SIZE, "",
(uchar**) &check_param.write_buffer_length,
(uchar**) &check_param.write_buffer_length, 0, GET_ULONG, REQUIRED_ARG,
(long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD,
- (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ INT_MAX32, (long) MALLOC_OVERHEAD, (long) 1L, 0},
{ "sort_buffer_size", OPT_SORT_BUFFER_SIZE, "",
(uchar**) &check_param.sort_buffer_length,
(uchar**) &check_param.sort_buffer_length, 0, GET_ULONG, REQUIRED_ARG,
(long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD),
- (long) ~0L, (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ ULONG_MAX, (long) MALLOC_OVERHEAD, (long) 1L, 0},
{ "sort_key_blocks", OPT_SORT_KEY_BLOCKS, "",
(uchar**) &check_param.sort_key_blocks,
(uchar**) &check_param.sort_key_blocks, 0, GET_ULONG, REQUIRED_ARG,
@@ -837,7 +837,7 @@ static int myisamchk(HA_CHECK *param, char * filename)
mi_check_print_error(param,"'%s' is marked as crashed after last repair",filename);
break;
case HA_ERR_OLD_FILE:
- mi_check_print_error(param,"'%s' is a old type of MyISAM-table", filename);
+ mi_check_print_error(param,"'%s' is an old type of MyISAM-table", filename);
break;
case HA_ERR_END_OF_FILE:
mi_check_print_error(param,"Couldn't read complete header from '%s'", filename);
@@ -1745,11 +1745,9 @@ err:
sorting
*/
-static int not_killed= 0;
-
-volatile int *killed_ptr(HA_CHECK *param __attribute__((unused)))
+int killed_ptr(HA_CHECK *param __attribute__((unused)))
{
- return &not_killed; /* always NULL */
+ return 0;
}
/* print warnings and errors */
diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h
index c2841c49199..680bdbf16dd 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -725,7 +725,7 @@ my_bool mi_dynmap_file(MI_INFO *info, my_off_t size);
void mi_remap_file(MI_INFO *info, my_off_t size);
/* Functions needed by mi_check */
-volatile int *killed_ptr(HA_CHECK *param);
+int killed_ptr(HA_CHECK *param);
void mi_check_print_error _VARARGS((HA_CHECK *param, const char *fmt, ...));
void mi_check_print_warning _VARARGS((HA_CHECK *param, const char *fmt, ...));
void mi_check_print_info _VARARGS((HA_CHECK *param, const char *fmt, ...));
diff --git a/storage/myisam/myisamlog.c b/storage/myisam/myisamlog.c
index 6e681676c12..679dc0b731b 100644
--- a/storage/myisam/myisamlog.c
+++ b/storage/myisam/myisamlog.c
@@ -385,7 +385,7 @@ static int examine_log(char * file_name, char **table_names)
file_info.name=0;
file_info.show_name=0;
file_info.record=0;
- if (read_string(&cache,(uchar**) &file_info.name,
+ if (read_string(&cache,(uchar**) (char*) &file_info.name,
(uint) mi_uint2korr(head)))
goto err;
{
diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c
index 3aaef41e1dd..86e4c8351c4 100644
--- a/storage/myisam/sort.c
+++ b/storage/myisam/sort.c
@@ -466,8 +466,12 @@ ok:
Detach from the share if the writer is involved. Avoid others to
be blocked. This includes a flush of the write buffer. This will
also indicate EOF to the readers.
+ That means that a writer always gets here first and readers -
+ only when they see EOF. But if a reader finishes prematurely
+ because of an error it may reach this earlier - don't allow it
+ to detach the writer thread.
*/
- if (sort_param->sort_info->info->rec_cache.share)
+ if (sort_param->master && sort_param->sort_info->info->rec_cache.share)
remove_io_thread(&sort_param->sort_info->info->rec_cache);
/* Readers detach from the share if any. Avoid others to be blocked. */
@@ -788,7 +792,12 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys,
cleanup:
close_cached_file(to_file); /* This holds old result */
if (to_file == t_file)
+ {
+ DBUG_ASSERT(t_file2.type == WRITE_CACHE);
*t_file=t_file2; /* Copy result file */
+ t_file->current_pos= &t_file->write_pos;
+ t_file->current_end= &t_file->write_end;
+ }
DBUG_RETURN(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */
} /* merge_many_buff */
@@ -900,7 +909,6 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
uchar *strpos;
BUFFPEK *buffpek,**refpek;
QUEUE queue;
- volatile int *killed= killed_ptr(info->sort_info->param);
DBUG_ENTER("merge_buffers");
count=error=0;
@@ -933,10 +941,6 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
{
for (;;)
{
- if (*killed)
- {
- error=1; goto err;
- }
buffpek=(BUFFPEK*) queue_top(&queue);
if (to_file)
{
@@ -956,6 +960,12 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
buffpek->key+=sort_length;
if (! --buffpek->mem_count)
{
+ /* It's enough to check for killedptr before a slow operation */
+ if (killed_ptr(info->sort_info->param))
+ {
+ error=1;
+ goto err;
+ }
if (!(error=(int) info->read_to_buffer(from_file,buffpek,sort_length)))
{
uchar *base= buffpek->base;
diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c
index b82e3682ebf..7b310dc2eed 100644
--- a/storage/myisammrg/myrg_open.c
+++ b/storage/myisammrg/myrg_open.c
@@ -392,7 +392,7 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking,
int save_errno;
uint idx;
uint child_nr;
- uint key_parts;
+ uint UNINIT_VAR(key_parts);
uint min_keys;
my_bool bad_children= FALSE;
DBUG_ENTER("myrg_attach_children");
@@ -409,7 +409,6 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking,
rc= 1;
errpos= 0;
file_offset= 0;
- LINT_INIT(key_parts);
min_keys= 0;
child_nr= 0;
while ((myisam= (*callback)(callback_param)))
diff --git a/storage/mysql_storage_engine.cmake b/storage/mysql_storage_engine.cmake
index bb368494898..af8c3a85cd1 100644
--- a/storage/mysql_storage_engine.cmake
+++ b/storage/mysql_storage_engine.cmake
@@ -7,6 +7,8 @@
# Remarks:
# ${engine}_SOURCES variable containing source files to produce the library must set before
# calling this macro
+# ${engine}_LIBS variable containing extra libraries to link with may be set
+
MACRO(MYSQL_STORAGE_ENGINE engine)
IF(NOT SOURCE_SUBLIBS)
@@ -22,6 +24,9 @@ IF(NOT SOURCE_SUBLIBS)
#Create static library. The name of the library is <storage_engine>.lib
ADD_LIBRARY(${libname} ${${engine}_SOURCES})
ADD_DEPENDENCIES(${libname} GenError)
+ IF(${engine}_LIBS)
+ TARGET_LINK_LIBRARIES(${libname} ${${engine}_LIBS})
+ ENDIF(${engine}_LIBS)
MESSAGE("build ${engine} as static library")
ELSEIF(${ENGINE_BUILD_TYPE} STREQUAL "DYNAMIC")
ADD_DEFINITIONS(-DMYSQL_DYNAMIC_PLUGIN)
@@ -30,6 +35,9 @@ IF(NOT SOURCE_SUBLIBS)
SET(dyn_libname ha_${libname})
ADD_LIBRARY(${dyn_libname} SHARED ${${engine}_SOURCES})
TARGET_LINK_LIBRARIES (${dyn_libname} mysqld)
+ IF(${engine}_LIBS)
+ TARGET_LINK_LIBRARIES(${dyn_libname} ${${engine}_LIBS})
+ ENDIF(${engine}_LIBS)
MESSAGE("build ${engine} as DLL")
ENDIF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC")
ENDIF(NOT SOURCE_SUBLIBS)
diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index bc8adf6fd32..11e8c1cc191 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -14831,7 +14831,7 @@ void Dblqh::srLogLimits(Signal* signal)
while(true) {
ndbrequire(tmbyte < clogFileSize);
if (logPartPtr.p->logExecState == LogPartRecord::LES_SEARCH_STOP) {
- if (logFilePtr.p->logMaxGciCompleted[tmbyte] < logPartPtr.p->logLastGci) {
+ if (logFilePtr.p->logMaxGciCompleted[tmbyte] <= logPartPtr.p->logLastGci) {
jam();
/* --------------------------------------------------------------------
* WE ARE STEPPING BACKWARDS FROM MBYTE TO MBYTE. THIS IS THE FIRST
diff --git a/storage/ndb/src/kernel/blocks/suma/Suma.cpp b/storage/ndb/src/kernel/blocks/suma/Suma.cpp
index 5f0510cf43a..9179cf7fbbd 100644
--- a/storage/ndb/src/kernel/blocks/suma/Suma.cpp
+++ b/storage/ndb/src/kernel/blocks/suma/Suma.cpp
@@ -274,7 +274,7 @@ Suma::execSTTOR(Signal* signal) {
jam();
send_start_me_req(signal);
- return;
+ DBUG_VOID_RETURN;
}
}
@@ -322,7 +322,7 @@ Suma::execSTTOR(Signal* signal) {
if (ERROR_INSERTED(13030))
{
ndbout_c("Dont start handover");
- return;
+ DBUG_VOID_RETURN;
}
}//if
@@ -332,7 +332,7 @@ Suma::execSTTOR(Signal* signal) {
* Allow API's to connect
*/
sendSTTORRY(signal);
- return;
+ DBUG_VOID_RETURN;
}
if(startphase == 101)
@@ -345,7 +345,7 @@ Suma::execSTTOR(Signal* signal) {
*/
c_startup.m_wait_handover= true;
check_start_handover(signal);
- return;
+ DBUG_VOID_RETURN;
}
}
sendSTTORRY(signal);
@@ -575,19 +575,19 @@ void Suma::execAPI_FAILREQ(Signal* signal)
jam();
sendSignalWithDelay(reference(), GSN_API_FAILREQ, signal,
200, signal->getLength());
- return;
+ DBUG_VOID_RETURN;
}
if (c_failedApiNodes.get(failedApiNode))
{
jam();
- return;
+ DBUG_VOID_RETURN;
}
if (!c_subscriber_nodes.get(failedApiNode))
{
jam();
- return;
+ DBUG_VOID_RETURN;
}
c_failedApiNodes.set(failedApiNode);
@@ -2453,7 +2453,7 @@ Suma::execSUB_START_REQ(Signal* signal){
jam();
c_subscriberPool.release(subbPtr);
sendSubStartRef(signal, SubStartRef::PartiallyConnected);
- return;
+ DBUG_VOID_RETURN;
}
DBUG_PRINT("info",("c_subscriberPool size: %d free: %d",
@@ -4289,7 +4289,7 @@ Suma::Restart::runSUMA_START_ME_REQ(Signal* signal, Uint32 sumaRef)
ref->errorCode = SumaStartMeRef::Busy;
suma.sendSignal(sumaRef, GSN_SUMA_START_ME_REF, signal,
SumaStartMeRef::SignalLength, JBB);
- return;
+ DBUG_VOID_RETURN;
}
nodeId = refToNode(sumaRef);
diff --git a/storage/pbxt/src/discover_xt.cc b/storage/pbxt/src/discover_xt.cc
index 5fce5da4ff2..1ca20fe8dd2 100644
--- a/storage/pbxt/src/discover_xt.cc
+++ b/storage/pbxt/src/discover_xt.cc
@@ -1256,7 +1256,7 @@ static bool mysql_create_table_no_lock(THD *thd,
(!thd->current_stmt_binlog_row_based ||
(thd->current_stmt_binlog_row_based &&
!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
- write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ write_bin_log(thd, TRUE, thd->query(), thd->query_length());
error= FALSE;
unlock_and_end:
pthread_mutex_unlock(&LOCK_open);
diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt
index 5b6268ce10c..ec1e5f7ed38 100644
--- a/storage/xtradb/CMakeLists.txt
+++ b/storage/xtradb/CMakeLists.txt
@@ -1,5 +1,5 @@
-# Copyright (C) 2006 MySQL AB
-#
+# Copyright (C) 2009 Oracle/Innobase Oy
+#
# 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.
@@ -11,21 +11,25 @@
#
# 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
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
+ SET(WIN64 TRUE)
+ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8)
+
+# Check type sizes
+include(CheckTypeSize)
+
+# Currently, the checked results are not used.
+CHECK_TYPE_SIZE(int SIZEOF_INT)
+CHECK_TYPE_SIZE(long SIZEOF_LONG)
+CHECK_TYPE_SIZE(void* SIZEOF_VOID_P)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
ADD_DEFINITIONS(-D_WIN32 -D_LIB -DMYSQL_SERVER)
-# Bug 19424 - InnoDB: Possibly a memory overrun of the buffer being freed (64-bit Visual C)
-# Removing Win64 compiler optimizations for all innodb/mem/* files.
-IF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 8)
- SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/storage/xtradb/mem/mem0mem.c
- ${CMAKE_SOURCE_DIR}/storage/xtradb/mem/mem0pool.c
- PROPERTIES COMPILE_FLAGS -Od)
-ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio" AND CMAKE_SIZEOF_VOID_P MATCHES 8)
-
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
${CMAKE_SOURCE_DIR}/storage/xtradb/include
${CMAKE_SOURCE_DIR}/storage/xtradb/handler
@@ -33,39 +37,45 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
${CMAKE_SOURCE_DIR}/regex
${CMAKE_SOURCE_DIR}/extra/yassl/include)
-SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
- buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c
- data/data0data.c data/data0type.c
- dict/dict0boot.c dict/dict0crea.c dict/dict0dict.c dict/dict0load.c dict/dict0mem.c
- dyn/dyn0dyn.c
- eval/eval0eval.c eval/eval0proc.c
- fil/fil0fil.c
- fsp/fsp0fsp.c
- fut/fut0fut.c fut/fut0lst.c
- ha/ha0ha.c ha/hash0hash.c ha/ha0storage.c
- ibuf/ibuf0ibuf.c
- pars/lexyy.c pars/pars0grm.c pars/pars0opt.c pars/pars0pars.c pars/pars0sym.c
- lock/lock0lock.c lock/lock0iter.c
- log/log0log.c log/log0recv.c
- mach/mach0data.c
- mem/mem0mem.c mem/mem0pool.c
- mtr/mtr0log.c mtr/mtr0mtr.c
- os/os0file.c os/os0proc.c os/os0sync.c os/os0thread.c
- page/page0cur.c page/page0page.c page/page0zip.c
- que/que0que.c
- handler/ha_innodb.cc handler/handler0alter.cc handler/i_s.cc handler/mysql_addons.cc
- read/read0read.c
- rem/rem0cmp.c rem/rem0rec.c
- row/row0ext.c row/row0ins.c row/row0merge.c row/row0mysql.c
- row/row0purge.c row/row0row.c row/row0sel.c row/row0uins.c
- row/row0umod.c row/row0undo.c row/row0upd.c row/row0vers.c
- srv/srv0que.c srv/srv0srv.c srv/srv0start.c
- sync/sync0arr.c sync/sync0rw.c sync/sync0sync.c
- thr/thr0loc.c
- trx/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c
- trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
- usr/usr0sess.c
- ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c ut/ut0list.c ut/ut0wqueue.c)
+# Removing compiler optimizations for innodb/mem/* files on 64-bit Windows
+# due to 64-bit compiler error, See MySQL Bug #19424, #36366, #34297
+IF(MSVC AND $(WIN64))
+ SET_SOURCE_FILES_PROPERTIES(mem/mem0mem.c mem/mem0pool.c
+ PROPERTIES COMPILE_FLAGS -Od)
+ENDIF(MSVC AND $(WIN64))
-MYSQL_STORAGE_ENGINE(INNOBASE)
+SET(INNOBASE_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
+ buf/buf0buddy.c buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c
+ data/data0data.c data/data0type.c
+ dict/dict0boot.c dict/dict0crea.c dict/dict0dict.c dict/dict0load.c dict/dict0mem.c
+ dyn/dyn0dyn.c
+ eval/eval0eval.c eval/eval0proc.c
+ fil/fil0fil.c
+ fsp/fsp0fsp.c
+ fut/fut0fut.c fut/fut0lst.c
+ ha/ha0ha.c ha/hash0hash.c ha/ha0storage.c
+ ibuf/ibuf0ibuf.c
+ pars/lexyy.c pars/pars0grm.c pars/pars0opt.c pars/pars0pars.c pars/pars0sym.c
+ lock/lock0lock.c lock/lock0iter.c
+ log/log0log.c log/log0recv.c
+ mach/mach0data.c
+ mem/mem0mem.c mem/mem0pool.c
+ mtr/mtr0log.c mtr/mtr0mtr.c
+ os/os0file.c os/os0proc.c os/os0sync.c os/os0thread.c
+ page/page0cur.c page/page0page.c page/page0zip.c
+ que/que0que.c
+ handler/ha_innodb.cc handler/handler0alter.cc handler/i_s.cc handler/mysql_addons.cc
+ read/read0read.c
+ rem/rem0cmp.c rem/rem0rec.c
+ row/row0ext.c row/row0ins.c row/row0merge.c row/row0mysql.c row/row0purge.c row/row0row.c
+ row/row0sel.c row/row0uins.c row/row0umod.c row/row0undo.c row/row0upd.c row/row0vers.c
+ srv/srv0que.c srv/srv0srv.c srv/srv0start.c
+ sync/sync0arr.c sync/sync0rw.c sync/sync0sync.c
+ thr/thr0loc.c
+ trx/trx0i_s.c trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c
+ trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
+ usr/usr0sess.c
+ ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
+ ut/ut0list.c ut/ut0wqueue.c)
+MYSQL_STORAGE_ENGINE(INNOBASE)
diff --git a/storage/xtradb/COPYING.Percona b/storage/xtradb/COPYING.Percona
new file mode 100644
index 00000000000..8c786811719
--- /dev/null
+++ b/storage/xtradb/COPYING.Percona
@@ -0,0 +1,30 @@
+Portions of this software contain modifications contributed by Percona, Inc.
+These contributions are used with the following license:
+
+Copyright (c) 2008, 2009, Percona Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+ * Neither the name of the Percona Inc. nor the names of its
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/storage/xtradb/COPYING.Sun_Microsystems b/storage/xtradb/COPYING.Sun_Microsystems
new file mode 100644
index 00000000000..5a77ef3ab73
--- /dev/null
+++ b/storage/xtradb/COPYING.Sun_Microsystems
@@ -0,0 +1,31 @@
+Portions of this software contain modifications contributed by
+Sun Microsystems, Inc. These contributions are used with the following
+license:
+
+Copyright (c) 2009, Sun Microsystems, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+ * Neither the name of Sun Microsystems, Inc. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/storage/xtradb/ChangeLog b/storage/xtradb/ChangeLog
index f662b02eea5..2b04c06f0e8 100644
--- a/storage/xtradb/ChangeLog
+++ b/storage/xtradb/ChangeLog
@@ -1,3 +1,377 @@
+2009-07-20 The InnoDB Team
+
+ * buf/buf0rea.c, handler/ha_innodb.cc, include/srv0srv.h,
+ srv/srv0srv.c:
+ Change the read ahead parameter name to innodb_read_ahead_threshold.
+ Change the meaning of this parameter to signify the number of pages
+ that must be sequentially accessed for InnoDB to trigger a readahead
+ request.
+
+2009-07-20 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Fix Bug#39802 On Windows, 32-bit time_t should be enforced
+
+2009-07-16 The InnoDB Team
+
+ * include/univ.i:
+ Support inlining of functions and prefetch with Sun Studio.
+ These changes are based on contribution from Sun Microsystems Inc.
+ under a BSD license.
+
+2009-07-14 The InnoDB Team
+
+ * fil/fil0fil.c:
+ Fix Bug#45814 URL reference in InnoDB server errors needs adjusting to
+ match documentation
+
+2009-07-14 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_bug21704.result,
+ mysql-test/innodb_bug21704.test:
+ Fix Bug#21704 Renaming column does not update FK definition
+
+2009-07-10 The InnoDB Team
+
+ * handler/ha_innodb.cc, srv/srv0srv.c:
+ Change the defaults for
+ innodb_sync_spin_loops: 20 -> 30
+ innodb_spin_wait_delay: 5 -> 6
+
+2009-07-08 The InnoDB Team
+
+ * buf/buf0flu.c, handler/ha_innodb.cc, include/buf0flu.h,
+ include/log0log.h, include/log0log.ic, include/srv0srv.h,
+ srv/srv0srv.c:
+ Implement the adaptive flushing of dirty pages, which uses
+ a heuristics based flushing rate of dirty pages to avoid IO
+ bursts at checkpoint. Expose new configure knob
+ innodb_adaptive_flushing to control whether the new flushing
+ algorithm should be used.
+
+2009-07-07 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/srv0srv.h, log/log0log.c,
+ srv/srv0srv.c:
+ Implement IO capacity tuning. Expose new configure knob
+ innodb_io_capacity to control the master threads IO rate. The
+ ibuf merge is also changed from synchronous to asynchronous.
+ These changes are based on contribution from Google Inc.
+ under a BSD license.
+
+2009-07-02 The InnoDB Team
+
+ * include/ut0ut.h, plug.in, ut/ut0ut.c:
+ Use the PAUSE instruction inside the spinloop if it is available,
+ Thanks to Mikael Ronstrom <mikael@mysql.com>.
+
+2009-06-29 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_file_format.test,
+ mysql-test/innodb_file_format.result:
+ Do not crash on SET GLOBAL innodb_file_format=DEFAULT
+ or SET GLOBAL innodb_file_format_check=DEFAULT.
+
+2009-06-29 The InnoDB Team
+
+ * buf/buf0buf.c, buf/buf0rea.c, lock/lock0lock.c:
+ Tolerate missing tablespaces during crash recovery and when
+ printing information on locks.
+
+2009-06-29 The InnoDB Team
+
+ * buf/buf0buf.c:
+ Fix a race condition when reading buf_fix_count.
+ Currently, it is not being protected by the buffer pool mutex,
+ but by the block mutex.
+
+2009-06-29 The InnoDB Team
+
+ * handler/handler0alter.cc:
+ Start the user transaction prebuilt->trx if it was not started
+ before adding or dropping an index. Without this fix, the
+ table could be locked outside an active transaction.
+
+2009-06-25 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb_bug42101.test,
+ mysql-test/innodb_bug42101.result,
+ mysql-test/innodb_bug42101-nonzero.test,
+ mysql-test/innodb_bug42101-nonzero.result:
+ Fix Bug#45749 Race condition in SET GLOBAL
+ innodb_commit_concurrency=DEFAULT
+
+2009-06-25 The InnoDB Team
+
+ * dict/dict0dict.c:
+ When an index column cannot be found in the table during index
+ creation, display additional diagnostic before an assertion failure.
+ This does NOT fix Bug #44571 InnoDB Plugin crashes on ADD INDEX,
+ but it helps understand the reason of the crash.
+
+2009-06-17 The InnoDB Team
+
+ * row/row0merge.c:
+ Fix Bug#45426 UNIV_DEBUG build cause assertion error at CREATE INDEX
+
+2009-06-17 The InnoDB Team
+
+ * mysql-test/innodb_bug45357.result, mysql-test/innodb_bug45357.test,
+ row/row0mysql.c:
+ Fix Bug#45357 5.1.35 crashes with Failing assertion: index->type &
+ DICT_CLUSTERED
+
+2009-06-17 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,
+ mysql-test/innodb-autoinc.test:
+ Fix Bug#44030 Error: (1500) Couldn't read the MAX(ID) autoinc value
+ from the index (PRIMARY)
+
+2009-06-11 The InnoDB Team
+
+ * handler/ha_innodb.cc, mysql-test/innodb.result, srv/srv0srv.c:
+ Change the following defaults:
+ max_dirty_pages_pct: from 90 to 75, max allowed from 100 to 99
+ additional_mem_pool_size: from 1 to 8 MB
+ buffer_pool_size: from 8 to 128 MB
+ log_buffer_size: from 1 to 8 MB
+ read_io_threads/write_io_threads: from 1 to 4
+
+2009-06-09 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/trx0trx.h, trx/trx0trx.c:
+ Enable Group Commit functionality that was broken in 5.0 when
+ distributed transactions were introduced.
+
+2009-06-05 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/os0file.h, include/srv0srv.h,
+ os/os0file.c, srv/srv0srv.c, srv/srv0start.c:
+ Enable functionality to have multiple background IO helper threads.
+ Expose new configure knobs innodb_read_io_threads and
+ innodb_write_io_threads and deprecate innodb_file_io_threads (this
+ parameter was relevant only on windows). Internally this allows
+ multiple segments for read and write IO request arrays where one
+ thread works on one segment.
+
+2009-06-05 The InnoDB Team
+
+ * buf/buf0lru.c, buf/buf0rea.c, handler/ha_innodb.cc,
+ include/srv0srv.h, srv/srv0srv.c:
+ Fix a bug in linear read ahead:
+ 1) Take into account access pattern when deciding whether or not to
+ do linear read ahead.
+ 2) Expose a knob innodb_read_ahead_factor = [0-64] default (8),
+ dynamic, global to control linear read ahead behavior. This is the
+ value of the number of pages that InnoDB will tolerate within a
+ 64 page extent even if they are accessed out of order or have
+ not been accessed at all. This number (which varies from 0 to 64)
+ is indicative of the slack that we have when deciding about linear
+ readahead.
+ 3) Disable random read ahead. Keep the code for now.
+
+2009-06-03 The InnoDB Team
+
+ * dict/dict0dict.c, mysql-test/t/innodb_mysql.test,
+ mysql-test/r/innodb_mysql.result:
+ Fix Bug#39793 Foreign keys not constructed when column
+ has a '#' in a comment or default value
+
+2009-05-27 The InnoDB Team
+
+ * Doxyfile:
+ Allow the extraction of documentation from the code base with the
+ Doxygen tool. Convert and add many (but not yet all) comments to
+ Doxygen format.
+
+2009-05-19 The InnoDB Team
+
+ * btr/btr0btr.c, btr/btr0cur.c, lock/lock0lock.c,
+ include/page0page.ic, include/lock0lock.h, include/dict0dict.h,
+ include/page0page.h, include/dict0dict.ic, ibuf/ibuf0ibuf.c,
+ page/page0zip.c, page/page0page.c:
+ Write updates of PAGE_MAX_TRX_ID to the redo log and add debug
+ assertions for checking that PAGE_MAX_TRX_ID is valid on leaf
+ pages of secondary indexes and the insert buffer B-tree. This bug
+ could cause failures in secondary index lookups in consistent
+ reads right after crash recovery.
+
+2009-05-18 The InnoDB Team
+
+ * btr/btr0cur.c:
+ Correctly estimate the space needed on the compressed page when
+ performing an update by delete-and-insert.
+
+2009-05-14 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/srv0srv.h,
+ mysql-test/innodb_bug42101-nonzero-master.opt,
+ mysql-test/innodb_bug42101-nonzero.result,
+ mysql-test/innodb_bug42101-nonzero.test,
+ mysql-test/innodb_bug42101.result, mysql-test/innodb_bug42101.test,
+ srv/srv0srv.c:
+ Fix Bug#42101 Race condition in innodb_commit_concurrency
+
+2009-05-13 The InnoDB Team
+
+ * dict/dict0dict.c:
+ Fix Bug#44320 InnoDB: missing DB_ROLL_PTR in Table Monitor COLUMNS
+ output
+
+2009-04-23 The InnoDB Team
+
+ * row/row0mysql.c:
+ When scanning indexes, report in the error log any error codes
+ returned by the search function. These error codes will still be
+ ignored in CHECK TABLE.
+
+2009-04-23 The InnoDB Team
+
+ * include/trx0types.h:
+ Define the logical type names trx_id_t, roll_ptr_t, and undo_no_t
+ and use them in place of dulint everywhere.
+
+2009-04-18 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/pars0pars.h:
+ Fix Bug#29125 Windows Server X64: so many compiler warnings
+
+2009-04-16 The InnoDB Team
+
+ * include/univ.i:
+ Define REFMAN as the base URL of the MySQL Reference Manual and
+ use the macro in all diagnostic output.
+
+2009-04-16 The InnoDB Team
+
+ * CMakeLists.txt, include/os0sync.h, include/sync0sync.h,
+ include/sync0sync.ic, include/univ.i, srv/srv0start.c,
+ sync/sync0sync.c:
+ Use the Windows Interlocked functions for atomic memory
+ access.
+
+2009-04-15 The InnoDB Team
+
+ * mysql-test/innodb.result, mysql-test/innodb.test:
+ Fix Bug#43309 Test main.innodb can't be run twice
+
+2009-04-14 The InnoDB Team
+
+ * CMakeLists.txt, handler/win_delay_loader.cc,
+ win-plugin/win-plugin.diff:
+ Remove statically linked libraries from MySQL (zlib and strings).
+
+2009-04-11 The InnoDB Team
+
+ * CMakeLists.txt, win-plugin/README, win-plugin/win-plugin.diff:
+ Rewrite CMakeLists.txt.
+
+2009-04-07 The InnoDB Team
+
+ * include/os0sync.h, include/sync0rw.ic, include/sync0sync.h,
+ include/sync0sync.ic, include/univ.i, plug.in, srv/srv0srv.c,
+ srv/srv0start.c, sync/sync0arr.c, sync/sync0sync.c:
+ Enable atomics on Solaris (using the libc functions as defined in
+ atomic.h) if GCC atomic builtins are not present.
+
+2009-04-07 The InnoDB Team
+
+ * btr/btr0btr.c, dict/dict0dict.c, ibuf/ibuf0ibuf.c,
+ include/data0data.h, include/data0data.ic, include/data0type.h,
+ include/data0type.ic, include/dict0dict.h, include/dict0dict.ic,
+ include/rem0rec.ic, mysql-test/innodb.result, mysql-test/innodb.test,
+ pars/pars0pars.c, rem/rem0rec.c, row/row0upd.c:
+ Fix Bug#44032 In ROW_FORMAT=REDUNDANT, update UTF-8 CHAR
+ to/from NULL is not in-place
+
+2009-04-07 The InnoDB Team
+
+ * page/page0cur.c:
+ Fix Bug#43660 SHOW INDEXES/ANALYZE does NOT update cardinality for
+ indexes of InnoDB table
+
+2009-04-06 The InnoDB Team
+
+ * handler/ha_innodb.cc:
+ Make the parameter innodb_change_buffering settable by the
+ configuration file or mysqld command line options. Before this
+ fix, the initial value specified for this parameter was ignored.
+
+2009-04-06 The InnoDB Team
+
+ * sync/sync0rw.c:
+ Avoid a bogus failure in UNIV_SYNC_DEBUG diagnostics.
+
+2009-04-02 The InnoDB Team
+
+ * handler/ha_innodb.cc, include/srv0srv.h, srv/srv0srv.c:
+ Add new parameter innodb_spin_wait_delay to set the maximum delay
+ between polling for a spin lock.
+
+2009-04-02 The InnoDB Team
+
+ * dict/dict0crea.c, handler/ha_innodb.cc, handler/ha_innodb.h,
+ include/dict0mem.h, include/row0merge.h, include/row0mysql.h,
+ mysql-test/innodb-index.result, mysql-test/innodb-index.test,
+ row/row0merge.c, row/row0sel.c:
+ In consistent reads, refuse to use newly created indexes that may
+ lack history.
+
+2009-03-25 The InnoDB Team
+
+ * buf/buf0buf.c, handler/ha_innodb.cc, include/buf0buf.h:
+ In SHOW ENGINE INNODB MUTEX do not show the status of block->mutex,
+ block->lock, block->lock->mutex (if applicable) and all mutexes and
+ rw-locks for which number of os-waits are zero because this can
+ be overwhelming particularly when the buffer pool is very large.
+
+2009-03-20 The InnoDB Team
+
+ * buf/buf0buf.c, include/log0recv.h, log/log0recv.c:
+ Remove the compile-time constant parameters of
+ recv_recover_page(), recv_scan_log_recs(), and recv_sys_init().
+
+2009-03-20 The InnoDB Team
+
+ * data/data0type.c, handler/ha_innodb.cc, include/ha_prototypes.h:
+ Declare innobase_get_at_most_n_mbchars() in ha_prototypes.h.
+
+2009-03-20 The InnoDB Team
+
+ * fil/fil0fil.h, fil/fil0fil.c, srv/srv0start.c:
+ Add the parameter hash_size to fil_init().
+
+2009-03-20 The InnoDB Team
+
+ * fil/fil0fil.c:
+ Refer to fil_system directly, not via local variables.
+
+2009-03-20 The InnoDB Team
+
+ * page/page0page.c:
+ In page_validate(), always report the space id, page number and
+ the name of the index when corruption is noticed.
+
+2009-03-20 The InnoDB Team
+
+ * include/log0log.h, include/log0log.ic, log/log0log.c:
+ Add in/out comments or const qualifiers to some function
+ parameters as appropriate.
+
+2009-03-20 The InnoDB Team
+
+ * dict/dict0boot.c, dict/dict0dict.c, fsp/fsp0fsp.c,
+ include/dict0dict.h, include/srv0srv.h, srv/srv0srv.c,
+ page/page0page.c:
+ Replace srv_sys->dummy_ind1 and srv_sys->dummy_ind2 with
+ dict_ind_redundant and dict_ind_compact, which are
+ initialized by dict_init().
+
+2009-03-11 The InnoDB Team
+
+ InnoDB Plugin 1.0.3 released
+
2009-03-05 The InnoDB Team
* handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,
diff --git a/storage/xtradb/Doxyfile b/storage/xtradb/Doxyfile
new file mode 100644
index 00000000000..62aa7dd8abc
--- /dev/null
+++ b/storage/xtradb/Doxyfile
@@ -0,0 +1,1419 @@
+# Doxyfile 1.5.6
+
+# Usage: SVNVERSION=-r$(svnversion) doxygen
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = "InnoDB Plugin"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 1.0$(SVNVERSION)
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = dox
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek,
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish,
+# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish,
+# and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page. This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = . include/univ.i
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS = *.c *.ic *.h
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE = ut0auxconf_*
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code. Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to FRAME, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature. Other possible values
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories,
+# and Class Hiererachy pages using a tree view instead of an ordered list;
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which
+# disables this behavior completely. For backwards compatibility with previous
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE
+# respectively.
+
+GENERATE_TREEVIEW = NONE
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = DOXYGEN UNIV_DEBUG UNIV_SYNC_DEBUG __attribute__()=
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED = UT_LIST_BASE_NODE_T UT_LIST_NODE_T
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = NO
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = FreeSans
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = NO
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 3
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is enabled by default, which results in a transparent
+# background. Warning: Depending on the platform used, enabling this option
+# may lead to badly anti-aliased labels on the edges of a graph (i.e. they
+# become hard to read).
+
+DOT_TRANSPARENT = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/storage/xtradb/Makefile.am b/storage/xtradb/Makefile.am
index 3b5826f33e6..3aaf7a58ef9 100644
--- a/storage/xtradb/Makefile.am
+++ b/storage/xtradb/Makefile.am
@@ -24,158 +24,306 @@ INCLUDES= -I$(top_srcdir)/include -I$(top_builddir)/include \
-I$(top_srcdir)/regex \
-I$(top_srcdir)/storage/xtradb/include \
-I$(top_srcdir)/sql \
- -I$(srcdir)
+ -I$(srcdir) @ZLIB_INCLUDES@
DEFS= @DEFS@
-noinst_HEADERS= include/btr0btr.h include/btr0btr.ic \
- include/btr0cur.h include/btr0cur.ic \
- include/btr0pcur.h include/btr0pcur.ic \
- include/btr0sea.h include/btr0sea.ic \
- include/btr0types.h include/buf0buddy.h \
- include/buf0buddy.ic include/buf0buf.h \
- include/buf0buf.ic include/buf0flu.h \
- include/buf0flu.ic include/buf0lru.h \
- include/buf0lru.ic include/buf0rea.h \
- include/buf0types.h include/data0data.h \
- include/data0data.ic include/data0type.h \
- include/data0type.ic include/data0types.h \
- include/db0err.h include/dict0boot.h \
- include/dict0boot.ic include/dict0crea.h \
- include/dict0crea.ic include/dict0dict.h \
- include/dict0dict.ic include/dict0load.h \
- include/dict0load.ic include/dict0mem.h \
- include/dict0mem.ic include/dict0types.h \
- include/dyn0dyn.h include/dyn0dyn.ic \
- include/eval0eval.h include/eval0eval.ic \
- include/eval0proc.h include/eval0proc.ic \
- include/fil0fil.h include/fsp0fsp.h \
- include/fsp0fsp.ic include/fut0fut.h \
- include/fut0fut.ic include/fut0lst.h \
- include/fut0lst.ic include/ha0ha.h \
- include/ha0ha.ic \
- include/ha0storage.h \
- include/ha0storage.ic \
- include/hash0hash.h \
- include/hash0hash.ic include/ibuf0ibuf.h \
- include/ibuf0ibuf.ic include/ibuf0types.h \
- include/lock0iter.h \
- include/lock0lock.h include/lock0lock.ic \
- include/lock0priv.h include/lock0priv.ic \
- include/lock0types.h include/log0log.h \
- include/log0log.ic include/log0recv.h \
- include/log0recv.ic include/mach0data.h \
- include/mach0data.ic include/mem0dbg.h \
- include/mem0dbg.ic mem/mem0dbg.c \
- include/mem0mem.h include/mem0mem.ic \
- include/mem0pool.h include/mem0pool.ic \
- include/mtr0log.h include/mtr0log.ic \
- include/mtr0mtr.h include/mtr0mtr.ic \
- include/mtr0types.h \
- include/mysql_addons.h \
- include/os0file.h \
- include/os0proc.h include/os0proc.ic \
- include/os0sync.h include/os0sync.ic \
- include/os0thread.h include/os0thread.ic \
- include/page0cur.h include/page0cur.ic \
- include/page0page.h include/page0page.ic \
- include/page0zip.h include/page0zip.ic \
- include/page0types.h include/pars0grm.h \
- include/pars0opt.h include/pars0opt.ic \
- include/pars0pars.h include/pars0pars.ic \
- include/pars0sym.h include/pars0sym.ic \
- include/pars0types.h include/que0que.h \
- include/que0que.ic include/que0types.h \
- include/read0read.h include/read0read.ic \
- include/read0types.h include/rem0cmp.h \
- include/rem0cmp.ic include/rem0rec.h \
- include/rem0rec.ic include/rem0types.h \
- include/row0ext.h include/row0ext.ic \
- include/row0ins.h include/row0ins.ic \
- include/row0merge.h \
- include/row0mysql.h include/row0mysql.ic \
- include/row0purge.h include/row0purge.ic \
- include/row0row.h include/row0row.ic \
- include/row0sel.h include/row0sel.ic \
- include/row0types.h include/row0uins.h \
- include/row0uins.ic include/row0umod.h \
- include/row0umod.ic include/row0undo.h \
- include/row0undo.ic include/row0upd.h \
- include/row0upd.ic include/row0vers.h \
- include/row0vers.ic include/srv0que.h \
- include/srv0srv.h include/srv0srv.ic \
- include/srv0start.h include/sync0arr.h \
- include/sync0arr.ic include/sync0rw.h \
- include/sync0rw.ic include/sync0sync.h \
- include/sync0sync.ic include/sync0types.h \
- include/thr0loc.h include/thr0loc.ic \
- include/trx0i_s.h \
- include/trx0purge.h include/trx0purge.ic \
- include/trx0rec.h include/trx0rec.ic \
- include/trx0roll.h include/trx0roll.ic \
- include/trx0rseg.h include/trx0rseg.ic \
- include/trx0sys.h include/trx0sys.ic \
- include/trx0trx.h include/trx0trx.ic \
- include/trx0types.h include/trx0undo.h \
- include/trx0undo.ic include/trx0xa.h \
- include/univ.i include/usr0sess.h \
- include/usr0sess.ic include/usr0types.h \
- include/ut0byte.h include/ut0byte.ic \
- include/ut0dbg.h include/ut0lst.h \
- include/ut0mem.h include/ut0mem.ic \
- include/ut0rnd.h include/ut0rnd.ic \
- include/ut0sort.h include/ut0ut.h \
- include/ut0ut.ic include/ut0vec.h \
- include/ut0vec.ic include/ut0list.h \
- include/ut0list.ic include/ut0wqueue.h \
- include/ha_prototypes.h handler/ha_innodb.h \
- include/handler0alter.h \
- handler/i_s.h handler/innodb_patch_info.h \
- handler/handler0vars.h
+noinst_HEADERS= \
+ handler/ha_innodb.h \
+ handler/handler0vars.h \
+ handler/i_s.h \
+ include/btr0btr.h \
+ include/btr0btr.ic \
+ include/btr0cur.h \
+ include/btr0cur.ic \
+ include/btr0pcur.h \
+ include/btr0pcur.ic \
+ include/btr0sea.h \
+ include/btr0sea.ic \
+ include/btr0types.h \
+ include/buf0buddy.h \
+ include/buf0buddy.ic \
+ include/buf0buf.h \
+ include/buf0buf.ic \
+ include/buf0flu.h \
+ include/buf0flu.ic \
+ include/buf0lru.h \
+ include/buf0lru.ic \
+ include/buf0rea.h \
+ include/buf0types.h \
+ include/data0data.h \
+ include/data0data.ic \
+ include/data0type.h \
+ include/data0type.ic \
+ include/data0types.h \
+ include/db0err.h \
+ include/dict0boot.h \
+ include/dict0boot.ic \
+ include/dict0crea.h \
+ include/dict0crea.ic \
+ include/dict0dict.h \
+ include/dict0dict.ic \
+ include/dict0load.h \
+ include/dict0load.ic \
+ include/dict0mem.h \
+ include/dict0mem.ic \
+ include/dict0types.h \
+ include/dyn0dyn.h \
+ include/dyn0dyn.ic \
+ include/eval0eval.h \
+ include/eval0eval.ic \
+ include/eval0proc.h \
+ include/eval0proc.ic \
+ include/fil0fil.h \
+ include/fsp0fsp.h \
+ include/fsp0fsp.ic \
+ include/fsp0types.h \
+ include/fut0fut.h \
+ include/fut0fut.ic \
+ include/fut0lst.h \
+ include/fut0lst.ic \
+ include/ha0ha.h \
+ include/ha0ha.ic \
+ include/ha0storage.h \
+ include/ha0storage.ic \
+ include/ha_prototypes.h \
+ include/handler0alter.h \
+ include/hash0hash.h \
+ include/hash0hash.ic \
+ include/ibuf0ibuf.h \
+ include/ibuf0ibuf.ic \
+ include/ibuf0types.h \
+ include/lock0iter.h \
+ include/lock0lock.h \
+ include/lock0lock.ic \
+ include/lock0priv.h \
+ include/lock0priv.ic \
+ include/lock0types.h \
+ include/log0log.h \
+ include/log0log.ic \
+ include/log0recv.h \
+ include/log0recv.ic \
+ include/mach0data.h \
+ include/mach0data.ic \
+ include/mem0dbg.h \
+ include/mem0dbg.ic \
+ include/mem0mem.h \
+ include/mem0mem.ic \
+ include/mem0pool.h \
+ include/mem0pool.ic \
+ include/mtr0log.h \
+ include/mtr0log.ic \
+ include/mtr0mtr.h \
+ include/mtr0mtr.ic \
+ include/mtr0types.h \
+ include/mysql_addons.h \
+ include/os0file.h \
+ include/os0proc.h \
+ include/os0proc.ic \
+ include/os0sync.h \
+ include/os0sync.ic \
+ include/os0thread.h \
+ include/os0thread.ic \
+ include/page0cur.h \
+ include/page0cur.ic \
+ include/page0page.h \
+ include/page0page.ic \
+ include/page0types.h \
+ include/page0zip.h \
+ include/page0zip.ic \
+ include/pars0grm.h \
+ include/pars0opt.h \
+ include/pars0opt.ic \
+ include/pars0pars.h \
+ include/pars0pars.ic \
+ include/pars0sym.h \
+ include/pars0sym.ic \
+ include/pars0types.h \
+ include/que0que.h \
+ include/que0que.ic \
+ include/que0types.h \
+ include/read0read.h \
+ include/read0read.ic \
+ include/read0types.h \
+ include/rem0cmp.h \
+ include/rem0cmp.ic \
+ include/rem0rec.h \
+ include/rem0rec.ic \
+ include/rem0types.h \
+ include/row0ext.h \
+ include/row0ext.ic \
+ include/row0ins.h \
+ include/row0ins.ic \
+ include/row0merge.h \
+ include/row0mysql.h \
+ include/row0mysql.ic \
+ include/row0purge.h \
+ include/row0purge.ic \
+ include/row0row.h \
+ include/row0row.ic \
+ include/row0sel.h \
+ include/row0sel.ic \
+ include/row0types.h \
+ include/row0uins.h \
+ include/row0uins.ic \
+ include/row0umod.h \
+ include/row0umod.ic \
+ include/row0undo.h \
+ include/row0undo.ic \
+ include/row0upd.h \
+ include/row0upd.ic \
+ include/row0vers.h \
+ include/row0vers.ic \
+ include/srv0que.h \
+ include/srv0srv.h \
+ include/srv0srv.ic \
+ include/srv0start.h \
+ include/sync0arr.h \
+ include/sync0arr.ic \
+ include/sync0rw.h \
+ include/sync0rw.ic \
+ include/sync0sync.h \
+ include/sync0sync.ic \
+ include/sync0types.h \
+ include/thr0loc.h \
+ include/thr0loc.ic \
+ include/trx0i_s.h \
+ include/trx0purge.h \
+ include/trx0purge.ic \
+ include/trx0rec.h \
+ include/trx0rec.ic \
+ include/trx0roll.h \
+ include/trx0roll.ic \
+ include/trx0rseg.h \
+ include/trx0rseg.ic \
+ include/trx0sys.h \
+ include/trx0sys.ic \
+ include/trx0trx.h \
+ include/trx0trx.ic \
+ include/trx0types.h \
+ include/trx0undo.h \
+ include/trx0undo.ic \
+ include/trx0xa.h \
+ include/univ.i \
+ include/usr0sess.h \
+ include/usr0sess.ic \
+ include/usr0types.h \
+ include/ut0auxconf.h \
+ include/ut0byte.h \
+ include/ut0byte.ic \
+ include/ut0dbg.h \
+ include/ut0list.h \
+ include/ut0list.ic \
+ include/ut0lst.h \
+ include/ut0mem.h \
+ include/ut0mem.ic \
+ include/ut0rnd.h \
+ include/ut0rnd.ic \
+ include/ut0sort.h \
+ include/ut0ut.h \
+ include/ut0ut.ic \
+ include/ut0vec.h \
+ include/ut0vec.ic \
+ include/ut0wqueue.h \
+ handler/innodb_patch_info.h \
+ mem/mem0dbg.c
EXTRA_LIBRARIES= libinnobase.a
noinst_LIBRARIES= @plugin_innobase_static_target@
-libinnobase_a_SOURCES= btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \
- btr/btr0sea.c buf/buf0buddy.c \
- buf/buf0buf.c buf/buf0flu.c \
- buf/buf0lru.c buf/buf0rea.c data/data0data.c \
- data/data0type.c dict/dict0boot.c \
- dict/dict0crea.c dict/dict0dict.c \
- dict/dict0load.c dict/dict0mem.c dyn/dyn0dyn.c \
- eval/eval0eval.c eval/eval0proc.c \
- fil/fil0fil.c fsp/fsp0fsp.c fut/fut0fut.c \
- fut/fut0lst.c ha/ha0ha.c \
- ha/ha0storage.c \
- ha/hash0hash.c \
- ibuf/ibuf0ibuf.c lock/lock0iter.c \
- lock/lock0lock.c \
- log/log0log.c log/log0recv.c mach/mach0data.c \
- mem/mem0mem.c mem/mem0pool.c mtr/mtr0log.c \
- mtr/mtr0mtr.c os/os0file.c os/os0proc.c \
- os/os0sync.c os/os0thread.c page/page0cur.c \
- page/page0page.c page/page0zip.c \
- pars/lexyy.c pars/pars0grm.c \
- pars/pars0opt.c pars/pars0pars.c \
- pars/pars0sym.c que/que0que.c read/read0read.c \
- rem/rem0cmp.c rem/rem0rec.c row/row0ext.c \
- row/row0ins.c row/row0merge.c \
- row/row0mysql.c row/row0purge.c row/row0row.c \
- row/row0sel.c row/row0uins.c row/row0umod.c \
- row/row0undo.c row/row0upd.c row/row0vers.c \
- srv/srv0que.c srv/srv0srv.c srv/srv0start.c \
- sync/sync0arr.c sync/sync0rw.c \
- sync/sync0sync.c thr/thr0loc.c \
- trx/trx0i_s.c \
- trx/trx0purge.c \
- trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c \
- trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c \
- usr/usr0sess.c ut/ut0byte.c ut/ut0dbg.c \
- ut/ut0list.c ut/ut0mem.c ut/ut0rnd.c \
- ut/ut0ut.c ut/ut0vec.c ut/ut0wqueue.c \
- handler/ha_innodb.cc handler/handler0alter.cc \
- handler/i_s.cc \
- handler/mysql_addons.cc
+libinnobase_a_SOURCES= \
+ btr/btr0btr.c \
+ btr/btr0cur.c \
+ btr/btr0pcur.c \
+ btr/btr0sea.c \
+ buf/buf0buddy.c \
+ buf/buf0buf.c \
+ buf/buf0flu.c \
+ buf/buf0lru.c \
+ buf/buf0rea.c \
+ data/data0data.c \
+ data/data0type.c \
+ dict/dict0boot.c \
+ dict/dict0crea.c \
+ dict/dict0dict.c \
+ dict/dict0load.c \
+ dict/dict0mem.c \
+ dyn/dyn0dyn.c \
+ eval/eval0eval.c \
+ eval/eval0proc.c \
+ fil/fil0fil.c \
+ fsp/fsp0fsp.c \
+ fut/fut0fut.c \
+ fut/fut0lst.c \
+ ha/ha0ha.c \
+ ha/ha0storage.c \
+ ha/hash0hash.c \
+ handler/ha_innodb.cc \
+ handler/handler0alter.cc \
+ handler/i_s.cc \
+ handler/mysql_addons.cc \
+ ibuf/ibuf0ibuf.c \
+ lock/lock0iter.c \
+ lock/lock0lock.c \
+ log/log0log.c \
+ log/log0recv.c \
+ mach/mach0data.c \
+ mem/mem0mem.c \
+ mem/mem0pool.c \
+ mtr/mtr0log.c \
+ mtr/mtr0mtr.c \
+ os/os0file.c \
+ os/os0proc.c \
+ os/os0sync.c \
+ os/os0thread.c \
+ page/page0cur.c \
+ page/page0page.c \
+ page/page0zip.c \
+ pars/lexyy.c \
+ pars/pars0grm.c \
+ pars/pars0opt.c \
+ pars/pars0pars.c \
+ pars/pars0sym.c \
+ que/que0que.c \
+ read/read0read.c \
+ rem/rem0cmp.c \
+ rem/rem0rec.c \
+ row/row0ext.c \
+ row/row0ins.c \
+ row/row0merge.c \
+ row/row0mysql.c \
+ row/row0purge.c \
+ row/row0row.c \
+ row/row0sel.c \
+ row/row0uins.c \
+ row/row0umod.c \
+ row/row0undo.c \
+ row/row0upd.c \
+ row/row0vers.c \
+ srv/srv0que.c \
+ srv/srv0srv.c \
+ srv/srv0start.c \
+ sync/sync0arr.c \
+ sync/sync0rw.c \
+ sync/sync0sync.c \
+ thr/thr0loc.c \
+ trx/trx0i_s.c \
+ trx/trx0purge.c \
+ trx/trx0rec.c \
+ trx/trx0roll.c \
+ trx/trx0rseg.c \
+ trx/trx0sys.c \
+ trx/trx0trx.c \
+ trx/trx0undo.c \
+ usr/usr0sess.c \
+ ut/ut0byte.c \
+ ut/ut0dbg.c \
+ ut/ut0list.c \
+ ut/ut0mem.c \
+ ut/ut0rnd.c \
+ ut/ut0ut.c \
+ ut/ut0vec.c \
+ ut/ut0wqueue.c
libinnobase_a_CXXFLAGS= $(AM_CFLAGS)
libinnobase_a_CFLAGS= $(AM_CFLAGS)
diff --git a/storage/xtradb/btr/btr0btr.c b/storage/xtradb/btr/btr0btr.c
index 2029a95cc19..6ba9b36207b 100644
--- a/storage/xtradb/btr/btr0btr.c
+++ b/storage/xtradb/btr/btr0btr.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file btr/btr0btr.c
The B-tree
Created 6/2/1994 Heikki Tuuri
@@ -31,6 +32,8 @@ Created 6/2/1994 Heikki Tuuri
#include "fsp0fsp.h"
#include "page0page.h"
#include "page0zip.h"
+
+#ifndef UNIV_HOTBACKUP
#include "btr0cur.h"
#include "btr0sea.h"
#include "btr0pcur.h"
@@ -95,15 +98,15 @@ we allocate pages for the non-leaf levels of the tree.
*/
#ifdef UNIV_BTR_DEBUG
-/******************************************************************
-Checks a file segment header within a B-tree root page. */
+/**************************************************************//**
+Checks a file segment header within a B-tree root page.
+@return TRUE if valid */
static
ibool
btr_root_fseg_validate(
/*===================*/
- /* out: TRUE if valid */
- const fseg_header_t* seg_header, /* in: segment header */
- ulint space) /* in: tablespace identifier */
+ const fseg_header_t* seg_header, /*!< in: segment header */
+ ulint space) /*!< in: tablespace identifier */
{
ulint offset = mach_read_from_2(seg_header + FSEG_HDR_OFFSET);
@@ -114,15 +117,15 @@ btr_root_fseg_validate(
}
#endif /* UNIV_BTR_DEBUG */
-/******************************************************************
-Gets the root node of a tree and x-latches it. */
+/**************************************************************//**
+Gets the root node of a tree and x-latches it.
+@return root page, x-latched */
static
buf_block_t*
btr_root_block_get(
/*===============*/
- /* out: root page, x-latched */
- dict_index_t* index, /* in: index tree */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint space;
ulint zip_size;
@@ -150,29 +153,29 @@ btr_root_block_get(
return(block);
}
-/******************************************************************
-Gets the root node of a tree and x-latches it. */
+/**************************************************************//**
+Gets the root node of a tree and x-latches it.
+@return root page, x-latched */
UNIV_INTERN
page_t*
btr_root_get(
/*=========*/
- /* out: root page, x-latched */
- dict_index_t* index, /* in: index tree */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ mtr_t* mtr) /*!< in: mtr */
{
return(buf_block_get_frame(btr_root_block_get(index, mtr)));
}
-/*****************************************************************
+/*************************************************************//**
Gets pointer to the previous user record in the tree. It is assumed that
-the caller has appropriate latches on the page and its neighbor. */
+the caller has appropriate latches on the page and its neighbor.
+@return previous user record, NULL if there is none */
UNIV_INTERN
rec_t*
btr_get_prev_user_rec(
/*==================*/
- /* out: previous user record, NULL if there is none */
- rec_t* rec, /* in: record on leaf level */
- mtr_t* mtr) /* in: mtr holding a latch on the page, and if
+ rec_t* rec, /*!< in: record on leaf level */
+ mtr_t* mtr) /*!< in: mtr holding a latch on the page, and if
needed, also to the previous page */
{
page_t* page;
@@ -221,16 +224,16 @@ btr_get_prev_user_rec(
return(NULL);
}
-/*****************************************************************
+/*************************************************************//**
Gets pointer to the next user record in the tree. It is assumed that the
-caller has appropriate latches on the page and its neighbor. */
+caller has appropriate latches on the page and its neighbor.
+@return next user record, NULL if there is none */
UNIV_INTERN
rec_t*
btr_get_next_user_rec(
/*==================*/
- /* out: next user record, NULL if there is none */
- rec_t* rec, /* in: record on leaf level */
- mtr_t* mtr) /* in: mtr holding a latch on the page, and if
+ rec_t* rec, /*!< in: record on leaf level */
+ mtr_t* mtr) /*!< in: mtr holding a latch on the page, and if
needed, also to the next page */
{
page_t* page;
@@ -277,18 +280,18 @@ btr_get_next_user_rec(
return(NULL);
}
-/******************************************************************
+/**************************************************************//**
Creates a new index page (not the root, and also not
used in page reorganization). @see btr_page_empty(). */
static
void
btr_page_create(
/*============*/
- buf_block_t* block, /* in/out: page to be created */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- dict_index_t* index, /* in: index */
- ulint level, /* in: the B-tree level of the page */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in/out: page to be created */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ dict_index_t* index, /*!< in: index */
+ ulint level, /*!< in: the B-tree level of the page */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* page = buf_block_get_frame(block);
@@ -307,16 +310,16 @@ btr_page_create(
btr_page_set_index_id(page, page_zip, index->id, mtr);
}
-/******************************************************************
+/**************************************************************//**
Allocates a new file page to be used in an ibuf tree. Takes the page from
-the free list of the tree, which must contain pages! */
+the free list of the tree, which must contain pages!
+@return new allocated block, x-latched */
static
buf_block_t*
btr_page_alloc_for_ibuf(
/*====================*/
- /* out: new allocated block, x-latched */
- dict_index_t* index, /* in: index tree */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ mtr_t* mtr) /*!< in: mtr */
{
fil_addr_t node_addr;
page_t* root;
@@ -344,22 +347,21 @@ btr_page_alloc_for_ibuf(
return(new_block);
}
-/******************************************************************
+/**************************************************************//**
Allocates a new file page to be used in an index tree. NOTE: we assume
-that the caller has made the reservation for free extents! */
+that the caller has made the reservation for free extents!
+@return new allocated block, x-latched; NULL if out of space */
UNIV_INTERN
buf_block_t*
btr_page_alloc(
/*===========*/
- /* out: new allocated block, x-latched;
- NULL if out of space */
- dict_index_t* index, /* in: index */
- ulint hint_page_no, /* in: hint of a good page */
- byte file_direction, /* in: direction where a possible
+ dict_index_t* index, /*!< in: index */
+ ulint hint_page_no, /*!< in: hint of a good page */
+ byte file_direction, /*!< in: direction where a possible
page split is made */
- ulint level, /* in: level where the page is placed
+ ulint level, /*!< in: level where the page is placed
in the tree */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
fseg_header_t* seg_header;
page_t* root;
@@ -398,15 +400,15 @@ btr_page_alloc(
return(new_block);
}
-/******************************************************************
-Gets the number of pages in a B-tree. */
+/**************************************************************//**
+Gets the number of pages in a B-tree.
+@return number of pages */
UNIV_INTERN
ulint
btr_get_size(
/*=========*/
- /* out: number of pages */
- dict_index_t* index, /* in: index */
- ulint flag) /* in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
+ dict_index_t* index, /*!< in: index */
+ ulint flag) /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
{
fseg_header_t* seg_header;
page_t* root;
@@ -442,16 +444,16 @@ btr_get_size(
return(n);
}
-/******************************************************************
+/**************************************************************//**
Frees a page used in an ibuf tree. Puts the page to the free list of the
ibuf tree. */
static
void
btr_page_free_for_ibuf(
/*===================*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: block to be freed, x-latched */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: block to be freed, x-latched */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* root;
@@ -466,7 +468,7 @@ btr_page_free_for_ibuf(
mtr));
}
-/******************************************************************
+/**************************************************************//**
Frees a file page used in an index tree. Can be used also to (BLOB)
external storage pages, because the page level 0 can be given as an
argument. */
@@ -474,10 +476,10 @@ UNIV_INTERN
void
btr_page_free_low(
/*==============*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: block to be freed, x-latched */
- ulint level, /* in: page level */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: block to be freed, x-latched */
+ ulint level, /*!< in: page level */
+ mtr_t* mtr) /*!< in: mtr */
{
fseg_header_t* seg_header;
page_t* root;
@@ -508,16 +510,16 @@ btr_page_free_low(
buf_block_get_page_no(block), mtr);
}
-/******************************************************************
+/**************************************************************//**
Frees a file page used in an index tree. NOTE: cannot free field external
storage pages because the page must contain info on its level. */
UNIV_INTERN
void
btr_page_free(
/*==========*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: block to be freed, x-latched */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: block to be freed, x-latched */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint level;
@@ -526,18 +528,18 @@ btr_page_free(
btr_page_free_low(index, block, level, mtr);
}
-/******************************************************************
+/**************************************************************//**
Sets the child node file address in a node pointer. */
UNIV_INLINE
void
btr_node_ptr_set_child_page_no(
/*===========================*/
- rec_t* rec, /* in: node pointer record */
- page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
+ rec_t* rec, /*!< in: node pointer record */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
part will be updated, or NULL */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint page_no,/* in: child node address */
- mtr_t* mtr) /* in: mtr */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint page_no,/*!< in: child node address */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* field;
ulint len;
@@ -561,17 +563,17 @@ btr_node_ptr_set_child_page_no(
}
}
-/****************************************************************
-Returns the child page of a node pointer and x-latches it. */
+/************************************************************//**
+Returns the child page of a node pointer and x-latches it.
+@return child page, x-latched */
static
buf_block_t*
btr_node_ptr_get_child(
/*===================*/
- /* out: child page, x-latched */
- const rec_t* node_ptr,/* in: node pointer */
- dict_index_t* index, /* in: index */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- mtr_t* mtr) /* in: mtr */
+ const rec_t* node_ptr,/*!< in: node pointer */
+ dict_index_t* index, /*!< in: index */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint page_no;
ulint space;
@@ -584,21 +586,20 @@ btr_node_ptr_get_child(
page_no, RW_X_LATCH, mtr));
}
-/****************************************************************
+/************************************************************//**
Returns the upper level node pointer to a page. It is assumed that mtr holds
-an x-latch on the tree. */
+an x-latch on the tree.
+@return rec_get_offsets() of the node pointer record */
static
ulint*
btr_page_get_father_node_ptr(
/*=========================*/
- /* out: rec_get_offsets() of the
- node pointer record */
- ulint* offsets,/* in: work area for the return value */
- mem_heap_t* heap, /* in: memory heap to use */
- btr_cur_t* cursor, /* in: cursor pointing to user record,
+ ulint* offsets,/*!< in: work area for the return value */
+ mem_heap_t* heap, /*!< in: memory heap to use */
+ btr_cur_t* cursor, /*!< in: cursor pointing to user record,
out: cursor on node pointer record,
its page x-latched */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dtuple_t* tuple;
rec_t* user_rec;
@@ -659,8 +660,7 @@ btr_page_get_father_node_ptr(
" to fix the\n"
"InnoDB: corruption. If the crash happens at "
"the database startup, see\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "forcing-recovery.html about\n"
+ "InnoDB: " REFMAN "forcing-recovery.html about\n"
"InnoDB: forcing recovery. "
"Then dump + drop + reimport.\n", stderr);
@@ -670,21 +670,20 @@ btr_page_get_father_node_ptr(
return(offsets);
}
-/****************************************************************
+/************************************************************//**
Returns the upper level node pointer to a page. It is assumed that mtr holds
-an x-latch on the tree. */
+an x-latch on the tree.
+@return rec_get_offsets() of the node pointer record */
static
ulint*
btr_page_get_father_block(
/*======================*/
- /* out: rec_get_offsets() of the
- node pointer record */
- ulint* offsets,/* in: work area for the return value */
- mem_heap_t* heap, /* in: memory heap to use */
- dict_index_t* index, /* in: b-tree index */
- buf_block_t* block, /* in: child page in the index */
- mtr_t* mtr, /* in: mtr */
- btr_cur_t* cursor) /* out: cursor on node pointer record,
+ ulint* offsets,/*!< in: work area for the return value */
+ mem_heap_t* heap, /*!< in: memory heap to use */
+ dict_index_t* index, /*!< in: b-tree index */
+ buf_block_t* block, /*!< in: child page in the index */
+ mtr_t* mtr, /*!< in: mtr */
+ btr_cur_t* cursor) /*!< out: cursor on node pointer record,
its page x-latched */
{
rec_t* rec
@@ -694,17 +693,17 @@ btr_page_get_father_block(
return(btr_page_get_father_node_ptr(offsets, heap, cursor, mtr));
}
-/****************************************************************
+/************************************************************//**
Seeks to the upper level node pointer to a page.
It is assumed that mtr holds an x-latch on the tree. */
static
void
btr_page_get_father(
/*================*/
- dict_index_t* index, /* in: b-tree index */
- buf_block_t* block, /* in: child page in the index */
- mtr_t* mtr, /* in: mtr */
- btr_cur_t* cursor) /* out: cursor on node pointer record,
+ dict_index_t* index, /*!< in: b-tree index */
+ buf_block_t* block, /*!< in: child page in the index */
+ mtr_t* mtr, /*!< in: mtr */
+ btr_cur_t* cursor) /*!< out: cursor on node pointer record,
its page x-latched */
{
mem_heap_t* heap;
@@ -718,21 +717,20 @@ btr_page_get_father(
mem_heap_free(heap);
}
-/****************************************************************
-Creates the root node for a new index tree. */
+/************************************************************//**
+Creates the root node for a new index tree.
+@return page number of the created root, FIL_NULL if did not succeed */
UNIV_INTERN
ulint
btr_create(
/*=======*/
- /* out: page number of the created root,
- FIL_NULL if did not succeed */
- ulint type, /* in: type of the index */
- ulint space, /* in: space where created */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint type, /*!< in: type of the index */
+ ulint space, /*!< in: space where created */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- dulint index_id,/* in: index id */
- dict_index_t* index, /* in: index */
- mtr_t* mtr) /* in: mini-transaction handle */
+ dulint index_id,/*!< in: index id */
+ dict_index_t* index, /*!< in: index */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint page_no;
buf_block_t* block;
@@ -837,17 +835,17 @@ btr_create(
return(page_no);
}
-/****************************************************************
+/************************************************************//**
Frees a B-tree except the root page, which MUST be freed after this
by calling btr_free_root. */
UNIV_INTERN
void
btr_free_but_not_root(
/*==================*/
- ulint space, /* in: space where created */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where created */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint root_page_no) /* in: root page number */
+ ulint root_page_no) /*!< in: root page number */
{
ibool finished;
page_t* root;
@@ -894,17 +892,17 @@ top_loop:
}
}
-/****************************************************************
+/************************************************************//**
Frees the B-tree root page. Other tree MUST already have been freed. */
UNIV_INTERN
void
btr_free_root(
/*==========*/
- ulint space, /* in: space where created */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where created */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint root_page_no, /* in: root page number */
- mtr_t* mtr) /* in: a mini-transaction which has already
+ ulint root_page_no, /*!< in: root page number */
+ mtr_t* mtr) /*!< in: a mini-transaction which has already
been started */
{
buf_block_t* block;
@@ -921,21 +919,22 @@ btr_free_root(
while (!fseg_free_step(header, mtr));
}
+#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+/*************************************************************//**
Reorganizes an index page. */
static
ibool
btr_page_reorganize_low(
/*====================*/
- ibool recovery,/* in: TRUE if called in recovery:
+ ibool recovery,/*!< in: TRUE if called in recovery:
locks should not be updated, i.e.,
there cannot exist locks on the
page, and a hash index should not be
dropped: it cannot exist */
- buf_block_t* block, /* in: page to be reorganized */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in: page to be reorganized */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* page = buf_block_get_frame(block);
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
@@ -956,29 +955,39 @@ btr_page_reorganize_low(
data_size1 = page_get_data_size(page);
max_ins_size1 = page_get_max_insert_size_after_reorganize(page, 1);
+#ifndef UNIV_HOTBACKUP
/* Write the log record */
mlog_open_and_write_index(mtr, page, index, page_is_comp(page)
? MLOG_COMP_PAGE_REORGANIZE
: MLOG_PAGE_REORGANIZE, 0);
+#endif /* !UNIV_HOTBACKUP */
/* Turn logging off */
log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
+#ifndef UNIV_HOTBACKUP
temp_block = buf_block_alloc(0);
+#else /* !UNIV_HOTBACKUP */
+ ut_ad(block == back_block1);
+ temp_block = back_block2;
+#endif /* !UNIV_HOTBACKUP */
temp_page = temp_block->frame;
/* Copy the old page to temporary space */
buf_frame_copy(temp_page, page);
+#ifndef UNIV_HOTBACKUP
if (UNIV_LIKELY(!recovery)) {
btr_search_drop_page_hash_index(block);
}
+ block->check_index_page_at_flush = TRUE;
+#endif /* !UNIV_HOTBACKUP */
+
/* Recreate the page: note that global data on page (possible
segment headers, next page-field, etc.) is preserved intact */
page_create(block, mtr, dict_table_is_comp(index->table));
- block->check_index_page_at_flush = TRUE;
/* Copy the records from the temporary space to the recreated page;
do not copy the lock bits yet */
@@ -986,8 +995,16 @@ btr_page_reorganize_low(
page_copy_rec_list_end_no_locks(block, temp_block,
page_get_infimum_rec(temp_page),
index, mtr);
- /* Copy max trx id to recreated page */
- page_set_max_trx_id(block, NULL, page_get_max_trx_id(temp_page));
+
+ if (dict_index_is_sec_or_ibuf(index) && page_is_leaf(page)) {
+ /* Copy max trx id to recreated page */
+ trx_id_t max_trx_id = page_get_max_trx_id(temp_page);
+ page_set_max_trx_id(block, NULL, max_trx_id, mtr);
+ /* In crash recovery, dict_index_is_sec_or_ibuf() always
+ returns TRUE, even for clustered indexes. max_trx_id is
+ unused in clustered index pages. */
+ ut_ad(!ut_dulint_is_zero(max_trx_id) || recovery);
+ }
if (UNIV_LIKELY_NULL(page_zip)
&& UNIV_UNLIKELY
@@ -999,10 +1016,12 @@ btr_page_reorganize_low(
goto func_exit;
}
+#ifndef UNIV_HOTBACKUP
if (UNIV_LIKELY(!recovery)) {
/* Update the record lock bitmaps */
lock_move_reorganize_page(block, temp_block);
}
+#endif /* !UNIV_HOTBACKUP */
data_size2 = page_get_data_size(page);
max_ins_size2 = page_get_max_insert_size_after_reorganize(page, 1);
@@ -1029,7 +1048,9 @@ func_exit:
#ifdef UNIV_ZIP_DEBUG
ut_a(!page_zip || page_zip_validate(page_zip, page));
#endif /* UNIV_ZIP_DEBUG */
+#ifndef UNIV_HOTBACKUP
buf_block_free(temp_block);
+#endif /* !UNIV_HOTBACKUP */
/* Restore logging mode */
mtr_set_log_mode(mtr, log_mode);
@@ -1037,37 +1058,39 @@ func_exit:
return(success);
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Reorganizes an index page.
IMPORTANT: if btr_page_reorganize() is invoked on a compressed leaf
page of a non-clustered index, the caller must update the insert
buffer free bits in the same mini-transaction in such a way that the
-modification will be redo-logged. */
+modification will be redo-logged.
+@return TRUE on success, FALSE on failure */
UNIV_INTERN
ibool
btr_page_reorganize(
/*================*/
- /* out: TRUE on success, FALSE on failure */
- buf_block_t* block, /* in: page to be reorganized */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in: page to be reorganized */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
return(btr_page_reorganize_low(FALSE, block, index, mtr));
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses a redo log record of reorganizing a page. */
+/***********************************************************//**
+Parses a redo log record of reorganizing a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_parse_page_reorganize(
/*======================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
+ byte* ptr, /*!< in: buffer */
byte* end_ptr __attribute__((unused)),
- /* in: buffer end */
- dict_index_t* index, /* in: record descriptor */
- buf_block_t* block, /* in: page to be reorganized, or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ /*!< in: buffer end */
+ dict_index_t* index, /*!< in: record descriptor */
+ buf_block_t* block, /*!< in: page to be reorganized, or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ut_ad(ptr && end_ptr);
@@ -1080,17 +1103,18 @@ btr_parse_page_reorganize(
return(ptr);
}
-/*****************************************************************
-Empties an index page. @see btr_page_create().*/
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
+Empties an index page. @see btr_page_create(). */
static
void
btr_page_empty(
/*===========*/
- buf_block_t* block, /* in: page to be emptied */
- page_zip_des_t* page_zip,/* out: compressed page, or NULL */
- dict_index_t* index, /* in: index of the page */
- ulint level, /* in: the B-tree level of the page */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in: page to be emptied */
+ page_zip_des_t* page_zip,/*!< out: compressed page, or NULL */
+ dict_index_t* index, /*!< in: index of the page */
+ ulint level, /*!< in: the B-tree level of the page */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* page = buf_block_get_frame(block);
@@ -1115,24 +1139,24 @@ btr_page_empty(
block->check_index_page_at_flush = TRUE;
}
-/*****************************************************************
+/*************************************************************//**
Makes tree one level higher by splitting the root, and inserts
the tuple. It is assumed that mtr contains an x-latch on the tree.
NOTE that the operation of this function must always succeed,
we cannot reverse it: therefore enough free disk space must be
-guaranteed to be available before this function is called. */
+guaranteed to be available before this function is called.
+@return inserted record */
UNIV_INTERN
rec_t*
btr_root_raise_and_insert(
/*======================*/
- /* out: inserted record */
- btr_cur_t* cursor, /* in: cursor at which to insert: must be
+ btr_cur_t* cursor, /*!< in: cursor at which to insert: must be
on the root page; when the function returns,
the cursor is positioned on the predecessor
of the inserted record */
- const dtuple_t* tuple, /* in: tuple to insert */
- ulint n_ext, /* in: number of externally stored columns */
- mtr_t* mtr) /* in: mtr */
+ const dtuple_t* tuple, /*!< in: tuple to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
page_t* root;
@@ -1287,16 +1311,16 @@ btr_root_raise_and_insert(
return(btr_page_split_and_insert(cursor, tuple, n_ext, mtr));
}
-/*****************************************************************
+/*************************************************************//**
Decides if the page should be split at the convergence point of inserts
-converging to the left. */
+converging to the left.
+@return TRUE if split recommended */
UNIV_INTERN
ibool
btr_page_get_split_rec_to_left(
/*===========================*/
- /* out: TRUE if split recommended */
- btr_cur_t* cursor, /* in: cursor at which to insert */
- rec_t** split_rec) /* out: if split recommended,
+ btr_cur_t* cursor, /*!< in: cursor at which to insert */
+ rec_t** split_rec) /*!< out: if split recommended,
the first record on upper half page,
or NULL if tuple to be inserted should
be first */
@@ -1332,16 +1356,16 @@ btr_page_get_split_rec_to_left(
return(FALSE);
}
-/*****************************************************************
+/*************************************************************//**
Decides if the page should be split at the convergence point of inserts
-converging to the right. */
+converging to the right.
+@return TRUE if split recommended */
UNIV_INTERN
ibool
btr_page_get_split_rec_to_right(
/*============================*/
- /* out: TRUE if split recommended */
- btr_cur_t* cursor, /* in: cursor at which to insert */
- rec_t** split_rec) /* out: if split recommended,
+ btr_cur_t* cursor, /*!< in: cursor at which to insert */
+ rec_t** split_rec) /*!< out: if split recommended,
the first record on upper half page,
or NULL if tuple to be inserted should
be first */
@@ -1390,19 +1414,19 @@ split_at_new:
return(FALSE);
}
-/*****************************************************************
+/*************************************************************//**
Calculates a split record such that the tuple will certainly fit on
its half-page when the split is performed. We assume in this function
-only that the cursor page has at least one user record. */
+only that the cursor page has at least one user record.
+@return split record, or NULL if tuple will be the first record on
+upper half-page */
static
rec_t*
btr_page_get_sure_split_rec(
/*========================*/
- /* out: split record, or NULL if tuple
- will be the first record on upper half-page */
- btr_cur_t* cursor, /* in: cursor at which insert should be made */
- const dtuple_t* tuple, /* in: tuple to insert */
- ulint n_ext) /* in: number of externally stored columns */
+ btr_cur_t* cursor, /*!< in: cursor at which insert should be made */
+ const dtuple_t* tuple, /*!< in: tuple to insert */
+ ulint n_ext) /*!< in: number of externally stored columns */
{
page_t* page;
page_zip_des_t* page_zip;
@@ -1510,24 +1534,24 @@ func_exit:
return(rec);
}
-/*****************************************************************
+/*************************************************************//**
Returns TRUE if the insert fits on the appropriate half-page with the
-chosen split_rec. */
+chosen split_rec.
+@return TRUE if fits */
static
ibool
btr_page_insert_fits(
/*=================*/
- /* out: TRUE if fits */
- btr_cur_t* cursor, /* in: cursor at which insert
+ btr_cur_t* cursor, /*!< in: cursor at which insert
should be made */
- const rec_t* split_rec,/* in: suggestion for first record
+ const rec_t* split_rec,/*!< in: suggestion for first record
on upper half-page, or NULL if
tuple to be inserted should be first */
- const ulint* offsets,/* in: rec_get_offsets(
+ const ulint* offsets,/*!< in: rec_get_offsets(
split_rec, cursor->index) */
- const dtuple_t* tuple, /* in: tuple to insert */
- ulint n_ext, /* in: number of externally stored columns */
- mem_heap_t* heap) /* in: temporary memory heap */
+ const dtuple_t* tuple, /*!< in: tuple to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ mem_heap_t* heap) /*!< in: temporary memory heap */
{
page_t* page;
ulint insert_size;
@@ -1607,17 +1631,17 @@ btr_page_insert_fits(
return(FALSE);
}
-/***********************************************************
+/*******************************************************//**
Inserts a data tuple to a tree on a non-leaf level. It is assumed
that mtr holds an x-latch on the tree. */
UNIV_INTERN
void
btr_insert_on_non_leaf_level(
/*=========================*/
- dict_index_t* index, /* in: index */
- ulint level, /* in: level, must be > 0 */
- dtuple_t* tuple, /* in: the record to be inserted */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index */
+ ulint level, /*!< in: level, must be > 0 */
+ dtuple_t* tuple, /*!< in: the record to be inserted */
+ mtr_t* mtr) /*!< in: mtr */
{
big_rec_t* dummy_big_rec;
btr_cur_t cursor;
@@ -1638,20 +1662,20 @@ btr_insert_on_non_leaf_level(
ut_a(err == DB_SUCCESS);
}
-/******************************************************************
+/**************************************************************//**
Attaches the halves of an index page on the appropriate level in an
index tree. */
static
void
btr_attach_half_pages(
/*==================*/
- dict_index_t* index, /* in: the index tree */
- buf_block_t* block, /* in/out: page to be split */
- rec_t* split_rec, /* in: first record on upper
+ dict_index_t* index, /*!< in: the index tree */
+ buf_block_t* block, /*!< in/out: page to be split */
+ rec_t* split_rec, /*!< in: first record on upper
half page */
- buf_block_t* new_block, /* in/out: the new half page */
- ulint direction, /* in: FSP_UP or FSP_DOWN */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: the new half page */
+ ulint direction, /*!< in: FSP_UP or FSP_DOWN */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint space;
ulint zip_size;
@@ -1773,26 +1797,25 @@ btr_attach_half_pages(
btr_page_set_next(upper_page, upper_page_zip, next_page_no, mtr);
}
-/*****************************************************************
+/*************************************************************//**
Splits an index page to halves and inserts the tuple. It is assumed
-that mtr holds an x-latch to the index tree. NOTE: the tree x-latch
-is released within this function! NOTE that the operation of this
-function must always succeed, we cannot reverse it: therefore
-enough free disk space must be guaranteed to be available before
-this function is called. */
+that mtr holds an x-latch to the index tree. NOTE: the tree x-latch is
+released within this function! NOTE that the operation of this
+function must always succeed, we cannot reverse it: therefore enough
+free disk space (2 pages) must be guaranteed to be available before
+this function is called.
+
+@return inserted record */
UNIV_INTERN
rec_t*
btr_page_split_and_insert(
/*======================*/
- /* out: inserted record; NOTE: the tree
- x-latch is released! NOTE: 2 free disk
- pages must be available! */
- btr_cur_t* cursor, /* in: cursor at which to insert; when the
+ btr_cur_t* cursor, /*!< in: cursor at which to insert; when the
function returns, the cursor is positioned
on the predecessor of the inserted record */
- const dtuple_t* tuple, /* in: tuple to insert */
- ulint n_ext, /* in: number of externally stored columns */
- mtr_t* mtr) /* in: mtr */
+ const dtuple_t* tuple, /*!< in: tuple to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
page_t* page;
@@ -2144,17 +2167,17 @@ func_exit:
return(rec);
}
-/*****************************************************************
+/*************************************************************//**
Removes a page from the level list of pages. */
static
void
btr_level_list_remove(
/*==================*/
- ulint space, /* in: space where removed */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space where removed */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- page_t* page, /* in: page to remove */
- mtr_t* mtr) /* in: mtr */
+ page_t* page, /*!< in: page to remove */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint prev_page_no;
ulint next_page_no;
@@ -2204,36 +2227,39 @@ btr_level_list_remove(
}
}
-/********************************************************************
+/****************************************************************//**
Writes the redo log record for setting an index record as the predefined
minimum record. */
UNIV_INLINE
void
btr_set_min_rec_mark_log(
/*=====================*/
- rec_t* rec, /* in: record */
- byte type, /* in: MLOG_COMP_REC_MIN_MARK or MLOG_REC_MIN_MARK */
- mtr_t* mtr) /* in: mtr */
+ rec_t* rec, /*!< in: record */
+ byte type, /*!< in: MLOG_COMP_REC_MIN_MARK or MLOG_REC_MIN_MARK */
+ mtr_t* mtr) /*!< in: mtr */
{
mlog_write_initial_log_record(rec, type, mtr);
/* Write rec offset as a 2-byte ulint */
mlog_catenate_ulint(mtr, page_offset(rec), MLOG_2BYTES);
}
+#else /* !UNIV_HOTBACKUP */
+# define btr_set_min_rec_mark_log(rec,comp,mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/********************************************************************
+/****************************************************************//**
Parses the redo log record for setting an index record as the predefined
-minimum record. */
+minimum record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_parse_set_min_rec_mark(
/*=======================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- ulint comp, /* in: nonzero=compact page format */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ ulint comp, /*!< in: nonzero=compact page format */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
rec_t* rec;
@@ -2253,14 +2279,14 @@ btr_parse_set_min_rec_mark(
return(ptr + 2);
}
-/********************************************************************
+/****************************************************************//**
Sets a record as the predefined minimum record. */
UNIV_INTERN
void
btr_set_min_rec_mark(
/*=================*/
- rec_t* rec, /* in: record */
- mtr_t* mtr) /* in: mtr */
+ rec_t* rec, /*!< in: record */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint info_bits;
@@ -2279,15 +2305,16 @@ btr_set_min_rec_mark(
}
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Deletes on the upper level the node pointer to a page. */
UNIV_INTERN
void
btr_node_ptr_delete(
/*================*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: page whose node pointer is deleted */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: page whose node pointer is deleted */
+ mtr_t* mtr) /*!< in: mtr */
{
btr_cur_t cursor;
ibool compressed;
@@ -2307,19 +2334,19 @@ btr_node_ptr_delete(
}
}
-/*****************************************************************
+/*************************************************************//**
If page is the only on its level, this function moves its records to the
father page, thus reducing the tree height. */
static
void
btr_lift_page_up(
/*=============*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: page which is the only on its level;
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: page which is the only on its level;
must not be empty: use
btr_discard_only_page_on_level if the last
record from the page should be removed */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* father_block;
page_t* father_page;
@@ -2328,7 +2355,7 @@ btr_lift_page_up(
page_t* page = buf_block_get_frame(block);
ulint root_page_no;
buf_block_t* blocks[BTR_MAX_LEVELS];
- ulint n_blocks; /* last used index in blocks[] */
+ ulint n_blocks; /*!< last used index in blocks[] */
ulint i;
ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL);
@@ -2429,7 +2456,7 @@ btr_lift_page_up(
ut_ad(btr_check_node_ptr(index, father_block, mtr));
}
-/*****************************************************************
+/*************************************************************//**
Tries to merge the page first to the left immediate brother if such a
brother exists, and the node pointers to the current page and to the brother
reside on the same page. If the left brother does not satisfy these
@@ -2437,17 +2464,17 @@ conditions, looks at the right brother. If the page is the only one on that
level lifts the records of the page to the father page, thus reducing the
tree height. It is assumed that mtr holds an x-latch on the tree and on the
page. If cursor is on the leaf level, mtr must also hold x-latches to the
-brothers, if they exist. */
+brothers, if they exist.
+@return TRUE on success */
UNIV_INTERN
ibool
btr_compress(
/*=========*/
- /* out: TRUE on success */
- btr_cur_t* cursor, /* in: cursor on the page to merge or lift;
+ btr_cur_t* cursor, /*!< in: cursor on the page to merge or lift;
the page must not be empty: in record delete
use btr_discard_page if the page would become
empty */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
ulint space;
@@ -2721,7 +2748,7 @@ err_exit:
return(TRUE);
}
-/*****************************************************************
+/*************************************************************//**
Discards a page that is the only page on its level. This will empty
the whole B-tree, leaving just an empty root page. This function
should never be reached, because btr_compress(), which is invoked in
@@ -2730,11 +2757,15 @@ static
void
btr_discard_only_page_on_level(
/*===========================*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: page which is the only on its level */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: page which is the only on its level */
+ mtr_t* mtr) /*!< in: mtr */
{
- ulint page_level = 0;
+ ulint page_level = 0;
+ trx_id_t max_trx_id;
+
+ /* Save the PAGE_MAX_TRX_ID from the leaf page. */
+ max_trx_id = page_get_max_trx_id(buf_block_get_frame(block));
while (buf_block_get_page_no(block) != dict_index_get_page(index)) {
btr_cur_t cursor;
@@ -2777,13 +2808,20 @@ btr_discard_only_page_on_level(
btr_page_empty(block, buf_block_get_page_zip(block), index, 0, mtr);
- /* We play it safe and reset the free bits for the root */
if (!dict_index_is_clust(index)) {
+ /* We play it safe and reset the free bits for the root */
ibuf_reset_free_bits(block);
+
+ if (page_is_leaf(buf_block_get_frame(block))) {
+ ut_a(!ut_dulint_is_zero(max_trx_id));
+ page_set_max_trx_id(block,
+ buf_block_get_page_zip(block),
+ max_trx_id, mtr);
+ }
}
}
-/*****************************************************************
+/*************************************************************//**
Discards a page from a B-tree. This is used to remove the last record from
a B-tree page: the whole page must be removed at the same time. This cannot
be used for the root page, which is allowed to be empty. */
@@ -2791,9 +2829,9 @@ UNIV_INTERN
void
btr_discard_page(
/*=============*/
- btr_cur_t* cursor, /* in: cursor on the page to discard: not on
+ btr_cur_t* cursor, /*!< in: cursor on the page to discard: not on
the root page */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
ulint space;
@@ -2892,13 +2930,13 @@ btr_discard_page(
}
#ifdef UNIV_BTR_PRINT
-/*****************************************************************
+/*************************************************************//**
Prints size info of a B-tree. */
UNIV_INTERN
void
btr_print_size(
/*===========*/
- dict_index_t* index) /* in: index tree */
+ dict_index_t* index) /*!< in: index tree */
{
page_t* root;
fseg_header_t* seg;
@@ -2931,19 +2969,19 @@ btr_print_size(
mtr_commit(&mtr);
}
-/****************************************************************
+/************************************************************//**
Prints recursively index tree pages. */
static
void
btr_print_recursive(
/*================*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: index page */
- ulint width, /* in: print this many entries from start
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: index page */
+ ulint width, /*!< in: print this many entries from start
and end */
- mem_heap_t** heap, /* in/out: heap for rec_get_offsets() */
- ulint** offsets,/* in/out: buffer for rec_get_offsets() */
- mtr_t* mtr) /* in: mtr */
+ mem_heap_t** heap, /*!< in/out: heap for rec_get_offsets() */
+ ulint** offsets,/*!< in/out: buffer for rec_get_offsets() */
+ mtr_t* mtr) /*!< in: mtr */
{
const page_t* page = buf_block_get_frame(block);
page_cur_t cursor;
@@ -2993,14 +3031,14 @@ btr_print_recursive(
}
}
-/******************************************************************
+/**************************************************************//**
Prints directories and other info of all nodes in the tree. */
UNIV_INTERN
void
btr_print_index(
/*============*/
- dict_index_t* index, /* in: index */
- ulint width) /* in: print this many entries from start
+ dict_index_t* index, /*!< in: index */
+ ulint width) /*!< in: print this many entries from start
and end */
{
mtr_t mtr;
@@ -3029,16 +3067,16 @@ btr_print_index(
#endif /* UNIV_BTR_PRINT */
#ifdef UNIV_DEBUG
-/****************************************************************
-Checks that the node pointer to a page is appropriate. */
+/************************************************************//**
+Checks that the node pointer to a page is appropriate.
+@return TRUE */
UNIV_INTERN
ibool
btr_check_node_ptr(
/*===============*/
- /* out: TRUE */
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: index page */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: index page */
+ mtr_t* mtr) /*!< in: mtr */
{
mem_heap_t* heap;
dtuple_t* tuple;
@@ -3073,15 +3111,15 @@ func_exit:
}
#endif /* UNIV_DEBUG */
-/****************************************************************
+/************************************************************//**
Display identification information for a record. */
static
void
btr_index_rec_validate_report(
/*==========================*/
- const page_t* page, /* in: index page */
- const rec_t* rec, /* in: index record */
- const dict_index_t* index) /* in: index */
+ const page_t* page, /*!< in: index page */
+ const rec_t* rec, /*!< in: index record */
+ const dict_index_t* index) /*!< in: index */
{
fputs("InnoDB: Record in ", stderr);
dict_index_name_print(stderr, NULL, index);
@@ -3089,17 +3127,17 @@ btr_index_rec_validate_report(
page_get_page_no(page), (ulint) page_offset(rec));
}
-/****************************************************************
+/************************************************************//**
Checks the size and number of fields in a record based on the definition of
-the index. */
+the index.
+@return TRUE if ok */
UNIV_INTERN
ibool
btr_index_rec_validate(
/*===================*/
- /* out: TRUE if ok */
- const rec_t* rec, /* in: index record */
- const dict_index_t* index, /* in: index */
- ibool dump_on_error) /* in: TRUE if the function
+ const rec_t* rec, /*!< in: index record */
+ const dict_index_t* index, /*!< in: index */
+ ibool dump_on_error) /*!< in: TRUE if the function
should print hex dump of record
and page on error */
{
@@ -3154,7 +3192,7 @@ btr_index_rec_validate(
for (i = 0; i < n; i++) {
ulint fixed_size = dict_col_get_fixed_size(
- dict_index_get_nth_col(index, i));
+ dict_index_get_nth_col(index, i), page_is_comp(page));
rec_get_nth_field_offs(offsets, i, &len);
@@ -3198,16 +3236,16 @@ btr_index_rec_validate(
return(TRUE);
}
-/****************************************************************
+/************************************************************//**
Checks the size and number of fields in records based on the definition of
-the index. */
+the index.
+@return TRUE if ok */
static
ibool
btr_index_page_validate(
/*====================*/
- /* out: TRUE if ok */
- buf_block_t* block, /* in: index page */
- dict_index_t* index) /* in: index */
+ buf_block_t* block, /*!< in: index page */
+ dict_index_t* index) /*!< in: index */
{
page_cur_t cur;
ibool ret = TRUE;
@@ -3232,16 +3270,15 @@ btr_index_page_validate(
return(ret);
}
-/****************************************************************
+/************************************************************//**
Report an error on one page of an index tree. */
static
void
btr_validate_report1(
/*=================*/
- /* out: TRUE if ok */
- dict_index_t* index, /* in: index */
- ulint level, /* in: B-tree level */
- const buf_block_t* block) /* in: index page */
+ dict_index_t* index, /*!< in: index */
+ ulint level, /*!< in: B-tree level */
+ const buf_block_t* block) /*!< in: index page */
{
fprintf(stderr, "InnoDB: Error in page %lu of ",
buf_block_get_page_no(block));
@@ -3252,17 +3289,16 @@ btr_validate_report1(
putc('\n', stderr);
}
-/****************************************************************
+/************************************************************//**
Report an error on two pages of an index tree. */
static
void
btr_validate_report2(
/*=================*/
- /* out: TRUE if ok */
- const dict_index_t* index, /* in: index */
- ulint level, /* in: B-tree level */
- const buf_block_t* block1, /* in: first index page */
- const buf_block_t* block2) /* in: second index page */
+ const dict_index_t* index, /*!< in: index */
+ ulint level, /*!< in: B-tree level */
+ const buf_block_t* block1, /*!< in: first index page */
+ const buf_block_t* block2) /*!< in: second index page */
{
fprintf(stderr, "InnoDB: Error in pages %lu and %lu of ",
buf_block_get_page_no(block1),
@@ -3274,16 +3310,16 @@ btr_validate_report2(
putc('\n', stderr);
}
-/****************************************************************
-Validates index tree level. */
+/************************************************************//**
+Validates index tree level.
+@return TRUE if ok */
static
ibool
btr_validate_level(
/*===============*/
- /* out: TRUE if ok */
- dict_index_t* index, /* in: index tree */
- trx_t* trx, /* in: transaction or NULL */
- ulint level) /* in: level number */
+ dict_index_t* index, /*!< in: index tree */
+ trx_t* trx, /*!< in: transaction or NULL */
+ ulint level) /*!< in: level number */
{
ulint space;
ulint zip_size;
@@ -3620,15 +3656,15 @@ node_ptr_fails:
return(ret);
}
-/******************************************************************
-Checks the consistency of an index tree. */
+/**************************************************************//**
+Checks the consistency of an index tree.
+@return TRUE if ok */
UNIV_INTERN
ibool
btr_validate_index(
/*===============*/
- /* out: TRUE if ok */
- dict_index_t* index, /* in: index */
- trx_t* trx) /* in: transaction or NULL */
+ dict_index_t* index, /*!< in: index */
+ trx_t* trx) /*!< in: transaction or NULL */
{
mtr_t mtr;
page_t* root;
@@ -3654,3 +3690,4 @@ btr_validate_index(
return(TRUE);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c
index ee5b2fc5701..601e5af3572 100644
--- a/storage/xtradb/btr/btr0cur.c
+++ b/storage/xtradb/btr/btr0cur.c
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file btr/btr0cur.c
The index tree cursor
All changes that row operations make to a B-tree or the records
@@ -46,6 +47,9 @@ Created 10/16/1994 Heikki Tuuri
#include "btr0cur.ic"
#endif
+#include "row0upd.h"
+#ifndef UNIV_HOTBACKUP
+#include "mtr0log.h"
#include "page0page.h"
#include "page0zip.h"
#include "rem0rec.h"
@@ -53,7 +57,6 @@ Created 10/16/1994 Heikki Tuuri
#include "buf0lru.h"
#include "btr0btr.h"
#include "btr0sea.h"
-#include "row0upd.h"
#include "trx0rec.h"
#include "trx0roll.h" /* trx_is_recv() */
#include "que0que.h"
@@ -64,36 +67,49 @@ Created 10/16/1994 Heikki Tuuri
#include "zlib.h"
#ifdef UNIV_DEBUG
-/* If the following is set to TRUE, this module prints a lot of
+/** If the following is set to TRUE, this module prints a lot of
trace information of individual record operations */
UNIV_INTERN ibool btr_cur_print_record_ops = FALSE;
#endif /* UNIV_DEBUG */
+/** Number of searches down the B-tree in btr_cur_search_to_nth_level(). */
UNIV_INTERN ulint btr_cur_n_non_sea = 0;
+/** Number of successful adaptive hash index lookups in
+btr_cur_search_to_nth_level(). */
UNIV_INTERN ulint btr_cur_n_sea = 0;
+/** Old value of btr_cur_n_non_sea. Copied by
+srv_refresh_innodb_monitor_stats(). Referenced by
+srv_printf_innodb_monitor(). */
UNIV_INTERN ulint btr_cur_n_non_sea_old = 0;
+/** Old value of btr_cur_n_sea. Copied by
+srv_refresh_innodb_monitor_stats(). Referenced by
+srv_printf_innodb_monitor(). */
UNIV_INTERN ulint btr_cur_n_sea_old = 0;
-/* In the optimistic insert, if the insert does not fit, but this much space
+/** In the optimistic insert, if the insert does not fit, but this much space
can be released by page reorganize, then it is reorganized */
-
#define BTR_CUR_PAGE_REORGANIZE_LIMIT (UNIV_PAGE_SIZE / 32)
-/* The structure of a BLOB part header */
+/** The structure of a BLOB part header */
+/* @{ */
/*--------------------------------------*/
-#define BTR_BLOB_HDR_PART_LEN 0 /* BLOB part len on this
+#define BTR_BLOB_HDR_PART_LEN 0 /*!< BLOB part len on this
page */
-#define BTR_BLOB_HDR_NEXT_PAGE_NO 4 /* next BLOB part page no,
+#define BTR_BLOB_HDR_NEXT_PAGE_NO 4 /*!< next BLOB part page no,
FIL_NULL if none */
/*--------------------------------------*/
-#define BTR_BLOB_HDR_SIZE 8
+#define BTR_BLOB_HDR_SIZE 8 /*!< Size of a BLOB
+ part header, in bytes */
+/* @} */
+#endif /* !UNIV_HOTBACKUP */
-/* A BLOB field reference full of zero, for use in assertions and tests.
+/** A BLOB field reference full of zero, for use in assertions and tests.
Initially, BLOB field references are set to zero, in
dtuple_convert_big_rec(). */
UNIV_INTERN const byte field_ref_zero[BTR_EXTERN_FIELD_REF_SIZE];
-/***********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Marks all extern fields in a record as owned by the record. This function
should be called if the delete mark of a record is removed: a not delete
marked record always owns all its extern fields. */
@@ -101,78 +117,76 @@ static
void
btr_cur_unmark_extern_fields(
/*=========================*/
- page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
part will be updated, or NULL */
- rec_t* rec, /* in/out: record in a clustered index */
- dict_index_t* index, /* in: index of the page */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- mtr_t* mtr); /* in: mtr, or NULL if not logged */
-/***********************************************************************
+ rec_t* rec, /*!< in/out: record in a clustered index */
+ dict_index_t* index, /*!< in: index of the page */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ mtr_t* mtr); /*!< in: mtr, or NULL if not logged */
+/*******************************************************************//**
Adds path information to the cursor for the current page, for which
the binary search has been performed. */
static
void
btr_cur_add_path_info(
/*==================*/
- btr_cur_t* cursor, /* in: cursor positioned on a page */
- ulint height, /* in: height of the page in tree;
+ btr_cur_t* cursor, /*!< in: cursor positioned on a page */
+ ulint height, /*!< in: height of the page in tree;
0 means leaf node */
- ulint root_height); /* in: root node height in tree */
-/***************************************************************
+ ulint root_height); /*!< in: root node height in tree */
+/***********************************************************//**
Frees the externally stored fields for a record, if the field is mentioned
in the update vector. */
static
void
btr_rec_free_updated_extern_fields(
/*===============================*/
- dict_index_t* index, /* in: index of rec; the index tree MUST be
+ dict_index_t* index, /*!< in: index of rec; the index tree MUST be
X-latched */
- rec_t* rec, /* in: record */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ rec_t* rec, /*!< in: record */
+ page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- const upd_t* update, /* in: update vector */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* mtr); /* in: mini-transaction handle which contains
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const upd_t* update, /*!< in: update vector */
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* mtr); /*!< in: mini-transaction handle which contains
an X-latch to record page and to the tree */
-/***************************************************************
+/***********************************************************//**
Frees the externally stored fields for a record. */
static
void
btr_rec_free_externally_stored_fields(
/*==================================*/
- dict_index_t* index, /* in: index of the data, the index
+ dict_index_t* index, /*!< in: index of the data, the index
tree MUST be X-latched */
- rec_t* rec, /* in: record */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ rec_t* rec, /*!< in: record */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* mtr); /* in: mini-transaction handle which contains
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* mtr); /*!< in: mini-transaction handle which contains
an X-latch to record page and to the index
tree */
-/***************************************************************
-Gets the externally stored size of a record, in units of a database page. */
+/***********************************************************//**
+Gets the externally stored size of a record, in units of a database page.
+@return externally stored part, in units of a database page */
static
ulint
btr_rec_get_externally_stored_len(
/*==============================*/
- /* out: externally stored part,
- in units of a database page */
- rec_t* rec, /* in: record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
+ rec_t* rec, /*!< in: record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+#endif /* !UNIV_HOTBACKUP */
-/**********************************************************
+/******************************************************//**
The following function is used to set the deleted bit of a record. */
UNIV_INLINE
void
btr_rec_set_deleted_flag(
/*=====================*/
- /* out: TRUE on success;
- FALSE on page_zip overflow */
- rec_t* rec, /* in/out: physical record */
- page_zip_des_t* page_zip,/* in/out: compressed page (or NULL) */
- ulint flag) /* in: nonzero if delete marked */
+ rec_t* rec, /*!< in/out: physical record */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page (or NULL) */
+ ulint flag) /*!< in: nonzero if delete marked */
{
if (page_rec_is_comp(rec)) {
rec_set_deleted_flag_new(rec, page_zip, flag);
@@ -182,23 +196,24 @@ btr_rec_set_deleted_flag(
}
}
+#ifndef UNIV_HOTBACKUP
/*==================== B-TREE SEARCH =========================*/
-/************************************************************************
+/********************************************************************//**
Latches the leaf page or pages requested. */
static
void
btr_cur_latch_leaves(
/*=================*/
- page_t* page, /* in: leaf page where the search
+ page_t* page, /*!< in: leaf page where the search
converged */
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number of the leaf */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_cur_t* cursor, /* in: cursor */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number of the leaf */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_cur_t* cursor, /*!< in: cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint mode;
ulint left_page_no;
@@ -288,7 +303,7 @@ btr_cur_latch_leaves(
ut_error;
}
-/************************************************************************
+/********************************************************************//**
Searches an index tree and positions a tree cursor on a given level.
NOTE: n_fields_cmp in tuple must be set so that it cannot be compared
to node pointer page number fields on the upper levels of the tree!
@@ -304,15 +319,15 @@ UNIV_INTERN
void
btr_cur_search_to_nth_level(
/*========================*/
- dict_index_t* index, /* in: index */
- ulint level, /* in: the tree level of search */
- const dtuple_t* tuple, /* in: data tuple; NOTE: n_fields_cmp in
+ dict_index_t* index, /*!< in: index */
+ ulint level, /*!< in: the tree level of search */
+ const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
tuple must be set so that it cannot get
compared to the node ptr page number field! */
- ulint mode, /* in: PAGE_CUR_L, ...;
+ ulint mode, /*!< in: PAGE_CUR_L, ...;
Inserts should always be made using
PAGE_CUR_LE to search the position! */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ..., ORed with
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ..., ORed with
BTR_INSERT and BTR_ESTIMATE;
cursor->left_block is used to store a pointer
to the left neighbor page, in the cases
@@ -322,12 +337,12 @@ btr_cur_search_to_nth_level(
on the cursor page, we assume
the caller uses his search latch
to protect the record! */
- btr_cur_t* cursor, /* in/out: tree cursor; the cursor page is
+ btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
s- or x-latched, but see also above! */
- ulint has_search_latch,/* in: info on the latch mode the
+ ulint has_search_latch,/*!< in: info on the latch mode the
caller currently has on btr_search_latch:
RW_S_LATCH, or 0 */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
page_cur_t* page_cursor;
page_t* page;
@@ -658,18 +673,18 @@ func_exit:
}
}
-/*********************************************************************
+/*****************************************************************//**
Opens a cursor at either end of an index. */
UNIV_INTERN
void
btr_cur_open_at_index_side(
/*=======================*/
- ibool from_left, /* in: TRUE if open to the low end,
+ ibool from_left, /*!< in: TRUE if open to the low end,
FALSE if to the high end */
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: latch mode */
- btr_cur_t* cursor, /* in: cursor */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: latch mode */
+ btr_cur_t* cursor, /*!< in: cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_cur_t* page_cursor;
ulint page_no;
@@ -789,16 +804,16 @@ btr_cur_open_at_index_side(
}
}
-/**************************************************************************
+/**********************************************************************//**
Positions a cursor at a randomly chosen position within a B-tree. */
UNIV_INTERN
void
btr_cur_open_at_rnd_pos(
/*====================*/
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_cur_t* cursor, /* in/out: B-tree cursor */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_cur_t* cursor, /*!< in/out: B-tree cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_cur_t* page_cursor;
ulint page_no;
@@ -873,23 +888,22 @@ btr_cur_open_at_rnd_pos(
/*==================== B-TREE INSERT =========================*/
-/*****************************************************************
+/*************************************************************//**
Inserts a record if there is enough space, or if enough space can
be freed by reorganizing. Differs from btr_cur_optimistic_insert because
no heuristics is applied to whether it pays to use CPU time for
-reorganizing the page or not. */
+reorganizing the page or not.
+@return pointer to inserted record if succeed, else NULL */
static
rec_t*
btr_cur_insert_if_possible(
/*=======================*/
- /* out: pointer to inserted record if succeed,
- else NULL */
- btr_cur_t* cursor, /* in: cursor on page after which to insert;
+ btr_cur_t* cursor, /*!< in: cursor on page after which to insert;
cursor stays valid */
- const dtuple_t* tuple, /* in: tuple to insert; the size info need not
+ const dtuple_t* tuple, /*!< in: tuple to insert; the size info need not
have been stored to tuple */
- ulint n_ext, /* in: number of externally stored columns */
- mtr_t* mtr) /* in: mtr */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ mtr_t* mtr) /*!< in: mtr */
{
page_cur_t* page_cursor;
buf_block_t* block;
@@ -922,28 +936,28 @@ btr_cur_insert_if_possible(
return(rec);
}
-/*****************************************************************
-For an insert, checks the locks and does the undo logging if desired. */
+/*************************************************************//**
+For an insert, checks the locks and does the undo logging if desired.
+@return DB_SUCCESS, DB_WAIT_LOCK, DB_FAIL, or error number */
UNIV_INLINE
ulint
btr_cur_ins_lock_and_undo(
/*======================*/
- /* out: DB_SUCCESS, DB_WAIT_LOCK,
- DB_FAIL, or error number */
- ulint flags, /* in: undo logging and locking flags: if
+ ulint flags, /*!< in: undo logging and locking flags: if
not zero, the parameters index and thr
should be specified */
- btr_cur_t* cursor, /* in: cursor on page after which to insert */
- const dtuple_t* entry, /* in: entry to insert */
- que_thr_t* thr, /* in: query thread or NULL */
- ibool* inherit)/* out: TRUE if the inserted new record maybe
+ btr_cur_t* cursor, /*!< in: cursor on page after which to insert */
+ const dtuple_t* entry, /*!< in: entry to insert */
+ que_thr_t* thr, /*!< in: query thread or NULL */
+ mtr_t* mtr, /*!< in/out: mini-transaction */
+ ibool* inherit)/*!< out: TRUE if the inserted new record maybe
should inherit LOCK_GAP type locks from the
successor record */
{
dict_index_t* index;
ulint err;
rec_t* rec;
- dulint roll_ptr;
+ roll_ptr_t roll_ptr;
/* Check if we have to wait for a lock: enqueue an explicit lock
request if yes */
@@ -953,7 +967,7 @@ btr_cur_ins_lock_and_undo(
err = lock_rec_insert_check_and_lock(flags, rec,
btr_cur_get_block(cursor),
- index, thr, inherit);
+ index, thr, mtr, inherit);
if (err != DB_SUCCESS) {
@@ -984,15 +998,15 @@ btr_cur_ins_lock_and_undo(
}
#ifdef UNIV_DEBUG
-/*****************************************************************
+/*************************************************************//**
Report information about a transaction. */
static
void
btr_cur_trx_report(
/*===============*/
- trx_t* trx, /* in: transaction */
- const dict_index_t* index, /* in: index */
- const char* op) /* in: operation */
+ trx_t* trx, /*!< in: transaction */
+ const dict_index_t* index, /*!< in: index */
+ const char* op) /*!< in: operation */
{
fprintf(stderr, "Trx with id " TRX_ID_FMT " going to ",
TRX_ID_PREP_PRINTF(trx->id));
@@ -1002,32 +1016,31 @@ btr_cur_trx_report(
}
#endif /* UNIV_DEBUG */
-/*****************************************************************
+/*************************************************************//**
Tries to perform an insert to a page in an index tree, next to cursor.
It is assumed that mtr holds an x-latch on the page. The operation does
not succeed if there is too little space on the page. If there is just
one record on the page, the insert will always succeed; this is to
-prevent trying to split a page with just one record. */
+prevent trying to split a page with just one record.
+@return DB_SUCCESS, DB_WAIT_LOCK, DB_FAIL, or error number */
UNIV_INTERN
ulint
btr_cur_optimistic_insert(
/*======================*/
- /* out: DB_SUCCESS, DB_WAIT_LOCK,
- DB_FAIL, or error number */
- ulint flags, /* in: undo logging and locking flags: if not
+ ulint flags, /*!< in: undo logging and locking flags: if not
zero, the parameters index and thr should be
specified */
- btr_cur_t* cursor, /* in: cursor on page after which to insert;
+ btr_cur_t* cursor, /*!< in: cursor on page after which to insert;
cursor stays valid */
- dtuple_t* entry, /* in/out: entry to insert */
- rec_t** rec, /* out: pointer to inserted record if
+ dtuple_t* entry, /*!< in/out: entry to insert */
+ rec_t** rec, /*!< out: pointer to inserted record if
succeed */
- big_rec_t** big_rec,/* out: big rec vector whose fields have to
+ big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or
NULL */
- ulint n_ext, /* in: number of externally stored columns */
- que_thr_t* thr, /* in: query thread or NULL */
- mtr_t* mtr) /* in: mtr; if this function returns
+ ulint n_ext, /*!< in: number of externally stored columns */
+ que_thr_t* thr, /*!< in: query thread or NULL */
+ mtr_t* mtr) /*!< in: mtr; if this function returns
DB_SUCCESS on a leaf page of a secondary
index in a compressed tablespace, the
mtr must be committed before latching
@@ -1167,7 +1180,8 @@ fail_err:
}
/* Check locks and write to the undo log, if specified */
- err = btr_cur_ins_lock_and_undo(flags, cursor, entry, thr, &inherit);
+ err = btr_cur_ins_lock_and_undo(flags, cursor, entry,
+ thr, mtr, &inherit);
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
@@ -1247,9 +1261,7 @@ fail_err:
buf_block_get_page_no(block), max_size,
rec_size + PAGE_DIR_SLOT_SIZE, index->type);
#endif
- if (leaf
- && !dict_index_is_clust(index)
- && !dict_index_is_ibuf(index)) {
+ if (leaf && !dict_index_is_clust(index)) {
/* Update the free bits of the B-tree page in the
insert buffer bitmap. */
@@ -1280,33 +1292,33 @@ fail_err:
return(DB_SUCCESS);
}
-/*****************************************************************
+/*************************************************************//**
Performs an insert on a page of an index tree. It is assumed that mtr
holds an x-latch on the tree and on the cursor page. If the insert is
made on the leaf level, to avoid deadlocks, mtr must also own x-latches
-to brothers of page, if those brothers exist. */
+to brothers of page, if those brothers exist.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
btr_cur_pessimistic_insert(
/*=======================*/
- /* out: DB_SUCCESS or error number */
- ulint flags, /* in: undo logging and locking flags: if not
+ ulint flags, /*!< in: undo logging and locking flags: if not
zero, the parameter thr should be
specified; if no undo logging is specified,
then the caller must have reserved enough
free extents in the file space so that the
insertion will certainly succeed */
- btr_cur_t* cursor, /* in: cursor after which to insert;
+ btr_cur_t* cursor, /*!< in: cursor after which to insert;
cursor stays valid */
- dtuple_t* entry, /* in/out: entry to insert */
- rec_t** rec, /* out: pointer to inserted record if
+ dtuple_t* entry, /*!< in/out: entry to insert */
+ rec_t** rec, /*!< out: pointer to inserted record if
succeed */
- big_rec_t** big_rec,/* out: big rec vector whose fields have to
+ big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or
NULL */
- ulint n_ext, /* in: number of externally stored columns */
- que_thr_t* thr, /* in: query thread or NULL */
- mtr_t* mtr) /* in: mtr */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ que_thr_t* thr, /*!< in: query thread or NULL */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index = cursor->index;
ulint zip_size = dict_table_zip_size(index->table);
@@ -1343,7 +1355,8 @@ btr_cur_pessimistic_insert(
/* Retry with a pessimistic insert. Check locks and write to undo log,
if specified */
- err = btr_cur_ins_lock_and_undo(flags, cursor, entry, thr, &dummy_inh);
+ err = btr_cur_ins_lock_and_undo(flags, cursor, entry,
+ thr, mtr, &dummy_inh);
if (err != DB_SUCCESS) {
@@ -1424,21 +1437,21 @@ btr_cur_pessimistic_insert(
/*==================== B-TREE UPDATE =========================*/
-/*****************************************************************
-For an update, checks the locks and does the undo logging. */
+/*************************************************************//**
+For an update, checks the locks and does the undo logging.
+@return DB_SUCCESS, DB_WAIT_LOCK, or error number */
UNIV_INLINE
ulint
btr_cur_upd_lock_and_undo(
/*======================*/
- /* out: DB_SUCCESS, DB_WAIT_LOCK, or error
- number */
- ulint flags, /* in: undo logging and locking flags */
- btr_cur_t* cursor, /* in: cursor on record to update */
- const upd_t* update, /* in: update vector */
- ulint cmpl_info,/* in: compiler info on secondary index
+ ulint flags, /*!< in: undo logging and locking flags */
+ btr_cur_t* cursor, /*!< in: cursor on record to update */
+ const upd_t* update, /*!< in: update vector */
+ ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
- que_thr_t* thr, /* in: query thread */
- dulint* roll_ptr)/* out: roll pointer */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr, /*!< in/out: mini-transaction */
+ roll_ptr_t* roll_ptr)/*!< out: roll pointer */
{
dict_index_t* index;
rec_t* rec;
@@ -1454,7 +1467,7 @@ btr_cur_upd_lock_and_undo(
record */
return(lock_sec_rec_modify_check_and_lock(
flags, btr_cur_get_block(cursor), rec,
- index, thr));
+ index, thr, mtr));
}
/* Check if we have to wait for a lock: enqueue an explicit lock
@@ -1488,19 +1501,19 @@ btr_cur_upd_lock_and_undo(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Writes a redo log record of updating a record in-place. */
UNIV_INLINE
void
btr_cur_update_in_place_log(
/*========================*/
- ulint flags, /* in: flags */
- rec_t* rec, /* in: record */
- dict_index_t* index, /* in: index where cursor positioned */
- const upd_t* update, /* in: update vector */
- trx_t* trx, /* in: transaction */
- dulint roll_ptr, /* in: roll ptr */
- mtr_t* mtr) /* in: mtr */
+ ulint flags, /*!< in: flags */
+ rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: index where cursor positioned */
+ const upd_t* update, /*!< in: update vector */
+ trx_t* trx, /*!< in: transaction */
+ roll_ptr_t roll_ptr, /*!< in: roll ptr */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* log_ptr;
page_t* page = page_align(rec);
@@ -1535,29 +1548,30 @@ btr_cur_update_in_place_log(
row_upd_index_write_log(update, log_ptr, mtr);
}
+#endif /* UNIV_HOTBACKUP */
-/***************************************************************
-Parses a redo log record of updating a record in-place. */
+/***********************************************************//**
+Parses a redo log record of updating a record in-place.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_cur_parse_update_in_place(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in/out: page or NULL */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- dict_index_t* index) /* in: index corresponding to page */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in/out: page or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ dict_index_t* index) /*!< in: index corresponding to page */
{
- ulint flags;
- rec_t* rec;
- upd_t* update;
- ulint pos;
- dulint trx_id;
- dulint roll_ptr;
- ulint rec_offset;
- mem_heap_t* heap;
- ulint* offsets;
+ ulint flags;
+ rec_t* rec;
+ upd_t* update;
+ ulint pos;
+ trx_id_t trx_id;
+ roll_ptr_t roll_ptr;
+ ulint rec_offset;
+ mem_heap_t* heap;
+ ulint* offsets;
if (end_ptr < ptr + 1) {
@@ -1614,26 +1628,29 @@ func_exit:
return(ptr);
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
See if there is enough place in the page modification log to log
-an update-in-place. */
+an update-in-place.
+@return TRUE if enough place */
static
ibool
btr_cur_update_alloc_zip(
/*=====================*/
- /* out: TRUE if enough place */
- page_zip_des_t* page_zip,/* in/out: compressed page */
- buf_block_t* block, /* in/out: buffer page */
- dict_index_t* index, /* in: the index corresponding to the block */
- ulint length, /* in: size needed */
- mtr_t* mtr) /* in: mini-transaction */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ buf_block_t* block, /*!< in/out: buffer page */
+ dict_index_t* index, /*!< in: the index corresponding to the block */
+ ulint length, /*!< in: size needed */
+ ibool create, /*!< in: TRUE=delete-and-insert,
+ FALSE=update-in-place */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
ut_a(page_zip == buf_block_get_page_zip(block));
ut_ad(page_zip);
ut_ad(!dict_index_is_ibuf(index));
if (page_zip_available(page_zip, dict_index_is_clust(index),
- length, 0)) {
+ length, create)) {
return(TRUE);
}
@@ -1660,7 +1677,7 @@ btr_cur_update_alloc_zip(
the free space available on the page. */
if (!page_zip_available(page_zip, dict_index_is_clust(index),
- length, 0)) {
+ length, create)) {
/* Out of space: reset the free bits. */
if (!dict_index_is_clust(index)
&& page_is_leaf(buf_block_get_frame(block))) {
@@ -1672,23 +1689,23 @@ btr_cur_update_alloc_zip(
return(TRUE);
}
-/*****************************************************************
+/*************************************************************//**
Updates a record when the update causes no size changes in its fields.
-We assume here that the ordering fields of the record do not change. */
+We assume here that the ordering fields of the record do not change.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
btr_cur_update_in_place(
/*====================*/
- /* out: DB_SUCCESS or error number */
- ulint flags, /* in: undo logging and locking flags */
- btr_cur_t* cursor, /* in: cursor on the record to update;
+ ulint flags, /*!< in: undo logging and locking flags */
+ btr_cur_t* cursor, /*!< in: cursor on the record to update;
cursor stays valid and positioned on the
same record */
- const upd_t* update, /* in: update vector */
- ulint cmpl_info,/* in: compiler info on secondary index
+ const upd_t* update, /*!< in: update vector */
+ ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr; must be committed before
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr; must be committed before
latching any further pages */
{
dict_index_t* index;
@@ -1696,7 +1713,7 @@ btr_cur_update_in_place(
page_zip_des_t* page_zip;
ulint err;
rec_t* rec;
- dulint roll_ptr = ut_dulint_zero;
+ roll_ptr_t roll_ptr = ut_dulint_zero;
trx_t* trx;
ulint was_delete_marked;
mem_heap_t* heap = NULL;
@@ -1725,13 +1742,13 @@ btr_cur_update_in_place(
/* Check that enough space is available on the compressed page. */
if (UNIV_LIKELY_NULL(page_zip)
&& !btr_cur_update_alloc_zip(page_zip, block, index,
- rec_offs_size(offsets), mtr)) {
+ rec_offs_size(offsets), FALSE, mtr)) {
return(DB_ZIP_OVERFLOW);
}
/* Do lock checking and undo logging */
err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
- thr, &roll_ptr);
+ thr, mtr, &roll_ptr);
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
if (UNIV_LIKELY_NULL(heap)) {
@@ -1794,31 +1811,29 @@ btr_cur_update_in_place(
return(DB_SUCCESS);
}
-/*****************************************************************
+/*************************************************************//**
Tries to update a record on a page in an index tree. It is assumed that mtr
holds an x-latch on the page. The operation does not succeed if there is too
little space on the page or if the update would result in too empty a page,
so that tree compression is recommended. We assume here that the ordering
-fields of the record do not change. */
+fields of the record do not change.
+@return DB_SUCCESS, or DB_OVERFLOW if the updated record does not fit,
+DB_UNDERFLOW if the page would become too empty, or DB_ZIP_OVERFLOW if
+there is not enough space left on the compressed page */
UNIV_INTERN
ulint
btr_cur_optimistic_update(
/*======================*/
- /* out: DB_SUCCESS, or DB_OVERFLOW if the
- updated record does not fit, DB_UNDERFLOW
- if the page would become too empty, or
- DB_ZIP_OVERFLOW if there is not enough
- space left on the compressed page */
- ulint flags, /* in: undo logging and locking flags */
- btr_cur_t* cursor, /* in: cursor on the record to update;
+ ulint flags, /*!< in: undo logging and locking flags */
+ btr_cur_t* cursor, /*!< in: cursor on the record to update;
cursor stays valid and positioned on the
same record */
- const upd_t* update, /* in: update vector; this must also
+ const upd_t* update, /*!< in: update vector; this must also
contain trx id and roll ptr fields */
- ulint cmpl_info,/* in: compiler info on secondary index
+ ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr; must be committed before
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr; must be committed before
latching any further pages */
{
dict_index_t* index;
@@ -1833,7 +1848,7 @@ btr_cur_optimistic_update(
ulint new_rec_size;
ulint old_rec_size;
dtuple_t* new_entry;
- dulint roll_ptr;
+ roll_ptr_t roll_ptr;
trx_t* trx;
mem_heap_t* heap;
ulint i;
@@ -1909,7 +1924,7 @@ any_extern:
if (UNIV_LIKELY_NULL(page_zip)
&& !btr_cur_update_alloc_zip(page_zip, block, index,
- new_rec_size, mtr)) {
+ new_rec_size, TRUE, mtr)) {
err = DB_ZIP_OVERFLOW;
goto err_exit;
}
@@ -1948,8 +1963,8 @@ any_extern:
}
/* Do lock checking and undo logging */
- err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info, thr,
- &roll_ptr);
+ 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);
@@ -2004,7 +2019,7 @@ err_exit:
return(DB_SUCCESS);
}
-/*****************************************************************
+/*************************************************************//**
If, in a split, a new supremum record was created as the predecessor of the
updated record, the supremum record must inherit exactly the locks on the
updated record. In the split it may have inherited locks from the successor
@@ -2014,9 +2029,9 @@ static
void
btr_cur_pess_upd_restore_supremum(
/*==============================*/
- buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: updated record */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: updated record */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* page;
buf_block_t* prev_block;
@@ -2052,30 +2067,30 @@ btr_cur_pess_upd_restore_supremum(
page_rec_get_heap_no(rec));
}
-/*****************************************************************
+/*************************************************************//**
Performs an update of a record on a page of a tree. It is assumed
that mtr holds an x-latch on the tree and on the cursor page. If the
update is made on the leaf level, to avoid deadlocks, mtr must also
own x-latches to brothers of page, if those brothers exist. We assume
-here that the ordering fields of the record do not change. */
+here that the ordering fields of the record do not change.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
btr_cur_pessimistic_update(
/*=======================*/
- /* out: DB_SUCCESS or error code */
- ulint flags, /* in: undo logging, locking, and rollback
+ ulint flags, /*!< in: undo logging, locking, and rollback
flags */
- btr_cur_t* cursor, /* in: cursor on the record to update */
- mem_heap_t** heap, /* in/out: pointer to memory heap, or NULL */
- big_rec_t** big_rec,/* out: big rec vector whose fields have to
+ btr_cur_t* cursor, /*!< in: cursor on the record to update */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
+ big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or NULL */
- const upd_t* update, /* in: update vector; this is allowed also
+ const upd_t* update, /*!< in: update vector; this is allowed also
contain trx id and roll ptr fields, but
the values in update vector have no effect */
- ulint cmpl_info,/* in: compiler info on secondary index
+ ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr; must be committed before
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr; must be committed before
latching any further pages */
{
big_rec_t* big_rec_vec = NULL;
@@ -2089,7 +2104,7 @@ btr_cur_pessimistic_update(
dtuple_t* new_entry;
ulint err;
ulint optim_err;
- dulint roll_ptr;
+ roll_ptr_t roll_ptr;
trx_t* trx;
ibool was_first;
ulint n_extents = 0;
@@ -2128,7 +2143,7 @@ btr_cur_pessimistic_update(
/* Do lock checking and undo logging */
err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
- thr, &roll_ptr);
+ thr, mtr, &roll_ptr);
if (err != DB_SUCCESS) {
return(err);
@@ -2303,6 +2318,19 @@ make_external:
ut_a(err == DB_SUCCESS);
ut_a(dummy_big_rec == NULL);
+ if (dict_index_is_sec_or_ibuf(index)) {
+ /* Update PAGE_MAX_TRX_ID in the index page header.
+ It was not updated by btr_cur_pessimistic_insert()
+ because of BTR_NO_LOCKING_FLAG. */
+ buf_block_t* rec_block;
+
+ rec_block = btr_cur_get_block(cursor);
+
+ page_update_max_trx_id(rec_block,
+ buf_block_get_page_zip(rec_block),
+ trx->id, mtr);
+ }
+
if (!rec_get_deleted_flag(rec, rec_offs_comp(offsets))) {
/* The new inserted record owns its possible externally
stored fields */
@@ -2349,20 +2377,20 @@ return_after_reservations:
/*==================== B-TREE DELETE MARK AND UNMARK ===============*/
-/********************************************************************
+/****************************************************************//**
Writes the redo log record for delete marking or unmarking of an index
record. */
UNIV_INLINE
void
btr_cur_del_mark_set_clust_rec_log(
/*===============================*/
- ulint flags, /* in: flags */
- rec_t* rec, /* in: record */
- dict_index_t* index, /* in: index of the record */
- ibool val, /* in: value to set */
- trx_t* trx, /* in: deleting transaction */
- dulint roll_ptr,/* in: roll ptr to the undo log record */
- mtr_t* mtr) /* in: mtr */
+ ulint flags, /*!< in: flags */
+ rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: index of the record */
+ ibool val, /*!< in: value to set */
+ trx_t* trx, /*!< in: deleting transaction */
+ roll_ptr_t roll_ptr,/*!< in: roll ptr to the undo log record */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* log_ptr;
ut_ad(flags < 256);
@@ -2394,28 +2422,29 @@ btr_cur_del_mark_set_clust_rec_log(
mlog_close(mtr, log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/********************************************************************
+/****************************************************************//**
Parses the redo log record for delete marking or unmarking of a clustered
-index record. */
+index record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_cur_parse_del_mark_set_clust_rec(
/*=================================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in/out: page or NULL */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- dict_index_t* index) /* in: index corresponding to page */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in/out: page or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ dict_index_t* index) /*!< in: index corresponding to page */
{
- ulint flags;
- ulint val;
- ulint pos;
- dulint trx_id;
- dulint roll_ptr;
- ulint offset;
- rec_t* rec;
+ ulint flags;
+ ulint val;
+ ulint pos;
+ trx_id_t trx_id;
+ roll_ptr_t roll_ptr;
+ ulint offset;
+ rec_t* rec;
ut_ad(!page
|| !!page_is_comp(page) == dict_table_is_comp(index->table));
@@ -2475,26 +2504,26 @@ btr_cur_parse_del_mark_set_clust_rec(
return(ptr);
}
-/***************************************************************
+#ifndef UNIV_HOTBACKUP
+/***********************************************************//**
Marks a clustered index record deleted. Writes an undo log record to
undo log on this delete marking. Writes in the trx id field the id
of the deleting transaction, and in the roll ptr field pointer to the
-undo log record created. */
+undo log record created.
+@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
UNIV_INTERN
ulint
btr_cur_del_mark_set_clust_rec(
/*===========================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
- number */
- ulint flags, /* in: undo logging and locking flags */
- btr_cur_t* cursor, /* in: cursor */
- ibool val, /* in: value to set */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr */
+ ulint flags, /*!< in: undo logging and locking flags */
+ btr_cur_t* cursor, /*!< in: cursor */
+ ibool val, /*!< in: value to set */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
buf_block_t* block;
- dulint roll_ptr;
+ roll_ptr_t roll_ptr;
ulint err;
rec_t* rec;
page_zip_des_t* page_zip;
@@ -2567,16 +2596,16 @@ func_exit:
return(err);
}
-/********************************************************************
+/****************************************************************//**
Writes the redo log record for a delete mark setting of a secondary
index record. */
UNIV_INLINE
void
btr_cur_del_mark_set_sec_rec_log(
/*=============================*/
- rec_t* rec, /* in: record */
- ibool val, /* in: value to set */
- mtr_t* mtr) /* in: mtr */
+ rec_t* rec, /*!< in: record */
+ ibool val, /*!< in: value to set */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* log_ptr;
ut_ad(val <= 1);
@@ -2599,19 +2628,20 @@ btr_cur_del_mark_set_sec_rec_log(
mlog_close(mtr, log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/********************************************************************
+/****************************************************************//**
Parses the redo log record for delete marking or unmarking of a secondary
-index record. */
+index record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_cur_parse_del_mark_set_sec_rec(
/*===============================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in/out: page or NULL */
- page_zip_des_t* page_zip)/* in/out: compressed page, or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in/out: page or NULL */
+ page_zip_des_t* page_zip)/*!< in/out: compressed page, or NULL */
{
ulint val;
ulint offset;
@@ -2643,19 +2673,19 @@ btr_cur_parse_del_mark_set_sec_rec(
return(ptr);
}
-/***************************************************************
-Sets a secondary index record delete mark to TRUE or FALSE. */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************//**
+Sets a secondary index record delete mark to TRUE or FALSE.
+@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
UNIV_INTERN
ulint
btr_cur_del_mark_set_sec_rec(
/*=========================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
- number */
- ulint flags, /* in: locking flag */
- btr_cur_t* cursor, /* in: cursor */
- ibool val, /* in: value to set */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr */
+ ulint flags, /*!< in: locking flag */
+ btr_cur_t* cursor, /*!< in: cursor */
+ ibool val, /*!< in: value to set */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
rec_t* rec;
@@ -2674,7 +2704,7 @@ btr_cur_del_mark_set_sec_rec(
err = lock_sec_rec_modify_check_and_lock(flags,
btr_cur_get_block(cursor),
- rec, cursor->index, thr);
+ rec, cursor->index, thr, mtr);
if (err != DB_SUCCESS) {
return(err);
@@ -2698,19 +2728,19 @@ btr_cur_del_mark_set_sec_rec(
return(DB_SUCCESS);
}
-/***************************************************************
+/***********************************************************//**
Clear a secondary index record's delete mark. This function is only
used by the insert buffer insert merge mechanism. */
UNIV_INTERN
void
btr_cur_del_unmark_for_ibuf(
/*========================*/
- rec_t* rec, /* in/out: record to delete unmark */
- page_zip_des_t* page_zip, /* in/out: compressed page
+ rec_t* rec, /*!< in/out: record to delete unmark */
+ page_zip_des_t* page_zip, /*!< in/out: compressed page
corresponding to rec, or NULL
when the tablespace is
uncompressed */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
/* We do not need to reserve btr_search_latch, as the page has just
been read to the buffer pool and there cannot be a hash index to it. */
@@ -2722,21 +2752,21 @@ btr_cur_del_unmark_for_ibuf(
/*==================== B-TREE RECORD REMOVE =========================*/
-/*****************************************************************
+/*************************************************************//**
Tries to compress a page of the tree if it seems useful. It is assumed
that mtr holds an x-latch on the tree and on the cursor page. To avoid
deadlocks, mtr must also own x-latches to brothers of page, if those
brothers exist. NOTE: it is assumed that the caller has reserved enough
-free extents so that the compression will always succeed if done! */
+free extents so that the compression will always succeed if done!
+@return TRUE if compression occurred */
UNIV_INTERN
ibool
btr_cur_compress_if_useful(
/*=======================*/
- /* out: TRUE if compression occurred */
- btr_cur_t* cursor, /* in: cursor on the page to compress;
+ btr_cur_t* cursor, /*!< in: cursor on the page to compress;
cursor does not stay valid if compression
occurs */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mtr_memo_contains(mtr,
dict_index_get_lock(btr_cur_get_index(cursor)),
@@ -2748,21 +2778,20 @@ btr_cur_compress_if_useful(
&& btr_compress(cursor, mtr));
}
-/***********************************************************
+/*******************************************************//**
Removes the record on which the tree cursor is positioned on a leaf page.
It is assumed that the mtr has an x-latch on the page where the cursor is
-positioned, but no latch on the whole tree. */
+positioned, but no latch on the whole tree.
+@return TRUE if success, i.e., the page did not become too empty */
UNIV_INTERN
ibool
btr_cur_optimistic_delete(
/*======================*/
- /* out: TRUE if success, i.e., the page
- did not become too empty */
- btr_cur_t* cursor, /* in: cursor on leaf page, on the record to
+ btr_cur_t* cursor, /*!< in: cursor on leaf page, on the record to
delete; cursor stays valid: if deletion
succeeds, on function exit it points to the
successor of the deleted record */
- mtr_t* mtr) /* in: mtr; if this function returns
+ mtr_t* mtr) /*!< in: mtr; if this function returns
TRUE on a leaf page of a secondary
index, the mtr must be committed
before latching any further pages */
@@ -2835,33 +2864,33 @@ btr_cur_optimistic_delete(
return(no_compress_needed);
}
-/*****************************************************************
+/*************************************************************//**
Removes the record on which the tree cursor is positioned. Tries
to compress the page if its fillfactor drops below a threshold
or if it is the only page on the level. It is assumed that mtr holds
an x-latch on the tree and on the cursor page. To avoid deadlocks,
mtr must also own x-latches to brothers of page, if those brothers
-exist. */
+exist.
+@return TRUE if compression occurred */
UNIV_INTERN
ibool
btr_cur_pessimistic_delete(
/*=======================*/
- /* out: TRUE if compression occurred */
- ulint* err, /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
+ ulint* err, /*!< out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
the latter may occur because we may have
to update node pointers on upper levels,
and in the case of variable length keys
these may actually grow in size */
- ibool has_reserved_extents, /* in: TRUE if the
+ ibool has_reserved_extents, /*!< in: TRUE if the
caller has already reserved enough free
extents so that he knows that the operation
will succeed */
- btr_cur_t* cursor, /* in: cursor on the record to delete;
+ btr_cur_t* cursor, /*!< in: cursor on the record to delete;
if compression does not occur, the cursor
stays valid: it points to successor of
deleted record on function exit */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* mtr) /* in: mtr */
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
page_t* page;
@@ -2998,17 +3027,17 @@ return_after_reservations:
return(ret);
}
-/***********************************************************************
+/*******************************************************************//**
Adds path information to the cursor for the current page, for which
the binary search has been performed. */
static
void
btr_cur_add_path_info(
/*==================*/
- btr_cur_t* cursor, /* in: cursor positioned on a page */
- ulint height, /* in: height of the page in tree;
+ btr_cur_t* cursor, /*!< in: cursor positioned on a page */
+ ulint height, /*!< in: height of the page in tree;
0 means leaf node */
- ulint root_height) /* in: root node height in tree */
+ ulint root_height) /*!< in: root node height in tree */
{
btr_path_t* slot;
rec_t* rec;
@@ -3038,18 +3067,18 @@ btr_cur_add_path_info(
slot->n_recs = page_get_n_recs(page_align(rec));
}
-/***********************************************************************
-Estimates the number of rows in a given index range. */
+/*******************************************************************//**
+Estimates the number of rows in a given index range.
+@return estimated number of rows */
UNIV_INTERN
ib_int64_t
btr_estimate_n_rows_in_range(
/*=========================*/
- /* out: estimated number of rows */
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple1, /* in: range start, may also be empty tuple */
- ulint mode1, /* in: search mode for range start */
- const dtuple_t* tuple2, /* in: range end, may also be empty tuple */
- ulint mode2) /* in: search mode for range end */
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
+ ulint mode1, /*!< in: search mode for range start */
+ const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
+ ulint mode2) /*!< in: search mode for range end */
{
btr_path_t path1[BTR_PATH_ARRAY_N_SLOTS];
btr_path_t path2[BTR_PATH_ARRAY_N_SLOTS];
@@ -3186,7 +3215,7 @@ btr_estimate_n_rows_in_range(
}
}
-/***********************************************************************
+/*******************************************************************//**
Estimates the number of different key values in a given index, for
each n-column prefix of the index where n <= dict_index_get_n_unique(index).
The estimates are stored in the array index->stat_n_diff_key_vals. */
@@ -3194,7 +3223,7 @@ UNIV_INTERN
void
btr_estimate_number_of_different_key_vals(
/*======================================*/
- dict_index_t* index) /* in: index */
+ dict_index_t* index) /*!< in: index */
{
btr_cur_t cursor;
page_t* page;
@@ -3267,7 +3296,7 @@ btr_estimate_number_of_different_key_vals(
}
while (rec != supremum) {
- rec_t* next_rec;
+ rec_t* next_rec;
/* count recs */
if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS) {
n_recs++;
@@ -3281,7 +3310,6 @@ btr_estimate_number_of_different_key_vals(
n_not_nulls[j]++;
}
}
-
next_rec = page_rec_get_next(rec);
if (next_rec == supremum) {
break;
@@ -3403,16 +3431,15 @@ btr_estimate_number_of_different_key_vals(
/*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/
-/***************************************************************
-Gets the externally stored size of a record, in units of a database page. */
+/***********************************************************//**
+Gets the externally stored size of a record, in units of a database page.
+@return externally stored part, in units of a database page */
static
ulint
btr_rec_get_externally_stored_len(
/*==============================*/
- /* out: externally stored part,
- in units of a database page */
- rec_t* rec, /* in: record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ rec_t* rec, /*!< in: record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n_fields;
byte* data;
@@ -3442,20 +3469,20 @@ btr_rec_get_externally_stored_len(
return(total_extern_len / UNIV_PAGE_SIZE);
}
-/***********************************************************************
+/*******************************************************************//**
Sets the ownership bit of an externally stored field in a record. */
static
void
btr_cur_set_ownership_of_extern_field(
/*==================================*/
- page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
part will be updated, or NULL */
- rec_t* rec, /* in/out: clustered index record */
- dict_index_t* index, /* in: index of the page */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint i, /* in: field number */
- ibool val, /* in: value to set */
- mtr_t* mtr) /* in: mtr, or NULL if not logged */
+ rec_t* rec, /*!< in/out: clustered index record */
+ dict_index_t* index, /*!< in: index of the page */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint i, /*!< in: field number */
+ ibool val, /*!< in: value to set */
+ mtr_t* mtr) /*!< in: mtr, or NULL if not logged */
{
byte* data;
ulint local_len;
@@ -3487,7 +3514,7 @@ btr_cur_set_ownership_of_extern_field(
}
}
-/***********************************************************************
+/*******************************************************************//**
Marks not updated extern fields as not-owned by this record. The ownership
is transferred to the updated record which is inserted elsewhere in the
index tree. In purge only the owner of externally stored field is allowed
@@ -3496,13 +3523,13 @@ UNIV_INTERN
void
btr_cur_mark_extern_inherited_fields(
/*=================================*/
- page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
part will be updated, or NULL */
- rec_t* rec, /* in/out: record in a clustered index */
- dict_index_t* index, /* in: index of the page */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- const upd_t* update, /* in: update vector */
- mtr_t* mtr) /* in: mtr, or NULL if not logged */
+ rec_t* rec, /*!< in/out: record in a clustered index */
+ dict_index_t* index, /*!< in: index of the page */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const upd_t* update, /*!< in: update vector */
+ mtr_t* mtr) /*!< in: mtr, or NULL if not logged */
{
ulint n;
ulint j;
@@ -3542,7 +3569,7 @@ updated:
}
}
-/***********************************************************************
+/*******************************************************************//**
The complement of the previous function: in an update entry may inherit
some externally stored fields from a record. We must mark them as inherited
in entry, so that they are not freed in a rollback. */
@@ -3550,9 +3577,9 @@ UNIV_INTERN
void
btr_cur_mark_dtuple_inherited_extern(
/*=================================*/
- dtuple_t* entry, /* in/out: updated entry to be
+ dtuple_t* entry, /*!< in/out: updated entry to be
inserted to clustered index */
- const upd_t* update) /* in: update vector */
+ const upd_t* update) /*!< in: update vector */
{
ulint i;
@@ -3586,7 +3613,7 @@ is_updated:
}
}
-/***********************************************************************
+/*******************************************************************//**
Marks all extern fields in a record as owned by the record. This function
should be called if the delete mark of a record is removed: a not delete
marked record always owns all its extern fields. */
@@ -3594,12 +3621,12 @@ static
void
btr_cur_unmark_extern_fields(
/*=========================*/
- page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
part will be updated, or NULL */
- rec_t* rec, /* in/out: record in a clustered index */
- dict_index_t* index, /* in: index of the page */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- mtr_t* mtr) /* in: mtr, or NULL if not logged */
+ rec_t* rec, /*!< in/out: record in a clustered index */
+ dict_index_t* index, /*!< in: index of the page */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ mtr_t* mtr) /*!< in: mtr, or NULL if not logged */
{
ulint n;
ulint i;
@@ -3621,13 +3648,13 @@ btr_cur_unmark_extern_fields(
}
}
-/***********************************************************************
+/*******************************************************************//**
Marks all extern fields in a dtuple as owned by the record. */
UNIV_INTERN
void
btr_cur_unmark_dtuple_extern_fields(
/*================================*/
- dtuple_t* entry) /* in/out: clustered index entry */
+ dtuple_t* entry) /*!< in/out: clustered index entry */
{
ulint i;
@@ -3644,18 +3671,18 @@ btr_cur_unmark_dtuple_extern_fields(
}
}
-/***********************************************************************
+/*******************************************************************//**
Flags the data tuple fields that are marked as extern storage in the
update vector. We use this function to remember which fields we must
-mark as extern storage in a record inserted for an update. */
+mark as extern storage in a record inserted for an update.
+@return number of flagged external columns */
UNIV_INTERN
ulint
btr_push_update_extern_fields(
/*==========================*/
- /* out: number of flagged external columns */
- dtuple_t* tuple, /* in/out: data tuple */
- const upd_t* update, /* in: update vector */
- mem_heap_t* heap) /* in: memory heap */
+ dtuple_t* tuple, /*!< in/out: data tuple */
+ const upd_t* update, /*!< in: update vector */
+ mem_heap_t* heap) /*!< in: memory heap */
{
ulint n_pushed = 0;
ulint n;
@@ -3724,41 +3751,40 @@ btr_push_update_extern_fields(
return(n_pushed);
}
-/***********************************************************************
-Returns the length of a BLOB part stored on the header page. */
+/*******************************************************************//**
+Returns the length of a BLOB part stored on the header page.
+@return part length */
static
ulint
btr_blob_get_part_len(
/*==================*/
- /* out: part length */
- const byte* blob_header) /* in: blob header */
+ const byte* blob_header) /*!< in: blob header */
{
return(mach_read_from_4(blob_header + BTR_BLOB_HDR_PART_LEN));
}
-/***********************************************************************
-Returns the page number where the next BLOB part is stored. */
+/*******************************************************************//**
+Returns the page number where the next BLOB part is stored.
+@return page number or FIL_NULL if no more pages */
static
ulint
btr_blob_get_next_page_no(
/*======================*/
- /* out: page number or FIL_NULL if
- no more pages */
- const byte* blob_header) /* in: blob header */
+ const byte* blob_header) /*!< in: blob header */
{
return(mach_read_from_4(blob_header + BTR_BLOB_HDR_NEXT_PAGE_NO));
}
-/***********************************************************************
+/*******************************************************************//**
Deallocate a buffer block that was reserved for a BLOB part. */
static
void
btr_blob_free(
/*==========*/
- buf_block_t* block, /* in: buffer block */
- ibool all, /* in: TRUE=remove also the compressed page
+ buf_block_t* block, /*!< in: buffer block */
+ ibool all, /*!< in: TRUE=remove also the compressed page
if there is one */
- mtr_t* mtr) /* in: mini-transaction to commit */
+ mtr_t* mtr) /*!< in: mini-transaction to commit */
{
ulint space = buf_block_get_space(block);
ulint page_no = buf_block_get_page_no(block);
@@ -3798,27 +3824,27 @@ btr_blob_free(
mutex_exit(&block->mutex);
}
-/***********************************************************************
+/*******************************************************************//**
Stores the fields in big_rec_vec to the tablespace and puts pointers to
them in rec. The extern flags in rec will have to be set beforehand.
The fields are stored on pages allocated from leaf node
-file segment of the index tree. */
+file segment of the index tree.
+@return DB_SUCCESS or error */
UNIV_INTERN
ulint
btr_store_big_rec_extern_fields(
/*============================*/
- /* out: DB_SUCCESS or error */
- dict_index_t* index, /* in: index of rec; the index tree
+ dict_index_t* index, /*!< in: index of rec; the index tree
MUST be X-latched */
- buf_block_t* rec_block, /* in/out: block containing rec */
- rec_t* rec, /* in/out: record */
- const ulint* offsets, /* in: rec_get_offsets(rec, index);
+ buf_block_t* rec_block, /*!< in/out: block containing rec */
+ rec_t* rec, /*!< in/out: record */
+ const ulint* offsets, /*!< in: rec_get_offsets(rec, index);
the "external storage" flags in offsets
will not correspond to rec when
this function returns */
- big_rec_t* big_rec_vec, /* in: vector containing fields
+ big_rec_t* big_rec_vec, /*!< in: vector containing fields
to be stored externally */
- mtr_t* local_mtr __attribute__((unused))) /* in: mtr
+ mtr_t* local_mtr __attribute__((unused))) /*!< in: mtr
containing the latch to rec and to the
tree */
{
@@ -3959,10 +3985,21 @@ btr_store_big_rec_extern_fields(
int err;
page_zip_des_t* blob_page_zip;
- mach_write_to_2(page + FIL_PAGE_TYPE,
- prev_page_no == FIL_NULL
- ? FIL_PAGE_TYPE_ZBLOB
- : FIL_PAGE_TYPE_ZBLOB2);
+ /* Write FIL_PAGE_TYPE to the redo log
+ separately, before logging any other
+ changes to the page, so that the debug
+ assertions in
+ recv_parse_or_apply_log_rec_body() can
+ be made simpler. Before InnoDB Plugin
+ 1.0.4, the initialization of
+ FIL_PAGE_TYPE was logged as part of
+ the mlog_log_string() below. */
+
+ mlog_write_ulint(page + FIL_PAGE_TYPE,
+ prev_page_no == FIL_NULL
+ ? FIL_PAGE_TYPE_ZBLOB
+ : FIL_PAGE_TYPE_ZBLOB2,
+ MLOG_2BYTES, &mtr);
c_stream.next_out = page
+ FIL_PAGE_DATA;
@@ -4008,9 +4045,9 @@ btr_store_big_rec_extern_fields(
memset(page + page_zip_get_size(page_zip)
- c_stream.avail_out,
0, c_stream.avail_out);
- mlog_log_string(page + FIL_PAGE_TYPE,
+ mlog_log_string(page + FIL_PAGE_FILE_FLUSH_LSN,
page_zip_get_size(page_zip)
- - FIL_PAGE_TYPE,
+ - FIL_PAGE_FILE_FLUSH_LSN,
&mtr);
/* Copy the page to compressed storage,
because it will be flushed to disk
@@ -4155,16 +4192,16 @@ next_zip_page:
return(DB_SUCCESS);
}
-/***********************************************************************
+/*******************************************************************//**
Check the FIL_PAGE_TYPE on an uncompressed BLOB page. */
static
void
btr_check_blob_fil_page_type(
/*=========================*/
- ulint space_id, /* in: space id */
- ulint page_no, /* in: page number */
- const page_t* page, /* in: page */
- ibool read) /* in: TRUE=read, FALSE=purge */
+ ulint space_id, /*!< in: space id */
+ ulint page_no, /*!< in: page number */
+ const page_t* page, /*!< in: page */
+ ibool read) /*!< in: TRUE=read, FALSE=purge */
{
ulint type = fil_page_get_type(page);
@@ -4193,7 +4230,7 @@ btr_check_blob_fil_page_type(
}
}
-/***********************************************************************
+/*******************************************************************//**
Frees the space in an externally stored field to the file space
management if the field in data is owned by the externally stored field,
in a rollback we may have the additional condition that the field must
@@ -4202,7 +4239,7 @@ UNIV_INTERN
void
btr_free_externally_stored_field(
/*=============================*/
- dict_index_t* index, /* in: index of the data, the index
+ dict_index_t* index, /*!< in: index of the data, the index
tree MUST be X-latched; if the tree
height is 1, then also the root page
must be X-latched! (this is relevant
@@ -4210,17 +4247,17 @@ btr_free_externally_stored_field(
from purge where 'data' is located on
an undo log page, not an index
page) */
- byte* field_ref, /* in/out: field reference */
- const rec_t* rec, /* in: record containing field_ref, for
+ byte* field_ref, /*!< in/out: field reference */
+ const rec_t* rec, /*!< in: record containing field_ref, for
page_zip_write_blob_ptr(), or NULL */
- const ulint* offsets, /* in: rec_get_offsets(rec, index),
+ const ulint* offsets, /*!< in: rec_get_offsets(rec, index),
or NULL */
- page_zip_des_t* page_zip, /* in: compressed page corresponding
+ page_zip_des_t* page_zip, /*!< in: compressed page corresponding
to rec, or NULL if rec == NULL */
- ulint i, /* in: field number of field_ref;
+ ulint i, /*!< in: field number of field_ref;
ignored if rec == NULL */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* local_mtr __attribute__((unused))) /* in: mtr
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* local_mtr __attribute__((unused))) /*!< in: mtr
containing the latch to data an an
X-latch to the index tree */
{
@@ -4378,20 +4415,20 @@ btr_free_externally_stored_field(
}
}
-/***************************************************************
+/***********************************************************//**
Frees the externally stored fields for a record. */
static
void
btr_rec_free_externally_stored_fields(
/*==================================*/
- dict_index_t* index, /* in: index of the data, the index
+ dict_index_t* index, /*!< in: index of the data, the index
tree MUST be X-latched */
- rec_t* rec, /* in/out: record */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ rec_t* rec, /*!< in/out: record */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* mtr) /* in: mini-transaction handle which contains
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* mtr) /*!< in: mini-transaction handle which contains
an X-latch to record page and to the index
tree */
{
@@ -4419,22 +4456,22 @@ btr_rec_free_externally_stored_fields(
}
}
-/***************************************************************
+/***********************************************************//**
Frees the externally stored fields for a record, if the field is mentioned
in the update vector. */
static
void
btr_rec_free_updated_extern_fields(
/*===============================*/
- dict_index_t* index, /* in: index of rec; the index tree MUST be
+ dict_index_t* index, /*!< in: index of rec; the index tree MUST be
X-latched */
- rec_t* rec, /* in/out: record */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ rec_t* rec, /*!< in/out: record */
+ page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- const upd_t* update, /* in: update vector */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* mtr) /* in: mini-transaction handle which contains
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const upd_t* update, /*!< in: update vector */
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* mtr) /*!< in: mini-transaction handle which contains
an X-latch to record page and to the tree */
{
ulint n_fields;
@@ -4464,20 +4501,20 @@ btr_rec_free_updated_extern_fields(
}
}
-/***********************************************************************
+/*******************************************************************//**
Copies the prefix of an uncompressed BLOB. The clustered index record
-that points to this BLOB must be protected by a lock or a page latch. */
+that points to this BLOB must be protected by a lock or a page latch.
+@return number of bytes written to buf */
static
ulint
btr_copy_blob_prefix(
/*=================*/
- /* out: number of bytes written to buf */
- byte* buf, /* out: the externally stored part of
+ byte* buf, /*!< out: the externally stored part of
the field, or a prefix of it */
- ulint len, /* in: length of buf, in bytes */
- ulint space_id,/* in: space id of the BLOB pages */
- ulint page_no,/* in: page number of the first BLOB page */
- ulint offset) /* in: offset on the first BLOB page */
+ ulint len, /*!< in: length of buf, in bytes */
+ ulint space_id,/*!< in: space id of the BLOB pages */
+ ulint page_no,/*!< in: page number of the first BLOB page */
+ ulint offset) /*!< in: offset on the first BLOB page */
{
ulint copied_len = 0;
@@ -4522,18 +4559,18 @@ btr_copy_blob_prefix(
}
}
-/***********************************************************************
+/*******************************************************************//**
Copies the prefix of a compressed BLOB. The clustered index record
that points to this BLOB must be protected by a lock or a page latch. */
static
void
btr_copy_zblob_prefix(
/*==================*/
- z_stream* d_stream,/* in/out: the decompressing stream */
- ulint zip_size,/* in: compressed BLOB page size */
- ulint space_id,/* in: space id of the BLOB pages */
- ulint page_no,/* in: page number of the first BLOB page */
- ulint offset) /* in: offset on the first BLOB page */
+ z_stream* d_stream,/*!< in/out: the decompressing stream */
+ ulint zip_size,/*!< in: compressed BLOB page size */
+ ulint space_id,/*!< in: space id of the BLOB pages */
+ ulint page_no,/*!< in: page number of the first BLOB page */
+ ulint offset) /*!< in: offset on the first BLOB page */
{
ulint page_type = FIL_PAGE_TYPE_ZBLOB;
@@ -4650,23 +4687,23 @@ end_of_blob:
}
}
-/***********************************************************************
+/*******************************************************************//**
Copies the prefix of an externally stored field of a record. The
clustered index record that points to this BLOB must be protected by a
-lock or a page latch. */
+lock or a page latch.
+@return number of bytes written to buf */
static
ulint
btr_copy_externally_stored_field_prefix_low(
/*========================================*/
- /* out: number of bytes written to buf */
- byte* buf, /* out: the externally stored part of
+ byte* buf, /*!< out: the externally stored part of
the field, or a prefix of it */
- ulint len, /* in: length of buf, in bytes */
- ulint zip_size,/* in: nonzero=compressed BLOB page size,
+ ulint len, /*!< in: length of buf, in bytes */
+ ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
- ulint space_id,/* in: space id of the first BLOB page */
- ulint page_no,/* in: page number of the first BLOB page */
- ulint offset) /* in: offset on the first BLOB page */
+ ulint space_id,/*!< in: space id of the first BLOB page */
+ ulint page_no,/*!< in: page number of the first BLOB page */
+ ulint offset) /*!< in: offset on the first BLOB page */
{
if (UNIV_UNLIKELY(len == 0)) {
return(0);
@@ -4700,25 +4737,24 @@ btr_copy_externally_stored_field_prefix_low(
}
}
-/***********************************************************************
+/*******************************************************************//**
Copies the prefix of an externally stored field of a record. The
-clustered index record must be protected by a lock or a page latch. */
+clustered index record must be protected by a lock or a page latch.
+@return the length of the copied field, or 0 if the column was being
+or has been deleted */
UNIV_INTERN
ulint
btr_copy_externally_stored_field_prefix(
/*====================================*/
- /* out: the length of the copied field,
- or 0 if the column was being or has been
- deleted */
- byte* buf, /* out: the field, or a prefix of it */
- ulint len, /* in: length of buf, in bytes */
- ulint zip_size,/* in: nonzero=compressed BLOB page size,
+ byte* buf, /*!< out: the field, or a prefix of it */
+ ulint len, /*!< in: length of buf, in bytes */
+ ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
- const byte* data, /* in: 'internally' stored part of the
+ const byte* data, /*!< in: 'internally' stored part of the
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len)/* in: length of data, in bytes */
+ ulint local_len)/*!< in: length of data, in bytes */
{
ulint space_id;
ulint page_no;
@@ -4760,23 +4796,23 @@ btr_copy_externally_stored_field_prefix(
offset));
}
-/***********************************************************************
+/*******************************************************************//**
Copies an externally stored field of a record to mem heap. The
-clustered index record must be protected by a lock or a page latch. */
+clustered index record must be protected by a lock or a page latch.
+@return the whole field copied to heap */
static
byte*
btr_copy_externally_stored_field(
/*=============================*/
- /* out: the whole field copied to heap */
- ulint* len, /* out: length of the whole field */
- const byte* data, /* in: 'internally' stored part of the
+ ulint* len, /*!< out: length of the whole field */
+ const byte* data, /*!< in: 'internally' stored part of the
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint zip_size,/* in: nonzero=compressed BLOB page size,
+ ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
- ulint local_len,/* in: length of data */
- mem_heap_t* heap) /* in: mem heap */
+ ulint local_len,/*!< in: length of data */
+ mem_heap_t* heap) /*!< in: mem heap */
{
ulint space_id;
ulint page_no;
@@ -4812,21 +4848,21 @@ btr_copy_externally_stored_field(
return(buf);
}
-/***********************************************************************
-Copies an externally stored field of a record to mem heap. */
+/*******************************************************************//**
+Copies an externally stored field of a record to mem heap.
+@return the field copied to heap */
UNIV_INTERN
byte*
btr_rec_copy_externally_stored_field(
/*=================================*/
- /* out: the field copied to heap */
- const rec_t* rec, /* in: record in a clustered index;
+ const rec_t* rec, /*!< in: record in a clustered index;
must be protected by a lock or a page latch */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint zip_size,/* in: nonzero=compressed BLOB page size,
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
- ulint no, /* in: field number */
- ulint* len, /* out: length of the field */
- mem_heap_t* heap) /* in: mem heap */
+ ulint no, /*!< in: field number */
+ ulint* len, /*!< out: length of the field */
+ mem_heap_t* heap) /*!< in: mem heap */
{
ulint local_len;
const byte* data;
@@ -4847,3 +4883,4 @@ btr_rec_copy_externally_stored_field(
return(btr_copy_externally_stored_field(len, data,
zip_size, local_len, heap));
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/btr/btr0pcur.c b/storage/xtradb/btr/btr0pcur.c
index b14efefe13f..ec98692c35b 100644
--- a/storage/xtradb/btr/btr0pcur.c
+++ b/storage/xtradb/btr/btr0pcur.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file btr/btr0pcur.c
The index tree persistent cursor
Created 2/23/1996 Heikki Tuuri
@@ -32,13 +33,13 @@ Created 2/23/1996 Heikki Tuuri
#include "rem0cmp.h"
#include "trx0trx.h"
-/******************************************************************
-Allocates memory for a persistent cursor object and initializes the cursor. */
+/**************************************************************//**
+Allocates memory for a persistent cursor object and initializes the cursor.
+@return own: persistent cursor */
UNIV_INTERN
btr_pcur_t*
btr_pcur_create_for_mysql(void)
/*============================*/
- /* out, own: persistent cursor */
{
btr_pcur_t* pcur;
@@ -50,13 +51,13 @@ btr_pcur_create_for_mysql(void)
return(pcur);
}
-/******************************************************************
+/**************************************************************//**
Frees the memory for a persistent cursor object. */
UNIV_INTERN
void
btr_pcur_free_for_mysql(
/*====================*/
- btr_pcur_t* cursor) /* in, own: persistent cursor */
+ btr_pcur_t* cursor) /*!< in, own: persistent cursor */
{
if (cursor->old_rec_buf != NULL) {
@@ -76,7 +77,7 @@ btr_pcur_free_for_mysql(
mem_free(cursor);
}
-/******************************************************************
+/**************************************************************//**
The position of the cursor is stored by taking an initial segment of the
record the cursor is positioned on, before, or after, and copying it to the
cursor data structure, or just setting a flag if the cursor id before the
@@ -87,8 +88,8 @@ UNIV_INTERN
void
btr_pcur_store_position(
/*====================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr) /* in: mtr */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_cur_t* page_cursor;
buf_block_t* block;
@@ -157,15 +158,15 @@ btr_pcur_store_position(
cursor->modify_clock = buf_block_get_modify_clock(block);
}
-/******************************************************************
+/**************************************************************//**
Copies the stored position of a pcur to another pcur. */
UNIV_INTERN
void
btr_pcur_copy_stored_position(
/*==========================*/
- btr_pcur_t* pcur_receive, /* in: pcur which will receive the
+ btr_pcur_t* pcur_receive, /*!< in: pcur which will receive the
position info */
- btr_pcur_t* pcur_donate) /* in: pcur from which the info is
+ btr_pcur_t* pcur_donate) /*!< in: pcur from which the info is
copied */
{
if (pcur_receive->old_rec_buf) {
@@ -187,7 +188,7 @@ btr_pcur_copy_stored_position(
pcur_receive->old_n_fields = pcur_donate->old_n_fields;
}
-/******************************************************************
+/**************************************************************//**
Restores the stored position of a persistent cursor bufferfixing the page and
obtaining the specified latches. If the cursor position was saved when the
(1) cursor was positioned on a user record: this function restores the position
@@ -198,19 +199,17 @@ infimum;
(3) cursor was positioned on the page supremum: restores to the first record
GREATER than the user record which was the predecessor of the supremum.
(4) cursor was positioned before the first or after the last in an empty tree:
-restores to before first or after the last in the tree. */
+restores to before first or after the last in the tree.
+@return TRUE if the cursor position was stored when it was on a user
+record and it can be restored on a user record whose ordering fields
+are identical to the ones of the original user record */
UNIV_INTERN
ibool
btr_pcur_restore_position(
/*======================*/
- /* out: TRUE if the cursor position
- was stored when it was on a user record
- and it can be restored on a user record
- whose ordering fields are identical to
- the ones of the original user record */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_pcur_t* cursor, /* in: detached persistent cursor */
- mtr_t* mtr) /* in: mtr */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_pcur_t* cursor, /*!< in: detached persistent cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
dtuple_t* tuple;
@@ -351,7 +350,7 @@ btr_pcur_restore_position(
return(FALSE);
}
-/******************************************************************
+/**************************************************************//**
If the latch mode of the cursor is BTR_LEAF_SEARCH or BTR_LEAF_MODIFY,
releases the page latch and bufferfix reserved by the cursor.
NOTE! In the case of BTR_LEAF_MODIFY, there should not exist changes
@@ -361,8 +360,8 @@ UNIV_INTERN
void
btr_pcur_release_leaf(
/*==================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr) /* in: mtr */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
@@ -378,7 +377,7 @@ btr_pcur_release_leaf(
cursor->pos_state = BTR_PCUR_WAS_POSITIONED;
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor to the first record on the next page. Releases the
latch on the current page, and bufferunfixes it. Note that there must not be
modifications on the current page, as then the x-latch can be released only in
@@ -387,9 +386,9 @@ UNIV_INTERN
void
btr_pcur_move_to_next_page(
/*=======================*/
- btr_pcur_t* cursor, /* in: persistent cursor; must be on the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; must be on the
last record of the current page */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint next_page_no;
ulint space;
@@ -429,7 +428,7 @@ btr_pcur_move_to_next_page(
page_check_dir(next_page);
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor backward if it is on the first record of the page.
Commits mtr. Note that to prevent a possible deadlock, the operation
first stores the position of the cursor, commits mtr, acquires the necessary
@@ -442,9 +441,9 @@ UNIV_INTERN
void
btr_pcur_move_backward_from_page(
/*=============================*/
- btr_pcur_t* cursor, /* in: persistent cursor, must be on the first
+ btr_pcur_t* cursor, /*!< in: persistent cursor, must be on the first
record of the current page */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint prev_page_no;
ulint space;
@@ -511,18 +510,17 @@ btr_pcur_move_backward_from_page(
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor to the previous record in the tree. If no records
-are left, the cursor stays 'before first in tree'. */
+are left, the cursor stays 'before first in tree'.
+@return TRUE if the cursor was not before first in tree */
UNIV_INTERN
ibool
btr_pcur_move_to_prev(
/*==================*/
- /* out: TRUE if the cursor was not before first
- in tree */
- btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -546,7 +544,7 @@ btr_pcur_move_to_prev(
return(TRUE);
}
-/******************************************************************
+/**************************************************************//**
If mode is PAGE_CUR_G or PAGE_CUR_GE, opens a persistent cursor on the first
user record satisfying the search condition, in the case PAGE_CUR_L or
PAGE_CUR_LE, on the last user record. If no such user record exists, then
@@ -557,14 +555,14 @@ UNIV_INTERN
void
btr_pcur_open_on_user_rec(
/*======================*/
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple, /* in: tuple on which search done */
- ulint mode, /* in: PAGE_CUR_L, ... */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF or
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple, /*!< in: tuple on which search done */
+ ulint mode, /*!< in: PAGE_CUR_L, ... */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */
- btr_pcur_t* cursor, /* in: memory buffer for persistent
+ btr_pcur_t* cursor, /*!< in: memory buffer for persistent
cursor */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
btr_pcur_open(index, tuple, mode, latch_mode, cursor, mtr);
diff --git a/storage/xtradb/btr/btr0sea.c b/storage/xtradb/btr/btr0sea.c
index a60f02cf86c..14f4b94f51b 100644
--- a/storage/xtradb/btr/btr0sea.c
+++ b/storage/xtradb/btr/btr0sea.c
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file btr/btr0sea.c
The index tree adaptive search
Created 2/17/1996 Heikki Tuuri
@@ -42,26 +43,29 @@ Created 2/17/1996 Heikki Tuuri
#include "btr0btr.h"
#include "ha0ha.h"
-/* Flag: has the search system been enabled?
+/** Flag: has the search system been enabled?
Protected by btr_search_latch and btr_search_enabled_mutex. */
UNIV_INTERN char btr_search_enabled = TRUE;
+/** Mutex protecting btr_search_enabled */
static mutex_t btr_search_enabled_mutex;
-/* A dummy variable to fool the compiler */
+/** A dummy variable to fool the compiler */
UNIV_INTERN ulint btr_search_this_is_zero = 0;
#ifdef UNIV_SEARCH_PERF_STAT
+/** Number of successful adaptive hash index lookups */
UNIV_INTERN ulint btr_search_n_succ = 0;
+/** Number of failed adaptive hash index lookups */
UNIV_INTERN ulint btr_search_n_hash_fail = 0;
#endif /* UNIV_SEARCH_PERF_STAT */
-/* padding to prevent other memory update
+/** padding to prevent other memory update
hotspots from residing on the same memory
cache line as btr_search_latch */
UNIV_INTERN byte btr_sea_pad1[64];
-/* The latch protecting the adaptive search system: this latch protects the
+/** The latch protecting the adaptive search system: this latch protects the
(1) positions of records on those pages where a hash index has been built.
NOTE: It does not protect values of non-ordering fields within a record from
being updated in-place! We can use fact (1) to perform unique searches to
@@ -71,24 +75,23 @@ indexes. */
same DRAM page as other hotspot semaphores */
UNIV_INTERN rw_lock_t* btr_search_latch_temp;
-/* padding to prevent other memory update hotspots from residing on
+/** padding to prevent other memory update hotspots from residing on
the same memory cache line */
UNIV_INTERN byte btr_sea_pad2[64];
+/** The adaptive hash index */
UNIV_INTERN btr_search_sys_t* btr_search_sys;
-/* If the number of records on the page divided by this parameter
+/** If the number of records on the page divided by this parameter
would have been successfully accessed using a hash index, the index
is then built on the page, assuming the global limit has been reached */
-
#define BTR_SEARCH_PAGE_BUILD_LIMIT 16
-/* The global limit for consecutive potentially successful hash searches,
+/** The global limit for consecutive potentially successful hash searches,
before hash index building is started */
-
#define BTR_SEARCH_BUILD_LIMIT 100
-/************************************************************************
+/********************************************************************//**
Builds a hash index on a page with the given parameters. If the page already
has a hash index with different parameters, the old hash index is removed.
If index is non-NULL, this function checks if n_fields and n_bytes are
@@ -97,15 +100,15 @@ static
void
btr_search_build_page_hash_index(
/*=============================*/
- dict_index_t* index, /* in: index for which to build, or NULL if
+ dict_index_t* index, /*!< in: index for which to build, or NULL if
not known */
- buf_block_t* block, /* in: index page, s- or x-latched */
- ulint n_fields,/* in: hash this many full fields */
- ulint n_bytes,/* in: hash this many bytes from the next
+ buf_block_t* block, /*!< in: index page, s- or x-latched */
+ ulint n_fields,/*!< in: hash this many full fields */
+ ulint n_bytes,/*!< in: hash this many bytes from the next
field */
- ibool left_side);/* in: hash for searches from left side? */
+ ibool left_side);/*!< in: hash for searches from left side? */
-/*********************************************************************
+/*****************************************************************//**
This function should be called before reserving any btr search mutex, if
the intended operation might add nodes to the search system hash table.
Because of the latching order, once we have reserved the btr search system
@@ -151,13 +154,13 @@ btr_search_check_free_space_in_heap(void)
}
}
-/*********************************************************************
+/*****************************************************************//**
Creates and initializes the adaptive search system at a database start. */
UNIV_INTERN
void
btr_search_sys_create(
/*==================*/
- ulint hash_size) /* in: hash index hash table size */
+ ulint hash_size) /*!< in: hash index hash table size */
{
/* We allocate the search latch from dynamic memory:
see above at the global variable definition */
@@ -172,7 +175,7 @@ btr_search_sys_create(
btr_search_sys->hash_index = ha_create(hash_size, 0, 0);
}
-/************************************************************************
+/********************************************************************//**
Disable the adaptive hash search system and empty the index. */
UNIV_INTERN
void
@@ -195,7 +198,7 @@ btr_search_disable(void)
mutex_exit(&btr_search_enabled_mutex);
}
-/************************************************************************
+/********************************************************************//**
Enable the adaptive hash search system. */
UNIV_INTERN
void
@@ -211,14 +214,14 @@ btr_search_enable(void)
mutex_exit(&btr_search_enabled_mutex);
}
-/*********************************************************************
-Creates and initializes a search info struct. */
+/*****************************************************************//**
+Creates and initializes a search info struct.
+@return own: search info struct */
UNIV_INTERN
btr_search_t*
btr_search_info_create(
/*===================*/
- /* out, own: search info struct */
- mem_heap_t* heap) /* in: heap where created */
+ mem_heap_t* heap) /*!< in: heap where created */
{
btr_search_t* info;
@@ -252,15 +255,15 @@ btr_search_info_create(
return(info);
}
-/*********************************************************************
+/*****************************************************************//**
Returns the value of ref_count. The value is protected by
-btr_search_latch. */
+btr_search_latch.
+@return ref_count value. */
UNIV_INTERN
ulint
btr_search_info_get_ref_count(
/*==========================*/
- /* out: ref_count value. */
- btr_search_t* info) /* in: search info. */
+ btr_search_t* info) /*!< in: search info. */
{
ulint ret;
@@ -278,7 +281,7 @@ btr_search_info_get_ref_count(
return(ret);
}
-/*************************************************************************
+/*********************************************************************//**
Updates the search info of an index about hash successes. NOTE that info
is NOT protected by any semaphore, to save CPU time! Do not assume its fields
are consistent. */
@@ -286,8 +289,8 @@ static
void
btr_search_info_update_hash(
/*========================*/
- btr_search_t* info, /* in/out: search info */
- btr_cur_t* cursor) /* in: cursor which was just positioned */
+ btr_search_t* info, /*!< in/out: search info */
+ btr_cur_t* cursor) /*!< in: cursor which was just positioned */
{
dict_index_t* index;
ulint n_unique;
@@ -398,20 +401,19 @@ set_new_recomm:
}
}
-/*************************************************************************
+/*********************************************************************//**
Updates the block search info on hash successes. NOTE that info and
block->n_hash_helps, n_fields, n_bytes, side are NOT protected by any
-semaphore, to save CPU time! Do not assume the fields are consistent. */
+semaphore, to save CPU time! Do not assume the fields are consistent.
+@return TRUE if building a (new) hash index on the block is recommended */
static
ibool
btr_search_update_block_hash_info(
/*==============================*/
- /* out: TRUE if building a (new) hash index on
- the block is recommended */
- btr_search_t* info, /* in: search info */
- buf_block_t* block, /* in: buffer block */
+ btr_search_t* info, /*!< in: search info */
+ buf_block_t* block, /*!< in: buffer block */
btr_cur_t* cursor __attribute__((unused)))
- /* in: cursor */
+ /*!< in: cursor */
{
#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
@@ -477,7 +479,7 @@ btr_search_update_block_hash_info(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Updates a hash node reference when it has been unsuccessfully used in a
search which could have succeeded with the used hash parameters. This can
happen because when building a hash index for a page, we do not check
@@ -489,9 +491,9 @@ static
void
btr_search_update_hash_ref(
/*=======================*/
- btr_search_t* info, /* in: search info */
- buf_block_t* block, /* in: buffer block where cursor positioned */
- btr_cur_t* cursor) /* in: cursor */
+ btr_search_t* info, /*!< in: search info */
+ buf_block_t* block, /*!< in: buffer block where cursor positioned */
+ btr_cur_t* cursor) /*!< in: cursor */
{
ulint fold;
rec_t* rec;
@@ -547,14 +549,14 @@ btr_search_update_hash_ref(
}
}
-/*************************************************************************
+/*********************************************************************//**
Updates the search info. */
UNIV_INTERN
void
btr_search_info_update_slow(
/*========================*/
- btr_search_t* info, /* in/out: search info */
- btr_cur_t* cursor) /* in: cursor which was just positioned */
+ btr_search_t* info, /*!< in/out: search info */
+ btr_cur_t* cursor) /*!< in: cursor which was just positioned */
{
buf_block_t* block;
ibool build_index;
@@ -624,28 +626,28 @@ btr_search_info_update_slow(
}
}
-/**********************************************************************
+/******************************************************************//**
Checks if a guessed position for a tree cursor is right. Note that if
mode is PAGE_CUR_LE, which is used in inserts, and the function returns
-TRUE, then cursor->up_match and cursor->low_match both have sensible values. */
+TRUE, then cursor->up_match and cursor->low_match both have sensible values.
+@return TRUE if success */
static
ibool
btr_search_check_guess(
/*===================*/
- /* out: TRUE if success */
- btr_cur_t* cursor, /* in: guessed cursor position */
+ btr_cur_t* cursor, /*!< in: guessed cursor position */
ibool can_only_compare_to_cursor_rec,
- /* in: if we do not have a latch on the page
+ /*!< in: if we do not have a latch on the page
of cursor, but only a latch on
btr_search_latch, then ONLY the columns
of the record UNDER the cursor are
protected, not the next or previous record
in the chain: we cannot look at the next or
previous record to check our guess! */
- const dtuple_t* tuple, /* in: data tuple */
- ulint mode, /* in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G,
+ const dtuple_t* tuple, /*!< in: data tuple */
+ ulint mode, /*!< in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G,
or PAGE_CUR_GE */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
rec_t* rec;
ulint n_unique;
@@ -770,31 +772,31 @@ exit_func:
return(success);
}
-/**********************************************************************
+/******************************************************************//**
Tries to guess the right search position based on the hash search info
of the index. Note that if mode is PAGE_CUR_LE, which is used in inserts,
and the function returns TRUE, then cursor->up_match and cursor->low_match
-both have sensible values. */
+both have sensible values.
+@return TRUE if succeeded */
UNIV_INTERN
ibool
btr_search_guess_on_hash(
/*=====================*/
- /* out: TRUE if succeeded */
- dict_index_t* index, /* in: index */
- btr_search_t* info, /* in: index search info */
- const dtuple_t* tuple, /* in: logical record */
- ulint mode, /* in: PAGE_CUR_L, ... */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ...;
+ dict_index_t* index, /*!< in: index */
+ btr_search_t* info, /*!< in: index search info */
+ const dtuple_t* tuple, /*!< in: logical record */
+ ulint mode, /*!< in: PAGE_CUR_L, ... */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ...;
NOTE that only if has_search_latch
is 0, we will have a latch set on
the cursor page, otherwise we assume
the caller uses his search latch
to protect the record! */
- btr_cur_t* cursor, /* out: tree cursor */
- ulint has_search_latch,/* in: latch mode the caller
+ btr_cur_t* cursor, /*!< out: tree cursor */
+ ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch:
RW_S_LATCH, RW_X_LATCH, or 0 */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
rec_t* rec;
@@ -979,13 +981,13 @@ failure:
return(FALSE);
}
-/************************************************************************
+/********************************************************************//**
Drops a page hash index. */
UNIV_INTERN
void
btr_search_drop_page_hash_index(
/*============================*/
- buf_block_t* block) /* in: block containing index page,
+ buf_block_t* block) /*!< in: block containing index page,
s- or x-latched, or an index page
for which we know that
block->buf_fix_count == 0 */
@@ -1147,16 +1149,136 @@ cleanup:
}
/************************************************************************
+Drops a page hash index based on index */
+UNIV_INTERN
+void
+btr_search_drop_page_hash_index_on_index(
+/*=====================================*/
+ dict_index_t* index) /* in: record descriptor */
+{
+ buf_page_t* bpage;
+ hash_table_t* table;
+ buf_block_t* block;
+ ulint n_fields;
+ ulint n_bytes;
+ const page_t* page;
+ const rec_t* rec;
+ ulint fold;
+ ulint prev_fold;
+ dulint index_id;
+ ulint n_cached;
+ ulint n_recs;
+ ulint* folds;
+ ulint i;
+ mem_heap_t* heap = NULL;
+ ulint* offsets;
+
+ rw_lock_x_lock(&btr_search_latch);
+ mutex_enter(&LRU_list_mutex);
+
+ table = btr_search_sys->hash_index;
+
+ bpage = UT_LIST_GET_LAST(buf_pool->LRU);
+
+ while (bpage != NULL) {
+ block = (buf_block_t*) bpage;
+ if (block->index == index && block->is_hashed) {
+ page = block->frame;
+
+ /* from btr_search_drop_page_hash_index() */
+ n_fields = block->curr_n_fields;
+ n_bytes = block->curr_n_bytes;
+
+ ut_a(n_fields + n_bytes > 0);
+
+ n_recs = page_get_n_recs(page);
+
+ /* Calculate and cache fold values into an array for fast deletion
+ from the hash index */
+
+ folds = mem_alloc(n_recs * sizeof(ulint));
+
+ n_cached = 0;
+
+ rec = page_get_infimum_rec(page);
+ rec = page_rec_get_next_low(rec, page_is_comp(page));
+
+ index_id = btr_page_get_index_id(page);
+
+ ut_a(0 == ut_dulint_cmp(index_id, index->id));
+
+ prev_fold = 0;
+
+ offsets = NULL;
+
+ while (!page_rec_is_supremum(rec)) {
+ offsets = rec_get_offsets(rec, index, offsets,
+ n_fields + (n_bytes > 0), &heap);
+ ut_a(rec_offs_n_fields(offsets) == n_fields + (n_bytes > 0));
+ fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id);
+
+ if (fold == prev_fold && prev_fold != 0) {
+
+ goto next_rec;
+ }
+
+ /* Remove all hash nodes pointing to this page from the
+ hash chain */
+
+ folds[n_cached] = fold;
+ n_cached++;
+next_rec:
+ rec = page_rec_get_next_low(rec, page_rec_is_comp(rec));
+ prev_fold = fold;
+ }
+
+ for (i = 0; i < n_cached; i++) {
+
+ ha_remove_all_nodes_to_page(table, folds[i], page);
+ }
+
+ ut_a(index->search_info->ref_count > 0);
+ index->search_info->ref_count--;
+
+ block->is_hashed = FALSE;
+ block->index = NULL;
+
+#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+ if (UNIV_UNLIKELY(block->n_pointers)) {
+ /* Corruption */
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: Corruption of adaptive hash index. After dropping\n"
+"InnoDB: the hash index to a page of %s, still %lu hash nodes remain.\n",
+ index->name, (ulong) block->n_pointers);
+ }
+#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+
+ mem_free(folds);
+ }
+
+ bpage = UT_LIST_GET_PREV(LRU, bpage);
+ }
+
+ mutex_exit(&LRU_list_mutex);
+ rw_lock_x_unlock(&btr_search_latch);
+
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
+}
+
+/********************************************************************//**
Drops a page hash index when a page is freed from a fseg to the file system.
Drops possible hash index if the page happens to be in the buffer pool. */
UNIV_INTERN
void
btr_search_drop_page_hash_when_freed(
/*=================================*/
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no) /* in: page number */
+ ulint page_no) /*!< in: page number */
{
buf_block_t* block;
mtr_t mtr;
@@ -1192,7 +1314,7 @@ btr_search_drop_page_hash_when_freed(
mtr_commit(&mtr);
}
-/************************************************************************
+/********************************************************************//**
Builds a hash index on a page with the given parameters. If the page already
has a hash index with different parameters, the old hash index is removed.
If index is non-NULL, this function checks if n_fields and n_bytes are
@@ -1201,12 +1323,12 @@ static
void
btr_search_build_page_hash_index(
/*=============================*/
- dict_index_t* index, /* in: index for which to build */
- buf_block_t* block, /* in: index page, s- or x-latched */
- ulint n_fields,/* in: hash this many full fields */
- ulint n_bytes,/* in: hash this many bytes from the next
+ dict_index_t* index, /*!< in: index for which to build */
+ buf_block_t* block, /*!< in: index page, s- or x-latched */
+ ulint n_fields,/*!< in: hash this many full fields */
+ ulint n_bytes,/*!< in: hash this many bytes from the next
field */
- ibool left_side)/* in: hash for searches from left side? */
+ ibool left_side)/*!< in: hash for searches from left side? */
{
hash_table_t* table;
page_t* page;
@@ -1387,7 +1509,7 @@ exit_func:
}
}
-/************************************************************************
+/********************************************************************//**
Moves or deletes hash entries for moved records. If new_page is already hashed,
then the hash index for page, if any, is dropped. If new_page is not hashed,
and page is hashed, then a new hash index is built to new_page with the same
@@ -1396,13 +1518,13 @@ UNIV_INTERN
void
btr_search_move_or_delete_hash_entries(
/*===================================*/
- buf_block_t* new_block, /* in: records are copied
+ buf_block_t* new_block, /*!< in: records are copied
to this page */
- buf_block_t* block, /* in: index page from which
+ buf_block_t* block, /*!< in: index page from which
records were copied, and the
copied records will be deleted
from this page */
- dict_index_t* index) /* in: record descriptor */
+ dict_index_t* index) /*!< in: record descriptor */
{
ulint n_fields;
ulint n_bytes;
@@ -1453,13 +1575,13 @@ btr_search_move_or_delete_hash_entries(
rw_lock_s_unlock(&btr_search_latch);
}
-/************************************************************************
+/********************************************************************//**
Updates the page hash index when a single record is deleted from a page. */
UNIV_INTERN
void
btr_search_update_hash_on_delete(
/*=============================*/
- btr_cur_t* cursor) /* in: cursor which was positioned on the
+ btr_cur_t* cursor) /*!< in: cursor which was positioned on the
record to delete using btr_cur_search_...,
the record is not yet deleted */
{
@@ -1506,13 +1628,13 @@ btr_search_update_hash_on_delete(
rw_lock_x_unlock(&btr_search_latch);
}
-/************************************************************************
+/********************************************************************//**
Updates the page hash index when a single record is inserted on a page. */
UNIV_INTERN
void
btr_search_update_hash_node_on_insert(
/*==================================*/
- btr_cur_t* cursor) /* in: cursor which was positioned to the
+ btr_cur_t* cursor) /*!< in: cursor which was positioned to the
place to insert using btr_cur_search_...,
and the new record has been inserted next
to the cursor */
@@ -1557,13 +1679,13 @@ btr_search_update_hash_node_on_insert(
}
}
-/************************************************************************
+/********************************************************************//**
Updates the page hash index when a single record is inserted on a page. */
UNIV_INTERN
void
btr_search_update_hash_on_insert(
/*=============================*/
- btr_cur_t* cursor) /* in: cursor which was positioned to the
+ btr_cur_t* cursor) /*!< in: cursor which was positioned to the
place to insert using btr_cur_search_...,
and the new record has been inserted next
to the cursor */
@@ -1707,13 +1829,13 @@ function_exit:
}
}
-/************************************************************************
-Validates the search system. */
+/********************************************************************//**
+Validates the search system.
+@return TRUE if ok */
UNIV_INTERN
ibool
btr_search_validate(void)
/*=====================*/
- /* out: TRUE if ok */
{
ha_node_t* node;
ulint n_page_dumps = 0;
diff --git a/storage/xtradb/buf/buf0buddy.c b/storage/xtradb/buf/buf0buddy.c
index 494db91d159..6ee7a71a2e5 100644
--- a/storage/xtradb/buf/buf0buddy.c
+++ b/storage/xtradb/buf/buf0buddy.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file buf/buf0buddy.c
Binary buddy allocator for compressed pages
Created December 2006 by Marko Makela
@@ -44,15 +45,15 @@ static ulint buf_buddy_n_frames;
Protected by buf_pool_mutex. */
UNIV_INTERN buf_buddy_stat_t buf_buddy_stat[BUF_BUDDY_SIZES + 1];
-/**************************************************************************
-Get the offset of the buddy of a compressed page frame. */
+/**********************************************************************//**
+Get the offset of the buddy of a compressed page frame.
+@return the buddy relative of page */
UNIV_INLINE
byte*
buf_buddy_get(
/*==========*/
- /* out: the buddy relative of page */
- byte* page, /* in: compressed page */
- ulint size) /* in: page size in bytes */
+ byte* page, /*!< in: compressed page */
+ ulint size) /*!< in: page size in bytes */
{
ut_ad(ut_is_2pow(size));
ut_ad(size >= BUF_BUDDY_LOW);
@@ -66,14 +67,14 @@ buf_buddy_get(
}
}
-/**************************************************************************
+/**********************************************************************//**
Add a block to the head of the appropriate buddy free list. */
UNIV_INLINE
void
buf_buddy_add_to_free(
/*==================*/
- buf_page_t* bpage, /* in,own: block to be freed */
- ulint i) /* in: index of buf_pool->zip_free[] */
+ buf_page_t* bpage, /*!< in,own: block to be freed */
+ ulint i) /*!< in: index of buf_pool->zip_free[] */
{
#ifdef UNIV_DEBUG_VALGRIND
buf_page_t* b = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
@@ -81,6 +82,9 @@ buf_buddy_add_to_free(
if (b) UNIV_MEM_VALID(b, BUF_BUDDY_LOW << i);
#endif /* UNIV_DEBUG_VALGRIND */
+ //ut_ad(buf_pool_mutex_own());
+ ut_ad(mutex_own(&zip_free_mutex));
+ ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
ut_ad(buf_pool->zip_free[i].start != bpage);
UT_LIST_ADD_FIRST(zip_list, buf_pool->zip_free[i], bpage);
@@ -90,14 +94,14 @@ buf_buddy_add_to_free(
#endif /* UNIV_DEBUG_VALGRIND */
}
-/**************************************************************************
+/**********************************************************************//**
Remove a block from the appropriate buddy free list. */
UNIV_INLINE
void
buf_buddy_remove_from_free(
/*=======================*/
- buf_page_t* bpage, /* in: block to be removed */
- ulint i) /* in: index of buf_pool->zip_free[] */
+ buf_page_t* bpage, /*!< in: block to be removed */
+ ulint i) /*!< in: index of buf_pool->zip_free[] */
{
#ifdef UNIV_DEBUG_VALGRIND
buf_page_t* prev = UT_LIST_GET_PREV(zip_list, bpage);
@@ -110,6 +114,8 @@ buf_buddy_remove_from_free(
ut_ad(!next || buf_page_get_state(next) == BUF_BLOCK_ZIP_FREE);
#endif /* UNIV_DEBUG_VALGRIND */
+ //ut_ad(buf_pool_mutex_own());
+ ut_ad(mutex_own(&zip_free_mutex));
ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
UT_LIST_REMOVE(zip_list, buf_pool->zip_free[i], bpage);
@@ -119,15 +125,14 @@ buf_buddy_remove_from_free(
#endif /* UNIV_DEBUG_VALGRIND */
}
-/**************************************************************************
-Try to allocate a block from buf_pool->zip_free[]. */
+/**********************************************************************//**
+Try to allocate a block from buf_pool->zip_free[].
+@return allocated block, or NULL if buf_pool->zip_free[] was empty */
static
void*
buf_buddy_alloc_zip(
/*================*/
- /* out: allocated block, or NULL
- if buf_pool->zip_free[] was empty */
- ulint i) /* in: index of buf_pool->zip_free[] */
+ ulint i) /*!< in: index of buf_pool->zip_free[] */
{
buf_page_t* bpage;
@@ -135,10 +140,12 @@ buf_buddy_alloc_zip(
ut_ad(mutex_own(&zip_free_mutex));
ut_a(i < BUF_BUDDY_SIZES);
-#if defined UNIV_DEBUG && !defined UNIV_DEBUG_VALGRIND
+#ifndef UNIV_DEBUG_VALGRIND
/* Valgrind would complain about accessing free memory. */
- UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i]);
-#endif /* UNIV_DEBUG && !UNIV_DEBUG_VALGRIND */
+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
+ ut_ad(buf_page_get_state(ut_list_node_313)
+ == BUF_BLOCK_ZIP_FREE)));
+#endif /* !UNIV_DEBUG_VALGRIND */
bpage = UT_LIST_GET_LAST(buf_pool->zip_free[i]);
if (bpage) {
@@ -172,13 +179,13 @@ buf_buddy_alloc_zip(
return(bpage);
}
-/**************************************************************************
+/**********************************************************************//**
Deallocate a buffer frame of UNIV_PAGE_SIZE. */
static
void
buf_buddy_block_free(
/*=================*/
- void* buf, /* in: buffer frame to deallocate */
+ void* buf, /*!< in: buffer frame to deallocate */
ibool have_page_hash_mutex)
{
const ulint fold = BUF_POOL_ZIP_FOLD_PTR(buf);
@@ -216,17 +223,18 @@ buf_buddy_block_free(
ut_d(buf_buddy_n_frames--);
}
-/**************************************************************************
+/**********************************************************************//**
Allocate a buffer block to the buddy allocator. */
static
void
buf_buddy_block_register(
/*=====================*/
- buf_block_t* block) /* in: buffer frame to allocate */
+ buf_block_t* block) /*!< in: buffer frame to allocate */
{
const ulint fold = BUF_POOL_ZIP_FOLD(block);
//ut_ad(buf_pool_mutex_own());
ut_ad(!mutex_own(&buf_pool_zip_mutex));
+ ut_ad(buf_block_get_state(block) == BUF_BLOCK_READY_FOR_USE);
buf_block_set_state(block, BUF_BLOCK_MEMORY);
@@ -244,16 +252,16 @@ buf_buddy_block_register(
ut_d(buf_buddy_n_frames++);
}
-/**************************************************************************
-Allocate a block from a bigger object. */
+/**********************************************************************//**
+Allocate a block from a bigger object.
+@return allocated block */
static
void*
buf_buddy_alloc_from(
/*=================*/
- /* out: allocated block */
- void* buf, /* in: a block that is free to use */
- ulint i, /* in: index of buf_pool->zip_free[] */
- ulint j) /* in: size of buf as an index
+ void* buf, /*!< in: a block that is free to use */
+ ulint i, /*!< in: index of buf_pool->zip_free[] */
+ ulint j) /*!< in: size of buf as an index
of buf_pool->zip_free[] */
{
ulint offs = BUF_BUDDY_LOW << j;
@@ -271,29 +279,31 @@ buf_buddy_alloc_from(
bpage = (buf_page_t*) ((byte*) buf + offs);
ut_d(memset(bpage, j, BUF_BUDDY_LOW << j));
bpage->state = BUF_BLOCK_ZIP_FREE;
-#if defined UNIV_DEBUG && !defined UNIV_DEBUG_VALGRIND
+#ifndef UNIV_DEBUG_VALGRIND
/* Valgrind would complain about accessing free memory. */
- UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[j]);
-#endif /* UNIV_DEBUG && !UNIV_DEBUG_VALGRIND */
+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
+ ut_ad(buf_page_get_state(
+ ut_list_node_313)
+ == BUF_BLOCK_ZIP_FREE)));
+#endif /* !UNIV_DEBUG_VALGRIND */
buf_buddy_add_to_free(bpage, j);
}
return(buf);
}
-/**************************************************************************
+/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any block->mutex.
-The buf_pool_mutex may only be released and reacquired if lru != NULL. */
+The buf_pool_mutex may only be released and reacquired if lru != NULL.
+@return allocated block, possibly NULL if lru==NULL */
UNIV_INTERN
void*
buf_buddy_alloc_low(
/*================*/
- /* out: allocated block,
- possibly NULL if lru==NULL */
- ulint i, /* in: index of buf_pool->zip_free[],
+ ulint i, /*!< in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
- ibool* lru, /* in: pointer to a variable that will be assigned
+ ibool* lru, /*!< in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released,
or NULL if the LRU list should not be used */
@@ -357,15 +367,15 @@ func_exit:
return(block);
}
-/**************************************************************************
-Try to relocate the control block of a compressed page. */
+/**********************************************************************//**
+Try to relocate the control block of a compressed page.
+@return TRUE if relocated */
static
ibool
buf_buddy_relocate_block(
/*=====================*/
- /* out: TRUE if relocated */
- buf_page_t* bpage, /* in: block to relocate */
- buf_page_t* dpage) /* in: free block to relocate to */
+ buf_page_t* bpage, /*!< in: block to relocate */
+ buf_page_t* dpage) /*!< in: free block to relocate to */
{
buf_page_t* b;
@@ -425,16 +435,16 @@ buf_buddy_relocate_block(
return(TRUE);
}
-/**************************************************************************
-Try to relocate a block. */
+/**********************************************************************//**
+Try to relocate a block.
+@return TRUE if relocated */
static
ibool
buf_buddy_relocate(
/*===============*/
- /* out: TRUE if relocated */
- void* src, /* in: block to relocate */
- void* dst, /* in: free block to relocate to */
- ulint i, /* in: index of buf_pool->zip_free[] */
+ void* src, /*!< in: block to relocate */
+ void* dst, /*!< in: free block to relocate to */
+ ulint i, /*!< in: index of buf_pool->zip_free[] */
ibool have_page_hash_mutex)
{
buf_page_t* bpage;
@@ -461,16 +471,15 @@ buf_buddy_relocate(
actually is a properly initialized buf_page_t object. */
if (size >= PAGE_ZIP_MIN_SIZE) {
- mutex_t* mutex;
- if (!have_page_hash_mutex)
- mutex_exit(&zip_free_mutex);
-
/* This is a compressed page. */
+ mutex_t* mutex;
if (!have_page_hash_mutex) {
+ mutex_exit(&zip_free_mutex);
mutex_enter(&LRU_list_mutex);
rw_lock_x_lock(&page_hash_latch);
}
+
/* The src block may be split into smaller blocks,
some of which may be free. Thus, the
mach_read_from_4() calls below may attempt to read
@@ -521,15 +530,9 @@ buf_buddy_relocate(
contain uninitialized data. */
UNIV_MEM_ASSERT_W(src, size);
- mutex = buf_page_get_mutex(bpage);
+ mutex = buf_page_get_mutex_enter(bpage);
+ ut_a(mutex);
-retry_lock:
- mutex_enter(mutex);
- if (mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(mutex);
- mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
mutex_enter(&zip_free_mutex);
if (buf_page_can_relocate(bpage)) {
@@ -594,15 +597,16 @@ success:
return(FALSE);
}
-/**************************************************************************
+/**********************************************************************//**
Deallocate a block. */
UNIV_INTERN
void
buf_buddy_free_low(
/*===============*/
- void* buf, /* in: block to be freed, must not be
+ void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
- ulint i, /* in: index of buf_pool->zip_free[] */
+ ulint i, /*!< in: index of buf_pool->zip_free[],
+ or BUF_BUDDY_SIZES */
ibool have_page_hash_mutex)
{
buf_page_t* bpage;
@@ -676,7 +680,9 @@ buddy_free2:
#ifndef UNIV_DEBUG_VALGRIND
buddy_nonfree:
/* Valgrind would complain about accessing free memory. */
- ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i]));
+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
+ ut_ad(buf_page_get_state(ut_list_node_313)
+ == BUF_BLOCK_ZIP_FREE)));
#endif /* UNIV_DEBUG_VALGRIND */
/* The buddy is not free. Is there a free block of this size? */
@@ -702,21 +708,20 @@ buddy_nonfree:
buddy = (buf_page_t*) buf_buddy_get(((byte*) bpage),
BUF_BUDDY_LOW << i);
-#if defined UNIV_DEBUG && !defined UNIV_DEBUG_VALGRIND
- {
- const buf_page_t* b;
+#ifndef UNIV_DEBUG_VALGRIND
+ /* Valgrind would complain about accessing free memory. */
- /* The buddy must not be (completely) free, because
- we always recombine adjacent free blocks.
- (Parts of the buddy can be free in
- buf_pool->zip_free[j] with j < i.)*/
- for (b = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
- b; b = UT_LIST_GET_NEXT(zip_list, b)) {
+ /* The buddy must not be (completely) free, because we
+ always recombine adjacent free blocks.
- ut_a(b != buddy);
- }
- }
-#endif /* UNIV_DEBUG && !UNIV_DEBUG_VALGRIND */
+ (Parts of the buddy can be free in
+ buf_pool->zip_free[j] with j < i.) */
+ ut_d(UT_LIST_VALIDATE(zip_list, buf_page_t, buf_pool->zip_free[i],
+ ut_ad(buf_page_get_state(
+ ut_list_node_313)
+ == BUF_BLOCK_ZIP_FREE
+ && ut_list_node_313 != buddy)));
+#endif /* !UNIV_DEBUG_VALGRIND */
if (buf_buddy_relocate(buddy, buf, i, have_page_hash_mutex)) {
diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c
index a02b7879121..8da0a87751d 100644
--- a/storage/xtradb/buf/buf0buf.c
+++ b/storage/xtradb/buf/buf0buf.c
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file buf/buf0buf.c
The database buffer buf_pool
Created 11/5/1995 Heikki Tuuri
@@ -35,17 +36,20 @@ Created 11/5/1995 Heikki Tuuri
#include "buf0buf.ic"
#endif
-#include "buf0buddy.h"
#include "mem0mem.h"
#include "btr0btr.h"
#include "fil0fil.h"
+#ifndef UNIV_HOTBACKUP
+#include "buf0buddy.h"
#include "lock0lock.h"
#include "btr0sea.h"
#include "ibuf0ibuf.h"
-#include "dict0dict.h"
-#include "log0recv.h"
#include "trx0undo.h"
+#include "log0log.h"
+#endif /* !UNIV_HOTBACKUP */
#include "srv0srv.h"
+#include "dict0dict.h"
+#include "log0recv.h"
#include "page0zip.h"
/*
@@ -235,13 +239,14 @@ that the whole area may be needed in the near future, and issue
the read requests for the whole area.
*/
-/* Value in microseconds */
+#ifndef UNIV_HOTBACKUP
+/** Value in microseconds */
static const int WAIT_FOR_READ = 5000;
-/* The buffer buf_pool of the database */
+/** The buffer buf_pool of the database */
UNIV_INTERN buf_pool_t* buf_pool = NULL;
-/* mutex protecting the buffer pool struct and control blocks, except the
+/** mutex protecting the buffer pool struct and control blocks, except the
read-write lock in them */
UNIV_INTERN mutex_t buf_pool_mutex;
UNIV_INTERN mutex_t LRU_list_mutex;
@@ -250,12 +255,12 @@ UNIV_INTERN rw_lock_t page_hash_latch;
UNIV_INTERN mutex_t free_list_mutex;
UNIV_INTERN mutex_t zip_free_mutex;
UNIV_INTERN mutex_t zip_hash_mutex;
-/* mutex protecting the control blocks of compressed-only pages
+/** mutex protecting the control blocks of compressed-only pages
(of type buf_page_t, not buf_block_t) */
UNIV_INTERN mutex_t buf_pool_zip_mutex;
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-static ulint buf_dbg_counter = 0; /* This is used to insert validation
+static ulint buf_dbg_counter = 0; /*!< This is used to insert validation
operations in excution in the
debug version */
/** Flag to forbid the release of the buffer pool mutex.
@@ -263,30 +268,31 @@ Protected by buf_pool_mutex. */
UNIV_INTERN ulint buf_pool_mutex_exit_forbidden = 0;
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG
-/* If this is set TRUE, the program prints info whenever
+/** If this is set TRUE, the program prints info whenever
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. */
+/** 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
+ 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 */
+ buf_block_t* blocks; /*!< array of buffer control blocks */
};
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
+/********************************************************************//**
Calculates a page checksum which is stored to the page when it is written
to a file. Note that we must be careful to calculate the same value on
-32-bit and 64-bit architectures. */
+32-bit and 64-bit architectures.
+@return checksum */
UNIV_INTERN
ulint
buf_calc_page_new_checksum(
/*=======================*/
- /* out: checksum */
- const byte* page) /* in: buffer page */
+ const byte* page) /*!< in: buffer page */
{
ulint checksum;
@@ -308,19 +314,19 @@ buf_calc_page_new_checksum(
return(checksum);
}
-/************************************************************************
+/********************************************************************//**
In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
looked at the first few bytes of the page. This calculates that old
checksum.
NOTE: we must first store the new formula checksum to
FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum
-because this takes that field as an input! */
+because this takes that field as an input!
+@return checksum */
UNIV_INTERN
ulint
buf_calc_page_old_checksum(
/*=======================*/
- /* out: checksum */
- const byte* page) /* in: buffer page */
+ const byte* page) /*!< in: buffer page */
{
ulint checksum;
@@ -331,22 +337,20 @@ buf_calc_page_old_checksum(
return(checksum);
}
-/************************************************************************
-Checks if a page is corrupt. */
+/********************************************************************//**
+Checks if a page is corrupt.
+@return TRUE if corrupted */
UNIV_INTERN
ibool
buf_page_is_corrupted(
/*==================*/
- /* out: TRUE if corrupted */
- const byte* read_buf, /* in: a database page */
- ulint zip_size) /* in: size of compressed page;
+ const byte* read_buf, /*!< in: a database page */
+ ulint zip_size) /*!< in: size of compressed page;
0 for uncompressed pages */
{
ulint checksum_field;
ulint old_checksum_field;
-#ifndef UNIV_HOTBACKUP
- ib_uint64_t current_lsn;
-#endif
+
if (UNIV_LIKELY(!zip_size)
&& memcmp(read_buf + FIL_PAGE_LSN + 4,
read_buf + UNIV_PAGE_SIZE
@@ -359,8 +363,11 @@ buf_page_is_corrupted(
}
#ifndef UNIV_HOTBACKUP
- if (recv_lsn_checks_on && log_peek_lsn(&current_lsn)) {
- if (current_lsn < mach_read_ull(read_buf + FIL_PAGE_LSN)) {
+ if (recv_lsn_checks_on) {
+ ib_uint64_t current_lsn;
+
+ if (log_peek_lsn(&current_lsn)
+ && current_lsn < mach_read_ull(read_buf + FIL_PAGE_LSN)) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -372,8 +379,7 @@ buf_page_is_corrupted(
"you may have copied the InnoDB\n"
"InnoDB: tablespace but not the InnoDB "
"log files. See\n"
- "InnoDB: http://dev.mysql.com/doc/refman/"
- "5.1/en/forcing-recovery.html\n"
+ "InnoDB: " REFMAN "forcing-recovery.html\n"
"InnoDB: for more information.\n",
(ulong) mach_read_from_4(read_buf
+ FIL_PAGE_OFFSET),
@@ -434,17 +440,19 @@ buf_page_is_corrupted(
return(FALSE);
}
-/************************************************************************
+/********************************************************************//**
Prints a page to stderr. */
UNIV_INTERN
void
buf_page_print(
/*===========*/
- const byte* read_buf, /* in: a database page */
- ulint zip_size) /* in: compressed page size, or
+ const byte* read_buf, /*!< in: a database page */
+ ulint zip_size) /*!< in: compressed page size, or
0 for uncompressed pages */
{
+#ifndef UNIV_HOTBACKUP
dict_index_t* index;
+#endif /* !UNIV_HOTBACKUP */
ulint checksum;
ulint old_checksum;
ulint size = zip_size;
@@ -558,6 +566,7 @@ buf_page_print(
(ulong) mach_read_from_4(read_buf
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID));
+#ifndef UNIV_HOTBACKUP
if (mach_read_from_2(read_buf + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE)
== TRX_UNDO_INSERT) {
fprintf(stderr,
@@ -568,6 +577,7 @@ buf_page_print(
fprintf(stderr,
"InnoDB: Page may be an update undo log page\n");
}
+#endif /* !UNIV_HOTBACKUP */
switch (fil_page_get_type(read_buf)) {
case FIL_PAGE_INDEX:
@@ -578,16 +588,7 @@ buf_page_print(
btr_page_get_index_id(read_buf)),
(ulong) ut_dulint_get_low(
btr_page_get_index_id(read_buf)));
-
-#ifdef UNIV_HOTBACKUP
- /* If the code is in ibbackup, dict_sys may be uninitialized,
- i.e., NULL */
-
- if (dict_sys == NULL) {
- break;
- }
-#endif /* UNIV_HOTBACKUP */
-
+#ifndef UNIV_HOTBACKUP
index = dict_index_find_on_id_low(
btr_page_get_index_id(read_buf));
if (index) {
@@ -595,6 +596,7 @@ buf_page_print(
dict_index_name_print(stderr, NULL, index);
fputs(")\n", stderr);
}
+#endif /* !UNIV_HOTBACKUP */
break;
case FIL_PAGE_INODE:
fputs("InnoDB: Page may be an 'inode' page\n", stderr);
@@ -639,14 +641,15 @@ buf_page_print(
}
}
-/************************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Initializes a buffer control block when the buf_pool is created. */
static
void
buf_block_init(
/*===========*/
- buf_block_t* block, /* in: pointer to control block */
- byte* frame) /* in: pointer to buffer frame */
+ buf_block_t* block, /*!< in: pointer to control block */
+ byte* frame) /*!< in: pointer to buffer frame */
{
UNIV_MEM_DESC(frame, UNIV_PAGE_SIZE, block);
@@ -688,15 +691,15 @@ buf_block_init(
#endif /* UNIV_SYNC_DEBUG */
}
-/************************************************************************
-Allocates a chunk of buffer frames. */
+/********************************************************************//**
+Allocates a chunk of buffer frames.
+@return chunk, or NULL on failure */
static
buf_chunk_t*
buf_chunk_init(
/*===========*/
- /* out: chunk, or NULL on failure */
- buf_chunk_t* chunk, /* out: chunk of buffers */
- ulint mem_size) /* in: requested size in bytes */
+ buf_chunk_t* chunk, /*!< out: chunk of buffers */
+ ulint mem_size) /*!< in: requested size in bytes */
{
buf_block_t* block;
byte* frame;
@@ -770,17 +773,16 @@ buf_chunk_init(
}
#ifdef UNIV_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Finds a block in the given buffer chunk that points to a
-given compressed page. */
+given compressed page.
+@return buffer block pointing to the compressed page, or NULL */
static
buf_block_t*
buf_chunk_contains_zip(
/*===================*/
- /* out: buffer block pointing to
- the compressed page, or NULL */
- buf_chunk_t* chunk, /* in: chunk being checked */
- const void* data) /* in: pointer to compressed page */
+ buf_chunk_t* chunk, /*!< in: chunk being checked */
+ const void* data) /*!< in: pointer to compressed page */
{
buf_block_t* block;
ulint i;
@@ -800,16 +802,15 @@ buf_chunk_contains_zip(
return(NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Finds a block in the buffer pool that points to a
-given compressed page. */
+given compressed page.
+@return buffer block pointing to the compressed page, or NULL */
UNIV_INTERN
buf_block_t*
buf_pool_contains_zip(
/*==================*/
- /* out: buffer block pointing to
- the compressed page, or NULL */
- const void* data) /* in: pointer to compressed page */
+ const void* data) /*!< in: pointer to compressed page */
{
ulint n;
buf_chunk_t* chunk = buf_pool->chunks;
@@ -826,15 +827,14 @@ buf_pool_contains_zip(
}
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Checks that all file pages in the buffer chunk are in a replaceable state. */
+/*********************************************************************//**
+Checks that all file pages in the buffer chunk are in a replaceable state.
+@return address of a non-free block, or NULL if all freed */
static
const buf_block_t*
buf_chunk_not_freed(
/*================*/
- /* out: address of a non-free block,
- or NULL if all freed */
- buf_chunk_t* chunk) /* in: chunk being checked */
+ buf_chunk_t* chunk) /*!< in: chunk being checked */
{
buf_block_t* block;
ulint i;
@@ -860,14 +860,14 @@ buf_chunk_not_freed(
return(NULL);
}
-/*************************************************************************
-Checks that all blocks in the buffer chunk are in BUF_BLOCK_NOT_USED state. */
+/*********************************************************************//**
+Checks that all blocks in the buffer chunk are in BUF_BLOCK_NOT_USED state.
+@return TRUE if all freed */
static
ibool
buf_chunk_all_free(
/*===============*/
- /* out: TRUE if all freed */
- const buf_chunk_t* chunk) /* in: chunk being checked */
+ const buf_chunk_t* chunk) /*!< in: chunk being checked */
{
const buf_block_t* block;
ulint i;
@@ -888,13 +888,13 @@ buf_chunk_all_free(
return(TRUE);
}
-/************************************************************************
+/********************************************************************//**
Frees a chunk of buffer frames. */
static
void
buf_chunk_free(
/*===========*/
- buf_chunk_t* chunk) /* out: chunk of buffers */
+ buf_chunk_t* chunk) /*!< out: chunk of buffers */
{
buf_block_t* block;
const buf_block_t* block_end;
@@ -928,14 +928,13 @@ buf_chunk_free(
os_mem_free_large(chunk->mem, chunk->mem_size);
}
-/************************************************************************
-Creates the buffer pool. */
+/********************************************************************//**
+Creates the buffer pool.
+@return own: buf_pool object, NULL if not enough memory or error */
UNIV_INTERN
buf_pool_t*
buf_pool_init(void)
/*===============*/
- /* out, own: buf_pool object, NULL if not
- enough memory or error */
{
buf_chunk_t* chunk;
ulint i;
@@ -1005,7 +1004,7 @@ buf_pool_init(void)
return(buf_pool);
}
-/************************************************************************
+/********************************************************************//**
Frees the buffer pool at shutdown. This must not be invoked before
freeing all mutexes. */
UNIV_INTERN
@@ -1028,8 +1027,7 @@ buf_pool_free(void)
buf_pool->n_chunks = 0;
}
-
-/************************************************************************
+/********************************************************************//**
Drops the adaptive hash index. To prevent a livelock, this function
is only to be called while holding btr_search_latch and while
btr_search_enabled == FALSE. */
@@ -1110,7 +1108,7 @@ buf_pool_drop_hash_index(void)
} while (released_search_latch);
}
-/************************************************************************
+/********************************************************************//**
Relocate a buffer control block. Relocates the block on the LRU list
and in buf_pool->page_hash. Does not relocate bpage->list.
The caller must take care of relocating bpage->list. */
@@ -1118,10 +1116,10 @@ UNIV_INTERN
void
buf_relocate(
/*=========*/
- buf_page_t* bpage, /* in/out: control block being relocated;
+ buf_page_t* bpage, /*!< in/out: control block being relocated;
buf_page_get_state(bpage) must be
BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_ZIP_PAGE */
- buf_page_t* dpage) /* in/out: destination control block */
+ buf_page_t* dpage) /*!< in/out: destination control block */
{
buf_page_t* b;
ulint fold;
@@ -1180,7 +1178,8 @@ buf_relocate(
#endif /* UNIV_LRU_DEBUG */
}
- ut_d(UT_LIST_VALIDATE(LRU, buf_page_t, buf_pool->LRU));
+ ut_d(UT_LIST_VALIDATE(LRU, buf_page_t, buf_pool->LRU,
+ ut_ad(ut_list_node_313->in_LRU_list)));
/* relocate buf_pool->page_hash */
fold = buf_page_address_fold(bpage->space, bpage->offset);
@@ -1191,14 +1190,13 @@ buf_relocate(
UNIV_MEM_INVALID(bpage, sizeof *bpage);
}
-/************************************************************************
+/********************************************************************//**
Shrinks the buffer pool. */
static
void
buf_pool_shrink(
/*============*/
- /* out: TRUE if shrunk */
- ulint chunk_size) /* in: number of pages to remove */
+ ulint chunk_size) /*!< in: number of pages to remove */
{
buf_chunk_t* chunks;
buf_chunk_t* chunk;
@@ -1346,7 +1344,7 @@ func_exit:
btr_search_enable();
}
-/************************************************************************
+/********************************************************************//**
Rebuild buf_pool->page_hash. */
static
void
@@ -1450,7 +1448,7 @@ buf_pool_page_hash_rebuild(void)
mutex_exit(&flush_list_mutex);
}
-/************************************************************************
+/********************************************************************//**
Resizes the buffer pool. */
UNIV_INTERN
void
@@ -1511,14 +1509,14 @@ buf_pool_resize(void)
buf_pool_page_hash_rebuild();
}
-/************************************************************************
-Moves to the block to the start of the LRU list if there is a danger
+/********************************************************************//**
+Moves the block to the start of the LRU list if there is a danger
that the block would drift out of the buffer pool. */
UNIV_INLINE
void
buf_block_make_young(
/*=================*/
- buf_page_t* bpage) /* in: block to make younger */
+ buf_page_t* bpage) /*!< in: block to make younger */
{
ut_ad(!buf_pool_mutex_own());
@@ -1538,7 +1536,7 @@ buf_block_make_young(
}
}
-/************************************************************************
+/********************************************************************//**
Moves a page to the start of the buffer pool LRU list. This high-level
function can be used to prevent an important page from from slipping out of
the buffer pool. */
@@ -1546,7 +1544,7 @@ UNIV_INTERN
void
buf_page_make_young(
/*================*/
- buf_page_t* bpage) /* in: buffer block of a file page */
+ buf_page_t* bpage) /*!< in: buffer block of a file page */
{
//buf_pool_mutex_enter();
mutex_enter(&LRU_list_mutex);
@@ -1559,15 +1557,15 @@ buf_page_make_young(
mutex_exit(&LRU_list_mutex);
}
-/************************************************************************
+/********************************************************************//**
Resets the check_index_page_at_flush field of a page if found in the buffer
pool. */
UNIV_INTERN
void
buf_reset_check_index_page_at_flush(
/*================================*/
- ulint space, /* in: space id */
- ulint offset) /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: page number */
{
buf_block_t* block;
@@ -1584,18 +1582,17 @@ buf_reset_check_index_page_at_flush(
rw_lock_s_unlock(&page_hash_latch);
}
-/************************************************************************
+/********************************************************************//**
Returns the current state of is_hashed of a page. FALSE if the page is
not in the pool. NOTE that this operation does not fix the page in the
-pool if it is found there. */
+pool if it is found there.
+@return TRUE if page hash index is built in search system */
UNIV_INTERN
ibool
buf_page_peek_if_search_hashed(
/*===========================*/
- /* out: TRUE if page hash index is built in search
- system */
- ulint space, /* in: space id */
- ulint offset) /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: page number */
{
buf_block_t* block;
ibool is_hashed;
@@ -1618,19 +1615,18 @@ buf_page_peek_if_search_hashed(
}
#ifdef UNIV_DEBUG_FILE_ACCESSES
-/************************************************************************
+/********************************************************************//**
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
-reallocated. */
+reallocated.
+@return control block if found in page hash table, otherwise NULL */
UNIV_INTERN
buf_page_t*
buf_page_set_file_page_was_freed(
/*=============================*/
- /* out: control block if found in page hash table,
- otherwise NULL */
- ulint space, /* in: space id */
- ulint offset) /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: page number */
{
buf_page_t* bpage;
@@ -1649,19 +1645,18 @@ buf_page_set_file_page_was_freed(
return(bpage);
}
-/************************************************************************
+/********************************************************************//**
Sets file_page_was_freed FALSE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
-reallocated. */
+reallocated.
+@return control block if found in page hash table, otherwise NULL */
UNIV_INTERN
buf_page_t*
buf_page_reset_file_page_was_freed(
/*===============================*/
- /* out: control block if found in page hash table,
- otherwise NULL */
- ulint space, /* in: space id */
- ulint offset) /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: page number */
{
buf_page_t* bpage;
@@ -1681,22 +1676,22 @@ buf_page_reset_file_page_was_freed(
}
#endif /* UNIV_DEBUG_FILE_ACCESSES */
-/************************************************************************
+/********************************************************************//**
Get read access to a compressed page (usually of type
FIL_PAGE_TYPE_ZBLOB or FIL_PAGE_TYPE_ZBLOB2).
The page must be released with buf_page_release_zip().
NOTE: the page is not protected by any latch. Mutual exclusion has to
be implemented at a higher level. In other words, all possible
accesses to a given page through this function must be protected by
-the same set of mutexes or latches. */
+the same set of mutexes or latches.
+@return pointer to the block */
UNIV_INTERN
buf_page_t*
buf_page_get_zip(
/*=============*/
- /* out: pointer to the block */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size */
- ulint offset) /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size */
+ ulint offset) /*!< in: page number */
{
buf_page_t* bpage;
mutex_t* block_mutex;
@@ -1730,19 +1725,13 @@ lookup:
if (UNIV_UNLIKELY(!bpage->zip.data)) {
/* There is no compressed page. */
+err_exit:
//buf_pool_mutex_exit();
rw_lock_s_unlock(&page_hash_latch);
return(NULL);
}
- block_mutex = buf_page_get_mutex(bpage);
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
+ block_mutex = buf_page_get_mutex_enter(bpage);
rw_lock_s_unlock(&page_hash_latch);
@@ -1752,13 +1741,17 @@ retry_lock:
case BUF_BLOCK_MEMORY:
case BUF_BLOCK_REMOVE_HASH:
case BUF_BLOCK_ZIP_FREE:
- ut_error;
+ if (block_mutex)
+ mutex_exit(block_mutex);
break;
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_ZIP_DIRTY:
+ ut_a(block_mutex == &buf_pool_zip_mutex);
bpage->buf_fix_count++;
- break;
+ goto got_block;
case BUF_BLOCK_FILE_PAGE:
+ ut_a(block_mutex == &((buf_block_t*) bpage)->mutex);
+
/* Discard the uncompressed page frame if possible. */
if (buf_LRU_free_block(bpage, FALSE, NULL, FALSE)
== BUF_LRU_FREED) {
@@ -1769,9 +1762,13 @@ retry_lock:
buf_block_buf_fix_inc((buf_block_t*) bpage,
__FILE__, __LINE__);
- break;
+ goto got_block;
}
+ ut_error;
+ goto err_exit;
+
+got_block:
must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
//buf_pool_mutex_exit();
@@ -1819,13 +1816,13 @@ retry_lock:
return(bpage);
}
-/************************************************************************
+/********************************************************************//**
Initialize some fields of a control block. */
UNIV_INLINE
void
buf_block_init_low(
/*===============*/
- buf_block_t* block) /* in: block to init */
+ buf_block_t* block) /*!< in: block to init */
{
block->check_index_page_at_flush = FALSE;
block->index = NULL;
@@ -1836,16 +1833,17 @@ buf_block_init_low(
block->n_bytes = 0;
block->left_side = TRUE;
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
-Decompress a block. */
-static
+/********************************************************************//**
+Decompress a block.
+@return TRUE if successful */
+UNIV_INTERN
ibool
buf_zip_decompress(
/*===============*/
- /* out: TRUE if successful */
- buf_block_t* block, /* in/out: block */
- ibool check) /* in: TRUE=verify the page checksum */
+ buf_block_t* block, /*!< in/out: block */
+ ibool check) /*!< in: TRUE=verify the page checksum */
{
const byte* frame = block->page.zip.data;
@@ -1903,14 +1901,15 @@ buf_zip_decompress(
return(FALSE);
}
-/***********************************************************************
-Gets the block to whose frame the pointer is pointing to. */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
+Gets the block to whose frame the pointer is pointing to.
+@return pointer to block, never NULL */
UNIV_INTERN
buf_block_t*
buf_block_align(
/*============*/
- /* out: pointer to block, never NULL */
- const byte* ptr) /* in: pointer to a frame */
+ const byte* ptr) /*!< in: pointer to a frame */
{
buf_chunk_t* chunk;
ulint i;
@@ -1990,31 +1989,25 @@ buf_block_align(
return(NULL);
}
-/************************************************************************
-Find out if a buffer block was created by buf_chunk_init(). */
-static
+/********************************************************************//**
+Find out if a pointer belongs to a buf_block_t. It can be a pointer to
+the buf_block_t itself or a member of it
+@return TRUE if ptr belongs to a buf_block_t struct */
+UNIV_INTERN
ibool
-buf_block_is_uncompressed(
-/*======================*/
- /* out: TRUE if "block" has
- been added to buf_pool->free
- by buf_chunk_init() */
- const buf_block_t* block) /* in: pointer to block,
- not dereferenced */
+buf_pointer_is_block_field(
+/*=======================*/
+ const void* ptr) /*!< in: pointer not
+ dereferenced */
{
const buf_chunk_t* chunk = buf_pool->chunks;
const buf_chunk_t* const echunk = chunk + buf_pool->n_chunks;
- //ut_ad(buf_pool_mutex_own());
-
- if (UNIV_UNLIKELY((((ulint) block) % sizeof *block) != 0)) {
- /* The pointer should be aligned. */
- return(FALSE);
- }
-
+ /* TODO: protect buf_pool->chunks with a mutex (it will
+ currently remain constant after buf_pool_init()) */
while (chunk < echunk) {
- if (block >= chunk->blocks
- && block < chunk->blocks + chunk->size) {
+ if (ptr >= (void *)chunk->blocks
+ && ptr < (void *)(chunk->blocks + chunk->size)) {
return(TRUE);
}
@@ -2025,24 +2018,44 @@ buf_block_is_uncompressed(
return(FALSE);
}
-/************************************************************************
-This is the general function used to get access to a database page. */
+/********************************************************************//**
+Find out if a buffer block was created by buf_chunk_init().
+@return TRUE if "block" has been added to buf_pool->free by buf_chunk_init() */
+static
+ibool
+buf_block_is_uncompressed(
+/*======================*/
+ const buf_block_t* block) /*!< in: pointer to block,
+ not dereferenced */
+{
+ //ut_ad(buf_pool_mutex_own());
+
+ if (UNIV_UNLIKELY((((ulint) block) % sizeof *block) != 0)) {
+ /* The pointer should be aligned. */
+ return(FALSE);
+ }
+
+ return(buf_pointer_is_block_field((void *)block));
+}
+
+/********************************************************************//**
+This is the general function used to get access to a database page.
+@return pointer to the block or NULL */
UNIV_INTERN
buf_block_t*
buf_page_get_gen(
/*=============*/
- /* out: pointer to the block or NULL */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint offset, /* in: page number */
- ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
- buf_block_t* guess, /* in: guessed block or NULL */
- ulint mode, /* in: BUF_GET, BUF_GET_IF_IN_POOL,
+ ulint offset, /*!< in: page number */
+ ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
+ buf_block_t* guess, /*!< in: guessed block or NULL */
+ ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
BUF_GET_NO_LATCH */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr) /* in: mini-transaction */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
buf_block_t* block;
ibool accessed;
@@ -2058,6 +2071,7 @@ buf_page_get_gen(
ut_ad((mode == BUF_GET) || (mode == BUF_GET_IF_IN_POOL)
|| (mode == BUF_GET_NO_LATCH));
ut_ad(zip_size == fil_space_get_zip_size(space));
+ ut_ad(ut_is_2pow(zip_size));
#ifndef UNIV_LOG_DEBUG
ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset, NULL));
#endif
@@ -2067,14 +2081,8 @@ loop:
//buf_pool_mutex_enter();
if (block) {
- block_mutex = buf_page_get_mutex((buf_page_t*)block);
-retry_lock_1:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex((buf_page_t*)block)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex((buf_page_t*)block);
- goto retry_lock_1;
- }
+ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
+ ut_a(block_mutex);
/* If the guess is a compressed page descriptor that
has been allocated by buf_buddy_alloc(), it may have
@@ -2102,14 +2110,8 @@ retry_lock_1:
rw_lock_s_lock(&page_hash_latch);
block = (buf_block_t*) buf_page_hash_get(space, offset);
if (block) {
- block_mutex = buf_page_get_mutex((buf_page_t*)block);
-retry_lock_2:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex((buf_page_t*)block)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex((buf_page_t*)block);
- goto retry_lock_2;
- }
+ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
+ ut_a(block_mutex);
}
rw_lock_s_unlock(&page_hash_latch);
}
@@ -2161,12 +2163,16 @@ loop2:
case BUF_BLOCK_ZIP_DIRTY:
ut_ad(block_mutex == &buf_pool_zip_mutex);
bpage = &block->page;
+ /* Protect bpage->buf_fix_count. */
+ /* Already proteced here. */
+ //mutex_enter(&buf_pool_zip_mutex);
if (bpage->buf_fix_count
|| buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
/* This condition often occurs when the buffer
is not buffer-fixed, but I/O-fixed by
buf_page_init_for_read(). */
+ //mutex_exit(&buf_pool_zip_mutex);
wait_until_unfixed:
/* The block is buffer-fixed or I/O-fixed.
Try again later. */
@@ -2179,6 +2185,7 @@ wait_until_unfixed:
/* Allocate an uncompressed page. */
//buf_pool_mutex_exit();
+ //mutex_exit(&buf_pool_zip_mutex);
mutex_exit(block_mutex);
block = buf_LRU_get_free_block(0);
@@ -2204,14 +2211,8 @@ wait_until_unfixed:
block = (buf_block_t*) hash_bpage;
if (block) {
- block_mutex = buf_page_get_mutex((buf_page_t*)block);
-retry_lock_3:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex((buf_page_t*)block)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex((buf_page_t*)block);
- goto retry_lock_3;
- }
+ block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
+ ut_a(block_mutex);
}
rw_lock_x_unlock(&page_hash_latch);
mutex_exit(&LRU_list_mutex);
@@ -2293,15 +2294,14 @@ retry_lock_3:
block->page.buf_fix_count = 1;
buf_block_set_io_fix(block, BUF_IO_READ);
+ rw_lock_x_lock(&block->lock);
+ mutex_exit(block_mutex);
+ mutex_exit(&buf_pool_zip_mutex);
mutex_enter(&buf_pool_mutex);
buf_pool->n_pend_unzip++;
mutex_exit(&buf_pool_mutex);
- rw_lock_x_lock(&block->lock);
- mutex_exit(block_mutex);
- mutex_exit(&buf_pool_zip_mutex);
-
buf_buddy_free(bpage, sizeof *bpage, FALSE);
//buf_pool_mutex_exit();
@@ -2319,12 +2319,12 @@ retry_lock_3:
//buf_pool_mutex_enter();
block_mutex = &block->mutex;
mutex_enter(block_mutex);
+ block->page.buf_fix_count--;
+ buf_block_set_io_fix(block, BUF_IO_NONE);
+
mutex_enter(&buf_pool_mutex);
buf_pool->n_pend_unzip--;
mutex_exit(&buf_pool_mutex);
- block->page.buf_fix_count--;
- buf_block_set_io_fix(block, BUF_IO_NONE);
- //mutex_exit(&block->mutex);
rw_lock_x_unlock(&block->lock);
if (UNIV_UNLIKELY(!success)) {
@@ -2428,21 +2428,21 @@ retry_lock_3:
return(block);
}
-/************************************************************************
+/********************************************************************//**
This is the general function used to get optimistic access to a database
-page. */
+page.
+@return TRUE if success */
UNIV_INTERN
ibool
buf_page_optimistic_get_func(
/*=========================*/
- /* out: TRUE if success */
- ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */
- buf_block_t* block, /* in: guessed buffer block */
- ib_uint64_t modify_clock,/* in: modify clock value if mode is
+ ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
+ buf_block_t* block, /*!< in: guessed buffer block */
+ ib_uint64_t modify_clock,/*!< in: modify clock value if mode is
..._GUESS_ON_CLOCK */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr) /* in: mini-transaction */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
ibool accessed;
ibool success;
@@ -2538,21 +2538,21 @@ buf_page_optimistic_get_func(
return(TRUE);
}
-/************************************************************************
+/********************************************************************//**
This is used to get access to a known database page, when no waiting can be
done. For example, if a search in an adaptive hash index leads us to this
-frame. */
+frame.
+@return TRUE if success */
UNIV_INTERN
ibool
buf_page_get_known_nowait(
/*======================*/
- /* out: TRUE if success */
- ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */
- buf_block_t* block, /* in: the known page */
- ulint mode, /* in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr) /* in: mini-transaction */
+ ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
+ buf_block_t* block, /*!< in: the known page */
+ ulint mode, /*!< in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
ibool success;
ulint fix_type;
@@ -2626,20 +2626,20 @@ buf_page_get_known_nowait(
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
Given a tablespace id and page number tries to get that page. If the
page is not in the buffer pool it is not loaded and NULL is returned.
-Suitable for using when holding the kernel mutex. */
+Suitable for using when holding the kernel mutex.
+@return pointer to a page or NULL */
UNIV_INTERN
const buf_block_t*
buf_page_try_get_func(
/*==================*/
- /* out: pointer to a page or NULL */
- ulint space_id,/* in: tablespace id */
- ulint page_no,/* in: page number */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr) /* in: mini-transaction */
+ ulint space_id,/*!< in: tablespace id */
+ ulint page_no,/*!< in: page number */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
buf_block_t* block;
ibool success;
@@ -2710,13 +2710,13 @@ buf_page_try_get_func(
return(block);
}
-/************************************************************************
+/********************************************************************//**
Initialize some fields of a control block. */
UNIV_INLINE
void
buf_page_init_low(
/*==============*/
- buf_page_t* bpage) /* in: block to init */
+ buf_page_t* bpage) /*!< in: block to init */
{
bpage->flush_type = BUF_FLUSH_LRU;
bpage->accessed = FALSE;
@@ -2731,49 +2731,16 @@ buf_page_init_low(
#endif /* UNIV_DEBUG_FILE_ACCESSES */
}
-#ifdef UNIV_HOTBACKUP
-/************************************************************************
-Inits a page to the buffer buf_pool, for use in ibbackup --restore. */
-UNIV_INTERN
-void
-buf_page_init_for_backup_restore(
-/*=============================*/
- ulint space, /* in: space id */
- ulint offset, /* in: offset of the page within space
- in units of a page */
- ulint zip_size,/* in: compressed page size in bytes
- or 0 for uncompressed pages */
- buf_block_t* block) /* in: block to init */
-{
- buf_block_init_low(block);
-
- block->lock_hash_val = 0;
-
- buf_page_init_low(&block->page);
- block->page.state = BUF_BLOCK_FILE_PAGE;
- block->page.space = space;
- block->page.offset = offset;
-
- page_zip_des_init(&block->page.zip);
-
- /* We assume that block->page.data has been allocated
- with zip_size == UNIV_PAGE_SIZE. */
- ut_ad(zip_size <= UNIV_PAGE_SIZE);
- ut_ad(ut_is_2pow(zip_size));
- page_zip_set_size(&block->page.zip, zip_size);
-}
-#endif /* UNIV_HOTBACKUP */
-
-/************************************************************************
+/********************************************************************//**
Inits a page to the buffer buf_pool. */
static
void
buf_page_init(
/*==========*/
- ulint space, /* in: space id */
- ulint offset, /* in: offset of the page within space
+ ulint space, /*!< in: space id */
+ ulint offset, /*!< in: offset of the page within space
in units of a page */
- buf_block_t* block) /* in: block to init */
+ buf_block_t* block) /*!< in: block to init */
{
buf_page_t* hash_page;
@@ -2832,7 +2799,7 @@ buf_page_init(
buf_page_address_fold(space, offset), &block->page);
}
-/************************************************************************
+/********************************************************************//**
Function which inits a page for read to the buffer buf_pool. If the page is
(1) already in buf_pool, or
(2) if we specify to read only ibuf pages and the page is not an ibuf page, or
@@ -2840,21 +2807,21 @@ Function which inits a page for read to the buffer buf_pool. If the page is
then this function does nothing.
Sets the io_fix flag to BUF_IO_READ and sets a non-recursive exclusive lock
on the buffer frame. The io-handler must take care that the flag is cleared
-and the lock released later. */
+and the lock released later.
+@return pointer to the block or NULL */
UNIV_INTERN
buf_page_t*
buf_page_init_for_read(
/*===================*/
- /* out: pointer to the block or NULL */
- ulint* err, /* out: DB_SUCCESS or DB_TABLESPACE_DELETED */
- ulint mode, /* in: BUF_READ_IBUF_PAGES_ONLY, ... */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size, or 0 */
- ibool unzip, /* in: TRUE=request uncompressed page */
- ib_int64_t tablespace_version,/* in: prevents reading from a wrong
+ ulint* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED */
+ ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ... */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ ibool unzip, /*!< in: TRUE=request uncompressed page */
+ ib_int64_t tablespace_version,/*!< in: prevents reading from a wrong
version of the tablespace in case we have done
DISCARD + IMPORT */
- ulint offset) /* in: page number */
+ ulint offset) /*!< in: page number */
{
buf_block_t* block;
buf_page_t* bpage;
@@ -3058,21 +3025,21 @@ func_exit:
return(bpage);
}
-/************************************************************************
+/********************************************************************//**
Initializes a page to the buffer buf_pool. The page is usually not read
from a file even if it cannot be found in the buffer buf_pool. This is one
of the functions which perform to a block a state transition NOT_USED =>
-FILE_PAGE (the other is buf_page_get_gen). */
+FILE_PAGE (the other is buf_page_get_gen).
+@return pointer to the block, page bufferfixed */
UNIV_INTERN
buf_block_t*
buf_page_create(
/*============*/
- /* out: pointer to the block, page bufferfixed */
- ulint space, /* in: space id */
- ulint offset, /* in: offset of the page within space in units of
+ ulint space, /*!< in: space id */
+ ulint offset, /*!< in: offset of the page within space in units of
a page */
- ulint zip_size,/* in: compressed page size, or 0 */
- mtr_t* mtr) /* in: mini-transaction handle */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
buf_frame_t* frame;
buf_block_t* block;
@@ -3206,14 +3173,14 @@ buf_page_create(
return(block);
}
-/************************************************************************
+/********************************************************************//**
Completes an asynchronous read or write request of a file page to or from
the buffer pool. */
UNIV_INTERN
void
buf_page_io_complete(
/*=================*/
- buf_page_t* bpage) /* in: pointer to the block in question */
+ buf_page_t* bpage) /*!< in: pointer to the block in question */
{
enum buf_io_fix io_type;
const ibool uncompressed = (buf_page_get_state(bpage)
@@ -3327,9 +3294,8 @@ corrupt:
" You can use CHECK\n"
"InnoDB: TABLE to scan your"
" table for corruption.\n"
- "InnoDB: See also"
- " http://dev.mysql.com/doc/refman/5.1/en/"
- "forcing-recovery.html\n"
+ "InnoDB: See also "
+ REFMAN "forcing-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) {
@@ -3343,7 +3309,7 @@ corrupt:
if (recv_recovery_is_on()) {
/* Pages must be uncompressed for crash recovery. */
ut_a(uncompressed);
- recv_recover_page(FALSE, TRUE, (buf_block_t*) bpage);
+ recv_recover_page(TRUE, (buf_block_t*) bpage);
}
if (uncompressed && !recv_no_ibuf_operations) {
@@ -3362,14 +3328,8 @@ corrupt:
mutex_enter(&LRU_list_mutex);
//}
}
- block_mutex = buf_page_get_mutex(bpage);
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
+ block_mutex = buf_page_get_mutex_enter(bpage);
+ ut_a(block_mutex);
mutex_enter(&buf_pool_mutex);
#ifdef UNIV_IBUF_COUNT_DEBUG
@@ -3442,7 +3402,7 @@ retry_lock:
//buf_pool_mutex_exit();
}
-/*************************************************************************
+/*********************************************************************//**
Invalidates the file pages in the buffer pool when an archive recovery is
completed. All the file pages buffered must be in a replaceable state when
this function is called: not latched and not modified. */
@@ -3472,8 +3432,9 @@ buf_pool_invalidate(void)
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/*************************************************************************
-Validates the buffer buf_pool data structure. */
+/*********************************************************************//**
+Validates the buffer buf_pool data structure.
+@return TRUE */
UNIV_INTERN
ibool
buf_validate(void)
@@ -3708,7 +3669,7 @@ buf_validate(void)
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Prints info of the buffer buf_pool data structure. */
UNIV_INTERN
void
@@ -3827,8 +3788,9 @@ buf_print(void)
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG
-/*************************************************************************
-Returns the number of latched pages in the buffer pool. */
+/*********************************************************************//**
+Returns the number of latched pages in the buffer pool.
+@return number of latched pages */
UNIV_INTERN
ulint
buf_get_latched_pages_number(void)
@@ -3917,8 +3879,9 @@ buf_get_latched_pages_number(void)
}
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Returns the number of pending buf pool ios. */
+/*********************************************************************//**
+Returns the number of pending buf pool ios.
+@return number of pending I/O operations */
UNIV_INTERN
ulint
buf_get_n_pending_ios(void)
@@ -3930,9 +3893,10 @@ buf_get_n_pending_ios(void)
+ buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]);
}
-/*************************************************************************
+/*********************************************************************//**
Returns the ratio in percents of modified pages in the buffer pool /
-database pages in the buffer pool. */
+database pages in the buffer pool.
+@return modified page percentage ratio */
UNIV_INTERN
ulint
buf_get_modified_ratio_pct(void)
@@ -3953,13 +3917,13 @@ buf_get_modified_ratio_pct(void)
return(ratio);
}
-/*************************************************************************
+/*********************************************************************//**
Prints info of the buffer i/o. */
UNIV_INTERN
void
buf_print_io(
/*=========*/
- FILE* file) /* in/out: buffer where to print */
+ FILE* file) /*!< in/out: buffer where to print */
{
time_t current_time;
double time_elapsed;
@@ -4046,7 +4010,7 @@ buf_print_io(
mutex_exit(&flush_list_mutex);
}
-/**************************************************************************
+/**********************************************************************//**
Refreshes the statistics used to print per-second averages. */
UNIV_INTERN
void
@@ -4060,8 +4024,9 @@ buf_refresh_io_stats(void)
buf_pool->n_pages_written_old = buf_pool->n_pages_written;
}
-/*************************************************************************
-Checks that all file pages in the buffer are in a replaceable state. */
+/*********************************************************************//**
+Asserts that all file pages in the buffer are in a replaceable state.
+@return TRUE */
UNIV_INTERN
ibool
buf_all_freed(void)
@@ -4094,14 +4059,14 @@ buf_all_freed(void)
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
Checks that there currently are no pending i/o-operations for the buffer
-pool. */
+pool.
+@return TRUE if there is no pending i/o */
UNIV_INTERN
ibool
buf_pool_check_no_pending_io(void)
/*==============================*/
- /* out: TRUE if there is no pending i/o */
{
ibool ret;
@@ -4122,8 +4087,9 @@ buf_pool_check_no_pending_io(void)
return(ret);
}
-/*************************************************************************
-Gets the current length of the free list of buffer blocks. */
+/*********************************************************************//**
+Gets the current length of the free list of buffer blocks.
+@return length of the free list */
UNIV_INTERN
ulint
buf_get_free_list_len(void)
@@ -4141,3 +4107,33 @@ buf_get_free_list_len(void)
return(len);
}
+#else /* !UNIV_HOTBACKUP */
+/********************************************************************//**
+Inits a page to the buffer buf_pool, for use in ibbackup --restore. */
+UNIV_INTERN
+void
+buf_page_init_for_backup_restore(
+/*=============================*/
+ ulint space, /*!< in: space id */
+ ulint offset, /*!< in: offset of the page within space
+ in units of a page */
+ ulint zip_size,/*!< in: compressed page size in bytes
+ or 0 for uncompressed pages */
+ buf_block_t* block) /*!< in: block to init */
+{
+ block->page.state = BUF_BLOCK_FILE_PAGE;
+ block->page.space = space;
+ block->page.offset = offset;
+
+ page_zip_des_init(&block->page.zip);
+
+ /* We assume that block->page.data has been allocated
+ with zip_size == UNIV_PAGE_SIZE. */
+ ut_ad(zip_size <= UNIV_PAGE_SIZE);
+ ut_ad(ut_is_2pow(zip_size));
+ page_zip_set_size(&block->page.zip, zip_size);
+ if (zip_size) {
+ block->page.zip.data = block->frame + UNIV_PAGE_SIZE;
+ }
+}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/buf/buf0flu.c b/storage/xtradb/buf/buf0flu.c
index ba8b0e9dc60..d465483691a 100644
--- a/storage/xtradb/buf/buf0flu.c
+++ b/storage/xtradb/buf/buf0flu.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file buf/buf0flu.c
The database buffer buf_pool flush algorithm
Created 11/11/1995 Heikki Tuuri
@@ -26,40 +27,73 @@ Created 11/11/1995 Heikki Tuuri
#ifdef UNIV_NONINL
#include "buf0flu.ic"
-#include "trx0sys.h"
#endif
+#include "buf0buf.h"
+#include "srv0srv.h"
+#include "page0zip.h"
+#ifndef UNIV_HOTBACKUP
#include "ut0byte.h"
#include "ut0lst.h"
#include "page0page.h"
-#include "page0zip.h"
#include "fil0fil.h"
-#include "buf0buf.h"
#include "buf0lru.h"
#include "buf0rea.h"
#include "ibuf0ibuf.h"
#include "log0log.h"
#include "os0file.h"
#include "trx0sys.h"
-#include "srv0srv.h"
-#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**********************************************************************
-Validates the flush list. */
+These statistics are generated for heuristics used in estimating the
+rate at which we should flush the dirty blocks to avoid bursty IO
+activity. Note that the rate of flushing not only depends on how many
+dirty pages we have in the buffer pool but it is also a fucntion of
+how much redo the workload is generating and at what rate. */
+/* @{ */
+
+/** Number of intervals for which we keep the history of these stats.
+Each interval is 1 second, defined by the rate at which
+srv_error_monitor_thread() calls buf_flush_stat_update(). */
+#define BUF_FLUSH_STAT_N_INTERVAL 20
+
+/** Sampled values buf_flush_stat_cur.
+Not protected by any mutex. Updated by buf_flush_stat_update(). */
+static buf_flush_stat_t buf_flush_stat_arr[BUF_FLUSH_STAT_N_INTERVAL];
+
+/** Cursor to buf_flush_stat_arr[]. Updated in a round-robin fashion. */
+static ulint buf_flush_stat_arr_ind;
+
+/** Values at start of the current interval. Reset by
+buf_flush_stat_update(). */
+static buf_flush_stat_t buf_flush_stat_cur;
+
+/** Running sum of past values of buf_flush_stat_cur.
+Updated by buf_flush_stat_update(). Not protected by any mutex. */
+static buf_flush_stat_t buf_flush_stat_sum;
+
+/** Number of pages flushed through non flush_list flushes. */
+static ulint buf_lru_flush_page_count = 0;
+
+/* @} */
+
+#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
+/******************************************************************//**
+Validates the flush list.
+@return TRUE if ok */
static
ibool
buf_flush_validate_low(void);
/*========================*/
- /* out: TRUE if ok */
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-/************************************************************************
+/********************************************************************//**
Inserts a modified block into the flush list. */
UNIV_INTERN
void
buf_flush_insert_into_flush_list(
/*=============================*/
- buf_block_t* block) /* in/out: block which is modified */
+ buf_block_t* block) /*!< in/out: block which is modified */
{
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(&block->mutex));
@@ -81,7 +115,7 @@ buf_flush_insert_into_flush_list(
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
}
-/************************************************************************
+/********************************************************************//**
Inserts a modified block into the flush list in the right sorted position.
This function is used by recovery, because there the modifications do not
necessarily come in the order of lsn's. */
@@ -89,7 +123,7 @@ UNIV_INTERN
void
buf_flush_insert_sorted_into_flush_list(
/*====================================*/
- buf_block_t* block) /* in/out: block which is modified */
+ buf_block_t* block) /*!< in/out: block which is modified */
{
buf_page_t* prev_b;
buf_page_t* b;
@@ -141,15 +175,15 @@ buf_flush_insert_sorted_into_flush_list(
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
}
-/************************************************************************
+/********************************************************************//**
Returns TRUE if the file page block is immediately suitable for replacement,
-i.e., the transition FILE_PAGE => NOT_USED allowed. */
+i.e., the transition FILE_PAGE => NOT_USED allowed.
+@return TRUE if can replace immediately */
UNIV_INTERN
ibool
buf_flush_ready_for_replace(
/*========================*/
- /* out: TRUE if can replace immediately */
- buf_page_t* bpage) /* in: buffer control block, must be
+ buf_page_t* bpage) /*!< in: buffer control block, must be
buf_page_in_file(bpage) and in the LRU list */
{
//ut_ad(buf_pool_mutex_own());
@@ -177,16 +211,16 @@ buf_flush_ready_for_replace(
return(FALSE);
}
-/************************************************************************
-Returns TRUE if the block is modified and ready for flushing. */
+/********************************************************************//**
+Returns TRUE if the block is modified and ready for flushing.
+@return TRUE if can flush immediately */
UNIV_INLINE
ibool
buf_flush_ready_for_flush(
/*======================*/
- /* out: TRUE if can flush immediately */
- buf_page_t* bpage, /* in: buffer control block, must be
+ buf_page_t* bpage, /*!< in: buffer control block, must be
buf_page_in_file(bpage) */
- enum buf_flush flush_type)/* in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
+ enum buf_flush flush_type)/*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
{
//ut_a(buf_page_in_file(bpage));
//ut_ad(buf_pool_mutex_own()); /*optimistic...*/
@@ -214,13 +248,13 @@ buf_flush_ready_for_flush(
return(FALSE);
}
-/************************************************************************
+/********************************************************************//**
Remove a block from the flush list of modified blocks. */
UNIV_INTERN
void
buf_flush_remove(
/*=============*/
- buf_page_t* bpage) /* in: pointer to the block in question */
+ buf_page_t* bpage) /*!< in: pointer to the block in question */
{
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
@@ -253,17 +287,18 @@ buf_flush_remove(
bpage->oldest_modification = 0;
- ut_d(UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list));
+ ut_d(UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,
+ ut_ad(ut_list_node_313->in_flush_list)));
mutex_exit(&flush_list_mutex);
}
-/************************************************************************
+/********************************************************************//**
Updates the flush system data structures when a write is completed. */
UNIV_INTERN
void
buf_flush_write_complete(
/*=====================*/
- buf_page_t* bpage) /* in: pointer to the block in question */
+ buf_page_t* bpage) /*!< in: pointer to the block in question */
{
enum buf_flush flush_type;
@@ -295,7 +330,7 @@ buf_flush_write_complete(
}
}
-/************************************************************************
+/********************************************************************//**
Flushes possible buffered writes from the doublewrite memory buffer to disk,
and also wakes up the aio thread if simulated aio is used. It is very
important to call this function after a batch of writes has been posted,
@@ -542,7 +577,7 @@ flush:
mutex_exit(&(trx_doublewrite->mutex));
}
-/************************************************************************
+/********************************************************************//**
Posts a buffer page for writing. If the doublewrite memory buffer is
full, calls buf_flush_buffered_writes and waits for for free space to
appear. */
@@ -550,7 +585,7 @@ static
void
buf_flush_post_to_doublewrite_buf(
/*==============================*/
- buf_page_t* bpage) /* in: buffer block to write */
+ buf_page_t* bpage) /*!< in: buffer block to write */
{
ulint zip_size;
try_again:
@@ -600,16 +635,17 @@ try_again:
mutex_exit(&(trx_doublewrite->mutex));
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
+/********************************************************************//**
Initializes a page for writing to the tablespace. */
UNIV_INTERN
void
buf_flush_init_for_writing(
/*=======================*/
- byte* page, /* in/out: page */
- void* page_zip_, /* in/out: compressed page, or NULL */
- ib_uint64_t newest_lsn) /* in: newest modification lsn
+ byte* page, /*!< in/out: page */
+ void* page_zip_, /*!< in/out: compressed page, or NULL */
+ ib_uint64_t newest_lsn) /*!< in: newest modification lsn
to the page */
{
ut_ad(page);
@@ -679,7 +715,8 @@ buf_flush_init_for_writing(
: BUF_NO_CHECKSUM_MAGIC);
}
-/************************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Does an asynchronous write of a buffer page. NOTE: in simulated aio and
also when the doublewrite buffer is used, we must call
buf_flush_buffered_writes after we have posted a batch of writes! */
@@ -687,7 +724,7 @@ static
void
buf_flush_write_block_low(
/*======================*/
- buf_page_t* bpage) /* in: buffer block to write */
+ buf_page_t* bpage) /*!< in: buffer block to write */
{
ulint zip_size = buf_page_get_zip_size(bpage);
page_t* frame = NULL;
@@ -769,7 +806,7 @@ buf_flush_write_block_low(
}
}
-/************************************************************************
+/********************************************************************//**
Writes a flushable page asynchronously from the buffer pool to a file.
NOTE: in simulated aio we must call
os_aio_simulated_wake_handler_threads after we have posted a batch of
@@ -780,8 +817,8 @@ static
void
buf_flush_page(
/*===========*/
- buf_page_t* bpage, /* in: buffer control block */
- enum buf_flush flush_type) /* in: BUF_FLUSH_LRU
+ buf_page_t* bpage, /*!< in: buffer control block */
+ enum buf_flush flush_type) /*!< in: BUF_FLUSH_LRU
or BUF_FLUSH_LIST */
{
mutex_t* block_mutex;
@@ -892,16 +929,16 @@ buf_flush_page(
buf_flush_write_block_low(bpage);
}
-/***************************************************************
-Flushes to disk all flushable pages within the flush area. */
+/***********************************************************//**
+Flushes to disk all flushable pages within the flush area.
+@return number of pages flushed */
static
ulint
buf_flush_try_neighbors(
/*====================*/
- /* out: number of pages flushed */
- ulint space, /* in: space id */
- ulint offset, /* in: page offset */
- enum buf_flush flush_type, /* in: BUF_FLUSH_LRU or
+ ulint space, /*!< in: space id */
+ ulint offset, /*!< in: page offset */
+ enum buf_flush flush_type, /*!< in: BUF_FLUSH_LRU or
BUF_FLUSH_LIST */
ulint flush_neighbors)
{
@@ -955,15 +992,9 @@ buf_flush_try_neighbors(
if (flush_type != BUF_FLUSH_LRU
|| i == offset
|| buf_page_is_old(bpage)) {
- mutex_t* block_mutex = buf_page_get_mutex(bpage);
+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
+ ut_a(block_mutex);
if (buf_flush_ready_for_flush(bpage, flush_type)
&& (i == offset || !bpage->buf_fix_count)) {
@@ -993,28 +1024,26 @@ retry_lock:
return(count);
}
-/***********************************************************************
+/*******************************************************************//**
This utility flushes dirty blocks from the end of the LRU list or flush_list.
NOTE 1: in the case of an LRU flush the calling thread may own latches to
pages: to avoid deadlocks, this function must be written so that it cannot
end up waiting for these latches! NOTE 2: in the case of a flush list flush,
-the calling thread is not allowed to own any latches on pages! */
+the calling thread is not allowed to own any latches on pages!
+@return number of blocks for which the write request was queued;
+ULINT_UNDEFINED if there was a flush of the same type already running */
UNIV_INTERN
ulint
buf_flush_batch(
/*============*/
- /* out: number of blocks for which the
- write request was queued;
- ULINT_UNDEFINED if there was a flush
- of the same type already running */
- enum buf_flush flush_type, /* in: BUF_FLUSH_LRU or
+ enum buf_flush flush_type, /*!< in: BUF_FLUSH_LRU or
BUF_FLUSH_LIST; if BUF_FLUSH_LIST,
then the caller must not own any
latches on pages */
- ulint min_n, /* in: wished minimum mumber of blocks
+ ulint min_n, /*!< in: wished minimum mumber of blocks
flushed (it is not guaranteed that the
actual number is that big, though) */
- ib_uint64_t lsn_limit) /* in the case BUF_FLUSH_LIST all
+ ib_uint64_t lsn_limit) /*!< in the case BUF_FLUSH_LIST all
blocks whose oldest_modification is
smaller than this should be flushed
(if their number does not exceed
@@ -1091,24 +1120,16 @@ flush_next:
function a pointer to a block in the list! */
do {
- mutex_t*block_mutex = buf_page_get_mutex(bpage);
+ mutex_t*block_mutex = buf_page_get_mutex_enter(bpage);
ibool ready;
-retry_lock_1:
ut_a(buf_page_in_file(bpage));
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock_1;
- }
+ ut_a(block_mutex);
ready = buf_flush_ready_for_flush(bpage, flush_type);
mutex_exit(block_mutex);
if (ready) {
- mutex_t* block_mutex;
- buf_page_t* bpage_tmp;
space = buf_page_get_space(bpage);
offset = buf_page_get_page_no(bpage);
@@ -1122,8 +1143,6 @@ retry_lock_1:
/* Try to flush also all the neighbors */
page_count += buf_flush_try_neighbors(
space, offset, flush_type, srv_flush_neighbor_pages);
- block_mutex = buf_page_get_mutex(bpage);
- bpage_tmp = buf_page_hash_get(space, offset);
/* fprintf(stderr,
"Flush type %lu, page no %lu, neighb %lu\n",
flush_type, offset,
@@ -1189,38 +1208,44 @@ retry_lock_1:
srv_buf_pool_flushed += page_count;
+ /* We keep track of all flushes happening as part of LRU
+ flush. When estimating the desired rate at which flush_list
+ should be flushed we factor in this value. */
+ if (flush_type == BUF_FLUSH_LRU) {
+ buf_lru_flush_page_count += page_count;
+ }
+
return(page_count);
}
-/**********************************************************************
+/******************************************************************//**
Waits until a flush batch of the given type ends */
UNIV_INTERN
void
buf_flush_wait_batch_end(
/*=====================*/
- enum buf_flush type) /* in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
+ enum buf_flush type) /*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
{
ut_ad((type == BUF_FLUSH_LRU) || (type == BUF_FLUSH_LIST));
os_event_wait(buf_pool->no_flush[type]);
}
-/**********************************************************************
+/******************************************************************//**
Gives a recommendation of how many blocks should be flushed to establish
a big enough margin of replaceable blocks near the end of the LRU list
-and in the free list. */
+and in the free list.
+@return number of blocks which should be flushed from the end of the
+LRU list */
static
ulint
buf_flush_LRU_recommendation(void)
/*==============================*/
- /* out: number of blocks which should be flushed
- from the end of the LRU list */
{
buf_page_t* bpage;
ulint n_replaceable;
ulint distance = 0;
ibool have_LRU_mutex = FALSE;
- mutex_t* block_mutex;
if(UT_LIST_GET_LEN(buf_pool->unzip_LRU))
have_LRU_mutex = TRUE;
@@ -1238,21 +1263,15 @@ buf_flush_LRU_recommendation(void)
+ BUF_FLUSH_EXTRA_MARGIN)
&& (distance < BUF_LRU_FREE_SEARCH_LEN)) {
- if (!bpage->in_LRU_list) {
+ mutex_t* block_mutex;
+ if (!bpage->in_LRU_list) {
/* reatart. but it is very optimistic */
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
continue;
}
+ block_mutex = buf_page_get_mutex_enter(bpage);
- block_mutex = buf_page_get_mutex(bpage);
-
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
+ ut_a(block_mutex);
if (buf_flush_ready_for_replace(bpage)) {
n_replaceable++;
@@ -1278,7 +1297,7 @@ retry_lock:
- n_replaceable);
}
-/*************************************************************************
+/*********************************************************************//**
Flushes pages from the end of the LRU list if there is too small a margin
of replaceable pages there or in the free list. VERY IMPORTANT: this function
is called also by threads which have locks on pages. To avoid deadlocks, we
@@ -1306,18 +1325,130 @@ buf_flush_free_margin(
}
}
+/*********************************************************************
+Update the historical stats that we are collecting for flush rate
+heuristics at the end of each interval.
+Flush rate heuristic depends on (a) rate of redo log generation and
+(b) the rate at which LRU flush is happening. */
+UNIV_INTERN
+void
+buf_flush_stat_update(void)
+/*=======================*/
+{
+ buf_flush_stat_t* item;
+ ib_uint64_t lsn_diff;
+ ib_uint64_t lsn;
+ ulint n_flushed;
+
+ lsn = log_get_lsn();
+ if (buf_flush_stat_cur.redo == 0) {
+ /* First time around. Just update the current LSN
+ and return. */
+ buf_flush_stat_cur.redo = lsn;
+ return;
+ }
+
+ item = &buf_flush_stat_arr[buf_flush_stat_arr_ind];
+
+ /* values for this interval */
+ lsn_diff = lsn - buf_flush_stat_cur.redo;
+ n_flushed = buf_lru_flush_page_count
+ - buf_flush_stat_cur.n_flushed;
+
+ /* add the current value and subtract the obsolete entry. */
+ buf_flush_stat_sum.redo += lsn_diff - item->redo;
+ buf_flush_stat_sum.n_flushed += n_flushed - item->n_flushed;
+
+ /* put current entry in the array. */
+ item->redo = lsn_diff;
+ item->n_flushed = n_flushed;
+
+ /* update the index */
+ buf_flush_stat_arr_ind++;
+ buf_flush_stat_arr_ind %= BUF_FLUSH_STAT_N_INTERVAL;
+
+ /* reset the current entry. */
+ buf_flush_stat_cur.redo = lsn;
+ buf_flush_stat_cur.n_flushed = buf_lru_flush_page_count;
+}
+
+/*********************************************************************
+Determines the fraction of dirty pages that need to be flushed based
+on the speed at which we generate redo log. Note that if redo log
+is generated at a significant rate without corresponding increase
+in the number of dirty pages (for example, an in-memory workload)
+it can cause IO bursts of flushing. This function implements heuristics
+to avoid this burstiness.
+@return number of dirty pages to be flushed / second */
+UNIV_INTERN
+ulint
+buf_flush_get_desired_flush_rate(void)
+/*==================================*/
+{
+ ulint redo_avg;
+ ulint lru_flush_avg;
+ ulint n_dirty;
+ ulint n_flush_req;
+ lint rate;
+ ib_uint64_t lsn = log_get_lsn();
+ ulint log_capacity = log_get_capacity();
+
+ /* log_capacity should never be zero after the initialization
+ of log subsystem. */
+ ut_ad(log_capacity != 0);
+
+ /* Get total number of dirty pages. It is OK to access
+ flush_list without holding any mtex as we are using this
+ only for heuristics. */
+ n_dirty = UT_LIST_GET_LEN(buf_pool->flush_list);
+
+ /* An overflow can happen if we generate more than 2^32 bytes
+ of redo in this interval i.e.: 4G of redo in 1 second. We can
+ safely consider this as infinity because if we ever come close
+ to 4G we'll start a synchronous flush of dirty pages. */
+ /* redo_avg below is average at which redo is generated in
+ past BUF_FLUSH_STAT_N_INTERVAL + redo generated in the current
+ interval. */
+ redo_avg = (ulint) (buf_flush_stat_sum.redo
+ / BUF_FLUSH_STAT_N_INTERVAL
+ + (lsn - buf_flush_stat_cur.redo));
+
+ /* An overflow can happen possibly if we flush more than 2^32
+ pages in BUF_FLUSH_STAT_N_INTERVAL. This is a very very
+ unlikely scenario. Even when this happens it means that our
+ flush rate will be off the mark. It won't affect correctness
+ of any subsystem. */
+ /* lru_flush_avg below is rate at which pages are flushed as
+ part of LRU flush in past BUF_FLUSH_STAT_N_INTERVAL + the
+ number of pages flushed in the current interval. */
+ lru_flush_avg = buf_flush_stat_sum.n_flushed
+ / BUF_FLUSH_STAT_N_INTERVAL
+ + (buf_lru_flush_page_count
+ - buf_flush_stat_cur.n_flushed);
+
+ n_flush_req = (n_dirty * redo_avg) / log_capacity;
+
+ /* The number of pages that we want to flush from the flush
+ list is the difference between the required rate and the
+ number of pages that we are historically flushing from the
+ LRU list */
+ rate = n_flush_req - lru_flush_avg;
+ return(rate > 0 ? (ulint) rate : 0);
+}
+
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**********************************************************************
-Validates the flush list. */
+/******************************************************************//**
+Validates the flush list.
+@return TRUE if ok */
static
ibool
buf_flush_validate_low(void)
/*========================*/
- /* out: TRUE if ok */
{
buf_page_t* bpage;
- UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list);
+ UT_LIST_VALIDATE(flush_list, buf_page_t, buf_pool->flush_list,
+ ut_ad(ut_list_node_313->in_flush_list));
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
@@ -1335,13 +1466,13 @@ buf_flush_validate_low(void)
return(TRUE);
}
-/**********************************************************************
-Validates the flush list. */
+/******************************************************************//**
+Validates the flush list.
+@return TRUE if ok */
UNIV_INTERN
ibool
buf_flush_validate(void)
/*====================*/
- /* out: TRUE if ok */
{
ibool ret;
@@ -1356,3 +1487,4 @@ buf_flush_validate(void)
return(ret);
}
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/buf/buf0lru.c b/storage/xtradb/buf/buf0lru.c
index e5613196dd9..2270ea5dce2 100644
--- a/storage/xtradb/buf/buf0lru.c
+++ b/storage/xtradb/buf/buf0lru.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file buf/buf0lru.c
The database buffer replacement algorithm
Created 11/5/1995 Heikki Tuuri
@@ -48,7 +49,7 @@ Created 11/5/1995 Heikki Tuuri
#include "log0recv.h"
#include "srv0srv.h"
-/* The number of blocks from the LRU_old pointer onward, including the block
+/** The number of blocks from the LRU_old pointer onward, including the block
pointed to, must be 3/8 of the whole LRU list length, except that the
tolerance defined below is allowed. Note that the tolerance must be small
enough such that for even the BUF_LRU_OLD_MIN_LEN long LRU list, the
@@ -56,21 +57,21 @@ LRU_old pointer is not allowed to point to either end of the LRU list. */
#define BUF_LRU_OLD_TOLERANCE 20
-/* The whole LRU list length is divided by this number to determine an
+/** The whole LRU list length is divided by this number to determine an
initial segment in buf_LRU_get_recent_limit */
#define BUF_LRU_INITIAL_RATIO 8
-/* When dropping the search hash index entries before deleting an ibd
+/** When dropping the search hash index entries before deleting an ibd
file, we build a local array of pages belonging to that tablespace
in the buffer pool. Following is the size of that array. */
#define BUF_LRU_DROP_SEARCH_HASH_SIZE 1024
-/* If we switch on the InnoDB monitor because there are too few available
+/** If we switch on the InnoDB monitor because there are too few available
frames in the buffer pool, we set this to TRUE */
-UNIV_INTERN ibool buf_lru_switched_on_innodb_mon = FALSE;
+static ibool buf_lru_switched_on_innodb_mon = FALSE;
-/**********************************************************************
+/******************************************************************//**
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
and page_zip_decompress() operations. Based on the statistics,
buf_LRU_evict_from_unzip_LRU() decides if we want to evict from
@@ -79,69 +80,71 @@ uncompressed frame (meaning we can evict dirty blocks as well). From
the regular LRU, we will evict the entire block (i.e.: both the
uncompressed and compressed data), which must be clean. */
-/* Number of intervals for which we keep the history of these stats.
+/* @{ */
+
+/** Number of intervals for which we keep the history of these stats.
Each interval is 1 second, defined by the rate at which
srv_error_monitor_thread() calls buf_LRU_stat_update(). */
#define BUF_LRU_STAT_N_INTERVAL 50
-/* Co-efficient with which we multiply I/O operations to equate them
+/** Co-efficient with which we multiply I/O operations to equate them
with page_zip_decompress() operations. */
#define BUF_LRU_IO_TO_UNZIP_FACTOR 50
-/* Sampled values buf_LRU_stat_cur.
+/** Sampled values buf_LRU_stat_cur.
Protected by buf_pool_mutex. Updated by buf_LRU_stat_update(). */
static buf_LRU_stat_t buf_LRU_stat_arr[BUF_LRU_STAT_N_INTERVAL];
-/* Cursor to buf_LRU_stat_arr[] that is updated in a round-robin fashion. */
+/** Cursor to buf_LRU_stat_arr[] that is updated in a round-robin fashion. */
static ulint buf_LRU_stat_arr_ind;
-/* Current operation counters. Not protected by any mutex. Cleared
+/** Current operation counters. Not protected by any mutex. Cleared
by buf_LRU_stat_update(). */
UNIV_INTERN buf_LRU_stat_t buf_LRU_stat_cur;
-/* Running sum of past values of buf_LRU_stat_cur.
+/** Running sum of past values of buf_LRU_stat_cur.
Updated by buf_LRU_stat_update(). Protected by buf_pool_mutex. */
UNIV_INTERN buf_LRU_stat_t buf_LRU_stat_sum;
-/**********************************************************************
+/* @} */
+
+/******************************************************************//**
Takes a block out of the LRU list and page hash table.
If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
the object will be freed and buf_pool_zip_mutex will be released.
If a compressed page or a compressed-only block descriptor is freed,
other compressed pages or compressed-only block descriptors may be
-relocated. */
+relocated.
+@return the new state of the block (BUF_BLOCK_ZIP_FREE if the state
+was BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH otherwise) */
static
enum buf_page_state
buf_LRU_block_remove_hashed_page(
/*=============================*/
- /* out: the new state of the block
- (BUF_BLOCK_ZIP_FREE if the state was
- BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH
- otherwise) */
- buf_page_t* bpage, /* in: block, must contain a file page and
+ buf_page_t* bpage, /*!< in: block, must contain a file page and
be in a state where it can be freed; there
may or may not be a hash index to the page */
- ibool zip); /* in: TRUE if should remove also the
+ ibool zip); /*!< in: TRUE if should remove also the
compressed page of an uncompressed page */
-/**********************************************************************
+/******************************************************************//**
Puts a file page whose has no hash index to the free list. */
static
void
buf_LRU_block_free_hashed_page(
/*===========================*/
- buf_block_t* block, /* in: block, must contain a file page and
+ buf_block_t* block, /*!< in: block, must contain a file page and
be in a state where it can be freed */
ibool have_page_hash_mutex);
-/**********************************************************************
+/******************************************************************//**
Determines if the unzip_LRU list should be used for evicting a victim
-instead of the general LRU list. */
+instead of the general LRU list.
+@return TRUE if should use unzip_LRU */
UNIV_INLINE
ibool
buf_LRU_evict_from_unzip_LRU(
ibool have_LRU_mutex)
/*==============================*/
- /* out: TRUE if should use unzip_LRU */
{
ulint io_avg;
ulint unzip_avg;
@@ -191,18 +194,18 @@ buf_LRU_evict_from_unzip_LRU(
return(unzip_avg <= io_avg * BUF_LRU_IO_TO_UNZIP_FACTOR);
}
-/**********************************************************************
+/******************************************************************//**
Attempts to drop page hash index on a batch of pages belonging to a
particular space id. */
static
void
buf_LRU_drop_page_hash_batch(
/*=========================*/
- ulint space_id, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space_id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- const ulint* arr, /* in: array of page_no */
- ulint count) /* in: number of entries in array */
+ const ulint* arr, /*!< in: array of page_no */
+ ulint count) /*!< in: number of entries in array */
{
ulint i;
@@ -215,7 +218,7 @@ buf_LRU_drop_page_hash_batch(
}
}
-/**********************************************************************
+/******************************************************************//**
When doing a DROP TABLE/DISCARD TABLESPACE we have to drop all page
hash index entries belonging to that table. This function tries to
do that in batch. Note that this is a 'best effort' attempt and does
@@ -224,7 +227,7 @@ static
void
buf_LRU_drop_page_hash_for_tablespace(
/*==================================*/
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
buf_page_t* bpage;
ulint* page_arr;
@@ -249,16 +252,10 @@ scan_again:
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
while (bpage != NULL) {
- mutex_t* block_mutex = buf_page_get_mutex(bpage);
+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
buf_page_t* prev_bpage;
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
+ ut_a(block_mutex);
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
ut_a(buf_page_in_file(bpage));
@@ -328,14 +325,14 @@ next_page:
ut_free(page_arr);
}
-/**********************************************************************
+/******************************************************************//**
Invalidates all pages belonging to a given tablespace when we are deleting
the data file(s) of that tablespace. */
UNIV_INTERN
void
buf_LRU_invalidate_tablespace(
/*==========================*/
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
buf_page_t* bpage;
ibool all_freed;
@@ -358,18 +355,12 @@ scan_again:
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
while (bpage != NULL) {
- mutex_t* block_mutex = buf_page_get_mutex(bpage);
+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
buf_page_t* prev_bpage;
ut_a(buf_page_in_file(bpage));
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
+ ut_a(block_mutex);
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
if (buf_page_get_space(bpage) == id) {
@@ -459,15 +450,15 @@ next_page:
}
}
-/**********************************************************************
+/******************************************************************//**
Gets the minimum LRU_position field for the blocks in an initial segment
(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
-guaranteed to be precise, because the ulint_clock may wrap around. */
+guaranteed to be precise, because the ulint_clock may wrap around.
+@return the limit; zero if could not determine it */
UNIV_INTERN
ulint
buf_LRU_get_recent_limit(void)
/*==========================*/
- /* out: the limit; zero if could not determine it */
{
const buf_page_t* bpage;
ulint len;
@@ -489,21 +480,22 @@ buf_LRU_get_recent_limit(void)
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
- limit = buf_page_get_LRU_position(bpage) - len / BUF_LRU_INITIAL_RATIO;
+ limit = buf_page_get_LRU_position(bpage);
+ len /= BUF_LRU_INITIAL_RATIO;
//buf_pool_mutex_exit();
mutex_exit(&LRU_list_mutex);
- return(limit);
+ return(limit > len ? (limit - len) : 0);
}
-/************************************************************************
+/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
UNIV_INTERN
void
buf_LRU_insert_zip_clean(
/*=====================*/
- buf_page_t* bpage) /* in: pointer to the block in question */
+ buf_page_t* bpage) /*!< in: pointer to the block in question */
{
buf_page_t* b;
@@ -531,15 +523,15 @@ buf_LRU_insert_zip_clean(
}
}
-/**********************************************************************
+/******************************************************************//**
Try to free an uncompressed page of a compressed block from the unzip
-LRU list. The compressed page is preserved, and it need not be clean. */
+LRU list. The compressed page is preserved, and it need not be clean.
+@return TRUE if freed */
UNIV_INLINE
ibool
buf_LRU_free_from_unzip_LRU_list(
/*=============================*/
- /* out: TRUE if freed */
- ulint n_iterations, /* in: how many times this has been called
+ ulint n_iterations, /*!< in: how many times this has been called
repeatedly without result: a high value means
that we should search farther; we will search
n_iterations / 5 of the unzip_LRU list,
@@ -611,14 +603,14 @@ restart:
return(FALSE);
}
-/**********************************************************************
-Try to free a clean page from the common LRU list. */
+/******************************************************************//**
+Try to free a clean page from the common LRU list.
+@return TRUE if freed */
UNIV_INLINE
ibool
buf_LRU_free_from_common_LRU_list(
/*==============================*/
- /* out: TRUE if freed */
- ulint n_iterations, /* in: how many times this has been called
+ ulint n_iterations, /*!< in: how many times this has been called
repeatedly without result: a high value means
that we should search farther; if
n_iterations < 10, then we search
@@ -640,16 +632,9 @@ restart:
enum buf_lru_free_block_status freed;
mutex_t* block_mutex
- = buf_page_get_mutex(bpage);
-
-retry_lock:
- mutex_enter(block_mutex);
+ = buf_page_get_mutex_enter(bpage);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
+ ut_a(block_mutex);
if (!bpage->in_LRU_list
|| !buf_page_in_file(bpage)) {
@@ -686,14 +671,14 @@ retry_lock:
return(FALSE);
}
-/**********************************************************************
-Try to free a replaceable block. */
+/******************************************************************//**
+Try to free a replaceable block.
+@return TRUE if found and freed */
UNIV_INTERN
ibool
buf_LRU_search_and_free_block(
/*==========================*/
- /* out: TRUE if found and freed */
- ulint n_iterations) /* in: how many times this has been called
+ ulint n_iterations) /*!< in: how many times this has been called
repeatedly without result: a high value means
that we should search farther; if
n_iterations < 10, then we search
@@ -734,7 +719,7 @@ buf_LRU_search_and_free_block(
return(freed);
}
-/**********************************************************************
+/******************************************************************//**
Tries to remove LRU flushed blocks from the end of the LRU list and put them
to the free list. This is beneficial for the efficiency of the insert buffer
operation, as flushed pages from non-unique non-clustered indexes are here
@@ -765,16 +750,15 @@ buf_LRU_try_free_flushed_blocks(void)
mutex_exit(&buf_pool_mutex);
}
-/**********************************************************************
+/******************************************************************//**
Returns TRUE if less than 25 % of the buffer pool is available. This can be
used in heuristics to prevent huge transactions eating up the whole buffer
-pool for their locks. */
+pool for their locks.
+@return TRUE if less than 25 % of buffer pool left */
UNIV_INTERN
ibool
buf_LRU_buf_pool_running_out(void)
/*==============================*/
- /* out: TRUE if less than 25 % of buffer pool
- left */
{
ibool ret = FALSE;
@@ -795,15 +779,14 @@ buf_LRU_buf_pool_running_out(void)
return(ret);
}
-/**********************************************************************
+/******************************************************************//**
Returns a free block from the buf_pool. The block is taken off the
-free list. If it is empty, returns NULL. */
+free list. If it is empty, returns NULL.
+@return a free control block, or NULL if the buf_block->free list is empty */
UNIV_INTERN
buf_block_t*
buf_LRU_get_free_only(void)
/*=======================*/
- /* out: a free control block, or NULL
- if the buf_block->free list is empty */
{
buf_block_t* block;
@@ -835,17 +818,16 @@ buf_LRU_get_free_only(void)
return(block);
}
-/**********************************************************************
+/******************************************************************//**
Returns a free block from the buf_pool. The block is taken off the
free list. If it is empty, blocks are moved from the end of the
-LRU list to the free list. */
+LRU list to the free list.
+@return the free control block, in state BUF_BLOCK_READY_FOR_USE */
UNIV_INTERN
buf_block_t*
buf_LRU_get_free_block(
/*===================*/
- /* out: the free control block,
- in state BUF_BLOCK_READY_FOR_USE */
- ulint zip_size) /* in: compressed page size in bytes,
+ ulint zip_size) /*!< in: compressed page size in bytes,
or 0 if uncompressed tablespace */
{
buf_block_t* block = NULL;
@@ -1031,7 +1013,7 @@ loop:
goto loop;
}
-/***********************************************************************
+/*******************************************************************//**
Moves the LRU_old pointer so that the length of the old blocks list
is inside the allowed limits. */
UNIV_INLINE
@@ -1092,7 +1074,7 @@ buf_LRU_old_adjust_len(void)
}
}
-/***********************************************************************
+/*******************************************************************//**
Initializes the old blocks pointer in the LRU list. This function should be
called when the LRU list grows to BUF_LRU_OLD_MIN_LEN length. */
static
@@ -1124,13 +1106,13 @@ buf_LRU_old_init(void)
buf_LRU_old_adjust_len();
}
-/**********************************************************************
+/******************************************************************//**
Remove a block from the unzip_LRU list if it belonged to the list. */
static
void
buf_unzip_LRU_remove_block_if_needed(
/*=================================*/
- buf_page_t* bpage) /* in/out: control block */
+ buf_page_t* bpage) /*!< in/out: control block */
{
ut_ad(buf_pool);
ut_ad(bpage);
@@ -1148,13 +1130,13 @@ buf_unzip_LRU_remove_block_if_needed(
}
}
-/**********************************************************************
+/******************************************************************//**
Removes a block from the LRU list. */
UNIV_INLINE
void
buf_LRU_remove_block(
/*=================*/
- buf_page_t* bpage) /* in: control block */
+ buf_page_t* bpage) /*!< in: control block */
{
ut_ad(buf_pool);
ut_ad(bpage);
@@ -1210,14 +1192,14 @@ buf_LRU_remove_block(
buf_LRU_old_adjust_len();
}
-/**********************************************************************
+/******************************************************************//**
Adds a block to the LRU list of decompressed zip pages. */
UNIV_INTERN
void
buf_unzip_LRU_add_block(
/*====================*/
- buf_block_t* block, /* in: control block */
- ibool old) /* in: TRUE if should be put to the end
+ buf_block_t* block, /*!< in: control block */
+ ibool old) /*!< in: TRUE if should be put to the end
of the list, else put to the start */
{
ut_ad(buf_pool);
@@ -1237,13 +1219,13 @@ buf_unzip_LRU_add_block(
}
}
-/**********************************************************************
+/******************************************************************//**
Adds a block to the LRU list end. */
UNIV_INLINE
void
buf_LRU_add_block_to_end_low(
/*=========================*/
- buf_page_t* bpage) /* in: control block */
+ buf_page_t* bpage) /*!< in: control block */
{
buf_page_t* last_bpage;
@@ -1296,14 +1278,14 @@ buf_LRU_add_block_to_end_low(
}
}
-/**********************************************************************
+/******************************************************************//**
Adds a block to the LRU list. */
UNIV_INLINE
void
buf_LRU_add_block_low(
/*==================*/
- buf_page_t* bpage, /* in: control block */
- ibool old) /* in: TRUE if should be put to the old blocks
+ buf_page_t* bpage, /*!< in: control block */
+ ibool old) /*!< in: TRUE if should be put to the old blocks
in the LRU list, else put to the start; if the
LRU list is very short, the block is added to
the start, regardless of this parameter */
@@ -1369,14 +1351,14 @@ buf_LRU_add_block_low(
}
}
-/**********************************************************************
+/******************************************************************//**
Adds a block to the LRU list. */
UNIV_INTERN
void
buf_LRU_add_block(
/*==============*/
- buf_page_t* bpage, /* in: control block */
- ibool old) /* in: TRUE if should be put to the old
+ buf_page_t* bpage, /*!< in: control block */
+ ibool old) /*!< in: TRUE if should be put to the old
blocks in the LRU list, else put to the start;
if the LRU list is very short, the block is
added to the start, regardless of this
@@ -1385,31 +1367,31 @@ buf_LRU_add_block(
buf_LRU_add_block_low(bpage, old);
}
-/**********************************************************************
+/******************************************************************//**
Moves a block to the start of the LRU list. */
UNIV_INTERN
void
buf_LRU_make_block_young(
/*=====================*/
- buf_page_t* bpage) /* in: control block */
+ buf_page_t* bpage) /*!< in: control block */
{
buf_LRU_remove_block(bpage);
buf_LRU_add_block_low(bpage, FALSE);
}
-/**********************************************************************
+/******************************************************************//**
Moves a block to the end of the LRU list. */
UNIV_INTERN
void
buf_LRU_make_block_old(
/*===================*/
- buf_page_t* bpage) /* in: control block */
+ buf_page_t* bpage) /*!< in: control block */
{
buf_LRU_remove_block(bpage);
buf_LRU_add_block_to_end_low(bpage);
}
-/**********************************************************************
+/******************************************************************//**
Try to free a block. If bpage is a descriptor of a compressed-only
page, the descriptor object will be freed as well.
@@ -1419,19 +1401,18 @@ accessible via bpage.
The caller must hold buf_pool_mutex and buf_page_get_mutex(bpage) and
release these two mutexes after the call. No other
-buf_page_get_mutex() may be held when calling this function. */
+buf_page_get_mutex() may be held when calling this function.
+@return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or
+BUF_LRU_NOT_FREED otherwise. */
UNIV_INTERN
enum buf_lru_free_block_status
buf_LRU_free_block(
/*===============*/
- /* out: BUF_LRU_FREED if freed,
- BUF_LRU_CANNOT_RELOCATE or
- BUF_LRU_NOT_FREED otherwise. */
- buf_page_t* bpage, /* in: block to be freed */
- ibool zip, /* in: TRUE if should remove also the
+ buf_page_t* bpage, /*!< in: block to be freed */
+ ibool zip, /*!< in: TRUE if should remove also the
compressed page of an uncompressed page */
ibool* buf_pool_mutex_released,
- /* in: pointer to a variable that will
+ /*!< in: pointer to a variable that will
be assigned TRUE if buf_pool_mutex
was temporarily released, or NULL */
ibool have_LRU_mutex)
@@ -1722,13 +1703,13 @@ not_freed:
return(BUF_LRU_FREED);
}
-/**********************************************************************
+/******************************************************************//**
Puts a block back to the free list. */
UNIV_INTERN
void
buf_LRU_block_free_non_file_page(
/*=============================*/
- buf_block_t* block, /* in: block, must not contain a file page */
+ buf_block_t* block, /*!< in: block, must not contain a file page */
ibool have_page_hash_mutex)
{
void* data;
@@ -1783,26 +1764,24 @@ buf_LRU_block_free_non_file_page(
UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
}
-/**********************************************************************
+/******************************************************************//**
Takes a block out of the LRU list and page hash table.
If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
the object will be freed and buf_pool_zip_mutex will be released.
If a compressed page or a compressed-only block descriptor is freed,
other compressed pages or compressed-only block descriptors may be
-relocated. */
+relocated.
+@return the new state of the block (BUF_BLOCK_ZIP_FREE if the state
+was BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH otherwise) */
static
enum buf_page_state
buf_LRU_block_remove_hashed_page(
/*=============================*/
- /* out: the new state of the block
- (BUF_BLOCK_ZIP_FREE if the state was
- BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH
- otherwise) */
- buf_page_t* bpage, /* in: block, must contain a file page and
+ buf_page_t* bpage, /*!< in: block, must contain a file page and
be in a state where it can be freed; there
may or may not be a hash index to the page */
- ibool zip) /* in: TRUE if should remove also the
+ ibool zip) /*!< in: TRUE if should remove also the
compressed page of an uncompressed page */
{
const buf_page_t* hashed_bpage;
@@ -1962,6 +1941,9 @@ buf_LRU_block_remove_hashed_page(
void* data = bpage->zip.data;
bpage->zip.data = NULL;
+ ut_ad(!bpage->in_free_list);
+ ut_ad(!bpage->in_flush_list);
+ ut_ad(!bpage->in_LRU_list);
mutex_exit(&((buf_block_t*) bpage)->mutex);
//buf_pool_mutex_exit_forbid();
buf_buddy_free(data, page_zip_get_size(&bpage->zip), TRUE);
@@ -1985,13 +1967,13 @@ buf_LRU_block_remove_hashed_page(
return(BUF_BLOCK_ZIP_FREE);
}
-/**********************************************************************
+/******************************************************************//**
Puts a file page whose has no hash index to the free list. */
static
void
buf_LRU_block_free_hashed_page(
/*===========================*/
- buf_block_t* block, /* in: block, must contain a file page and
+ buf_block_t* block, /*!< in: block, must contain a file page and
be in a state where it can be freed */
ibool have_page_hash_mutex)
{
@@ -2003,7 +1985,7 @@ buf_LRU_block_free_hashed_page(
buf_LRU_block_free_non_file_page(block, have_page_hash_mutex);
}
-/************************************************************************
+/********************************************************************//**
Update the historical stats that we are collecting for LRU eviction
policy at the end of each interval. */
UNIV_INTERN
@@ -2042,8 +2024,9 @@ func_exit:
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**************************************************************************
-Validates the LRU list. */
+/**********************************************************************//**
+Validates the LRU list.
+@return TRUE */
UNIV_INTERN
ibool
buf_LRU_validate(void)
@@ -2068,7 +2051,8 @@ buf_LRU_validate(void)
ut_a(old_len <= new_len + BUF_LRU_OLD_TOLERANCE);
}
- UT_LIST_VALIDATE(LRU, buf_page_t, buf_pool->LRU);
+ UT_LIST_VALIDATE(LRU, buf_page_t, buf_pool->LRU,
+ ut_ad(ut_list_node_313->in_LRU_list));
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
@@ -2119,7 +2103,8 @@ buf_LRU_validate(void)
mutex_exit(&LRU_list_mutex);
mutex_enter(&free_list_mutex);
- UT_LIST_VALIDATE(free, buf_page_t, buf_pool->free);
+ UT_LIST_VALIDATE(free, buf_page_t, buf_pool->free,
+ ut_ad(ut_list_node_313->in_free_list));
for (bpage = UT_LIST_GET_FIRST(buf_pool->free);
bpage != NULL;
@@ -2131,7 +2116,9 @@ buf_LRU_validate(void)
mutex_exit(&free_list_mutex);
mutex_enter(&LRU_list_mutex);
- UT_LIST_VALIDATE(unzip_LRU, buf_block_t, buf_pool->unzip_LRU);
+ UT_LIST_VALIDATE(unzip_LRU, buf_block_t, buf_pool->unzip_LRU,
+ ut_ad(ut_list_node_313->in_unzip_LRU_list
+ && ut_list_node_313->page.in_LRU_list));
for (block = UT_LIST_GET_FIRST(buf_pool->unzip_LRU);
block;
@@ -2149,7 +2136,7 @@ buf_LRU_validate(void)
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Prints the LRU list. */
UNIV_INTERN
void
diff --git a/storage/xtradb/buf/buf0rea.c b/storage/xtradb/buf/buf0rea.c
index 086ea035a7b..f2dbe939c92 100644
--- a/storage/xtradb/buf/buf0rea.c
+++ b/storage/xtradb/buf/buf0rea.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file buf/buf0rea.c
The database buffer read
Created 11/5/1995 Heikki Tuuri
@@ -35,61 +36,53 @@ Created 11/5/1995 Heikki Tuuri
#include "trx0sys.h"
#include "os0file.h"
#include "srv0start.h"
+#include "srv0srv.h"
-extern ulint srv_read_ahead;
-extern ulint srv_read_ahead_rnd;
-extern ulint srv_read_ahead_seq;
-extern ulint srv_buf_pool_reads;
-
-/* The size in blocks of the area where the random read-ahead algorithm counts
+/** The size in blocks of the area where the random read-ahead algorithm counts
the accessed pages when deciding whether to read-ahead */
#define BUF_READ_AHEAD_RANDOM_AREA BUF_READ_AHEAD_AREA
-/* There must be at least this many pages in buf_pool in the area to start
+/** There must be at least this many pages in buf_pool in the area to start
a random read-ahead */
-#define BUF_READ_AHEAD_RANDOM_THRESHOLD (5 + buf_read_ahead_random_area / 8)
+#define BUF_READ_AHEAD_RANDOM_THRESHOLD (1 + BUF_READ_AHEAD_RANDOM_AREA / 2)
-/* The linear read-ahead area size */
+/** The linear read-ahead area size */
#define BUF_READ_AHEAD_LINEAR_AREA BUF_READ_AHEAD_AREA
-/* The linear read-ahead threshold */
-#define LINEAR_AREA_THRESHOLD_COEF 5 / 8
-
-/* If there are buf_pool->curr_size per the number below pending reads, then
+/** If there are buf_pool->curr_size per the number below pending reads, then
read-ahead is not done: this is to prevent flooding the buffer pool with
i/o-fixed buffer blocks */
#define BUF_READ_AHEAD_PEND_LIMIT 2
-/************************************************************************
+/********************************************************************//**
Low-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there, in which case does nothing.
Sets the io_fix flag and sets an exclusive lock on the buffer frame. The
-flag is cleared and the x-lock released by an i/o-handler thread. */
+flag is cleared and the x-lock released by an i/o-handler thread.
+@return 1 if a read request was queued, 0 if the page already resided
+in buf_pool, or if the page is in the doublewrite buffer blocks in
+which case it is never read into the pool, or if the tablespace does
+not exist or is being dropped */
static
ulint
buf_read_page_low(
/*==============*/
- /* out: 1 if a read request was queued, 0 if the page
- already resided in buf_pool, or if the page is in
- the doublewrite buffer blocks in which case it is never
- read into the pool, or if the tablespace does not
- exist or is being dropped */
- ulint* err, /* out: DB_SUCCESS or DB_TABLESPACE_DELETED if we are
+ ulint* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED if we are
trying to read from a non-existent tablespace, or a
tablespace which is just now being dropped */
- ibool sync, /* in: TRUE if synchronous aio is desired */
- ulint mode, /* in: BUF_READ_IBUF_PAGES_ONLY, ...,
+ ibool sync, /*!< in: TRUE if synchronous aio is desired */
+ ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ...,
ORed to OS_AIO_SIMULATED_WAKE_LATER (see below
at read-ahead functions) */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size, or 0 */
- ibool unzip, /* in: TRUE=request uncompressed page */
- ib_int64_t tablespace_version, /* in: if the space memory object has
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ ibool unzip, /*!< in: TRUE=request uncompressed page */
+ ib_int64_t tablespace_version, /*!< in: if the space memory object has
this timestamp different from what we are giving here,
treat the tablespace as dropped; this is a timestamp we
use to stop dangling page reads from a tablespace
which we have DISCARDed + IMPORTed back */
- ulint offset) /* in: page number */
+ ulint offset) /*!< in: page number */
{
buf_page_t* bpage;
ulint wake_later;
@@ -211,7 +204,7 @@ not_to_recover:
return(1);
}
-/************************************************************************
+/********************************************************************//**
Applies a random read-ahead in buf_pool if there are at least a threshold
value of accessed pages from the random read-ahead area. Does not read any
page, not even the one at the position (space, offset), if the read-ahead
@@ -220,18 +213,17 @@ pages: to avoid deadlocks this function must be written such that it cannot
end up waiting for these latches! NOTE 2: the calling thread must want
access to the page given: this rule is set to prevent unintended read-aheads
performed by ibuf routines, a situation which could result in a deadlock if
-the OS does not support asynchronous i/o. */
+the OS does not support asynchronous i/o.
+@return number of page read requests issued; NOTE that if we read ibuf
+pages, it may happen that the page at the given page number does not
+get read even if we return a positive value! */
static
ulint
buf_read_ahead_random(
/*==================*/
- /* out: number of page read requests issued; NOTE
- that if we read ibuf pages, it may happen that
- the page at the given page number does not get
- read even if we return a value > 0! */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint offset) /* in: page number of a page which the current thread
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint offset) /*!< in: page number of a page which the current thread
wants to access */
{
ib_int64_t tablespace_version;
@@ -244,6 +236,9 @@ buf_read_ahead_random(
ulint i;
ulint buf_read_ahead_random_area;
+// /* We have currently disabled random readahead */
+// return(0);
+
if (!(srv_read_ahead & 1)) {
return(0);
}
@@ -378,21 +373,21 @@ read_ahead:
return(count);
}
-/************************************************************************
+/********************************************************************//**
High-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
released by the i/o-handler thread. Does a random read-ahead if it seems
-sensible. */
+sensible.
+@return number of page read requests issued: this can be greater than
+1 if read-ahead occurred */
UNIV_INTERN
ulint
buf_read_page(
/*==========*/
- /* out: number of page read requests issued: this can
- be > 1 if read-ahead occurred */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint offset) /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint offset) /*!< in: page number */
{
ib_int64_t tablespace_version;
ulint count;
@@ -429,7 +424,7 @@ buf_read_page(
return(count + count2);
}
-/************************************************************************
+/********************************************************************//**
Applies linear read-ahead if in the buf_pool the page is a border page of
a linear read-ahead area and all the pages in the area have been accessed.
Does not read any page if the read-ahead mechanism is not activated. Note
@@ -451,15 +446,15 @@ function must be written such that it cannot end up waiting for these
latches!
NOTE 3: the calling thread must want access to the page given: this rule is
set to prevent unintended read-aheads performed by ibuf routines, a situation
-which could result in a deadlock if the OS does not support asynchronous io. */
+which could result in a deadlock if the OS does not support asynchronous io.
+@return number of page read requests issued */
UNIV_INTERN
ulint
buf_read_ahead_linear(
/*==================*/
- /* out: number of page read requests issued */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint offset) /* in: page number of a page; NOTE: the current thread
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint offset) /*!< in: page number of a page; NOTE: the current thread
must want access to this page (see NOTE 3 above) */
{
ib_int64_t tablespace_version;
@@ -478,11 +473,12 @@ buf_read_ahead_linear(
ulint i;
const ulint buf_read_ahead_linear_area
= BUF_READ_AHEAD_LINEAR_AREA;
+ ulint threshold;
if (!(srv_read_ahead & 2)) {
return(0);
}
-
+
if (UNIV_UNLIKELY(srv_startup_is_before_trx_rollback_phase)) {
/* No read-ahead to avoid thread deadlocks */
return(0);
@@ -545,6 +541,11 @@ buf_read_ahead_linear(
asc_or_desc = -1;
}
+ /* How many out of order accessed pages can we ignore
+ when working out the access pattern for linear readahead */
+ threshold = ut_min((64 - srv_read_ahead_threshold),
+ BUF_READ_AHEAD_AREA);
+
fail_count = 0;
rw_lock_s_lock(&page_hash_latch);
@@ -555,26 +556,26 @@ buf_read_ahead_linear(
/* Not accessed */
fail_count++;
- } else if (pred_bpage
- && (ut_ulint_cmp(
+ } else if (pred_bpage) {
+ int res = (ut_ulint_cmp(
buf_page_get_LRU_position(bpage),
- buf_page_get_LRU_position(pred_bpage))
- != asc_or_desc)) {
+ buf_page_get_LRU_position(pred_bpage)));
/* Accesses not in the right order */
-
- fail_count++;
- pred_bpage = bpage;
+ if (res != 0 && res != asc_or_desc) {
+ fail_count++;
+ }
}
- }
-
- if (fail_count > buf_read_ahead_linear_area
- * LINEAR_AREA_THRESHOLD_COEF) {
- /* Too many failures: return */
- //buf_pool_mutex_exit();
- rw_lock_s_unlock(&page_hash_latch);
+ if (fail_count > threshold) {
+ /* Too many failures: return */
+ //buf_pool_mutex_exit();
+ rw_lock_s_unlock(&page_hash_latch);
+ return(0);
+ }
- return(0);
+ if (bpage && buf_page_is_accessed(bpage)) {
+ pred_bpage = bpage;
+ }
}
/* If we got this far, we know that enough pages in the area have
@@ -708,7 +709,7 @@ buf_read_ahead_linear(
return(count);
}
-/************************************************************************
+/********************************************************************//**
Issues read requests for pages which the ibuf module wants to read in, in
order to contract the insert buffer tree. Technically, this function is like
a read-ahead function. */
@@ -716,24 +717,24 @@ UNIV_INTERN
void
buf_read_ibuf_merge_pages(
/*======================*/
- ibool sync, /* in: TRUE if the caller
+ ibool sync, /*!< in: TRUE if the caller
wants this function to wait
for the highest address page
to get read in, before this
function returns */
- const ulint* space_ids, /* in: array of space ids */
- const ib_int64_t* space_versions,/* in: the spaces must have
+ const ulint* space_ids, /*!< in: array of space ids */
+ const ib_int64_t* space_versions,/*!< in: the spaces must have
this version number
(timestamp), otherwise we
discard the read; we use this
to cancel reads if DISCARD +
IMPORT may have changed the
tablespace size */
- const ulint* page_nos, /* in: array of page numbers
+ const ulint* page_nos, /*!< in: array of page numbers
to read, with the highest page
number the last in the
array */
- ulint n_stored) /* in: number of elements
+ ulint n_stored) /*!< in: number of elements
in the arrays */
{
ulint i;
@@ -786,25 +787,25 @@ tablespace_deleted:
#endif /* UNIV_DEBUG */
}
-/************************************************************************
+/********************************************************************//**
Issues read requests for pages which recovery wants to read in. */
UNIV_INTERN
void
buf_read_recv_pages(
/*================*/
- ibool sync, /* in: TRUE if the caller
+ ibool sync, /*!< in: TRUE if the caller
wants this function to wait
for the highest address page
to get read in, before this
function returns */
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in
bytes, or 0 */
- const ulint* page_nos, /* in: array of page numbers
+ const ulint* page_nos, /*!< in: array of page numbers
to read, with the highest page
number the last in the
array */
- ulint n_stored) /* in: number of page numbers
+ ulint n_stored) /*!< in: number of page numbers
in the array */
{
ib_int64_t tablespace_version;
@@ -813,6 +814,14 @@ buf_read_recv_pages(
ulint i;
zip_size = fil_space_get_zip_size(space);
+
+ if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
+ /* It is a single table tablespace and the .ibd file is
+ missing: do nothing */
+
+ return;
+ }
+
tablespace_version = fil_space_get_version(space);
for (i = 0; i < n_stored; i++) {
diff --git a/storage/xtradb/data/data0data.c b/storage/xtradb/data/data0data.c
index 1cb3803b187..e3c1f1b4f23 100644
--- a/storage/xtradb/data/data0data.c
+++ b/storage/xtradb/data/data0data.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file data/data0data.c
SQL data field and tuple
Created 5/30/1994 Heikki Tuuri
@@ -28,6 +29,7 @@ Created 5/30/1994 Heikki Tuuri
#include "data0data.ic"
#endif
+#ifndef UNIV_HOTBACKUP
#include "rem0rec.h"
#include "rem0cmp.h"
#include "page0page.h"
@@ -36,28 +38,31 @@ Created 5/30/1994 Heikki Tuuri
#include "btr0cur.h"
#include <ctype.h>
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
-/* data pointers of tuple fields are initialized to point here
-for error checking */
+/** Dummy variable to catch access to uninitialized fields. In the
+debug version, dtuple_create() will make all fields of dtuple_t point
+to data_error. */
UNIV_INTERN byte data_error;
# ifndef UNIV_DEBUG_VALGRIND
-/* this is used to fool the compiler in dtuple_validate */
+/** this is used to fool the compiler in dtuple_validate */
UNIV_INTERN ulint data_dummy;
# endif /* !UNIV_DEBUG_VALGRIND */
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Tests if dfield data length and content is equal to the given. */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
+Tests if dfield data length and content is equal to the given.
+@return TRUE if equal */
UNIV_INTERN
ibool
dfield_data_is_binary_equal(
/*========================*/
- /* out: TRUE if equal */
- const dfield_t* field, /* in: field */
- ulint len, /* in: data length or UNIV_SQL_NULL */
- const byte* data) /* in: data */
+ const dfield_t* field, /*!< in: field */
+ ulint len, /*!< in: data length or UNIV_SQL_NULL */
+ const byte* data) /*!< in: data */
{
if (len != dfield_get_len(field)) {
@@ -77,16 +82,16 @@ dfield_data_is_binary_equal(
return(TRUE);
}
-/****************************************************************
-Compare two data tuples, respecting the collation of character fields. */
+/************************************************************//**
+Compare two data tuples, respecting the collation of character fields.
+@return 1, 0 , -1 if tuple1 is greater, equal, less, respectively,
+than tuple2 */
UNIV_INTERN
int
dtuple_coll_cmp(
/*============*/
- /* out: 1, 0 , -1 if tuple1 is greater, equal,
- less, respectively, than tuple2 */
- const dtuple_t* tuple1, /* in: tuple 1 */
- const dtuple_t* tuple2) /* in: tuple 2 */
+ const dtuple_t* tuple1, /*!< in: tuple 1 */
+ const dtuple_t* tuple2) /*!< in: tuple 2 */
{
ulint n_fields;
ulint i;
@@ -119,15 +124,15 @@ dtuple_coll_cmp(
return(0);
}
-/*************************************************************************
+/*********************************************************************//**
Sets number of fields used in a tuple. Normally this is set in
dtuple_create, but if you want later to set it smaller, you can use this. */
UNIV_INTERN
void
dtuple_set_n_fields(
/*================*/
- dtuple_t* tuple, /* in: tuple */
- ulint n_fields) /* in: number of fields */
+ dtuple_t* tuple, /*!< in: tuple */
+ ulint n_fields) /*!< in: number of fields */
{
ut_ad(tuple);
@@ -135,14 +140,14 @@ dtuple_set_n_fields(
tuple->n_fields_cmp = n_fields;
}
-/**************************************************************
-Checks that a data field is typed. */
+/**********************************************************//**
+Checks that a data field is typed.
+@return TRUE if ok */
static
ibool
dfield_check_typed_no_assert(
/*=========================*/
- /* out: TRUE if ok */
- const dfield_t* field) /* in: data field */
+ const dfield_t* field) /*!< in: data field */
{
if (dfield_get_type(field)->mtype > DATA_MYSQL
|| dfield_get_type(field)->mtype < DATA_VARCHAR) {
@@ -157,14 +162,14 @@ dfield_check_typed_no_assert(
return(TRUE);
}
-/**************************************************************
-Checks that a data tuple is typed. */
+/**********************************************************//**
+Checks that a data tuple is typed.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_check_typed_no_assert(
/*=========================*/
- /* out: TRUE if ok */
- const dtuple_t* tuple) /* in: tuple */
+ const dtuple_t* tuple) /*!< in: tuple */
{
const dfield_t* field;
ulint i;
@@ -192,15 +197,17 @@ dump:
return(TRUE);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************
-Checks that a data field is typed. Asserts an error if not. */
+#ifdef UNIV_DEBUG
+/**********************************************************//**
+Checks that a data field is typed. Asserts an error if not.
+@return TRUE if ok */
UNIV_INTERN
ibool
dfield_check_typed(
/*===============*/
- /* out: TRUE if ok */
- const dfield_t* field) /* in: data field */
+ const dfield_t* field) /*!< in: data field */
{
if (dfield_get_type(field)->mtype > DATA_MYSQL
|| dfield_get_type(field)->mtype < DATA_VARCHAR) {
@@ -216,14 +223,14 @@ dfield_check_typed(
return(TRUE);
}
-/**************************************************************
-Checks that a data tuple is typed. Asserts an error if not. */
+/**********************************************************//**
+Checks that a data tuple is typed. Asserts an error if not.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_check_typed(
/*===============*/
- /* out: TRUE if ok */
- const dtuple_t* tuple) /* in: tuple */
+ const dtuple_t* tuple) /*!< in: tuple */
{
const dfield_t* field;
ulint i;
@@ -238,16 +245,15 @@ dtuple_check_typed(
return(TRUE);
}
-#ifdef UNIV_DEBUG
-/**************************************************************
+/**********************************************************//**
Validates the consistency of a tuple which must be complete, i.e,
-all fields must have been set. */
+all fields must have been set.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_validate(
/*============*/
- /* out: TRUE if ok */
- const dtuple_t* tuple) /* in: tuple */
+ const dtuple_t* tuple) /*!< in: tuple */
{
const dfield_t* field;
ulint n_fields;
@@ -291,13 +297,14 @@ dtuple_validate(
}
#endif /* UNIV_DEBUG */
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Pretty prints a dfield value according to its data type. */
UNIV_INTERN
void
dfield_print(
/*=========*/
- const dfield_t* dfield) /* in: dfield */
+ const dfield_t* dfield) /*!< in: dfield */
{
const byte* data;
ulint len;
@@ -333,14 +340,14 @@ dfield_print(
}
}
-/*****************************************************************
+/*************************************************************//**
Pretty prints a dfield value according to its data type. Also the hex string
is printed if a string contains non-printable characters. */
UNIV_INTERN
void
dfield_print_also_hex(
/*==================*/
- const dfield_t* dfield) /* in: dfield */
+ const dfield_t* dfield) /*!< in: dfield */
{
const byte* data;
ulint len;
@@ -505,14 +512,14 @@ print_hex:
}
}
-/*****************************************************************
+/*************************************************************//**
Print a dfield value using ut_print_buf. */
static
void
dfield_print_raw(
/*=============*/
- FILE* f, /* in: output stream */
- const dfield_t* dfield) /* in: dfield */
+ FILE* f, /*!< in: output stream */
+ const dfield_t* dfield) /*!< in: dfield */
{
ulint len = dfield_get_len(dfield);
if (!dfield_is_null(dfield)) {
@@ -528,14 +535,14 @@ dfield_print_raw(
}
}
-/**************************************************************
+/**********************************************************//**
The following function prints the contents of a tuple. */
UNIV_INTERN
void
dtuple_print(
/*=========*/
- FILE* f, /* in: output stream */
- const dtuple_t* tuple) /* in: tuple */
+ FILE* f, /*!< in: output stream */
+ const dtuple_t* tuple) /*!< in: tuple */
{
ulint n_fields;
ulint i;
@@ -556,23 +563,21 @@ dtuple_print(
ut_ad(dtuple_validate(tuple));
}
-/******************************************************************
+/**************************************************************//**
Moves parts of long fields in entry to the big record vector so that
the size of tuple drops below the maximum record size allowed in the
database. Moves data only from those fields which are not necessary
-to determine uniquely the insertion place of the tuple in the index. */
+to determine uniquely the insertion place of the tuple in the index.
+@return own: created big record vector, NULL if we are not able to
+shorten the entry enough, i.e., if there are too many fixed-length or
+short fields in entry or the index is clustered */
UNIV_INTERN
big_rec_t*
dtuple_convert_big_rec(
/*===================*/
- /* out, own: created big record vector,
- NULL if we are not able to shorten
- the entry enough, i.e., if there are
- too many fixed-length or short fields
- in entry or the index is clustered */
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in/out: index entry */
- ulint* n_ext) /* in/out: number of
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in/out: index entry */
+ ulint* n_ext) /*!< in/out: number of
externally stored columns */
{
mem_heap_t* heap;
@@ -719,7 +724,7 @@ skip_field:
return(vector);
}
-/******************************************************************
+/**************************************************************//**
Puts back to entry the data stored in vector. Note that to ensure the
fields in entry can accommodate the data, vector must have been created
from entry with dtuple_convert_big_rec. */
@@ -727,9 +732,9 @@ UNIV_INTERN
void
dtuple_convert_back_big_rec(
/*========================*/
- dict_index_t* index __attribute__((unused)), /* in: index */
- dtuple_t* entry, /* in: entry whose data was put to vector */
- big_rec_t* vector) /* in, own: big rec vector; it is
+ dict_index_t* index __attribute__((unused)), /*!< in: index */
+ dtuple_t* entry, /*!< in: entry whose data was put to vector */
+ big_rec_t* vector) /*!< in, own: big rec vector; it is
freed in this function */
{
big_rec_field_t* b = vector->fields;
@@ -756,3 +761,4 @@ dtuple_convert_back_big_rec(
mem_heap_free(vector->heap);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/data/data0type.c b/storage/xtradb/data/data0type.c
index 5df933ef9fd..8429775e7d8 100644
--- a/storage/xtradb/data/data0type.c
+++ b/storage/xtradb/data/data0type.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file data/data0type.c
Data types
Created 1/16/1996 Heikki Tuuri
@@ -28,26 +29,8 @@ Created 1/16/1996 Heikki Tuuri
#include "data0type.ic"
#endif
-/**********************************************************************
-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
-finds charset information and returns length of prefix_len characters in the
-index field in bytes.
-
-NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
-this function, you MUST change also the prototype here! */
-UNIV_INTERN
-ulint
-innobase_get_at_most_n_mbchars(
-/*===========================*/
- /* out: number of bytes occupied by the first
- n characters */
- ulint charset_id, /* in: character set id */
- ulint prefix_len, /* in: prefix length in bytes of the index
- (this has to be divided by mbmaxlen to get the
- number of CHARACTERS n in the prefix) */
- ulint data_len, /* in: length of the string in bytes */
- const char* str); /* in: character string */
+#ifndef UNIV_HOTBACKUP
+# include "ha_prototypes.h"
/* At the database startup we store the default-charset collation number of
this MySQL installation to this global variable. If we have < 4.1.2 format
@@ -56,29 +39,27 @@ charset-collation code for them. */
UNIV_INTERN ulint data_mysql_default_charset_coll;
-/*************************************************************************
+/*********************************************************************//**
Determine how many bytes the first n characters of the given string occupy.
If the string is shorter than n characters, returns the number of bytes
-the characters in the string occupy. */
+the characters in the string occupy.
+@return length of the prefix, in bytes */
UNIV_INTERN
ulint
dtype_get_at_most_n_mbchars(
/*========================*/
- /* out: length of the prefix,
- in bytes */
- ulint prtype, /* in: precise type */
- ulint mbminlen, /* in: minimum length of a
+ ulint prtype, /*!< in: precise type */
+ ulint mbminlen, /*!< in: minimum length of a
multi-byte character */
- ulint mbmaxlen, /* in: maximum length of a
+ ulint mbmaxlen, /*!< in: maximum length of a
multi-byte character */
- ulint prefix_len, /* in: length of the requested
+ ulint prefix_len, /*!< in: length of the requested
prefix, in characters, multiplied by
dtype_get_mbmaxlen(dtype) */
- ulint data_len, /* in: length of str (in bytes) */
- const char* str) /* in: the string whose prefix
+ ulint data_len, /*!< in: length of str (in bytes) */
+ const char* str) /*!< in: the string whose prefix
length is being determined */
{
-#ifndef UNIV_HOTBACKUP
ut_a(data_len != UNIV_SQL_NULL);
ut_ad(!mbmaxlen || !(prefix_len % mbmaxlen));
@@ -96,23 +77,18 @@ dtype_get_at_most_n_mbchars(
}
return(data_len);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
-#endif /* UNIV_HOTBACKUP */
}
+#endif /* UNIV_HOTBACKUP */
-/*************************************************************************
+/*********************************************************************//**
Checks if a data main type is a string type. Also a BLOB is considered a
-string type. */
+string type.
+@return TRUE if string type */
UNIV_INTERN
ibool
dtype_is_string_type(
/*=================*/
- /* out: TRUE if string type */
- ulint mtype) /* in: InnoDB main data type code: DATA_CHAR, ... */
+ ulint mtype) /*!< in: InnoDB main data type code: DATA_CHAR, ... */
{
if (mtype <= DATA_BLOB
|| mtype == DATA_MYSQL
@@ -124,17 +100,17 @@ dtype_is_string_type(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if a type is a binary string type. Note that for tables created with
< 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For
-those DATA_BLOB columns this function currently returns FALSE. */
+those DATA_BLOB columns this function currently returns FALSE.
+@return TRUE if binary string type */
UNIV_INTERN
ibool
dtype_is_binary_string_type(
/*========================*/
- /* out: TRUE if binary string type */
- ulint mtype, /* in: main data type */
- ulint prtype) /* in: precise type */
+ ulint mtype, /*!< in: main data type */
+ ulint prtype) /*!< in: precise type */
{
if ((mtype == DATA_FIXBINARY)
|| (mtype == DATA_BINARY)
@@ -146,18 +122,18 @@ dtype_is_binary_string_type(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if a type is a non-binary string type. That is, dtype_is_string_type is
TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created
with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
-For those DATA_BLOB columns this function currently returns TRUE. */
+For those DATA_BLOB columns this function currently returns TRUE.
+@return TRUE if non-binary string type */
UNIV_INTERN
ibool
dtype_is_non_binary_string_type(
/*============================*/
- /* out: TRUE if non-binary string type */
- ulint mtype, /* in: main data type */
- ulint prtype) /* in: precise type */
+ ulint mtype, /*!< in: main data type */
+ ulint prtype) /*!< in: precise type */
{
if (dtype_is_string_type(mtype) == TRUE
&& dtype_is_binary_string_type(mtype, prtype) == FALSE) {
@@ -168,16 +144,17 @@ dtype_is_non_binary_string_type(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Forms a precise type from the < 4.1.2 format precise type plus the
-charset-collation code. */
+charset-collation code.
+@return precise type, including the charset-collation code */
UNIV_INTERN
ulint
dtype_form_prtype(
/*==============*/
- ulint old_prtype, /* in: the MySQL type code and the flags
+ ulint old_prtype, /*!< in: the MySQL type code and the flags
DATA_BINARY_TYPE etc. */
- ulint charset_coll) /* in: MySQL charset-collation code */
+ ulint charset_coll) /*!< in: MySQL charset-collation code */
{
ut_a(old_prtype < 256 * 256);
ut_a(charset_coll < 256);
@@ -185,14 +162,14 @@ dtype_form_prtype(
return(old_prtype + (charset_coll << 16));
}
-/*************************************************************************
-Validates a data type structure. */
+/*********************************************************************//**
+Validates a data type structure.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtype_validate(
/*===========*/
- /* out: TRUE if ok */
- const dtype_t* type) /* in: type struct to validate */
+ const dtype_t* type) /*!< in: type struct to validate */
{
ut_a(type);
ut_a(type->mtype >= DATA_VARCHAR);
@@ -202,18 +179,21 @@ dtype_validate(
ut_a((type->prtype & DATA_MYSQL_TYPE_MASK) < DATA_N_SYS_COLS);
}
+#ifndef UNIV_HOTBACKUP
ut_a(type->mbminlen <= type->mbmaxlen);
+#endif /* !UNIV_HOTBACKUP */
return(TRUE);
}
-/*************************************************************************
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
Prints a data type structure. */
UNIV_INTERN
void
dtype_print(
/*========*/
- const dtype_t* type) /* in: type */
+ const dtype_t* type) /*!< in: type */
{
ulint mtype;
ulint prtype;
@@ -298,3 +278,4 @@ dtype_print(
fprintf(stderr, " len %lu", (ulong) len);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/dict/dict0boot.c b/storage/xtradb/dict/dict0boot.c
index cd90016dd78..0eb73e6c2f9 100644
--- a/storage/xtradb/dict/dict0boot.c
+++ b/storage/xtradb/dict/dict0boot.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file dict/dict0boot.c
Data dictionary creation and booting
Created 4/18/1996 Heikki Tuuri
@@ -39,15 +40,14 @@ Created 4/18/1996 Heikki Tuuri
#include "log0recv.h"
#include "os0file.h"
-/**************************************************************************
-Gets a pointer to the dictionary header and x-latches its page. */
+/**********************************************************************//**
+Gets a pointer to the dictionary header and x-latches its page.
+@return pointer to the dictionary header, page x-latched */
UNIV_INTERN
dict_hdr_t*
dict_hdr_get(
/*=========*/
- /* out: pointer to the dictionary header,
- page x-latched */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
dict_hdr_t* header;
@@ -61,14 +61,14 @@ dict_hdr_get(
return(header);
}
-/**************************************************************************
-Returns a new table, index, or tree id. */
+/**********************************************************************//**
+Returns a new table, index, or tree id.
+@return the new id */
UNIV_INTERN
dulint
dict_hdr_get_new_id(
/*================*/
- /* out: the new id */
- ulint type) /* in: DICT_HDR_ROW_ID, ... */
+ ulint type) /*!< in: DICT_HDR_ROW_ID, ... */
{
dict_hdr_t* dict_hdr;
dulint id;
@@ -90,7 +90,7 @@ dict_hdr_get_new_id(
return(id);
}
-/**************************************************************************
+/**********************************************************************//**
Writes the current value of the row id counter to the dictionary header file
page. */
UNIV_INTERN
@@ -115,15 +115,15 @@ dict_hdr_flush_row_id(void)
mtr_commit(&mtr);
}
-/*********************************************************************
+/*****************************************************************//**
Creates the file page for the dictionary header. This function is
-called only at the database creation. */
+called only at the database creation.
+@return TRUE if succeed */
static
ibool
dict_hdr_create(
/*============*/
- /* out: TRUE if succeed */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
dict_hdr_t* dict_header;
@@ -161,7 +161,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, 0, DICT_TABLES_ID,
- srv_sys->dummy_ind1, mtr);
+ dict_ind_redundant, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
@@ -172,7 +172,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_UNIQUE, DICT_HDR_SPACE, 0,
DICT_TABLE_IDS_ID,
- srv_sys->dummy_ind1, mtr);
+ dict_ind_redundant, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
@@ -183,7 +183,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, 0, DICT_COLUMNS_ID,
- srv_sys->dummy_ind1, mtr);
+ dict_ind_redundant, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
@@ -194,7 +194,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, 0, DICT_INDEXES_ID,
- srv_sys->dummy_ind1, mtr);
+ dict_ind_redundant, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
@@ -205,7 +205,7 @@ dict_hdr_create(
/*--------------------------*/
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
DICT_HDR_SPACE, 0, DICT_FIELDS_ID,
- srv_sys->dummy_ind1, mtr);
+ dict_ind_redundant, mtr);
if (root_page_no == FIL_NULL) {
return(FALSE);
@@ -218,7 +218,7 @@ dict_hdr_create(
return(TRUE);
}
-/*********************************************************************
+/*****************************************************************//**
Initializes the data dictionary memory structures when the database is
started. This function is also called when the data dictionary is created. */
UNIV_INTERN
@@ -434,7 +434,7 @@ dict_boot(void)
mutex_exit(&(dict_sys->mutex));
}
-/*********************************************************************
+/*****************************************************************//**
Inserts the basic system table data into themselves in the database
creation. */
static
@@ -445,7 +445,7 @@ dict_insert_initial_data(void)
/* Does nothing yet */
}
-/*********************************************************************
+/*****************************************************************//**
Creates and initializes the data dictionary at the database creation. */
UNIV_INTERN
void
diff --git a/storage/xtradb/dict/dict0crea.c b/storage/xtradb/dict/dict0crea.c
index 01d092005c3..10e3ff409f3 100644
--- a/storage/xtradb/dict/dict0crea.c
+++ b/storage/xtradb/dict/dict0crea.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file dict/dict0crea.c
Database object creation
Created 1/8/1996 Heikki Tuuri
@@ -42,16 +43,16 @@ Created 1/8/1996 Heikki Tuuri
#include "usr0sess.h"
#include "ut0vec.h"
-/*********************************************************************
+/*****************************************************************//**
Based on a table object, this function builds the entry to be inserted
-in the SYS_TABLES system table. */
+in the SYS_TABLES system table.
+@return the tuple which should be inserted */
static
dtuple_t*
dict_create_sys_tables_tuple(
/*=========================*/
- /* out: the tuple which should be inserted */
- dict_table_t* table, /* in: table */
- mem_heap_t* heap) /* in: memory heap from which the memory for
+ dict_table_t* table, /*!< in: table */
+ mem_heap_t* heap) /*!< in: memory heap from which the memory for
the built tuple is allocated */
{
dict_table_t* sys_tables;
@@ -134,17 +135,17 @@ dict_create_sys_tables_tuple(
return(entry);
}
-/*********************************************************************
+/*****************************************************************//**
Based on a table object, this function builds the entry to be inserted
-in the SYS_COLUMNS system table. */
+in the SYS_COLUMNS system table.
+@return the tuple which should be inserted */
static
dtuple_t*
dict_create_sys_columns_tuple(
/*==========================*/
- /* out: the tuple which should be inserted */
- dict_table_t* table, /* in: table */
- ulint i, /* in: column number */
- mem_heap_t* heap) /* in: memory heap from which the memory for
+ dict_table_t* table, /*!< in: table */
+ ulint i, /*!< in: column number */
+ mem_heap_t* heap) /*!< in: memory heap from which the memory for
the built tuple is allocated */
{
dict_table_t* sys_columns;
@@ -216,15 +217,15 @@ dict_create_sys_columns_tuple(
return(entry);
}
-/*******************************************************************
-Builds a table definition to insert. */
+/***************************************************************//**
+Builds a table definition to insert.
+@return DB_SUCCESS or error code */
static
ulint
dict_build_table_def_step(
/*======================*/
- /* out: DB_SUCCESS or error code */
- que_thr_t* thr, /* in: query thread */
- tab_node_t* node) /* in: table create node */
+ que_thr_t* thr, /*!< in: query thread */
+ tab_node_t* node) /*!< in: table create node */
{
dict_table_t* table;
dtuple_t* row;
@@ -295,14 +296,14 @@ dict_build_table_def_step(
return(DB_SUCCESS);
}
-/*******************************************************************
-Builds a column definition to insert. */
+/***************************************************************//**
+Builds a column definition to insert.
+@return DB_SUCCESS */
static
ulint
dict_build_col_def_step(
/*====================*/
- /* out: DB_SUCCESS */
- tab_node_t* node) /* in: table create node */
+ tab_node_t* node) /*!< in: table create node */
{
dtuple_t* row;
@@ -313,16 +314,16 @@ dict_build_col_def_step(
return(DB_SUCCESS);
}
-/*********************************************************************
+/*****************************************************************//**
Based on an index object, this function builds the entry to be inserted
-in the SYS_INDEXES system table. */
+in the SYS_INDEXES system table.
+@return the tuple which should be inserted */
static
dtuple_t*
dict_create_sys_indexes_tuple(
/*==========================*/
- /* out: the tuple which should be inserted */
- dict_index_t* index, /* in: index */
- mem_heap_t* heap) /* in: memory heap from which the memory for
+ dict_index_t* index, /*!< in: index */
+ mem_heap_t* heap) /*!< in: memory heap from which the memory for
the built tuple is allocated */
{
dict_table_t* sys_indexes;
@@ -403,17 +404,17 @@ dict_create_sys_indexes_tuple(
return(entry);
}
-/*********************************************************************
+/*****************************************************************//**
Based on an index object, this function builds the entry to be inserted
-in the SYS_FIELDS system table. */
+in the SYS_FIELDS system table.
+@return the tuple which should be inserted */
static
dtuple_t*
dict_create_sys_fields_tuple(
/*=========================*/
- /* out: the tuple which should be inserted */
- dict_index_t* index, /* in: index */
- ulint i, /* in: field number */
- mem_heap_t* heap) /* in: memory heap from which the memory for
+ dict_index_t* index, /*!< in: index */
+ ulint i, /*!< in: field number */
+ mem_heap_t* heap) /*!< in: memory heap from which the memory for
the built tuple is allocated */
{
dict_table_t* sys_fields;
@@ -479,17 +480,17 @@ dict_create_sys_fields_tuple(
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. */
+tree root page number, if such a tree is created.
+@return the tuple for search */
static
dtuple_t*
dict_create_search_tuple(
/*=====================*/
- /* out: the tuple for search */
- const dtuple_t* tuple, /* in: the tuple inserted in the SYS_INDEXES
+ const dtuple_t* tuple, /*!< in: the tuple inserted in the SYS_INDEXES
table */
- mem_heap_t* heap) /* in: memory heap from which the memory for
+ mem_heap_t* heap) /*!< in: memory heap from which the memory for
the built tuple is allocated */
{
dtuple_t* search_tuple;
@@ -515,15 +516,15 @@ dict_create_search_tuple(
return(search_tuple);
}
-/*******************************************************************
-Builds an index definition row to insert. */
+/***************************************************************//**
+Builds an index definition row to insert.
+@return DB_SUCCESS or error code */
static
ulint
dict_build_index_def_step(
/*======================*/
- /* out: DB_SUCCESS or error code */
- que_thr_t* thr, /* in: query thread */
- ind_node_t* node) /* in: index create node */
+ que_thr_t* thr, /*!< in: query thread */
+ ind_node_t* node) /*!< in: index create node */
{
dict_table_t* table;
dict_index_t* index;
@@ -561,22 +562,20 @@ dict_build_index_def_step(
ins_node_set_new_row(node->ind_def, row);
-#ifdef ROW_MERGE_IS_INDEX_USABLE
/* Note that the index was created by this transaction. */
- index->trx_id = trx->id;
-#endif /* ROW_MERGE_IS_INDEX_USABLE */
+ index->trx_id = (ib_uint64_t) ut_conv_dulint_to_longlong(trx->id);
return(DB_SUCCESS);
}
-/*******************************************************************
-Builds a field definition row to insert. */
+/***************************************************************//**
+Builds a field definition row to insert.
+@return DB_SUCCESS */
static
ulint
dict_build_field_def_step(
/*======================*/
- /* out: DB_SUCCESS */
- ind_node_t* node) /* in: index create node */
+ ind_node_t* node) /*!< in: index create node */
{
dict_index_t* index;
dtuple_t* row;
@@ -590,14 +589,14 @@ dict_build_field_def_step(
return(DB_SUCCESS);
}
-/*******************************************************************
-Creates an index tree for the index if it is not a member of a cluster. */
+/***************************************************************//**
+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
ulint
dict_create_index_tree_step(
/*========================*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- ind_node_t* node) /* in: index create node */
+ ind_node_t* node) /*!< in: index create node */
{
dict_index_t* index;
dict_table_t* sys_indexes;
@@ -647,15 +646,15 @@ dict_create_index_tree_step(
return(DB_SUCCESS);
}
-/***********************************************************************
+/*******************************************************************//**
Drops the index tree associated with a row in SYS_INDEXES table. */
UNIV_INTERN
void
dict_drop_index_tree(
/*=================*/
- rec_t* rec, /* in/out: record in the clustered index
+ rec_t* rec, /*!< in/out: record in the clustered index
of SYS_INDEXES table */
- mtr_t* mtr) /* in: mtr having the latch on the record page */
+ mtr_t* mtr) /*!< in: mtr having the latch on the record page */
{
ulint root_page_no;
ulint space;
@@ -710,23 +709,22 @@ dict_drop_index_tree(
FIL_NULL, mtr);
}
-/***********************************************************************
-Truncates the index tree associated with a row in SYS_INDEXES table. */
+/*******************************************************************//**
+Truncates the index tree associated with a row in SYS_INDEXES table.
+@return new root page number, or FIL_NULL on failure */
UNIV_INTERN
ulint
dict_truncate_index_tree(
/*=====================*/
- /* out: new root page number, or
- FIL_NULL on failure */
- dict_table_t* table, /* in: the table the index belongs to */
- ulint space, /* in: 0=truncate,
+ dict_table_t* table, /*!< in: the table the index belongs to */
+ ulint space, /*!< in: 0=truncate,
nonzero=create the index tree in the
given tablespace */
- btr_pcur_t* pcur, /* in/out: persistent cursor pointing to
+ btr_pcur_t* pcur, /*!< in/out: persistent cursor pointing to
record in the clustered index of
SYS_INDEXES table. The cursor may be
repositioned in this call. */
- mtr_t* mtr) /* in: mtr having the latch
+ mtr_t* mtr) /*!< in: mtr having the latch
on the record page. The mtr may be
committed and restarted in this call. */
{
@@ -846,16 +844,16 @@ create:
return(FIL_NULL);
}
-/*************************************************************************
-Creates a table create graph. */
+/*********************************************************************//**
+Creates a table create graph.
+@return own: table create node */
UNIV_INTERN
tab_node_t*
tab_create_graph_create(
/*====================*/
- /* out, own: table create node */
- dict_table_t* table, /* in: table to create, built as a memory data
+ dict_table_t* table, /*!< in: table to create, built as a memory data
structure */
- mem_heap_t* heap) /* in: heap where created */
+ mem_heap_t* heap) /*!< in: heap where created */
{
tab_node_t* node;
@@ -882,16 +880,16 @@ tab_create_graph_create(
return(node);
}
-/*************************************************************************
-Creates an index create graph. */
+/*********************************************************************//**
+Creates an index create graph.
+@return own: index create node */
UNIV_INTERN
ind_node_t*
ind_create_graph_create(
/*====================*/
- /* out, own: index create node */
- dict_index_t* index, /* in: index to create, built as a memory data
+ dict_index_t* index, /*!< in: index to create, built as a memory data
structure */
- mem_heap_t* heap) /* in: heap where created */
+ mem_heap_t* heap) /*!< in: heap where created */
{
ind_node_t* node;
@@ -919,14 +917,14 @@ ind_create_graph_create(
return(node);
}
-/***************************************************************
-Creates a table. This is a high-level function used in SQL execution graphs. */
+/***********************************************************//**
+Creates a table. This is a high-level function used in SQL execution graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
dict_create_table_step(
/*===================*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
tab_node_t* node;
ulint err = DB_ERROR;
@@ -1025,15 +1023,15 @@ function_exit:
return(thr);
}
-/***************************************************************
+/***********************************************************//**
Creates an index. This is a high-level function used in SQL execution
-graphs. */
+graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
dict_create_index_step(
/*===================*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ind_node_t* node;
ulint err = DB_ERROR;
@@ -1156,16 +1154,15 @@ function_exit:
return(thr);
}
-#ifndef UNIV_HOTBACKUP
-/********************************************************************
+/****************************************************************//**
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. */
+not of the right form.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_create_or_check_foreign_constraint_tables(void)
/*================================================*/
- /* out: DB_SUCCESS or error code */
{
dict_table_t* table1;
dict_table_t* table2;
@@ -1286,18 +1283,18 @@ dict_create_or_check_foreign_constraint_tables(void)
return(error);
}
-/********************************************************************
-Evaluate the given foreign key SQL statement. */
+/****************************************************************//**
+Evaluate the given foreign key SQL statement.
+@return error code or DB_SUCCESS */
static
ulint
dict_foreign_eval_sql(
/*==================*/
- /* out: error code or DB_SUCCESS */
- pars_info_t* info, /* in: info struct, or NULL */
- const char* sql, /* in: SQL string to evaluate */
- dict_table_t* table, /* in: table */
- dict_foreign_t* foreign,/* in: foreign */
- trx_t* trx) /* in: transaction */
+ pars_info_t* info, /*!< in: info struct, or NULL */
+ const char* sql, /*!< in: SQL string to evaluate */
+ dict_table_t* table, /*!< in: table */
+ dict_foreign_t* foreign,/*!< in: foreign */
+ trx_t* trx) /*!< in: transaction */
{
ulint error;
FILE* ef = dict_foreign_err_file;
@@ -1351,18 +1348,18 @@ dict_foreign_eval_sql(
return(DB_SUCCESS);
}
-/************************************************************************
+/********************************************************************//**
Add a single foreign key field definition to the data dictionary tables in
-the database. */
+the database.
+@return error code or DB_SUCCESS */
static
ulint
dict_create_add_foreign_field_to_dictionary(
/*========================================*/
- /* out: error code or DB_SUCCESS */
- ulint field_nr, /* in: foreign field number */
- dict_table_t* table, /* in: table */
- dict_foreign_t* foreign, /* in: foreign */
- trx_t* trx) /* in: transaction */
+ ulint field_nr, /*!< in: foreign field number */
+ dict_table_t* table, /*!< in: table */
+ dict_foreign_t* foreign, /*!< in: foreign */
+ trx_t* trx) /*!< in: transaction */
{
pars_info_t* info = pars_info_create();
@@ -1386,23 +1383,23 @@ dict_create_add_foreign_field_to_dictionary(
table, foreign, trx));
}
-/************************************************************************
+/********************************************************************//**
Add a single foreign key definition to the data dictionary tables in the
database. We also generate names to constraints that were not named by the
user. A generated constraint has a name of the format
databasename/tablename_ibfk_<number>, where the numbers start from 1, and
are given locally for this table, that is, the number is not global, as in
-the old format constraints < 4.0.18 it used to be. */
+the old format constraints < 4.0.18 it used to be.
+@return error code or DB_SUCCESS */
static
ulint
dict_create_add_foreign_to_dictionary(
/*==================================*/
- /* out: error code or DB_SUCCESS */
- ulint* id_nr, /* in/out: number to use in id generation;
+ ulint* id_nr, /*!< in/out: number to use in id generation;
incremented if used */
- dict_table_t* table, /* in: table */
- dict_foreign_t* foreign,/* in: foreign */
- trx_t* trx) /* in: transaction */
+ dict_table_t* table, /*!< in: table */
+ dict_foreign_t* foreign,/*!< in: foreign */
+ trx_t* trx) /*!< in: transaction */
{
ulint error;
ulint i;
@@ -1461,14 +1458,14 @@ dict_create_add_foreign_to_dictionary(
return(error);
}
-/************************************************************************
-Adds foreign key definitions to data dictionary tables in the database. */
+/********************************************************************//**
+Adds foreign key definitions to data dictionary tables in the database.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
dict_create_add_foreigns_to_dictionary(
/*===================================*/
- /* out: error code or DB_SUCCESS */
- ulint start_id,/* in: if we are actually doing ALTER TABLE
+ ulint start_id,/*!< in: if we are actually doing ALTER TABLE
ADD CONSTRAINT, we want to generate constraint
numbers which are bigger than in the table so
far; we number the constraints from
@@ -1476,8 +1473,8 @@ dict_create_add_foreigns_to_dictionary(
we are creating a new table, or if the table
so far has no constraints for which the name
was generated here */
- dict_table_t* table, /* in: table */
- trx_t* trx) /* in: transaction */
+ dict_table_t* table, /*!< in: table */
+ trx_t* trx) /*!< in: transaction */
{
dict_foreign_t* foreign;
ulint number = start_id + 1;
@@ -1508,4 +1505,3 @@ dict_create_add_foreigns_to_dictionary(
return(DB_SUCCESS);
}
-#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c
index 68fa5fccf64..050182bc831 100644
--- a/storage/xtradb/dict/dict0dict.c
+++ b/storage/xtradb/dict/dict0dict.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file dict/dict0dict.c
Data dictionary system
Created 1/8/1996 Heikki Tuuri
@@ -28,6 +29,12 @@ Created 1/8/1996 Heikki Tuuri
#include "dict0dict.ic"
#endif
+/** dummy index for ROW_FORMAT=REDUNDANT supremum and infimum records */
+UNIV_INTERN dict_index_t* dict_ind_redundant;
+/** dummy index for ROW_FORMAT=COMPACT supremum and infimum records */
+UNIV_INTERN dict_index_t* dict_ind_compact;
+
+#ifndef UNIV_HOTBACKUP
#include "buf0buf.h"
#include "data0type.h"
#include "mach0data.h"
@@ -45,105 +52,101 @@ Created 1/8/1996 Heikki Tuuri
#include "que0que.h"
#include "rem0cmp.h"
#include "row0merge.h"
-#ifndef UNIV_HOTBACKUP
-# include "m_ctype.h" /* my_isspace() */
-# include "ha_prototypes.h" /* innobase_strcasecmp() */
-#endif /* !UNIV_HOTBACKUP */
+#include "m_ctype.h" /* my_isspace() */
+#include "ha_prototypes.h" /* innobase_strcasecmp() */
#include <ctype.h>
-/* the dictionary system */
+/** the dictionary system */
UNIV_INTERN dict_sys_t* dict_sys = NULL;
-/* table create, drop, etc. reserve this in X-mode; implicit or
+/** @brief the data dictionary rw-latch protecting dict_sys
+
+table create, drop, etc. reserve this in X-mode; implicit or
backround operations purge, rollback, foreign key checks reserve this
in S-mode; we cannot trust that MySQL protects implicit or background
operations a table drop since MySQL does not know of them; therefore
we need this; NOTE: a transaction which reserves this must keep book
-on the mode in trx->dict_operation_lock_mode */
+on the mode in trx_struct::dict_operation_lock_mode */
UNIV_INTERN rw_lock_t dict_operation_lock;
-#define DICT_HEAP_SIZE 100 /* initial memory heap size when
+#define DICT_HEAP_SIZE 100 /*!< initial memory heap size when
creating a table or index object */
-#define DICT_POOL_PER_TABLE_HASH 512 /* buffer pool max size per table
+#define DICT_POOL_PER_TABLE_HASH 512 /*!< buffer pool max size per table
hash table fixed size in bytes */
-#define DICT_POOL_PER_VARYING 4 /* buffer pool max size per data
+#define DICT_POOL_PER_VARYING 4 /*!< buffer pool max size per data
dictionary varying size in bytes */
-/* Identifies generated InnoDB foreign key names */
+/** Identifies generated InnoDB foreign key names */
static char dict_ibfk[] = "_ibfk_";
-/***********************************************************************
+/*******************************************************************//**
Tries to find column names for the index and sets the col field of the
index. */
static
void
dict_index_find_cols(
/*=================*/
- dict_table_t* table, /* in: table */
- dict_index_t* index); /* in: index */
-/***********************************************************************
+ dict_table_t* table, /*!< in: table */
+ dict_index_t* index); /*!< in: index */
+/*******************************************************************//**
Builds the internal dictionary cache representation for a clustered
-index, containing also system fields not defined by the user. */
+index, containing also system fields not defined by the user.
+@return own: the internal representation of the clustered index */
static
dict_index_t*
dict_index_build_internal_clust(
/*============================*/
- /* out, own: the internal
- representation of the clustered
- index */
- const dict_table_t* table, /* in: table */
- dict_index_t* index); /* in: user representation of
+ const dict_table_t* table, /*!< in: table */
+ dict_index_t* index); /*!< in: user representation of
a clustered index */
-/***********************************************************************
+/*******************************************************************//**
Builds the internal dictionary cache representation for a non-clustered
-index, containing also system fields not defined by the user. */
+index, containing also system fields not defined by the user.
+@return own: the internal representation of the non-clustered index */
static
dict_index_t*
dict_index_build_internal_non_clust(
/*================================*/
- /* out, own: the internal
- representation of the non-clustered
- index */
- const dict_table_t* table, /* in: table */
- dict_index_t* index); /* in: user representation of
+ const dict_table_t* table, /*!< in: table */
+ dict_index_t* index); /*!< in: user representation of
a non-clustered index */
-/**************************************************************************
+/**********************************************************************//**
Removes a foreign constraint struct from the dictionary cache. */
static
void
dict_foreign_remove_from_cache(
/*===========================*/
- dict_foreign_t* foreign); /* in, own: foreign constraint */
-/**************************************************************************
+ dict_foreign_t* foreign); /*!< in, own: foreign constraint */
+/**********************************************************************//**
Prints a column data. */
static
void
dict_col_print_low(
/*===============*/
- const dict_table_t* table, /* in: table */
- const dict_col_t* col); /* in: column */
-/**************************************************************************
+ const dict_table_t* table, /*!< in: table */
+ const dict_col_t* col); /*!< in: column */
+/**********************************************************************//**
Prints an index data. */
static
void
dict_index_print_low(
/*=================*/
- dict_index_t* index); /* in: index */
-/**************************************************************************
+ dict_index_t* index); /*!< in: index */
+/**********************************************************************//**
Prints a field data. */
static
void
dict_field_print_low(
/*=================*/
- dict_field_t* field); /* in: field */
-/*************************************************************************
+ dict_field_t* field); /*!< in: field */
+/*********************************************************************//**
Frees a foreign key struct. */
static
void
dict_foreign_free(
/*==============*/
- dict_foreign_t* foreign); /* in, own: foreign key struct */
+ dict_foreign_t* foreign); /*!< in, own: foreign key struct */
/* Stream for storing detailed information about the latest foreign key
and unique key errors */
@@ -151,29 +154,27 @@ UNIV_INTERN FILE* dict_foreign_err_file = NULL;
/* mutex protecting the foreign and unique error buffers */
UNIV_INTERN mutex_t dict_foreign_err_mutex;
-#ifndef UNIV_HOTBACKUP
-/**********************************************************************
+/******************************************************************//**
Makes all characters in a NUL-terminated UTF-8 string lower case. */
UNIV_INTERN
void
dict_casedn_str(
/*============*/
- char* a) /* in/out: string to put in lower case */
+ char* a) /*!< in/out: string to put in lower case */
{
innobase_casedn_str(a);
}
-#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
-Checks if the database name in two table names is the same. */
+/********************************************************************//**
+Checks if the database name in two table names is the same.
+@return TRUE if same db name */
UNIV_INTERN
ibool
dict_tables_have_same_db(
/*=====================*/
- /* out: TRUE if same db name */
- const char* name1, /* in: table name in the form
+ const char* name1, /*!< in: table name in the form
dbname '/' tablename */
- const char* name2) /* in: table name in the form
+ const char* name2) /*!< in: table name in the form
dbname '/' tablename */
{
for (; *name1 == *name2; name1++, name2++) {
@@ -185,14 +186,14 @@ dict_tables_have_same_db(
return(FALSE);
}
-/************************************************************************
-Return the end of table name where we have removed dbname and '/'. */
+/********************************************************************//**
+Return the end of table name where we have removed dbname and '/'.
+@return table name */
UNIV_INTERN
const char*
dict_remove_db_name(
/*================*/
- /* out: table name */
- const char* name) /* in: table name in the form
+ const char* name) /*!< in: table name in the form
dbname '/' tablename */
{
const char* s = strchr(name, '/');
@@ -201,14 +202,14 @@ dict_remove_db_name(
return(s + 1);
}
-/************************************************************************
-Get the database name length in a table name. */
+/********************************************************************//**
+Get the database name length in a table name.
+@return database name length */
UNIV_INTERN
ulint
dict_get_db_name_len(
/*=================*/
- /* out: database name length */
- const char* name) /* in: table name in the form
+ const char* name) /*!< in: table name in the form
dbname '/' tablename */
{
const char* s;
@@ -217,7 +218,7 @@ dict_get_db_name_len(
return(s - name);
}
-/************************************************************************
+/********************************************************************//**
Reserves the dictionary system mutex for MySQL. */
UNIV_INTERN
void
@@ -227,7 +228,7 @@ dict_mutex_enter_for_mysql(void)
mutex_enter(&(dict_sys->mutex));
}
-/************************************************************************
+/********************************************************************//**
Releases the dictionary system mutex for MySQL. */
UNIV_INTERN
void
@@ -237,14 +238,14 @@ dict_mutex_exit_for_mysql(void)
mutex_exit(&(dict_sys->mutex));
}
-/************************************************************************
+/********************************************************************//**
Decrements the count of open MySQL handles to a table. */
UNIV_INTERN
void
dict_table_decrement_handle_count(
/*==============================*/
- dict_table_t* table, /* in/out: table */
- ibool dict_locked) /* in: TRUE=data dictionary locked */
+ dict_table_t* table, /*!< in/out: table */
+ ibool dict_locked) /*!< in: TRUE=data dictionary locked */
{
if (!dict_locked) {
mutex_enter(&dict_sys->mutex);
@@ -259,19 +260,18 @@ dict_table_decrement_handle_count(
mutex_exit(&dict_sys->mutex);
}
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
-Returns a column's name. */
+/**********************************************************************//**
+Returns a column's name.
+@return column name. NOTE: not guaranteed to stay valid if table is
+modified in any way (columns added, etc.). */
UNIV_INTERN
const char*
dict_table_get_col_name(
/*====================*/
- /* out: column name. NOTE: not
- guaranteed to stay valid if table is
- modified in any way (columns added,
- etc.). */
- const dict_table_t* table, /* in: table */
- ulint col_nr) /* in: column number */
+ const dict_table_t* table, /*!< in: table */
+ ulint col_nr) /*!< in: column number */
{
ulint i;
const char* s;
@@ -290,48 +290,48 @@ dict_table_get_col_name(
return(s);
}
-
-/************************************************************************
-Acquire the autoinc lock.*/
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Acquire the autoinc lock. */
UNIV_INTERN
void
dict_table_autoinc_lock(
/*====================*/
- dict_table_t* table) /* in/out: table */
+ dict_table_t* table) /*!< in/out: table */
{
mutex_enter(&table->autoinc_mutex);
}
-/************************************************************************
+/********************************************************************//**
Unconditionally set the autoinc counter. */
UNIV_INTERN
void
dict_table_autoinc_initialize(
/*==========================*/
- dict_table_t* table, /* in/out: table */
- ib_uint64_t value) /* in: next value to assign to a row */
+ dict_table_t* table, /*!< in/out: table */
+ ib_uint64_t value) /*!< in: next value to assign to a row */
{
ut_ad(mutex_own(&table->autoinc_mutex));
table->autoinc = value;
}
-/************************************************************************
+/********************************************************************//**
Reads the next autoinc value (== autoinc counter value), 0 if not yet
-initialized. */
+initialized.
+@return value for a new row, or 0 */
UNIV_INTERN
ib_uint64_t
dict_table_autoinc_read(
/*====================*/
- /* out: value for a new row, or 0 */
- const dict_table_t* table) /* in: table */
+ const dict_table_t* table) /*!< in: table */
{
ut_ad(mutex_own(&table->autoinc_mutex));
return(table->autoinc);
}
-/************************************************************************
+/********************************************************************//**
Updates the autoinc counter if the value supplied is greater than the
current value. */
UNIV_INTERN
@@ -339,8 +339,8 @@ void
dict_table_autoinc_update_if_greater(
/*=================================*/
- dict_table_t* table, /* in/out: table */
- ib_uint64_t value) /* in: value which was assigned to a row */
+ dict_table_t* table, /*!< in/out: table */
+ ib_uint64_t value) /*!< in: value which was assigned to a row */
{
ut_ad(mutex_own(&table->autoinc_mutex));
@@ -350,28 +350,27 @@ dict_table_autoinc_update_if_greater(
}
}
-/************************************************************************
-Release the autoinc lock.*/
+/********************************************************************//**
+Release the autoinc lock. */
UNIV_INTERN
void
dict_table_autoinc_unlock(
/*======================*/
- dict_table_t* table) /* in/out: table */
+ dict_table_t* table) /*!< in/out: table */
{
mutex_exit(&table->autoinc_mutex);
}
-/**************************************************************************
+/**********************************************************************//**
Looks for an index with the given table and index id.
-NOTE that we do not reserve the dictionary mutex. */
+NOTE that we do not reserve the dictionary mutex.
+@return index or NULL if not found from cache */
UNIV_INTERN
dict_index_t*
dict_index_get_on_id_low(
/*=====================*/
- /* out: index or NULL if not found
- from cache */
- dict_table_t* table, /* in: table */
- dulint id) /* in: index id */
+ dict_table_t* table, /*!< in: table */
+ dulint id) /*!< in: index id */
{
dict_index_t* index;
@@ -389,19 +388,18 @@ dict_index_get_on_id_low(
return(NULL);
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
-Looks for column n in an index. */
+/********************************************************************//**
+Looks for column n in an index.
+@return position in internal representation of the index;
+ULINT_UNDEFINED if not contained */
UNIV_INTERN
ulint
dict_index_get_nth_col_pos(
/*=======================*/
- /* out: position in internal
- representation of the index;
- if not contained, returns
- ULINT_UNDEFINED */
- const dict_index_t* index, /* in: index */
- ulint n) /* in: column number */
+ const dict_index_t* index, /*!< in: index */
+ ulint n) /*!< in: column number */
{
const dict_field_t* field;
const dict_col_t* col;
@@ -432,16 +430,16 @@ dict_index_get_nth_col_pos(
return(ULINT_UNDEFINED);
}
-/************************************************************************
-Returns TRUE if the index contains a column or a prefix of that column. */
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Returns TRUE if the index contains a column or a prefix of that column.
+@return TRUE if contains the column or its prefix */
UNIV_INTERN
ibool
dict_index_contains_col_or_prefix(
/*==============================*/
- /* out: TRUE if contains the column
- or its prefix */
- const dict_index_t* index, /* in: index */
- ulint n) /* in: column number */
+ const dict_index_t* index, /*!< in: index */
+ ulint n) /*!< in: column number */
{
const dict_field_t* field;
const dict_col_t* col;
@@ -472,22 +470,20 @@ dict_index_contains_col_or_prefix(
return(FALSE);
}
-/************************************************************************
+/********************************************************************//**
Looks for a matching field in an index. The column has to be the same. The
column in index must be complete, or must contain a prefix longer than the
column in index2. That is, we must be able to construct the prefix in index2
-from the prefix in index. */
+from the prefix in index.
+@return position in internal representation of the index;
+ULINT_UNDEFINED if not contained */
UNIV_INTERN
ulint
dict_index_get_nth_field_pos(
/*=========================*/
- /* out: position in internal
- representation of the index;
- if not contained, returns
- ULINT_UNDEFINED */
- const dict_index_t* index, /* in: index from which to search */
- const dict_index_t* index2, /* in: index */
- ulint n) /* in: field number in index2 */
+ const dict_index_t* index, /*!< in: index from which to search */
+ const dict_index_t* index2, /*!< in: index */
+ ulint n) /*!< in: field number in index2 */
{
const dict_field_t* field;
const dict_field_t* field2;
@@ -516,15 +512,15 @@ dict_index_get_nth_field_pos(
return(ULINT_UNDEFINED);
}
-/**************************************************************************
-Returns a table object based on table id. */
+/**********************************************************************//**
+Returns a table object based on table id.
+@return table, NULL if does not exist */
UNIV_INTERN
dict_table_t*
dict_table_get_on_id(
/*=================*/
- /* out: table, NULL if does not exist */
- dulint table_id, /* in: table id */
- trx_t* trx) /* in: transaction handle */
+ dulint table_id, /*!< in: table id */
+ trx_t* trx) /*!< in: transaction handle */
{
dict_table_t* table;
@@ -552,33 +548,30 @@ dict_table_get_on_id(
return(table);
}
-/************************************************************************
-Looks for column n position in the clustered index. */
+/********************************************************************//**
+Looks for column n position in the clustered index.
+@return position in internal representation of the clustered index */
UNIV_INTERN
ulint
dict_table_get_nth_col_pos(
/*=======================*/
- /* out: position in internal
- representation of
- the clustered index */
- const dict_table_t* table, /* in: table */
- ulint n) /* in: column number */
+ const dict_table_t* table, /*!< in: table */
+ ulint n) /*!< in: column number */
{
return(dict_index_get_nth_col_pos(dict_table_get_first_index(table),
n));
}
-/************************************************************************
+/********************************************************************//**
Checks if a column is in the ordering columns of the clustered index of a
-table. Column prefixes are treated like whole columns. */
+table. Column prefixes are treated like whole columns.
+@return TRUE if the column, or its prefix, is in the clustered key */
UNIV_INTERN
ibool
dict_table_col_in_clustered_key(
/*============================*/
- /* out: TRUE if the column, or its
- prefix, is in the clustered key */
- const dict_table_t* table, /* in: table */
- ulint n) /* in: column number */
+ const dict_table_t* table, /*!< in: table */
+ ulint n) /*!< in: column number */
{
const dict_index_t* index;
const dict_field_t* field;
@@ -606,7 +599,7 @@ dict_table_col_in_clustered_key(
return(FALSE);
}
-/**************************************************************************
+/**********************************************************************//**
Inits the data dictionary module. */
UNIV_INTERN
void
@@ -635,20 +628,18 @@ dict_init(void)
mutex_create(&dict_foreign_err_mutex, SYNC_ANY_LATCH);
}
-/**************************************************************************
+/**********************************************************************//**
Returns a table object and optionally increment its MySQL open handle count.
NOTE! This is a high-level function to be used mainly from outside the
'dict' directory. Inside this directory dict_table_get_low is usually the
-appropriate function. */
+appropriate function.
+@return table, NULL if does not exist */
UNIV_INTERN
dict_table_t*
dict_table_get(
/*===========*/
- /* out: table, NULL if
- does not exist */
- const char* table_name, /* in: table name */
- ibool inc_mysql_count)
- /* in: whether to increment the open
+ const char* table_name, /*!< in: table name */
+ ibool inc_mysql_count)/*!< in: whether to increment the open
handle count on the table */
{
dict_table_t* table;
@@ -676,15 +667,16 @@ dict_table_get(
return(table);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Adds system columns to a table object. */
UNIV_INTERN
void
dict_table_add_system_columns(
/*==========================*/
- dict_table_t* table, /* in/out: table */
- mem_heap_t* heap) /* in: temporary heap */
+ dict_table_t* table, /*!< in/out: table */
+ mem_heap_t* heap) /*!< in: temporary heap */
{
ut_ad(table);
ut_ad(table->n_def == table->n_cols - DATA_N_SYS_COLS);
@@ -723,14 +715,15 @@ dict_table_add_system_columns(
#endif
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Adds a table object to the dictionary cache. */
UNIV_INTERN
void
dict_table_add_to_cache(
/*====================*/
- dict_table_t* table, /* in: table */
- mem_heap_t* heap) /* in: temporary heap */
+ dict_table_t* table, /*!< in: table */
+ mem_heap_t* heap) /*!< in: temporary heap */
{
ulint fold;
ulint id_fold;
@@ -814,16 +807,16 @@ dict_table_add_to_cache(
dict_sys->size += mem_heap_get_size(table->heap);
}
-/**************************************************************************
+/**********************************************************************//**
Looks for an index with the given id. NOTE that we do not reserve
the dictionary mutex: this function is for emergency purposes like
-printing info of a corrupt database page! */
+printing info of a corrupt database page!
+@return index or NULL if not found from cache */
UNIV_INTERN
dict_index_t*
dict_index_find_on_id_low(
/*======================*/
- /* out: index or NULL if not found from cache */
- dulint id) /* in: index id */
+ dulint id) /*!< in: index id */
{
dict_table_t* table;
dict_index_t* index;
@@ -849,16 +842,16 @@ dict_index_find_on_id_low(
return(NULL);
}
-/**************************************************************************
-Renames a table object. */
+/**********************************************************************//**
+Renames a table object.
+@return TRUE if success */
UNIV_INTERN
ibool
dict_table_rename_in_cache(
/*=======================*/
- /* out: TRUE if success */
- dict_table_t* table, /* in/out: table */
- const char* new_name, /* in: new name */
- ibool rename_also_foreigns)/* in: in ALTER TABLE we want
+ dict_table_t* table, /*!< in/out: table */
+ const char* new_name, /*!< in: new name */
+ ibool rename_also_foreigns)/*!< in: in ALTER TABLE we want
to preserve the original table name
in constraints which reference it */
{
@@ -1065,15 +1058,15 @@ dict_table_rename_in_cache(
return(TRUE);
}
-/**************************************************************************
+/**********************************************************************//**
Change the id of a table object in the dictionary cache. This is used in
DISCARD TABLESPACE. */
UNIV_INTERN
void
dict_table_change_id_in_cache(
/*==========================*/
- dict_table_t* table, /* in/out: table object already in cache */
- dulint new_id) /* in: new id to set */
+ dict_table_t* table, /*!< in/out: table object already in cache */
+ dulint new_id) /*!< in: new id to set */
{
ut_ad(table);
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -1090,13 +1083,13 @@ dict_table_change_id_in_cache(
ut_fold_dulint(table->id), table);
}
-/**************************************************************************
+/**********************************************************************//**
Removes a table object from the dictionary cache. */
UNIV_INTERN
void
dict_table_remove_from_cache(
/*=========================*/
- dict_table_t* table) /* in, own: table */
+ dict_table_t* table) /*!< in, own: table */
{
dict_foreign_t* foreign;
dict_index_t* index;
@@ -1215,15 +1208,15 @@ next_loop:
goto retry;
}
-/********************************************************************
+/****************************************************************//**
If the given column name is reserved for InnoDB system columns, return
-TRUE. */
+TRUE.
+@return TRUE if name is reserved */
UNIV_INTERN
ibool
dict_col_name_is_reserved(
/*======================*/
- /* out: TRUE if name is reserved */
- const char* name) /* in: column name */
+ const char* name) /*!< in: column name */
{
/* This check reminds that if a new system column is added to
the program, it should be dealt with here. */
@@ -1238,7 +1231,7 @@ dict_col_name_is_reserved(
ulint i;
for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) {
- if (strcmp(name, reserved_names[i]) == 0) {
+ if (innobase_strcasecmp(name, reserved_names[i]) == 0) {
return(TRUE);
}
@@ -1247,17 +1240,16 @@ dict_col_name_is_reserved(
return(FALSE);
}
-/********************************************************************
+/****************************************************************//**
If an undo log record for this table might not fit on a single page,
-return TRUE. */
+return TRUE.
+@return TRUE if the undo log record could become too big */
static
ibool
dict_index_too_big_for_undo(
/*========================*/
- /* out: TRUE if the undo log
- record could become too big */
- const dict_table_t* table, /* in: table */
- const dict_index_t* new_index) /* in: index */
+ const dict_table_t* table, /*!< in: table */
+ const dict_index_t* new_index) /*!< in: index */
{
/* Make sure that all column prefixes will fit in the undo log record
in trx_undo_page_report_modify() right after trx_undo_page_init(). */
@@ -1307,7 +1299,8 @@ dict_index_too_big_for_undo(
ulint max_size
= dict_col_get_max_size(col);
ulint fixed_size
- = dict_col_get_fixed_size(col);
+ = dict_col_get_fixed_size(col,
+ dict_table_is_comp(table));
if (fixed_size) {
/* Fixed-size columns are stored locally. */
@@ -1349,17 +1342,16 @@ is_ord_part:
return(undo_page_len >= UNIV_PAGE_SIZE);
}
-/********************************************************************
+/****************************************************************//**
If a record of this index might not fit on a single B-tree page,
-return TRUE. */
+return TRUE.
+@return TRUE if the index record could become too big */
static
ibool
dict_index_too_big_for_tree(
/*========================*/
- /* out: TRUE if the index
- record could become too big */
- const dict_table_t* table, /* in: table */
- const dict_index_t* new_index) /* in: index */
+ const dict_table_t* table, /*!< in: table */
+ const dict_index_t* new_index) /*!< in: index */
{
ulint zip_size;
ulint comp;
@@ -1437,7 +1429,7 @@ dict_index_too_big_for_tree(
case in rec_get_converted_size_comp() for
REC_STATUS_ORDINARY records. */
- field_max_size = dict_col_get_fixed_size(col);
+ field_max_size = dict_col_get_fixed_size(col, comp);
if (field_max_size) {
/* dict_index_add_col() should guarantee this */
ut_ad(!field->prefix_len
@@ -1499,18 +1491,18 @@ add_field_size:
return(FALSE);
}
-/**************************************************************************
-Adds an index to the dictionary cache. */
+/**********************************************************************//**
+Adds an index to the dictionary cache.
+@return DB_SUCCESS or DB_TOO_BIG_RECORD */
UNIV_INTERN
ulint
dict_index_add_to_cache(
/*====================*/
- /* out: DB_SUCCESS or DB_TOO_BIG_RECORD */
- dict_table_t* table, /* in: table on which the index is */
- dict_index_t* index, /* in, own: index; NOTE! The index memory
+ dict_table_t* table, /*!< in: table on which the index is */
+ dict_index_t* index, /*!< in, own: index; NOTE! The index memory
object is freed in this function! */
- ulint page_no,/* in: root page number of the index */
- ibool strict) /* in: TRUE=refuse to create the index
+ ulint page_no,/*!< in: root page number of the index */
+ ibool strict) /*!< in: TRUE=refuse to create the index
if records could be too big to fit in
an B-tree page */
{
@@ -1597,7 +1589,7 @@ too_big:
if (field->prefix_len /* prefix index */
&& !col->ord_part /* not yet ordering column */
- && !dict_col_get_fixed_size(col) /* variable-length */
+ && !dict_col_get_fixed_size(col, TRUE) /* variable-length */
&& dict_col_get_max_size(col)
> BTR_EXTERN_FIELD_REF_SIZE * 2 /* long enough */) {
@@ -1656,14 +1648,14 @@ undo_size_ok:
return(DB_SUCCESS);
}
-/**************************************************************************
+/**********************************************************************//**
Removes an index from the dictionary cache. */
UNIV_INTERN
void
dict_index_remove_from_cache(
/*=========================*/
- dict_table_t* table, /* in/out: table */
- dict_index_t* index) /* in, own: index */
+ dict_table_t* table, /*!< in/out: table */
+ dict_index_t* index) /*!< in, own: index */
{
ulint size;
ulint retries = 0;
@@ -1674,6 +1666,11 @@ dict_index_remove_from_cache(
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
ut_ad(mutex_own(&(dict_sys->mutex)));
+ /* remove all entry of the index from adaptive hash index,
+ because removing from adaptive hash index needs dict_index */
+ if (btr_search_enabled && srv_dict_size_limit)
+ btr_search_drop_page_hash_index_on_index(index);
+
/* We always create search info whether or not adaptive
hash index is enabled or not. */
info = index->search_info;
@@ -1733,15 +1730,15 @@ dict_index_remove_from_cache(
dict_mem_index_free(index);
}
-/***********************************************************************
+/*******************************************************************//**
Tries to find column names for the index and sets the col field of the
index. */
static
void
dict_index_find_cols(
/*=================*/
- dict_table_t* table, /* in: table */
- dict_index_t* index) /* in: index */
+ dict_table_t* table, /*!< in: table */
+ dict_index_t* index) /*!< in: index */
{
ulint i;
@@ -1763,23 +1760,29 @@ dict_index_find_cols(
}
/* It is an error not to find a matching column. */
+ fputs("InnoDB: Error: no matching column for ", stderr);
+ ut_print_name(stderr, NULL, FALSE, field->name);
+ fputs(" in ", stderr);
+ dict_index_name_print(stderr, NULL, index);
+ fputs("!\n", stderr);
ut_error;
found:
;
}
}
+#endif /* !UNIV_HOTBACKUP */
-/***********************************************************************
+/*******************************************************************//**
Adds a column to index. */
UNIV_INTERN
void
dict_index_add_col(
/*===============*/
- dict_index_t* index, /* in/out: index */
- const dict_table_t* table, /* in: table */
- dict_col_t* col, /* in: column */
- ulint prefix_len) /* in: column prefix length */
+ dict_index_t* index, /*!< in/out: index */
+ const dict_table_t* table, /*!< in: table */
+ dict_col_t* col, /*!< in: column */
+ ulint prefix_len) /*!< in: column prefix length */
{
dict_field_t* field;
const char* col_name;
@@ -1791,7 +1794,8 @@ dict_index_add_col(
field = dict_index_get_nth_field(index, index->n_def - 1);
field->col = col;
- field->fixed_len = (unsigned int) dict_col_get_fixed_size(col);
+ field->fixed_len = (unsigned int) dict_col_get_fixed_size(
+ col, dict_table_is_comp(table));
if (prefix_len && field->fixed_len > prefix_len) {
field->fixed_len = (unsigned int) prefix_len;
@@ -1816,17 +1820,18 @@ dict_index_add_col(
}
}
-/***********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Copies fields contained in index2 to index1. */
static
void
dict_index_copy(
/*============*/
- dict_index_t* index1, /* in: index to copy to */
- dict_index_t* index2, /* in: index to copy from */
- const dict_table_t* table, /* in: table */
- ulint start, /* in: first position to copy */
- ulint end) /* in: last position to copy */
+ dict_index_t* index1, /*!< in: index to copy to */
+ dict_index_t* index2, /*!< in: index to copy from */
+ const dict_table_t* table, /*!< in: table */
+ ulint start, /*!< in: first position to copy */
+ ulint end) /*!< in: last position to copy */
{
dict_field_t* field;
ulint i;
@@ -1841,15 +1846,15 @@ dict_index_copy(
}
}
-/***********************************************************************
+/*******************************************************************//**
Copies types of fields contained in index to tuple. */
UNIV_INTERN
void
dict_index_copy_types(
/*==================*/
- dtuple_t* tuple, /* in/out: data tuple */
- const dict_index_t* index, /* in: index */
- ulint n_fields) /* in: number of
+ dtuple_t* tuple, /*!< in/out: data tuple */
+ const dict_index_t* index, /*!< in: index */
+ ulint n_fields) /*!< in: number of
field types to copy */
{
ulint i;
@@ -1870,7 +1875,7 @@ dict_index_copy_types(
}
}
-/***********************************************************************
+/*******************************************************************//**
Copies types of columns contained in table to tuple and sets all
fields of the tuple to the SQL NULL value. This function should
be called right after dtuple_create(). */
@@ -1878,8 +1883,8 @@ UNIV_INTERN
void
dict_table_copy_types(
/*==================*/
- dtuple_t* tuple, /* in/out: data tuple */
- const dict_table_t* table) /* in: table */
+ dtuple_t* tuple, /*!< in/out: data tuple */
+ const dict_table_t* table) /*!< in: table */
{
ulint i;
@@ -1893,18 +1898,16 @@ dict_table_copy_types(
}
}
-/***********************************************************************
+/*******************************************************************//**
Builds the internal dictionary cache representation for a clustered
-index, containing also system fields not defined by the user. */
+index, containing also system fields not defined by the user.
+@return own: the internal representation of the clustered index */
static
dict_index_t*
dict_index_build_internal_clust(
/*============================*/
- /* out, own: the internal
- representation of the clustered
- index */
- const dict_table_t* table, /* in: table */
- dict_index_t* index) /* in: user representation of
+ const dict_table_t* table, /*!< in: table */
+ dict_index_t* index) /*!< in: user representation of
a clustered index */
{
dict_index_t* new_index;
@@ -1987,7 +1990,8 @@ dict_index_build_internal_clust(
for (i = 0; i < trx_id_pos; i++) {
fixed_size = dict_col_get_fixed_size(
- dict_index_get_nth_col(new_index, i));
+ dict_index_get_nth_col(new_index, i),
+ dict_table_is_comp(table));
if (fixed_size == 0) {
new_index->trx_id_offset = 0;
@@ -2046,18 +2050,16 @@ dict_index_build_internal_clust(
return(new_index);
}
-/***********************************************************************
+/*******************************************************************//**
Builds the internal dictionary cache representation for a non-clustered
-index, containing also system fields not defined by the user. */
+index, containing also system fields not defined by the user.
+@return own: the internal representation of the non-clustered index */
static
dict_index_t*
dict_index_build_internal_non_clust(
/*================================*/
- /* out, own: the internal
- representation of the non-clustered
- index */
- const dict_table_t* table, /* in: table */
- dict_index_t* index) /* in: user representation of
+ const dict_table_t* table, /*!< in: table */
+ dict_index_t* index) /*!< in: user representation of
a non-clustered index */
{
dict_field_t* field;
@@ -2143,30 +2145,29 @@ dict_index_build_internal_non_clust(
/*====================== FOREIGN KEY PROCESSING ========================*/
-/*************************************************************************
-Checks if a table is referenced by foreign keys. */
+/*********************************************************************//**
+Checks if a table is referenced by foreign keys.
+@return TRUE if table is referenced by a foreign key */
UNIV_INTERN
ibool
dict_table_is_referenced_by_foreign_key(
/*====================================*/
- /* out: TRUE if table is referenced
- by a foreign key */
- const dict_table_t* table) /* in: InnoDB table */
+ const dict_table_t* table) /*!< in: InnoDB table */
{
return(UT_LIST_GET_LEN(table->referenced_list) > 0);
}
-/*************************************************************************
+/*********************************************************************//**
Check if the index is referenced by a foreign key, if TRUE return foreign
-else return NULL */
+else return NULL
+@return pointer to foreign key struct if index is defined for foreign
+key, otherwise NULL */
UNIV_INTERN
dict_foreign_t*
dict_table_get_referenced_constraint(
/*=================================*/
- /* out: pointer to foreign key struct if index
- is defined for foreign key, otherwise NULL */
- dict_table_t* table, /* in: InnoDB table */
- dict_index_t* index) /* in: InnoDB index */
+ dict_table_t* table, /*!< in: InnoDB table */
+ dict_index_t* index) /*!< in: InnoDB index */
{
dict_foreign_t* foreign;
@@ -2186,18 +2187,18 @@ dict_table_get_referenced_constraint(
return(NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if a index is defined for a foreign key constraint. Index is a part
of a foreign key constraint if the index is referenced by foreign key
-or index is a foreign key index. */
+or index is a foreign key index.
+@return pointer to foreign key struct if index is defined for foreign
+key, otherwise NULL */
UNIV_INTERN
dict_foreign_t*
dict_table_get_foreign_constraint(
/*==============================*/
- /* out: pointer to foreign key struct if index
- is defined for foreign key, otherwise NULL */
- dict_table_t* table, /* in: InnoDB table */
- dict_index_t* index) /* in: InnoDB index */
+ dict_table_t* table, /*!< in: InnoDB table */
+ dict_index_t* index) /*!< in: InnoDB index */
{
dict_foreign_t* foreign;
@@ -2218,24 +2219,24 @@ dict_table_get_foreign_constraint(
return(NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Frees a foreign key struct. */
static
void
dict_foreign_free(
/*==============*/
- dict_foreign_t* foreign) /* in, own: foreign key struct */
+ dict_foreign_t* foreign) /*!< in, own: foreign key struct */
{
mem_heap_free(foreign->heap);
}
-/**************************************************************************
+/**********************************************************************//**
Removes a foreign constraint struct from the dictionary cache. */
static
void
dict_foreign_remove_from_cache(
/*===========================*/
- dict_foreign_t* foreign) /* in, own: foreign constraint */
+ dict_foreign_t* foreign) /*!< in, own: foreign constraint */
{
ut_ad(mutex_own(&(dict_sys->mutex)));
ut_a(foreign);
@@ -2255,17 +2256,16 @@ dict_foreign_remove_from_cache(
dict_foreign_free(foreign);
}
-#ifndef UNIV_HOTBACKUP
-/**************************************************************************
+/**********************************************************************//**
Looks for the foreign constraint from the foreign and referenced lists
-of a table. */
+of a table.
+@return foreign constraint */
static
dict_foreign_t*
dict_foreign_find(
/*==============*/
- /* out: foreign constraint */
- dict_table_t* table, /* in: table object */
- const char* id) /* in: foreign constraint id */
+ dict_table_t* table, /*!< in: table object */
+ const char* id) /*!< in: foreign constraint id */
{
dict_foreign_t* foreign;
@@ -2296,25 +2296,25 @@ dict_foreign_find(
return(NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Tries to find an index whose first fields are the columns in the array,
in the same order and is not marked for deletion and is not the same
-as types_idx. */
+as types_idx.
+@return matching index, NULL if not found */
static
dict_index_t*
dict_foreign_find_index(
/*====================*/
- /* out: matching index, NULL if not found */
- dict_table_t* table, /* in: table */
- const char** columns,/* in: array of column names */
- ulint n_cols, /* in: number of columns */
- dict_index_t* types_idx, /* in: NULL or an index to whose types the
+ dict_table_t* table, /*!< in: table */
+ const char** columns,/*!< in: array of column names */
+ ulint n_cols, /*!< in: number of columns */
+ dict_index_t* types_idx, /*!< in: NULL or an index to whose types the
column types must match */
ibool check_charsets,
- /* in: whether to check charsets.
+ /*!< in: whether to check charsets.
only has an effect if types_idx != NULL */
ulint check_null)
- /* in: nonzero if none of the columns must
+ /*!< in: nonzero if none of the columns must
be declared NOT NULL */
{
dict_index_t* index;
@@ -2382,16 +2382,15 @@ next_rec:
return(NULL);
}
-/**************************************************************************
+/**********************************************************************//**
Find an index that is equivalent to the one passed in and is not marked
-for deletion. */
+for deletion.
+@return index equivalent to foreign->foreign_index, or NULL */
UNIV_INTERN
dict_index_t*
dict_foreign_find_equiv_index(
/*==========================*/
- /* out: index equivalent to
- foreign->foreign_index, or NULL */
- dict_foreign_t* foreign)/* in: foreign key */
+ dict_foreign_t* foreign)/*!< in: foreign key */
{
ut_a(foreign != NULL);
@@ -2406,18 +2405,18 @@ dict_foreign_find_equiv_index(
FALSE/* allow columns to be NULL */));
}
-/**************************************************************************
+/**********************************************************************//**
Returns an index object by matching on the name and column names and
-if more than one index matches return the index with the max id */
+if more than one index matches return the index with the max id
+@return matching index, NULL if not found */
UNIV_INTERN
dict_index_t*
dict_table_get_index_by_max_id(
/*===========================*/
- /* out: matching index, NULL if not found */
- dict_table_t* table, /* in: table */
- const char* name, /* in: the index name to find */
- const char** columns,/* in: array of column names */
- ulint n_cols) /* in: number of columns */
+ dict_table_t* table, /*!< in: table */
+ const char* name, /*!< in: the index name to find */
+ const char** columns,/*!< in: array of column names */
+ ulint n_cols) /*!< in: number of columns */
{
dict_index_t* index;
dict_index_t* found;
@@ -2466,14 +2465,14 @@ dict_table_get_index_by_max_id(
return(found);
}
-/**************************************************************************
+/**********************************************************************//**
Report an error in a foreign key definition. */
static
void
dict_foreign_error_report_low(
/*==========================*/
- FILE* file, /* in: output stream */
- const char* name) /* in: table name */
+ FILE* file, /*!< in: output stream */
+ const char* name) /*!< in: table name */
{
rewind(file);
ut_print_timestamp(file);
@@ -2481,15 +2480,15 @@ dict_foreign_error_report_low(
name);
}
-/**************************************************************************
+/**********************************************************************//**
Report an error in a foreign key definition. */
static
void
dict_foreign_error_report(
/*======================*/
- FILE* file, /* in: output stream */
- dict_foreign_t* fk, /* in: foreign key constraint */
- const char* msg) /* in: the error message */
+ FILE* file, /*!< in: output stream */
+ dict_foreign_t* fk, /*!< in: foreign key constraint */
+ const char* msg) /*!< in: the error message */
{
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(file, fk->foreign_table_name);
@@ -2501,26 +2500,25 @@ dict_foreign_error_report(
fputs("The index in the foreign key in table is ", file);
ut_print_name(file, NULL, FALSE, fk->foreign_index->name);
fputs("\n"
- "See http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-foreign-key-constraints.html\n"
+ "See " REFMAN "innodb-foreign-key-constraints.html\n"
"for correct foreign key definition.\n",
file);
}
mutex_exit(&dict_foreign_err_mutex);
}
-/**************************************************************************
+/**********************************************************************//**
Adds a foreign key constraint object to the dictionary cache. May free
the object if there already is an object with the same identifier in.
At least one of the foreign table and the referenced table must already
-be in the dictionary cache! */
+be in the dictionary cache!
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_foreign_add_to_cache(
/*======================*/
- /* out: DB_SUCCESS or error code */
- dict_foreign_t* foreign, /* in, own: foreign key constraint */
- ibool check_charsets) /* in: TRUE=check charset
+ dict_foreign_t* foreign, /*!< in, own: foreign key constraint */
+ ibool check_charsets) /*!< in: TRUE=check charset
compatibility */
{
dict_table_t* for_table;
@@ -2632,17 +2630,17 @@ dict_foreign_add_to_cache(
return(DB_SUCCESS);
}
-/*************************************************************************
+/*********************************************************************//**
Scans from pointer onwards. Stops if is at the start of a copy of
'string' where characters are compared without case sensitivity, and
-only outside `` or "" quotes. Stops also at '\0'. */
+only outside `` or "" quotes. Stops also at NUL.
+@return scanned up to this */
static
const char*
dict_scan_to(
/*=========*/
- /* out: scanned up to this */
- const char* ptr, /* in: scan from */
- const char* string) /* in: look for this */
+ const char* ptr, /*!< in: scan from */
+ const char* string) /*!< in: look for this */
{
char quote = '\0';
@@ -2675,19 +2673,19 @@ nomatch:
return(ptr);
}
-/*************************************************************************
-Accepts a specified string. Comparisons are case-insensitive. */
+/*********************************************************************//**
+Accepts a specified string. Comparisons are case-insensitive.
+@return if string was accepted, the pointer is moved after that, else
+ptr is returned */
static
const char*
dict_accept(
/*========*/
- /* out: if string was accepted, the pointer
- is moved after that, else ptr is returned */
- struct charset_info_st* cs,/* in: the character set of ptr */
- const char* ptr, /* in: scan from this */
- const char* string, /* in: accept only this string as the next
+ struct charset_info_st* cs,/*!< in: the character set of ptr */
+ const char* ptr, /*!< in: scan from this */
+ const char* string, /*!< in: accept only this string as the next
non-whitespace string */
- ibool* success)/* out: TRUE if accepted */
+ ibool* success)/*!< out: TRUE if accepted */
{
const char* old_ptr = ptr;
const char* old_ptr2;
@@ -2711,25 +2709,25 @@ dict_accept(
return(ptr + ut_strlen(string));
}
-/*************************************************************************
+/*********************************************************************//**
Scans an id. For the lexical definition of an 'id', see the code below.
-Strips backquotes or double quotes from around the id. */
+Strips backquotes or double quotes from around the id.
+@return scanned to */
static
const char*
dict_scan_id(
/*=========*/
- /* out: scanned to */
- struct charset_info_st* cs,/* in: the character set of ptr */
- const char* ptr, /* in: scanned to */
- mem_heap_t* heap, /* in: heap where to allocate the id
+ struct charset_info_st* cs,/*!< in: the character set of ptr */
+ const char* ptr, /*!< in: scanned to */
+ mem_heap_t* heap, /*!< in: heap where to allocate the id
(NULL=id will not be allocated, but it
will point to string near ptr) */
- const char** id, /* out,own: the id; NULL if no id was
+ const char** id, /*!< out,own: the id; NULL if no id was
scannable */
- ibool table_id,/* in: TRUE=convert the allocated id
+ ibool table_id,/*!< in: TRUE=convert the allocated id
as a table name; FALSE=convert to UTF-8 */
ibool accept_also_dot)
- /* in: TRUE if also a dot can appear in a
+ /*!< in: TRUE if also a dot can appear in a
non-quoted id; in a quoted id it can appear
always */
{
@@ -2831,20 +2829,20 @@ convert_id:
return(ptr);
}
-/*************************************************************************
-Tries to scan a column name. */
+/*********************************************************************//**
+Tries to scan a column name.
+@return scanned to */
static
const char*
dict_scan_col(
/*==========*/
- /* out: scanned to */
- struct charset_info_st* cs, /* in: the character set of ptr */
- const char* ptr, /* in: scanned to */
- ibool* success,/* out: TRUE if success */
- dict_table_t* table, /* in: table in which the column is */
- const dict_col_t** column, /* out: pointer to column if success */
- mem_heap_t* heap, /* in: heap where to allocate */
- const char** name) /* out,own: the column name;
+ struct charset_info_st* cs, /*!< in: the character set of ptr */
+ const char* ptr, /*!< in: scanned to */
+ ibool* success,/*!< out: TRUE if success */
+ dict_table_t* table, /*!< in: table in which the column is */
+ const dict_col_t** column, /*!< out: pointer to column if success */
+ mem_heap_t* heap, /*!< in: heap where to allocate */
+ const char** name) /*!< out,own: the column name;
NULL if no name was scannable */
{
ulint i;
@@ -2882,20 +2880,20 @@ dict_scan_col(
return(ptr);
}
-/*************************************************************************
-Scans a table name from an SQL string. */
+/*********************************************************************//**
+Scans a table name from an SQL string.
+@return scanned to */
static
const char*
dict_scan_table_name(
/*=================*/
- /* out: scanned to */
- struct charset_info_st* cs,/* in: the character set of ptr */
- const char* ptr, /* in: scanned to */
- dict_table_t** table, /* out: table object or NULL */
- const char* name, /* in: foreign key table name */
- ibool* success,/* out: TRUE if ok name found */
- mem_heap_t* heap, /* in: heap where to allocate the id */
- const char** ref_name)/* out,own: the table name;
+ struct charset_info_st* cs,/*!< in: the character set of ptr */
+ const char* ptr, /*!< in: scanned to */
+ dict_table_t** table, /*!< out: table object or NULL */
+ const char* name, /*!< in: foreign key table name */
+ ibool* success,/*!< out: TRUE if ok name found */
+ mem_heap_t* heap, /*!< in: heap where to allocate the id */
+ const char** ref_name)/*!< out,own: the table name;
NULL if no name was scannable */
{
const char* database_name = NULL;
@@ -2981,16 +2979,16 @@ dict_scan_table_name(
return(ptr);
}
-/*************************************************************************
-Skips one id. The id is allowed to contain also '.'. */
+/*********************************************************************//**
+Skips one id. The id is allowed to contain also '.'.
+@return scanned to */
static
const char*
dict_skip_word(
/*===========*/
- /* out: scanned to */
- struct charset_info_st* cs,/* in: the character set of ptr */
- const char* ptr, /* in: scanned to */
- ibool* success)/* out: TRUE if success, FALSE if just spaces
+ struct charset_info_st* cs,/*!< in: the character set of ptr */
+ const char* ptr, /*!< in: scanned to */
+ ibool* success)/*!< out: TRUE if success, FALSE if just spaces
left in string or a syntax error */
{
const char* start;
@@ -3006,20 +3004,19 @@ dict_skip_word(
return(ptr);
}
-/*************************************************************************
+/*********************************************************************//**
Removes MySQL comments from an SQL string. A comment is either
(a) '#' to the end of the line,
-(b) '--<space>' to the end of the line, or
-(c) '<slash><asterisk>' till the next '<asterisk><slash>' (like the familiar
-C comment syntax). */
+(b) '--[space]' to the end of the line, or
+(c) '[slash][asterisk]' till the next '[asterisk][slash]' (like the familiar
+C comment syntax).
+@return own: SQL string stripped from comments; the caller must free
+this with mem_free()! */
static
char*
dict_strip_comments(
/*================*/
- /* out, own: SQL string stripped from
- comments; the caller must free this
- with mem_free()! */
- const char* sql_string) /* in: SQL string */
+ const char* sql_string) /*!< in: SQL string */
{
char* str;
const char* sptr;
@@ -3093,17 +3090,16 @@ scan_more:
}
}
-/*************************************************************************
-Finds the highest <number> for foreign key constraints of the table. Looks
+/*********************************************************************//**
+Finds the highest [number] for foreign key constraints of the table. Looks
only at the >= 4.0.18-format id's, which are of the form
-databasename/tablename_ibfk_<number>. */
+databasename/tablename_ibfk_[number].
+@return highest number, 0 if table has no new format foreign key constraints */
static
ulint
dict_table_get_highest_foreign_id(
/*==============================*/
- /* out: highest number, 0 if table has no new
- format foreign key constraints */
- dict_table_t* table) /* in: table in the dictionary memory cache */
+ dict_table_t* table) /*!< in: table in the dictionary memory cache */
{
dict_foreign_t* foreign;
char* endp;
@@ -3142,17 +3138,17 @@ dict_table_get_highest_foreign_id(
return(biggest_id);
}
-/*************************************************************************
+/*********************************************************************//**
Reports a simple foreign key create clause syntax error. */
static
void
dict_foreign_report_syntax_err(
/*===========================*/
- const char* name, /* in: table name */
+ const char* name, /*!< in: table name */
const char* start_of_latest_foreign,
- /* in: start of the foreign key clause
+ /*!< in: start of the foreign key clause
in the SQL string */
- const char* ptr) /* in: place of the syntax error */
+ const char* ptr) /*!< in: place of the syntax error */
{
FILE* ef = dict_foreign_err_file;
@@ -3163,31 +3159,31 @@ dict_foreign_report_syntax_err(
mutex_exit(&dict_foreign_err_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
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. Each foreign key constraint must
be accompanied with indexes in both participating tables. The indexes are
-allowed to contain more fields than mentioned in the constraint. */
+allowed to contain more fields than mentioned in the constraint.
+@return error code or DB_SUCCESS */
static
ulint
dict_create_foreign_constraints_low(
/*================================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in: transaction */
- mem_heap_t* heap, /* in: memory heap */
- struct charset_info_st* cs,/* in: the character set of sql_string */
+ trx_t* trx, /*!< in: transaction */
+ mem_heap_t* heap, /*!< in: memory heap */
+ struct charset_info_st* cs,/*!< in: the character set of sql_string */
const char* sql_string,
- /* in: CREATE TABLE or ALTER TABLE statement
+ /*!< in: CREATE TABLE or ALTER TABLE statement
where foreign keys are declared like:
FOREIGN KEY (a, b) REFERENCES table2(c, d),
table2 can be written also with the database
name before it: test.table2; the default
database is the database of parameter name */
- const char* name, /* in: table full name in the normalized form
+ const char* name, /*!< in: table full name in the normalized form
database_name/table_name */
ibool reject_fks)
- /* in: if TRUE, fail with error code
+ /*!< in: if TRUE, fail with error code
DB_CANNOT_ADD_CONSTRAINT if any foreign
keys are found. */
{
@@ -3261,8 +3257,8 @@ dict_create_foreign_constraints_low(
}
/* Starting from 4.0.18 and 4.1.2, we generate foreign key id's in the
- format databasename/tablename_ibfk_<number>, where <number> is local
- to the table; look for the highest <number> for table_to_alter, so
+ format databasename/tablename_ibfk_[number], where [number] is local
+ to the table; look for the highest [number] for table_to_alter, so
that we can assign to new constraints higher numbers. */
/* If we are altering a temporary table, the table name after ALTER
@@ -3422,8 +3418,7 @@ col_loop1:
ut_print_name(ef, NULL, TRUE, name);
fprintf(ef, " where the columns appear\n"
"as the first columns. Constraint:\n%s\n"
- "See http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-foreign-key-constraints.html\n"
+ "See " REFMAN "innodb-foreign-key-constraints.html\n"
"for correct foreign key definition.\n",
start_of_latest_foreign);
mutex_exit(&dict_foreign_err_mutex);
@@ -3703,7 +3698,7 @@ try_find_index:
" and such columns in old tables\n"
"cannot be referenced by such columns"
" in new tables.\n"
- "See http://dev.mysql.com/doc/refman/5.1/en/"
+ "See " REFMAN
"innodb-foreign-key-constraints.html\n"
"for correct foreign key definition.\n",
start_of_latest_foreign);
@@ -3742,19 +3737,19 @@ try_find_index:
goto loop;
}
-/*************************************************************************
+/*********************************************************************//**
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. Each foreign key constraint must
be accompanied with indexes in both participating tables. The indexes are
-allowed to contain more fields than mentioned in the constraint. */
+allowed to contain more fields than mentioned in the constraint.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
dict_create_foreign_constraints(
/*============================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in: transaction */
- const char* sql_string, /* in: table create statement where
+ trx_t* trx, /*!< in: transaction */
+ const char* sql_string, /*!< in: table create statement where
foreign keys are declared like:
FOREIGN KEY (a, b) REFERENCES
table2(c, d), table2 can be written
@@ -3762,10 +3757,10 @@ dict_create_foreign_constraints(
name before it: test.table2; the
default database id the database of
parameter name */
- const char* name, /* in: table full name in the
+ const char* name, /*!< in: table full name in the
normalized form
database_name/table_name */
- ibool reject_fks) /* in: if TRUE, fail with error
+ ibool reject_fks) /*!< in: if TRUE, fail with error
code DB_CANNOT_ADD_CONSTRAINT if
any foreign keys are found. */
{
@@ -3789,23 +3784,21 @@ dict_create_foreign_constraints(
return(err);
}
-/**************************************************************************
-Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement. */
+/**********************************************************************//**
+Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement.
+@return DB_SUCCESS or DB_CANNOT_DROP_CONSTRAINT if syntax error or the
+constraint id does not match */
UNIV_INTERN
ulint
dict_foreign_parse_drop_constraints(
/*================================*/
- /* out: DB_SUCCESS or
- DB_CANNOT_DROP_CONSTRAINT if
- syntax error or the constraint
- id does not match */
- mem_heap_t* heap, /* in: heap from which we can
+ mem_heap_t* heap, /*!< in: heap from which we can
allocate memory */
- trx_t* trx, /* in: transaction */
- dict_table_t* table, /* in: table */
- ulint* n, /* out: number of constraints
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table, /*!< in: table */
+ ulint* n, /*!< out: number of constraints
to drop */
- const char*** constraints_to_drop) /* out: id's of the
+ const char*** constraints_to_drop) /*!< out: id's of the
constraints to drop */
{
dict_foreign_t* foreign;
@@ -3923,19 +3916,18 @@ syntax_error:
return(DB_CANNOT_DROP_CONSTRAINT);
}
-#endif /* UNIV_HOTBACKUP */
/*==================== END OF FOREIGN KEY PROCESSING ====================*/
-/**************************************************************************
+/**********************************************************************//**
Returns an index object if it is found in the dictionary cache.
-Assumes that dict_sys->mutex is already being held. */
+Assumes that dict_sys->mutex is already being held.
+@return index, NULL if not found */
UNIV_INTERN
dict_index_t*
dict_index_get_if_in_cache_low(
/*===========================*/
- /* out: index, NULL if not found */
- dulint index_id) /* in: index id */
+ dulint index_id) /*!< in: index id */
{
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -3943,14 +3935,14 @@ dict_index_get_if_in_cache_low(
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**************************************************************************
-Returns an index object if it is found in the dictionary cache. */
+/**********************************************************************//**
+Returns an index object if it is found in the dictionary cache.
+@return index, NULL if not found */
UNIV_INTERN
dict_index_t*
dict_index_get_if_in_cache(
/*=======================*/
- /* out: index, NULL if not found */
- dulint index_id) /* in: index id */
+ dulint index_id) /*!< in: index id */
{
dict_index_t* index;
@@ -3969,16 +3961,16 @@ dict_index_get_if_in_cache(
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Checks that a tuple has n_fields_cmp value in a sensible range, so that
-no comparison can occur with the page number field in a node pointer. */
+no comparison can occur with the page number field in a node pointer.
+@return TRUE if ok */
UNIV_INTERN
ibool
dict_index_check_search_tuple(
/*==========================*/
- /* out: TRUE if ok */
- const dict_index_t* index, /* in: index tree */
- const dtuple_t* tuple) /* in: tuple used in a search */
+ const dict_index_t* index, /*!< in: index tree */
+ const dtuple_t* tuple) /*!< in: tuple used in a search */
{
ut_a(index);
ut_a(dtuple_get_n_fields_cmp(tuple)
@@ -3987,21 +3979,21 @@ dict_index_check_search_tuple(
}
#endif /* UNIV_DEBUG */
-/**************************************************************************
-Builds a node pointer out of a physical record and a page number. */
+/**********************************************************************//**
+Builds a node pointer out of a physical record and a page number.
+@return own: node pointer */
UNIV_INTERN
dtuple_t*
dict_index_build_node_ptr(
/*======================*/
- /* out, own: node pointer */
- const dict_index_t* index, /* in: index */
- const rec_t* rec, /* in: record for which to build node
+ const dict_index_t* index, /*!< in: index */
+ const rec_t* rec, /*!< in: record for which to build node
pointer */
- ulint page_no,/* in: page number to put in node
+ ulint page_no,/*!< in: page number to put in node
pointer */
- mem_heap_t* heap, /* in: memory heap where pointer
+ mem_heap_t* heap, /*!< in: memory heap where pointer
created */
- ulint level) /* in: level of rec in tree:
+ ulint level) /*!< in: level of rec in tree:
0 means leaf level */
{
dtuple_t* tuple;
@@ -4056,21 +4048,21 @@ dict_index_build_node_ptr(
return(tuple);
}
-/**************************************************************************
+/**********************************************************************//**
Copies an initial segment of a physical record, long enough to specify an
-index entry uniquely. */
+index entry uniquely.
+@return pointer to the prefix record */
UNIV_INTERN
rec_t*
dict_index_copy_rec_order_prefix(
/*=============================*/
- /* out: pointer to the prefix record */
- const dict_index_t* index, /* in: index */
- const rec_t* rec, /* in: record for which to
+ const dict_index_t* index, /*!< in: index */
+ const rec_t* rec, /*!< in: record for which to
copy prefix */
- ulint* n_fields,/* out: number of fields copied */
- byte** buf, /* in/out: memory buffer for the
+ ulint* n_fields,/*!< out: number of fields copied */
+ byte** buf, /*!< in/out: memory buffer for the
copied prefix, or NULL */
- ulint* buf_size)/* in/out: buffer size */
+ ulint* buf_size)/*!< in/out: buffer size */
{
ulint n;
@@ -4087,17 +4079,17 @@ dict_index_copy_rec_order_prefix(
return(rec_copy_prefix_to_buf(rec, index, n, buf, buf_size));
}
-/**************************************************************************
-Builds a typed data tuple out of a physical record. */
+/**********************************************************************//**
+Builds a typed data tuple out of a physical record.
+@return own: data tuple */
UNIV_INTERN
dtuple_t*
dict_index_build_data_tuple(
/*========================*/
- /* out, own: data tuple */
- dict_index_t* index, /* in: index tree */
- rec_t* rec, /* in: record for which to build data tuple */
- ulint n_fields,/* in: number of data fields */
- mem_heap_t* heap) /* in: memory heap where tuple created */
+ dict_index_t* index, /*!< in: index tree */
+ rec_t* rec, /*!< in: record for which to build data tuple */
+ ulint n_fields,/*!< in: number of data fields */
+ mem_heap_t* heap) /*!< in: memory heap where tuple created */
{
dtuple_t* tuple;
@@ -4115,24 +4107,25 @@ dict_index_build_data_tuple(
return(tuple);
}
-/*************************************************************************
+/*********************************************************************//**
Calculates the minimum record length in an index. */
UNIV_INTERN
ulint
dict_index_calc_min_rec_len(
/*========================*/
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ulint sum = 0;
ulint i;
+ ulint comp = dict_table_is_comp(index->table);
- if (dict_table_is_comp(index->table)) {
+ if (comp) {
ulint nullable = 0;
sum = REC_N_NEW_EXTRA_BYTES;
for (i = 0; i < dict_index_get_n_fields(index); i++) {
const dict_col_t* col
= dict_index_get_nth_col(index, i);
- ulint size = dict_col_get_fixed_size(col);
+ ulint size = dict_col_get_fixed_size(col, comp);
sum += size;
if (!size) {
size = col->len;
@@ -4151,7 +4144,7 @@ dict_index_calc_min_rec_len(
for (i = 0; i < dict_index_get_n_fields(index); i++) {
sum += dict_col_get_fixed_size(
- dict_index_get_nth_col(index, i));
+ dict_index_get_nth_col(index, i), comp);
}
if (sum > 127) {
@@ -4165,16 +4158,16 @@ dict_index_calc_min_rec_len(
return(sum);
}
-/*************************************************************************
+/*********************************************************************//**
Calculates new estimates for table and index statistics. The statistics
are used in query optimization. */
UNIV_INTERN
void
dict_update_statistics_low(
/*=======================*/
- dict_table_t* table, /* in/out: table */
+ dict_table_t* table, /*!< in/out: table */
ibool has_dict_mutex __attribute__((unused)))
- /* in: TRUE if the caller has the
+ /*!< in: TRUE if the caller has the
dictionary mutex */
{
dict_index_t* index;
@@ -4187,8 +4180,7 @@ dict_update_statistics_low(
" InnoDB: cannot calculate statistics for table %s\n"
"InnoDB: because the .ibd file is missing. For help,"
" please refer to\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n",
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n",
table->name);
return;
@@ -4249,25 +4241,25 @@ dict_update_statistics_low(
table->stat_modified_counter = 0;
}
-/*************************************************************************
+/*********************************************************************//**
Calculates new estimates for table and index statistics. The statistics
are used in query optimization. */
UNIV_INTERN
void
dict_update_statistics(
/*===================*/
- dict_table_t* table) /* in/out: table */
+ dict_table_t* table) /*!< in/out: table */
{
dict_update_statistics_low(table, FALSE);
}
-/**************************************************************************
+/**********************************************************************//**
Prints info of a foreign key constraint. */
static
void
dict_foreign_print_low(
/*===================*/
- dict_foreign_t* foreign) /* in: foreign key constraint */
+ dict_foreign_t* foreign) /*!< in: foreign key constraint */
{
ulint i;
@@ -4291,26 +4283,26 @@ dict_foreign_print_low(
fputs(" )\n", stderr);
}
-/**************************************************************************
+/**********************************************************************//**
Prints a table data. */
UNIV_INTERN
void
dict_table_print(
/*=============*/
- dict_table_t* table) /* in: table */
+ dict_table_t* table) /*!< in: table */
{
mutex_enter(&(dict_sys->mutex));
dict_table_print_low(table);
mutex_exit(&(dict_sys->mutex));
}
-/**************************************************************************
+/**********************************************************************//**
Prints a table data when we know the table name. */
UNIV_INTERN
void
dict_table_print_by_name(
/*=====================*/
- const char* name)
+ const char* name) /*!< in: table name */
{
dict_table_t* table;
@@ -4324,13 +4316,13 @@ dict_table_print_by_name(
mutex_exit(&(dict_sys->mutex));
}
-/**************************************************************************
+/**********************************************************************//**
Prints a table data. */
UNIV_INTERN
void
dict_table_print_low(
/*=================*/
- dict_table_t* table) /* in: table */
+ dict_table_t* table) /*!< in: table */
{
dict_index_t* index;
dict_foreign_t* foreign;
@@ -4354,7 +4346,7 @@ dict_table_print_low(
(ulong) UT_LIST_GET_LEN(table->indexes),
(ulong) table->stat_n_rows);
- for (i = 0; i + 1 < (ulint) table->n_cols; i++) {
+ for (i = 0; i < (ulint) table->n_cols; i++) {
dict_col_print_low(table, dict_table_get_nth_col(table, i));
fputs("; ", stderr);
}
@@ -4383,14 +4375,14 @@ dict_table_print_low(
}
}
-/**************************************************************************
+/**********************************************************************//**
Prints a column data. */
static
void
dict_col_print_low(
/*===============*/
- const dict_table_t* table, /* in: table */
- const dict_col_t* col) /* in: column */
+ const dict_table_t* table, /*!< in: table */
+ const dict_col_t* col) /*!< in: column */
{
dtype_t type;
@@ -4403,13 +4395,13 @@ dict_col_print_low(
dtype_print(&type);
}
-/**************************************************************************
+/**********************************************************************//**
Prints an index data. */
static
void
dict_index_print_low(
/*=================*/
- dict_index_t* index) /* in: index */
+ dict_index_t* index) /*!< in: index */
{
ib_int64_t n_vals;
ulint i;
@@ -4463,13 +4455,13 @@ dict_index_print_low(
#endif /* UNIV_BTR_PRINT */
}
-/**************************************************************************
+/**********************************************************************//**
Prints a field data. */
static
void
dict_field_print_low(
/*=================*/
- dict_field_t* field) /* in: field */
+ dict_field_t* field) /*!< in: field */
{
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -4480,17 +4472,17 @@ dict_field_print_low(
}
}
-/**************************************************************************
+/**********************************************************************//**
Outputs info on a foreign key of a table in a format suitable for
CREATE TABLE. */
UNIV_INTERN
void
dict_print_info_on_foreign_key_in_create_format(
/*============================================*/
- FILE* file, /* in: file where to print */
- trx_t* trx, /* in: transaction */
- dict_foreign_t* foreign, /* in: foreign key constraint */
- ibool add_newline) /* in: whether to add a newline */
+ FILE* file, /*!< in: file where to print */
+ trx_t* trx, /*!< in: transaction */
+ dict_foreign_t* foreign, /*!< in: foreign key constraint */
+ ibool add_newline) /*!< in: whether to add a newline */
{
const char* stripped_id;
ulint i;
@@ -4578,19 +4570,19 @@ dict_print_info_on_foreign_key_in_create_format(
}
}
-/**************************************************************************
+/**********************************************************************//**
Outputs info on foreign keys of a table. */
UNIV_INTERN
void
dict_print_info_on_foreign_keys(
/*============================*/
- ibool create_table_format, /* in: if TRUE then print in
+ ibool create_table_format, /*!< in: if TRUE then print in
a format suitable to be inserted into
a CREATE TABLE, otherwise in the format
of SHOW TABLE STATUS */
- FILE* file, /* in: file where to print */
- trx_t* trx, /* in: transaction */
- dict_table_t* table) /* in: table */
+ FILE* file, /*!< in: file where to print */
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table) /*!< in: table */
{
dict_foreign_t* foreign;
@@ -4668,31 +4660,67 @@ dict_print_info_on_foreign_keys(
mutex_exit(&(dict_sys->mutex));
}
-/************************************************************************
+/********************************************************************//**
Displays the names of the index and the table. */
UNIV_INTERN
void
dict_index_name_print(
/*==================*/
- FILE* file, /* in: output stream */
- trx_t* trx, /* in: transaction */
- const dict_index_t* index) /* in: index to print */
+ FILE* file, /*!< in: output stream */
+ trx_t* trx, /*!< in: transaction */
+ const dict_index_t* index) /*!< in: index to print */
{
fputs("index ", file);
ut_print_name(file, trx, FALSE, index->name);
fputs(" of table ", file);
ut_print_name(file, trx, TRUE, index->table_name);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
-Get index by name */
+/**********************************************************************//**
+Inits dict_ind_redundant and dict_ind_compact. */
+UNIV_INTERN
+void
+dict_ind_init(void)
+/*===============*/
+{
+ dict_table_t* table;
+
+ /* create dummy table and index for REDUNDANT infimum and supremum */
+ table = dict_mem_table_create("SYS_DUMMY1", DICT_HDR_SPACE, 1, 0);
+ dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
+ DATA_ENGLISH | DATA_NOT_NULL, 8);
+
+ dict_ind_redundant = dict_mem_index_create("SYS_DUMMY1", "SYS_DUMMY1",
+ DICT_HDR_SPACE, 0, 1);
+ dict_index_add_col(dict_ind_redundant, table,
+ dict_table_get_nth_col(table, 0), 0);
+ dict_ind_redundant->table = table;
+ /* create dummy table and index for COMPACT infimum and supremum */
+ table = dict_mem_table_create("SYS_DUMMY2",
+ DICT_HDR_SPACE, 1, DICT_TF_COMPACT);
+ dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
+ DATA_ENGLISH | DATA_NOT_NULL, 8);
+ dict_ind_compact = dict_mem_index_create("SYS_DUMMY2", "SYS_DUMMY2",
+ DICT_HDR_SPACE, 0, 1);
+ dict_index_add_col(dict_ind_compact, table,
+ dict_table_get_nth_col(table, 0), 0);
+ dict_ind_compact->table = table;
+
+ /* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
+ dict_ind_redundant->cached = dict_ind_compact->cached = TRUE;
+}
+
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
+Get index by name
+@return index, NULL if does not exist */
UNIV_INTERN
dict_index_t*
dict_table_get_index_on_name(
/*=========================*/
- /* out: index, NULL if does not exist */
- dict_table_t* table, /* in: table */
- const char* name) /* in: name of the index to find */
+ dict_table_t* table, /*!< in: table */
+ const char* name) /*!< in: name of the index to find */
{
dict_index_t* index;
@@ -4711,15 +4739,15 @@ dict_table_get_index_on_name(
}
-/**************************************************************************
+/**********************************************************************//**
Replace the index passed in with another equivalent index in the tables
foreign key list. */
UNIV_INTERN
void
dict_table_replace_index_in_foreign_list(
/*=====================================*/
- dict_table_t* table, /* in/out: table */
- dict_index_t* index) /* in: index to be replaced */
+ dict_table_t* table, /*!< in/out: table */
+ dict_index_t* index) /*!< in: index to be replaced */
{
dict_foreign_t* foreign;
@@ -4737,16 +4765,16 @@ dict_table_replace_index_in_foreign_list(
}
}
-/**************************************************************************
+/**********************************************************************//**
In case there is more than one index with the same name return the index
-with the min(id). */
+with the min(id).
+@return index, NULL if does not exist */
UNIV_INTERN
dict_index_t*
dict_table_get_index_on_name_and_min_id(
/*=====================================*/
- /* out: index, NULL if does not exist */
- dict_table_t* table, /* in: table */
- const char* name) /* in: name of the index to find */
+ dict_table_t* table, /*!< in: table */
+ const char* name) /*!< in: name of the index to find */
{
dict_index_t* index;
dict_index_t* min_index; /* Index with matching name and min(id) */
@@ -4771,13 +4799,13 @@ dict_table_get_index_on_name_and_min_id(
}
#ifdef UNIV_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Check for duplicate index entries in a table [using the index name] */
UNIV_INTERN
void
dict_table_check_for_dup_indexes(
/*=============================*/
- const dict_table_t* table) /* in: Check for dup indexes
+ const dict_table_t* table) /*!< in: Check for dup indexes
in this table */
{
/* Check for duplicates, ignoring indexes that are marked
@@ -4808,3 +4836,4 @@ dict_table_check_for_dup_indexes(
}
}
#endif /* UNIV_DEBUG */
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/dict/dict0load.c b/storage/xtradb/dict/dict0load.c
index 0e3f3c04c1f..46cce5050cd 100644
--- a/storage/xtradb/dict/dict0load.c
+++ b/storage/xtradb/dict/dict0load.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file dict/dict0load.c
Loads to the memory cache database object definitions
from dictionary tables
@@ -24,9 +25,7 @@ Created 4/24/1996 Heikki Tuuri
*******************************************************/
#include "dict0load.h"
-#ifndef UNIV_HOTBACKUP
#include "mysql_version.h"
-#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_NONINL
#include "dict0load.ic"
@@ -42,17 +41,17 @@ Created 4/24/1996 Heikki Tuuri
#include "srv0start.h"
#include "srv0srv.h"
-/********************************************************************
-Returns TRUE if index's i'th column's name is 'name' .*/
+/****************************************************************//**
+Compare the name of an index column.
+@return TRUE if the i'th column of index is 'name'. */
static
ibool
name_of_col_is(
/*===========*/
- /* out: */
- dict_table_t* table, /* in: table */
- dict_index_t* index, /* in: index */
- ulint i, /* in: */
- const char* name) /* in: name to compare to */
+ const dict_table_t* table, /*!< in: table */
+ const dict_index_t* index, /*!< in: index */
+ ulint i, /*!< in: index field offset */
+ const char* name) /*!< in: name to compare to */
{
ulint tmp = dict_col_get_no(dict_field_get_col(
dict_index_get_nth_field(
@@ -61,16 +60,15 @@ name_of_col_is(
return(strcmp(name, dict_table_get_col_name(table, tmp)) == 0);
}
-/************************************************************************
-Finds the first table name in the given database. */
+/********************************************************************//**
+Finds the first table name in the given database.
+@return own: table name, NULL if does not exist; the caller must free
+the memory in the string! */
UNIV_INTERN
char*
dict_get_first_table_name_in_db(
/*============================*/
- /* out, own: table name, NULL if
- does not exist; the caller must
- free the memory in the string! */
- const char* name) /* in: database name which ends in '/' */
+ const char* name) /*!< in: database name which ends in '/' */
{
dict_table_t* sys_tables;
btr_pcur_t pcur;
@@ -145,7 +143,7 @@ loop:
goto loop;
}
-/************************************************************************
+/********************************************************************//**
Prints to the standard output information on all tables found in the data
dictionary system table. */
UNIV_INTERN
@@ -238,16 +236,15 @@ loop:
goto loop;
}
-/************************************************************************
-Determine the flags of a table described in SYS_TABLES. */
+/********************************************************************//**
+Determine the flags of a table described in SYS_TABLES.
+@return compressed page size in kilobytes; or 0 if the tablespace is
+uncompressed, ULINT_UNDEFINED on error */
static
ulint
dict_sys_tables_get_flags(
/*======================*/
- /* out: compressed page size in kilobytes;
- or 0 if the tablespace is uncompressed,
- ULINT_UNDEFINED on error */
- const rec_t* rec) /* in: a record of SYS_TABLES */
+ const rec_t* rec) /*!< in: a record of SYS_TABLES */
{
const byte* field;
ulint len;
@@ -301,7 +298,7 @@ dict_sys_tables_get_flags(
return(flags);
}
-/************************************************************************
+/********************************************************************//**
In a crash recovery we already have all the tablespace objects created.
This function compares the space id information in the InnoDB data dictionary
to what we already read with fil_load_single_table_tablespaces().
@@ -313,7 +310,7 @@ UNIV_INTERN
void
dict_check_tablespaces_and_store_max_id(
/*====================================*/
- ibool in_crash_recovery) /* in: are we doing a crash recovery */
+ ibool in_crash_recovery) /*!< in: are we doing a crash recovery */
{
dict_table_t* sys_tables;
dict_index_t* sys_index;
@@ -423,14 +420,14 @@ loop:
goto loop;
}
-/************************************************************************
+/********************************************************************//**
Loads definitions for table columns. */
static
void
dict_load_columns(
/*==============*/
- dict_table_t* table, /* in: table */
- mem_heap_t* heap) /* in: memory heap for temporary storage */
+ dict_table_t* table, /*!< in: table */
+ mem_heap_t* heap) /*!< in: memory heap for temporary storage */
{
dict_table_t* sys_columns;
dict_index_t* sys_index;
@@ -529,14 +526,14 @@ dict_load_columns(
mtr_commit(&mtr);
}
-/************************************************************************
+/********************************************************************//**
Loads definitions for index fields. */
static
void
dict_load_fields(
/*=============*/
- dict_index_t* index, /* in: index whose fields to load */
- mem_heap_t* heap) /* in: memory heap for temporary storage */
+ dict_index_t* index, /*!< in: index whose fields to load */
+ mem_heap_t* heap) /*!< in: memory heap for temporary storage */
{
dict_table_t* sys_fields;
dict_index_t* sys_index;
@@ -630,19 +627,17 @@ next_rec:
mtr_commit(&mtr);
}
-/************************************************************************
+/********************************************************************//**
Loads definitions for table indexes. Adds them to the data dictionary
-cache. */
+cache.
+@return DB_SUCCESS if ok, DB_CORRUPTION if corruption of dictionary
+table or DB_UNSUPPORTED if table has unknown index type */
static
ulint
dict_load_indexes(
/*==============*/
- /* out: DB_SUCCESS if ok, DB_CORRUPTION
- if corruption of dictionary table or
- DB_UNSUPPORTED if table has unknown index
- type */
- dict_table_t* table, /* in: table */
- mem_heap_t* heap) /* in: memory heap for temporary storage */
+ dict_table_t* table, /*!< in: table */
+ mem_heap_t* heap) /*!< in: memory heap for temporary storage */
{
dict_table_t* sys_indexes;
dict_index_t* sys_index;
@@ -805,22 +800,20 @@ func_exit:
return(error);
}
-/************************************************************************
+/********************************************************************//**
Loads a table definition and also all its index definitions, and also
the cluster definition if the table is a member in a cluster. Also loads
all foreign key constraints where the foreign key is in the table or where
a foreign key references columns in this table. Adds all these to the data
-dictionary cache. */
+dictionary cache.
+@return table, NULL if does not exist; if the table is stored in an
+.ibd file, but the file does not exist, then we set the
+ibd_file_missing flag TRUE in the table object we return */
UNIV_INTERN
dict_table_t*
dict_load_table(
/*============*/
- /* out: table, NULL if does not exist;
- if the table is stored in an .ibd file,
- but the file does not exist,
- then we set the ibd_file_missing flag TRUE
- in the table object we return */
- const char* name) /* in: table name in the
+ const char* name) /*!< in: table name in the
databasename/tablename format */
{
ibool ibd_file_missing = FALSE;
@@ -960,7 +953,7 @@ err_exit:
mem_heap_empty(heap);
err = dict_load_indexes(table, heap);
-#ifndef UNIV_HOTBACKUP
+
/* If the force recovery flag is set, we open the table irrespective
of the error condition, since the user may want to dump data from the
clustered index. However we load the foreign key information only if
@@ -971,7 +964,7 @@ err_exit:
dict_table_remove_from_cache(table);
table = NULL;
}
-# if 0
+#if 0
if (err != DB_SUCCESS && table != NULL) {
mutex_enter(&dict_foreign_err_mutex);
@@ -994,21 +987,20 @@ err_exit:
mutex_exit(&dict_foreign_err_mutex);
}
-# endif /* 0 */
-#endif /* !UNIV_HOTBACKUP */
+#endif /* 0 */
mem_heap_free(heap);
return(table);
}
-/***************************************************************************
-Loads a table object based on the table id. */
+/***********************************************************************//**
+Loads a table object based on the table id.
+@return table; NULL if table does not exist */
UNIV_INTERN
dict_table_t*
dict_load_table_on_id(
/*==================*/
- /* out: table; NULL if table does not exist */
- dulint table_id) /* in: table id */
+ dulint table_id) /*!< in: table id */
{
byte id_buf[8];
btr_pcur_t pcur;
@@ -1092,7 +1084,7 @@ dict_load_table_on_id(
return(table);
}
-/************************************************************************
+/********************************************************************//**
This function is called when the database is booted. Loads system table
index definitions except for the clustered index which is added to the
dictionary cache at booting before calling this function. */
@@ -1100,7 +1092,7 @@ UNIV_INTERN
void
dict_load_sys_table(
/*================*/
- dict_table_t* table) /* in: system table */
+ dict_table_t* table) /*!< in: system table */
{
mem_heap_t* heap;
@@ -1113,16 +1105,15 @@ dict_load_sys_table(
mem_heap_free(heap);
}
-#ifndef UNIV_HOTBACKUP
-/************************************************************************
+/********************************************************************//**
Loads foreign key constraint col names (also for the referenced table). */
static
void
dict_load_foreign_cols(
/*===================*/
- const char* id, /* in: foreign constraint id as a
+ const char* id, /*!< in: foreign constraint id as a
null-terminated string */
- dict_foreign_t* foreign)/* in: foreign constraint object */
+ dict_foreign_t* foreign)/*!< in: foreign constraint object */
{
dict_table_t* sys_foreign_cols;
dict_index_t* sys_index;
@@ -1186,17 +1177,17 @@ dict_load_foreign_cols(
mtr_commit(&mtr);
}
-/***************************************************************************
-Loads a foreign key constraint to the dictionary cache. */
+/***********************************************************************//**
+Loads a foreign key constraint to the dictionary cache.
+@return DB_SUCCESS or error code */
static
ulint
dict_load_foreign(
/*==============*/
- /* out: DB_SUCCESS or error code */
- const char* id, /* in: foreign constraint id as a
+ const char* id, /*!< in: foreign constraint id as a
null-terminated string */
ibool check_charsets)
- /* in: TRUE=check charset compatibility */
+ /*!< in: TRUE=check charset compatibility */
{
dict_foreign_t* foreign;
dict_table_t* sys_foreign;
@@ -1311,19 +1302,19 @@ dict_load_foreign(
return(dict_foreign_add_to_cache(foreign, check_charsets));
}
-/***************************************************************************
+/***********************************************************************//**
Loads foreign key constraints where the table is either the foreign key
holder or where the table is referenced by a foreign key. Adds these
constraints to the data dictionary. Note that we know that the dictionary
cache already contains all constraints where the other relevant table is
-already in the dictionary cache. */
+already in the dictionary cache.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_load_foreigns(
/*===============*/
- /* out: DB_SUCCESS or error code */
- const char* table_name, /* in: table name */
- ibool check_charsets) /* in: TRUE=check charset
+ const char* table_name, /*!< in: table name */
+ ibool check_charsets) /*!< in: TRUE=check charset
compatibility */
{
btr_pcur_t pcur;
@@ -1457,4 +1448,3 @@ load_next_index:
return(DB_SUCCESS);
}
-#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/dict/dict0mem.c b/storage/xtradb/dict/dict0mem.c
index 31c0c23f450..6458cbab92d 100644
--- a/storage/xtradb/dict/dict0mem.c
+++ b/storage/xtradb/dict/dict0mem.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file dict/dict0mem.c
Data dictionary memory object creation
Created 1/8/1996 Heikki Tuuri
@@ -32,25 +33,27 @@ Created 1/8/1996 Heikki Tuuri
#include "data0type.h"
#include "mach0data.h"
#include "dict0dict.h"
-#include "lock0lock.h"
+#ifndef UNIV_HOTBACKUP
+# include "lock0lock.h"
+#endif /* !UNIV_HOTBACKUP */
-#define DICT_HEAP_SIZE 100 /* initial memory heap size when
+#define DICT_HEAP_SIZE 100 /*!< initial memory heap size when
creating a table or index object */
-/**************************************************************************
-Creates a table memory object. */
+/**********************************************************************//**
+Creates a table memory object.
+@return own: table object */
UNIV_INTERN
dict_table_t*
dict_mem_table_create(
/*==================*/
- /* out, own: table object */
- const char* name, /* in: table name */
- ulint space, /* in: space where the clustered index of
+ const char* name, /*!< in: table name */
+ ulint space, /*!< in: space where the clustered index of
the table is placed; this parameter is
ignored if the table is made a member of
a cluster */
- ulint n_cols, /* in: number of columns */
- ulint flags) /* in: table flags */
+ ulint n_cols, /*!< in: number of columns */
+ ulint flags) /*!< in: table flags */
{
dict_table_t* table;
mem_heap_t* heap;
@@ -72,6 +75,7 @@ dict_mem_table_create(
table->cols = mem_heap_alloc(heap, (n_cols + DATA_N_SYS_COLS)
* sizeof(dict_col_t));
+#ifndef UNIV_HOTBACKUP
table->autoinc_lock = mem_heap_alloc(heap, lock_get_size());
mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX);
@@ -81,41 +85,42 @@ dict_mem_table_create(
/* The number of transactions that are either waiting on the
AUTOINC lock or have been granted the lock. */
table->n_waiting_or_granted_auto_inc_locks = 0;
+#endif /* !UNIV_HOTBACKUP */
-#ifdef UNIV_DEBUG
- table->magic_n = DICT_TABLE_MAGIC_N;
-#endif /* UNIV_DEBUG */
+ ut_d(table->magic_n = DICT_TABLE_MAGIC_N);
return(table);
}
-/********************************************************************
+/****************************************************************//**
Free a table memory object. */
UNIV_INTERN
void
dict_mem_table_free(
/*================*/
- dict_table_t* table) /* in: table */
+ dict_table_t* table) /*!< in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
ut_d(table->cached = FALSE);
+#ifndef UNIV_HOTBACKUP
mutex_free(&(table->autoinc_mutex));
+#endif /* UNIV_HOTBACKUP */
mem_heap_free(table->heap);
}
-/********************************************************************
-Append 'name' to 'col_names' (@see dict_table_t::col_names). */
+/****************************************************************//**
+Append 'name' to 'col_names'. @see dict_table_t::col_names
+@return new column names array */
static
const char*
dict_add_col_name(
/*==============*/
- /* out: new column names array */
- const char* col_names, /* in: existing column names, or
+ const char* col_names, /*!< in: existing column names, or
NULL */
- ulint cols, /* in: number of existing columns */
- const char* name, /* in: new column name */
- mem_heap_t* heap) /* in: heap */
+ ulint cols, /*!< in: number of existing columns */
+ const char* name, /*!< in: new column name */
+ mem_heap_t* heap) /*!< in: heap */
{
ulint old_len;
ulint new_len;
@@ -152,22 +157,24 @@ dict_add_col_name(
return(res);
}
-/**************************************************************************
+/**********************************************************************//**
Adds a column definition to a table. */
UNIV_INTERN
void
dict_mem_table_add_col(
/*===================*/
- dict_table_t* table, /* in: table */
- mem_heap_t* heap, /* in: temporary memory heap, or NULL */
- const char* name, /* in: column name, or NULL */
- ulint mtype, /* in: main datatype */
- ulint prtype, /* in: precise type */
- ulint len) /* in: precision */
+ dict_table_t* table, /*!< in: table */
+ mem_heap_t* heap, /*!< in: temporary memory heap, or NULL */
+ const char* name, /*!< in: column name, or NULL */
+ ulint mtype, /*!< in: main datatype */
+ ulint prtype, /*!< in: precise type */
+ ulint len) /*!< in: precision */
{
dict_col_t* col;
+#ifndef UNIV_HOTBACKUP
ulint mbminlen;
ulint mbmaxlen;
+#endif /* !UNIV_HOTBACKUP */
ulint i;
ut_ad(table);
@@ -199,27 +206,29 @@ dict_mem_table_add_col(
col->prtype = (unsigned int) prtype;
col->len = (unsigned int) len;
+#ifndef UNIV_HOTBACKUP
dtype_get_mblen(mtype, prtype, &mbminlen, &mbmaxlen);
col->mbminlen = (unsigned int) mbminlen;
col->mbmaxlen = (unsigned int) mbmaxlen;
+#endif /* !UNIV_HOTBACKUP */
}
-/**************************************************************************
-Creates an index memory object. */
+/**********************************************************************//**
+Creates an index memory object.
+@return own: index object */
UNIV_INTERN
dict_index_t*
dict_mem_index_create(
/*==================*/
- /* out, own: index object */
- const char* table_name, /* in: table name */
- const char* index_name, /* in: index name */
- ulint space, /* in: space where the index tree is
+ const char* table_name, /*!< in: table name */
+ const char* index_name, /*!< in: index name */
+ ulint space, /*!< in: space where the index tree is
placed, ignored if the index is of
the clustered type */
- ulint type, /* in: DICT_UNIQUE,
+ ulint type, /*!< in: DICT_UNIQUE,
DICT_CLUSTERED, ... ORed */
- ulint n_fields) /* in: number of fields */
+ ulint n_fields) /*!< in: number of fields */
{
dict_index_t* index;
mem_heap_t* heap;
@@ -232,7 +241,9 @@ dict_mem_index_create(
index->heap = heap;
index->type = type;
+#ifndef UNIV_HOTBACKUP
index->space = (unsigned int) space;
+#endif /* !UNIV_HOTBACKUP */
index->name = mem_heap_strdup(heap, index_name);
index->table_name = table_name;
index->n_fields = (unsigned int) n_fields;
@@ -246,13 +257,13 @@ dict_mem_index_create(
return(index);
}
-/**************************************************************************
-Creates and initializes a foreign constraint memory object. */
+/**********************************************************************//**
+Creates and initializes a foreign constraint memory object.
+@return own: foreign constraint struct */
UNIV_INTERN
dict_foreign_t*
dict_mem_foreign_create(void)
/*=========================*/
- /* out, own: foreign constraint struct */
{
dict_foreign_t* foreign;
mem_heap_t* heap;
@@ -266,7 +277,7 @@ dict_mem_foreign_create(void)
return(foreign);
}
-/**************************************************************************
+/**********************************************************************//**
Adds a field definition to an index. NOTE: does not take a copy
of the column name if the field is a column. The memory occupied
by the column name may be released only after publishing the index. */
@@ -274,9 +285,9 @@ UNIV_INTERN
void
dict_mem_index_add_field(
/*=====================*/
- dict_index_t* index, /* in: index */
- const char* name, /* in: column name */
- ulint prefix_len) /* in: 0 or the column prefix length
+ dict_index_t* index, /*!< in: index */
+ const char* name, /*!< in: column name */
+ ulint prefix_len) /*!< in: 0 or the column prefix length
in a MySQL index like
INDEX (textcol(25)) */
{
@@ -293,13 +304,13 @@ dict_mem_index_add_field(
field->prefix_len = (unsigned int) prefix_len;
}
-/**************************************************************************
+/**********************************************************************//**
Frees an index memory object. */
UNIV_INTERN
void
dict_mem_index_free(
/*================*/
- dict_index_t* index) /* in: index */
+ dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
diff --git a/storage/xtradb/dyn/dyn0dyn.c b/storage/xtradb/dyn/dyn0dyn.c
index 16e82eaed66..e1275f040f3 100644
--- a/storage/xtradb/dyn/dyn0dyn.c
+++ b/storage/xtradb/dyn/dyn0dyn.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file dyn/dyn0dyn.c
The dynamically allocated array
Created 2/5/1996 Heikki Tuuri
@@ -27,14 +28,14 @@ Created 2/5/1996 Heikki Tuuri
#include "dyn0dyn.ic"
#endif
-/****************************************************************
-Adds a new block to a dyn array. */
+/************************************************************//**
+Adds a new block to a dyn array.
+@return created block */
UNIV_INTERN
dyn_block_t*
dyn_array_add_block(
/*================*/
- /* out: created block */
- dyn_array_t* arr) /* in: dyn array */
+ dyn_array_t* arr) /*!< in: dyn array */
{
mem_heap_t* heap;
dyn_block_t* block;
diff --git a/storage/xtradb/eval/eval0eval.c b/storage/xtradb/eval/eval0eval.c
index a2590c63c38..589b0fa1576 100644
--- a/storage/xtradb/eval/eval0eval.c
+++ b/storage/xtradb/eval/eval0eval.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file eval/eval0eval.c
SQL evaluator: evaluates simple data structures, like expressions, in
a query graph
@@ -32,29 +33,29 @@ Created 12/29/1997 Heikki Tuuri
#include "data0data.h"
#include "row0sel.h"
-/* The RND function seed */
+/** The RND function seed */
static ulint eval_rnd = 128367121;
-/* Dummy adress used when we should allocate a buffer of size 0 in
-the function below */
+/** Dummy adress used when we should allocate a buffer of size 0 in
+eval_node_alloc_val_buf */
static byte eval_dummy;
-/*********************************************************************
+/*****************************************************************//**
Allocate a buffer from global dynamic memory for a value of a que_node.
NOTE that this memory must be explicitly freed when the query graph is
freed. If the node already has an allocated buffer, that buffer is freed
here. NOTE that this is the only function where dynamic memory should be
-allocated for a query node val field. */
+allocated for a query node val field.
+@return pointer to allocated buffer */
UNIV_INTERN
byte*
eval_node_alloc_val_buf(
/*====================*/
- /* out: pointer to allocated buffer */
- que_node_t* node, /* in: query graph node; sets the val field
+ que_node_t* node, /*!< in: query graph node; sets the val field
data field to point to the new buffer, and
len field equal to size */
- ulint size) /* in: buffer size */
+ ulint size) /*!< in: buffer size */
{
dfield_t* dfield;
byte* data;
@@ -83,7 +84,7 @@ eval_node_alloc_val_buf(
return(data);
}
-/*********************************************************************
+/*****************************************************************//**
Free the buffer from global dynamic memory for a value of a que_node,
if it has been allocated in the above function. The freeing for pushed
column values is done in sel_col_prefetch_buf_free. */
@@ -91,7 +92,7 @@ UNIV_INTERN
void
eval_node_free_val_buf(
/*===================*/
- que_node_t* node) /* in: query graph node */
+ que_node_t* node) /*!< in: query graph node */
{
dfield_t* dfield;
byte* data;
@@ -110,14 +111,14 @@ eval_node_free_val_buf(
}
}
-/*********************************************************************
-Evaluates a comparison node. */
+/*****************************************************************//**
+Evaluates a comparison node.
+@return the result of the comparison */
UNIV_INTERN
ibool
eval_cmp(
/*=====*/
- /* out: the result of the comparison */
- func_node_t* cmp_node) /* in: comparison node */
+ func_node_t* cmp_node) /*!< in: comparison node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -169,13 +170,13 @@ eval_cmp(
return(val);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a logical operation node. */
UNIV_INLINE
void
eval_logical(
/*=========*/
- func_node_t* logical_node) /* in: logical operation node */
+ func_node_t* logical_node) /*!< in: logical operation node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -210,13 +211,13 @@ eval_logical(
eval_node_set_ibool_val(logical_node, val);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates an arithmetic operation node. */
UNIV_INLINE
void
eval_arith(
/*=======*/
- func_node_t* arith_node) /* in: arithmetic operation node */
+ func_node_t* arith_node) /*!< in: arithmetic operation node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -254,13 +255,13 @@ eval_arith(
eval_node_set_int_val(arith_node, val);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates an aggregate operation node. */
UNIV_INLINE
void
eval_aggregate(
/*===========*/
- func_node_t* node) /* in: aggregate operation node */
+ func_node_t* node) /*!< in: aggregate operation node */
{
que_node_t* arg;
lint val;
@@ -288,14 +289,14 @@ eval_aggregate(
eval_node_set_int_val(node, val);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a predefined function node where the function is not relevant
in benchmarks. */
static
void
eval_predefined_2(
/*==============*/
- func_node_t* func_node) /* in: predefined function node */
+ func_node_t* func_node) /*!< in: predefined function node */
{
que_node_t* arg;
que_node_t* arg1;
@@ -375,13 +376,13 @@ eval_predefined_2(
}
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a notfound-function node. */
UNIV_INLINE
void
eval_notfound(
/*==========*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -417,13 +418,13 @@ eval_notfound(
eval_node_set_ibool_val(func_node, ibool_val);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a substr-function node. */
UNIV_INLINE
void
eval_substr(
/*========*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -450,13 +451,13 @@ eval_substr(
dfield_set_data(dfield, str1 + len1, len2);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a replstr-procedure node. */
static
void
eval_replstr(
/*=========*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -490,13 +491,13 @@ eval_replstr(
ut_memcpy(str1 + len1, str2, len2);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates an instr-function node. */
static
void
eval_instr(
/*=======*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -562,13 +563,13 @@ match_found:
eval_node_set_int_val(func_node, int_val);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a predefined function node. */
UNIV_INLINE
void
eval_binary_to_number(
/*==================*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
dfield_t* dfield;
@@ -600,13 +601,13 @@ eval_binary_to_number(
eval_node_copy_and_alloc_val(func_node, str2, 4);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a predefined function node. */
static
void
eval_concat(
/*========*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg;
dfield_t* dfield;
@@ -642,7 +643,7 @@ eval_concat(
}
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a predefined function node. If the first argument is an integer,
this function looks at the second argument which is the integer length in
bytes, and converts the integer to a VARCHAR.
@@ -652,7 +653,7 @@ UNIV_INLINE
void
eval_to_binary(
/*===========*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -690,13 +691,13 @@ eval_to_binary(
dfield_set_data(dfield, str1 + (4 - len1), len1);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a predefined function node. */
UNIV_INLINE
void
eval_predefined(
/*============*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg1;
lint int_val;
@@ -782,13 +783,13 @@ eval_predefined(
eval_node_set_int_val(func_node, int_val);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a function node. */
UNIV_INTERN
void
eval_func(
/*======*/
- func_node_t* func_node) /* in: function node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg;
ulint class;
diff --git a/storage/xtradb/eval/eval0proc.c b/storage/xtradb/eval/eval0proc.c
index 9c7563e8c7d..3a4218d92bf 100644
--- a/storage/xtradb/eval/eval0proc.c
+++ b/storage/xtradb/eval/eval0proc.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file eval/eval0proc.c
Executes SQL stored procedures and their control structures
Created 1/20/1998 Heikki Tuuri
@@ -28,14 +29,14 @@ Created 1/20/1998 Heikki Tuuri
#include "eval0proc.ic"
#endif
-/**************************************************************************
-Performs an execution step of an if-statement node. */
+/**********************************************************************//**
+Performs an execution step of an if-statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
if_step(
/*====*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
if_node_t* node;
elsif_node_t* elsif_node;
@@ -104,14 +105,14 @@ if_step(
return(thr);
}
-/**************************************************************************
-Performs an execution step of a while-statement node. */
+/**********************************************************************//**
+Performs an execution step of a while-statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
while_step(
/*=======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
while_node_t* node;
@@ -140,14 +141,14 @@ while_step(
return(thr);
}
-/**************************************************************************
-Performs an execution step of an assignment statement node. */
+/**********************************************************************//**
+Performs an execution step of an assignment statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
assign_step(
/*========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
assign_node_t* node;
@@ -167,14 +168,14 @@ assign_step(
return(thr);
}
-/**************************************************************************
-Performs an execution step of a for-loop node. */
+/**********************************************************************//**
+Performs an execution step of a for-loop node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
for_step(
/*=====*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
for_node_t* node;
que_node_t* parent;
@@ -229,14 +230,14 @@ for_step(
return(thr);
}
-/**************************************************************************
-Performs an execution step of an exit statement node. */
+/**********************************************************************//**
+Performs an execution step of an exit statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
exit_step(
/*======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
exit_node_t* node;
que_node_t* loop_node;
@@ -261,14 +262,14 @@ exit_step(
return(thr);
}
-/**************************************************************************
-Performs an execution step of a return-statement node. */
+/**********************************************************************//**
+Performs an execution step of a return-statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
return_step(
/*========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
return_node_t* node;
que_node_t* parent;
diff --git a/storage/xtradb/fil/fil0fil.c b/storage/xtradb/fil/fil0fil.c
index c60136e27c0..8d81fd41d58 100644
--- a/storage/xtradb/fil/fil0fil.c
+++ b/storage/xtradb/fil/fil0fil.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file fil/fil0fil.c
The tablespace memory cache
Created 10/25/1995 Heikki Tuuri
@@ -25,15 +26,11 @@ Created 10/25/1995 Heikki Tuuri
#include "fil0fil.h"
#include "mem0mem.h"
-#include "sync0sync.h"
#include "hash0hash.h"
#include "os0file.h"
-#include "os0sync.h"
#include "mach0data.h"
-#include "ibuf0ibuf.h"
#include "buf0buf.h"
#include "buf0flu.h"
-#include "buf0lru.h"
#include "log0recv.h"
#include "fsp0fsp.h"
#include "srv0srv.h"
@@ -48,7 +45,14 @@ Created 10/25/1995 Heikki Tuuri
#include "row0row.h"
#include "row0mysql.h"
#include "que0que.h"
-
+#ifndef UNIV_HOTBACKUP
+# include "buf0lru.h"
+# include "ibuf0ibuf.h"
+# include "sync0sync.h"
+# include "os0sync.h"
+#else /* !UNIV_HOTBACKUP */
+static ulint srv_data_read, srv_data_written;
+#endif /* !UNIV_HOTBACKUP */
/*
IMPLEMENTATION OF THE TABLESPACE MEMORY CACHE
@@ -106,131 +110,144 @@ out of the LRU-list and keep a count of pending operations. When an operation
completes, we decrement the count and return the file node to the LRU-list if
the count drops to zero. */
-/* When mysqld is run, the default directory "." is the mysqld datadir,
+/** When mysqld is run, the default directory "." is the mysqld datadir,
but in the MySQL Embedded Server Library and ibbackup it is not the default
directory, and we must set the base file path explicitly */
UNIV_INTERN const char* fil_path_to_mysql_datadir = ".";
-/* The number of fsyncs done to the log */
+/** The number of fsyncs done to the log */
UNIV_INTERN ulint fil_n_log_flushes = 0;
+/** Number of pending redo log flushes */
UNIV_INTERN ulint fil_n_pending_log_flushes = 0;
+/** Number of pending tablespace flushes */
UNIV_INTERN ulint fil_n_pending_tablespace_flushes = 0;
-/* Null file address */
+/** The null file address */
UNIV_INTERN fil_addr_t fil_addr_null = {FIL_NULL, 0};
-/* File node of a tablespace or the log data space */
+/** File node of a tablespace or the log data space */
struct fil_node_struct {
- fil_space_t* space; /* backpointer to the space where this node
+ fil_space_t* space; /*!< backpointer to the space where this node
belongs */
- char* name; /* path to the file */
- ibool open; /* TRUE if file open */
- os_file_t handle; /* OS handle to the file, if file open */
- ibool is_raw_disk;/* TRUE if the 'file' is actually a raw
+ char* name; /*!< path to the file */
+ ibool open; /*!< TRUE if file open */
+ os_file_t handle; /*!< OS handle to the file, if file open */
+ ibool is_raw_disk;/*!< TRUE if the 'file' is actually a raw
device or a raw disk partition */
- ulint size; /* size of the file in database pages, 0 if
+ ulint size; /*!< size of the file in database pages, 0 if
not known yet; the possible last incomplete
megabyte may be ignored if space == 0 */
ulint n_pending;
- /* count of pending i/o's on this file;
+ /*!< count of pending i/o's on this file;
closing of the file is not allowed if
this is > 0 */
ulint n_pending_flushes;
- /* count of pending flushes on this file;
+ /*!< count of pending flushes on this file;
closing of the file is not allowed if
this is > 0 */
- ib_int64_t modification_counter;/* when we write to the file we
+ ib_int64_t modification_counter;/*!< when we write to the file we
increment this by one */
- ib_int64_t flush_counter;/* up to what modification_counter value
- we have flushed the modifications to disk */
+ ib_int64_t flush_counter;/*!< up to what
+ modification_counter value we have
+ flushed the modifications to disk */
UT_LIST_NODE_T(fil_node_t) chain;
- /* link field for the file chain */
+ /*!< link field for the file chain */
UT_LIST_NODE_T(fil_node_t) LRU;
- /* link field for the LRU list */
- ulint magic_n;
+ /*!< link field for the LRU list */
+ ulint magic_n;/*!< FIL_NODE_MAGIC_N */
};
+/** Value of fil_node_struct::magic_n */
#define FIL_NODE_MAGIC_N 89389
-/* Tablespace or log data space: let us call them by a common name space */
+/** Tablespace or log data space: let us call them by a common name space */
struct fil_space_struct {
- char* name; /* space name = the path to the first file in
+ char* name; /*!< space name = the path to the first file in
it */
- ulint id; /* space id */
+ ulint id; /*!< space id */
ib_int64_t tablespace_version;
- /* in DISCARD/IMPORT this timestamp is used to
- check if we should ignore an insert buffer
- merge request for a page because it actually
- was for the previous incarnation of the
- space */
- ibool mark; /* this is set to TRUE at database startup if
+ /*!< in DISCARD/IMPORT this timestamp
+ is used to check if we should ignore
+ an insert buffer merge request for a
+ page because it actually was for the
+ previous incarnation of the space */
+ ibool mark; /*!< this is set to TRUE at database startup if
the space corresponds to a table in the InnoDB
data dictionary; so we can print a warning of
orphaned tablespaces */
- ibool stop_ios;/* TRUE if we want to rename the .ibd file of
- tablespace and want to stop temporarily
- posting of new i/o requests on the file */
+ ibool stop_ios;/*!< TRUE if we want to rename the
+ .ibd file of tablespace and want to
+ stop temporarily posting of new i/o
+ requests on the file */
ibool stop_ibuf_merges;
- /* we set this TRUE when we start deleting a
- single-table tablespace */
+ /*!< we set this TRUE when we start
+ deleting a single-table tablespace */
ibool is_being_deleted;
- /* this is set to TRUE when we start
+ /*!< this is set to TRUE when we start
deleting a single-table tablespace and its
file; when this flag is set no further i/o
or flush requests can be placed on this space,
though there may be such requests still being
processed on this space */
- ulint purpose;/* FIL_TABLESPACE, FIL_LOG, or FIL_ARCH_LOG */
+ ulint purpose;/*!< FIL_TABLESPACE, FIL_LOG, or
+ FIL_ARCH_LOG */
UT_LIST_BASE_NODE_T(fil_node_t) chain;
- /* base node for the file chain */
- ulint size; /* space size in pages; 0 if a single-table
+ /*!< base node for the file chain */
+ ulint size; /*!< space size in pages; 0 if a single-table
tablespace whose size we do not know yet;
last incomplete megabytes in data files may be
ignored if space == 0 */
- ulint flags; /* in: compressed page size
- and file format, or 0 */
+ ulint flags; /*!< compressed page size and file format, or 0 */
ulint n_reserved_extents;
- /* number of reserved free extents for
+ /*!< number of reserved free extents for
ongoing operations like B-tree page split */
- ulint n_pending_flushes; /* this is > 0 when flushing
+ ulint n_pending_flushes; /*!< this is positive when flushing
the tablespace to disk; dropping of the
- tablespace is forbidden if this is > 0 */
- ulint n_pending_ibuf_merges;/* this is > 0 when merging
- insert buffer entries to a page so that we
- may need to access the ibuf bitmap page in the
- tablespade: dropping of the tablespace is
- forbidden if this is > 0 */
- hash_node_t hash; /* hash chain node */
- hash_node_t name_hash;/* hash chain the name_hash table */
- rw_lock_t latch; /* latch protecting the file space storage
+ tablespace is forbidden if this is positive */
+ ulint n_pending_ibuf_merges;/*!< this is positive
+ when merging insert buffer entries to
+ a page so that we may need to access
+ the ibuf bitmap page in the
+ tablespade: dropping of the tablespace
+ is forbidden if this is positive */
+ hash_node_t hash; /*!< hash chain node */
+ hash_node_t name_hash;/*!< hash chain the name_hash table */
+#ifndef UNIV_HOTBACKUP
+ rw_lock_t latch; /*!< latch protecting the file space storage
allocation */
+#endif /* !UNIV_HOTBACKUP */
UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
- /* list of spaces with at least one unflushed
+ /*!< list of spaces with at least one unflushed
file we have written to */
- ibool is_in_unflushed_spaces; /* TRUE if this space is
- currently in the list above */
+ ibool is_in_unflushed_spaces; /*!< TRUE if this space is
+ currently in unflushed_spaces */
UT_LIST_NODE_T(fil_space_t) space_list;
- /* list of all spaces */
- ulint magic_n;
+ /*!< list of all spaces */
+ ulint magic_n;/*!< FIL_SPACE_MAGIC_N */
};
+/** Value of fil_space_struct::magic_n */
#define FIL_SPACE_MAGIC_N 89472
-/* The tablespace memory cache; also the totality of logs = the log data space,
-is stored here; below we talk about tablespaces, but also the ib_logfiles
-form a 'space' and it is handled here */
-
+/** The tablespace memory cache */
typedef struct fil_system_struct fil_system_t;
+
+/** The tablespace memory cache; also the totality of logs (the log
+data space) is stored here; below we talk about tablespaces, but also
+the ib_logfiles form a 'space' and it is handled here */
+
struct fil_system_struct {
- mutex_t mutex; /* The mutex protecting the cache */
- hash_table_t* spaces; /* The hash table of spaces in the
+#ifndef UNIV_HOTBACKUP
+ mutex_t mutex; /*!< The mutex protecting the cache */
+#endif /* !UNIV_HOTBACKUP */
+ hash_table_t* spaces; /*!< The hash table of spaces in the
system; they are hashed on the space
id */
- hash_table_t* name_hash; /* hash table based on the space
+ hash_table_t* name_hash; /*!< hash table based on the space
name */
UT_LIST_BASE_NODE_T(fil_node_t) LRU;
- /* base node for the LRU list of the
+ /*!< base node for the LRU list of the
most recently used open files with no
pending i/o's; if we start an i/o on
the file, we first remove it from this
@@ -241,24 +258,24 @@ struct fil_system_struct {
after the startup, and kept open until
shutdown */
UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces;
- /* base node for the list of those
+ /*!< base node for the list of those
tablespaces whose files contain
unflushed writes; those spaces have
at least one file node where
modification_counter > flush_counter */
- ulint n_open; /* number of files currently open */
- ulint max_n_open; /* n_open is not allowed to exceed
+ ulint n_open; /*!< number of files currently open */
+ ulint max_n_open; /*!< n_open is not allowed to exceed
this */
- ib_int64_t modification_counter;/* when we write to a file we
+ ib_int64_t modification_counter;/*!< when we write to a file we
increment this by one */
- ulint max_assigned_id;/* maximum space id in the existing
+ ulint max_assigned_id;/*!< maximum space id in the existing
tables, or assigned during the time
mysqld has been up; at an InnoDB
startup we scan the data dictionary
and set here the maximum of the
space id's of the tables there */
ib_int64_t tablespace_version;
- /* a counter which is incremented for
+ /*!< a counter which is incremented for
every space object memory creation;
every space mem object gets a
'timestamp' from this; in DISCARD/
@@ -266,15 +283,15 @@ struct fil_system_struct {
should ignore an insert buffer merge
request */
UT_LIST_BASE_NODE_T(fil_space_t) space_list;
- /* list of all file spaces */
+ /*!< list of all file spaces */
};
-/* The tablespace memory cache. This variable is NULL before the module is
+/** The tablespace memory cache. This variable is NULL before the module is
initialized. */
-UNIV_INTERN fil_system_t* fil_system = NULL;
+static fil_system_t* fil_system = NULL;
-/************************************************************************
+/********************************************************************//**
NOTE: you must call fil_mutex_enter_and_prepare_for_io() first!
Prepares a file node for i/o. Opens the file if it is closed. Updates the
@@ -285,99 +302,96 @@ static
void
fil_node_prepare_for_io(
/*====================*/
- fil_node_t* node, /* in: file node */
- fil_system_t* system, /* in: tablespace memory cache */
- fil_space_t* space); /* in: space */
-/************************************************************************
+ fil_node_t* node, /*!< in: file node */
+ fil_system_t* system, /*!< in: tablespace memory cache */
+ fil_space_t* space); /*!< in: space */
+/********************************************************************//**
Updates the data structures when an i/o operation finishes. Updates the
pending i/o's field in the node appropriately. */
static
void
fil_node_complete_io(
/*=================*/
- fil_node_t* node, /* in: file node */
- fil_system_t* system, /* in: tablespace memory cache */
- ulint type); /* in: OS_FILE_WRITE or OS_FILE_READ; marks
+ fil_node_t* node, /*!< in: file node */
+ fil_system_t* system, /*!< in: tablespace memory cache */
+ ulint type); /*!< in: OS_FILE_WRITE or OS_FILE_READ; marks
the node as modified if
type == OS_FILE_WRITE */
-/***********************************************************************
+/*******************************************************************//**
Checks if a single-table tablespace for a given table name exists in the
-tablespace memory cache. */
+tablespace memory cache.
+@return space id, ULINT_UNDEFINED if not found */
static
ulint
fil_get_space_id_for_table(
/*=======================*/
- /* out: space id, ULINT_UNDEFINED if not
- found */
- const char* name); /* in: table name in the standard
+ const char* name); /*!< in: table name in the standard
'databasename/tablename' format */
-/************************************************************************
+/********************************************************************//**
Reads data from a space to a buffer. Remember that the possible incomplete
blocks at the end of file are ignored: they are not taken into account when
-calculating the byte offset within a space. */
+calculating the byte offset within a space.
+@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
+i/o on a tablespace which does not exist */
UNIV_INLINE
ulint
fil_read(
/*=====*/
- /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
- if we are trying to do i/o on a tablespace
- which does not exist */
- ibool sync, /* in: TRUE if synchronous aio is desired */
- ulint space_id, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes;
+ ibool sync, /*!< in: TRUE if synchronous aio is desired */
+ ulint space_id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint block_offset, /* in: offset in number of blocks */
- ulint byte_offset, /* in: remainder of offset in bytes; in aio
+ ulint block_offset, /*!< in: offset in number of blocks */
+ ulint byte_offset, /*!< in: remainder of offset in bytes; in aio
this must be divisible by the OS block size */
- ulint len, /* in: how many bytes to read; this must not
+ ulint len, /*!< in: how many bytes to read; this must not
cross a file boundary; in aio this must be a
block size multiple */
- void* buf, /* in/out: buffer where to store data read;
+ void* buf, /*!< in/out: buffer where to store data read;
in aio this must be appropriately aligned */
- void* message) /* in: message for aio handler if non-sync
+ void* message) /*!< in: message for aio handler if non-sync
aio used, else ignored */
{
return(fil_io(OS_FILE_READ, sync, space_id, zip_size, block_offset,
byte_offset, len, buf, message));
}
-/************************************************************************
+/********************************************************************//**
Writes data to a space from a buffer. Remember that the possible incomplete
blocks at the end of file are ignored: they are not taken into account when
-calculating the byte offset within a space. */
+calculating the byte offset within a space.
+@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
+i/o on a tablespace which does not exist */
UNIV_INLINE
ulint
fil_write(
/*======*/
- /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
- if we are trying to do i/o on a tablespace
- which does not exist */
- ibool sync, /* in: TRUE if synchronous aio is desired */
- ulint space_id, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes;
+ ibool sync, /*!< in: TRUE if synchronous aio is desired */
+ ulint space_id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint block_offset, /* in: offset in number of blocks */
- ulint byte_offset, /* in: remainder of offset in bytes; in aio
+ ulint block_offset, /*!< in: offset in number of blocks */
+ ulint byte_offset, /*!< in: remainder of offset in bytes; in aio
this must be divisible by the OS block size */
- ulint len, /* in: how many bytes to write; this must
+ ulint len, /*!< in: how many bytes to write; this must
not cross a file boundary; in aio this must
be a block size multiple */
- void* buf, /* in: buffer from which to write; in aio
+ void* buf, /*!< in: buffer from which to write; in aio
this must be appropriately aligned */
- void* message) /* in: message for aio handler if non-sync
+ void* message) /*!< in: message for aio handler if non-sync
aio used, else ignored */
{
return(fil_io(OS_FILE_WRITE, sync, space_id, zip_size, block_offset,
byte_offset, len, buf, message));
}
-/***********************************************************************
+/*******************************************************************//**
Returns the table space by a given id, NULL if not found. */
UNIV_INLINE
fil_space_t*
fil_space_get_by_id(
/*================*/
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
fil_space_t* space;
@@ -391,13 +405,13 @@ fil_space_get_by_id(
return(space);
}
-/***********************************************************************
+/*******************************************************************//**
Returns the table space by a given name, NULL if not found. */
UNIV_INLINE
fil_space_t*
fil_space_get_by_name(
/*==================*/
- const char* name) /* in: space name */
+ const char* name) /*!< in: space name */
{
fil_space_t* space;
ulint fold;
@@ -414,23 +428,23 @@ fil_space_get_by_name(
return(space);
}
-/***********************************************************************
-Returns the version number of a tablespace, -1 if not found. */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
+Returns the version number of a tablespace, -1 if not found.
+@return version number, -1 if the tablespace does not exist in the
+memory cache */
UNIV_INTERN
ib_int64_t
fil_space_get_version(
/*==================*/
- /* out: version number, -1 if the tablespace does not
- exist in the memory cache */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
ib_int64_t version = -1;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -438,27 +452,26 @@ fil_space_get_version(
version = space->tablespace_version;
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(version);
}
-/***********************************************************************
-Returns the latch of a file space. */
+/*******************************************************************//**
+Returns the latch of a file space.
+@return latch protecting storage allocation */
UNIV_INTERN
rw_lock_t*
fil_space_get_latch(
/*================*/
- /* out: latch protecting storage allocation */
- ulint id, /* in: space id */
- ulint* flags) /* out: tablespace flags */
+ ulint id, /*!< in: space id */
+ ulint* flags) /*!< out: tablespace flags */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -468,49 +481,49 @@ fil_space_get_latch(
*flags = space->flags;
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(&(space->latch));
}
-/***********************************************************************
-Returns the type of a file space. */
+/*******************************************************************//**
+Returns the type of a file space.
+@return FIL_TABLESPACE or FIL_LOG */
UNIV_INTERN
ulint
fil_space_get_type(
/*===============*/
- /* out: FIL_TABLESPACE or FIL_LOG */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
ut_a(space);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(space->purpose);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Checks if all the file nodes in a space are flushed. The caller must hold
-the fil_system mutex. */
+the fil_system mutex.
+@return TRUE if all are flushed */
static
ibool
fil_space_is_flushed(
/*=================*/
- /* out: TRUE if all are flushed */
- fil_space_t* space) /* in: space */
+ fil_space_t* space) /*!< in: space */
{
fil_node_t* node;
- ut_ad(mutex_own(&(fil_system->mutex)));
+ ut_ad(mutex_own(&fil_system->mutex));
node = UT_LIST_GET_FIRST(space->chain);
@@ -526,27 +539,26 @@ fil_space_is_flushed(
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
Appends a new file to the chain of files of a space. File must be closed. */
UNIV_INTERN
void
fil_node_create(
/*============*/
- const char* name, /* in: file name (file must be closed) */
- ulint size, /* in: file size in database blocks, rounded
+ const char* name, /*!< in: file name (file must be closed) */
+ ulint size, /*!< in: file size in database blocks, rounded
downwards to an integer */
- ulint id, /* in: space id where to append */
- ibool is_raw) /* in: TRUE if a raw device or
+ ulint id, /*!< in: space id where to append */
+ ibool is_raw) /*!< in: TRUE if a raw device or
a raw disk partition */
{
- fil_system_t* system = fil_system;
fil_node_t* node;
fil_space_t* space;
- ut_a(system);
+ ut_a(fil_system);
ut_a(name);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
node = mem_alloc(sizeof(fil_node_t));
@@ -577,7 +589,7 @@ fil_node_create(
mem_free(node);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return;
}
@@ -588,19 +600,19 @@ fil_node_create(
UT_LIST_ADD_LAST(chain, space->chain, node);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
-/************************************************************************
+/********************************************************************//**
Opens a the file of a node of a tablespace. The caller must own the fil_system
mutex. */
static
void
fil_node_open_file(
/*===============*/
- fil_node_t* node, /* in: file node */
- fil_system_t* system, /* in: tablespace memory cache */
- fil_space_t* space) /* in: space */
+ fil_node_t* node, /*!< in: file node */
+ fil_system_t* system, /*!< in: tablespace memory cache */
+ fil_space_t* space) /*!< in: space */
{
ib_int64_t size_bytes;
ulint size_low;
@@ -763,14 +775,14 @@ fil_node_open_file(
}
}
-/**************************************************************************
+/**********************************************************************//**
Closes a file. */
static
void
fil_node_close_file(
/*================*/
- fil_node_t* node, /* in: file node */
- fil_system_t* system) /* in: tablespace memory cache */
+ fil_node_t* node, /*!< in: file node */
+ fil_system_t* system) /*!< in: tablespace memory cache */
{
ibool ret;
@@ -798,41 +810,38 @@ fil_node_close_file(
}
}
-/************************************************************************
+/********************************************************************//**
Tries to close a file in the LRU list. The caller must hold the fil_sys
-mutex. */
+mutex.
+@return TRUE if success, FALSE if should retry later; since i/o's
+generally complete in < 100 ms, and as InnoDB writes at most 128 pages
+from the buffer pool in a batch, and then immediately flushes the
+files, there is a good chance that the next time we find a suitable
+node from the LRU list */
static
ibool
fil_try_to_close_file_in_LRU(
/*=========================*/
- /* out: TRUE if success, FALSE if should retry
- later; since i/o's generally complete in <
- 100 ms, and as InnoDB writes at most 128 pages
- from the buffer pool in a batch, and then
- immediately flushes the files, there is a good
- chance that the next time we find a suitable
- node from the LRU list */
- ibool print_info) /* in: if TRUE, prints information why it
+ ibool print_info) /*!< in: if TRUE, prints information why it
cannot close a file */
{
- fil_system_t* system = fil_system;
fil_node_t* node;
- ut_ad(mutex_own(&(system->mutex)));
+ ut_ad(mutex_own(&fil_system->mutex));
- node = UT_LIST_GET_LAST(system->LRU);
+ node = UT_LIST_GET_LAST(fil_system->LRU);
if (print_info) {
fprintf(stderr,
"InnoDB: fil_sys open file LRU len %lu\n",
- (ulong) UT_LIST_GET_LEN(system->LRU));
+ (ulong) UT_LIST_GET_LEN(fil_system->LRU));
}
while (node != NULL) {
if (node->modification_counter == node->flush_counter
&& node->n_pending_flushes == 0) {
- fil_node_close_file(node, system);
+ fil_node_close_file(node, fil_system);
return(TRUE);
}
@@ -860,7 +869,7 @@ fil_try_to_close_file_in_LRU(
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Reserves the fil_system mutex and tries to make sure we can open at least one
file while holding it. This should be called before calling
fil_node_prepare_for_io(), because that function may need to open a file. */
@@ -868,18 +877,16 @@ static
void
fil_mutex_enter_and_prepare_for_io(
/*===============================*/
- ulint space_id) /* in: space id */
+ ulint space_id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
ibool success;
ibool print_info = FALSE;
ulint count = 0;
ulint count2 = 0;
- ut_ad(!mutex_own(&(system->mutex)));
retry:
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
if (space_id == 0 || space_id >= SRV_LOG_SPACE_FIRST_ID) {
/* We keep log files and system tablespace files always open;
@@ -891,7 +898,7 @@ retry:
return;
}
- if (system->n_open < system->max_n_open) {
+ if (fil_system->n_open < fil_system->max_n_open) {
return;
}
@@ -910,7 +917,7 @@ retry:
(ulong) count2);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
os_thread_sleep(20000);
@@ -936,12 +943,12 @@ retry:
close_more:
success = fil_try_to_close_file_in_LRU(print_info);
- if (success && system->n_open >= system->max_n_open) {
+ if (success && fil_system->n_open >= fil_system->max_n_open) {
goto close_more;
}
- if (system->n_open < system->max_n_open) {
+ if (fil_system->n_open < fil_system->max_n_open) {
/* Ok */
return;
@@ -956,12 +963,13 @@ close_more:
"InnoDB: You may need to raise the value of"
" innodb_max_files_open in\n"
"InnoDB: my.cnf.\n",
- (ulong) system->n_open, (ulong) system->max_n_open);
+ (ulong) fil_system->n_open,
+ (ulong) fil_system->max_n_open);
return;
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
#ifndef UNIV_HOTBACKUP
/* Wake the i/o-handler threads to make sure pending i/o's are
@@ -980,15 +988,15 @@ close_more:
goto retry;
}
-/***********************************************************************
+/*******************************************************************//**
Frees a file node object from a tablespace memory cache. */
static
void
fil_node_free(
/*==========*/
- fil_node_t* node, /* in, own: file node */
- fil_system_t* system, /* in: tablespace memory cache */
- fil_space_t* space) /* in: space where the file node is chained */
+ fil_node_t* node, /*!< in, own: file node */
+ fil_system_t* system, /*!< in: tablespace memory cache */
+ fil_space_t* space) /*!< in: space where the file node is chained */
{
ut_ad(node && system && space);
ut_ad(mutex_own(&(system->mutex)));
@@ -1023,23 +1031,22 @@ fil_node_free(
}
#ifdef UNIV_LOG_ARCHIVE
-/********************************************************************
+/****************************************************************//**
Drops files from the start of a file space, so that its size is cut by
the amount given. */
UNIV_INTERN
void
fil_space_truncate_start(
/*=====================*/
- ulint id, /* in: space id */
- ulint trunc_len) /* in: truncate by this much; it is an error
+ ulint id, /*!< in: space id */
+ ulint trunc_len) /*!< in: truncate by this much; it is an error
if this does not equal to the combined size of
some initial files in the space */
{
- fil_system_t* system = fil_system;
fil_node_t* node;
fil_space_t* space;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -1052,28 +1059,27 @@ fil_space_truncate_start(
trunc_len -= node->size * UNIV_PAGE_SIZE;
- fil_node_free(node, system, space);
+ fil_node_free(node, fil_system, space);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
#endif /* UNIV_LOG_ARCHIVE */
-/***********************************************************************
+/*******************************************************************//**
Creates a space memory object and puts it to the tablespace memory cache. If
-there is an error, prints an error message to the .err log. */
+there is an error, prints an error message to the .err log.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_space_create(
/*=============*/
- /* out: TRUE if success */
- const char* name, /* in: space name */
- ulint id, /* in: space id */
- ulint flags, /* in: compressed page size
+ const char* name, /*!< in: space name */
+ ulint id, /*!< in: space id */
+ ulint flags, /*!< in: compressed page size
and file format, or 0 */
- ulint purpose)/* in: FIL_TABLESPACE, or FIL_LOG if log */
+ ulint purpose)/*!< in: FIL_TABLESPACE, or FIL_LOG if log */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
@@ -1087,10 +1093,10 @@ try_again:
"InnoDB: Adding tablespace %lu of name %s, purpose %lu\n", id, name,
purpose);*/
- ut_a(system);
+ ut_a(fil_system);
ut_a(name);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_name(name);
@@ -1111,7 +1117,7 @@ try_again:
if (id == 0 || purpose != FIL_TABLESPACE) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
@@ -1133,7 +1139,7 @@ try_again:
namesake_id = space->id;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
fil_space_free(namesake_id);
@@ -1155,7 +1161,7 @@ try_again:
fputs(" already exists in the tablespace\n"
"InnoDB: memory cache!\n", stderr);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
@@ -1165,12 +1171,12 @@ try_again:
space->name = mem_strdup(name);
space->id = id;
- system->tablespace_version++;
- space->tablespace_version = system->tablespace_version;
+ fil_system->tablespace_version++;
+ space->tablespace_version = fil_system->tablespace_version;
space->mark = FALSE;
- if (purpose == FIL_TABLESPACE && id > system->max_assigned_id) {
- system->max_assigned_id = id;
+ if (purpose == FIL_TABLESPACE && id > fil_system->max_assigned_id) {
+ fil_system->max_assigned_id = id;
}
space->stop_ios = FALSE;
@@ -1190,38 +1196,36 @@ try_again:
rw_lock_create(&space->latch, SYNC_FSP);
- HASH_INSERT(fil_space_t, hash, system->spaces, id, space);
+ HASH_INSERT(fil_space_t, hash, fil_system->spaces, id, space);
- HASH_INSERT(fil_space_t, name_hash, system->name_hash,
+ HASH_INSERT(fil_space_t, name_hash, fil_system->name_hash,
ut_fold_string(name), space);
space->is_in_unflushed_spaces = FALSE;
- UT_LIST_ADD_LAST(space_list, system->space_list, space);
+ UT_LIST_ADD_LAST(space_list, fil_system->space_list, space);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
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. */
+to recycle id's.
+@return new tablespace id; ULINT_UNDEFINED if could not assign an id */
static
ulint
fil_assign_new_space_id(void)
/*=========================*/
- /* out: new tablespace id; ULINT_UNDEFINED if could
- not assign an id */
{
- fil_system_t* system = fil_system;
ulint id;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- system->max_assigned_id++;
+ fil_system->max_assigned_id++;
- id = system->max_assigned_id;
+ id = fil_system->max_assigned_id;
if (id > (SRV_LOG_SPACE_FIRST_ID / 2) && (id % 1000000UL == 0)) {
ut_print_timestamp(stderr);
@@ -1247,33 +1251,32 @@ fil_assign_new_space_id(void)
" have to dump all your tables and\n"
"InnoDB: recreate the whole InnoDB installation.\n",
(ulong) id);
- system->max_assigned_id--;
+ fil_system->max_assigned_id--;
id = ULINT_UNDEFINED;
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(id);
}
-/***********************************************************************
+/*******************************************************************//**
Frees a space object from the tablespace memory cache. Closes the files in
the chain but does not delete them. There must not be any pending i/o's or
-flushes on the files. */
+flushes on the files.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_space_free(
/*===========*/
- /* out: TRUE if success */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
fil_space_t* namespace;
fil_node_t* fil_node;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -1284,28 +1287,28 @@ fil_space_free(
" from the cache but\n"
"InnoDB: it is not there.\n", (ulong) id);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
- HASH_DELETE(fil_space_t, hash, system->spaces, id, space);
+ HASH_DELETE(fil_space_t, hash, fil_system->spaces, id, space);
namespace = fil_space_get_by_name(space->name);
ut_a(namespace);
ut_a(space == namespace);
- HASH_DELETE(fil_space_t, name_hash, system->name_hash,
+ HASH_DELETE(fil_space_t, name_hash, fil_system->name_hash,
ut_fold_string(space->name), space);
if (space->is_in_unflushed_spaces) {
space->is_in_unflushed_spaces = FALSE;
- UT_LIST_REMOVE(unflushed_spaces, system->unflushed_spaces,
+ UT_LIST_REMOVE(unflushed_spaces, fil_system->unflushed_spaces,
space);
}
- UT_LIST_REMOVE(space_list, system->space_list, space);
+ UT_LIST_REMOVE(space_list, fil_system->space_list, space);
ut_a(space->magic_n == FIL_SPACE_MAGIC_N);
ut_a(0 == space->n_pending_flushes);
@@ -1313,14 +1316,14 @@ fil_space_free(
fil_node = UT_LIST_GET_FIRST(space->chain);
while (fil_node != NULL) {
- fil_node_free(fil_node, system, space);
+ fil_node_free(fil_node, fil_system, space);
fil_node = UT_LIST_GET_FIRST(space->chain);
}
ut_a(0 == UT_LIST_GET_LEN(space->chain));
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
rw_lock_free(&(space->latch));
@@ -1330,52 +1333,28 @@ fil_space_free(
return(TRUE);
}
-#ifdef UNIV_HOTBACKUP
-/***********************************************************************
-Returns the tablespace object for a given id, or NULL if not found from the
-tablespace memory cache. */
-static
-fil_space_t*
-fil_get_space_for_id_low(
-/*=====================*/
- /* out: tablespace object or NULL; NOTE that you must
- own &(fil_system->mutex) to call this function! */
- ulint id) /* in: space id */
-{
- fil_system_t* system = fil_system;
- fil_space_t* space;
-
- ut_ad(system);
-
- space = fil_space_get_by_id(id);
-
- return(space);
-}
-#endif
-
-/***********************************************************************
+/*******************************************************************//**
Returns the size of the space in pages. The tablespace must be cached in the
-memory cache. */
+memory cache.
+@return space size, 0 if space not found */
UNIV_INTERN
ulint
fil_space_get_size(
/*===============*/
- /* out: space size, 0 if space not found */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_node_t* node;
fil_space_t* space;
ulint size;
- ut_ad(system);
+ ut_ad(fil_system);
fil_mutex_enter_and_prepare_for_io(id);
space = fil_space_get_by_id(id);
if (space == NULL) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(0);
}
@@ -1391,33 +1370,32 @@ fil_space_get_size(
the file yet; the following calls will open it and update the
size fields */
- fil_node_prepare_for_io(node, system, space);
- fil_node_complete_io(node, system, OS_FILE_READ);
+ fil_node_prepare_for_io(node, fil_system, space);
+ fil_node_complete_io(node, fil_system, OS_FILE_READ);
}
size = space->size;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(size);
}
-/***********************************************************************
+/*******************************************************************//**
Returns the flags of the space. The tablespace must be cached
-in the memory cache. */
+in the memory cache.
+@return flags, ULINT_UNDEFINED if space not found */
UNIV_INTERN
ulint
fil_space_get_flags(
/*================*/
- /* out: flags, ULINT_UNDEFINED if space not found */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_node_t* node;
fil_space_t* space;
ulint flags;
- ut_ad(system);
+ ut_ad(fil_system);
if (UNIV_UNLIKELY(!id)) {
return(0);
@@ -1428,7 +1406,7 @@ fil_space_get_flags(
space = fil_space_get_by_id(id);
if (space == NULL) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(ULINT_UNDEFINED);
}
@@ -1444,27 +1422,26 @@ fil_space_get_flags(
the file yet; the following calls will open it and update the
size fields */
- fil_node_prepare_for_io(node, system, space);
- fil_node_complete_io(node, system, OS_FILE_READ);
+ fil_node_prepare_for_io(node, fil_system, space);
+ fil_node_complete_io(node, fil_system, OS_FILE_READ);
}
flags = space->flags;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(flags);
}
-/***********************************************************************
+/*******************************************************************//**
Returns the compressed page size of the space, or 0 if the space
-is not compressed. The tablespace must be cached in the memory cache. */
+is not compressed. The tablespace must be cached in the memory cache.
+@return compressed page size, ULINT_UNDEFINED if space not found */
UNIV_INTERN
ulint
fil_space_get_zip_size(
/*===================*/
- /* out: compressed page size, ULINT_UNDEFINED
- if space not found */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
ulint flags;
@@ -1478,16 +1455,16 @@ fil_space_get_zip_size(
return(flags);
}
-/***********************************************************************
+/*******************************************************************//**
Checks if the pair space, page_no refers to an existing page in a tablespace
-file space. The tablespace must be cached in the memory cache. */
+file space. The tablespace must be cached in the memory cache.
+@return TRUE if the address is meaningful */
UNIV_INTERN
ibool
fil_check_adress_in_tablespace(
/*===========================*/
- /* out: TRUE if the address is meaningful */
- ulint id, /* in: space id */
- ulint page_no)/* in: page number */
+ ulint id, /*!< in: space id */
+ ulint page_no)/*!< in: page number */
{
if (fil_space_get_size(id) > page_no) {
@@ -1497,67 +1474,42 @@ fil_check_adress_in_tablespace(
return(FALSE);
}
-/********************************************************************
-Creates a the tablespace memory cache. */
-static
-fil_system_t*
-fil_system_create(
-/*==============*/
- /* out, own: tablespace memory cache */
- ulint hash_size, /* in: hash table size */
- ulint max_n_open) /* in: maximum number of open files; must be
- > 10 */
+/****************************************************************//**
+Initializes the tablespace memory cache. */
+UNIV_INTERN
+void
+fil_init(
+/*=====*/
+ ulint hash_size, /*!< in: hash table size */
+ ulint max_n_open) /*!< in: max number of open files */
{
- fil_system_t* system;
+ ut_a(fil_system == NULL);
ut_a(hash_size > 0);
ut_a(max_n_open > 0);
- system = mem_alloc(sizeof(fil_system_t));
-
- mutex_create(&system->mutex, SYNC_ANY_LATCH);
-
- system->spaces = hash_create(hash_size);
- system->name_hash = hash_create(hash_size);
-
- UT_LIST_INIT(system->LRU);
+ fil_system = mem_alloc(sizeof(fil_system_t));
- system->n_open = 0;
- system->max_n_open = max_n_open;
+ mutex_create(&fil_system->mutex, SYNC_ANY_LATCH);
- system->modification_counter = 0;
- system->max_assigned_id = 0;
+ fil_system->spaces = hash_create(hash_size);
+ fil_system->name_hash = hash_create(hash_size);
- system->tablespace_version = 0;
+ UT_LIST_INIT(fil_system->LRU);
- UT_LIST_INIT(system->unflushed_spaces);
- UT_LIST_INIT(system->space_list);
+ fil_system->n_open = 0;
+ fil_system->max_n_open = max_n_open;
- return(system);
-}
-
-/********************************************************************
-Initializes the tablespace memory cache. */
-UNIV_INTERN
-void
-fil_init(
-/*=====*/
- ulint max_n_open) /* in: max number of open files */
-{
- ulint hash_size;
-
- ut_a(fil_system == NULL);
+ fil_system->modification_counter = 0;
+ fil_system->max_assigned_id = 0;
- if (srv_file_per_table) {
- hash_size = 50000;
- } else {
- hash_size = 5000;
- }
+ fil_system->tablespace_version = 0;
- fil_system = fil_system_create(hash_size, max_n_open);
+ UT_LIST_INIT(fil_system->unflushed_spaces);
+ UT_LIST_INIT(fil_system->space_list);
}
-/***********************************************************************
+/*******************************************************************//**
Opens all log files and system tablespace data files. They stay open until the
database server shutdown. This should be called at a server startup after the
space objects for the log and the system tablespace have been created. The
@@ -1568,13 +1520,12 @@ void
fil_open_log_and_system_tablespace_files(void)
/*==========================================*/
{
- fil_system_t* system = fil_system;
fil_space_t* space;
fil_node_t* node;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- space = UT_LIST_GET_FIRST(system->space_list);
+ space = UT_LIST_GET_FIRST(fil_system->space_list);
while (space != NULL) {
if (space->purpose != FIL_TABLESPACE || space->id == 0) {
@@ -1582,10 +1533,11 @@ fil_open_log_and_system_tablespace_files(void)
while (node != NULL) {
if (!node->open) {
- fil_node_open_file(node, system,
+ fil_node_open_file(node, fil_system,
space);
}
- if (system->max_n_open < 10 + system->n_open) {
+ if (fil_system->max_n_open
+ < 10 + fil_system->n_open) {
fprintf(stderr,
"InnoDB: Warning: you must"
" raise the value of"
@@ -1603,8 +1555,8 @@ fil_open_log_and_system_tablespace_files(void)
" Current open files %lu,"
" max allowed"
" open files %lu.\n",
- (ulong) system->n_open,
- (ulong) system->max_n_open);
+ (ulong) fil_system->n_open,
+ (ulong) fil_system->max_n_open);
}
node = UT_LIST_GET_NEXT(chain, node);
}
@@ -1612,10 +1564,10 @@ fil_open_log_and_system_tablespace_files(void)
space = UT_LIST_GET_NEXT(space_list, space);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
-/***********************************************************************
+/*******************************************************************//**
Closes all open files. There must not be any pending i/o's or not flushed
modifications in the files. */
UNIV_INTERN
@@ -1623,58 +1575,55 @@ void
fil_close_all_files(void)
/*=====================*/
{
- fil_system_t* system = fil_system;
fil_space_t* space;
fil_node_t* node;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- space = UT_LIST_GET_FIRST(system->space_list);
+ space = UT_LIST_GET_FIRST(fil_system->space_list);
while (space != NULL) {
node = UT_LIST_GET_FIRST(space->chain);
while (node != NULL) {
if (node->open) {
- fil_node_close_file(node, system);
+ fil_node_close_file(node, fil_system);
}
node = UT_LIST_GET_NEXT(chain, node);
}
space = UT_LIST_GET_NEXT(space_list, space);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
-/***********************************************************************
+/*******************************************************************//**
Sets the max tablespace id counter if the given number is bigger than the
previous value. */
UNIV_INTERN
void
fil_set_max_space_id_if_bigger(
/*===========================*/
- ulint max_id) /* in: maximum known id */
+ ulint max_id) /*!< in: maximum known id */
{
- fil_system_t* system = fil_system;
-
if (max_id >= SRV_LOG_SPACE_FIRST_ID) {
fprintf(stderr,
"InnoDB: Fatal error: max tablespace id"
" is too high, %lu\n", (ulong) max_id);
- ut_a(0);
+ ut_error;
}
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- if (system->max_assigned_id < max_id) {
+ if (fil_system->max_assigned_id < max_id) {
- system->max_assigned_id = max_id;
+ fil_system->max_assigned_id = max_id;
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
-/********************************************************************
+/****************************************************************//**
Writes the flushed lsn and the latest archived log number to the page header
of the first page of a data file of the system tablespace (space 0),
which is uncompressed. */
@@ -1682,11 +1631,11 @@ static
ulint
fil_write_lsn_and_arch_no_to_file(
/*==============================*/
- ulint sum_of_sizes, /* in: combined size of previous files
+ ulint sum_of_sizes, /*!< in: combined size of previous files
in space, in database pages */
- ib_uint64_t lsn, /* in: lsn to write */
- ulint arch_log_no /* in: archived log number to write */
- __attribute__((unused)))
+ ib_uint64_t lsn, /*!< in: lsn to write */
+ ulint arch_log_no __attribute__((unused)))
+ /*!< in: archived log number to write */
{
byte* buf1;
byte* buf;
@@ -1705,16 +1654,16 @@ fil_write_lsn_and_arch_no_to_file(
return(DB_SUCCESS);
}
-/********************************************************************
+/****************************************************************//**
Writes the flushed lsn and the latest archived log number to the page
-header of the first page of each data file in the system tablespace. */
+header of the first page of each data file in the system tablespace.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
fil_write_flushed_lsn_to_data_files(
/*================================*/
- /* out: DB_SUCCESS or error number */
- ib_uint64_t lsn, /* in: lsn to write */
- ulint arch_log_no) /* in: latest archived log
+ ib_uint64_t lsn, /*!< in: lsn to write */
+ ulint arch_log_no) /*!< in: latest archived log
file number */
{
fil_space_t* space;
@@ -1722,7 +1671,7 @@ fil_write_flushed_lsn_to_data_files(
ulint sum_of_sizes;
ulint err;
- mutex_enter(&(fil_system->mutex));
+ mutex_enter(&fil_system->mutex);
space = UT_LIST_GET_FIRST(fil_system->space_list);
@@ -1739,7 +1688,7 @@ fil_write_flushed_lsn_to_data_files(
node = UT_LIST_GET_FIRST(space->chain);
while (node) {
- mutex_exit(&(fil_system->mutex));
+ mutex_exit(&fil_system->mutex);
err = fil_write_lsn_and_arch_no_to_file(
sum_of_sizes, lsn, arch_log_no);
@@ -1748,7 +1697,7 @@ fil_write_flushed_lsn_to_data_files(
return(err);
}
- mutex_enter(&(fil_system->mutex));
+ mutex_enter(&fil_system->mutex);
sum_of_sizes += node->size;
node = UT_LIST_GET_NEXT(chain, node);
@@ -1757,28 +1706,28 @@ fil_write_flushed_lsn_to_data_files(
space = UT_LIST_GET_NEXT(space_list, space);
}
- mutex_exit(&(fil_system->mutex));
+ mutex_exit(&fil_system->mutex);
return(DB_SUCCESS);
}
-/***********************************************************************
+/*******************************************************************//**
Reads the flushed lsn and arch no fields from a data file at database
startup. */
UNIV_INTERN
void
fil_read_flushed_lsn_and_arch_log_no(
/*=================================*/
- os_file_t data_file, /* in: open data file */
- ibool one_read_already, /* in: TRUE if min and max
+ os_file_t data_file, /*!< in: open data file */
+ ibool one_read_already, /*!< in: TRUE if min and max
parameters below already
contain sensible data */
#ifdef UNIV_LOG_ARCHIVE
- ulint* min_arch_log_no, /* in/out: */
- ulint* max_arch_log_no, /* in/out: */
+ ulint* min_arch_log_no, /*!< in/out: */
+ ulint* max_arch_log_no, /*!< in/out: */
#endif /* UNIV_LOG_ARCHIVE */
- ib_uint64_t* min_flushed_lsn, /* in/out: */
- ib_uint64_t* max_flushed_lsn) /* in/out: */
+ ib_uint64_t* min_flushed_lsn, /*!< in/out: */
+ ib_uint64_t* max_flushed_lsn) /*!< in/out: */
{
byte* buf;
byte* buf2;
@@ -1822,21 +1771,20 @@ fil_read_flushed_lsn_and_arch_log_no(
/*================ SINGLE-TABLE TABLESPACES ==========================*/
-/***********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Increments the count of pending insert buffer page merges, if space is not
-being deleted. */
+being deleted.
+@return TRUE if being deleted, and ibuf merges should be skipped */
UNIV_INTERN
ibool
fil_inc_pending_ibuf_merges(
/*========================*/
- /* out: TRUE if being deleted, and ibuf merges should
- be skipped */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -1848,30 +1796,29 @@ fil_inc_pending_ibuf_merges(
}
if (space == NULL || space->stop_ibuf_merges) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(TRUE);
}
space->n_pending_ibuf_merges++;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Decrements the count of pending insert buffer page merges. */
UNIV_INTERN
void
fil_decr_pending_ibuf_merges(
/*=========================*/
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -1886,16 +1833,17 @@ fil_decr_pending_ibuf_merges(
space->n_pending_ibuf_merges--;
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************
+/********************************************************//**
Creates the database directory for a table if it does not exist yet. */
static
void
fil_create_directory_for_tablename(
/*===============================*/
- const char* name) /* in: name in the standard
+ const char* name) /*!< in: name in the standard
'databasename/tablename' format */
{
const char* namend;
@@ -1919,28 +1867,30 @@ fil_create_directory_for_tablename(
}
#ifndef UNIV_HOTBACKUP
-/************************************************************
+/********************************************************//**
Writes a log record about an .ibd file create/rename/delete. */
static
void
fil_op_write_log(
/*=============*/
- ulint type, /* in: MLOG_FILE_CREATE,
+ ulint type, /*!< in: MLOG_FILE_CREATE,
MLOG_FILE_CREATE2,
MLOG_FILE_DELETE, or
MLOG_FILE_RENAME */
- ulint space_id, /* in: space id */
- ulint flags, /* in: compressed page size
+ ulint space_id, /*!< in: space id */
+ ulint log_flags, /*!< in: redo log flags (stored
+ in the page number field) */
+ ulint flags, /*!< in: compressed page size
and file format
if type==MLOG_FILE_CREATE2, or 0 */
- const char* name, /* in: table name in the familiar
+ const char* name, /*!< in: table name in the familiar
'databasename/tablename' format, or
the file path in the case of
MLOG_FILE_DELETE */
- const char* new_name, /* in: if type is MLOG_FILE_RENAME,
+ const char* new_name, /*!< in: if type is MLOG_FILE_RENAME,
the new table name in the
'databasename/tablename' format */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
byte* log_ptr;
ulint len;
@@ -1953,8 +1903,8 @@ fil_op_write_log(
return;
}
- log_ptr = mlog_write_initial_log_record_for_file_op(type, space_id, 0,
- log_ptr, mtr);
+ log_ptr = mlog_write_initial_log_record_for_file_op(
+ type, space_id, log_flags, log_ptr, mtr);
if (type == MLOG_FILE_CREATE2) {
mach_write_to_4(log_ptr, flags);
log_ptr += 4;
@@ -1983,7 +1933,7 @@ fil_op_write_log(
}
#endif
-/***********************************************************************
+/*******************************************************************//**
Parses the body of a log record written about an .ibd file operation. That is,
the log record part after the standard (type, space id, page no) header of the
log record.
@@ -1994,22 +1944,23 @@ at that path does not exist yet. If the database directory for the file to be
created does not exist, then we create the directory, too.
Note that ibbackup --apply-log sets fil_path_to_mysql_datadir to point to the
-datadir that we should use in replaying the file operations. */
+datadir that we should use in replaying the file operations.
+@return end of log record, or NULL if the record was not completely
+contained between ptr and end_ptr */
UNIV_INTERN
byte*
fil_op_log_parse_or_replay(
/*=======================*/
- /* out: end of log record, or NULL if the
- record was not completely contained between
- ptr and end_ptr */
- byte* ptr, /* in: buffer containing the log record body,
+ byte* ptr, /*!< in: buffer containing the log record body,
or an initial segment of it, if the record does
not fir completely between ptr and end_ptr */
- byte* end_ptr, /* in: buffer end */
- ulint type, /* in: the type of this log record */
- ulint space_id) /* in: the space id of the tablespace in
+ byte* end_ptr, /*!< in: buffer end */
+ ulint type, /*!< in: the type of this log record */
+ ulint space_id, /*!< in: the space id of the tablespace in
question, or 0 if the log record should
only be parsed but not replayed */
+ ulint log_flags) /*!< in: redo log flags
+ (stored in the page number parameter) */
{
ulint name_len;
ulint new_name_len;
@@ -2129,6 +2080,8 @@ fil_op_log_parse_or_replay(
} else if (fil_get_space_id_for_table(name)
!= ULINT_UNDEFINED) {
/* Do nothing */
+ } else if (log_flags & MLOG_FILE_FLAG_TEMP) {
+ /* Temporary table, do nothing */
} else {
/* Create the database directory for name, if it does
not exist yet */
@@ -2150,17 +2103,16 @@ fil_op_log_parse_or_replay(
return(ptr);
}
-/***********************************************************************
+/*******************************************************************//**
Deletes a single-table tablespace. The tablespace must be cached in the
-memory cache. */
+memory cache.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_delete_tablespace(
/*==================*/
- /* out: TRUE if success */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
ibool success;
fil_space_t* space;
fil_node_t* node;
@@ -2169,7 +2121,7 @@ fil_delete_tablespace(
ut_a(id != 0);
stop_ibuf_merges:
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -2177,7 +2129,7 @@ stop_ibuf_merges:
space->stop_ibuf_merges = TRUE;
if (space->n_pending_ibuf_merges == 0) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
count = 0;
@@ -2196,7 +2148,7 @@ stop_ibuf_merges:
(ulong) count);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
os_thread_sleep(20000);
count++;
@@ -2205,11 +2157,11 @@ stop_ibuf_merges:
}
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
count = 0;
try_again:
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -2221,7 +2173,7 @@ try_again:
" tablespace memory cache.\n",
(ulong) id);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
@@ -2248,7 +2200,7 @@ try_again:
(ulong) node->n_pending,
(ulong) count);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
os_thread_sleep(20000);
count++;
@@ -2258,7 +2210,7 @@ try_again:
path = mem_strdup(space->name);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
#ifndef UNIV_HOTBACKUP
/* Invalidate in the buffer pool all pages belonging to the
tablespace. Since we have set space->is_being_deleted = TRUE, readahead
@@ -2293,7 +2245,7 @@ try_again:
to write any log record */
mtr_start(&mtr);
- fil_op_write_log(MLOG_FILE_DELETE, id, 0, path, NULL, &mtr);
+ fil_op_write_log(MLOG_FILE_DELETE, id, 0, 0, path, NULL, &mtr);
mtr_commit(&mtr);
#endif
mem_free(path);
@@ -2306,20 +2258,21 @@ try_again:
return(FALSE);
}
-/***********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Discards a single-table tablespace. The tablespace must be cached in the
memory cache. Discarding is like deleting a tablespace, but
1) we do not drop the table from the data dictionary;
2) we remove all insert buffer entries for the tablespace immediately; in DROP
TABLE they are only removed gradually in the background;
3) when the user does IMPORT TABLESPACE, the tablespace will have the same id
-as it originally had. */
+as it originally had.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_discard_tablespace(
/*===================*/
- /* out: TRUE if success */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
ibool success;
@@ -2340,22 +2293,24 @@ fil_discard_tablespace(
return(success);
}
+#endif /* !UNIV_HOTBACKUP */
-/***********************************************************************
-Renames the memory cache structures of a single-table tablespace. */
+/*******************************************************************//**
+Renames the memory cache structures of a single-table tablespace.
+@return TRUE if success */
static
ibool
fil_rename_tablespace_in_mem(
/*=========================*/
- /* out: TRUE if success */
- fil_space_t* space, /* in: tablespace memory object */
- fil_node_t* node, /* in: file node of that tablespace */
- const char* path) /* in: new name */
+ fil_space_t* space, /*!< in: tablespace memory object */
+ fil_node_t* node, /*!< in: file node of that tablespace */
+ const char* path) /*!< in: new name */
{
- fil_system_t* system = fil_system;
fil_space_t* space2;
const char* old_name = space->name;
+ ut_ad(mutex_own(&fil_system->mutex));
+
space2 = fil_space_get_by_name(old_name);
if (space != space2) {
fputs("InnoDB: Error: cannot find ", stderr);
@@ -2374,7 +2329,7 @@ fil_rename_tablespace_in_mem(
return(FALSE);
}
- HASH_DELETE(fil_space_t, name_hash, system->name_hash,
+ HASH_DELETE(fil_space_t, name_hash, fil_system->name_hash,
ut_fold_string(space->name), space);
mem_free(space->name);
mem_free(node->name);
@@ -2382,22 +2337,22 @@ fil_rename_tablespace_in_mem(
space->name = mem_strdup(path);
node->name = mem_strdup(path);
- HASH_INSERT(fil_space_t, name_hash, system->name_hash,
+ HASH_INSERT(fil_space_t, name_hash, fil_system->name_hash,
ut_fold_string(path), space);
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
Allocates a file name for a single-table tablespace. The string must be freed
-by caller with mem_free(). */
+by caller with mem_free().
+@return own: file name */
static
char*
fil_make_ibd_name(
/*==============*/
- /* out, own: file name */
- const char* name, /* in: table name or a dir path of a
+ const char* name, /*!< in: table name or a dir path of a
TEMPORARY table */
- ibool is_temp) /* in: TRUE if it is a dir path */
+ ibool is_temp) /*!< in: TRUE if it is a dir path */
{
ulint namelen = strlen(name);
ulint dirlen = strlen(fil_path_to_mysql_datadir);
@@ -2419,24 +2374,23 @@ fil_make_ibd_name(
return(filename);
}
-/***********************************************************************
+/*******************************************************************//**
Renames a single-table tablespace. The tablespace must be cached in the
-tablespace memory cache. */
+tablespace memory cache.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_rename_tablespace(
/*==================*/
- /* out: TRUE if success */
- const char* old_name, /* in: old table name in the standard
+ const char* old_name, /*!< in: old table name in the standard
databasename/tablename format of
InnoDB, or NULL if we do the rename
based on the space id only */
- ulint id, /* in: space id */
- const char* new_name) /* in: new table name in the standard
+ ulint id, /*!< in: space id */
+ const char* new_name) /*!< in: new table name in the standard
databasename/tablename format
of InnoDB */
{
- fil_system_t* system = fil_system;
ibool success;
fil_space_t* space;
fil_node_t* node;
@@ -2463,7 +2417,7 @@ retry:
fprintf(stderr, ", %lu iterations\n", (ulong) count);
}
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -2474,14 +2428,14 @@ retry:
"InnoDB: though the table ", (ulong) id);
ut_print_filename(stderr, old_name);
fputs(" in a rename operation should have that id\n", stderr);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
if (count > 25000) {
space->stop_ios = FALSE;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
@@ -2499,7 +2453,7 @@ retry:
/* There are pending i/o's or flushes, sleep for a while and
retry */
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
os_thread_sleep(20000);
@@ -2508,7 +2462,7 @@ retry:
} else if (node->modification_counter > node->flush_counter) {
/* Flush the space */
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
os_thread_sleep(20000);
@@ -2519,7 +2473,7 @@ retry:
} else if (node->open) {
/* Close the file */
- fil_node_close_file(node, system);
+ fil_node_close_file(node, fil_system);
}
/* Check that the old name in the space is right */
@@ -2554,7 +2508,7 @@ retry:
space->stop_ios = FALSE;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
#ifndef UNIV_HOTBACKUP
if (success) {
@@ -2562,7 +2516,7 @@ retry:
mtr_start(&mtr);
- fil_op_write_log(MLOG_FILE_RENAME, id, 0, old_name, new_name,
+ fil_op_write_log(MLOG_FILE_RENAME, id, 0, 0, old_name, new_name,
&mtr);
mtr_commit(&mtr);
}
@@ -2570,28 +2524,28 @@ retry:
return(success);
}
-/***********************************************************************
+/*******************************************************************//**
Creates a new single-table tablespace to a database directory of MySQL.
Database directories are under the 'datadir' of MySQL. The datadir is the
directory of a running mysqld program. We can refer to it by simply the
path '.'. Tables created with CREATE TEMPORARY TABLE we place in the temp
-dir of the mysqld server. */
+dir of the mysqld server.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
fil_create_new_single_table_tablespace(
/*===================================*/
- /* out: DB_SUCCESS or error code */
- ulint* space_id, /* in/out: space id; if this is != 0,
+ ulint* space_id, /*!< in/out: space id; if this is != 0,
then this is an input parameter,
otherwise output */
- const char* tablename, /* in: the table name in the usual
+ const char* tablename, /*!< in: the table name in the usual
databasename/tablename format
of InnoDB, or a dir path to a temp
table */
- ibool is_temp, /* in: TRUE if a table created with
+ ibool is_temp, /*!< in: TRUE if a table created with
CREATE TEMPORARY TABLE */
- ulint flags, /* in: tablespace flags */
- ulint size) /* in: the initial size of the
+ ulint flags, /*!< in: tablespace flags */
+ ulint size) /*!< in: the initial size of the
tablespace file in pages,
must be >= FIL_IBD_FILE_INITIAL_SIZE */
{
@@ -2766,7 +2720,9 @@ error_exit2:
fil_op_write_log(flags
? MLOG_FILE_CREATE2
: MLOG_FILE_CREATE,
- *space_id, flags,
+ *space_id,
+ is_temp ? MLOG_FILE_FLAG_TEMP : 0,
+ flags,
tablename, NULL, &mtr);
mtr_commit(&mtr);
@@ -2776,7 +2732,8 @@ error_exit2:
return(DB_SUCCESS);
}
-/************************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
It is possible, though very improbable, that the lsn's in the tablespace to be
imported have risen above the current system lsn, if a lengthy purge, ibuf
merge, or rollback was performed on a backup taken with ibbackup. If that is
@@ -2784,15 +2741,15 @@ the case, reset page lsn's in the file. We assume that mysqld was shut down
after it performed these cleanup operations on the .ibd file, so that it at
the shutdown stamped the latest lsn to the FIL_PAGE_FILE_FLUSH_LSN in the
first page of the .ibd file, and we can determine whether we need to reset the
-lsn's just by looking at that flush lsn. */
+lsn's just by looking at that flush lsn.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_reset_too_high_lsns(
/*====================*/
- /* out: TRUE if success */
- const char* name, /* in: table name in the
+ const char* name, /*!< in: table name in the
databasename/tablename format */
- ib_uint64_t current_lsn) /* in: reset lsn's if the lsn stamped
+ ib_uint64_t current_lsn) /*!< in: reset lsn's if the lsn stamped
to FIL_PAGE_FILE_FLUSH_LSN in the
first page is too high */
{
@@ -2939,7 +2896,7 @@ func_exit:
return(success);
}
-/************************************************************************
+/********************************************************************//**
Tries to open a single-table tablespace and optionally checks the space id is
right in it. If does not succeed, prints an error message to the .err log. This
function is used to open a tablespace when we start up mysqld, and also in
@@ -2947,22 +2904,22 @@ IMPORT TABLESPACE.
NOTE that we assume this operation is used either at the database startup
or under the protection of the dictionary mutex, so that two users cannot
race here. This operation does not leave the file associated with the
-tablespace open, but closes it after we have looked at the space id in it. */
+tablespace open, but closes it after we have looked at the space id in it.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_open_single_table_tablespace(
/*=============================*/
- /* out: TRUE if success */
- ibool check_space_id, /* in: should we check that the space
+ ibool check_space_id, /*!< in: should we check that the space
id in the file is right; we assume
that this function runs much faster
if no check is made, since accessing
the file inode probably is much
faster (the OS caches them) than
accessing the first page of the file */
- ulint id, /* in: space id */
- ulint flags, /* in: tablespace flags */
- const char* name) /* in: table name in the
+ ulint id, /*!< in: space id */
+ ulint flags, /*!< in: tablespace flags */
+ const char* name) /*!< in: table name in the
databasename/tablename format */
{
os_file_t file;
@@ -3003,8 +2960,7 @@ fil_open_single_table_tablespace(
" a temporary table #sql...,\n"
"InnoDB: and MySQL removed the .ibd file for this.\n"
"InnoDB: Please refer to\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting-datadict.html\n"
"InnoDB: for how to resolve the issue.\n", stderr);
mem_free(filepath);
@@ -3043,8 +2999,8 @@ fil_open_single_table_tablespace(
ib_uint64_t current_lsn;
ulint size_low, size_high, size;
ib_int64_t size_bytes;
- dict_table_t* table;
- dict_index_t* index;
+ dict_table_t* table;
+ dict_index_t* index;
fil_system_t* system;
fil_node_t* node = NULL;
fil_space_t* space;
@@ -3078,7 +3034,6 @@ fil_open_single_table_tablespace(
index = dict_table_get_first_index(table);
ut_a(index->page==3);
-
/* read metadata from .exp file */
n_index = 0;
memset(old_id, 0, sizeof(old_id));
@@ -3133,22 +3088,58 @@ skip_info:
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
- ib_int64_t offset;
+ ib_int64_t offset;
+
size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
/* over write space id of all pages */
-
rec_offs_init(offsets_);
fprintf(stderr, "%s", "InnoDB: Progress in %:");
for (offset = 0; offset < size_bytes; offset += UNIV_PAGE_SIZE) {
+ ulint checksum_field;
+ ulint old_checksum_field;
+
success = os_file_read(file, page,
(ulint)(offset & 0xFFFFFFFFUL),
(ulint)(offset >> 32), UNIV_PAGE_SIZE);
+
+ /* skip inconsistent pages, it may be free page. */
+ if (memcmp(page + FIL_PAGE_LSN + 4,
+ page + UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM + 4, 4)) {
+
+ goto skip_write;
+ }
+
+ checksum_field = mach_read_from_4(page
+ + FIL_PAGE_SPACE_OR_CHKSUM);
+
+ old_checksum_field = mach_read_from_4(
+ page + UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM);
+
+ if (old_checksum_field != mach_read_from_4(page
+ + FIL_PAGE_LSN)
+ && old_checksum_field != BUF_NO_CHECKSUM_MAGIC
+ && old_checksum_field
+ != buf_calc_page_old_checksum(page)) {
+
+ goto skip_write;
+ }
+
+ if (checksum_field != 0
+ && checksum_field != BUF_NO_CHECKSUM_MAGIC
+ && checksum_field
+ != buf_calc_page_new_checksum(page)) {
+
+ goto skip_write;
+ }
+
if (mach_read_from_4(page + FIL_PAGE_OFFSET) || !offset) {
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id);
- for (i = 0; i < n_index; i++) {
+ for (i = 0; (ulint) i < n_index; i++) {
if (offset / UNIV_PAGE_SIZE == root_page[i]) {
/* this is index root page */
mach_write_to_4(page + FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
@@ -3174,13 +3165,30 @@ skip_info:
n_recs = page_get_n_recs(page);
while (rec && rec != supremum && n_recs > 0) {
+ ulint n_fields;
+ ulint i;
ulint offset = index->trx_id_offset;
+ offsets = rec_get_offsets(rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+ n_fields = rec_offs_n_fields(offsets);
if (!offset) {
- offsets = rec_get_offsets(rec, index, offsets,
- ULINT_UNDEFINED, &heap);
offset = row_get_trx_id_offset(rec, index, offsets);
}
trx_write_trx_id(rec + offset, ut_dulint_create(0, 1));
+
+ for (i = 0; i < n_fields; i++) {
+ if (rec_offs_nth_extern(offsets, i)) {
+ ulint local_len;
+ byte* data;
+
+ data = rec_get_nth_field(rec, offsets, i, &local_len);
+
+ local_len -= BTR_EXTERN_FIELD_REF_SIZE;
+
+ mach_write_to_4(data + local_len + BTR_EXTERN_SPACE_ID, id);
+ }
+ }
+
rec = page_rec_get_next(rec);
n_recs--;
}
@@ -3214,6 +3222,7 @@ skip_info:
(ulint)(offset >> 32), UNIV_PAGE_SIZE);
}
+skip_write:
if (size_bytes
&& ((ib_int64_t)((offset + UNIV_PAGE_SIZE) * 100) / size_bytes)
!= ((offset * 100) / size_bytes)) {
@@ -3316,8 +3325,7 @@ skip_info:
"InnoDB: commands DISCARD TABLESPACE and"
" IMPORT TABLESPACE?\n"
"InnoDB: Please refer to\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting-datadict.html\n"
"InnoDB: for how to resolve the issue.\n",
(ulong) space_id, (ulong) space_flags,
(ulong) id, (ulong) flags);
@@ -3344,17 +3352,18 @@ func_exit:
return(ret);
}
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_HOTBACKUP
-/***********************************************************************
+/*******************************************************************//**
Allocates a file name for an old version of a single-table tablespace.
-The string must be freed by caller with mem_free()! */
+The string must be freed by caller with mem_free()!
+@return own: file name */
static
char*
fil_make_ibbackup_old_name(
/*=======================*/
- /* out, own: file name */
- const char* name) /* in: original file name */
+ const char* name) /*!< in: original file name */
{
static const char suffix[] = "_ibbackup_old_vers_";
ulint len = strlen(name);
@@ -3367,15 +3376,15 @@ fil_make_ibbackup_old_name(
}
#endif /* UNIV_HOTBACKUP */
-/************************************************************************
+/********************************************************************//**
Opens an .ibd file and adds the associated single-table tablespace to the
InnoDB fil0fil.c data structures. */
static
void
fil_load_single_table_tablespace(
/*=============================*/
- const char* dbname, /* in: database name */
- const char* filename) /* in: file name (not a path),
+ const char* dbname, /*!< in: database name */
+ const char* filename) /*!< in: file name (not a path),
including the .ibd extension */
{
os_file_t file;
@@ -3583,9 +3592,9 @@ fil_load_single_table_tablespace(
file than delete it, because if there is a bug, we do not want to
destroy valuable data. */
- mutex_enter(&(fil_system->mutex));
+ mutex_enter(&fil_system->mutex);
- space = fil_get_space_for_id_low(space_id);
+ space = fil_space_get_by_id(space_id);
if (space) {
char* new_path;
@@ -3603,7 +3612,7 @@ fil_load_single_table_tablespace(
new_path = fil_make_ibbackup_old_name(filepath);
- mutex_exit(&(fil_system->mutex));
+ mutex_exit(&fil_system->mutex);
ut_a(os_file_rename(filepath, new_path));
@@ -3613,7 +3622,7 @@ fil_load_single_table_tablespace(
return;
}
- mutex_exit(&(fil_system->mutex));
+ mutex_exit(&fil_system->mutex);
#endif
success = fil_space_create(filepath, space_id, flags, FIL_TABLESPACE);
@@ -3633,21 +3642,21 @@ func_exit:
mem_free(filepath);
}
-/***************************************************************************
+/***********************************************************************//**
A fault-tolerant function that tries to read the next file name in the
directory. We retry 100 times if os_file_readdir_next_file() returns -1. The
-idea is to read as much good data as we can and jump over bad data. */
+idea is to read as much good data as we can and jump over bad data.
+@return 0 if ok, -1 if error even after the retries, 1 if at the end
+of the directory */
static
int
fil_file_readdir_next_file(
/*=======================*/
- /* out: 0 if ok, -1 if error even after the
- retries, 1 if at the end of the directory */
- ulint* err, /* out: this is set to DB_ERROR if an error
+ ulint* err, /*!< out: this is set to DB_ERROR if an error
was encountered, otherwise not changed */
- const char* dirname,/* in: directory name or path */
- os_file_dir_t dir, /* in: directory stream */
- os_file_stat_t* info) /* in/out: buffer where the info is returned */
+ const char* dirname,/*!< in: directory name or path */
+ os_file_dir_t dir, /*!< in: directory stream */
+ os_file_stat_t* info) /*!< in/out: buffer where the info is returned */
{
ulint i;
int ret;
@@ -3673,18 +3682,18 @@ fil_file_readdir_next_file(
return(-1);
}
-/************************************************************************
+/********************************************************************//**
At the server startup, if we need crash recovery, scans the database
directories under the MySQL datadir, looking for .ibd files. Those files are
single-table tablespaces. We need to know the space id in each of them so that
we know into which file we should look to check the contents of a page stored
in the doublewrite buffer, also to know where to apply log records where the
-space id is != 0. */
+space id is != 0.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
fil_load_single_table_tablespaces(void)
/*===================================*/
- /* out: DB_SUCCESS or error number */
{
int ret;
char* dbpath = NULL;
@@ -3802,7 +3811,7 @@ 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
@@ -3813,12 +3822,11 @@ void
fil_print_orphaned_tablespaces(void)
/*================================*/
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- space = UT_LIST_GET_FIRST(system->space_list);
+ space = UT_LIST_GET_FIRST(fil_system->space_list);
while (space) {
if (space->purpose == FIL_TABLESPACE && space->id != 0
@@ -3833,115 +3841,104 @@ fil_print_orphaned_tablespaces(void)
space = UT_LIST_GET_NEXT(space_list, space);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
-/***********************************************************************
+/*******************************************************************//**
Returns TRUE if a single-table tablespace does not exist in the memory cache,
-or is being deleted there. */
+or is being deleted there.
+@return TRUE if does not exist or is being\ deleted */
UNIV_INTERN
ibool
fil_tablespace_deleted_or_being_deleted_in_mem(
/*===========================================*/
- /* out: TRUE if does not exist or is being\
- deleted */
- ulint id, /* in: space id */
- ib_int64_t version)/* in: tablespace_version should be this; if
+ ulint id, /*!< in: space id */
+ ib_int64_t version)/*!< in: tablespace_version should be this; if
you pass -1 as the value of this, then this
parameter is ignored */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
if (space == NULL || space->is_being_deleted) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(TRUE);
}
if (version != ((ib_int64_t)-1)
&& space->tablespace_version != version) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(TRUE);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
-/***********************************************************************
-Returns TRUE if a single-table tablespace exists in the memory cache. */
+/*******************************************************************//**
+Returns TRUE if a single-table tablespace exists in the memory cache.
+@return TRUE if exists */
UNIV_INTERN
ibool
fil_tablespace_exists_in_mem(
/*=========================*/
- /* out: TRUE if exists */
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
- if (space == NULL) {
- mutex_exit(&(system->mutex));
-
- return(FALSE);
- }
-
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
- return(TRUE);
+ return(space != NULL);
}
-/***********************************************************************
+/*******************************************************************//**
Returns TRUE if a matching tablespace exists in the InnoDB tablespace memory
cache. Note that if we have not done a crash recovery at the database startup,
-there may be many tablespaces which are not yet in the memory cache. */
+there may be many tablespaces which are not yet in the memory cache.
+@return TRUE if a matching tablespace exists in the memory cache */
UNIV_INTERN
ibool
fil_space_for_table_exists_in_mem(
/*==============================*/
- /* out: TRUE if a matching tablespace
- exists in the memory cache */
- ulint id, /* in: space id */
- const char* name, /* in: table name in the standard
+ ulint id, /*!< in: space id */
+ const char* name, /*!< in: table name in the standard
'databasename/tablename' format or
the dir path to a temp table */
- ibool is_temp, /* in: TRUE if created with CREATE
+ ibool is_temp, /*!< in: TRUE if created with CREATE
TEMPORARY TABLE */
- ibool mark_space, /* in: in crash recovery, at database
+ ibool mark_space, /*!< in: in crash recovery, at database
startup we mark all spaces which have
an associated table in the InnoDB
data dictionary, so that
we can print a warning about orphaned
tablespaces */
ibool print_error_if_does_not_exist)
- /* in: print detailed error
+ /*!< in: print detailed error
information to the .err log if a
matching tablespace is not found from
memory */
{
- fil_system_t* system = fil_system;
fil_space_t* namespace;
fil_space_t* space;
char* path;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
path = fil_make_ibd_name(name, is_temp);
@@ -3961,7 +3958,7 @@ fil_space_for_table_exists_in_mem(
}
mem_free(path);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(TRUE);
}
@@ -3969,7 +3966,7 @@ fil_space_for_table_exists_in_mem(
if (!print_error_if_does_not_exist) {
mem_free(path);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
@@ -4009,12 +4006,11 @@ fil_space_for_table_exists_in_mem(
}
error_exit:
fputs("InnoDB: Please refer to\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting-datadict.html\n"
"InnoDB: for how to resolve the issue.\n", stderr);
mem_free(path);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
@@ -4044,31 +4040,29 @@ error_exit:
}
mem_free(path);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Checks if a single-table tablespace for a given table name exists in the
-tablespace memory cache. */
+tablespace memory cache.
+@return space id, ULINT_UNDEFINED if not found */
static
ulint
fil_get_space_id_for_table(
/*=======================*/
- /* out: space id, ULINT_UNDEFINED if not
- found */
- const char* name) /* in: table name in the standard
+ const char* name) /*!< in: table name in the standard
'databasename/tablename' format */
{
- fil_system_t* system = fil_system;
fil_space_t* namespace;
ulint id = ULINT_UNDEFINED;
char* path;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
path = fil_make_ibd_name(name, FALSE);
@@ -4083,29 +4077,28 @@ fil_get_space_id_for_table(
mem_free(path);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(id);
}
-/**************************************************************************
+/**********************************************************************//**
Tries to extend a data file so that it would accommodate the number of pages
given. The tablespace must be cached in the memory cache. If the space is big
-enough already, does nothing. */
+enough already, does nothing.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_extend_space_to_desired_size(
/*=============================*/
- /* out: TRUE if success */
- ulint* actual_size, /* out: size of the space after extension;
+ ulint* actual_size, /*!< out: size of the space after extension;
if we ran out of disk space this may be lower
than the desired size */
- ulint space_id, /* in: space id */
- ulint size_after_extend)/* in: desired size in pages after the
+ ulint space_id, /*!< in: space id */
+ ulint size_after_extend)/*!< in: desired size in pages after the
extension; if the current space size is bigger
than this already, the function does nothing */
{
- fil_system_t* system = fil_system;
fil_node_t* node;
fil_space_t* space;
byte* buf2;
@@ -4128,7 +4121,7 @@ fil_extend_space_to_desired_size(
*actual_size = space->size;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(TRUE);
}
@@ -4140,7 +4133,7 @@ fil_extend_space_to_desired_size(
node = UT_LIST_GET_LAST(space->chain);
- fil_node_prepare_for_io(node, system, space);
+ fil_node_prepare_for_io(node, fil_system, space);
start_page_no = space->size;
file_start_page_no = space->size - node->size;
@@ -4197,7 +4190,7 @@ fil_extend_space_to_desired_size(
mem_free(buf2);
- fil_node_complete_io(node, system, OS_FILE_WRITE);
+ fil_node_complete_io(node, fil_system, OS_FILE_WRITE);
*actual_size = space->size;
@@ -4216,7 +4209,7 @@ fil_extend_space_to_desired_size(
/*
printf("Extended %s to %lu, actual size %lu pages\n", space->name,
size_after_extend, *actual_size); */
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
fil_flush(space_id);
@@ -4224,7 +4217,7 @@ fil_extend_space_to_desired_size(
}
#ifdef UNIV_HOTBACKUP
-/************************************************************************
+/********************************************************************//**
Extends all tablespaces to the size stored in the space header. During the
ibbackup --apply-log phase we extended the spaces on-demand so that log records
could be applied, but that may have left spaces still too small compared to
@@ -4234,7 +4227,6 @@ void
fil_extend_tablespaces_to_stored_len(void)
/*======================================*/
{
- fil_system_t* system = fil_system;
fil_space_t* space;
byte* buf;
ulint actual_size;
@@ -4244,17 +4236,18 @@ fil_extend_tablespaces_to_stored_len(void)
buf = mem_alloc(UNIV_PAGE_SIZE);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- space = UT_LIST_GET_FIRST(system->space_list);
+ space = UT_LIST_GET_FIRST(fil_system->space_list);
while (space) {
ut_a(space->purpose == FIL_TABLESPACE);
- mutex_exit(&(system->mutex)); /* no need to protect with a
+ mutex_exit(&fil_system->mutex); /* no need to protect with a
mutex, because this is a
single-threaded operation */
- error = fil_read(TRUE, space->id, space->zip_size,
+ error = fil_read(TRUE, space->id,
+ dict_table_flags_to_zip_size(space->flags),
0, 0, UNIV_PAGE_SIZE, buf, NULL);
ut_a(error == DB_SUCCESS);
@@ -4275,12 +4268,12 @@ fil_extend_tablespaces_to_stored_len(void)
exit(1);
}
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = UT_LIST_GET_NEXT(space_list, space);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
mem_free(buf);
}
@@ -4288,24 +4281,23 @@ fil_extend_tablespaces_to_stored_len(void)
/*========== RESERVE FREE EXTENTS (for a B-tree split, for example) ===*/
-/***********************************************************************
-Tries to reserve free extents in a file space. */
+/*******************************************************************//**
+Tries to reserve free extents in a file space.
+@return TRUE if succeed */
UNIV_INTERN
ibool
fil_space_reserve_free_extents(
/*===========================*/
- /* out: TRUE if succeed */
- ulint id, /* in: space id */
- ulint n_free_now, /* in: number of free extents now */
- ulint n_to_reserve) /* in: how many one wants to reserve */
+ ulint id, /*!< in: space id */
+ ulint n_free_now, /*!< in: number of free extents now */
+ ulint n_to_reserve) /*!< in: how many one wants to reserve */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
ibool success;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -4318,26 +4310,25 @@ fil_space_reserve_free_extents(
success = TRUE;
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(success);
}
-/***********************************************************************
+/*******************************************************************//**
Releases free extents in a file space. */
UNIV_INTERN
void
fil_space_release_free_extents(
/*===========================*/
- ulint id, /* in: space id */
- ulint n_reserved) /* in: how many one reserved */
+ ulint id, /*!< in: space id */
+ ulint n_reserved) /*!< in: how many one reserved */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -4346,25 +4337,24 @@ fil_space_release_free_extents(
space->n_reserved_extents -= n_reserved;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
-/***********************************************************************
+/*******************************************************************//**
Gets the number of reserved extents. If the database is silent, this number
should be zero. */
UNIV_INTERN
ulint
fil_space_get_n_reserved_extents(
/*=============================*/
- ulint id) /* in: space id */
+ ulint id) /*!< in: space id */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
ulint n;
- ut_ad(system);
+ ut_ad(fil_system);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -4372,14 +4362,14 @@ fil_space_get_n_reserved_extents(
n = space->n_reserved_extents;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(n);
}
/*============================ FILE I/O ================================*/
-/************************************************************************
+/********************************************************************//**
NOTE: you must call fil_mutex_enter_and_prepare_for_io() first!
Prepares a file node for i/o. Opens the file if it is closed. Updates the
@@ -4390,9 +4380,9 @@ static
void
fil_node_prepare_for_io(
/*====================*/
- fil_node_t* node, /* in: file node */
- fil_system_t* system, /* in: tablespace memory cache */
- fil_space_t* space) /* in: space */
+ fil_node_t* node, /*!< in: file node */
+ fil_system_t* system, /*!< in: tablespace memory cache */
+ fil_space_t* space) /*!< in: space */
{
ut_ad(node && system && space);
ut_ad(mutex_own(&(system->mutex)));
@@ -4425,16 +4415,16 @@ fil_node_prepare_for_io(
node->n_pending++;
}
-/************************************************************************
+/********************************************************************//**
Updates the data structures when an i/o operation finishes. Updates the
pending i/o's field in the node appropriately. */
static
void
fil_node_complete_io(
/*=================*/
- fil_node_t* node, /* in: file node */
- fil_system_t* system, /* in: tablespace memory cache */
- ulint type) /* in: OS_FILE_WRITE or OS_FILE_READ; marks
+ fil_node_t* node, /*!< in: file node */
+ fil_system_t* system, /*!< in: tablespace memory cache */
+ ulint type) /*!< in: OS_FILE_WRITE or OS_FILE_READ; marks
the node as modified if
type == OS_FILE_WRITE */
{
@@ -4466,18 +4456,18 @@ fil_node_complete_io(
}
}
-/************************************************************************
+/********************************************************************//**
Report information about an invalid page access. */
static
void
fil_report_invalid_page_access(
/*===========================*/
- ulint block_offset, /* in: block offset */
- ulint space_id, /* in: space id */
- const char* space_name, /* in: space name */
- ulint byte_offset, /* in: byte offset */
- ulint len, /* in: I/O length */
- ulint type) /* in: I/O type */
+ ulint block_offset, /*!< in: block offset */
+ ulint space_id, /*!< in: space id */
+ const char* space_name, /*!< in: space name */
+ ulint byte_offset, /*!< in: byte offset */
+ ulint len, /*!< in: I/O length */
+ ulint type) /*!< in: I/O type */
{
fprintf(stderr,
"InnoDB: Error: trying to access page number %lu"
@@ -4494,16 +4484,15 @@ fil_report_invalid_page_access(
(ulong) byte_offset, (ulong) len, (ulong) type);
}
-/************************************************************************
-Reads or writes data. This operation is asynchronous (aio). */
+/********************************************************************//**
+Reads or writes data. This operation is asynchronous (aio).
+@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
+i/o on a tablespace which does not exist */
UNIV_INTERN
ulint
fil_io(
/*===*/
- /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
- if we are trying to do i/o on a tablespace
- which does not exist */
- ulint type, /* in: OS_FILE_READ or OS_FILE_WRITE,
+ ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
ORed to OS_FILE_LOG, if a log i/o
and ORed to OS_AIO_SIMULATED_WAKE_LATER
if simulated aio and we want to post a
@@ -4512,24 +4501,23 @@ fil_io(
because i/os are not actually handled until
all have been posted: use with great
caution! */
- ibool sync, /* in: TRUE if synchronous aio is desired */
- ulint space_id, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes;
+ ibool sync, /*!< in: TRUE if synchronous aio is desired */
+ ulint space_id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint block_offset, /* in: offset in number of blocks */
- ulint byte_offset, /* in: remainder of offset in bytes; in
+ ulint block_offset, /*!< in: offset in number of blocks */
+ ulint byte_offset, /*!< in: remainder of offset in bytes; in
aio this must be divisible by the OS block
size */
- ulint len, /* in: how many bytes to read or write; this
+ ulint len, /*!< in: how many bytes to read or write; this
must not cross a file boundary; in aio this
must be a block size multiple */
- void* buf, /* in/out: buffer where to store read data
+ void* buf, /*!< in/out: buffer where to store read data
or from where to write; in aio this must be
appropriately aligned */
- void* message) /* in: message for aio handler if non-sync
+ void* message) /*!< in: message for aio handler if non-sync
aio used, else ignored */
{
- fil_system_t* system = fil_system;
ulint mode;
fil_space_t* space;
fil_node_t* node;
@@ -4554,14 +4542,15 @@ fil_io(
# error "(1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE"
#endif
ut_ad(fil_validate());
-#ifndef UNIV_LOG_DEBUG
+#ifndef UNIV_HOTBACKUP
+# ifndef UNIV_LOG_DEBUG
/* ibuf bitmap pages must be read in the sync aio mode: */
ut_ad(recv_no_ibuf_operations || (type == OS_FILE_WRITE)
|| !ibuf_bitmap_page(zip_size, block_offset)
|| sync || is_log);
ut_ad(!ibuf_inside() || is_log || (type == OS_FILE_WRITE)
|| ibuf_page(space_id, zip_size, block_offset, NULL));
-#endif
+# endif /* UNIV_LOG_DEBUG */
if (sync) {
mode = OS_AIO_SYNC;
} else if (is_log) {
@@ -4573,6 +4562,10 @@ fil_io(
} else {
mode = OS_AIO_NORMAL;
}
+#else /* !UNIV_HOTBACKUP */
+ ut_a(sync);
+ mode = OS_AIO_SYNC;
+#endif /* !UNIV_HOTBACKUP */
if (type == OS_FILE_READ) {
srv_data_read+= len;
@@ -4588,7 +4581,7 @@ fil_io(
space = fil_space_get_by_id(space_id);
if (!space) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -4632,7 +4625,7 @@ fil_io(
}
/* Open file if closed */
- fil_node_prepare_for_io(node, system, space);
+ fil_node_prepare_for_io(node, fil_system, space);
/* Check that at least the start offset is within the bounds of a
single-table tablespace */
@@ -4646,8 +4639,8 @@ fil_io(
ut_error;
}
- /* Now we have made the changes in the data structures of system */
- mutex_exit(&(system->mutex));
+ /* Now we have made the changes in the data structures of fil_system */
+ mutex_exit(&fil_system->mutex);
/* Calculate the low 32 bits and the high 32 bits of the file offset */
@@ -4701,11 +4694,11 @@ fil_io(
/* The i/o operation is already completed when we return from
os_aio: */
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- fil_node_complete_io(node, system, type);
+ fil_node_complete_io(node, fil_system, type);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
ut_ad(fil_validate());
}
@@ -4713,7 +4706,8 @@ fil_io(
return(DB_SUCCESS);
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Waits for an aio operation to complete. This function is used to write the
handler for completed requests. The aio array of pending requests is divided
into segments (see os0file.c for more info). The thread specifies which
@@ -4722,10 +4716,9 @@ UNIV_INTERN
void
fil_aio_wait(
/*=========*/
- ulint segment) /* in: the number of the segment in the aio
+ ulint segment) /*!< in: the number of the segment in the aio
array to wait for */
{
- fil_system_t* system = fil_system;
ibool ret;
fil_node_t* fil_node;
void* message;
@@ -4753,11 +4746,11 @@ fil_aio_wait(
srv_set_io_thread_op_info(segment, "complete io for fil node");
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
fil_node_complete_io(fil_node, fil_system, type);
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
ut_ad(fil_validate());
@@ -4775,34 +4768,34 @@ fil_aio_wait(
log_io_complete(message);
}
}
+#endif /* UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Flushes to disk possible writes cached by the OS. If the space does not exist
or is being dropped, does not do anything. */
UNIV_INTERN
void
fil_flush(
/*======*/
- ulint space_id) /* in: file space id (this can be a group of
+ ulint space_id) /*!< in: file space id (this can be a group of
log files or a tablespace of the database) */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
fil_node_t* node;
os_file_t file;
ib_int64_t old_mod_counter;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(space_id);
if (!space || space->is_being_deleted) {
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return;
}
- space->n_pending_flushes++; /* prevent dropping of the space while
+ space->n_pending_flushes++; /*!< prevent dropping of the space while
we are flushing */
node = UT_LIST_GET_FIRST(space->chain);
@@ -4833,11 +4826,11 @@ retry:
not know what bugs OS's may contain in file
i/o; sleep for a while */
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
os_thread_sleep(20000);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
if (node->flush_counter >= old_mod_counter) {
@@ -4851,14 +4844,14 @@ retry:
file = node->handle;
node->n_pending_flushes++;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
/* fprintf(stderr, "Flushing to file %s\n",
node->name); */
os_file_flush(file);
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
node->n_pending_flushes--;
skip_flush:
@@ -4872,7 +4865,7 @@ skip_flush:
UT_LIST_REMOVE(
unflushed_spaces,
- system->unflushed_spaces,
+ fil_system->unflushed_spaces,
space);
}
}
@@ -4889,42 +4882,41 @@ skip_flush:
space->n_pending_flushes--;
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
}
-/**************************************************************************
+/**********************************************************************//**
Flushes to disk the writes in file spaces of the given type possibly cached by
the OS. */
UNIV_INTERN
void
fil_flush_file_spaces(
/*==================*/
- ulint purpose) /* in: FIL_TABLESPACE, FIL_LOG */
+ ulint purpose) /*!< in: FIL_TABLESPACE, FIL_LOG */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
ulint* space_ids;
ulint n_space_ids;
ulint i;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
- n_space_ids = UT_LIST_GET_LEN(system->unflushed_spaces);
+ n_space_ids = UT_LIST_GET_LEN(fil_system->unflushed_spaces);
if (n_space_ids == 0) {
- mutex_exit(&system->mutex);
+ mutex_exit(&fil_system->mutex);
return;
}
/* Assemble a list of space ids to flush. Previously, we
- traversed system->unflushed_spaces and called UT_LIST_GET_NEXT()
+ traversed fil_system->unflushed_spaces and called UT_LIST_GET_NEXT()
on a space that was just removed from the list by fil_flush().
Thus, the space could be dropped and the memory overwritten. */
space_ids = mem_alloc(n_space_ids * sizeof *space_ids);
n_space_ids = 0;
- for (space = UT_LIST_GET_FIRST(system->unflushed_spaces);
+ for (space = UT_LIST_GET_FIRST(fil_system->unflushed_spaces);
space;
space = UT_LIST_GET_NEXT(unflushed_spaces, space)) {
@@ -4934,7 +4926,7 @@ fil_flush_file_spaces(
}
}
- mutex_exit(&system->mutex);
+ mutex_exit(&fil_system->mutex);
/* Flush the spaces. It will not hurt to call fil_flush() on
a non-existing space id. */
@@ -4946,30 +4938,31 @@ fil_flush_file_spaces(
mem_free(space_ids);
}
-/**********************************************************************
-Checks the consistency of the tablespace cache. */
+/******************************************************************//**
+Checks the consistency of the tablespace cache.
+@return TRUE if ok */
UNIV_INTERN
ibool
fil_validate(void)
/*==============*/
- /* out: TRUE if ok */
{
- fil_system_t* system = fil_system;
fil_space_t* space;
fil_node_t* fil_node;
ulint n_open = 0;
ulint i;
- mutex_enter(&(system->mutex));
+ mutex_enter(&fil_system->mutex);
/* Look for spaces in the hash table */
- for (i = 0; i < hash_get_n_cells(system->spaces); i++) {
+ for (i = 0; i < hash_get_n_cells(fil_system->spaces); i++) {
- space = HASH_GET_FIRST(system->spaces, i);
+ space = HASH_GET_FIRST(fil_system->spaces, i);
while (space != NULL) {
- UT_LIST_VALIDATE(chain, fil_node_t, space->chain);
+ UT_LIST_VALIDATE(chain, fil_node_t, space->chain,
+ ut_a(ut_list_node_313->open
+ || !ut_list_node_313->n_pending));
fil_node = UT_LIST_GET_FIRST(space->chain);
@@ -4987,11 +4980,11 @@ fil_validate(void)
}
}
- ut_a(system->n_open == n_open);
+ ut_a(fil_system->n_open == n_open);
- UT_LIST_VALIDATE(LRU, fil_node_t, system->LRU);
+ UT_LIST_VALIDATE(LRU, fil_node_t, fil_system->LRU, (void) 0);
- fil_node = UT_LIST_GET_FIRST(system->LRU);
+ fil_node = UT_LIST_GET_FIRST(fil_system->LRU);
while (fil_node != NULL) {
ut_a(fil_node->n_pending == 0);
@@ -5002,63 +4995,70 @@ fil_validate(void)
fil_node = UT_LIST_GET_NEXT(LRU, fil_node);
}
- mutex_exit(&(system->mutex));
+ mutex_exit(&fil_system->mutex);
return(TRUE);
}
-/************************************************************************
-Returns TRUE if file address is undefined. */
+/********************************************************************//**
+Returns TRUE if file address is undefined.
+@return TRUE if undefined */
UNIV_INTERN
ibool
fil_addr_is_null(
/*=============*/
- /* out: TRUE if undefined */
- fil_addr_t addr) /* in: address */
+ fil_addr_t addr) /*!< in: address */
{
return(addr.page == FIL_NULL);
}
-/************************************************************************
-Accessor functions for a file page */
+/********************************************************************//**
+Get the predecessor of a file page.
+@return FIL_PAGE_PREV */
UNIV_INTERN
ulint
-fil_page_get_prev(const byte* page)
+fil_page_get_prev(
+/*==============*/
+ const byte* page) /*!< in: file page */
{
return(mach_read_from_4(page + FIL_PAGE_PREV));
}
+/********************************************************************//**
+Get the successor of a file page.
+@return FIL_PAGE_NEXT */
UNIV_INTERN
ulint
-fil_page_get_next(const byte* page)
+fil_page_get_next(
+/*==============*/
+ const byte* page) /*!< in: file page */
{
return(mach_read_from_4(page + FIL_PAGE_NEXT));
}
-/*************************************************************************
+/*********************************************************************//**
Sets the file page type. */
UNIV_INTERN
void
fil_page_set_type(
/*==============*/
- byte* page, /* in: file page */
- ulint type) /* in: type */
+ byte* page, /*!< in/out: file page */
+ ulint type) /*!< in: type */
{
ut_ad(page);
mach_write_to_2(page + FIL_PAGE_TYPE, type);
}
-/*************************************************************************
-Gets the file page type. */
+/*********************************************************************//**
+Gets the file page type.
+@return type; NOTE that if the type has not been written to page, the
+return value not defined */
UNIV_INTERN
ulint
fil_page_get_type(
/*==============*/
- /* out: type; NOTE that if the type
- has not been written to page, the return value
- not defined */
- const byte* page) /* in: file page */
+ const byte* page) /*!< in: file page */
{
ut_ad(page);
diff --git a/storage/xtradb/fsp/fsp0fsp.c b/storage/xtradb/fsp/fsp0fsp.c
index 25d260daeea..ce14723ba18 100644
--- a/storage/xtradb/fsp/fsp0fsp.c
+++ b/storage/xtradb/fsp/fsp0fsp.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file fsp/fsp0fsp.c
File space management
Created 11/29/1995 Heikki Tuuri
@@ -30,18 +31,23 @@ Created 11/29/1995 Heikki Tuuri
#include "buf0buf.h"
#include "fil0fil.h"
-#include "sync0sync.h"
#include "mtr0log.h"
-#include "fut0fut.h"
#include "ut0byte.h"
-#include "srv0srv.h"
+#include "page0page.h"
#include "page0zip.h"
-#include "ibuf0ibuf.h"
-#include "btr0btr.h"
-#include "btr0sea.h"
-#include "dict0boot.h"
+#ifdef UNIV_HOTBACKUP
+# include "fut0lst.h"
+#else /* UNIV_HOTBACKUP */
+# include "sync0sync.h"
+# include "fut0fut.h"
+# include "srv0srv.h"
+# include "ibuf0ibuf.h"
+# include "btr0btr.h"
+# include "btr0sea.h"
+# include "dict0boot.h"
+# include "log0log.h"
+#endif /* UNIV_HOTBACKUP */
#include "dict0mem.h"
-#include "log0log.h"
#define FSP_HEADER_OFFSET FIL_PAGE_DATA /* Offset of the space header
@@ -225,69 +231,70 @@ the extent are free and which contain old tuple version to clean. */
/* Offset of the descriptor array on a descriptor page */
#define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Returns an extent to the free list of a space. */
static
void
fsp_free_extent(
/*============*/
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: page offset in the extent */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ ulint page, /*!< in: page offset in the extent */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Frees an extent of a segment to the space free list. */
static
void
fseg_free_extent(
/*=============*/
- fseg_inode_t* seg_inode, /* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* seg_inode, /*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: page offset in the extent */
- mtr_t* mtr); /* in: mtr handle */
-/**************************************************************************
+ ulint page, /*!< in: page offset in the extent */
+ mtr_t* mtr); /*!< in: mtr handle */
+/**********************************************************************//**
Calculates the number of pages reserved by a segment, and how
-many pages are currently used. */
+many pages are currently used.
+@return number of reserved pages */
static
ulint
fseg_n_reserved_pages_low(
/*======================*/
- /* out: number of reserved pages */
- fseg_inode_t* header, /* in: segment inode */
- ulint* used, /* out: number of pages used (<= reserved) */
- mtr_t* mtr); /* in: mtr handle */
-/************************************************************************
+ fseg_inode_t* header, /*!< in: segment inode */
+ ulint* used, /*!< out: number of pages used (not
+ more than reserved) */
+ mtr_t* mtr); /*!< in: mtr handle */
+/********************************************************************//**
Marks a page used. The page must reside within the extents of the given
segment. */
static
void
fseg_mark_page_used(
/*================*/
- fseg_inode_t* seg_inode,/* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* seg_inode,/*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: page offset */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ ulint page, /*!< in: page offset */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Returns the first extent descriptor for a segment. We think of the extent
lists of the segment catenated in the order FSEG_FULL -> FSEG_NOT_FULL
--> FSEG_FREE. */
+-> FSEG_FREE.
+@return the first extent descriptor, or NULL if none */
static
xdes_t*
fseg_get_first_extent(
/*==================*/
- /* out: the first extent descriptor, or NULL if
- none */
- fseg_inode_t* inode, /* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* inode, /*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Puts new extents to the free list if
there are free extents above the free limit. If an extent happens
to contain an extent descriptor page, the extent is put to
@@ -296,60 +303,60 @@ static
void
fsp_fill_free_list(
/*===============*/
- ibool init_space, /* in: TRUE if this is a single-table
+ ibool init_space, /*!< in: TRUE if this is a single-table
tablespace and we are only initing
the tablespace's first extent
descriptor page and ibuf bitmap page;
then we do not allocate more extents */
- ulint space, /* in: space */
- fsp_header_t* header, /* in: space header */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ ulint space, /*!< in: space */
+ fsp_header_t* header, /*!< in: space header */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Allocates a single free page from a segment. This function implements
the intelligent allocation strategy which tries to minimize file space
-fragmentation. */
+fragmentation.
+@return the allocated page number, FIL_NULL if no page could be allocated */
static
ulint
fseg_alloc_free_page_low(
/*=====================*/
- /* out: the allocated page number, FIL_NULL
- if no page could be allocated */
- ulint space, /* in: space */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- fseg_inode_t* seg_inode, /* in: segment inode */
- ulint hint, /* in: hint of which page would be desirable */
- byte direction, /* in: if the new page is needed because
+ fseg_inode_t* seg_inode, /*!< in: segment inode */
+ ulint hint, /*!< in: hint of which page would be desirable */
+ byte direction, /*!< in: if the new page is needed because
of an index page split, and records are
inserted there in order, into which
direction they go alphabetically: FSP_DOWN,
FSP_UP, FSP_NO_DIR */
- mtr_t* mtr); /* in: mtr handle */
+ mtr_t* mtr); /*!< in: mtr handle */
+#endif /* !UNIV_HOTBACKUP */
-
-/**************************************************************************
-Reads the file space size stored in the header page. */
+/**********************************************************************//**
+Reads the file space size stored in the header page.
+@return tablespace size stored in the space header */
UNIV_INTERN
ulint
fsp_get_size_low(
/*=============*/
- /* out: tablespace size stored in the space header */
- page_t* page) /* in: header page (page 0 in the tablespace) */
+ page_t* page) /*!< in: header page (page 0 in the tablespace) */
{
return(mach_read_from_4(page + FSP_HEADER_OFFSET + FSP_SIZE));
}
-/**************************************************************************
-Gets a pointer to the space header and x-locks its page. */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
+Gets a pointer to the space header and x-locks its page.
+@return pointer to the space header, page x-locked */
UNIV_INLINE
fsp_header_t*
fsp_get_space_header(
/*=================*/
- /* out: pointer to the space header, page x-locked */
- ulint id, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint id, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
fsp_header_t* header;
@@ -369,18 +376,18 @@ fsp_get_space_header(
return(header);
}
-/**************************************************************************
-Gets a descriptor bit of a page. */
+/**********************************************************************//**
+Gets a descriptor bit of a page.
+@return TRUE if free */
UNIV_INLINE
ibool
xdes_get_bit(
/*=========*/
- /* out: TRUE if free */
- xdes_t* descr, /* in: descriptor */
- ulint bit, /* in: XDES_FREE_BIT or XDES_CLEAN_BIT */
- ulint offset, /* in: page offset within extent:
+ xdes_t* descr, /*!< in: descriptor */
+ ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */
+ ulint offset, /*!< in: page offset within extent:
0 ... FSP_EXTENT_SIZE - 1 */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint index;
ulint byte_index;
@@ -400,18 +407,18 @@ xdes_get_bit(
bit_index));
}
-/**************************************************************************
+/**********************************************************************//**
Sets a descriptor bit of a page. */
UNIV_INLINE
void
xdes_set_bit(
/*=========*/
- xdes_t* descr, /* in: descriptor */
- ulint bit, /* in: XDES_FREE_BIT or XDES_CLEAN_BIT */
- ulint offset, /* in: page offset within extent:
+ xdes_t* descr, /*!< in: descriptor */
+ ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */
+ ulint offset, /*!< in: page offset within extent:
0 ... FSP_EXTENT_SIZE - 1 */
- ibool val, /* in: bit value */
- mtr_t* mtr) /* in: mtr */
+ ibool val, /*!< in: bit value */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint index;
ulint byte_index;
@@ -435,21 +442,20 @@ xdes_set_bit(
MLOG_1BYTE, mtr);
}
-/**************************************************************************
+/**********************************************************************//**
Looks for a descriptor bit having the desired value. Starts from hint
and scans upward; at the end of the extent the search is wrapped to
-the start of the extent. */
+the start of the extent.
+@return bit index of the bit, ULINT_UNDEFINED if not found */
UNIV_INLINE
ulint
xdes_find_bit(
/*==========*/
- /* out: bit index of the bit, ULINT_UNDEFINED if not
- found */
- xdes_t* descr, /* in: descriptor */
- ulint bit, /* in: XDES_FREE_BIT or XDES_CLEAN_BIT */
- ibool val, /* in: desired bit value */
- ulint hint, /* in: hint of which bit position would be desirable */
- mtr_t* mtr) /* in: mtr */
+ xdes_t* descr, /*!< in: descriptor */
+ ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */
+ ibool val, /*!< in: desired bit value */
+ ulint hint, /*!< in: hint of which bit position would be desirable */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint i;
@@ -474,20 +480,19 @@ xdes_find_bit(
return(ULINT_UNDEFINED);
}
-/**************************************************************************
+/**********************************************************************//**
Looks for a descriptor bit having the desired value. Scans the extent in
-a direction opposite to xdes_find_bit. */
+a direction opposite to xdes_find_bit.
+@return bit index of the bit, ULINT_UNDEFINED if not found */
UNIV_INLINE
ulint
xdes_find_bit_downward(
/*===================*/
- /* out: bit index of the bit, ULINT_UNDEFINED if not
- found */
- xdes_t* descr, /* in: descriptor */
- ulint bit, /* in: XDES_FREE_BIT or XDES_CLEAN_BIT */
- ibool val, /* in: desired bit value */
- ulint hint, /* in: hint of which bit position would be desirable */
- mtr_t* mtr) /* in: mtr */
+ xdes_t* descr, /*!< in: descriptor */
+ ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */
+ ibool val, /*!< in: desired bit value */
+ ulint hint, /*!< in: hint of which bit position would be desirable */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint i;
@@ -512,15 +517,15 @@ xdes_find_bit_downward(
return(ULINT_UNDEFINED);
}
-/**************************************************************************
-Returns the number of used pages in a descriptor. */
+/**********************************************************************//**
+Returns the number of used pages in a descriptor.
+@return number of pages used */
UNIV_INLINE
ulint
xdes_get_n_used(
/*============*/
- /* out: number of pages used */
- xdes_t* descr, /* in: descriptor */
- mtr_t* mtr) /* in: mtr */
+ xdes_t* descr, /*!< in: descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint i;
ulint count = 0;
@@ -536,15 +541,15 @@ xdes_get_n_used(
return(count);
}
-/**************************************************************************
-Returns true if extent contains no used pages. */
+/**********************************************************************//**
+Returns true if extent contains no used pages.
+@return TRUE if totally free */
UNIV_INLINE
ibool
xdes_is_free(
/*=========*/
- /* out: TRUE if totally free */
- xdes_t* descr, /* in: descriptor */
- mtr_t* mtr) /* in: mtr */
+ xdes_t* descr, /*!< in: descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
if (0 == xdes_get_n_used(descr, mtr)) {
@@ -554,15 +559,15 @@ xdes_is_free(
return(FALSE);
}
-/**************************************************************************
-Returns true if extent contains no free pages. */
+/**********************************************************************//**
+Returns true if extent contains no free pages.
+@return TRUE if full */
UNIV_INLINE
ibool
xdes_is_full(
/*=========*/
- /* out: TRUE if full */
- xdes_t* descr, /* in: descriptor */
- mtr_t* mtr) /* in: mtr */
+ xdes_t* descr, /*!< in: descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
if (FSP_EXTENT_SIZE == xdes_get_n_used(descr, mtr)) {
@@ -572,15 +577,15 @@ xdes_is_full(
return(FALSE);
}
-/**************************************************************************
+/**********************************************************************//**
Sets the state of an xdes. */
UNIV_INLINE
void
xdes_set_state(
/*===========*/
- xdes_t* descr, /* in: descriptor */
- ulint state, /* in: state to set */
- mtr_t* mtr) /* in: mtr handle */
+ xdes_t* descr, /*!< in: descriptor */
+ ulint state, /*!< in: state to set */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ut_ad(descr && mtr);
ut_ad(state >= XDES_FREE);
@@ -590,15 +595,15 @@ xdes_set_state(
mlog_write_ulint(descr + XDES_STATE, state, MLOG_4BYTES, mtr);
}
-/**************************************************************************
-Gets the state of an xdes. */
+/**********************************************************************//**
+Gets the state of an xdes.
+@return state */
UNIV_INLINE
ulint
xdes_get_state(
/*===========*/
- /* out: state */
- xdes_t* descr, /* in: descriptor */
- mtr_t* mtr) /* in: mtr handle */
+ xdes_t* descr, /*!< in: descriptor */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint state;
@@ -610,14 +615,14 @@ xdes_get_state(
return(state);
}
-/**************************************************************************
+/**********************************************************************//**
Inits an extent descriptor to the free and clean state. */
UNIV_INLINE
void
xdes_init(
/*======*/
- xdes_t* descr, /* in: descriptor */
- mtr_t* mtr) /* in: mtr */
+ xdes_t* descr, /*!< in: descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint i;
@@ -632,25 +637,27 @@ xdes_init(
xdes_set_state(descr, XDES_FREE, mtr);
}
-/************************************************************************
-Calculates the page where the descriptor of a page resides. */
+/********************************************************************//**
+Calculates the page where the descriptor of a page resides.
+@return descriptor page offset */
UNIV_INLINE
ulint
xdes_calc_descriptor_page(
/*======================*/
- /* out: descriptor page offset */
- ulint zip_size, /* in: compressed page size in bytes;
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint offset) /* in: page offset */
+ ulint offset) /*!< in: page offset */
{
-#if UNIV_PAGE_SIZE <= XDES_ARR_OFFSET \
+#ifndef DOXYGEN /* Doxygen gets confused of these */
+# if UNIV_PAGE_SIZE <= XDES_ARR_OFFSET \
+ (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
-# error
-#endif
-#if PAGE_ZIP_MIN_SIZE <= XDES_ARR_OFFSET \
+# error
+# endif
+# if PAGE_ZIP_MIN_SIZE <= XDES_ARR_OFFSET \
+ (PAGE_ZIP_MIN_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
-# error
-#endif
+# error
+# endif
+#endif /* !DOXYGEN */
ut_ad(ut_is_2pow(zip_size));
if (!zip_size) {
@@ -662,16 +669,16 @@ xdes_calc_descriptor_page(
}
}
-/************************************************************************
-Calculates the descriptor index within a descriptor page. */
+/********************************************************************//**
+Calculates the descriptor index within a descriptor page.
+@return descriptor index */
UNIV_INLINE
ulint
xdes_calc_descriptor_index(
/*=======================*/
- /* out: descriptor index */
- ulint zip_size, /* in: compressed page size in bytes;
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint offset) /* in: page offset */
+ ulint offset) /*!< in: page offset */
{
ut_ad(ut_is_2pow(zip_size));
@@ -683,26 +690,25 @@ xdes_calc_descriptor_index(
}
}
-/************************************************************************
+/********************************************************************//**
Gets pointer to a the extent descriptor of a page. The page where the extent
descriptor resides is x-locked. If the page offset is equal to the free limit
of the space, adds new extents from above the free limit to the space free
list, if not free limit == space size. This adding is necessary to make the
-descriptor defined, as they are uninitialized above the free limit. */
+descriptor defined, as they are uninitialized above the free limit.
+@return pointer to the extent descriptor, NULL if the page does not
+exist in the space or if the offset exceeds the free limit */
UNIV_INLINE
xdes_t*
xdes_get_descriptor_with_space_hdr(
/*===============================*/
- /* out: pointer to the extent descriptor,
- NULL if the page does not exist in the
- space or if offset > free limit */
- fsp_header_t* sp_header,/* in: space header, x-latched */
- ulint space, /* in: space id */
- ulint offset, /* in: page offset;
+ fsp_header_t* sp_header,/*!< in: space header, x-latched */
+ ulint space, /*!< in: space id */
+ ulint offset, /*!< in: page offset;
if equal to the free limit,
we try to add new extents to
the space free list */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint limit;
ulint size;
@@ -755,26 +761,25 @@ xdes_get_descriptor_with_space_hdr(
+ XDES_SIZE * xdes_calc_descriptor_index(zip_size, offset));
}
-/************************************************************************
+/********************************************************************//**
Gets pointer to a the extent descriptor of a page. The page where the
extent descriptor resides is x-locked. If the page offset is equal to
the free limit of the space, adds new extents from above the free limit
to the space free list, if not free limit == space size. This adding
is necessary to make the descriptor defined, as they are uninitialized
-above the free limit. */
+above the free limit.
+@return pointer to the extent descriptor, NULL if the page does not
+exist in the space or if the offset exceeds the free limit */
static
xdes_t*
xdes_get_descriptor(
/*================*/
- /* out: pointer to the extent descriptor, NULL if the
- page does not exist in the space or if offset > free
- limit */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint offset, /* in: page offset; if equal to the free limit,
+ ulint offset, /*!< in: page offset; if equal to the free limit,
we try to add new extents to the space free list */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr) /*!< in: mtr handle */
{
buf_block_t* block;
fsp_header_t* sp_header;
@@ -787,21 +792,21 @@ xdes_get_descriptor(
mtr));
}
-/************************************************************************
+/********************************************************************//**
Gets pointer to a the extent descriptor if the file address
of the descriptor list node is known. The page where the
-extent descriptor resides is x-locked. */
+extent descriptor resides is x-locked.
+@return pointer to the extent descriptor */
UNIV_INLINE
xdes_t*
xdes_lst_get_descriptor(
/*====================*/
- /* out: pointer to the extent descriptor */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- fil_addr_t lst_node,/* in: file address of the list node
+ fil_addr_t lst_node,/*!< in: file address of the list node
contained in the descriptor */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr) /*!< in: mtr handle */
{
xdes_t* descr;
@@ -814,14 +819,14 @@ xdes_lst_get_descriptor(
return(descr);
}
-/************************************************************************
-Returns page offset of the first page in extent described by a descriptor. */
+/********************************************************************//**
+Returns page offset of the first page in extent described by a descriptor.
+@return offset of the first page in extent */
UNIV_INLINE
ulint
xdes_get_offset(
/*============*/
- /* out: offset of the first page in extent */
- xdes_t* descr) /* in: extent descriptor */
+ xdes_t* descr) /*!< in: extent descriptor */
{
ut_ad(descr);
@@ -829,19 +834,22 @@ xdes_get_offset(
+ ((page_offset(descr) - XDES_ARR_OFFSET) / XDES_SIZE)
* FSP_EXTENT_SIZE);
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
+/***********************************************************//**
Inits a file page whose prior contents should be ignored. */
static
void
fsp_init_file_page_low(
/*===================*/
- buf_block_t* block) /* in: pointer to a page */
+ buf_block_t* block) /*!< in: pointer to a page */
{
page_t* page = buf_block_get_frame(block);
page_zip_des_t* page_zip= buf_block_get_page_zip(block);
+#ifndef UNIV_HOTBACKUP
block->check_index_page_at_flush = FALSE;
+#endif /* !UNIV_HOTBACKUP */
if (UNIV_LIKELY_NULL(page_zip)) {
memset(page, 0, UNIV_PAGE_SIZE);
@@ -868,31 +876,33 @@ fsp_init_file_page_low(
memset(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, 0, 8);
}
-/***************************************************************
+#ifndef UNIV_HOTBACKUP
+/***********************************************************//**
Inits a file page whose prior contents should be ignored. */
static
void
fsp_init_file_page(
/*===============*/
- buf_block_t* block, /* in: pointer to a page */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in: pointer to a page */
+ mtr_t* mtr) /*!< in: mtr */
{
fsp_init_file_page_low(block);
mlog_write_initial_log_record(buf_block_get_frame(block),
MLOG_INIT_FILE_PAGE, mtr);
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses a redo log record of a file page init. */
+/***********************************************************//**
+Parses a redo log record of a file page init.
+@return end of log record or NULL */
UNIV_INTERN
byte*
fsp_parse_init_file_page(
/*=====================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr __attribute__((unused)), /* in: buffer end */
- buf_block_t* block) /* in: block or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr __attribute__((unused)), /*!< in: buffer end */
+ buf_block_t* block) /*!< in: block or NULL */
{
ut_ad(ptr && end_ptr);
@@ -903,7 +913,7 @@ fsp_parse_init_file_page(
return(ptr);
}
-/**************************************************************************
+/**********************************************************************//**
Initializes the fsp system. */
UNIV_INTERN
void
@@ -913,7 +923,7 @@ fsp_init(void)
/* Does nothing at the moment */
}
-/**************************************************************************
+/**********************************************************************//**
Writes the space id and compressed page size to a tablespace header.
This function is used past the buffer pool when we in fil0fil.c create
a new single-table tablespace. */
@@ -921,9 +931,9 @@ UNIV_INTERN
void
fsp_header_init_fields(
/*===================*/
- page_t* page, /* in/out: first page in the space */
- ulint space_id, /* in: space id */
- ulint flags) /* in: tablespace flags (FSP_SPACE_FLAGS):
+ page_t* page, /*!< in/out: first page in the space */
+ ulint space_id, /*!< in: space id */
+ ulint flags) /*!< in: tablespace flags (FSP_SPACE_FLAGS):
0, or table->flags if newer than COMPACT */
{
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
@@ -938,16 +948,17 @@ fsp_header_init_fields(
flags);
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Initializes the space header of a new created space and creates also the
insert buffer tree root if space == 0. */
UNIV_INTERN
void
fsp_header_init(
/*============*/
- ulint space, /* in: space id */
- ulint size, /* in: current size in blocks */
- mtr_t* mtr) /* in: mini-transaction handle */
+ ulint space, /*!< in: space id */
+ ulint size, /*!< in: current size in blocks */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
fsp_header_t* header;
buf_block_t* block;
@@ -994,20 +1005,21 @@ fsp_header_init(
fsp_fill_free_list(FALSE, space, header, mtr);
btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,
0, 0, ut_dulint_add(DICT_IBUF_ID_MIN, space),
- srv_sys->dummy_ind1, mtr);
+ dict_ind_redundant, mtr);
} else {
fsp_fill_free_list(TRUE, space, header, mtr);
}
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
-Reads the space id from the first page of a tablespace. */
+/**********************************************************************//**
+Reads the space id from the first page of a tablespace.
+@return space id, ULINT UNDEFINED if error */
UNIV_INTERN
ulint
fsp_header_get_space_id(
/*====================*/
- /* out: space id, ULINT UNDEFINED if error */
- const page_t* page) /* in: first page of a tablespace */
+ const page_t* page) /*!< in: first page of a tablespace */
{
ulint fsp_id;
ulint id;
@@ -1028,44 +1040,44 @@ fsp_header_get_space_id(
return(id);
}
-/**************************************************************************
-Reads the space flags from the first page of a tablespace. */
+/**********************************************************************//**
+Reads the space flags from the first page of a tablespace.
+@return flags */
UNIV_INTERN
ulint
fsp_header_get_flags(
/*=================*/
- /* out: flags */
- const page_t* page) /* in: first page of a tablespace */
+ const page_t* page) /*!< in: first page of a tablespace */
{
ut_ad(!page_offset(page));
return(mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page));
}
-/**************************************************************************
-Reads the compressed page size from the first page of a tablespace. */
+/**********************************************************************//**
+Reads the compressed page size from the first page of a tablespace.
+@return compressed page size in bytes, or 0 if uncompressed */
UNIV_INTERN
ulint
fsp_header_get_zip_size(
/*====================*/
- /* out: compressed page size in bytes,
- or 0 if uncompressed */
- const page_t* page) /* in: first page of a tablespace */
+ const page_t* page) /*!< in: first page of a tablespace */
{
ulint flags = fsp_header_get_flags(page);
return(dict_table_flags_to_zip_size(flags));
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Increases the space size field of a space. */
UNIV_INTERN
void
fsp_header_inc_size(
/*================*/
- ulint space, /* in: space id */
- ulint size_inc,/* in: size increment in pages */
- mtr_t* mtr) /* in: mini-transaction handle */
+ ulint space, /*!< in: space id */
+ ulint size_inc,/*!< in: size increment in pages */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
fsp_header_t* header;
ulint size;
@@ -1085,16 +1097,16 @@ fsp_header_inc_size(
mtr);
}
-/**************************************************************************
+/**********************************************************************//**
Gets the current free limit of the system tablespace. The free limit
means the place of the first page which has never been put to the the
free list for allocation. The space above that address is initialized
-to zero. Sets also the global variable log_fsp_current_free_limit. */
+to zero. Sets also the global variable log_fsp_current_free_limit.
+@return free limit in megabytes */
UNIV_INTERN
ulint
fsp_header_get_free_limit(void)
/*===========================*/
- /* out: free limit in megabytes */
{
fsp_header_t* header;
ulint limit;
@@ -1117,16 +1129,16 @@ fsp_header_get_free_limit(void)
return(limit);
}
-/**************************************************************************
+/**********************************************************************//**
Gets the size of the system tablespace from the tablespace header. If
we do not have an auto-extending data file, this should be equal to
the size of the data files. If there is an auto-extending data file,
-this can be smaller. */
+this can be smaller.
+@return size in pages */
UNIV_INTERN
ulint
fsp_header_get_tablespace_size(void)
/*================================*/
- /* out: size in pages */
{
fsp_header_t* header;
ulint size;
@@ -1145,18 +1157,18 @@ fsp_header_get_tablespace_size(void)
return(size);
}
-/***************************************************************************
+/***********************************************************************//**
Tries to extend a single-table tablespace so that a page would fit in the
-data file. */
+data file.
+@return TRUE if success */
static
ibool
fsp_try_extend_data_file_with_pages(
/*================================*/
- /* out: TRUE if success */
- ulint space, /* in: space */
- ulint page_no, /* in: page number */
- fsp_header_t* header, /* in: space header */
- mtr_t* mtr) /* in: mtr */
+ ulint space, /*!< in: space */
+ ulint page_no, /*!< in: page number */
+ fsp_header_t* header, /*!< in: space header */
+ mtr_t* mtr) /*!< in: mtr */
{
ibool success;
ulint actual_size;
@@ -1178,21 +1190,21 @@ fsp_try_extend_data_file_with_pages(
return(success);
}
-/***************************************************************************
-Tries to extend the last data file of a tablespace if it is auto-extending. */
+/***********************************************************************//**
+Tries to extend the last data file of a tablespace if it is auto-extending.
+@return FALSE if not auto-extending */
static
ibool
fsp_try_extend_data_file(
/*=====================*/
- /* out: FALSE if not auto-extending */
- ulint* actual_increase,/* out: actual increase in pages, where
+ ulint* actual_increase,/*!< out: actual increase in pages, where
we measure the tablespace size from
what the header field says; it may be
the actual file size rounded down to
megabyte */
- ulint space, /* in: space */
- fsp_header_t* header, /* in: space header */
- mtr_t* mtr) /* in: mtr */
+ ulint space, /*!< in: space */
+ fsp_header_t* header, /*!< in: space header */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint size;
ulint zip_size;
@@ -1241,7 +1253,7 @@ fsp_try_extend_data_file(
at a time, but for bigger tablespaces more. It is not
enough to extend always by one extent, because some
extents are frag page extents. */
- ulint extent_size; /* one megabyte, in pages */
+ ulint extent_size; /*!< one megabyte, in pages */
if (!zip_size) {
extent_size = FSP_EXTENT_SIZE;
@@ -1300,7 +1312,7 @@ fsp_try_extend_data_file(
return(TRUE);
}
-/**************************************************************************
+/**********************************************************************//**
Puts new extents to the free list if there are free extents above the free
limit. If an extent happens to contain an extent descriptor page, the extent
is put to the FSP_FREE_FRAG list with the page marked as used. */
@@ -1308,14 +1320,14 @@ static
void
fsp_fill_free_list(
/*===============*/
- ibool init_space, /* in: TRUE if this is a single-table
+ ibool init_space, /*!< in: TRUE if this is a single-table
tablespace and we are only initing
the tablespace's first extent
descriptor page and ibuf bitmap page;
then we do not allocate more extents */
- ulint space, /* in: space */
- fsp_header_t* header, /* in: space header */
- mtr_t* mtr) /* in: mtr */
+ ulint space, /*!< in: space */
+ fsp_header_t* header, /*!< in: space header */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint limit;
ulint size;
@@ -1463,21 +1475,20 @@ fsp_fill_free_list(
}
}
-/**************************************************************************
-Allocates a new free extent. */
+/**********************************************************************//**
+Allocates a new free extent.
+@return extent descriptor, NULL if cannot be allocated */
static
xdes_t*
fsp_alloc_free_extent(
/*==================*/
- /* out: extent descriptor, NULL if cannot be
- allocated */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint hint, /* in: hint of which extent would be desirable: any
+ ulint hint, /*!< in: hint of which extent would be desirable: any
page offset in the extent goes; the hint must not
be > FSP_FREE_LIMIT */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
fsp_header_t* header;
fil_addr_t first;
@@ -1514,19 +1525,18 @@ fsp_alloc_free_extent(
return(descr);
}
-/**************************************************************************
-Allocates a single free page from a space. The page is marked as used. */
+/**********************************************************************//**
+Allocates a single free page from a space. The page is marked as used.
+@return the page offset, FIL_NULL if no page could be allocated */
static
ulint
fsp_alloc_free_page(
/*================*/
- /* out: the page offset, FIL_NULL if no page could
- be allocated */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint hint, /* in: hint of which page would be desirable */
- mtr_t* mtr) /* in: mtr handle */
+ ulint hint, /*!< in: hint of which page would be desirable */
+ mtr_t* mtr) /*!< in: mtr handle */
{
fsp_header_t* header;
fil_addr_t first;
@@ -1656,17 +1666,17 @@ fsp_alloc_free_page(
return(page_no);
}
-/**************************************************************************
+/**********************************************************************//**
Frees a single page of a space. The page is marked as free and clean. */
static
void
fsp_free_page(
/*==========*/
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: page offset */
- mtr_t* mtr) /* in: mtr handle */
+ ulint page, /*!< in: page offset */
+ mtr_t* mtr) /*!< in: mtr handle */
{
fsp_header_t* header;
xdes_t* descr;
@@ -1746,17 +1756,17 @@ fsp_free_page(
}
}
-/**************************************************************************
+/**********************************************************************//**
Returns an extent to the free list of a space. */
static
void
fsp_free_extent(
/*============*/
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: page offset in the extent */
- mtr_t* mtr) /* in: mtr */
+ ulint page, /*!< in: page offset in the extent */
+ mtr_t* mtr) /*!< in: mtr */
{
fsp_header_t* header;
xdes_t* descr;
@@ -1780,19 +1790,19 @@ fsp_free_extent(
flst_add_last(header + FSP_FREE, descr + XDES_FLST_NODE, mtr);
}
-/**************************************************************************
-Returns the nth inode slot on an inode page. */
+/**********************************************************************//**
+Returns the nth inode slot on an inode page.
+@return segment inode */
UNIV_INLINE
fseg_inode_t*
fsp_seg_inode_page_get_nth_inode(
/*=============================*/
- /* out: segment inode */
- page_t* page, /* in: segment inode page */
- ulint i, /* in: inode index on page */
+ page_t* page, /*!< in: segment inode page */
+ ulint i, /*!< in: inode index on page */
ulint zip_size __attribute__((unused)),
- /* in: compressed page size, or 0 */
+ /*!< in: compressed page size, or 0 */
mtr_t* mtr __attribute__((unused)))
- /* in: mini-transaction handle */
+ /*!< in: mini-transaction handle */
{
ut_ad(i < FSP_SEG_INODES_PER_PAGE(zip_size));
ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
@@ -1800,17 +1810,16 @@ fsp_seg_inode_page_get_nth_inode(
return(page + FSEG_ARR_OFFSET + FSEG_INODE_SIZE * i);
}
-/**************************************************************************
-Looks for a used segment inode on a segment inode page. */
+/**********************************************************************//**
+Looks for a used segment inode on a segment inode page.
+@return segment inode index, or ULINT_UNDEFINED if not found */
static
ulint
fsp_seg_inode_page_find_used(
/*=========================*/
- /* out: segment inode index, or ULINT_UNDEFINED
- if not found */
- page_t* page, /* in: segment inode page */
- ulint zip_size,/* in: compressed page size, or 0 */
- mtr_t* mtr) /* in: mini-transaction handle */
+ page_t* page, /*!< in: segment inode page */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint i;
fseg_inode_t* inode;
@@ -1830,18 +1839,17 @@ fsp_seg_inode_page_find_used(
return(ULINT_UNDEFINED);
}
-/**************************************************************************
-Looks for an unused segment inode on a segment inode page. */
+/**********************************************************************//**
+Looks for an unused segment inode on a segment inode page.
+@return segment inode index, or ULINT_UNDEFINED if not found */
static
ulint
fsp_seg_inode_page_find_free(
/*=========================*/
- /* out: segment inode index, or ULINT_UNDEFINED
- if not found */
- page_t* page, /* in: segment inode page */
- ulint i, /* in: search forward starting from this index */
- ulint zip_size,/* in: compressed page size, or 0 */
- mtr_t* mtr) /* in: mini-transaction handle */
+ page_t* page, /*!< in: segment inode page */
+ ulint i, /*!< in: search forward starting from this index */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
fseg_inode_t* inode;
@@ -1860,15 +1868,15 @@ fsp_seg_inode_page_find_free(
return(ULINT_UNDEFINED);
}
-/**************************************************************************
-Allocates a new file segment inode page. */
+/**********************************************************************//**
+Allocates a new file segment inode page.
+@return TRUE if could be allocated */
static
ibool
fsp_alloc_seg_inode_page(
/*=====================*/
- /* out: TRUE if could be allocated */
- fsp_header_t* space_header, /* in: space header */
- mtr_t* mtr) /* in: mini-transaction handle */
+ fsp_header_t* space_header, /*!< in: space header */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
fseg_inode_t* inode;
buf_block_t* block;
@@ -1914,16 +1922,15 @@ fsp_alloc_seg_inode_page(
return(TRUE);
}
-/**************************************************************************
-Allocates a new file segment inode. */
+/**********************************************************************//**
+Allocates a new file segment inode.
+@return segment inode, or NULL if not enough space */
static
fseg_inode_t*
fsp_alloc_seg_inode(
/*================*/
- /* out: segment inode, or NULL if
- not enough space */
- fsp_header_t* space_header, /* in: space header */
- mtr_t* mtr) /* in: mini-transaction handle */
+ fsp_header_t* space_header, /*!< in: space header */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint page_no;
buf_block_t* block;
@@ -1977,17 +1984,17 @@ fsp_alloc_seg_inode(
return(inode);
}
-/**************************************************************************
+/**********************************************************************//**
Frees a file segment inode. */
static
void
fsp_free_seg_inode(
/*===============*/
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- fseg_inode_t* inode, /* in: segment inode */
- mtr_t* mtr) /* in: mini-transaction handle */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
page_t* page;
fsp_header_t* space_header;
@@ -2025,18 +2032,18 @@ fsp_free_seg_inode(
}
}
-/**************************************************************************
-Returns the file segment inode, page x-latched. */
+/**********************************************************************//**
+Returns the file segment inode, page x-latched.
+@return segment inode, page x-latched */
static
fseg_inode_t*
fseg_inode_get(
/*===========*/
- /* out: segment inode, page x-latched */
- fseg_header_t* header, /* in: segment header */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_header_t* header, /*!< in: segment header */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr) /*!< in: mtr handle */
{
fil_addr_t inode_addr;
fseg_inode_t* inode;
@@ -2052,16 +2059,16 @@ fseg_inode_get(
return(inode);
}
-/**************************************************************************
-Gets the page number from the nth fragment page slot. */
+/**********************************************************************//**
+Gets the page number from the nth fragment page slot.
+@return page number, FIL_NULL if not in use */
UNIV_INLINE
ulint
fseg_get_nth_frag_page_no(
/*======================*/
- /* out: page number, FIL_NULL if not in use */
- fseg_inode_t* inode, /* in: segment inode */
- ulint n, /* in: slot index */
- mtr_t* mtr __attribute__((unused))) /* in: mtr handle */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ ulint n, /*!< in: slot index */
+ mtr_t* mtr __attribute__((unused))) /*!< in: mtr handle */
{
ut_ad(inode && mtr);
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
@@ -2070,16 +2077,16 @@ fseg_get_nth_frag_page_no(
+ n * FSEG_FRAG_SLOT_SIZE));
}
-/**************************************************************************
+/**********************************************************************//**
Sets the page number in the nth fragment page slot. */
UNIV_INLINE
void
fseg_set_nth_frag_page_no(
/*======================*/
- fseg_inode_t* inode, /* in: segment inode */
- ulint n, /* in: slot index */
- ulint page_no,/* in: page number to set */
- mtr_t* mtr) /* in: mtr handle */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ ulint n, /*!< in: slot index */
+ ulint page_no,/*!< in: page number to set */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ut_ad(inode && mtr);
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS);
@@ -2089,16 +2096,15 @@ fseg_set_nth_frag_page_no(
page_no, MLOG_4BYTES, mtr);
}
-/**************************************************************************
-Finds a fragment page slot which is free. */
+/**********************************************************************//**
+Finds a fragment page slot which is free.
+@return slot index; ULINT_UNDEFINED if none found */
static
ulint
fseg_find_free_frag_page_slot(
/*==========================*/
- /* out: slot index; ULINT_UNDEFINED if none
- found */
- fseg_inode_t* inode, /* in: segment inode */
- mtr_t* mtr) /* in: mtr handle */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint i;
ulint page_no;
@@ -2117,16 +2123,15 @@ fseg_find_free_frag_page_slot(
return(ULINT_UNDEFINED);
}
-/**************************************************************************
-Finds a fragment page slot which is used and last in the array. */
+/**********************************************************************//**
+Finds a fragment page slot which is used and last in the array.
+@return slot index; ULINT_UNDEFINED if none found */
static
ulint
fseg_find_last_used_frag_page_slot(
/*===============================*/
- /* out: slot index; ULINT_UNDEFINED if none
- found */
- fseg_inode_t* inode, /* in: segment inode */
- mtr_t* mtr) /* in: mtr handle */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint i;
ulint page_no;
@@ -2146,15 +2151,15 @@ fseg_find_last_used_frag_page_slot(
return(ULINT_UNDEFINED);
}
-/**************************************************************************
-Calculates reserved fragment page slots. */
+/**********************************************************************//**
+Calculates reserved fragment page slots.
+@return number of fragment pages */
static
ulint
fseg_get_n_frag_pages(
/*==================*/
- /* out: number of fragment pages */
- fseg_inode_t* inode, /* in: segment inode */
- mtr_t* mtr) /* in: mtr handle */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint i;
ulint count = 0;
@@ -2170,29 +2175,28 @@ fseg_get_n_frag_pages(
return(count);
}
-/**************************************************************************
-Creates a new segment. */
+/**********************************************************************//**
+Creates a new segment.
+@return the block where the segment header is placed, x-latched, NULL
+if could not create segment because of lack of space */
UNIV_INTERN
buf_block_t*
fseg_create_general(
/*================*/
- /* out: the block where the segment header is placed,
- x-latched, NULL if could not create segment
- because of lack of space */
- ulint space, /* in: space id */
- ulint page, /* in: page where the segment header is placed: if
+ ulint space, /*!< in: space id */
+ ulint page, /*!< in: page where the segment header is placed: if
this is != 0, the page must belong to another segment,
if this is 0, a new page will be allocated and it
will belong to the created segment */
- ulint byte_offset, /* in: byte offset of the created segment header
+ ulint byte_offset, /*!< in: byte offset of the created segment header
on the page */
- ibool has_done_reservation, /* in: TRUE if the caller has already
+ ibool has_done_reservation, /*!< in: TRUE if the caller has already
done the reservation for the pages with
fsp_reserve_free_extents (at least 2 extents: one for
the inode and the other for the segment) then there is
no need to do the check for this individual
operation */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint flags;
ulint zip_size;
@@ -2305,38 +2309,38 @@ funct_exit:
return(block);
}
-/**************************************************************************
-Creates a new segment. */
+/**********************************************************************//**
+Creates a new segment.
+@return the block where the segment header is placed, x-latched, NULL
+if could not create segment because of lack of space */
UNIV_INTERN
buf_block_t*
fseg_create(
/*========*/
- /* out: the block where the segment header is placed,
- x-latched, NULL if could not create segment
- because of lack of space */
- ulint space, /* in: space id */
- ulint page, /* in: page where the segment header is placed: if
+ ulint space, /*!< in: space id */
+ ulint page, /*!< in: page where the segment header is placed: if
this is != 0, the page must belong to another segment,
if this is 0, a new page will be allocated and it
will belong to the created segment */
- ulint byte_offset, /* in: byte offset of the created segment header
+ ulint byte_offset, /*!< in: byte offset of the created segment header
on the page */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
return(fseg_create_general(space, page, byte_offset, FALSE, mtr));
}
-/**************************************************************************
+/**********************************************************************//**
Calculates the number of pages reserved by a segment, and how many pages are
-currently used. */
+currently used.
+@return number of reserved pages */
static
ulint
fseg_n_reserved_pages_low(
/*======================*/
- /* out: number of reserved pages */
- fseg_inode_t* inode, /* in: segment inode */
- ulint* used, /* out: number of pages used (<= reserved) */
- mtr_t* mtr) /* in: mtr handle */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ ulint* used, /*!< out: number of pages used (not
+ more than reserved) */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint ret;
@@ -2355,17 +2359,17 @@ fseg_n_reserved_pages_low(
return(ret);
}
-/**************************************************************************
+/**********************************************************************//**
Calculates the number of pages reserved by a segment, and how many pages are
-currently used. */
+currently used.
+@return number of reserved pages */
UNIV_INTERN
ulint
fseg_n_reserved_pages(
/*==================*/
- /* out: number of reserved pages */
- fseg_header_t* header, /* in: segment header */
- ulint* used, /* out: number of pages used (<= reserved) */
- mtr_t* mtr) /* in: mtr handle */
+ fseg_header_t* header, /*!< in: segment header */
+ ulint* used, /*!< out: number of pages used (<= reserved) */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint ret;
fseg_inode_t* inode;
@@ -2390,7 +2394,7 @@ fseg_n_reserved_pages(
return(ret);
}
-/*************************************************************************
+/*********************************************************************//**
Tries to fill the free list of a segment with consecutive free extents.
This happens if the segment is big enough to allow extents in the free list,
the free list is empty, and the extents can be allocated consecutively from
@@ -2399,13 +2403,13 @@ static
void
fseg_fill_free_list(
/*================*/
- fseg_inode_t* inode, /* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* inode, /*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint hint, /* in: hint which extent would be good as
+ ulint hint, /*!< in: hint which extent would be good as
the first extent */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
xdes_t* descr;
ulint i;
@@ -2454,22 +2458,21 @@ fseg_fill_free_list(
}
}
-/*************************************************************************
+/*********************************************************************//**
Allocates a free extent for the segment: looks first in the free list of the
segment, then tries to allocate from the space free list. NOTE that the extent
-returned still resides in the segment free list, it is not yet taken off it! */
+returned still resides in the segment free list, it is not yet taken off it!
+@return allocated extent, still placed in the segment free list, NULL
+if could not be allocated */
static
xdes_t*
fseg_alloc_free_extent(
/*===================*/
- /* out: allocated extent, still placed in the
- segment free list, NULL if could
- not be allocated */
- fseg_inode_t* inode, /* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* inode, /*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
xdes_t* descr;
dulint seg_id;
@@ -2507,37 +2510,36 @@ fseg_alloc_free_extent(
return(descr);
}
-/**************************************************************************
+/**********************************************************************//**
Allocates a single free page from a segment. This function implements
the intelligent allocation strategy which tries to minimize file space
-fragmentation. */
+fragmentation.
+@return the allocated page number, FIL_NULL if no page could be allocated */
static
ulint
fseg_alloc_free_page_low(
/*=====================*/
- /* out: the allocated page number, FIL_NULL
- if no page could be allocated */
- ulint space, /* in: space */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- fseg_inode_t* seg_inode, /* in: segment inode */
- ulint hint, /* in: hint of which page would be desirable */
- byte direction, /* in: if the new page is needed because
+ fseg_inode_t* seg_inode, /*!< in: segment inode */
+ ulint hint, /*!< in: hint of which page would be desirable */
+ byte direction, /*!< in: if the new page is needed because
of an index page split, and records are
inserted there in order, into which
direction they go alphabetically: FSP_DOWN,
FSP_UP, FSP_NO_DIR */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr) /*!< in: mtr handle */
{
fsp_header_t* space_header;
ulint space_size;
dulint seg_id;
ulint used;
ulint reserved;
- xdes_t* descr; /* extent of the hinted page */
- ulint ret_page; /* the allocated page offset, FIL_NULL
+ xdes_t* descr; /*!< extent of the hinted page */
+ ulint ret_page; /*!< the allocated page offset, FIL_NULL
if could not be allocated */
- xdes_t* ret_descr; /* the extent of the allocated page */
+ xdes_t* ret_descr; /*!< the extent of the allocated page */
ibool frag_page_allocated = FALSE;
ibool success;
ulint n;
@@ -2756,29 +2758,28 @@ fseg_alloc_free_page_low(
return(ret_page);
}
-/**************************************************************************
+/**********************************************************************//**
Allocates a single free page from a segment. This function implements
the intelligent allocation strategy which tries to minimize file space
-fragmentation. */
+fragmentation.
+@return allocated page offset, FIL_NULL if no page could be allocated */
UNIV_INTERN
ulint
fseg_alloc_free_page_general(
/*=========================*/
- /* out: allocated page offset, FIL_NULL if no
- page could be allocated */
- fseg_header_t* seg_header,/* in: segment header */
- ulint hint, /* in: hint of which page would be desirable */
- byte direction,/* in: if the new page is needed because
+ fseg_header_t* seg_header,/*!< in: segment header */
+ ulint hint, /*!< in: hint of which page would be desirable */
+ byte direction,/*!< in: if the new page is needed because
of an index page split, and records are
inserted there in order, into which
direction they go alphabetically: FSP_DOWN,
FSP_UP, FSP_NO_DIR */
- ibool has_done_reservation, /* in: TRUE if the caller has
+ ibool has_done_reservation, /*!< in: TRUE if the caller has
already done the reservation for the page
with fsp_reserve_free_extents, then there
is no need to do the check for this individual
page */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr) /*!< in: mtr handle */
{
fseg_inode_t* inode;
ulint space;
@@ -2828,47 +2829,45 @@ fseg_alloc_free_page_general(
return(page_no);
}
-/**************************************************************************
+/**********************************************************************//**
Allocates a single free page from a segment. This function implements
the intelligent allocation strategy which tries to minimize file space
-fragmentation. */
+fragmentation.
+@return allocated page offset, FIL_NULL if no page could be allocated */
UNIV_INTERN
ulint
fseg_alloc_free_page(
/*=================*/
- /* out: allocated page offset, FIL_NULL if no
- page could be allocated */
- fseg_header_t* seg_header,/* in: segment header */
- ulint hint, /* in: hint of which page would be desirable */
- byte direction,/* in: if the new page is needed because
+ fseg_header_t* seg_header,/*!< in: segment header */
+ ulint hint, /*!< in: hint of which page would be desirable */
+ byte direction,/*!< in: if the new page is needed because
of an index page split, and records are
inserted there in order, into which
direction they go alphabetically: FSP_DOWN,
FSP_UP, FSP_NO_DIR */
- mtr_t* mtr) /* in: mtr handle */
+ mtr_t* mtr) /*!< in: mtr handle */
{
return(fseg_alloc_free_page_general(seg_header, hint, direction,
FALSE, mtr));
}
-/**************************************************************************
+/**********************************************************************//**
Checks that we have at least 2 frag pages free in the first extent of a
single-table tablespace, and they are also physically initialized to the data
file. That is we have already extended the data file so that those pages are
inside the data file. If not, this function extends the tablespace with
-pages. */
+pages.
+@return TRUE if there were >= 3 free pages, or we were able to extend */
static
ibool
fsp_reserve_free_pages(
/*===================*/
- /* out: TRUE if there were >= 3 free
- pages, or we were able to extend */
- ulint space, /* in: space id, must be != 0 */
- fsp_header_t* space_header, /* in: header of that space,
+ ulint space, /*!< in: space id, must be != 0 */
+ fsp_header_t* space_header, /*!< in: header of that space,
x-latched */
- ulint size, /* in: size of the tablespace in pages,
+ ulint size, /*!< in: size of the tablespace in pages,
must be < FSP_EXTENT_SIZE / 2 */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
xdes_t* descr;
ulint n_used;
@@ -2891,7 +2890,7 @@ fsp_reserve_free_pages(
space_header, mtr));
}
-/**************************************************************************
+/**********************************************************************//**
Reserves free pages from a tablespace. All mini-transactions which may
use several pages from the tablespace should call this function beforehand
and reserve enough free extents so that they certainly will be able
@@ -2915,19 +2914,19 @@ Single-table tablespaces whose size is < 32 pages are a special case. In this
function we would liberally reserve several 64 page extents for every page
split or merge in a B-tree. But we do not want to waste disk space if the table
only occupies < 32 pages. That is why we apply different rules in that special
-case, just ensuring that there are 3 free pages available. */
+case, just ensuring that there are 3 free pages available.
+@return TRUE if we were able to make the reservation */
UNIV_INTERN
ibool
fsp_reserve_free_extents(
/*=====================*/
- /* out: TRUE if we were able to make the reservation */
- ulint* n_reserved,/* out: number of extents actually reserved; if we
+ ulint* n_reserved,/*!< out: number of extents actually reserved; if we
return TRUE and the tablespace size is < 64 pages,
then this can be 0, otherwise it is n_ext */
- ulint space, /* in: space id */
- ulint n_ext, /* in: number of extents to reserve */
- ulint alloc_type,/* in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING */
- mtr_t* mtr) /* in: mtr */
+ ulint space, /*!< in: space id */
+ ulint n_ext, /*!< in: number of extents to reserve */
+ ulint alloc_type,/*!< in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING */
+ mtr_t* mtr) /*!< in: mtr */
{
fsp_header_t* space_header;
rw_lock_t* latch;
@@ -3027,17 +3026,17 @@ try_to_extend:
return(FALSE);
}
-/**************************************************************************
+/**********************************************************************//**
This function should be used to get information on how much we still
will be able to insert new data to the database without running out the
tablespace. Only free extents are taken into account and we also subtract
-the safety margin required by the above function fsp_reserve_free_extents. */
+the safety margin required by the above function fsp_reserve_free_extents.
+@return available space in kB */
UNIV_INTERN
ullint
fsp_get_available_space_in_free_extents(
/*====================================*/
- /* out: available space in kB */
- ulint space) /* in: space id */
+ ulint space) /*!< in: space id */
{
fsp_header_t* space_header;
ulint n_free_list_ext;
@@ -3118,19 +3117,19 @@ fsp_get_available_space_in_free_extents(
}
}
-/************************************************************************
+/********************************************************************//**
Marks a page used. The page must reside within the extents of the given
segment. */
static
void
fseg_mark_page_used(
/*================*/
- fseg_inode_t* seg_inode,/* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* seg_inode,/*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: page offset */
- mtr_t* mtr) /* in: mtr */
+ ulint page, /*!< in: page offset */
+ mtr_t* mtr) /*!< in: mtr */
{
xdes_t* descr;
ulint not_full_n_used;
@@ -3176,18 +3175,18 @@ fseg_mark_page_used(
}
}
-/**************************************************************************
+/**********************************************************************//**
Frees a single page of a segment. */
static
void
fseg_free_page_low(
/*===============*/
- fseg_inode_t* seg_inode, /* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* seg_inode, /*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: page offset */
- mtr_t* mtr) /* in: mtr handle */
+ ulint page, /*!< in: page offset */
+ mtr_t* mtr) /*!< in: mtr handle */
{
xdes_t* descr;
ulint not_full_n_used;
@@ -3225,8 +3224,7 @@ fseg_free_page_low(
"InnoDB: database!\n", (ulong) page);
crash:
fputs("InnoDB: Please refer to\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "forcing-recovery.html\n"
+ "InnoDB: " REFMAN "forcing-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
ut_error;
}
@@ -3316,16 +3314,16 @@ crash:
}
}
-/**************************************************************************
+/**********************************************************************//**
Frees a single page of a segment. */
UNIV_INTERN
void
fseg_free_page(
/*===========*/
- fseg_header_t* seg_header, /* in: segment header */
- ulint space, /* in: space id */
- ulint page, /* in: page offset */
- mtr_t* mtr) /* in: mtr handle */
+ fseg_header_t* seg_header, /*!< in: segment header */
+ ulint space, /*!< in: space id */
+ ulint page, /*!< in: page offset */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint flags;
ulint zip_size;
@@ -3349,18 +3347,18 @@ fseg_free_page(
#endif
}
-/**************************************************************************
+/**********************************************************************//**
Frees an extent of a segment to the space free list. */
static
void
fseg_free_extent(
/*=============*/
- fseg_inode_t* seg_inode, /* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* seg_inode, /*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page, /* in: a page in the extent */
- mtr_t* mtr) /* in: mtr handle */
+ ulint page, /*!< in: a page in the extent */
+ mtr_t* mtr) /*!< in: mtr handle */
{
ulint first_page_in_extent;
xdes_t* descr;
@@ -3420,21 +3418,21 @@ fseg_free_extent(
#endif
}
-/**************************************************************************
+/**********************************************************************//**
Frees part of a segment. This function can be used to free a segment by
repeatedly calling this function in different mini-transactions. Doing
the freeing in a single mini-transaction might result in too big a
-mini-transaction. */
+mini-transaction.
+@return TRUE if freeing completed */
UNIV_INTERN
ibool
fseg_free_step(
/*===========*/
- /* out: TRUE if freeing completed */
- fseg_header_t* header, /* in, own: segment header; NOTE: if the header
+ fseg_header_t* header, /*!< in, own: segment header; NOTE: if the header
resides on the first page of the frag list
of the segment, this pointer becomes obsolete
after the last freeing step */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint n;
ulint page;
@@ -3503,18 +3501,17 @@ fseg_free_step(
return(FALSE);
}
-/**************************************************************************
+/**********************************************************************//**
Frees part of a segment. Differs from fseg_free_step because this function
-leaves the header page unfreed. */
+leaves the header page unfreed.
+@return TRUE if freeing completed, except the header page */
UNIV_INTERN
ibool
fseg_free_step_not_header(
/*======================*/
- /* out: TRUE if freeing completed, except the
- header page */
- fseg_header_t* header, /* in: segment header which must reside on
+ fseg_header_t* header, /*!< in: segment header which must reside on
the first fragment page of the segment */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint n;
ulint page;
@@ -3569,60 +3566,20 @@ fseg_free_step_not_header(
return(FALSE);
}
-/***********************************************************************
-Frees a segment. The freeing is performed in several mini-transactions,
-so that there is no danger of bufferfixing too many buffer pages. */
-UNIV_INTERN
-void
-fseg_free(
-/*======*/
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
- or 0 for uncompressed pages */
- ulint page_no,/* in: page number where the segment header is
- placed */
- ulint offset) /* in: byte offset of the segment header on that
- page */
-{
- mtr_t mtr;
- ibool finished;
- fseg_header_t* header;
- fil_addr_t addr;
-
- addr.page = page_no;
- addr.boffset = offset;
-
- for (;;) {
- mtr_start(&mtr);
-
- header = fut_get_ptr(space, zip_size, addr, RW_X_LATCH, &mtr);
-
- finished = fseg_free_step(header, &mtr);
-
- mtr_commit(&mtr);
-
- if (finished) {
-
- return;
- }
- }
-}
-
-/**************************************************************************
+/**********************************************************************//**
Returns the first extent descriptor for a segment. We think of the extent
lists of the segment catenated in the order FSEG_FULL -> FSEG_NOT_FULL
--> FSEG_FREE. */
+-> FSEG_FREE.
+@return the first extent descriptor, or NULL if none */
static
xdes_t*
fseg_get_first_extent(
/*==================*/
- /* out: the first extent descriptor, or NULL if
- none */
- fseg_inode_t* inode, /* in: segment inode */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ fseg_inode_t* inode, /*!< in: segment inode */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
fil_addr_t first;
xdes_t* descr;
@@ -3655,15 +3612,15 @@ fseg_get_first_extent(
return(descr);
}
-/***********************************************************************
-Validates a segment. */
+/*******************************************************************//**
+Validates a segment.
+@return TRUE if ok */
static
ibool
fseg_validate_low(
/*==============*/
- /* out: TRUE if ok */
- fseg_inode_t* inode, /* in: segment inode */
- mtr_t* mtr2) /* in: mtr */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ mtr_t* mtr2) /*!< in: mtr */
{
ulint space;
dulint seg_id;
@@ -3764,15 +3721,16 @@ fseg_validate_low(
return(TRUE);
}
-/***********************************************************************
-Validates a segment. */
+#ifdef UNIV_DEBUG
+/*******************************************************************//**
+Validates a segment.
+@return TRUE if ok */
UNIV_INTERN
ibool
fseg_validate(
/*==========*/
- /* out: TRUE if ok */
- fseg_header_t* header, /* in: segment header */
- mtr_t* mtr) /* in: mtr */
+ fseg_header_t* header, /*!< in: segment header */
+ mtr_t* mtr) /*!< in: mtr */
{
fseg_inode_t* inode;
ibool ret;
@@ -3791,15 +3749,16 @@ fseg_validate(
return(ret);
}
+#endif /* UNIV_DEBUG */
-/***********************************************************************
+/*******************************************************************//**
Writes info of a segment. */
static
void
fseg_print_low(
/*===========*/
- fseg_inode_t* inode, /* in: segment inode */
- mtr_t* mtr) /* in: mtr */
+ fseg_inode_t* inode, /*!< in: segment inode */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint space;
ulint seg_id_low;
@@ -3845,14 +3804,14 @@ fseg_print_low(
}
#ifdef UNIV_BTR_PRINT
-/***********************************************************************
+/*******************************************************************//**
Writes info of a segment. */
UNIV_INTERN
void
fseg_print(
/*=======*/
- fseg_header_t* header, /* in: segment header */
- mtr_t* mtr) /* in: mtr */
+ fseg_header_t* header, /*!< in: segment header */
+ mtr_t* mtr) /*!< in: mtr */
{
fseg_inode_t* inode;
ulint space;
@@ -3870,14 +3829,14 @@ fseg_print(
}
#endif /* UNIV_BTR_PRINT */
-/***********************************************************************
-Validates the file space system and its segments. */
+/*******************************************************************//**
+Validates the file space system and its segments.
+@return TRUE if ok */
UNIV_INTERN
ibool
fsp_validate(
/*=========*/
- /* out: TRUE if ok */
- ulint space) /* in: space id */
+ ulint space) /*!< in: space id */
{
fsp_header_t* header;
fseg_inode_t* seg_inode;
@@ -4125,13 +4084,13 @@ fsp_validate(
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
Prints info of a file space. */
UNIV_INTERN
void
fsp_print(
/*======*/
- ulint space) /* in: space id */
+ ulint space) /*!< in: space id */
{
fsp_header_t* header;
fseg_inode_t* seg_inode;
@@ -4282,3 +4241,4 @@ fsp_print(
fprintf(stderr, "NUMBER of file segments: %lu\n", (ulong) n_segs);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/fut/fut0fut.c b/storage/xtradb/fut/fut0fut.c
index 41ee0cb6715..20b45a575e6 100644
--- a/storage/xtradb/fut/fut0fut.c
+++ b/storage/xtradb/fut/fut0fut.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file fut/fut0fut.c
File-based utilities
Created 12/13/1995 Heikki Tuuri
diff --git a/storage/xtradb/fut/fut0lst.c b/storage/xtradb/fut/fut0lst.c
index bea27ab70d1..a1e21c22725 100644
--- a/storage/xtradb/fut/fut0lst.c
+++ b/storage/xtradb/fut/fut0lst.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file fut/fut0lst.c
File-based list utilities
Created 11/28/1995 Heikki Tuuri
@@ -31,16 +32,16 @@ Created 11/28/1995 Heikki Tuuri
#include "buf0buf.h"
#include "page0page.h"
-/************************************************************************
+/********************************************************************//**
Adds a node to an empty list. */
static
void
flst_add_to_empty(
/*==============*/
- flst_base_node_t* base, /* in: pointer to base node of
+ flst_base_node_t* base, /*!< in: pointer to base node of
empty list */
- flst_node_t* node, /* in: node to add */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_node_t* node, /*!< in: node to add */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
fil_addr_t node_addr;
@@ -67,15 +68,15 @@ flst_add_to_empty(
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
}
-/************************************************************************
+/********************************************************************//**
Adds a node as the last node in a list. */
UNIV_INTERN
void
flst_add_last(
/*==========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node, /* in: node to add */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node, /*!< in: node to add */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
fil_addr_t node_addr;
@@ -110,15 +111,15 @@ flst_add_last(
}
}
-/************************************************************************
+/********************************************************************//**
Adds a node as the first node in a list. */
UNIV_INTERN
void
flst_add_first(
/*===========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node, /* in: node to add */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node, /*!< in: node to add */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
fil_addr_t node_addr;
@@ -153,16 +154,16 @@ flst_add_first(
}
}
-/************************************************************************
+/********************************************************************//**
Inserts a node after another in a list. */
UNIV_INTERN
void
flst_insert_after(
/*==============*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node1, /* in: node to insert after */
- flst_node_t* node2, /* in: node to add */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node1, /*!< in: node to insert after */
+ flst_node_t* node2, /*!< in: node to add */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
fil_addr_t node1_addr;
@@ -208,16 +209,16 @@ flst_insert_after(
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
}
-/************************************************************************
+/********************************************************************//**
Inserts a node before another in a list. */
UNIV_INTERN
void
flst_insert_before(
/*===============*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: node to insert */
- flst_node_t* node3, /* in: node to insert before */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: node to insert */
+ flst_node_t* node3, /*!< in: node to insert before */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
flst_node_t* node1;
@@ -262,15 +263,15 @@ flst_insert_before(
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
}
-/************************************************************************
+/********************************************************************//**
Removes a node. */
UNIV_INTERN
void
flst_remove(
/*========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: node to remove */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: node to remove */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
ulint zip_size;
@@ -337,7 +338,7 @@ flst_remove(
mlog_write_ulint(base + FLST_LEN, len - 1, MLOG_4BYTES, mtr);
}
-/************************************************************************
+/********************************************************************//**
Cuts off the tail of the list, including the node given. The number of
nodes which will be removed must be provided by the caller, as this function
does not measure the length of the tail. */
@@ -345,11 +346,11 @@ UNIV_INTERN
void
flst_cut_end(
/*=========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: first node to remove */
- ulint n_nodes,/* in: number of nodes to remove,
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: first node to remove */
+ ulint n_nodes,/*!< in: number of nodes to remove,
must be >= 1 */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint space;
flst_node_t* node1;
@@ -394,7 +395,7 @@ flst_cut_end(
mlog_write_ulint(base + FLST_LEN, len - n_nodes, MLOG_4BYTES, mtr);
}
-/************************************************************************
+/********************************************************************//**
Cuts off the tail of the list, not including the given node. The number of
nodes which will be removed must be provided by the caller, as this function
does not measure the length of the tail. */
@@ -402,10 +403,10 @@ UNIV_INTERN
void
flst_truncate_end(
/*==============*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: first node not to remove */
- ulint n_nodes,/* in: number of nodes to remove */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: first node not to remove */
+ ulint n_nodes,/*!< in: number of nodes to remove */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
fil_addr_t node2_addr;
ulint len;
@@ -435,15 +436,15 @@ flst_truncate_end(
mlog_write_ulint(base + FLST_LEN, len - n_nodes, MLOG_4BYTES, mtr);
}
-/************************************************************************
-Validates a file-based list. */
+/********************************************************************//**
+Validates a file-based list.
+@return TRUE if ok */
UNIV_INTERN
ibool
flst_validate(
/*==========*/
- /* out: TRUE if ok */
- const flst_base_node_t* base, /* in: pointer to base node of list */
- mtr_t* mtr1) /* in: mtr */
+ const flst_base_node_t* base, /*!< in: pointer to base node of list */
+ mtr_t* mtr1) /*!< in: mtr */
{
ulint space;
ulint zip_size;
@@ -502,14 +503,14 @@ flst_validate(
return(TRUE);
}
-/************************************************************************
+/********************************************************************//**
Prints info of a file-based list. */
UNIV_INTERN
void
flst_print(
/*=======*/
- const flst_base_node_t* base, /* in: pointer to base node of list */
- mtr_t* mtr) /* in: mtr */
+ const flst_base_node_t* base, /*!< in: pointer to base node of list */
+ mtr_t* mtr) /*!< in: mtr */
{
const buf_frame_t* frame;
ulint len;
diff --git a/storage/xtradb/ha/ha0ha.c b/storage/xtradb/ha/ha0ha.c
index 1ecba3df663..cb5e541b55d 100644
--- a/storage/xtradb/ha/ha0ha.c
+++ b/storage/xtradb/ha/ha0ha.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file ha/ha0ha.c
The hash table with external chains
Created 8/22/1994 Heikki Tuuri
@@ -35,29 +36,34 @@ Created 8/22/1994 Heikki Tuuri
#endif /* UNIV_SYNC_DEBUG */
#include "page0page.h"
-/*****************************************************************
-Creates a hash table with >= n array cells. The actual number of cells is
-chosen to be a prime number slightly bigger than n. */
+/*************************************************************//**
+Creates a hash table with at least n array cells. The actual number
+of cells is chosen to be a prime number slightly bigger than n.
+@return own: created table */
UNIV_INTERN
hash_table_t*
ha_create_func(
/*===========*/
- /* out, own: created table */
- ulint n, /* in: number of array cells */
+ ulint n, /*!< in: number of array cells */
#ifdef UNIV_SYNC_DEBUG
- ulint mutex_level, /* in: level of the mutexes in the latching
+ ulint mutex_level, /*!< in: level of the mutexes in the latching
order: this is used in the debug version */
#endif /* UNIV_SYNC_DEBUG */
- ulint n_mutexes) /* in: number of mutexes to protect the
+ ulint n_mutexes) /*!< in: number of mutexes to protect the
hash table: must be a power of 2, or 0 */
{
hash_table_t* table;
+#ifndef UNIV_HOTBACKUP
ulint i;
+#endif /* !UNIV_HOTBACKUP */
+ ut_ad(ut_is_2pow(n_mutexes));
table = hash_create(n);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+# ifndef UNIV_HOTBACKUP
table->adaptive = TRUE;
+# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
/* Creating MEM_HEAP_BTR_SEARCH type heaps can potentially fail,
but in practise it never should in this case, hence the asserts. */
@@ -70,6 +76,7 @@ ha_create_func(
return(table);
}
+#ifndef UNIV_HOTBACKUP
hash_create_mutexes(table, n_mutexes, mutex_level);
table->heaps = mem_alloc(n_mutexes * sizeof(void*));
@@ -78,17 +85,18 @@ ha_create_func(
table->heaps[i] = mem_heap_create_in_btr_search(4096);
ut_a(table->heaps[i]);
}
+#endif /* !UNIV_HOTBACKUP */
return(table);
}
-/*****************************************************************
+/*************************************************************//**
Empties a hash table and frees the memory heaps. */
UNIV_INTERN
void
ha_clear(
/*=====*/
- hash_table_t* table) /* in, own: hash table */
+ hash_table_t* table) /*!< in, own: hash table */
{
ulint i;
ulint n;
@@ -97,12 +105,14 @@ ha_clear(
ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE));
#endif /* UNIV_SYNC_DEBUG */
+#ifndef UNIV_HOTBACKUP
/* Free the memory heaps. */
n = table->n_mutexes;
for (i = 0; i < n; i++) {
mem_heap_free(table->heaps[i]);
}
+#endif /* !UNIV_HOTBACKUP */
/* Clear the hash table. */
n = hash_get_n_cells(table);
@@ -112,25 +122,24 @@ 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.
+@return TRUE if succeed, FALSE if no more memory could be allocated */
UNIV_INTERN
ibool
ha_insert_for_fold_func(
/*====================*/
- /* out: TRUE if succeed, FALSE if no more
- memory could be allocated */
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of data; if a node with
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold, /*!< in: folded value of data; if a node with
the same fold value already exists, it is
updated to point to the same data, and no new
node is created! */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- buf_block_t* block, /* in: buffer block containing the data */
+ buf_block_t* block, /*!< in: buffer block containing the data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- void* data) /* in: data, must not be NULL */
+ void* data) /*!< in: data, must not be NULL */
{
hash_cell_t* cell;
ha_node_t* node;
@@ -141,7 +150,7 @@ ha_insert_for_fold_func(
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(block->frame == page_align(data));
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
+ ASSERT_HASH_MUTEX_OWN(table, fold);
hash = hash_calc_hash(fold, table);
@@ -152,6 +161,7 @@ ha_insert_for_fold_func(
while (prev_node != NULL) {
if (prev_node->fold == fold) {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
buf_block_t* prev_block = prev_node->block;
ut_a(prev_block->frame
@@ -160,6 +170,7 @@ ha_insert_for_fold_func(
prev_block->n_pointers--;
block->n_pointers++;
}
+# endif /* !UNIV_HOTBACKUP */
prev_node->block = block;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@@ -187,10 +198,13 @@ ha_insert_for_fold_func(
ha_node_set_data(node, block, data);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
block->n_pointers++;
}
+# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+
node->fold = fold;
node->next = NULL;
@@ -214,65 +228,46 @@ ha_insert_for_fold_func(
return(TRUE);
}
-/***************************************************************
+/***********************************************************//**
Deletes a hash node. */
UNIV_INTERN
void
ha_delete_hash_node(
/*================*/
- hash_table_t* table, /* in: hash table */
- ha_node_t* del_node) /* in: node to be deleted */
+ hash_table_t* table, /*!< in: hash table */
+ ha_node_t* del_node) /*!< in: node to be deleted */
{
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
ut_a(del_node->block->frame = page_align(del_node->data));
ut_a(del_node->block->n_pointers > 0);
del_node->block->n_pointers--;
}
+# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- HASH_DELETE_AND_COMPACT(ha_node_t, next, table, del_node);
-}
-/*****************************************************************
-Deletes an entry from a hash table. */
-UNIV_INTERN
-void
-ha_delete(
-/*======*/
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of data */
- void* data) /* in: data, must not be NULL and must exist
- in the hash table */
-{
- ha_node_t* node;
-
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
-
- node = ha_search_with_data(table, fold, data);
-
- ut_a(node);
-
- ha_delete_hash_node(table, node);
+ HASH_DELETE_AND_COMPACT(ha_node_t, next, table, del_node);
}
-/*************************************************************
+/*********************************************************//**
Looks for an element when we know the pointer to the data, and updates
the pointer to data, if found. */
UNIV_INTERN
void
ha_search_and_update_if_found_func(
/*===============================*/
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of the searched data */
- void* data, /* in: pointer to the data */
+ hash_table_t* table, /*!< in/out: hash table */
+ ulint fold, /*!< in: folded value of the searched data */
+ void* data, /*!< in: pointer to the data */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- buf_block_t* new_block,/* in: block containing new_data */
+ buf_block_t* new_block,/*!< in: block containing new_data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- void* new_data)/* in: new pointer to the data */
+ void* new_data)/*!< in: new pointer to the data */
{
ha_node_t* node;
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
+ ASSERT_HASH_MUTEX_OWN(table, fold);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(new_block->frame == page_align(new_data));
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@@ -281,11 +276,13 @@ ha_search_and_update_if_found_func(
if (node) {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
ut_a(node->block->n_pointers > 0);
node->block->n_pointers--;
new_block->n_pointers++;
}
+# endif /* !UNIV_HOTBACKUP */
node->block = new_block;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@@ -293,20 +290,21 @@ ha_search_and_update_if_found_func(
}
}
-/*********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*****************************************************************//**
Removes from the chain determined by fold all nodes whose data pointer
points to the page given. */
UNIV_INTERN
void
ha_remove_all_nodes_to_page(
/*========================*/
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: fold value */
- const page_t* page) /* in: buffer page */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold, /*!< in: fold value */
+ const page_t* page) /*!< in: buffer page */
{
ha_node_t* node;
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
+ ASSERT_HASH_MUTEX_OWN(table, fold);
node = ha_chain_get_first(table, fold);
@@ -339,16 +337,16 @@ ha_remove_all_nodes_to_page(
#endif
}
-/*****************************************************************
-Validates a given range of the cells in hash table. */
+/*************************************************************//**
+Validates a given range of the cells in hash table.
+@return TRUE if ok */
UNIV_INTERN
ibool
ha_validate(
/*========*/
- /* out: TRUE if ok */
- hash_table_t* table, /* in: hash table */
- ulint start_index, /* in: start index */
- ulint end_index) /* in: end index */
+ hash_table_t* table, /*!< in: hash table */
+ ulint start_index, /*!< in: start index */
+ ulint end_index) /*!< in: end index */
{
hash_cell_t* cell;
ha_node_t* node;
@@ -384,14 +382,14 @@ ha_validate(
return(ok);
}
-/*****************************************************************
+/*************************************************************//**
Prints info of a hash table. */
UNIV_INTERN
void
ha_print_info(
/*==========*/
- FILE* file, /* in: file where to print */
- hash_table_t* table) /* in: hash table */
+ FILE* file, /*!< in: file where to print */
+ hash_table_t* table) /*!< in: hash table */
{
#ifdef UNIV_DEBUG
/* Some of the code here is disabled for performance reasons in production
@@ -440,3 +438,4 @@ builds, see http://bugs.mysql.com/36941 */
(ulong) n_bufs);
}
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/ha/ha0storage.c b/storage/xtradb/ha/ha0storage.c
index e7e09591193..698e34f1166 100644
--- a/storage/xtradb/ha/ha0storage.c
+++ b/storage/xtradb/ha/ha0storage.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file ha/ha0storage.c
Hash storage.
Provides a data structure that stores chunks of data in
its own storage, avoiding duplicates.
@@ -34,16 +35,16 @@ Created September 22, 2007 Vasil Dimov
#include "ha0storage.ic"
#endif
-/***********************************************************************
+/*******************************************************************//**
Retrieves a data from a storage. If it is present, a pointer to the
stored copy of data is returned, otherwise NULL is returned. */
static
const void*
ha_storage_get(
/*===========*/
- ha_storage_t* storage, /* in: hash storage */
- const void* data, /* in: data to check for */
- ulint data_len) /* in: data length */
+ ha_storage_t* storage, /*!< in: hash storage */
+ const void* data, /*!< in: data to check for */
+ ulint data_len) /*!< in: data length */
{
ha_storage_node_t* node;
ulint fold;
@@ -73,7 +74,7 @@ ha_storage_get(
return(node->data);
}
-/***********************************************************************
+/*******************************************************************//**
Copies data into the storage and returns a pointer to the copy. If the
same data chunk is already present, then pointer to it is returned.
Data chunks are considered to be equal if len1 == len2 and
@@ -86,10 +87,10 @@ UNIV_INTERN
const void*
ha_storage_put_memlim(
/*==================*/
- ha_storage_t* storage, /* in/out: hash storage */
- const void* data, /* in: data to store */
- ulint data_len, /* in: data length */
- ulint memlim) /* in: memory limit to obey */
+ ha_storage_t* storage, /*!< in/out: hash storage */
+ const void* data, /*!< in: data to store */
+ ulint data_len, /*!< in: data length */
+ ulint memlim) /*!< in: memory limit to obey */
{
void* raw;
ha_storage_node_t* node;
diff --git a/storage/xtradb/ha/hash0hash.c b/storage/xtradb/ha/hash0hash.c
index 9694a288c99..2800d7793f8 100644
--- a/storage/xtradb/ha/hash0hash.c
+++ b/storage/xtradb/ha/hash0hash.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file ha/hash0hash.c
The simple hash table utility
Created 5/20/1997 Heikki Tuuri
@@ -29,37 +30,38 @@ Created 5/20/1997 Heikki Tuuri
#include "mem0mem.h"
-/****************************************************************
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
Reserves the mutex for a fold value in a hash table. */
UNIV_INTERN
void
hash_mutex_enter(
/*=============*/
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: fold */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: fold */
{
mutex_enter(hash_get_mutex(table, fold));
}
-/****************************************************************
+/************************************************************//**
Releases the mutex for a fold value in a hash table. */
UNIV_INTERN
void
hash_mutex_exit(
/*============*/
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: fold */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: fold */
{
mutex_exit(hash_get_mutex(table, fold));
}
-/****************************************************************
+/************************************************************//**
Reserves all the mutexes of a hash table, in an ascending order. */
UNIV_INTERN
void
hash_mutex_enter_all(
/*=================*/
- hash_table_t* table) /* in: hash table */
+ hash_table_t* table) /*!< in: hash table */
{
ulint i;
@@ -69,13 +71,13 @@ hash_mutex_enter_all(
}
}
-/****************************************************************
+/************************************************************//**
Releases all the mutexes of a hash table. */
UNIV_INTERN
void
hash_mutex_exit_all(
/*================*/
- hash_table_t* table) /* in: hash table */
+ hash_table_t* table) /*!< in: hash table */
{
ulint i;
@@ -84,16 +86,17 @@ hash_mutex_exit_all(
mutex_exit(table->mutexes + i);
}
}
+#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+/*************************************************************//**
Creates a hash table with >= n array cells. The actual number of cells is
-chosen to be a prime number slightly bigger than n. */
+chosen to be a prime number slightly bigger than n.
+@return own: created table */
UNIV_INTERN
hash_table_t*
hash_create(
/*========*/
- /* out, own: created table */
- ulint n) /* in: number of array cells */
+ ulint n) /*!< in: number of array cells */
{
hash_cell_t* array;
ulint prime;
@@ -105,14 +108,16 @@ hash_create(
array = ut_malloc(sizeof(hash_cell_t) * prime);
-#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- table->adaptive = FALSE;
-#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
table->array = array;
table->n_cells = prime;
+#ifndef UNIV_HOTBACKUP
+# 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;
+#endif /* !UNIV_HOTBACKUP */
table->heap = NULL;
table->magic_n = HASH_TABLE_MAGIC_N;
@@ -122,32 +127,35 @@ hash_create(
return(table);
}
-/*****************************************************************
+/*************************************************************//**
Frees a hash table. */
UNIV_INTERN
void
hash_table_free(
/*============*/
- hash_table_t* table) /* in, own: hash table */
+ hash_table_t* table) /*!< in, own: hash table */
{
+#ifndef UNIV_HOTBACKUP
ut_a(table->mutexes == NULL);
+#endif /* !UNIV_HOTBACKUP */
ut_free(table->array);
mem_free(table);
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Creates a mutex array to protect a hash table. */
UNIV_INTERN
void
hash_create_mutexes_func(
/*=====================*/
- hash_table_t* table, /* in: hash table */
+ hash_table_t* table, /*!< in: hash table */
#ifdef UNIV_SYNC_DEBUG
- ulint sync_level, /* in: latching order level of the
+ ulint sync_level, /*!< in: latching order level of the
mutexes: used in the debug version */
#endif /* UNIV_SYNC_DEBUG */
- ulint n_mutexes) /* in: number of mutexes, must be a
+ ulint n_mutexes) /*!< in: number of mutexes, must be a
power of 2 */
{
ulint i;
@@ -163,3 +171,4 @@ hash_create_mutexes_func(
table->n_mutexes = n_mutexes;
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 1cd4000846a..094649eb2a7 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2009, MySQL AB & Innobase Oy. All Rights Reserved.
-Copyright (c) 2008, Google Inc.
+Copyright (c) 2008, 2009 Google Inc.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -22,6 +22,32 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+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
+
+***********************************************************************/
/* TODO list for the InnoDB handler in 5.0:
- Remove the flag trx->active_trans and look at trx->conc_state
@@ -46,37 +72,39 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <mysys_err.h>
#include <mysql/plugin.h>
+/** @file ha_innodb.cc */
+
/* Include necessary InnoDB headers */
extern "C" {
-#include "../storage/xtradb/include/univ.i"
-#include "../storage/xtradb/include/btr0sea.h"
-#include "../storage/xtradb/include/os0file.h"
-#include "../storage/xtradb/include/os0thread.h"
-#include "../storage/xtradb/include/srv0start.h"
-#include "../storage/xtradb/include/srv0srv.h"
-#include "../storage/xtradb/include/trx0roll.h"
-#include "../storage/xtradb/include/trx0trx.h"
-#include "../storage/xtradb/include/trx0sys.h"
-#include "../storage/xtradb/include/mtr0mtr.h"
-#include "../storage/xtradb/include/row0ins.h"
-#include "../storage/xtradb/include/row0mysql.h"
-#include "../storage/xtradb/include/row0sel.h"
-#include "../storage/xtradb/include/row0upd.h"
-#include "../storage/xtradb/include/log0log.h"
-#include "../storage/xtradb/include/lock0lock.h"
-#include "../storage/xtradb/include/dict0crea.h"
-#include "../storage/xtradb/include/btr0cur.h"
-#include "../storage/xtradb/include/btr0btr.h"
-#include "../storage/xtradb/include/fsp0fsp.h"
-#include "../storage/xtradb/include/sync0sync.h"
-#include "../storage/xtradb/include/fil0fil.h"
-#include "../storage/xtradb/include/trx0xa.h"
-#include "../storage/xtradb/include/row0merge.h"
-#include "../storage/xtradb/include/thr0loc.h"
-#include "../storage/xtradb/include/dict0boot.h"
-#include "../storage/xtradb/include/ha_prototypes.h"
-#include "../storage/xtradb/include/ut0mem.h"
-#include "../storage/xtradb/include/ibuf0ibuf.h"
+#include "univ.i"
+#include "btr0sea.h"
+#include "os0file.h"
+#include "os0thread.h"
+#include "srv0start.h"
+#include "srv0srv.h"
+#include "trx0roll.h"
+#include "trx0trx.h"
+#include "trx0sys.h"
+#include "mtr0mtr.h"
+#include "row0ins.h"
+#include "row0mysql.h"
+#include "row0sel.h"
+#include "row0upd.h"
+#include "log0log.h"
+#include "lock0lock.h"
+#include "dict0crea.h"
+#include "btr0cur.h"
+#include "btr0btr.h"
+#include "fsp0fsp.h"
+#include "sync0sync.h"
+#include "fil0fil.h"
+#include "trx0xa.h"
+#include "row0merge.h"
+#include "thr0loc.h"
+#include "dict0boot.h"
+#include "ha_prototypes.h"
+#include "ut0mem.h"
+#include "ibuf0ibuf.h"
}
#include "ha_innodb.h"
@@ -111,6 +139,7 @@ static ulong commit_threads = 0;
static pthread_mutex_t commit_threads_m;
static pthread_cond_t commit_cond;
static pthread_mutex_t commit_cond_m;
+static pthread_mutex_t analyze_mutex;
static bool innodb_inited = 0;
#define INSIDE_HA_INNOBASE_CC
@@ -125,26 +154,7 @@ undefined. Map it to NULL. */
# define EQ_CURRENT_THD(thd) ((thd) == current_thd)
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
-#ifdef MYSQL_DYNAMIC_PLUGIN
-/* These must be weak global variables in the dynamic plugin. */
-struct handlerton* innodb_hton_ptr;
-#ifdef __WIN__
-struct st_mysql_plugin* builtin_innobase_plugin_ptr;
-#else
-int builtin_innobase_plugin;
-#endif /* __WIN__ */
-/********************************************************************
-Copy InnoDB system variables from the static InnoDB to the dynamic
-plugin. */
-static
-bool
-innodb_plugin_init(void);
-/*====================*/
- /* out: TRUE if the dynamic InnoDB plugin should start */
-#else /* MYSQL_DYNAMIC_PLUGIN */
-/* This must be a global variable in the statically linked InnoDB. */
-struct handlerton* innodb_hton_ptr = NULL;
-#endif /* MYSQL_DYNAMIC_PLUGIN */
+static struct handlerton* innodb_hton_ptr;
static const long AUTOINC_OLD_STYLE_LOCKING = 0;
static const long AUTOINC_NEW_STYLE_LOCKING = 1;
@@ -155,9 +165,10 @@ static long innobase_mirrored_log_groups, innobase_log_files_in_group,
innobase_additional_mem_pool_size, innobase_file_io_threads,
innobase_force_recovery, innobase_open_files,
innobase_autoinc_lock_mode;
-static unsigned long innobase_commit_concurrency = 0;
+static ulong innobase_commit_concurrency = 0;
+static ulong innobase_read_io_threads;
+static ulong innobase_write_io_threads;
-static unsigned long innobase_read_io_threads, innobase_write_io_threads;
static my_bool innobase_thread_concurrency_timer_based;
static long long innobase_buffer_pool_size, innobase_log_file_size;
@@ -191,6 +202,7 @@ static my_bool innobase_use_doublewrite = TRUE;
static my_bool innobase_use_checksums = TRUE;
static my_bool innobase_extra_undoslots = FALSE;
static my_bool innobase_fast_recovery = FALSE;
+static my_bool innobase_use_purge_thread = FALSE;
static my_bool innobase_locks_unsafe_for_binlog = FALSE;
static my_bool innobase_overwrite_relay_log_info = FALSE;
static my_bool innobase_rollback_on_timeout = FALSE;
@@ -234,37 +246,52 @@ static int innobase_release_savepoint(handlerton *hton, THD* thd,
static handler *innobase_create_handler(handlerton *hton,
TABLE_SHARE *table,
MEM_ROOT *mem_root);
+/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
+system primary index. */
+static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX";
+
+/** @brief Initialize the default value of innodb_commit_concurrency.
+
+Once InnoDB is running, the innodb_commit_concurrency must not change
+from zero to nonzero. (Bug #42101)
+
+The initial default value is 0, and without this extra initialization,
+SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
+to 0, even if it was initially set to nonzero at the command line
+or configuration file. */
+static
+void
+innobase_commit_concurrency_init_default(void);
+/*==========================================*/
-/****************************************************************
-Validate the file format name and return its corresponding id. */
+/************************************************************//**
+Validate the file format name and return its corresponding id.
+@return valid file format id */
static
uint
innobase_file_format_name_lookup(
/*=============================*/
- /* out: valid file format id */
- const char* format_name); /* in: pointer to file format
+ const char* format_name); /*!< in: pointer to file format
name */
-/****************************************************************
+/************************************************************//**
Validate the file format check config parameters, as a side effect it
-sets the srv_check_file_format_at_startup variable. */
+sets the srv_check_file_format_at_startup variable.
+@return true if one of "on" or "off" */
static
bool
innobase_file_format_check_on_off(
/*==============================*/
- /* out: true if one of
- "on" or "off" */
- const char* format_check); /* in: parameter value */
-/****************************************************************
+ const char* format_check); /*!< in: parameter value */
+/************************************************************//**
Validate the file format check config parameters, as a side effect it
-sets the srv_check_file_format_at_startup variable. */
+sets the srv_check_file_format_at_startup variable.
+@return true if valid config value */
static
bool
innobase_file_format_check_validate(
/*================================*/
- /* out: true if valid
- config value */
- const char* format_check); /* in: parameter value */
-/********************************************************************
+ const char* format_check); /*!< in: parameter value */
+/****************************************************************//**
Return alter table flags supported in an InnoDB database. */
static
uint
@@ -274,34 +301,19 @@ innobase_alter_table_flags(
static const char innobase_hton_name[]= "InnoDB";
-/** @brief Initialize the default value of innodb_commit_concurrency.
-
-Once InnoDB is running, the innodb_commit_concurrency must not change
-from zero to nonzero. (Bug #42101)
-
-The initial default value is 0, and without this extra initialization,
-SET GLOBAL innodb_commit_concurrency=DEFAULT would set the parameter
-to 0, even if it was initially set to nonzero at the command line
-or configuration file. */
-static
-void
-innobase_commit_concurrency_init_default(void);
-/*==========================================*/
-
-/*****************************************************************
-Check for a valid value of innobase_commit_concurrency. */
+/*************************************************************//**
+Check for a valid value of innobase_commit_concurrency.
+@return 0 for valid innodb_commit_concurrency */
static
int
innobase_commit_concurrency_validate(
/*=================================*/
- /* out: 0 for valid
- innodb_commit_concurrency */
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to system
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to system
variable */
- void* save, /* out: immediate result
+ void* save, /*!< out: immediate result
for update function */
- struct st_mysql_value* value) /* in: incoming string */
+ struct st_mysql_value* value) /*!< in: incoming string */
{
long long intbuf;
ulong commit_concurrency;
@@ -347,62 +359,64 @@ static handler *innobase_create_handler(handlerton *hton,
return new (mem_root) ha_innobase(hton, table);
}
-/***********************************************************************
-This function is used to prepare X/Open XA distributed transaction */
+/*******************************************************************//**
+This function is used to prepare an X/Open XA distributed transaction.
+@return 0 or error number */
static
int
innobase_xa_prepare(
/*================*/
- /* out: 0 or error number */
- handlerton* hton,
- THD* thd, /* in: handle to the MySQL thread of the user
- whose XA transaction should be prepared */
- bool all); /* in: TRUE - commit transaction
- FALSE - the current SQL statement ended */
-/***********************************************************************
-This function is used to recover X/Open XA distributed transactions */
+ handlerton* hton, /*!< in: InnoDB handlerton */
+ THD* thd, /*!< in: handle to the MySQL thread of
+ the user whose XA transaction should
+ be prepared */
+ bool all); /*!< in: TRUE - commit transaction
+ FALSE - the current SQL statement
+ ended */
+/*******************************************************************//**
+This function is used to recover X/Open XA distributed transactions.
+@return number of prepared transactions stored in xid_list */
static
int
innobase_xa_recover(
/*================*/
- /* out: number of prepared transactions
- stored in xid_list */
- handlerton* hton,
- XID* xid_list, /* in/out: prepared transactions */
- uint len); /* in: number of slots in xid_list */
-/***********************************************************************
+ handlerton* hton, /*!< in: InnoDB handlerton */
+ XID* xid_list,/*!< in/out: prepared transactions */
+ uint len); /*!< in: number of slots in xid_list */
+/*******************************************************************//**
This function is used to commit one X/Open XA distributed transaction
-which is in the prepared state */
+which is in the prepared state
+@return 0 or error number */
static
int
innobase_commit_by_xid(
/*===================*/
- /* out: 0 or error number */
handlerton* hton,
- XID* xid); /* in: X/Open XA transaction identification */
-/***********************************************************************
+ XID* xid); /*!< in: X/Open XA transaction identification */
+/*******************************************************************//**
This function is used to rollback one X/Open XA distributed transaction
-which is in the prepared state */
+which is in the prepared state
+@return 0 or error number */
static
int
innobase_rollback_by_xid(
/*=====================*/
- /* out: 0 or error number */
- handlerton* hton,
- XID *xid); /* in: X/Open XA transaction identification */
-/***********************************************************************
+ handlerton* hton, /*!< in: InnoDB handlerton */
+ XID* xid); /*!< in: X/Open XA transaction
+ identification */
+/*******************************************************************//**
Create a consistent view for a cursor based on current transaction
which is created if the corresponding MySQL thread still lacks one.
This consistent view is then used inside of MySQL when accessing records
-using a cursor. */
+using a cursor.
+@return pointer to cursor view or NULL */
static
void*
innobase_create_cursor_view(
/*========================*/
- /* out: pointer to cursor view or NULL */
- handlerton* hton, /* in: innobase hton */
- THD* thd); /* in: user thread handle */
-/***********************************************************************
+ handlerton* hton, /*!< in: innobase hton */
+ THD* thd); /*!< in: user thread handle */
+/*******************************************************************//**
Set the given consistent cursor view to a transaction which is created
if the corresponding MySQL thread still lacks one. If the given
consistent cursor view is NULL global read view of a transaction is
@@ -412,9 +426,9 @@ void
innobase_set_cursor_view(
/*=====================*/
handlerton* hton,
- THD* thd, /* in: user thread handle */
- void* curview);/* in: Consistent cursor view to be set */
-/***********************************************************************
+ THD* thd, /*!< in: user thread handle */
+ void* curview);/*!< in: Consistent cursor view to be set */
+/*******************************************************************//**
Close the given consistent cursor view of a transaction and restore
global read view to a transaction read view. Transaction is created if the
corresponding MySQL thread still lacks one. */
@@ -423,71 +437,70 @@ void
innobase_close_cursor_view(
/*=======================*/
handlerton* hton,
- THD* thd, /* in: user thread handle */
- void* curview);/* in: Consistent read view to be closed */
-/*********************************************************************
+ THD* thd, /*!< in: user thread handle */
+ void* curview);/*!< in: Consistent read view to be closed */
+/*****************************************************************//**
Removes all tables in the named database inside InnoDB. */
static
void
innobase_drop_database(
/*===================*/
- /* out: error number */
- handlerton* hton, /* in: handlerton of Innodb */
- char* path); /* in: database path; inside InnoDB the name
+ handlerton* hton, /*!< in: handlerton of Innodb */
+ char* path); /*!< in: database path; inside InnoDB the name
of the last directory in the path is used as
the database name: for example, in 'mysql/data/test'
the database name is 'test' */
-/***********************************************************************
+/*******************************************************************//**
Closes an InnoDB database. */
static
int
innobase_end(handlerton *hton, ha_panic_function type);
-/*********************************************************************
+/*****************************************************************//**
Creates an InnoDB transaction struct for the thd if it does not yet have one.
Starts a new InnoDB transaction if a transaction is not yet started. And
assigns a new snapshot for a consistent read if the transaction does not yet
-have one. */
+have one.
+@return 0 */
static
int
innobase_start_trx_and_assign_read_view(
/*====================================*/
- /* out: 0 */
- handlerton* hton, /* in: Innodb handlerton */
- THD* thd); /* in: MySQL thread handle of the user for whom
+ handlerton* hton, /*!< in: Innodb handlerton */
+ THD* thd); /*!< in: MySQL thread handle of the user for whom
the transaction should be committed */
-/********************************************************************
+/****************************************************************//**
Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
-the logs, and the name of this function should be innobase_checkpoint. */
+the logs, and the name of this function should be innobase_checkpoint.
+@return TRUE if error */
static
bool
innobase_flush_logs(
/*================*/
- /* out: TRUE if error */
- handlerton* hton); /* in: InnoDB handlerton */
+ handlerton* hton); /*!< in: InnoDB handlerton */
-/****************************************************************************
+/************************************************************************//**
Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
Monitor to the client. */
static
bool
innodb_show_status(
/*===============*/
- handlerton* hton, /* in: the innodb handlerton */
- THD* thd, /* in: the MySQL query thread of the caller */
+ handlerton* hton, /*!< in: the innodb handlerton */
+ THD* thd, /*!< in: the MySQL query thread of the caller */
stat_print_fn *stat_print);
static
bool innobase_show_status(handlerton *hton, THD* thd,
stat_print_fn* stat_print,
enum ha_stat_type stat_type);
-/*********************************************************************
+/*****************************************************************//**
Commits a transaction in an InnoDB database. */
static
void
innobase_commit_low(
/*================*/
- trx_t* trx); /* in: transaction handle */
+ trx_t* trx); /*!< in: transaction handle */
static SHOW_VAR innodb_status_variables[]= {
{"buffer_pool_pages_data",
@@ -587,30 +600,30 @@ static SHOW_VAR innodb_status_variables[]= {
/* General functions */
-/**********************************************************************
+/******************************************************************//**
Returns true if the thread is the replication thread on the slave
server. Used in srv_conc_enter_innodb() to determine if the thread
should be allowed to enter InnoDB - the replication thread is treated
differently than other threads. Also used in
-srv_conc_force_exit_innodb(). */
+srv_conc_force_exit_innodb().
+@return true if thd is the replication thread */
extern "C" UNIV_INTERN
ibool
thd_is_replication_slave_thread(
/*============================*/
- /* out: true if thd is the replication thread */
- void* thd) /* in: thread handle (THD*) */
+ void* thd) /*!< in: thread handle (THD*) */
{
return((ibool) thd_slave_thread((THD*) thd));
}
-/**********************************************************************
+/******************************************************************//**
Save some CPU by testing the value of srv_thread_concurrency in inline
functions. */
static inline
void
innodb_srv_conc_enter_innodb(
/*=========================*/
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx) /*!< in: transaction handle */
{
if (UNIV_LIKELY(!srv_thread_concurrency)) {
@@ -620,14 +633,14 @@ innodb_srv_conc_enter_innodb(
srv_conc_enter_innodb(trx);
}
-/**********************************************************************
+/******************************************************************//**
Save some CPU by testing the value of srv_thread_concurrency in inline
functions. */
static inline
void
innodb_srv_conc_exit_innodb(
/*========================*/
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx) /*!< in: transaction handle */
{
if (UNIV_LIKELY(!trx->declared_to_be_inside_innodb)) {
@@ -637,7 +650,7 @@ innodb_srv_conc_exit_innodb(
srv_conc_exit_innodb(trx);
}
-/**********************************************************************
+/******************************************************************//**
Releases possible search latch and InnoDB thread FIFO ticket. These should
be released at each SQL statement end, and also when mysqld passes the
control to the client. It does no harm to release these also in the middle
@@ -646,7 +659,7 @@ static inline
void
innobase_release_stat_resources(
/*============================*/
- trx_t* trx) /* in: transaction object */
+ trx_t* trx) /*!< in: transaction object */
{
if (trx->has_search_latch) {
trx_search_latch_release_if_reserved(trx);
@@ -659,56 +672,55 @@ innobase_release_stat_resources(
}
}
-/**********************************************************************
+/******************************************************************//**
Returns true if the transaction this thread is processing has edited
non-transactional tables. Used by the deadlock detector when deciding
which transaction to rollback in case of a deadlock - we try to avoid
-rolling back transactions that have edited non-transactional tables. */
+rolling back transactions that have edited non-transactional tables.
+@return true if non-transactional tables have been edited */
extern "C" UNIV_INTERN
ibool
thd_has_edited_nontrans_tables(
/*===========================*/
- /* out: true if non-transactional tables have
- been edited */
- void* thd) /* in: thread handle (THD*) */
+ void* thd) /*!< in: thread handle (THD*) */
{
return((ibool) thd_non_transactional_update((THD*) thd));
}
-/**********************************************************************
-Returns true if the thread is executing a SELECT statement. */
+/******************************************************************//**
+Returns true if the thread is executing a SELECT statement.
+@return true if thd is executing SELECT */
extern "C" UNIV_INTERN
ibool
thd_is_select(
/*==========*/
- /* out: true if thd is executing SELECT */
- const void* thd) /* in: thread handle (THD*) */
+ const void* thd) /*!< in: thread handle (THD*) */
{
return(thd_sql_command((const THD*) thd) == SQLCOM_SELECT);
}
-/**********************************************************************
+/******************************************************************//**
Returns true if the thread supports XA,
-global value of innodb_supports_xa if thd is NULL. */
+global value of innodb_supports_xa if thd is NULL.
+@return true if thd has XA support */
extern "C" UNIV_INTERN
ibool
thd_supports_xa(
/*============*/
- /* out: true if thd has XA support */
- void* thd) /* in: thread handle (THD*), or NULL to query
+ void* thd) /*!< in: thread handle (THD*), or NULL to query
the global innodb_supports_xa */
{
return(THDVAR((THD*) thd, support_xa));
}
-/**********************************************************************
-Returns the lock wait timeout for the current connection. */
+/******************************************************************//**
+Returns the lock wait timeout for the current connection.
+@return the lock wait timeout, in seconds */
extern "C" UNIV_INTERN
ulong
thd_lock_wait_timeout(
/*==================*/
- /* out: the lock wait timeout, in seconds */
- void* thd) /* in: thread handle (THD*), or NULL to query
+ void* thd) /*!< in: thread handle (THD*), or NULL to query
the global innodb_lock_wait_timeout */
{
/* According to <mysql/plugin.h>, passing thd == NULL
@@ -716,29 +728,29 @@ thd_lock_wait_timeout(
return(THDVAR((THD*) thd, lock_wait_timeout));
}
-/************************************************************************
-Obtain the InnoDB transaction of a MySQL thread. */
+/********************************************************************//**
+Obtain the InnoDB transaction of a MySQL thread.
+@return reference to transaction pointer */
static inline
trx_t*&
thd_to_trx(
/*=======*/
- /* out: reference to transaction pointer */
- THD* thd) /* in: MySQL thread */
+ THD* thd) /*!< in: MySQL thread */
{
return(*(trx_t**) thd_ha_data(thd, innodb_hton_ptr));
}
-/************************************************************************
+/********************************************************************//**
Call this function when mysqld passes control to the client. That is to
avoid deadlocks on the adaptive hash S-latch possibly held by thd. For more
-documentation, see handler.cc. */
+documentation, see handler.cc.
+@return 0 */
static
int
innobase_release_temporary_latches(
/*===============================*/
- /* out: 0 */
- handlerton* hton, /* in: handlerton */
- THD* thd) /* in: MySQL thread */
+ handlerton* hton, /*!< in: handlerton */
+ THD* thd) /*!< in: MySQL thread */
{
trx_t* trx;
@@ -757,7 +769,7 @@ innobase_release_temporary_latches(
return(0);
}
-/************************************************************************
+/********************************************************************//**
Increments innobase_active_counter and every INNOBASE_WAKE_INTERVALth
time calls srv_active_wake_master_thread. This function should be used
when a single database operation may introduce a small need for
@@ -774,18 +786,18 @@ innobase_active_small(void)
}
}
-/************************************************************************
+/********************************************************************//**
Converts an InnoDB error code to a MySQL error code and also tells to MySQL
about a possible transaction rollback inside InnoDB caused by a lock wait
-timeout or a deadlock. */
+timeout or a deadlock.
+@return MySQL error code */
extern "C" UNIV_INTERN
int
convert_error_code_to_mysql(
/*========================*/
- /* out: MySQL error code */
- int error, /* in: InnoDB error code */
- ulint flags, /* in: InnoDB table flags, or 0 */
- THD* thd) /* in: user thread handle or NULL */
+ int error, /*!< in: InnoDB error code */
+ ulint flags, /*!< in: InnoDB table flags, or 0 */
+ THD* thd) /*!< in: user thread handle or NULL */
{
switch (error) {
case DB_SUCCESS:
@@ -801,6 +813,9 @@ convert_error_code_to_mysql(
case DB_FOREIGN_DUPLICATE_KEY:
return(HA_ERR_FOREIGN_DUPLICATE_KEY);
+ case DB_MISSING_HISTORY:
+ return(HA_ERR_TABLE_DEF_CHANGED);
+
case DB_RECORD_NOT_FOUND:
return(HA_ERR_NO_ACTIVE_RECORD);
@@ -895,7 +910,7 @@ convert_error_code_to_mysql(
}
}
-/*****************************************************************
+/*************************************************************//**
If you want to print a thd that is not associated with the current thread,
you must call this function before reserving the InnoDB kernel_mutex, to
protect MySQL from setting thd->query NULL. If you print a thd of the current
@@ -911,7 +926,7 @@ innobase_mysql_prepare_print_arbitrary_thd(void)
VOID(pthread_mutex_lock(&LOCK_thread_count));
}
-/*****************************************************************
+/*************************************************************//**
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
In the InnoDB latching order, the mutex sits right above the
kernel_mutex. In debug builds, we assert that the kernel_mutex is
@@ -925,15 +940,15 @@ innobase_mysql_end_print_arbitrary_thd(void)
VOID(pthread_mutex_unlock(&LOCK_thread_count));
}
-/*****************************************************************
+/*************************************************************//**
Prints info of a THD object (== user session thread) to the given file. */
extern "C" UNIV_INTERN
void
innobase_mysql_print_thd(
/*=====================*/
- FILE* f, /* in: output stream */
- void* thd, /* in: pointer to a MySQL THD object */
- uint max_query_len) /* in: max query length to print, or 0 to
+ FILE* f, /*!< in: output stream */
+ void* thd, /*!< in: pointer to a MySQL THD object */
+ uint max_query_len) /*!< in: max query length to print, or 0 to
use the default max length */
{
char buffer[1024];
@@ -943,15 +958,15 @@ innobase_mysql_print_thd(
putc('\n', f);
}
-/**********************************************************************
+/******************************************************************//**
Get the variable length bounds of the given character set. */
extern "C" UNIV_INTERN
void
innobase_get_cset_width(
/*====================*/
- ulint cset, /* in: MySQL charset-collation code */
- ulint* mbminlen, /* out: minimum length of a char (in bytes) */
- ulint* mbmaxlen) /* out: maximum length of a char (in bytes) */
+ ulint cset, /*!< in: MySQL charset-collation code */
+ ulint* mbminlen, /*!< out: minimum length of a char (in bytes) */
+ ulint* mbmaxlen) /*!< out: maximum length of a char (in bytes) */
{
CHARSET_INFO* cs;
ut_ad(cset < 256);
@@ -968,90 +983,90 @@ innobase_get_cset_width(
}
}
-/**********************************************************************
+/******************************************************************//**
Converts an identifier to a table name. */
extern "C" UNIV_INTERN
void
innobase_convert_from_table_id(
/*===========================*/
- struct charset_info_st* cs, /* in: the 'from' character set */
- char* to, /* out: converted identifier */
- const char* from, /* in: identifier to convert */
- ulint len) /* in: length of 'to', in bytes */
+ struct charset_info_st* cs, /*!< in: the 'from' character set */
+ char* to, /*!< out: converted identifier */
+ const char* from, /*!< in: identifier to convert */
+ ulint len) /*!< in: length of 'to', in bytes */
{
uint errors;
strconvert(cs, from, &my_charset_filename, to, (uint) len, &errors);
}
-/**********************************************************************
+/******************************************************************//**
Converts an identifier to UTF-8. */
extern "C" UNIV_INTERN
void
innobase_convert_from_id(
/*=====================*/
- struct charset_info_st* cs, /* in: the 'from' character set */
- char* to, /* out: converted identifier */
- const char* from, /* in: identifier to convert */
- ulint len) /* in: length of 'to', in bytes */
+ struct charset_info_st* cs, /*!< in: the 'from' character set */
+ char* to, /*!< out: converted identifier */
+ const char* from, /*!< in: identifier to convert */
+ ulint len) /*!< in: length of 'to', in bytes */
{
uint errors;
strconvert(cs, from, system_charset_info, to, (uint) len, &errors);
}
-/**********************************************************************
-Compares NUL-terminated UTF-8 strings case insensitively. */
+/******************************************************************//**
+Compares NUL-terminated UTF-8 strings case insensitively.
+@return 0 if a=b, <0 if a<b, >1 if a>b */
extern "C" UNIV_INTERN
int
innobase_strcasecmp(
/*================*/
- /* out: 0 if a=b, <0 if a<b, >1 if a>b */
- const char* a, /* in: first string to compare */
- const char* b) /* in: second string to compare */
+ const char* a, /*!< in: first string to compare */
+ const char* b) /*!< in: second string to compare */
{
return(my_strcasecmp(system_charset_info, a, b));
}
-/**********************************************************************
+/******************************************************************//**
Makes all characters in a NUL-terminated UTF-8 string lower case. */
extern "C" UNIV_INTERN
void
innobase_casedn_str(
/*================*/
- char* a) /* in/out: string to put in lower case */
+ char* a) /*!< in/out: string to put in lower case */
{
my_casedn_str(system_charset_info, a);
}
-/**************************************************************************
-Determines the connection character set. */
+/**********************************************************************//**
+Determines the connection character set.
+@return connection character set */
extern "C" UNIV_INTERN
struct charset_info_st*
innobase_get_charset(
/*=================*/
- /* out: connection character set */
- void* mysql_thd) /* in: MySQL thread handle */
+ void* mysql_thd) /*!< in: MySQL thread handle */
{
return(thd_charset((THD*) mysql_thd));
}
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
-/***********************************************************************
+/*******************************************************************//**
Map an OS error to an errno value. The OS error number is stored in
_doserrno and the mapped value is stored in errno) */
extern "C"
void __cdecl
_dosmaperr(
- unsigned long); /* in: OS error value */
+ unsigned long); /*!< in: OS error value */
-/*************************************************************************
-Creates a temporary file. */
+/*********************************************************************//**
+Creates a temporary file.
+@return temporary file descriptor, or < 0 on error */
extern "C" UNIV_INTERN
int
innobase_mysql_tmpfile(void)
/*========================*/
- /* out: temporary file descriptor, or < 0 on error */
{
int fd; /* handle of opened file */
HANDLE osfh; /* OS handle of opened file */
@@ -1129,13 +1144,13 @@ innobase_mysql_tmpfile(void)
DBUG_RETURN(fd);
}
#else
-/*************************************************************************
-Creates a temporary file. */
+/*********************************************************************//**
+Creates a temporary file.
+@return temporary file descriptor, or < 0 on error */
extern "C" UNIV_INTERN
int
innobase_mysql_tmpfile(void)
/*========================*/
- /* out: temporary file descriptor, or < 0 on error */
{
int fd2 = -1;
File fd = mysql_tmpfile("ib");
@@ -1162,46 +1177,47 @@ innobase_mysql_tmpfile(void)
}
#endif /* defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) */
-/*************************************************************************
-Wrapper around MySQL's copy_and_convert function, see it for
-documentation. */
+/*********************************************************************//**
+Wrapper around MySQL's copy_and_convert function.
+@return number of bytes copied to 'to' */
extern "C" UNIV_INTERN
ulint
innobase_convert_string(
/*====================*/
- void* to,
- ulint to_length,
- CHARSET_INFO* to_cs,
- const void* from,
- ulint from_length,
- CHARSET_INFO* from_cs,
- uint* errors)
+ void* to, /*!< out: converted string */
+ ulint to_length, /*!< in: number of bytes reserved
+ for the converted string */
+ CHARSET_INFO* to_cs, /*!< in: character set to convert to */
+ const void* from, /*!< in: string to convert */
+ ulint from_length, /*!< in: number of bytes to convert */
+ CHARSET_INFO* from_cs, /*!< in: character set to convert from */
+ uint* errors) /*!< out: number of errors encountered
+ during the conversion */
{
return(copy_and_convert((char*)to, (uint32) to_length, to_cs,
(const char*)from, (uint32) from_length, from_cs,
errors));
}
-/***********************************************************************
+/*******************************************************************//**
Formats the raw data in "data" (in InnoDB on-disk format) that is of
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "charset_coll" and writes
the result to "buf". The result is converted to "system_charset_info".
Not more than "buf_size" bytes are written to "buf".
-The result is always '\0'-terminated (provided buf_size > 0) and the
+The result is always NUL-terminated (provided buf_size > 0) and the
number of bytes that were written to "buf" is returned (including the
-terminating '\0'). */
+terminating NUL).
+@return number of bytes that were written */
extern "C" UNIV_INTERN
ulint
innobase_raw_format(
/*================*/
- /* out: number of bytes
- that were written */
- const char* data, /* in: raw data */
- ulint data_len, /* in: raw data length
+ const char* data, /*!< in: raw data */
+ ulint data_len, /*!< in: raw data length
in bytes */
- ulint charset_coll, /* in: charset collation */
- char* buf, /* out: output buffer */
- ulint buf_size) /* in: output buffer size
+ ulint charset_coll, /*!< in: charset collation */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size) /*!< in: output buffer size
in bytes */
{
/* XXX we use a hard limit instead of allocating
@@ -1221,7 +1237,7 @@ innobase_raw_format(
return(ut_str_sql_format(buf_tmp, buf_tmp_used, buf, buf_size));
}
-/*************************************************************************
+/*********************************************************************//**
Compute the next autoinc value.
For MySQL replication the autoincrement values can be partitioned among
@@ -1237,16 +1253,16 @@ values we want to reserve for multi-value inserts e.g.,
innobase_next_autoinc() will be called with increment set to
n * 3 where autoinc_lock_mode != TRADITIONAL because we want
-to reserve 3 values for the multi-value INSERT above. */
+to reserve 3 values for the multi-value INSERT above.
+@return the next value */
static
ulonglong
innobase_next_autoinc(
/*==================*/
- /* out: the next value */
- ulonglong current, /* in: Current value */
- ulonglong increment, /* in: increment current by */
- ulonglong offset, /* in: AUTOINC offset */
- ulonglong max_value) /* in: max value for type */
+ ulonglong current, /*!< in: Current value */
+ ulonglong increment, /*!< in: increment current by */
+ ulonglong offset, /*!< in: AUTOINC offset */
+ ulonglong max_value) /*!< in: max value for type */
{
ulonglong next_value;
@@ -1304,14 +1320,14 @@ innobase_next_autoinc(
return(next_value);
}
-/*************************************************************************
+/*********************************************************************//**
Initializes some fields in an InnoDB transaction object. */
static
void
innobase_trx_init(
/*==============*/
- THD* thd, /* in: user thread handle */
- trx_t* trx) /* in/out: InnoDB transaction handle */
+ THD* thd, /*!< in: user thread handle */
+ trx_t* trx) /*!< in/out: InnoDB transaction handle */
{
DBUG_ENTER("innobase_trx_init");
DBUG_ASSERT(EQ_CURRENT_THD(thd));
@@ -1326,14 +1342,14 @@ innobase_trx_init(
DBUG_VOID_RETURN;
}
-/*************************************************************************
-Allocates an InnoDB transaction for a MySQL handler object. */
+/*********************************************************************//**
+Allocates an InnoDB transaction for a MySQL handler object.
+@return InnoDB transaction handle */
extern "C" UNIV_INTERN
trx_t*
innobase_trx_allocate(
/*==================*/
- /* out: InnoDB transaction handle */
- THD* thd) /* in: user thread handle */
+ THD* thd) /*!< in: user thread handle */
{
trx_t* trx;
@@ -1351,16 +1367,16 @@ innobase_trx_allocate(
DBUG_RETURN(trx);
}
-/*************************************************************************
+/*********************************************************************//**
Gets the InnoDB transaction handle for a MySQL handler object, creates
an InnoDB transaction struct if the corresponding MySQL thread struct still
-lacks one. */
+lacks one.
+@return InnoDB transaction handle */
static
trx_t*
check_trx_exists(
/*=============*/
- /* out: InnoDB transaction handle */
- THD* thd) /* in: user thread handle */
+ THD* thd) /*!< in: user thread handle */
{
trx_t*& trx = thd_to_trx(thd);
@@ -1379,7 +1395,7 @@ check_trx_exists(
}
-/*************************************************************************
+/*********************************************************************//**
Construct ha_innobase handler. */
UNIV_INTERN
ha_innobase::ha_innobase(handlerton *hton, TABLE_SHARE *table_arg)
@@ -1397,14 +1413,14 @@ ha_innobase::ha_innobase(handlerton *hton, TABLE_SHARE *table_arg)
num_write_row(0)
{}
-/*************************************************************************
+/*********************************************************************//**
Destruct ha_innobase handler. */
UNIV_INTERN
ha_innobase::~ha_innobase()
{
}
-/*************************************************************************
+/*********************************************************************//**
Updates the user_thd field in a handle and also allocates a new InnoDB
transaction handle if needed, and updates the transaction fields in the
prebuilt struct. */
@@ -1412,7 +1428,7 @@ UNIV_INTERN inline
void
ha_innobase::update_thd(
/*====================*/
- THD* thd) /* in: thd to use the handle */
+ THD* thd) /*!< in: thd to use the handle */
{
trx_t* trx;
@@ -1426,7 +1442,7 @@ ha_innobase::update_thd(
user_thd = thd;
}
-/*************************************************************************
+/*********************************************************************//**
Updates the user_thd field in a handle and also allocates a new InnoDB
transaction handle if needed, and updates the transaction fields in the
prebuilt struct. */
@@ -1440,7 +1456,7 @@ ha_innobase::update_thd()
update_thd(thd);
}
-/*************************************************************************
+/*********************************************************************//**
Registers that InnoDB takes part in an SQL statement, so that MySQL knows to
roll back the statement if the statement results in an error. This MUST be
called for every SQL statement that may be rolled back by MySQL. Calling this
@@ -1449,15 +1465,15 @@ static inline
void
innobase_register_stmt(
/*===================*/
- handlerton* hton, /* in: Innobase hton */
- THD* thd) /* in: MySQL thd (connection) object */
+ handlerton* hton, /*!< in: Innobase hton */
+ THD* thd) /*!< in: MySQL thd (connection) object */
{
DBUG_ASSERT(hton == innodb_hton_ptr);
/* Register the statement */
trans_register_ha(thd, FALSE, hton);
}
-/*************************************************************************
+/*********************************************************************//**
Registers an InnoDB transaction in MySQL, so that the MySQL XA code knows
to call the InnoDB prepare and commit, or rollback for the transaction. This
MUST be called for every transaction for which the user may call commit or
@@ -1468,8 +1484,8 @@ static inline
void
innobase_register_trx_and_stmt(
/*===========================*/
- handlerton *hton, /* in: Innobase handlerton */
- THD* thd) /* in: MySQL thd (connection) object */
+ handlerton *hton, /*!< in: Innobase handlerton */
+ THD* thd) /*!< in: MySQL thd (connection) object */
{
/* NOTE that actually innobase_register_stmt() registers also
the transaction in the AUTOCOMMIT=1 mode. */
@@ -1526,7 +1542,7 @@ AUTOCOMMIT==0 or we are inside BEGIN ... COMMIT. Thus transactions no longer
put restrictions on the use of the query cache.
*/
-/**********************************************************************
+/******************************************************************//**
The MySQL query cache uses this to check from InnoDB if the query cache at
the moment is allowed to operate on an InnoDB table. The SQL query must
be a non-locking SELECT.
@@ -1543,24 +1559,23 @@ at the start of a SELECT processing. Then the calling thread cannot be
holding any InnoDB semaphores. The calling thread is holding the
query cache mutex, and this function will reserver the InnoDB kernel mutex.
Thus, the 'rank' in sync0sync.h of the MySQL query cache mutex is above
-the InnoDB kernel mutex. */
+the InnoDB kernel mutex.
+@return TRUE if permitted, FALSE if not; note that the value FALSE
+does not mean we should invalidate the query cache: invalidation is
+called explicitly */
static
my_bool
innobase_query_caching_of_table_permitted(
/*======================================*/
- /* out: TRUE if permitted, FALSE if not;
- note that the value FALSE does not mean
- we should invalidate the query cache:
- invalidation is called explicitly */
- THD* thd, /* in: thd of the user who is trying to
+ THD* thd, /*!< in: thd of the user who is trying to
store a result to the query cache or
retrieve it */
- char* full_name, /* in: concatenation of database name,
- the null character '\0', and the table
+ char* full_name, /*!< in: concatenation of database name,
+ the null character NUL, and the table
name */
- uint full_name_len, /* in: length of the full name, i.e.
+ uint full_name_len, /*!< in: length of the full name, i.e.
len(dbname) + len(tablename) + 1 */
- ulonglong *unused) /* unused for this engine */
+ ulonglong *unused) /*!< unused for this engine */
{
ibool is_autocommit;
trx_t* trx;
@@ -1650,21 +1665,21 @@ innobase_query_caching_of_table_permitted(
return((my_bool)FALSE);
}
-/*********************************************************************
-Invalidates the MySQL query cache for the table.
-NOTE that the exact prototype of this function has to be in
-/xtradb/row/row0ins.c! */
+/*****************************************************************//**
+Invalidates the MySQL query cache for the table. */
extern "C" UNIV_INTERN
void
innobase_invalidate_query_cache(
/*============================*/
- trx_t* trx, /* in: transaction which modifies the table */
- char* full_name, /* in: concatenation of database name, null
- char '\0', table name, null char'\0';
- NOTE that in Windows this is always
- in LOWER CASE! */
- ulint full_name_len) /* in: full name length where also the null
- chars count */
+ trx_t* trx, /*!< in: transaction which
+ modifies the table */
+ const char* full_name, /*!< in: concatenation of
+ database name, null char NUL,
+ table name, null char NUL;
+ NOTE that in Windows this is
+ always in LOWER CASE! */
+ ulint full_name_len) /*!< in: full name length where
+ also the null chars count */
{
/* Note that the sync0sync.h rank of the query cache mutex is just
above the InnoDB kernel mutex. The caller of this function must not
@@ -1673,26 +1688,26 @@ innobase_invalidate_query_cache(
/* Argument TRUE below means we are using transactions */
#ifdef HAVE_QUERY_CACHE
mysql_query_cache_invalidate4((THD*) trx->mysql_thd,
- (const char*) full_name,
+ full_name,
(uint32) full_name_len,
TRUE);
#endif
}
-/*********************************************************************
+/*****************************************************************//**
Convert an SQL identifier to the MySQL system_charset_info (UTF-8)
-and quote it if needed. */
+and quote it if needed.
+@return pointer to the end of buf */
static
char*
innobase_convert_identifier(
/*========================*/
- /* out: pointer to the end of buf */
- char* buf, /* out: buffer for converted identifier */
- ulint buflen, /* in: length of buf, in bytes */
- const char* id, /* in: identifier to convert */
- ulint idlen, /* in: length of id, in bytes */
- void* thd, /* in: MySQL connection thread, or NULL */
- ibool file_id)/* in: TRUE=id is a table or database name;
+ char* buf, /*!< out: buffer for converted identifier */
+ ulint buflen, /*!< in: length of buf, in bytes */
+ const char* id, /*!< in: identifier to convert */
+ ulint idlen, /*!< in: length of id, in bytes */
+ void* thd, /*!< in: MySQL connection thread, or NULL */
+ ibool file_id)/*!< in: TRUE=id is a table or database name;
FALSE=id is an UTF-8 string */
{
char nz[NAME_LEN + 1];
@@ -1764,20 +1779,20 @@ innobase_convert_identifier(
return(buf);
}
-/*********************************************************************
+/*****************************************************************//**
Convert a table or index name to the MySQL system_charset_info (UTF-8)
-and quote it if needed. */
+and quote it if needed.
+@return pointer to the end of buf */
extern "C" UNIV_INTERN
char*
innobase_convert_name(
/*==================*/
- /* out: pointer to the end of buf */
- char* buf, /* out: buffer for converted identifier */
- ulint buflen, /* in: length of buf, in bytes */
- const char* id, /* in: identifier to convert */
- ulint idlen, /* in: length of id, in bytes */
- void* thd, /* in: MySQL connection thread, or NULL */
- ibool table_id)/* in: TRUE=id is a table or database name;
+ char* buf, /*!< out: buffer for converted identifier */
+ ulint buflen, /*!< in: length of buf, in bytes */
+ const char* id, /*!< in: identifier to convert */
+ ulint idlen, /*!< in: length of id, in bytes */
+ void* thd, /*!< in: MySQL connection thread, or NULL */
+ ibool table_id)/*!< in: TRUE=id is a table or database name;
FALSE=id is an index name */
{
char* s = buf;
@@ -1821,32 +1836,32 @@ no_db_name:
}
-/**************************************************************************
-Determines if the currently running transaction has been interrupted. */
+/**********************************************************************//**
+Determines if the currently running transaction has been interrupted.
+@return TRUE if interrupted */
extern "C" UNIV_INTERN
ibool
trx_is_interrupted(
/*===============*/
- /* out: TRUE if interrupted */
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
return(trx && trx->mysql_thd && thd_killed((THD*) trx->mysql_thd));
}
-/******************************************************************
+/**************************************************************//**
Resets some fields of a prebuilt struct. The template is used in fast
retrieval of just those column values MySQL needs in its processing. */
static
void
reset_template(
/*===========*/
- row_prebuilt_t* prebuilt) /* in/out: prebuilt struct */
+ row_prebuilt_t* prebuilt) /*!< in/out: prebuilt struct */
{
prebuilt->keep_other_fields_on_keyread = 0;
prebuilt->read_just_key = 0;
}
-/*********************************************************************
+/*****************************************************************//**
Call this when you have opened a new table handle in HANDLER, before you
call index_read_idx() etc. Actually, we can let the cursor stay open even
over a transaction commit! Then you should call this before every operation,
@@ -1908,16 +1923,16 @@ ha_innobase::init_table_handle_for_HANDLER(void)
reset_template(prebuilt);
}
-/*************************************************************************
-Opens an InnoDB database. */
+/*********************************************************************//**
+Opens an InnoDB database.
+@return 0 on success, error code on failure */
static
int
innobase_init(
/*==========*/
- /* out: 0 on success, error code on failure */
- void *p) /* in: InnoDB handlerton */
+ void *p) /*!< in: InnoDB handlerton */
{
- static char current_dir[3]; /* Set if using current lib */
+ static char current_dir[3]; /*!< Set if using current lib */
int err;
bool ret;
char *default_path;
@@ -1925,19 +1940,6 @@ innobase_init(
DBUG_ENTER("innobase_init");
handlerton *innobase_hton= (handlerton *)p;
-
-#ifdef MYSQL_DYNAMIC_PLUGIN
- if (!innodb_plugin_init()) {
- sql_print_error("InnoDB plugin init failed.");
- DBUG_RETURN(-1);
- }
-
- if (innodb_hton_ptr) {
- /* Patch the statically linked handlerton and variables */
- innobase_hton = innodb_hton_ptr;
- }
-#endif /* MYSQL_DYNAMIC_PLUGIN */
-
innodb_hton_ptr = innobase_hton;
innobase_hton->state = SHOW_OPTION_YES;
@@ -2235,6 +2237,27 @@ mem_free_and_error:
}
}
+ if (innobase_change_buffering) {
+ ulint use;
+
+ for (use = 0;
+ use < UT_ARR_SIZE(innobase_change_buffering_values);
+ use++) {
+ if (!innobase_strcasecmp(
+ innobase_change_buffering,
+ innobase_change_buffering_values[use])) {
+ ibuf_use = (ibuf_use_t) use;
+ goto innobase_change_buffering_inited_ok;
+ }
+ }
+
+ sql_print_error("InnoDB: invalid value "
+ "innodb_file_format_check=%s",
+ innobase_change_buffering);
+ goto mem_free_and_error;
+ }
+
+innobase_change_buffering_inited_ok:
ut_a((ulint) ibuf_use < UT_ARR_SIZE(innobase_change_buffering_values));
innobase_change_buffering = (char*)
innobase_change_buffering_values[ibuf_use];
@@ -2270,6 +2293,8 @@ mem_free_and_error:
srv_fast_recovery = (ibool) innobase_fast_recovery;
+ srv_use_purge_thread = (ibool) innobase_use_purge_thread;
+
srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
srv_use_checksums = (ibool) innobase_use_checksums;
@@ -2393,6 +2418,7 @@ skip_overwrite:
pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&analyze_mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&commit_cond, NULL);
innodb_inited= 1;
#ifdef MYSQL_DYNAMIC_PLUGIN
@@ -2410,13 +2436,16 @@ error:
DBUG_RETURN(TRUE);
}
-/***********************************************************************
-Closes an InnoDB database. */
+/*******************************************************************//**
+Closes an InnoDB database.
+@return TRUE if error */
static
int
-innobase_end(handlerton *hton, ha_panic_function type)
-/*==============*/
- /* out: TRUE if error */
+innobase_end(
+/*=========*/
+ handlerton* hton, /*!< in/out: InnoDB handlerton */
+ ha_panic_function type __attribute__((unused)))
+ /*!< in: ha_panic() parameter */
{
int err= 0;
@@ -2444,20 +2473,22 @@ innobase_end(handlerton *hton, ha_panic_function type)
pthread_mutex_destroy(&prepare_commit_mutex);
pthread_mutex_destroy(&commit_threads_m);
pthread_mutex_destroy(&commit_cond_m);
+ pthread_mutex_destroy(&analyze_mutex);
pthread_cond_destroy(&commit_cond);
}
DBUG_RETURN(err);
}
-/********************************************************************
+/****************************************************************//**
Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
-the logs, and the name of this function should be innobase_checkpoint. */
+the logs, and the name of this function should be innobase_checkpoint.
+@return TRUE if error */
static
bool
-innobase_flush_logs(handlerton *hton)
-/*=====================*/
- /* out: TRUE if error */
+innobase_flush_logs(
+/*================*/
+ handlerton* hton) /*!< in/out: InnoDB handlerton */
{
bool result = 0;
@@ -2469,7 +2500,7 @@ innobase_flush_logs(handlerton *hton)
DBUG_RETURN(result);
}
-/********************************************************************
+/****************************************************************//**
Return alter table flags supported in an InnoDB database. */
static
uint
@@ -2484,13 +2515,13 @@ innobase_alter_table_flags(
| HA_ONLINE_ADD_PK_INDEX_NO_WRITES);
}
-/*********************************************************************
+/*****************************************************************//**
Commits a transaction in an InnoDB database. */
static
void
innobase_commit_low(
/*================*/
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx) /*!< in: transaction handle */
{
if (trx->conc_state == TRX_NOT_STARTED) {
@@ -2522,18 +2553,18 @@ innobase_commit_low(
trx_commit_for_mysql(trx);
}
-/*********************************************************************
+/*****************************************************************//**
Creates an InnoDB transaction struct for the thd if it does not yet have one.
Starts a new InnoDB transaction if a transaction is not yet started. And
assigns a new snapshot for a consistent read if the transaction does not yet
-have one. */
+have one.
+@return 0 */
static
int
innobase_start_trx_and_assign_read_view(
/*====================================*/
- /* out: 0 */
- handlerton *hton, /* in: Innodb handlerton */
- THD* thd) /* in: MySQL thread handle of the user for whom
+ handlerton *hton, /*!< in: Innodb handlerton */
+ THD* thd) /*!< in: MySQL thread handle of the user for whom
the transaction should be committed */
{
trx_t* trx;
@@ -2569,18 +2600,18 @@ innobase_start_trx_and_assign_read_view(
DBUG_RETURN(0);
}
-/*********************************************************************
+/*****************************************************************//**
Commits a transaction in an InnoDB database or marks an SQL statement
-ended. */
+ended.
+@return 0 */
static
int
innobase_commit(
/*============*/
- /* out: 0 */
- handlerton *hton, /* in: Innodb handlerton */
- THD* thd, /* in: MySQL thread handle of the user for whom
+ handlerton *hton, /*!< in: Innodb handlerton */
+ THD* thd, /*!< in: MySQL thread handle of the user for whom
the transaction should be committed */
- bool all) /* in: TRUE - commit transaction
+ bool all) /*!< in: TRUE - commit transaction
FALSE - the current SQL statement ended */
{
trx_t* trx;
@@ -2648,7 +2679,12 @@ retry:
trx->mysql_log_file_name = mysql_bin_log_file_name();
trx->mysql_log_offset = (ib_int64_t) mysql_bin_log_file_pos();
+ /* Don't do write + flush right now. For group commit
+ to work we want to do the flush after releasing the
+ prepare_commit_mutex. */
+ trx->flush_log_later = TRUE;
innobase_commit_low(trx);
+ trx->flush_log_later = FALSE;
if (innobase_commit_concurrency > 0) {
pthread_mutex_lock(&commit_cond_m);
@@ -2662,6 +2698,8 @@ retry:
pthread_mutex_unlock(&prepare_commit_mutex);
}
+ /* Now do a write + flush of logs. */
+ trx_commit_complete_for_mysql(trx);
trx->active_trans = 0;
} else {
@@ -2695,17 +2733,17 @@ retry:
DBUG_RETURN(0);
}
-/*********************************************************************
-Rolls back a transaction or the latest SQL statement. */
+/*****************************************************************//**
+Rolls back a transaction or the latest SQL statement.
+@return 0 or error number */
static
int
innobase_rollback(
/*==============*/
- /* out: 0 or error number */
- handlerton *hton, /* in: Innodb handlerton */
- THD* thd, /* in: handle to the MySQL thread of the user
+ handlerton *hton, /*!< in: Innodb handlerton */
+ THD* thd, /*!< in: handle to the MySQL thread of the user
whose transaction should be rolled back */
- bool all) /* in: TRUE - commit transaction
+ bool all) /*!< in: TRUE - commit transaction
FALSE - the current SQL statement ended */
{
int error = 0;
@@ -2741,14 +2779,14 @@ innobase_rollback(
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
}
-/*********************************************************************
-Rolls back a transaction */
+/*****************************************************************//**
+Rolls back a transaction
+@return 0 or error number */
static
int
innobase_rollback_trx(
/*==================*/
- /* out: 0 or error number */
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
int error = 0;
@@ -2772,18 +2810,18 @@ innobase_rollback_trx(
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
}
-/*********************************************************************
-Rolls back a transaction to a savepoint. */
+/*****************************************************************//**
+Rolls back a transaction to a savepoint.
+@return 0 if success, HA_ERR_NO_SAVEPOINT if no savepoint with the
+given name */
static
int
innobase_rollback_to_savepoint(
/*===========================*/
- /* out: 0 if success, HA_ERR_NO_SAVEPOINT if
- no savepoint with the given name */
- handlerton *hton, /* in: Innodb handlerton */
- THD* thd, /* in: handle to the MySQL thread of the user
+ handlerton *hton, /*!< in: Innodb handlerton */
+ THD* thd, /*!< in: handle to the MySQL thread of the user
whose transaction should be rolled back */
- void* savepoint) /* in: savepoint data */
+ void* savepoint) /*!< in: savepoint data */
{
ib_int64_t mysql_binlog_cache_pos;
int error = 0;
@@ -2810,18 +2848,18 @@ innobase_rollback_to_savepoint(
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
}
-/*********************************************************************
-Release transaction savepoint name. */
+/*****************************************************************//**
+Release transaction savepoint name.
+@return 0 if success, HA_ERR_NO_SAVEPOINT if no savepoint with the
+given name */
static
int
innobase_release_savepoint(
/*=======================*/
- /* out: 0 if success, HA_ERR_NO_SAVEPOINT if
- no savepoint with the given name */
- handlerton* hton, /* in: handlerton for Innodb */
- THD* thd, /* in: handle to the MySQL thread of the user
+ handlerton* hton, /*!< in: handlerton for Innodb */
+ THD* thd, /*!< in: handle to the MySQL thread of the user
whose transaction should be rolled back */
- void* savepoint) /* in: savepoint data */
+ void* savepoint) /*!< in: savepoint data */
{
int error = 0;
trx_t* trx;
@@ -2841,16 +2879,16 @@ innobase_release_savepoint(
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
}
-/*********************************************************************
-Sets a transaction savepoint. */
+/*****************************************************************//**
+Sets a transaction savepoint.
+@return always 0, that is, always succeeds */
static
int
innobase_savepoint(
/*===============*/
- /* out: always 0, that is, always succeeds */
- handlerton* hton, /* in: handle to the Innodb handlerton */
- THD* thd, /* in: handle to the MySQL thread */
- void* savepoint) /* in: savepoint data */
+ handlerton* hton, /*!< in: handle to the Innodb handlerton */
+ THD* thd, /*!< in: handle to the MySQL thread */
+ void* savepoint) /*!< in: savepoint data */
{
int error = 0;
trx_t* trx;
@@ -2888,15 +2926,15 @@ innobase_savepoint(
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
}
-/*********************************************************************
-Frees a possible InnoDB trx object associated with the current THD. */
+/*****************************************************************//**
+Frees a possible InnoDB trx object associated with the current THD.
+@return 0 or error number */
static
int
innobase_close_connection(
/*======================*/
- /* out: 0 or error number */
- handlerton* hton, /* in: innobase handlerton */
- THD* thd) /* in: handle to the MySQL thread of the user
+ handlerton* hton, /*!< in: innobase handlerton */
+ THD* thd) /*!< in: handle to the MySQL thread of the user
whose resources should be free'd */
{
trx_t* trx;
@@ -2933,21 +2971,18 @@ innobase_close_connection(
}
-/*****************************************************************************
+/*************************************************************************//**
** InnoDB database tables
*****************************************************************************/
-/********************************************************************
-Get the record format from the data dictionary. */
+/****************************************************************//**
+Get the record format from the data dictionary.
+@return one of ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT,
+ROW_TYPE_COMPRESSED, ROW_TYPE_DYNAMIC */
UNIV_INTERN
enum row_type
ha_innobase::get_row_type() const
/*=============================*/
- /* out: one of
- ROW_TYPE_REDUNDANT,
- ROW_TYPE_COMPACT,
- ROW_TYPE_COMPRESSED,
- ROW_TYPE_DYNAMIC */
{
if (prebuilt && prebuilt->table) {
const ulint flags = prebuilt->table->flags;
@@ -2978,11 +3013,13 @@ ha_innobase::get_row_type() const
-/********************************************************************
-Get the table flags to use for the statement. */
+/****************************************************************//**
+Get the table flags to use for the statement.
+@return table flags */
UNIV_INTERN
handler::Table_flags
ha_innobase::table_flags() const
+/*============================*/
{
/* Need to use tx_isolation here since table flags is (also)
called before prebuilt is inited. */
@@ -2992,58 +3029,81 @@ ha_innobase::table_flags() const
return int_table_flags | HA_BINLOG_STMT_CAPABLE;
}
-/********************************************************************
+/****************************************************************//**
Gives the file extension of an InnoDB single-table tablespace. */
static const char* ha_innobase_exts[] = {
".ibd",
NullS
};
+/****************************************************************//**
+Returns the table type (storage engine name).
+@return table type */
UNIV_INTERN
const char*
ha_innobase::table_type() const
/*===========================*/
- /* out: table type */
{
return(innobase_hton_name);
}
+/****************************************************************//**
+Returns the index type. */
UNIV_INTERN
const char*
-ha_innobase::index_type(uint)
-/*=========================*/
- /* out: index type */
+ha_innobase::index_type(
+/*====================*/
+ uint)
+ /*!< out: index type */
{
return("BTREE");
}
+/****************************************************************//**
+Returns the table file name extension.
+@return file extension string */
UNIV_INTERN
const char**
ha_innobase::bas_ext() const
/*========================*/
- /* out: file extension string */
{
return(ha_innobase_exts);
}
+/****************************************************************//**
+Returns the operations supported for indexes.
+@return flags of supported operations */
UNIV_INTERN
ulong
-ha_innobase::index_flags(uint, uint, bool) const
+ha_innobase::index_flags(
+/*=====================*/
+ uint,
+ uint,
+ bool)
+const
{
return(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER
| HA_READ_RANGE | HA_KEYREAD_ONLY);
}
+/****************************************************************//**
+Returns the maximum number of keys.
+@return MAX_KEY */
UNIV_INTERN
uint
ha_innobase::max_supported_keys() const
+/*===================================*/
{
return(MAX_KEY);
}
+/****************************************************************//**
+Returns the maximum key length.
+@return maximum supported key length, in bytes */
UNIV_INTERN
uint
ha_innobase::max_supported_key_length() const
+/*=========================================*/
{
/* An InnoDB page must store >= 2 keys; a secondary key record
must also contain the primary key value: max key length is
@@ -3053,6 +3113,9 @@ ha_innobase::max_supported_key_length() const
return(3500);
}
+/****************************************************************//**
+Returns the key map of keys that are usable for scanning.
+@return key_map_full */
UNIV_INTERN
const key_map*
ha_innobase::keys_to_use_for_scanning()
@@ -3060,6 +3123,9 @@ ha_innobase::keys_to_use_for_scanning()
return(&key_map_full);
}
+/****************************************************************//**
+Determines if table caching is supported.
+@return HA_CACHE_TBL_ASKTRANSACT */
UNIV_INTERN
uint8
ha_innobase::table_cache_type()
@@ -3067,6 +3133,9 @@ ha_innobase::table_cache_type()
return(HA_CACHE_TBL_ASKTRANSACT);
}
+/****************************************************************//**
+Determines if the primary key is clustered index.
+@return true */
UNIV_INTERN
bool
ha_innobase::primary_key_is_clustered()
@@ -3074,7 +3143,7 @@ ha_innobase::primary_key_is_clustered()
return(true);
}
-/*********************************************************************
+/*****************************************************************//**
Normalizes a table name string. A normalized name consists of the
database name catenated to '/' and table name. An example:
test/mytable. On Windows normalization puts both the database name and the
@@ -3083,9 +3152,9 @@ static
void
normalize_table_name(
/*=================*/
- char* norm_name, /* out: normalized name as a
+ char* norm_name, /*!< out: normalized name as a
null-terminated string */
- const char* name) /* in: table name string */
+ const char* name) /*!< in: table name string */
{
char* name_ptr;
char* db_ptr;
@@ -3120,9 +3189,10 @@ normalize_table_name(
#endif
}
-/************************************************************************
+/********************************************************************//**
Set the autoinc column max value. This should only be called once from
-ha_innobase::open(). Therefore there's no need for a covering lock. */
+ha_innobase::open(). Therefore there's no need for a covering lock.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
ha_innobase::innobase_initialize_autoinc()
@@ -3131,8 +3201,7 @@ ha_innobase::innobase_initialize_autoinc()
dict_index_t* index;
ulonglong auto_inc;
const char* col_name;
- ulint error = DB_SUCCESS;
- dict_table_t* innodb_table = prebuilt->table;
+ ulint error;
col_name = table->found_next_number_field->field_name;
index = innobase_get_index(table->s->next_number_index);
@@ -3140,35 +3209,53 @@ ha_innobase::innobase_initialize_autoinc()
/* Execute SELECT MAX(col_name) FROM TABLE; */
error = row_search_max_autoinc(index, col_name, &auto_inc);
- if (error == DB_SUCCESS) {
+ switch (error) {
+ case DB_SUCCESS:
- /* At the this stage we dont' know the increment
+ /* At the this stage we don't know the increment
or the offset, so use default inrement of 1. */
++auto_inc;
+ break;
- dict_table_autoinc_initialize(innodb_table, auto_inc);
-
- } else {
+ case DB_RECORD_NOT_FOUND:
ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Error: (%lu) Couldn't read "
- "the MAX(%s) autoinc value from the "
- "index (%s).\n", error, col_name, index->name);
+ fprintf(stderr, " InnoDB: MySQL and InnoDB data "
+ "dictionaries are out of sync.\n"
+ "InnoDB: Unable to find the AUTOINC column %s in the "
+ "InnoDB table %s.\n"
+ "InnoDB: We set the next AUTOINC column value to the "
+ "maximum possible value,\n"
+ "InnoDB: in effect disabling the AUTOINC next value "
+ "generation.\n"
+ "InnoDB: You can either set the next AUTOINC value "
+ "explicitly using ALTER TABLE\n"
+ "InnoDB: or fix the data dictionary by recreating "
+ "the table.\n",
+ col_name, index->table->name);
+
+ auto_inc = 0xFFFFFFFFFFFFFFFFULL;
+ break;
+
+ default:
+ return(error);
}
- return(error);
+ dict_table_autoinc_initialize(prebuilt->table, auto_inc);
+
+ return(DB_SUCCESS);
}
-/*********************************************************************
+/*****************************************************************//**
Creates and opens a handle to a table which already exists in an InnoDB
-database. */
+database.
+@return 1 if error, 0 if success */
UNIV_INTERN
int
ha_innobase::open(
/*==============*/
- /* out: 1 if error, 0 if success */
- const char* name, /* in: table name */
- int mode, /* in: not used */
- uint test_if_locked) /* in: not used */
+ const char* name, /*!< in: table name */
+ int mode, /*!< in: not used */
+ uint test_if_locked) /*!< in: not used */
{
dict_table_t* ib_table;
char norm_name[1000];
@@ -3251,7 +3338,7 @@ retry:
"or, the table contains indexes that this "
"version of the engine\n"
"doesn't support.\n"
- "See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
+ "See " REFMAN "innodb-troubleshooting.html\n"
"how you can resolve the problem.\n",
norm_name);
free_share(share);
@@ -3267,7 +3354,7 @@ retry:
"Have you deleted the .ibd file from the "
"database directory under\nthe MySQL datadir, "
"or have you used DISCARD TABLESPACE?\n"
- "See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
+ "See " REFMAN "innodb-troubleshooting.html\n"
"how you can resolve the problem.\n",
norm_name);
free_share(share);
@@ -3373,7 +3460,6 @@ retry:
if (dict_table_autoinc_read(prebuilt->table) == 0) {
error = innobase_initialize_autoinc();
- /* Should always succeed! */
ut_a(error == DB_SUCCESS);
}
@@ -3390,13 +3476,13 @@ ha_innobase::max_supported_key_part_length() const
return(DICT_MAX_INDEX_COL_LEN - 1);
}
-/**********************************************************************
-Closes a handle to an InnoDB table. */
+/******************************************************************//**
+Closes a handle to an InnoDB table.
+@return 0 */
UNIV_INTERN
int
ha_innobase::close(void)
/*====================*/
- /* out: 0 */
{
THD* thd;
@@ -3422,30 +3508,30 @@ ha_innobase::close(void)
/* The following accessor functions should really be inside MySQL code! */
-/******************************************************************
-Gets field offset for a field in a table. */
+/**************************************************************//**
+Gets field offset for a field in a table.
+@return offset */
static inline
uint
get_field_offset(
/*=============*/
- /* out: offset */
- TABLE* table, /* in: MySQL table object */
- Field* field) /* in: MySQL field object */
+ TABLE* table, /*!< in: MySQL table object */
+ Field* field) /*!< in: MySQL field object */
{
return((uint) (field->ptr - table->record[0]));
}
-/******************************************************************
+/**************************************************************//**
Checks if a field in a record is SQL NULL. Uses the record format
-information in table to track the null bit in record. */
+information in table to track the null bit in record.
+@return 1 if NULL, 0 otherwise */
static inline
uint
field_in_record_is_null(
/*====================*/
- /* out: 1 if NULL, 0 otherwise */
- TABLE* table, /* in: MySQL table object */
- Field* field, /* in: MySQL field object */
- char* record) /* in: a row in MySQL format */
+ TABLE* table, /*!< in: MySQL table object */
+ Field* field, /*!< in: MySQL field object */
+ char* record) /*!< in: a row in MySQL format */
{
int null_offset;
@@ -3465,16 +3551,16 @@ field_in_record_is_null(
return(0);
}
-/******************************************************************
+/**************************************************************//**
Sets a field in a record to SQL NULL. Uses the record format
information in table to track the null bit in record. */
static inline
void
set_field_in_record_to_null(
/*========================*/
- TABLE* table, /* in: MySQL table object */
- Field* field, /* in: MySQL field object */
- char* record) /* in: a row in MySQL format */
+ TABLE* table, /*!< in: MySQL table object */
+ Field* field, /*!< in: MySQL field object */
+ char* record) /*!< in: a row in MySQL format */
{
int null_offset;
@@ -3484,24 +3570,23 @@ set_field_in_record_to_null(
record[null_offset] = record[null_offset] | field->null_bit;
}
-/*****************************************************************
+/*************************************************************//**
InnoDB uses this function to compare two data fields for which the data type
is such that we must use MySQL code to compare them. NOTE that the prototype
of this function is in rem0cmp.c in InnoDB source code! If you change this
-function, remember to update the prototype there! */
+function, remember to update the prototype there!
+@return 1, 0, -1, if a is greater, equal, less than b, respectively */
extern "C" UNIV_INTERN
int
innobase_mysql_cmp(
/*===============*/
- /* out: 1, 0, -1, if a is greater,
- equal, less than b, respectively */
- int mysql_type, /* in: MySQL type */
- uint charset_number, /* in: number of the charset */
- const unsigned char* a, /* in: data field */
- unsigned int a_length, /* in: data field length,
+ int mysql_type, /*!< in: MySQL type */
+ uint charset_number, /*!< in: number of the charset */
+ const unsigned char* a, /*!< in: data field */
+ unsigned int a_length, /*!< in: data field length,
not UNIV_SQL_NULL */
- const unsigned char* b, /* in: data field */
- unsigned int b_length) /* in: data field length,
+ const unsigned char* b, /*!< in: data field */
+ unsigned int b_length) /*!< in: data field length,
not UNIV_SQL_NULL */
{
CHARSET_INFO* charset;
@@ -3566,22 +3651,21 @@ innobase_mysql_cmp(
return(0);
}
-/******************************************************************
+/**************************************************************//**
Converts a MySQL type to an InnoDB type. Note that this function returns
the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
-VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'. */
+VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'.
+@return DATA_BINARY, DATA_VARCHAR, ... */
extern "C" UNIV_INTERN
ulint
get_innobase_type_from_mysql_type(
/*==============================*/
- /* out: DATA_BINARY,
- DATA_VARCHAR, ... */
- ulint* unsigned_flag, /* out: DATA_UNSIGNED if an
+ ulint* unsigned_flag, /*!< out: DATA_UNSIGNED if an
'unsigned type';
at least ENUM and SET,
and unsigned integer
types are 'unsigned types' */
- const void* f) /* in: MySQL Field */
+ const void* f) /*!< in: MySQL Field */
{
const class Field* field = reinterpret_cast<const class Field*>(f);
@@ -3674,15 +3758,15 @@ get_innobase_type_from_mysql_type(
return(0);
}
-/***********************************************************************
+/*******************************************************************//**
Writes an unsigned integer value < 64k to 2 bytes, in the little-endian
storage format. */
static inline
void
innobase_write_to_2_little_endian(
/*==============================*/
- byte* buf, /* in: where to store */
- ulint val) /* in: value to write, must be < 64k */
+ byte* buf, /*!< in: where to store */
+ ulint val) /*!< in: value to write, must be < 64k */
{
ut_a(val < 256 * 256);
@@ -3690,31 +3774,31 @@ innobase_write_to_2_little_endian(
buf[1] = (byte)(val / 256);
}
-/***********************************************************************
+/*******************************************************************//**
Reads an unsigned integer value < 64k from 2 bytes, in the little-endian
-storage format. */
+storage format.
+@return value */
static inline
uint
innobase_read_from_2_little_endian(
/*===============================*/
- /* out: value */
- const uchar* buf) /* in: from where to read */
+ const uchar* buf) /*!< in: from where to read */
{
return (uint) ((ulint)(buf[0]) + 256 * ((ulint)(buf[1])));
}
-/***********************************************************************
-Stores a key value for a row to a buffer. */
+/*******************************************************************//**
+Stores a key value for a row to a buffer.
+@return key value length as stored in buff */
UNIV_INTERN
uint
ha_innobase::store_key_val_for_row(
/*===============================*/
- /* out: key value length as stored in buff */
- uint keynr, /* in: key number */
- char* buff, /* in/out: buffer for the key value (in MySQL
+ uint keynr, /*!< in: key number */
+ char* buff, /*!< in/out: buffer for the key value (in MySQL
format) */
- uint buff_len,/* in: buffer length */
- const uchar* record)/* in: row in MySQL format */
+ uint buff_len,/*!< in: buffer length */
+ const uchar* record)/*!< in: row in MySQL format */
{
KEY* key_info = table->key_info + keynr;
KEY_PART_INFO* key_part = key_info->key_part;
@@ -3837,7 +3921,11 @@ ha_innobase::store_key_val_for_row(
} else if (mysql_type == MYSQL_TYPE_TINY_BLOB
|| mysql_type == MYSQL_TYPE_MEDIUM_BLOB
|| mysql_type == MYSQL_TYPE_BLOB
- || mysql_type == MYSQL_TYPE_LONG_BLOB) {
+ || mysql_type == MYSQL_TYPE_LONG_BLOB
+ /* MYSQL_TYPE_GEOMETRY data is treated
+ as BLOB data in innodb. */
+ || mysql_type == MYSQL_TYPE_GEOMETRY) {
+
CHARSET_INFO* cs;
ulint key_len;
@@ -3977,19 +4065,19 @@ ha_innobase::store_key_val_for_row(
DBUG_RETURN((uint)(buff - buff_start));
}
-/******************************************************************
+/**************************************************************//**
Builds a 'template' to the prebuilt struct. The template is used in fast
retrieval of just those column values MySQL needs in its processing. */
static
void
build_template(
/*===========*/
- row_prebuilt_t* prebuilt, /* in/out: prebuilt struct */
- THD* thd, /* in: current user thread, used
+ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct */
+ THD* thd, /*!< in: current user thread, used
only if templ_type is
ROW_MYSQL_REC_FIELDS */
- TABLE* table, /* in: MySQL table */
- uint templ_type) /* in: ROW_MYSQL_WHOLE_ROW or
+ TABLE* table, /*!< in: MySQL table */
+ uint templ_type) /*!< in: ROW_MYSQL_WHOLE_ROW or
ROW_MYSQL_REC_FIELDS */
{
dict_index_t* index;
@@ -4194,7 +4282,7 @@ skip_field:
}
}
-/************************************************************************
+/********************************************************************//**
Get the upper limit of the MySQL integral and floating-point type. */
UNIV_INTERN
ulonglong
@@ -4255,18 +4343,17 @@ ha_innobase::innobase_get_int_col_max_value(
return(max_value);
}
-/************************************************************************
+/********************************************************************//**
This special handling is really to overcome the limitations of MySQL's
binlogging. We need to eliminate the non-determinism that will arise in
INSERT ... SELECT type of statements, since MySQL binlog only stores the
min value of the autoinc interval. Once that is fixed we can get rid of
-the special lock handling.*/
+the special lock handling.
+@return DB_SUCCESS if all OK else error code */
UNIV_INTERN
ulint
ha_innobase::innobase_lock_autoinc(void)
/*====================================*/
- /* out: DB_SUCCESS if all OK else
- error code */
{
ulint error = DB_SUCCESS;
@@ -4316,15 +4403,14 @@ ha_innobase::innobase_lock_autoinc(void)
return(ulong(error));
}
-/************************************************************************
-Reset the autoinc value in the table.*/
+/********************************************************************//**
+Reset the autoinc value in the table.
+@return DB_SUCCESS if all went well else error code */
UNIV_INTERN
ulint
ha_innobase::innobase_reset_autoinc(
/*================================*/
- /* out: DB_SUCCESS if all went well
- else error code */
- ulonglong autoinc) /* in: value to store */
+ ulonglong autoinc) /*!< in: value to store */
{
ulint error;
@@ -4340,16 +4426,15 @@ ha_innobase::innobase_reset_autoinc(
return(ulong(error));
}
-/************************************************************************
+/********************************************************************//**
Store the autoinc value in the table. The autoinc value is only set if
-it's greater than the existing autoinc value in the table.*/
+it's greater than the existing autoinc value in the table.
+@return DB_SUCCESS if all went well else error code */
UNIV_INTERN
ulint
ha_innobase::innobase_set_max_autoinc(
/*==================================*/
- /* out: DB_SUCCES if all went well
- else error code */
- ulonglong auto_inc) /* in: value to store */
+ ulonglong auto_inc) /*!< in: value to store */
{
ulint error;
@@ -4365,15 +4450,15 @@ ha_innobase::innobase_set_max_autoinc(
return(ulong(error));
}
-/************************************************************************
+/********************************************************************//**
Stores a row in an InnoDB database, to the table specified in this
-handle. */
+handle.
+@return error code */
UNIV_INTERN
int
ha_innobase::write_row(
/*===================*/
- /* out: error code */
- uchar* record) /* in: a row in MySQL format */
+ uchar* record) /*!< in: a row in MySQL format */
{
ulint error = 0;
int error_result= 0;
@@ -4605,23 +4690,23 @@ func_exit:
DBUG_RETURN(error_result);
}
-/**************************************************************************
+/**********************************************************************//**
Checks which fields have changed in a row and stores information
-of them to an update vector. */
+of them to an update vector.
+@return error number or 0 */
static
int
calc_row_difference(
/*================*/
- /* out: error number or 0 */
- upd_t* uvect, /* in/out: update vector */
- uchar* old_row, /* in: old row in MySQL format */
- uchar* new_row, /* in: new row in MySQL format */
- struct st_table* table, /* in: table in MySQL data
+ upd_t* uvect, /*!< in/out: update vector */
+ uchar* old_row, /*!< in: old row in MySQL format */
+ uchar* new_row, /*!< in: new row in MySQL format */
+ struct st_table* table, /*!< in: table in MySQL data
dictionary */
- uchar* upd_buff, /* in: buffer to use */
- ulint buff_len, /* in: buffer length */
- row_prebuilt_t* prebuilt, /* in: InnoDB prebuilt struct */
- THD* thd) /* in: user thread */
+ uchar* upd_buff, /*!< in: buffer to use */
+ ulint buff_len, /*!< in: buffer length */
+ row_prebuilt_t* prebuilt, /*!< in: InnoDB prebuilt struct */
+ THD* thd) /*!< in: user thread */
{
uchar* original_upd_buff = upd_buff;
Field* field;
@@ -4757,20 +4842,20 @@ calc_row_difference(
return(0);
}
-/**************************************************************************
+/**********************************************************************//**
Updates a row given as a parameter to a new value. Note that we are given
whole rows, not just the fields which are updated: this incurs some
overhead for CPU when we check which fields are actually updated.
TODO: currently InnoDB does not prevent the 'Halloween problem':
in a searched update a single row can get updated several times
-if its index columns are updated! */
+if its index columns are updated!
+@return error number or 0 */
UNIV_INTERN
int
ha_innobase::update_row(
/*====================*/
- /* out: error number or 0 */
- const uchar* old_row, /* in: old row in MySQL format */
- uchar* new_row) /* in: new row in MySQL format */
+ const uchar* old_row, /*!< in: old row in MySQL format */
+ uchar* new_row) /*!< in: new row in MySQL format */
{
upd_t* uvect;
int error = 0;
@@ -4870,14 +4955,14 @@ ha_innobase::update_row(
DBUG_RETURN(error);
}
-/**************************************************************************
-Deletes a row given as the parameter. */
+/**********************************************************************//**
+Deletes a row given as the parameter.
+@return error number or 0 */
UNIV_INTERN
int
ha_innobase::delete_row(
/*====================*/
- /* out: error number or 0 */
- const uchar* record) /* in: a row in MySQL format */
+ const uchar* record) /*!< in: a row in MySQL format */
{
int error = 0;
trx_t* trx = thd_to_trx(user_thd);
@@ -4913,7 +4998,7 @@ ha_innobase::delete_row(
DBUG_RETURN(error);
}
-/**************************************************************************
+/**********************************************************************//**
Removes a new lock set on a row, if it was not read optimistically. This can
be called after a row has been read in the processing of an UPDATE or a DELETE
query, if the option innodb_locks_unsafe_for_binlog is set. */
@@ -4981,55 +5066,24 @@ ha_innobase::try_semi_consistent_read(bool yes)
}
}
-#ifdef ROW_MERGE_IS_INDEX_USABLE
-/**********************************************************************
-Check if an index can be used by the optimizer. */
-UNIV_INTERN
-bool
-ha_innobase::is_index_available(
-/*============================*/
- /* out: true if available else false*/
- uint keynr) /* in: index number to check */
-{
- DBUG_ENTER("ha_innobase::is_index_available");
-
- if (table && keynr != MAX_KEY && table->s->keys > 0) {
- const dict_index_t* index;
- const KEY* key = table->key_info + keynr;
-
- ut_ad(user_thd == ha_thd());
- ut_a(prebuilt->trx == thd_to_trx(user_thd));
-
- index = dict_table_get_index_on_name(
- prebuilt->table, key->name);
-
- if (!row_merge_is_index_usable(prebuilt->trx, index)) {
-
- DBUG_RETURN(false);
- }
- }
-
- DBUG_RETURN(true);
-}
-#endif /* ROW_MERGE_IS_INDEX_USABLE */
-
-/**********************************************************************
-Initializes a handle to use an index. */
+/******************************************************************//**
+Initializes a handle to use an index.
+@return 0 or error number */
UNIV_INTERN
int
ha_innobase::index_init(
/*====================*/
- /* out: 0 or error number */
- uint keynr, /* in: key (index) number */
- bool sorted) /* in: 1 if result MUST be sorted according to index */
+ uint keynr, /*!< in: key (index) number */
+ bool sorted) /*!< in: 1 if result MUST be sorted according to index */
{
DBUG_ENTER("index_init");
DBUG_RETURN(change_active_index(keynr));
}
-/**********************************************************************
-Currently does nothing. */
+/******************************************************************//**
+Currently does nothing.
+@return 0 */
UNIV_INTERN
int
ha_innobase::index_end(void)
@@ -5041,7 +5095,7 @@ ha_innobase::index_end(void)
DBUG_RETURN(error);
}
-/*************************************************************************
+/*********************************************************************//**
Converts a search mode flag understood by MySQL to a flag understood
by InnoDB. */
static inline
@@ -5146,18 +5200,17 @@ overwrap, we use this test only as a secondary way of determining the
start of a new SQL statement. */
-/**************************************************************************
+/**********************************************************************//**
Positions an index cursor to the index specified in the handle. Fetches the
-row if any. */
+row if any.
+@return 0, HA_ERR_KEY_NOT_FOUND, or error number */
UNIV_INTERN
int
ha_innobase::index_read(
/*====================*/
- /* out: 0, HA_ERR_KEY_NOT_FOUND,
- or error number */
- uchar* buf, /* in/out: buffer for the returned
+ uchar* buf, /*!< in/out: buffer for the returned
row */
- const uchar* key_ptr, /* in: key value; if this is NULL
+ const uchar* key_ptr, /*!< in: key value; if this is NULL
we position the cursor at the
start or end of index; this can
also contain an InnoDB row id, in
@@ -5166,8 +5219,8 @@ ha_innobase::index_read(
also be a prefix of a full key value,
and the last column can be a prefix
of a full column */
- uint key_len,/* in: key value length */
- enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
+ uint key_len,/*!< in: key value length */
+ enum ha_rkey_function find_flag)/*!< in: search flags from my_base.h */
{
ulint mode;
dict_index_t* index;
@@ -5262,32 +5315,31 @@ ha_innobase::index_read(
DBUG_RETURN(error);
}
-/***********************************************************************
+/*******************************************************************//**
The following functions works like index_read, but it find the last
-row with the current key value or prefix. */
+row with the current key value or prefix.
+@return 0, HA_ERR_KEY_NOT_FOUND, or an error code */
UNIV_INTERN
int
ha_innobase::index_read_last(
/*=========================*/
- /* out: 0, HA_ERR_KEY_NOT_FOUND, or an
- error code */
- uchar* buf, /* out: fetched row */
- const uchar* key_ptr,/* in: key value, or a prefix of a full
+ uchar* buf, /*!< out: fetched row */
+ const uchar* key_ptr,/*!< in: key value, or a prefix of a full
key value */
- uint key_len)/* in: length of the key val or prefix
+ uint key_len)/*!< in: length of the key val or prefix
in bytes */
{
return(index_read(buf, key_ptr, key_len, HA_READ_PREFIX_LAST));
}
-/************************************************************************
-Get the index for a handle. Does not change active index.*/
+/********************************************************************//**
+Get the index for a handle. Does not change active index.
+@return NULL or index instance. */
UNIV_INTERN
dict_index_t*
ha_innobase::innobase_get_index(
/*============================*/
- /* out: NULL or index instance. */
- uint keynr) /* in: use this index; MAX_KEY means always
+ uint keynr) /*!< in: use this index; MAX_KEY means always
clustered index, even if it was internally
generated by InnoDB */
{
@@ -5320,14 +5372,14 @@ ha_innobase::innobase_get_index(
DBUG_RETURN(index);
}
-/************************************************************************
-Changes the active index of a handle. */
+/********************************************************************//**
+Changes the active index of a handle.
+@return 0 or error code */
UNIV_INTERN
int
ha_innobase::change_active_index(
/*=============================*/
- /* out: 0 or error code */
- uint keynr) /* in: use this index; MAX_KEY means always clustered
+ uint keynr) /*!< in: use this index; MAX_KEY means always clustered
index, even if it was internally generated by
InnoDB */
{
@@ -5346,6 +5398,18 @@ ha_innobase::change_active_index(
DBUG_RETURN(1);
}
+ prebuilt->index_usable = row_merge_is_index_usable(prebuilt->trx,
+ prebuilt->index);
+
+ if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
+ sql_print_warning("InnoDB: insufficient history for index %u",
+ keynr);
+ /* The caller seems to ignore this. Thus, we must check
+ this again in row_search_for_mysql(). */
+ DBUG_RETURN(convert_error_code_to_mysql(DB_MISSING_HISTORY,
+ 0, NULL));
+ }
+
ut_a(prebuilt->search_tuple != 0);
dtuple_set_n_fields(prebuilt->search_tuple, prebuilt->index->n_fields);
@@ -5364,23 +5428,23 @@ ha_innobase::change_active_index(
DBUG_RETURN(0);
}
-/**************************************************************************
+/**********************************************************************//**
Positions an index cursor to the index specified in keynr. Fetches the
-row if any. */
-/* ??? This is only used to read whole keys ??? */
+row if any.
+??? This is only used to read whole keys ???
+@return error number or 0 */
UNIV_INTERN
int
ha_innobase::index_read_idx(
/*========================*/
- /* out: error number or 0 */
- uchar* buf, /* in/out: buffer for the returned
+ uchar* buf, /*!< in/out: buffer for the returned
row */
- uint keynr, /* in: use this index */
- const uchar* key, /* in: key value; if this is NULL
+ uint keynr, /*!< in: use this index */
+ const uchar* key, /*!< in: key value; if this is NULL
we position the cursor at the
start or end of index */
- uint key_len, /* in: key value length */
- enum ha_rkey_function find_flag)/* in: search flags from my_base.h */
+ uint key_len, /*!< in: key value length */
+ enum ha_rkey_function find_flag)/*!< in: search flags from my_base.h */
{
if (change_active_index(keynr)) {
@@ -5390,19 +5454,18 @@ ha_innobase::index_read_idx(
return(index_read(buf, key, key_len, find_flag));
}
-/***************************************************************************
+/***********************************************************************//**
Reads the next or previous row from a cursor, which must have previously been
-positioned using index_read. */
+positioned using index_read.
+@return 0, HA_ERR_END_OF_FILE, or error number */
UNIV_INTERN
int
ha_innobase::general_fetch(
/*=======================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error
- number */
- uchar* buf, /* in/out: buffer for next row in MySQL
+ uchar* buf, /*!< in/out: buffer for next row in MySQL
format */
- uint direction, /* in: ROW_SEL_NEXT or ROW_SEL_PREV */
- uint match_mode) /* in: 0, ROW_SEL_EXACT, or
+ uint direction, /*!< in: ROW_SEL_NEXT or ROW_SEL_PREV */
+ uint match_mode) /*!< in: 0, ROW_SEL_EXACT, or
ROW_SEL_EXACT_PREFIX */
{
ulint ret;
@@ -5442,16 +5505,15 @@ ha_innobase::general_fetch(
DBUG_RETURN(error);
}
-/***************************************************************************
+/***********************************************************************//**
Reads the next row from a cursor, which must have previously been
-positioned using index_read. */
+positioned using index_read.
+@return 0, HA_ERR_END_OF_FILE, or error number */
UNIV_INTERN
int
ha_innobase::index_next(
/*====================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error
- number */
- uchar* buf) /* in/out: buffer for next row in MySQL
+ uchar* buf) /*!< in/out: buffer for next row in MySQL
format */
{
ha_statistic_increment(&SSV::ha_read_next_count);
@@ -5459,47 +5521,46 @@ ha_innobase::index_next(
return(general_fetch(buf, ROW_SEL_NEXT, 0));
}
-/***********************************************************************
-Reads the next row matching to the key value given as the parameter. */
+/*******************************************************************//**
+Reads the next row matching to the key value given as the parameter.
+@return 0, HA_ERR_END_OF_FILE, or error number */
UNIV_INTERN
int
ha_innobase::index_next_same(
/*=========================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error
- number */
- uchar* buf, /* in/out: buffer for the row */
- const uchar* key, /* in: key value */
- uint keylen) /* in: key value length */
+ uchar* buf, /*!< in/out: buffer for the row */
+ const uchar* key, /*!< in: key value */
+ uint keylen) /*!< in: key value length */
{
ha_statistic_increment(&SSV::ha_read_next_count);
return(general_fetch(buf, ROW_SEL_NEXT, last_match_mode));
}
-/***************************************************************************
+/***********************************************************************//**
Reads the previous row from a cursor, which must have previously been
-positioned using index_read. */
+positioned using index_read.
+@return 0, HA_ERR_END_OF_FILE, or error number */
UNIV_INTERN
int
ha_innobase::index_prev(
/*====================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error number */
- uchar* buf) /* in/out: buffer for previous row in MySQL format */
+ uchar* buf) /*!< in/out: buffer for previous row in MySQL format */
{
ha_statistic_increment(&SSV::ha_read_prev_count);
return(general_fetch(buf, ROW_SEL_PREV, 0));
}
-/************************************************************************
+/********************************************************************//**
Positions a cursor on the first record in an index and reads the
-corresponding row to buf. */
+corresponding row to buf.
+@return 0, HA_ERR_END_OF_FILE, or error code */
UNIV_INTERN
int
ha_innobase::index_first(
/*=====================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error code */
- uchar* buf) /* in/out: buffer for the row */
+ uchar* buf) /*!< in/out: buffer for the row */
{
int error;
@@ -5517,15 +5578,15 @@ ha_innobase::index_first(
DBUG_RETURN(error);
}
-/************************************************************************
+/********************************************************************//**
Positions a cursor on the last record in an index and reads the
-corresponding row to buf. */
+corresponding row to buf.
+@return 0, HA_ERR_END_OF_FILE, or error code */
UNIV_INTERN
int
ha_innobase::index_last(
/*====================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error code */
- uchar* buf) /* in/out: buffer for the row */
+ uchar* buf) /*!< in/out: buffer for the row */
{
int error;
@@ -5543,14 +5604,14 @@ ha_innobase::index_last(
DBUG_RETURN(error);
}
-/********************************************************************
-Initialize a table scan. */
+/****************************************************************//**
+Initialize a table scan.
+@return 0 or error number */
UNIV_INTERN
int
ha_innobase::rnd_init(
/*==================*/
- /* out: 0 or error number */
- bool scan) /* in: TRUE if table/index scan FALSE otherwise */
+ bool scan) /*!< in: TRUE if table/index scan FALSE otherwise */
{
int err;
@@ -5575,26 +5636,26 @@ ha_innobase::rnd_init(
return(err);
}
-/*********************************************************************
-Ends a table scan. */
+/*****************************************************************//**
+Ends a table scan.
+@return 0 or error number */
UNIV_INTERN
int
ha_innobase::rnd_end(void)
/*======================*/
- /* out: 0 or error number */
{
return(index_end());
}
-/*********************************************************************
+/*****************************************************************//**
Reads the next row in a table scan (also used to read the FIRST row
-in a table scan). */
+in a table scan).
+@return 0, HA_ERR_END_OF_FILE, or error number */
UNIV_INTERN
int
ha_innobase::rnd_next(
/*==================*/
- /* out: 0, HA_ERR_END_OF_FILE, or error number */
- uchar* buf) /* in/out: returns the row in this buffer,
+ uchar* buf) /*!< in/out: returns the row in this buffer,
in MySQL format */
{
int error;
@@ -5617,15 +5678,15 @@ ha_innobase::rnd_next(
DBUG_RETURN(error);
}
-/**************************************************************************
-Fetches a row from the table based on a row reference. */
+/**********************************************************************//**
+Fetches a row from the table based on a row reference.
+@return 0, HA_ERR_KEY_NOT_FOUND, or error code */
UNIV_INTERN
int
ha_innobase::rnd_pos(
/*=================*/
- /* out: 0, HA_ERR_KEY_NOT_FOUND, or error code */
- uchar* buf, /* in/out: buffer for the row */
- uchar* pos) /* in: primary key value of the row in the
+ uchar* buf, /*!< in/out: buffer for the row */
+ uchar* pos) /*!< in: primary key value of the row in the
MySQL format, or the row id if the clustered
index was internally generated by InnoDB; the
length of data in pos has to be ref_length */
@@ -5669,7 +5730,7 @@ ha_innobase::rnd_pos(
DBUG_RETURN(error);
}
-/*************************************************************************
+/*********************************************************************//**
Stores a reference to the current row to 'ref' field of the handle. Note
that in the case where we have generated the clustered index for the
table, the function parameter is illogical: we MUST ASSUME that 'record'
@@ -5681,7 +5742,7 @@ UNIV_INTERN
void
ha_innobase::position(
/*==================*/
- const uchar* record) /* in: row in MySQL format */
+ const uchar* record) /*!< in: row in MySQL format */
{
uint len;
@@ -5716,17 +5777,17 @@ See http://bugs.mysql.com/32710 for expl. why we choose PROCESS. */
(row_is_magic_monitor_table(table_name) \
&& check_global_access(thd, PROCESS_ACL))
-/*********************************************************************
+/*****************************************************************//**
Creates a table definition to an InnoDB database. */
static
int
create_table_def(
/*=============*/
- trx_t* trx, /* in: InnoDB transaction handle */
- TABLE* form, /* in: information on table
+ trx_t* trx, /*!< in: InnoDB transaction handle */
+ TABLE* form, /*!< in: information on table
columns and indexes */
- const char* table_name, /* in: table name */
- const char* path_of_temp_table,/* in: if this is a table explicitly
+ const char* table_name, /*!< in: table name */
+ const char* path_of_temp_table,/*!< in: if this is a table explicitly
created by the user with the
TEMPORARY keyword, then this
parameter is the dir path where the
@@ -5734,7 +5795,7 @@ create_table_def(
an .ibd file for it (no .ibd extension
in the path, though); otherwise this
is NULL */
- ulint flags) /* in: table flags */
+ ulint flags) /*!< in: table flags */
{
Field* field;
dict_table_t* table;
@@ -5829,6 +5890,28 @@ create_table_def(
}
}
+ /* First check whether the column to be added has a
+ system reserved name. */
+ if (dict_col_name_is_reserved(field->field_name)){
+ push_warning_printf(
+ (THD*) trx->mysql_thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_CANT_CREATE_TABLE,
+ "Error creating table '%s' with "
+ "column name '%s'. '%s' is a "
+ "reserved name. Please try to "
+ "re-create the table with a "
+ "different column name.",
+ table->name, (char*) field->field_name,
+ (char*) field->field_name);
+
+ dict_mem_table_free(table);
+ trx_commit_for_mysql(trx);
+
+ error = DB_ERROR;
+ goto error_ret;
+ }
+
dict_mem_table_add_col(table, table->heap,
(char*) field->field_name,
col_type,
@@ -5842,23 +5925,24 @@ create_table_def(
error = row_create_table_for_mysql(table, trx);
+error_ret:
error = convert_error_code_to_mysql(error, flags, NULL);
DBUG_RETURN(error);
}
-/*********************************************************************
+/*****************************************************************//**
Creates an index in an InnoDB database. */
static
int
create_index(
/*=========*/
- trx_t* trx, /* in: InnoDB transaction handle */
- TABLE* form, /* in: information on table
+ trx_t* trx, /*!< in: InnoDB transaction handle */
+ TABLE* form, /*!< in: information on table
columns and indexes */
- ulint flags, /* in: InnoDB table flags */
- const char* table_name, /* in: table name */
- uint key_num) /* in: index number */
+ ulint flags, /*!< in: InnoDB table flags */
+ const char* table_name, /*!< in: table name */
+ uint key_num) /*!< in: index number */
{
Field* field;
dict_index_t* index;
@@ -5880,6 +5964,9 @@ create_index(
n_fields = key->key_parts;
+ /* Assert that "GEN_CLUST_INDEX" cannot be used as non-primary index */
+ ut_a(innobase_strcasecmp(key->name, innobase_index_reserve_name) != 0);
+
ind_type = 0;
if (key_num == form->s->primary_key) {
@@ -5972,16 +6059,16 @@ create_index(
DBUG_RETURN(error);
}
-/*********************************************************************
+/*****************************************************************//**
Creates an index to an InnoDB table when the user has defined no
primary index. */
static
int
create_clustered_index_when_no_primary(
/*===================================*/
- trx_t* trx, /* in: InnoDB transaction handle */
- ulint flags, /* in: InnoDB table flags */
- const char* table_name) /* in: table name */
+ trx_t* trx, /*!< in: InnoDB transaction handle */
+ ulint flags, /*!< in: InnoDB table flags */
+ const char* table_name) /*!< in: table name */
{
dict_index_t* index;
int error;
@@ -5989,7 +6076,8 @@ create_clustered_index_when_no_primary(
/* We pass 0 as the space id, and determine at a lower level the space
id where to store the table */
- index = dict_mem_index_create(table_name, "GEN_CLUST_INDEX",
+ index = dict_mem_index_create(table_name,
+ innobase_index_reserve_name,
0, DICT_CLUSTERED, 0);
error = row_create_index_for_mysql(index, trx, NULL);
@@ -5999,20 +6087,20 @@ create_clustered_index_when_no_primary(
return(error);
}
-/*********************************************************************
+/*****************************************************************//**
Validates the create options. We may build on this function
in future. For now, it checks two specifiers:
KEY_BLOCK_SIZE and ROW_FORMAT
-If innodb_strict_mode is not set then this function is a no-op */
+If innodb_strict_mode is not set then this function is a no-op
+@return TRUE if valid. */
static
ibool
create_options_are_valid(
/*=====================*/
- /* out: TRUE if valid. */
- THD* thd, /* in: connection thread. */
- TABLE* form, /* in: information on table
+ THD* thd, /*!< in: connection thread. */
+ TABLE* form, /*!< in: information on table
columns and indexes */
- HA_CREATE_INFO* create_info) /* in: create info. */
+ HA_CREATE_INFO* create_info) /*!< in: create info. */
{
ibool kbs_specified = FALSE;
ibool ret = TRUE;
@@ -6165,13 +6253,13 @@ create_options_are_valid(
return(ret);
}
-/*********************************************************************
+/*****************************************************************//**
Update create_info. Used in SHOW CREATE TABLE et al. */
UNIV_INTERN
void
ha_innobase::update_create_info(
/*============================*/
- HA_CREATE_INFO* create_info) /* in/out: create info */
+ HA_CREATE_INFO* create_info) /*!< in/out: create info */
{
if (!(create_info->used_fields & HA_CREATE_USED_AUTO)) {
ha_innobase::info(HA_STATUS_AUTO);
@@ -6179,17 +6267,17 @@ ha_innobase::update_create_info(
}
}
-/*********************************************************************
-Creates a new table to an InnoDB database. */
+/*****************************************************************//**
+Creates a new table to an InnoDB database.
+@return error number */
UNIV_INTERN
int
ha_innobase::create(
/*================*/
- /* out: error number */
- const char* name, /* in: table name */
- TABLE* form, /* in: information on table
+ const char* name, /*!< in: table name */
+ TABLE* form, /*!< in: information on table
columns and indexes */
- HA_CREATE_INFO* create_info) /* in: more information of the
+ HA_CREATE_INFO* create_info) /*!< in: more information of the
created table, contains also the
create statement string */
{
@@ -6415,14 +6503,6 @@ ha_innobase::create(
flags = DICT_TF_COMPACT;
}
- error = create_table_def(trx, form, norm_name,
- create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
- flags);
-
- if (error) {
- goto cleanup;
- }
-
/* Look for a primary key */
primary_key_no= (form->s->primary_key != MAX_KEY ?
@@ -6432,7 +6512,23 @@ ha_innobase::create(
/* Our function row_get_mysql_key_number_for_index assumes
the primary key is always number 0, if it exists */
- DBUG_ASSERT(primary_key_no == -1 || primary_key_no == 0);
+ ut_a(primary_key_no == -1 || primary_key_no == 0);
+
+ /* Check for name conflicts (with reserved name) for
+ any user indices to be created. */
+ if (innobase_index_name_is_reserved(trx, form->key_info,
+ form->s->keys)) {
+ error = -1;
+ goto cleanup;
+ }
+
+ error = create_table_def(trx, form, norm_name,
+ create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
+ flags);
+
+ if (error) {
+ goto cleanup;
+ }
/* Create the keys */
@@ -6507,18 +6603,22 @@ ha_innobase::create(
setup at this stage and so we use thd. */
/* We need to copy the AUTOINC value from the old table if
- this is an ALTER TABLE. */
+ this is an ALTER TABLE or CREATE INDEX because CREATE INDEX
+ does a table copy too. */
if (((create_info->used_fields & HA_CREATE_USED_AUTO)
- || thd_sql_command(thd) == SQLCOM_ALTER_TABLE)
- && create_info->auto_increment_value != 0) {
-
- /* Query was ALTER TABLE...AUTO_INCREMENT = x; or
- CREATE TABLE ...AUTO_INCREMENT = x; Find out a table
- definition from the dictionary and get the current value
- of the auto increment field. Set a new value to the
- auto increment field if the value is greater than the
- maximum value in the column. */
+ || thd_sql_command(thd) == SQLCOM_ALTER_TABLE
+ || thd_sql_command(thd) == SQLCOM_CREATE_INDEX)
+ && create_info->auto_increment_value > 0) {
+
+ /* Query was one of :
+ CREATE TABLE ...AUTO_INCREMENT = x; or
+ ALTER TABLE...AUTO_INCREMENT = x; or
+ CREATE INDEX x on t(...);
+ Find out a table definition from the dictionary and get
+ the current value of the auto increment field. Set a new
+ value to the auto increment field if the value is greater
+ than the maximum value in the column. */
auto_inc_value = create_info->auto_increment_value;
@@ -6546,14 +6646,14 @@ cleanup:
DBUG_RETURN(error);
}
-/*********************************************************************
-Discards or imports an InnoDB tablespace. */
+/*****************************************************************//**
+Discards or imports an InnoDB tablespace.
+@return 0 == success, -1 == error */
UNIV_INTERN
int
ha_innobase::discard_or_import_tablespace(
/*======================================*/
- /* out: 0 == success, -1 == error */
- my_bool discard) /* in: TRUE if discard, else import */
+ my_bool discard) /*!< in: TRUE if discard, else import */
{
dict_table_t* dict_table;
trx_t* trx;
@@ -6579,13 +6679,13 @@ ha_innobase::discard_or_import_tablespace(
DBUG_RETURN(err);
}
-/*********************************************************************
-Deletes all rows of an InnoDB table. */
+/*****************************************************************//**
+Deletes all rows of an InnoDB table.
+@return error number */
UNIV_INTERN
int
ha_innobase::delete_all_rows(void)
/*==============================*/
- /* out: error number */
{
int error;
@@ -6618,18 +6718,18 @@ ha_innobase::delete_all_rows(void)
DBUG_RETURN(error);
}
-/*********************************************************************
+/*****************************************************************//**
Drops a table from an InnoDB database. Before calling this function,
MySQL calls innobase_commit to commit the transaction of the current user.
Then the current user cannot have locks set on the table. Drop table
operation inside InnoDB will remove all locks any user has on the table
-inside InnoDB. */
+inside InnoDB.
+@return error number */
UNIV_INTERN
int
ha_innobase::delete_table(
/*======================*/
- /* out: error number */
- const char* name) /* in: table name */
+ const char* name) /*!< in: table name */
{
ulint name_len;
int error;
@@ -6696,15 +6796,14 @@ ha_innobase::delete_table(
DBUG_RETURN(error);
}
-/*********************************************************************
+/*****************************************************************//**
Removes all tables in the named database inside InnoDB. */
static
void
innobase_drop_database(
/*===================*/
- /* out: error number */
- handlerton *hton, /* in: handlerton of Innodb */
- char* path) /* in: database path; inside InnoDB the name
+ handlerton *hton, /*!< in: handlerton of Innodb */
+ char* path) /*!< in: database path; inside InnoDB the name
of the last directory in the path is used as
the database name: for example, in 'mysql/data/test'
the database name is 'test' */
@@ -6773,18 +6872,18 @@ innobase_drop_database(
innobase_commit_low(trx);
trx_free_for_mysql(trx);
}
-/*************************************************************************
-Renames an InnoDB table. */
+/*********************************************************************//**
+Renames an InnoDB table.
+@return 0 or error code */
static
int
innobase_rename_table(
/*==================*/
- /* out: 0 or error code */
- trx_t* trx, /* in: transaction */
- const char* from, /* in: old name of the table */
- const char* to, /* in: new name of the table */
+ trx_t* trx, /*!< in: transaction */
+ const char* from, /*!< in: old name of the table */
+ const char* to, /*!< in: new name of the table */
ibool lock_and_commit)
- /* in: TRUE=lock data dictionary and commit */
+ /*!< in: TRUE=lock data dictionary and commit */
{
int error;
char* norm_to;
@@ -6840,15 +6939,15 @@ innobase_rename_table(
DBUG_RETURN(error);
}
-/*************************************************************************
-Renames an InnoDB table. */
+/*********************************************************************//**
+Renames an InnoDB table.
+@return 0 or error code */
UNIV_INTERN
int
ha_innobase::rename_table(
/*======================*/
- /* out: 0 or error code */
- const char* from, /* in: old name of the table */
- const char* to) /* in: new name of the table */
+ const char* from, /*!< in: old name of the table */
+ const char* to) /*!< in: new name of the table */
{
trx_t* trx;
int error;
@@ -6884,18 +6983,17 @@ ha_innobase::rename_table(
DBUG_RETURN(error);
}
-/*************************************************************************
-Estimates the number of index records in a range. */
+/*********************************************************************//**
+Estimates the number of index records in a range.
+@return estimated number of rows */
UNIV_INTERN
ha_rows
ha_innobase::records_in_range(
/*==========================*/
- /* out: estimated number of
- rows */
- uint keynr, /* in: index number */
- key_range *min_key, /* in: start key value of the
+ uint keynr, /*!< in: index number */
+ key_range *min_key, /*!< in: start key value of the
range, may also be 0 */
- key_range *max_key) /* in: range end key val, may
+ key_range *max_key) /*!< in: range end key val, may
also be 0 */
{
KEY* key;
@@ -6993,14 +7091,14 @@ ha_innobase::records_in_range(
DBUG_RETURN((ha_rows) n_rows);
}
-/*************************************************************************
+/*********************************************************************//**
Gives an UPPER BOUND to the number of rows in a table. This is used in
-filesort.cc. */
+filesort.cc.
+@return upper bound of rows */
UNIV_INTERN
ha_rows
ha_innobase::estimate_rows_upper_bound(void)
/*======================================*/
- /* out: upper bound of rows */
{
dict_index_t* index;
ulonglong estimate;
@@ -7043,15 +7141,15 @@ ha_innobase::estimate_rows_upper_bound(void)
DBUG_RETURN((ha_rows) estimate);
}
-/*************************************************************************
+/*********************************************************************//**
How many seeks it will take to read through the table. This is to be
comparable to the number returned by records_in_range so that we can
-decide if we should scan the table or use keys. */
+decide if we should scan the table or use keys.
+@return estimated time measured in disk seeks */
UNIV_INTERN
double
ha_innobase::scan_time()
/*====================*/
- /* out: estimated time measured in disk seeks */
{
/* Since MySQL seems to favor table scans too much over index
searches, we pretend that a sequential read takes the same time
@@ -7061,17 +7159,17 @@ ha_innobase::scan_time()
return((double) (prebuilt->table->stat_clustered_index_size));
}
-/**********************************************************************
+/******************************************************************//**
Calculate the time it takes to read a set of ranges through an index
-This enables us to optimise reads for clustered indexes. */
+This enables us to optimise reads for clustered indexes.
+@return estimated time measured in disk seeks */
UNIV_INTERN
double
ha_innobase::read_time(
/*===================*/
- /* out: estimated time measured in disk seeks */
- uint index, /* in: key number */
- uint ranges, /* in: how many ranges */
- ha_rows rows) /* in: estimated number of rows in the ranges */
+ uint index, /*!< in: key number */
+ uint ranges, /*!< in: how many ranges */
+ ha_rows rows) /*!< in: estimated number of rows in the ranges */
{
ha_rows total_rows;
double time_for_scan;
@@ -7099,14 +7197,14 @@ ha_innobase::read_time(
return(ranges + (double) rows / (double) total_rows * time_for_scan);
}
-/*************************************************************************
+/*********************************************************************//**
Returns statistics information of the table to the MySQL interpreter,
in various fields of the handle object. */
UNIV_INTERN
int
ha_innobase::info(
/*==============*/
- uint flag) /* in: what information MySQL requests */
+ uint flag) /*!< in: what information MySQL requests */
{
dict_table_t* ib_table;
dict_index_t* index;
@@ -7171,7 +7269,7 @@ ha_innobase::info(
nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
if (os_file_get_status(path,&stat_info)) {
- stats.create_time = stat_info.ctime;
+ stats.create_time = (ulong) stat_info.ctime;
}
}
@@ -7233,7 +7331,7 @@ ha_innobase::info(
We do not update delete_length if no locking is requested
so the "old" value can remain. delete_length is initialized
to 0 in the ha_statistics' constructor. */
- if (!(flag & HA_STATUS_NO_LOCK)) {
+ if (!(flag & HA_STATUS_NO_LOCK) && srv_stats_update_need_lock) {
/* lock the data dictionary to avoid races with
ibd_file_missing and tablespace_discarded */
@@ -7293,8 +7391,8 @@ ha_innobase::info(
".frm file. Have you mixed up "
".frm files from different "
"installations? See "
-"http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n",
-
+ REFMAN
+ "innodb-troubleshooting.html\n",
ib_table->name);
break;
}
@@ -7306,7 +7404,7 @@ ha_innobase::info(
"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
"statistics for %lu columns. Have you mixed up .frm files from different "
"installations? "
-"See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n",
+"See " REFMAN "innodb-troubleshooting.html\n",
index->name,
ib_table->name,
(unsigned long)
@@ -7367,48 +7465,53 @@ ha_innobase::info(
DBUG_RETURN(0);
}
-/**************************************************************************
+/**********************************************************************//**
Updates index cardinalities of the table, based on 8 random dives into
-each index tree. This does NOT calculate exact statistics on the table. */
+each index tree. This does NOT calculate exact statistics on the table.
+@return returns always 0 (success) */
UNIV_INTERN
int
ha_innobase::analyze(
/*=================*/
- /* out: returns always 0 (success) */
- THD* thd, /* in: connection thread handle */
- HA_CHECK_OPT* check_opt) /* in: currently ignored */
+ THD* thd, /*!< in: connection thread handle */
+ HA_CHECK_OPT* check_opt) /*!< in: currently ignored */
{
+ /* Serialize ANALYZE TABLE inside InnoDB, see
+ Bug#38996 Race condition in ANALYZE TABLE */
+ pthread_mutex_lock(&analyze_mutex);
+
/* Simply call ::info() with all the flags */
info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
+ pthread_mutex_unlock(&analyze_mutex);
+
return(0);
}
-/**************************************************************************
+/**********************************************************************//**
This is mapped to "ALTER TABLE tablename ENGINE=InnoDB", which rebuilds
the table in MySQL. */
UNIV_INTERN
int
ha_innobase::optimize(
/*==================*/
- THD* thd, /* in: connection thread handle */
- HA_CHECK_OPT* check_opt) /* in: currently ignored */
+ THD* thd, /*!< in: connection thread handle */
+ HA_CHECK_OPT* check_opt) /*!< in: currently ignored */
{
return(HA_ADMIN_TRY_ALTER);
}
-/***********************************************************************
+/*******************************************************************//**
Tries to check that an InnoDB table is not corrupted. If corruption is
noticed, prints to stderr information about it. In case of corruption
-may also assert a failure and crash the server. */
+may also assert a failure and crash the server.
+@return HA_ADMIN_CORRUPT or HA_ADMIN_OK */
UNIV_INTERN
int
ha_innobase::check(
/*===============*/
- /* out: HA_ADMIN_CORRUPT or
- HA_ADMIN_OK */
- THD* thd, /* in: user thread handle */
- HA_CHECK_OPT* check_opt) /* in: check options, currently
+ THD* thd, /*!< in: user thread handle */
+ HA_CHECK_OPT* check_opt) /*!< in: check options, currently
ignored */
{
ulint ret;
@@ -7434,17 +7537,16 @@ ha_innobase::check(
return(HA_ADMIN_CORRUPT);
}
-/*****************************************************************
+/*************************************************************//**
Adds information about free space in the InnoDB tablespace to a table comment
which is printed out when a user calls SHOW TABLE STATUS. Adds also info on
-foreign keys. */
+foreign keys.
+@return table comment + InnoDB free space + info on foreign keys */
UNIV_INTERN
char*
ha_innobase::update_table_comment(
/*==============================*/
- /* out: table comment + InnoDB free space +
- info on foreign keys */
- const char* comment)/* in: table comment defined by user */
+ const char* comment)/*!< in: table comment defined by user */
{
uint length = (uint) strlen(comment);
char* str;
@@ -7510,15 +7612,15 @@ ha_innobase::update_table_comment(
return(str ? str : (char*) comment);
}
-/***********************************************************************
-Gets the foreign key create info for a table stored in InnoDB. */
+/*******************************************************************//**
+Gets the foreign key create info for a table stored in InnoDB.
+@return own: character string in the form which can be inserted to the
+CREATE TABLE statement, MUST be freed with
+ha_innobase::free_foreign_key_create_info */
UNIV_INTERN
char*
ha_innobase::get_foreign_key_create_info(void)
/*==========================================*/
- /* out, own: character string in the form which
- can be inserted to the CREATE TABLE statement,
- MUST be freed with ::free_foreign_key_create_info */
{
char* str = 0;
long flen;
@@ -7703,10 +7805,11 @@ ha_innobase::get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
DBUG_RETURN(0);
}
-/*********************************************************************
+/*****************************************************************//**
Checks if ALTER TABLE may change the storage engine of the table.
Changing storage engines is not allowed for tables for which there
-are foreign key constraints (parent or child tables). */
+are foreign key constraints (parent or child tables).
+@return TRUE if can switch engines */
UNIV_INTERN
bool
ha_innobase::can_switch_engines(void)
@@ -7731,16 +7834,16 @@ ha_innobase::can_switch_engines(void)
DBUG_RETURN(can_switch);
}
-/***********************************************************************
+/*******************************************************************//**
Checks if a table is referenced by a foreign key. The MySQL manual states that
a REPLACE is either equivalent to an INSERT, or DELETE(s) + INSERT. Only a
delete is then allowed internally to resolve a duplicate key conflict in
-REPLACE, not an update. */
+REPLACE, not an update.
+@return > 0 if referenced by a FOREIGN KEY */
UNIV_INTERN
uint
ha_innobase::referenced_by_foreign_key(void)
/*========================================*/
- /* out: > 0 if referenced by a FOREIGN KEY */
{
if (dict_table_is_referenced_by_foreign_key(prebuilt->table)) {
@@ -7750,29 +7853,29 @@ ha_innobase::referenced_by_foreign_key(void)
return(0);
}
-/***********************************************************************
+/*******************************************************************//**
Frees the foreign key create info for a table stored in InnoDB, if it is
non-NULL. */
UNIV_INTERN
void
ha_innobase::free_foreign_key_create_info(
/*======================================*/
- char* str) /* in, own: create info string to free */
+ char* str) /*!< in, own: create info string to free */
{
if (str) {
my_free(str, MYF(0));
}
}
-/***********************************************************************
-Tells something additional to the handler about how to do things. */
+/*******************************************************************//**
+Tells something additional to the handler about how to do things.
+@return 0 or error number */
UNIV_INTERN
int
ha_innobase::extra(
/*===============*/
- /* out: 0 or error number */
enum ha_extra_function operation)
- /* in: HA_EXTRA_FLUSH or some other flag */
+ /*!< in: HA_EXTRA_FLUSH or some other flag */
{
/* Warning: since it is not sure that MySQL calls external_lock
before calling this function, the trx field in prebuilt can be
@@ -7842,7 +7945,7 @@ ha_innobase::reset()
return(0);
}
-/**********************************************************************
+/******************************************************************//**
MySQL calls this function at the start of each SQL statement inside LOCK
TABLES. Inside LOCK TABLES the ::external_lock method does not work to
mark SQL statement borders. Note also a special case: if a temporary table
@@ -7852,13 +7955,13 @@ MySQL-5.0 also calls this before each statement in an execution of a stored
procedure. To make the execution more deterministic for binlogging, MySQL-5.0
locks all tables involved in a stored procedure with full explicit table
locks (thd_in_lock_tables(thd) holds in store_lock()) before executing the
-procedure. */
+procedure.
+@return 0 or error code */
UNIV_INTERN
int
ha_innobase::start_stmt(
/*====================*/
- /* out: 0 or error code */
- THD* thd, /* in: handle to the user thread */
+ THD* thd, /*!< in: handle to the user thread */
thr_lock_type lock_type)
{
trx_t* trx;
@@ -7927,14 +8030,14 @@ ha_innobase::start_stmt(
return(0);
}
-/**********************************************************************
-Maps a MySQL trx isolation level code to the InnoDB isolation level code */
+/******************************************************************//**
+Maps a MySQL trx isolation level code to the InnoDB isolation level code
+@return InnoDB isolation level */
static inline
ulint
innobase_map_isolation_level(
/*=========================*/
- /* out: InnoDB isolation level */
- enum_tx_isolation iso) /* in: MySQL isolation level code */
+ enum_tx_isolation iso) /*!< in: MySQL isolation level code */
{
switch(iso) {
case ISO_REPEATABLE_READ: return(TRX_ISO_REPEATABLE_READ);
@@ -7945,21 +8048,21 @@ innobase_map_isolation_level(
}
}
-/**********************************************************************
+/******************************************************************//**
As MySQL will execute an external lock for every new table it uses when it
starts to process an SQL statement (an exception is when MySQL calls
start_stmt for the handle) we can use this function to store the pointer to
the THD in the handle. We will also use this function to communicate
to InnoDB that a new SQL statement has started and that we must store a
savepoint to our transaction handle, so that we are able to roll back
-the SQL statement in case of an error. */
+the SQL statement in case of an error.
+@return 0 */
UNIV_INTERN
int
ha_innobase::external_lock(
/*=======================*/
- /* out: 0 */
- THD* thd, /* in: handle to the user thread */
- int lock_type) /* in: lock type */
+ THD* thd, /*!< in: handle to the user thread */
+ int lock_type) /*!< in: lock type */
{
trx_t* trx;
@@ -7976,8 +8079,9 @@ ha_innobase::external_lock(
{
ulong const binlog_format= thd_binlog_format(thd);
ulong const tx_isolation = thd_tx_isolation(ha_thd());
- if (tx_isolation <= ISO_READ_COMMITTED &&
- binlog_format == BINLOG_FORMAT_STMT)
+ if (tx_isolation <= ISO_READ_COMMITTED
+ && binlog_format == BINLOG_FORMAT_STMT
+ && thd_binlog_filter_ok(thd))
{
char buf[256];
my_snprintf(buf, sizeof(buf),
@@ -8113,16 +8217,16 @@ ha_innobase::external_lock(
DBUG_RETURN(0);
}
-/**********************************************************************
+/******************************************************************//**
With this function MySQL request a transactional lock to a table when
-user issued query LOCK TABLES..WHERE ENGINE = InnoDB. */
+user issued query LOCK TABLES..WHERE ENGINE = InnoDB.
+@return error code */
UNIV_INTERN
int
ha_innobase::transactional_table_lock(
/*==================================*/
- /* out: error code */
- THD* thd, /* in: handle to the user thread */
- int lock_type) /* in: lock type */
+ THD* thd, /*!< in: handle to the user thread */
+ int lock_type) /*!< in: lock type */
{
trx_t* trx;
@@ -8144,8 +8248,8 @@ ha_innobase::transactional_table_lock(
"InnoDB: Have you deleted the .ibd file"
" from the database directory under\n"
"InnoDB: the MySQL datadir?"
- "InnoDB: See"
- " http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
+ "InnoDB: See " REFMAN
+ "innodb-troubleshooting.html\n"
"InnoDB: how you can resolve the problem.\n",
prebuilt->table->name);
DBUG_RETURN(HA_ERR_CRASHED);
@@ -8206,29 +8310,27 @@ ha_innobase::transactional_table_lock(
DBUG_RETURN(0);
}
-/****************************************************************************
-Here we export InnoDB status variables to MySQL. */
+/************************************************************************//**
+Here we export InnoDB status variables to MySQL. */
static
-int
-innodb_export_status()
-/*==================*/
+void
+innodb_export_status(void)
+/*======================*/
{
if (innodb_inited) {
srv_export_innodb_status();
}
-
- return(0);
}
-/****************************************************************************
+/************************************************************************//**
Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB
Monitor to the client. */
static
bool
innodb_show_status(
/*===============*/
- handlerton* hton, /* in: the innodb handlerton */
- THD* thd, /* in: the MySQL query thread of the caller */
+ handlerton* hton, /*!< in: the innodb handlerton */
+ THD* thd, /*!< in: the MySQL query thread of the caller */
stat_print_fn *stat_print)
{
trx_t* trx;
@@ -8309,14 +8411,14 @@ innodb_show_status(
DBUG_RETURN(FALSE);
}
-/****************************************************************************
+/************************************************************************//**
Implements the SHOW MUTEX STATUS command. . */
static
bool
innodb_mutex_show_status(
/*=====================*/
- handlerton* hton, /* in: the innodb handlerton */
- THD* thd, /* in: the MySQL query thread of the
+ handlerton* hton, /*!< in: the innodb handlerton */
+ THD* thd, /*!< in: the MySQL query thread of the
caller */
stat_print_fn* stat_print)
{
@@ -8340,6 +8442,10 @@ innodb_mutex_show_status(
mutex = UT_LIST_GET_FIRST(mutex_list);
while (mutex != NULL) {
+ if (mutex->count_os_wait == 0
+ || buf_pool_is_block_mutex(mutex)) {
+ goto next_mutex;
+ }
#ifdef UNIV_DEBUG
if (mutex->mutex_type != 1) {
if (mutex->count_using > 0) {
@@ -8388,6 +8494,7 @@ innodb_mutex_show_status(
}
#endif /* UNIV_DEBUG */
+next_mutex:
mutex = UT_LIST_GET_NEXT(list, mutex);
}
@@ -8398,7 +8505,8 @@ innodb_mutex_show_status(
lock = UT_LIST_GET_FIRST(rw_lock_list);
while (lock != NULL) {
- if (lock->count_os_wait) {
+ if (lock->count_os_wait
+ && !buf_pool_is_block_lock(lock)) {
buf1len= my_snprintf(buf1, sizeof(buf1), "%s:%lu",
lock->cfile_name, (ulong) lock->cline);
buf2len= my_snprintf(buf2, sizeof(buf2),
@@ -8451,7 +8559,7 @@ bool innobase_show_status(handlerton *hton, THD* thd,
}
}
-/****************************************************************************
+/************************************************************************//**
Handling the shared INNOBASE_SHARE structure that is needed to provide table
locking.
****************************************************************************/
@@ -8485,7 +8593,6 @@ static INNOBASE_SHARE* get_share(const char* table_name)
innobase_open_tables, fold, share);
thr_lock_init(&share->lock);
- pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
}
share->use_count++;
@@ -8516,7 +8623,6 @@ static void free_share(INNOBASE_SHARE* share)
HASH_DELETE(INNOBASE_SHARE, table_name_hash,
innobase_open_tables, fold, share);
thr_lock_delete(&share->lock);
- pthread_mutex_destroy(&share->mutex);
my_free(share, MYF(0));
/* TODO: invoke HASH_MIGRATE if innobase_open_tables
@@ -8526,27 +8632,26 @@ static void free_share(INNOBASE_SHARE* share)
pthread_mutex_unlock(&innobase_share_mutex);
}
-/*********************************************************************
+/*****************************************************************//**
Converts a MySQL table lock stored in the 'lock' field of the handle to
a proper type before storing pointer to the lock into an array of pointers.
MySQL also calls this if it wants to reset some table locks to a not-locked
state during the processing of an SQL query. An example is that during a
SELECT the read lock is released early on the 'const' tables where we only
fetch one row. MySQL does not call this when it releases all locks at the
-end of an SQL statement. */
+end of an SQL statement.
+@return pointer to the next element in the 'to' array */
UNIV_INTERN
THR_LOCK_DATA**
ha_innobase::store_lock(
/*====================*/
- /* out: pointer to the next
- element in the 'to' array */
- THD* thd, /* in: user thread handle */
- THR_LOCK_DATA** to, /* in: pointer to an array
+ THD* thd, /*!< in: user thread handle */
+ THR_LOCK_DATA** to, /*!< in: pointer to an array
of pointers to lock structs;
pointer to the 'lock' field
of current handle is stored
next to this array */
- enum thr_lock_type lock_type) /* in: lock type to store in
+ enum thr_lock_type lock_type) /*!< in: lock type to store in
'lock'; this may also be
TL_IGNORE */
{
@@ -8729,16 +8834,16 @@ ha_innobase::store_lock(
return(to);
}
-/*******************************************************************************
+/*********************************************************************//**
Read the next autoinc value. Acquire the relevant locks before reading
the AUTOINC value. If SUCCESS then the table AUTOINC mutex will be locked
-on return and all relevant locks acquired. */
+on return and all relevant locks acquired.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
ha_innobase::innobase_get_autoinc(
/*==============================*/
- /* out: DB_SUCCESS or error code */
- ulonglong* value) /* out: autoinc value */
+ ulonglong* value) /*!< out: autoinc value */
{
*value = 0;
@@ -8756,14 +8861,14 @@ ha_innobase::innobase_get_autoinc(
return(prebuilt->autoinc_error);
}
-/***********************************************************************
+/*******************************************************************//**
This function reads the global auto-inc counter. It doesn't use the
-AUTOINC lock even if the lock mode is set to TRADITIONAL. */
+AUTOINC lock even if the lock mode is set to TRADITIONAL.
+@return the autoinc value */
UNIV_INTERN
ulonglong
ha_innobase::innobase_peek_autoinc(void)
/*====================================*/
- /* out: the autoinc value */
{
ulonglong auto_inc;
dict_table_t* innodb_table;
@@ -8780,11 +8885,11 @@ ha_innobase::innobase_peek_autoinc(void)
ut_a(auto_inc > 0);
dict_table_autoinc_unlock(innodb_table);
-
+
return(auto_inc);
}
-
-/*******************************************************************************
+
+/*********************************************************************//**
This function initializes the auto-inc counter if it has not been
initialized yet. This function does not change the value of the auto-inc
counter if it already has been initialized. Returns the value of the
@@ -8795,11 +8900,11 @@ UNIV_INTERN
void
ha_innobase::get_auto_increment(
/*============================*/
- ulonglong offset, /* in: */
- ulonglong increment, /* in: table autoinc increment */
- ulonglong nb_desired_values, /* in: number of values reqd */
- ulonglong *first_value, /* out: the autoinc value */
- ulonglong *nb_reserved_values) /* out: count of reserved values */
+ ulonglong offset, /*!< in: table autoinc offset */
+ ulonglong increment, /*!< in: table autoinc increment */
+ ulonglong nb_desired_values, /*!< in: number of values reqd */
+ ulonglong *first_value, /*!< out: the autoinc value */
+ ulonglong *nb_reserved_values) /*!< out: count of reserved values */
{
trx_t* trx;
ulint error;
@@ -8854,6 +8959,7 @@ ha_innobase::get_auto_increment(
AUTOINC counter after attempting to insert the row. */
if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
ulonglong need;
+ ulonglong current;
ulonglong next_value;
ulonglong col_max_value;
@@ -8862,11 +8968,13 @@ ha_innobase::get_auto_increment(
col_max_value = innobase_get_int_col_max_value(
table->next_number_field);
+ current = *first_value > col_max_value ? autoinc : *first_value;
+
need = *nb_reserved_values * increment;
/* Compute the last value in the interval */
next_value = innobase_next_autoinc(
- *first_value, need, offset, col_max_value);
+ current, need, offset, col_max_value);
prebuilt->autoinc_last_value = next_value;
@@ -8893,12 +9001,17 @@ ha_innobase::get_auto_increment(
dict_table_autoinc_unlock(prebuilt->table);
}
-/* See comment in handler.h */
+/*******************************************************************//**
+Reset the auto-increment counter to the given value, i.e. the next row
+inserted will get the given value. This is called e.g. after TRUNCATE
+is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is
+returned by storage engines that don't support this operation.
+@return 0 or error code */
UNIV_INTERN
int
ha_innobase::reset_auto_increment(
/*==============================*/
- ulonglong value) /* in: new value for table autoinc */
+ ulonglong value) /*!< in: new value for table autoinc */
{
DBUG_ENTER("ha_innobase::reset_auto_increment");
@@ -8939,19 +9052,18 @@ ha_innobase::get_error_message(int error, String *buf)
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Compares two 'refs'. A 'ref' is the (internal) primary key value of the row.
If there is no explicitly declared non-null unique key or a primary key, then
-InnoDB internally uses the row id as the primary key. */
+InnoDB internally uses the row id as the primary key.
+@return < 0 if ref1 < ref2, 0 if equal, else > 0 */
UNIV_INTERN
int
ha_innobase::cmp_ref(
/*=================*/
- /* out: < 0 if ref1 < ref2, 0 if equal, else
- > 0 */
- const uchar* ref1, /* in: an (internal) primary key value in the
+ const uchar* ref1, /*!< in: an (internal) primary key value in the
MySQL key value format */
- const uchar* ref2) /* in: an (internal) primary key value in the
+ const uchar* ref2) /*!< in: an (internal) primary key value in the
MySQL key value format */
{
enum_field_types mysql_type;
@@ -9011,25 +9123,24 @@ ha_innobase::cmp_ref(
return(0);
}
-/***********************************************************************
-Ask InnoDB if a query to a table can be cached. */
+/*******************************************************************//**
+Ask InnoDB if a query to a table can be cached.
+@return TRUE if query caching of the table is permitted */
UNIV_INTERN
my_bool
ha_innobase::register_query_cache_table(
/*====================================*/
- /* out: TRUE if query caching
- of the table is permitted */
- THD* thd, /* in: user thread handle */
- char* table_key, /* in: concatenation of database name,
- the null character '\0',
+ THD* thd, /*!< in: user thread handle */
+ char* table_key, /*!< in: concatenation of database name,
+ the null character NUL,
and the table name */
- uint key_length, /* in: length of the full name, i.e.
+ uint key_length, /*!< in: length of the full name, i.e.
len(dbname) + len(tablename) + 1 */
qc_engine_callback*
- call_back, /* out: pointer to function for
+ call_back, /*!< out: pointer to function for
checking if query caching
is permitted */
- ulonglong *engine_data) /* in/out: data to call_back */
+ ulonglong *engine_data) /*!< in/out: data to call_back */
{
*call_back = innobase_query_caching_of_table_permitted;
*engine_data = 0;
@@ -9055,30 +9166,26 @@ ha_innobase::get_mysql_bin_log_pos()
return(trx_sys_mysql_bin_log_pos);
}
-/**********************************************************************
+/******************************************************************//**
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
finds charset information and returns length of prefix_len characters in the
index field in bytes.
-
-NOTE: the prototype of this function is copied to data0type.c! If you change
-this function, you MUST change also data0type.c! */
+@return number of bytes occupied by the first n characters */
extern "C" UNIV_INTERN
ulint
innobase_get_at_most_n_mbchars(
/*===========================*/
- /* out: number of bytes occupied by the first
- n characters */
- ulint charset_id, /* in: character set id */
- ulint prefix_len, /* in: prefix length in bytes of the index
+ ulint charset_id, /*!< in: character set id */
+ ulint prefix_len, /*!< in: prefix length in bytes of the index
(this has to be divided by mbmaxlen to get the
number of CHARACTERS n in the prefix) */
- ulint data_len, /* in: length of the string in bytes */
- const char* str) /* in: character string */
+ ulint data_len, /*!< in: length of the string in bytes */
+ const char* str) /*!< in: character string */
{
- ulint char_length; /* character length in bytes */
- ulint n_chars; /* number of characters in prefix */
- CHARSET_INFO* charset; /* charset used in the field */
+ ulint char_length; /*!< character length in bytes */
+ ulint n_chars; /*!< number of characters in prefix */
+ CHARSET_INFO* charset; /*!< charset used in the field */
charset = get_charset((uint) charset_id, MYF(MY_WME));
@@ -9129,55 +9236,26 @@ innobase_get_at_most_n_mbchars(
return(char_length);
}
-/***********************************************************************
-This function is used to prepare X/Open XA distributed transaction */
+/*******************************************************************//**
+This function is used to prepare an X/Open XA distributed transaction.
+@return 0 or error number */
static
int
innobase_xa_prepare(
/*================*/
- /* out: 0 or error number */
- handlerton *hton,
- THD* thd, /* in: handle to the MySQL thread of the user
- whose XA transaction should be prepared */
- bool all) /* in: TRUE - commit transaction
- FALSE - the current SQL statement ended */
+ handlerton* hton, /*!< in: InnoDB handlerton */
+ THD* thd, /*!< in: handle to the MySQL thread of
+ the user whose XA transaction should
+ be prepared */
+ bool all) /*!< in: TRUE - commit transaction
+ FALSE - the current SQL statement
+ ended */
{
int error = 0;
trx_t* trx = check_trx_exists(thd);
DBUG_ASSERT(hton == innodb_hton_ptr);
- if (thd_sql_command(thd) != SQLCOM_XA_PREPARE &&
- (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
- {
- if (srv_enable_unsafe_group_commit && !THDVAR(thd, support_xa)) {
- /* choose group commit rather than binlog order */
- return(0);
- }
-
- /* For ibbackup to work the order of transactions in binlog
- and InnoDB must be the same. Consider the situation
-
- thread1> prepare; write to binlog; ...
- <context switch>
- thread2> prepare; write to binlog; commit
- thread1> ... commit
-
- To ensure this will not happen we're taking the mutex on
- prepare, and releasing it on commit.
-
- Note: only do it for normal commits, done via ha_commit_trans.
- If 2pc protocol is executed by external transaction
- coordinator, it will be just a regular MySQL client
- executing XA PREPARE and XA COMMIT commands.
- In this case we cannot know how many minutes or hours
- will be between XA PREPARE and XA COMMIT, and we don't want
- to block for undefined period of time.
- */
- pthread_mutex_lock(&prepare_commit_mutex);
- trx->active_trans = 2;
- }
-
/* we use support_xa value as it was seen at transaction start
time, not the current session variable value. Any possible changes
to the session variable take effect only in the next transaction */
@@ -9230,20 +9308,50 @@ innobase_xa_prepare(
srv_active_wake_master_thread();
+ if (thd_sql_command(thd) != SQLCOM_XA_PREPARE &&
+ (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
+ {
+ if (srv_enable_unsafe_group_commit && !THDVAR(thd, support_xa)) {
+ /* choose group commit rather than binlog order */
+ return(error);
+ }
+
+ /* For ibbackup to work the order of transactions in binlog
+ and InnoDB must be the same. Consider the situation
+
+ thread1> prepare; write to binlog; ...
+ <context switch>
+ thread2> prepare; write to binlog; commit
+ thread1> ... commit
+
+ To ensure this will not happen we're taking the mutex on
+ prepare, and releasing it on commit.
+
+ Note: only do it for normal commits, done via ha_commit_trans.
+ If 2pc protocol is executed by external transaction
+ coordinator, it will be just a regular MySQL client
+ executing XA PREPARE and XA COMMIT commands.
+ In this case we cannot know how many minutes or hours
+ will be between XA PREPARE and XA COMMIT, and we don't want
+ to block for undefined period of time.
+ */
+ pthread_mutex_lock(&prepare_commit_mutex);
+ trx->active_trans = 2;
+ }
+
return(error);
}
-/***********************************************************************
-This function is used to recover X/Open XA distributed transactions */
+/*******************************************************************//**
+This function is used to recover X/Open XA distributed transactions.
+@return number of prepared transactions stored in xid_list */
static
int
innobase_xa_recover(
/*================*/
- /* out: number of prepared transactions
- stored in xid_list */
- handlerton *hton,
- XID* xid_list, /* in/out: prepared transactions */
- uint len) /* in: number of slots in xid_list */
+ handlerton* hton, /*!< in: InnoDB handlerton */
+ XID* xid_list,/*!< in/out: prepared transactions */
+ uint len) /*!< in: number of slots in xid_list */
{
DBUG_ASSERT(hton == innodb_hton_ptr);
@@ -9255,16 +9363,16 @@ innobase_xa_recover(
return(trx_recover_for_mysql(xid_list, len));
}
-/***********************************************************************
+/*******************************************************************//**
This function is used to commit one X/Open XA distributed transaction
-which is in the prepared state */
+which is in the prepared state
+@return 0 or error number */
static
int
innobase_commit_by_xid(
/*===================*/
- /* out: 0 or error number */
handlerton *hton,
- XID* xid) /* in: X/Open XA transaction identification */
+ XID* xid) /*!< in: X/Open XA transaction identification */
{
trx_t* trx;
@@ -9281,16 +9389,17 @@ innobase_commit_by_xid(
}
}
-/***********************************************************************
+/*******************************************************************//**
This function is used to rollback one X/Open XA distributed transaction
-which is in the prepared state */
+which is in the prepared state
+@return 0 or error number */
static
int
innobase_rollback_by_xid(
/*=====================*/
- /* out: 0 or error number */
- handlerton *hton,
- XID *xid) /* in: X/Open XA transaction identification */
+ handlerton* hton, /*!< in: InnoDB handlerton */
+ XID* xid) /*!< in: X/Open XA transaction
+ identification */
{
trx_t* trx;
@@ -9305,25 +9414,25 @@ innobase_rollback_by_xid(
}
}
-/***********************************************************************
+/*******************************************************************//**
Create a consistent view for a cursor based on current transaction
which is created if the corresponding MySQL thread still lacks one.
This consistent view is then used inside of MySQL when accessing records
-using a cursor. */
+using a cursor.
+@return pointer to cursor view or NULL */
static
void*
innobase_create_cursor_view(
/*========================*/
- /* out: pointer to cursor view or NULL */
- handlerton *hton, /* in: innobase hton */
- THD* thd) /* in: user thread handle */
+ handlerton *hton, /*!< in: innobase hton */
+ THD* thd) /*!< in: user thread handle */
{
DBUG_ASSERT(hton == innodb_hton_ptr);
return(read_cursor_view_create_for_mysql(check_trx_exists(thd)));
}
-/***********************************************************************
+/*******************************************************************//**
Close the given consistent cursor view of a transaction and restore
global read view to a transaction read view. Transaction is created if the
corresponding MySQL thread still lacks one. */
@@ -9332,8 +9441,8 @@ void
innobase_close_cursor_view(
/*=======================*/
handlerton *hton,
- THD* thd, /* in: user thread handle */
- void* curview)/* in: Consistent read view to be closed */
+ THD* thd, /*!< in: user thread handle */
+ void* curview)/*!< in: Consistent read view to be closed */
{
DBUG_ASSERT(hton == innodb_hton_ptr);
@@ -9341,7 +9450,7 @@ innobase_close_cursor_view(
(cursor_view_t*) curview);
}
-/***********************************************************************
+/*******************************************************************//**
Set the given consistent cursor view to a transaction which is created
if the corresponding MySQL thread still lacks one. If the given
consistent cursor view is NULL global read view of a transaction is
@@ -9351,8 +9460,8 @@ void
innobase_set_cursor_view(
/*=====================*/
handlerton *hton,
- THD* thd, /* in: user thread handle */
- void* curview)/* in: Consistent cursor view to be set */
+ THD* thd, /*!< in: user thread handle */
+ void* curview)/*!< in: Consistent cursor view to be set */
{
DBUG_ASSERT(hton == innodb_hton_ptr);
@@ -9511,14 +9620,14 @@ ha_innobase::check_if_incompatible_data(
DBUG_RETURN(COMPATIBLE_DATA_YES);
}
-/****************************************************************
-Validate the file format name and return its corresponding id. */
+/************************************************************//**
+Validate the file format name and return its corresponding id.
+@return valid file format id */
static
uint
innobase_file_format_name_lookup(
/*=============================*/
- /* out: valid file format id*/
- const char* format_name) /* in: pointer to file format name */
+ const char* format_name) /*!< in: pointer to file format name */
{
char* endp;
uint format_id;
@@ -9554,16 +9663,15 @@ innobase_file_format_name_lookup(
return(DICT_TF_FORMAT_MAX + 1);
}
-/****************************************************************
+/************************************************************//**
Validate the file format check value, is it one of "on" or "off",
-as a side effect it sets the srv_check_file_format_at_startup variable. */
+as a side effect it sets the srv_check_file_format_at_startup variable.
+@return true if config value one of "on" or "off" */
static
bool
innobase_file_format_check_on_off(
/*==============================*/
- /* out: true if config value one
- of "on" or "off" */
- const char* format_check) /* in: parameter value */
+ const char* format_check) /*!< in: parameter value */
{
bool ret = true;
@@ -9583,15 +9691,15 @@ innobase_file_format_check_on_off(
return(ret);
}
-/****************************************************************
+/************************************************************//**
Validate the file format check config parameters, as a side effect it
-sets the srv_check_file_format_at_startup variable. */
+sets the srv_check_file_format_at_startup variable.
+@return true if valid config value */
static
bool
innobase_file_format_check_validate(
/*================================*/
- /* out: true if valid config value */
- const char* format_check) /* in: parameter value */
+ const char* format_check) /*!< in: parameter value */
{
uint format_id;
bool ret = true;
@@ -9607,23 +9715,23 @@ innobase_file_format_check_validate(
return(ret);
}
-/*****************************************************************
+/*************************************************************//**
Check if it is a valid file format. This function is registered as
-a callback with MySQL. */
+a callback with MySQL.
+@return 0 for valid file format */
static
int
innodb_file_format_name_validate(
/*=============================*/
- /* out: 0 for valid file
- format */
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to system
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to system
variable */
- void* save, /* out: immediate result
+ void* save, /*!< out: immediate result
for update function */
- struct st_mysql_value* value) /* in: incoming string */
+ struct st_mysql_value* value) /*!< in: incoming string */
{
const char* file_format_input;
+ char* file_format_input_strdup;
char buff[STRING_BUFFER_USUAL_SIZE];
int len = sizeof(buff);
@@ -9640,56 +9748,78 @@ innodb_file_format_name_validate(
if (format_id <= DICT_TF_FORMAT_MAX) {
- *(uint*) save = format_id;
- return(0);
+ /* Copy out from stack-allocated memory (which will not
+ survive return from this function). The memory will be
+ freed in innodb_file_format_check_update(). */
+ file_format_input_strdup = thd_strmake(thd, file_format_input, len);
+
+ *static_cast<char**>(save) = file_format_input_strdup;
+
+ if (file_format_input_strdup == NULL) {
+ return(1);
+ } else {
+ return(0);
+ }
}
}
+ *static_cast<const char**>(save) = NULL;
return(1);
}
-/********************************************************************
+/****************************************************************//**
Update the system variable innodb_file_format using the "saved"
value. This function is registered as a callback with MySQL. */
static
void
innodb_file_format_name_update(
/*===========================*/
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to
system variable */
- void* var_ptr, /* out: where the
+ void* var_ptr, /*!< out: where the
formal string goes */
- const void* save) /* in: immediate result
+ const void* save) /*!< in: immediate result
from check function */
{
+ const char* format_name;
+
ut_a(var_ptr != NULL);
ut_a(save != NULL);
- ut_a((*(const uint*) save) <= DICT_TF_FORMAT_MAX);
- srv_file_format = *(const uint*) save;
+ format_name = *static_cast<const char*const*>(save);
+
+ if (format_name) {
+ uint format_id;
+
+ format_id = innobase_file_format_name_lookup(format_name);
- *(const char**) var_ptr
+ if (format_id <= DICT_TF_FORMAT_MAX) {
+ srv_file_format = format_id;
+ }
+ }
+
+ *static_cast<const char**>(var_ptr)
= trx_sys_file_format_id_to_name(srv_file_format);
}
-/*****************************************************************
+/*************************************************************//**
Check if valid argument to innodb_file_format_check. This
-function is registered as a callback with MySQL. */
+function is registered as a callback with MySQL.
+@return 0 for valid file format */
static
int
innodb_file_format_check_validate(
/*==============================*/
- /* out: 0 for valid file
- format */
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to system
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to system
variable */
- void* save, /* out: immediate result
+ void* save, /*!< out: immediate result
for update function */
- struct st_mysql_value* value) /* in: incoming string */
+ struct st_mysql_value* value) /*!< in: incoming string */
{
const char* file_format_input;
+ char* file_format_input_strdup;
char buff[STRING_BUFFER_USUAL_SIZE];
int len = sizeof(buff);
@@ -9711,16 +9841,18 @@ innodb_file_format_check_validate(
} else if (innobase_file_format_check_validate(
file_format_input)) {
- uint format_id;
-
- format_id = innobase_file_format_name_lookup(
- file_format_input);
-
- ut_a(format_id <= DICT_TF_FORMAT_MAX);
+ /* Copy out from stack-allocated memory (which will not
+ survive return from this function). The memory will be
+ freed in innodb_file_format_check_update(). */
+ file_format_input_strdup = thd_strmake(thd, file_format_input, len);
- *(uint*) save = format_id;
+ *static_cast<char**>(save) = file_format_input_strdup;
- return(0);
+ if (file_format_input_strdup == NULL) {
+ return(1);
+ } else {
+ return(0);
+ }
} else {
sql_print_warning(
@@ -9732,53 +9864,73 @@ innodb_file_format_check_validate(
}
}
+ *static_cast<const char**>(save) = NULL;
return(1);
}
-/********************************************************************
+/****************************************************************//**
Update the system variable innodb_file_format_check using the "saved"
value. This function is registered as a callback with MySQL. */
static
void
innodb_file_format_check_update(
/*============================*/
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to
system variable */
- void* var_ptr, /* out: where the
+ void* var_ptr, /*!< out: where the
formal string goes */
- const void* save) /* in: immediate result
+ const void* save) /*!< in: immediate result
from check function */
{
- uint format_id;
+ const char* format_name_in;
+ const char** format_name_out;
+ uint format_id;
ut_a(save != NULL);
ut_a(var_ptr != NULL);
- format_id = *(const uint*) save;
+ format_name_in = *static_cast<const char*const*>(save);
+ if (!format_name_in) {
+
+ return;
+ }
+
+ format_id = innobase_file_format_name_lookup(format_name_in);
+
+ if (format_id > DICT_TF_FORMAT_MAX) {
+ /* DEFAULT is "on", which is invalid at runtime. */
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
+ "Ignoring SET innodb_file_format=%s",
+ format_name_in);
+ return;
+ }
+
+ format_name_out = static_cast<const char**>(var_ptr);
/* Update the max format id in the system tablespace. */
- if (trx_sys_file_format_max_set(format_id, (const char**) var_ptr)) {
+ if (trx_sys_file_format_max_set(format_id, format_name_out)) {
ut_print_timestamp(stderr);
fprintf(stderr,
" [Info] InnoDB: the file format in the system "
- "tablespace is now set to %s.\n", *(char**) var_ptr);
+ "tablespace is now set to %s.\n", *format_name_out);
}
}
-/********************************************************************
+/****************************************************************//**
Update the system variable innodb_adaptive_hash_index using the "saved"
value. This function is registered as a callback with MySQL. */
static
void
innodb_adaptive_hash_index_update(
/*==============================*/
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to
system variable */
- void* var_ptr, /* out: where the
+ void* var_ptr, /*!< out: where the
formal string goes */
- const void* save) /* in: immediate result
+ const void* save) /*!< in: immediate result
from check function */
{
if (*(my_bool*) save) {
@@ -9788,21 +9940,20 @@ innodb_adaptive_hash_index_update(
}
}
-/*****************************************************************
+/*************************************************************//**
Check if it is a valid value of innodb_change_buffering. This function is
-registered as a callback with MySQL. */
+registered as a callback with MySQL.
+@return 0 for valid innodb_change_buffering */
static
int
innodb_change_buffering_validate(
/*=============================*/
- /* out: 0 for valid
- innodb_change_buffering */
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to system
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to system
variable */
- void* save, /* out: immediate result
+ void* save, /*!< out: immediate result
for update function */
- struct st_mysql_value* value) /* in: incoming string */
+ struct st_mysql_value* value) /*!< in: incoming string */
{
const char* change_buffering_input;
char buff[STRING_BUFFER_USUAL_SIZE];
@@ -9830,19 +9981,19 @@ innodb_change_buffering_validate(
return(1);
}
-/********************************************************************
+/****************************************************************//**
Update the system variable innodb_change_buffering using the "saved"
value. This function is registered as a callback with MySQL. */
static
void
innodb_change_buffering_update(
/*===========================*/
- THD* thd, /* in: thread handle */
- struct st_mysql_sys_var* var, /* in: pointer to
+ THD* thd, /*!< in: thread handle */
+ struct st_mysql_sys_var* var, /*!< in: pointer to
system variable */
- void* var_ptr, /* out: where the
+ void* var_ptr, /*!< out: where the
formal string goes */
- const void* save) /* in: immediate result
+ const void* save) /*!< in: immediate result
from check function */
{
ut_a(var_ptr != NULL);
@@ -9862,6 +10013,49 @@ static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff)
return 0;
}
+/***********************************************************************
+This function checks each index name for a table against reserved
+system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
+this function pushes an warning message to the client, and returns true. */
+extern "C" UNIV_INTERN
+bool
+innobase_index_name_is_reserved(
+/*============================*/
+ /* out: true if an index name
+ matches the reserved name */
+ const trx_t* trx, /* in: InnoDB transaction handle */
+ const KEY* key_info, /* in: Indexes to be created */
+ ulint num_of_keys) /* in: Number of indexes to
+ be created. */
+{
+ const KEY* key;
+ uint key_num; /* index number */
+
+ for (key_num = 0; key_num < num_of_keys; key_num++) {
+ key = &key_info[key_num];
+
+ if (innobase_strcasecmp(key->name,
+ innobase_index_reserve_name) == 0) {
+ /* Push warning to mysql */
+ push_warning_printf((THD*) trx->mysql_thd,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_NAME_FOR_INDEX,
+ "Cannot Create Index with name "
+ "'%s'. The name is reserved "
+ "for the system default primary "
+ "index.",
+ innobase_index_reserve_name);
+
+ my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
+ innobase_index_reserve_name);
+
+ return(true);
+ }
+ }
+
+ return(false);
+}
+
static SHOW_VAR innodb_status_variables_export[]= {
{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
{NullS, NullS, SHOW_LONG}
@@ -9894,6 +10088,11 @@ static MYSQL_SYSVAR_BOOL(fast_recovery, innobase_fast_recovery,
"Enable to use speed hack of recovery avoiding flush list sorting.",
NULL, NULL, FALSE);
+static MYSQL_SYSVAR_BOOL(use_purge_thread, innobase_use_purge_thread,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "Enable to use purge devoted thread.",
+ NULL, NULL, FALSE);
+
static MYSQL_SYSVAR_BOOL(overwrite_relay_log_info, innobase_overwrite_relay_log_info,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
"During InnoDB crash recovery on slave overwrite relay-log.info "
@@ -9906,6 +10105,11 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
"Disable with --skip-innodb-doublewrite.",
NULL, NULL, TRUE);
+static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity,
+ PLUGIN_VAR_RQCMDARG,
+ "Number of IOPs the server can do. Tunes the background IO rate",
+ NULL, NULL, 200, 100, ~0L, 0);
+
static MYSQL_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
PLUGIN_VAR_OPCMDARG,
"Speeds up the shutdown process of the InnoDB storage engine. Possible "
@@ -9979,7 +10183,12 @@ static MYSQL_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
static MYSQL_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
PLUGIN_VAR_RQCMDARG,
"Percentage of dirty pages allowed in bufferpool.",
- NULL, NULL, 90, 0, 100, 0);
+ NULL, NULL, 75, 0, 99, 0);
+
+static MYSQL_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
+ PLUGIN_VAR_NOCMDARG,
+ "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
+ NULL, NULL, TRUE);
static MYSQL_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
PLUGIN_VAR_RQCMDARG,
@@ -10031,6 +10240,12 @@ static MYSQL_SYSVAR_ULONG(stats_auto_update, srv_stats_auto_update,
"(except for ANALYZE TABLE command) 0:disable 1:enable",
NULL, NULL, 1, 0, 1, 0);
+static MYSQL_SYSVAR_ULONG(stats_update_need_lock, srv_stats_update_need_lock,
+ PLUGIN_VAR_RQCMDARG,
+ "Enable/Disable InnoDB's update statistics which needs to lock dictionary. "
+ "e.g. Data_free.",
+ NULL, NULL, 1, 0, 1, 0);
+
static MYSQL_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
PLUGIN_VAR_OPCMDARG,
"Enable InnoDB adaptive hash index (enabled by default). "
@@ -10046,7 +10261,7 @@ static MYSQL_SYSVAR_ULONG(replication_delay, srv_replication_delay,
static MYSQL_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
- NULL, NULL, 1*1024*1024L, 512*1024L, LONG_MAX, 1024);
+ NULL, NULL, 8*1024*1024L, 512*1024L, LONG_MAX, 1024);
static MYSQL_SYSVAR_ULONG(autoextend_increment, srv_auto_extend_increment,
PLUGIN_VAR_RQCMDARG,
@@ -10056,7 +10271,7 @@ 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, 8*1024*1024L, 5*1024*1024L, LONGLONG_MAX, 1024*1024L);
+ NULL, NULL, 128*1024*1024L, 5*1024*1024L, LONGLONG_MAX, 1024*1024L);
static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
PLUGIN_VAR_RQCMDARG,
@@ -10073,6 +10288,16 @@ static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
"Number of file I/O threads in InnoDB.",
NULL, NULL, 4, 4, 64, 0);
+static MYSQL_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Number of background read I/O threads in InnoDB.",
+ NULL, NULL, 4, 1, 64, 0);
+
+static MYSQL_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Number of background write I/O threads in InnoDB.",
+ NULL, NULL, 4, 1, 64, 0);
+
static MYSQL_SYSVAR_LONG(force_recovery, innobase_force_recovery,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Helps to save your data in case the disk image of the database becomes corrupt.",
@@ -10081,7 +10306,7 @@ static MYSQL_SYSVAR_LONG(force_recovery, innobase_force_recovery,
static MYSQL_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"The size of the buffer which InnoDB uses to write log to the log files on disk.",
- NULL, NULL, 1024*1024L, 256*1024L, LONG_MAX, 1024);
+ NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
static MYSQL_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
@@ -10105,8 +10330,13 @@ static MYSQL_SYSVAR_LONG(open_files, innobase_open_files,
static MYSQL_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
PLUGIN_VAR_RQCMDARG,
- "Count of spin-loop rounds in InnoDB mutexes",
- NULL, NULL, 20L, 0L, ~0L, 0);
+ "Count of spin-loop rounds in InnoDB mutexes (30 by default)",
+ NULL, NULL, 30L, 0L, ~0L, 0);
+
+static MYSQL_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
+ PLUGIN_VAR_OPCMDARG,
+ "Maximum delay between polling for a spin lock (6 by default)",
+ NULL, NULL, 6L, 0L, ~0L, 0);
static MYSQL_SYSVAR_BOOL(thread_concurrency_timer_based,
innobase_thread_concurrency_timer_based,
@@ -10157,10 +10387,11 @@ static MYSQL_SYSVAR_STR(change_buffering, innobase_change_buffering,
innodb_change_buffering_validate,
innodb_change_buffering_update, NULL);
-static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity,
+static MYSQL_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
PLUGIN_VAR_RQCMDARG,
- "Number of IO operations per second the server can do. Tunes background IO rate.",
- NULL, NULL, 200, 100, 999999999, 0);
+ "Number of pages that must be accessed sequentially for InnoDB to"
+ "trigger a readahead.",
+ NULL, NULL, 56, 0, 64, 0);
static MYSQL_SYSVAR_LONGLONG(ibuf_max_size, srv_ibuf_max_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
@@ -10212,8 +10443,8 @@ TYPELIB read_ahead_typelib=
};
static MYSQL_SYSVAR_ENUM(read_ahead, srv_read_ahead,
PLUGIN_VAR_RQCMDARG,
- "Control read ahead activity. (none, random, linear, [both])",
- NULL, innodb_read_ahead_update, 3, &read_ahead_typelib);
+ "Control read ahead activity. (none, random, [linear], both)",
+ NULL, innodb_read_ahead_update, 2, &read_ahead_typelib);
static
void
@@ -10251,16 +10482,6 @@ static MYSQL_SYSVAR_ULONG(enable_unsafe_group_commit, srv_enable_unsafe_group_co
"Enable/Disable unsafe group commit when support_xa=OFF and use with binlog or other XA storage engine.",
NULL, NULL, 0, 0, 1, 0);
-static MYSQL_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Number of background read I/O threads in InnoDB.",
- NULL, NULL, 8, 1, 64, 0);
-
-static MYSQL_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
- PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
- "Number of background write I/O threads in InnoDB.",
- NULL, NULL, 8, 1, 64, 0);
-
static MYSQL_SYSVAR_ULONG(expand_import, srv_expand_import,
PLUGIN_VAR_RQCMDARG,
"Enable/Disable converting automatically *.ibd files when import tablespace.",
@@ -10269,7 +10490,7 @@ static MYSQL_SYSVAR_ULONG(expand_import, srv_expand_import,
static MYSQL_SYSVAR_ULONG(extra_rsegments, srv_extra_rsegments,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Number of extra user rollback segments when create new database.",
- NULL, NULL, 0, 0, 127, 0);
+ NULL, NULL, 0, 0, 126, 0);
static MYSQL_SYSVAR_ULONG(dict_size_limit, srv_dict_size_limit,
PLUGIN_VAR_RQCMDARG,
@@ -10290,6 +10511,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(fast_recovery),
MYSQL_SYSVAR(fast_shutdown),
MYSQL_SYSVAR(file_io_threads),
+ MYSQL_SYSVAR(read_io_threads),
+ MYSQL_SYSVAR(write_io_threads),
MYSQL_SYSVAR(file_per_table),
MYSQL_SYSVAR(file_format),
MYSQL_SYSVAR(file_format_check),
@@ -10307,6 +10530,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(log_files_in_group),
MYSQL_SYSVAR(log_group_home_dir),
MYSQL_SYSVAR(max_dirty_pages_pct),
+ MYSQL_SYSVAR(adaptive_flushing),
MYSQL_SYSVAR(max_purge_lag),
MYSQL_SYSVAR(mirrored_log_groups),
MYSQL_SYSVAR(open_files),
@@ -10315,6 +10539,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(stats_on_metadata),
MYSQL_SYSVAR(stats_method),
MYSQL_SYSVAR(stats_auto_update),
+ MYSQL_SYSVAR(stats_update_need_lock),
MYSQL_SYSVAR(stats_sample_pages),
MYSQL_SYSVAR(adaptive_hash_index),
MYSQL_SYSVAR(replication_delay),
@@ -10322,6 +10547,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(strict_mode),
MYSQL_SYSVAR(support_xa),
MYSQL_SYSVAR(sync_spin_loops),
+ MYSQL_SYSVAR(spin_wait_delay),
MYSQL_SYSVAR(table_locks),
MYSQL_SYSVAR(thread_concurrency),
MYSQL_SYSVAR(thread_concurrency_timer_based),
@@ -10330,7 +10556,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(show_verbose_locks),
MYSQL_SYSVAR(show_locks_held),
MYSQL_SYSVAR(version),
- MYSQL_SYSVAR(io_capacity),
MYSQL_SYSVAR(ibuf_max_size),
MYSQL_SYSVAR(ibuf_active_contract),
MYSQL_SYSVAR(ibuf_accel_rate),
@@ -10338,178 +10563,17 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(read_ahead),
MYSQL_SYSVAR(adaptive_checkpoint),
MYSQL_SYSVAR(enable_unsafe_group_commit),
- MYSQL_SYSVAR(read_io_threads),
- MYSQL_SYSVAR(write_io_threads),
MYSQL_SYSVAR(expand_import),
MYSQL_SYSVAR(extra_rsegments),
MYSQL_SYSVAR(dict_size_limit),
MYSQL_SYSVAR(use_sys_malloc),
MYSQL_SYSVAR(change_buffering),
+ MYSQL_SYSVAR(read_ahead_threshold),
+ MYSQL_SYSVAR(io_capacity),
+ MYSQL_SYSVAR(use_purge_thread),
NULL
};
-#ifdef MYSQL_DYNAMIC_PLUGIN
-struct st_mysql_sys_var
-{
- MYSQL_PLUGIN_VAR_HEADER;
- void* value;
-};
-
-struct param_mapping
-{
- const char* server; /* Parameter name in the server. */
- const char* plugin; /* Paramater name in the plugin. */
-};
-
-/********************************************************************
-Match the parameters from the static and dynamic versions. */
-static
-bool
-innobase_match_parameter(
-/*=====================*/
- /* out: true if names match */
- const char* from_server, /* in: variable name from server */
- const char* from_plugin) /* in: variable name from plugin */
-{
- static const param_mapping param_map[] = {
- {"use_adaptive_hash_indexes", "adaptive_hash_index"}
- };
-
- if (strcmp(from_server, from_plugin) == 0) {
- return(true);
- }
-
- const param_mapping* param = param_map;
- int n_elems = sizeof(param_map) / sizeof(param_map[0]);
-
- for (int i = 0; i < n_elems; ++i, ++param) {
-
- if (strcmp(param->server, from_server) == 0
- && strcmp(param->plugin, from_plugin) == 0) {
-
- return(true);
- }
- }
-
- return(false);
-}
-
-/********************************************************************
-Copy InnoDB system variables from the static InnoDB to the dynamic
-plugin. */
-static
-bool
-innodb_plugin_init(void)
-/*====================*/
- /* out: TRUE if the dynamic InnoDB plugin should start */
-{
-#if !MYSQL_STORAGE_ENGINE_PLUGIN
-#error "MYSQL_STORAGE_ENGINE_PLUGIN must be nonzero."
-#endif
-
- /* Copy the system variables. */
-
- struct st_mysql_plugin* builtin;
- struct st_mysql_sys_var** sta; /* static parameters */
- struct st_mysql_sys_var** dyn; /* dynamic parameters */
-
-#ifdef __WIN__
- if (!builtin_innobase_plugin_ptr) {
-
- return(true);
- }
-
- builtin = builtin_innobase_plugin_ptr;
-#else
- switch (builtin_innobase_plugin) {
- case 0:
- return(true);
- case MYSQL_STORAGE_ENGINE_PLUGIN:
- break;
- default:
- return(false);
- }
-
- builtin = (struct st_mysql_plugin*) &builtin_innobase_plugin;
-#endif
-
- for (sta = builtin->system_vars; *sta != NULL; sta++) {
-
- for (dyn = innobase_system_variables; *dyn != NULL; dyn++) {
-
- /* do not copy session variables */
- if (((*sta)->flags | (*dyn)->flags)
- & PLUGIN_VAR_THDLOCAL) {
- continue;
- }
-
- if (innobase_match_parameter((*sta)->name,
- (*dyn)->name)) {
-
- /* found the corresponding parameter */
-
- /* check if the flags are the same,
- ignoring differences in the READONLY or
- NOSYSVAR flags;
- e.g. we are not copying string variable to
- an integer one, but we do not care if it is
- readonly in the static and not in the
- dynamic */
- if (((*sta)->flags ^ (*dyn)->flags)
- & ~(PLUGIN_VAR_READONLY
- | PLUGIN_VAR_NOSYSVAR)) {
-
- fprintf(stderr,
- "InnoDB: %s in static InnoDB "
- "(flags=0x%x) differs from "
- "%s in dynamic InnoDB "
- "(flags=0x%x)\n",
- (*sta)->name, (*sta)->flags,
- (*dyn)->name, (*dyn)->flags);
-
- /* we could break; here leaving this
- parameter uncopied */
- return(false);
- }
-
- /* assign the value of the static parameter
- to the dynamic one, according to their type */
-
-#define COPY_VAR(label, type) \
- case label: \
- *(type*)(*dyn)->value = *(type*)(*sta)->value; \
- break;
-
- switch ((*sta)->flags
- & ~(PLUGIN_VAR_MASK
- | PLUGIN_VAR_UNSIGNED)) {
-
- COPY_VAR(PLUGIN_VAR_BOOL, char);
- COPY_VAR(PLUGIN_VAR_INT, int);
- COPY_VAR(PLUGIN_VAR_LONG, long);
- COPY_VAR(PLUGIN_VAR_LONGLONG, long long);
- COPY_VAR(PLUGIN_VAR_STR, char*);
-
- default:
- fprintf(stderr,
- "InnoDB: unknown flags "
- "0x%x for %s\n",
- (*sta)->flags, (*sta)->name);
- }
-
- /* Make the static InnoDB variable point to
- the dynamic one */
- (*sta)->value = (*dyn)->value;
-
- break;
- }
- }
- }
-
- return(true);
-}
-#endif /* MYSQL_DYNAMIC_PLUGIN */
-
mysql_declare_plugin(innobase)
{
MYSQL_STORAGE_ENGINE_PLUGIN,
diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h
index cf58a3ed972..21f5b944139 100644
--- a/storage/xtradb/handler/ha_innodb.h
+++ b/storage/xtradb/handler/ha_innodb.h
@@ -27,35 +27,43 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#pragma interface /* gcc class implementation */
#endif
+/** InnoDB table share */
typedef struct st_innobase_share {
- THR_LOCK lock;
- pthread_mutex_t mutex;
- const char* table_name;
- uint use_count;
- void* table_name_hash;
+ THR_LOCK lock; /*!< MySQL lock protecting
+ this structure */
+ const char* table_name; /*!< InnoDB table name */
+ uint use_count; /*!< reference count,
+ incremented in get_share()
+ and decremented in free_share() */
+ void* table_name_hash;/*!< hash table chain node */
} INNOBASE_SHARE;
+/** InnoDB B-tree index */
struct dict_index_struct;
+/** Prebuilt structures in an Innobase table handle used within MySQL */
struct row_prebuilt_struct;
+/** InnoDB B-tree index */
typedef struct dict_index_struct dict_index_t;
+/** Prebuilt structures in an Innobase table handle used within MySQL */
typedef struct row_prebuilt_struct row_prebuilt_t;
-/* The class defining a handle to an Innodb table */
+/** The class defining a handle to an Innodb table */
class ha_innobase: public handler
{
- row_prebuilt_t* prebuilt; /* prebuilt struct in InnoDB, used
+ row_prebuilt_t* prebuilt; /*!< prebuilt struct in InnoDB, used
to save CPU time with prebuilt data
structures*/
- THD* user_thd; /* the thread handle of the user
+ THD* user_thd; /*!< the thread handle of the user
currently using the handle; this is
set in external_lock function */
THR_LOCK_DATA lock;
- INNOBASE_SHARE *share;
+ INNOBASE_SHARE* share; /*!< information for MySQL
+ table locking */
- uchar* upd_buff; /* buffer used in updates */
- uchar* key_val_buff; /* buffer used in converting
+ uchar* upd_buff; /*!< buffer used in updates */
+ uchar* key_val_buff; /*!< buffer used in converting
search key values from MySQL format
to Innodb format */
ulong upd_and_key_val_buff_len;
@@ -63,13 +71,13 @@ class ha_innobase: public handler
two buffers */
Table_flags int_table_flags;
uint primary_key;
- ulong start_of_scan; /* this is set to 1 when we are
+ ulong start_of_scan; /*!< this is set to 1 when we are
starting a table scan but have not
yet fetched any row, else 0 */
uint last_match_mode;/* match mode of the latest search:
ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
or undefined */
- uint num_write_row; /* number of write_row() calls */
+ uint num_write_row; /*!< number of write_row() calls */
uint store_key_val_for_row(uint keynr, char* buff, uint buff_len,
const uchar* record);
@@ -119,14 +127,6 @@ class ha_innobase: public handler
void try_semi_consistent_read(bool yes);
void unlock_row();
-#ifdef ROW_MERGE_IS_INDEX_USABLE
- /** Check if an index can be used by this transaction.
- * @param keynr key number to check
- * @return true if available, false if the index
- * does not contain old records that exist
- * in the read view of this transaction */
- bool is_index_available(uint keynr);
-#endif /* ROW_MERGE_IS_INDEX_USABLE */
int index_init(uint index, bool sorted);
int index_end();
int index_read(uchar * buf, const uchar * key,
@@ -258,27 +258,51 @@ int thd_binlog_format(const MYSQL_THD thd);
@param all TRUE <=> rollback main transaction.
*/
void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
+
+/**
+ Check if binary logging is filtered for thread's current db.
+ @param thd Thread handle
+ @retval 1 the query is not filtered, 0 otherwise.
+*/
+bool thd_binlog_filter_ok(const MYSQL_THD thd);
}
typedef struct trx_struct trx_t;
-/************************************************************************
+/********************************************************************//**
+@file handler/ha_innodb.h
Converts an InnoDB error code to a MySQL error code and also tells to MySQL
about a possible transaction rollback inside InnoDB caused by a lock wait
-timeout or a deadlock. */
+timeout or a deadlock.
+@return MySQL error code */
extern "C"
int
convert_error_code_to_mysql(
/*========================*/
- /* out: MySQL error code */
- int error, /* in: InnoDB error code */
- ulint flags, /* in: InnoDB table flags, or 0 */
- MYSQL_THD thd); /* in: user thread handle or NULL */
+ int error, /*!< in: InnoDB error code */
+ ulint flags, /*!< in: InnoDB table flags, or 0 */
+ MYSQL_THD thd); /*!< in: user thread handle or NULL */
-/*************************************************************************
-Allocates an InnoDB transaction for a MySQL handler object. */
+/*********************************************************************//**
+Allocates an InnoDB transaction for a MySQL handler object.
+@return InnoDB transaction handle */
extern "C"
trx_t*
innobase_trx_allocate(
/*==================*/
- /* out: InnoDB transaction handle */
- MYSQL_THD thd); /* in: user thread handle */
+ MYSQL_THD thd); /*!< in: user thread handle */
+/*********************************************************************//**
+This function checks each index name for a table against reserved
+system default primary index name 'GEN_CLUST_INDEX'. If a name
+matches, this function pushes an warning message to the client,
+and returns true. */
+extern "C"
+bool
+innobase_index_name_is_reserved(
+/*============================*/
+ /* out: true if the index name
+ matches the reserved name */
+ const trx_t* trx, /* in: InnoDB transaction handle */
+ const KEY* key_info, /* in: Indexes to be created */
+ ulint num_of_keys); /* in: Number of indexes to
+ be created. */
+
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index 1b5466e66eb..a523fe406ed 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file handler/handler0alter.cc
Smart ALTER TABLE
*******************************************************/
@@ -36,17 +37,17 @@ extern "C" {
#include "ha_innodb.h"
#include "handler0vars.h"
-/*****************************************************************
+/*************************************************************//**
Copies an InnoDB column to a MySQL field. This function is
adapted from row_sel_field_store_in_mysql_format(). */
static
void
innobase_col_to_mysql(
/*==================*/
- const dict_col_t* col, /* in: InnoDB column */
- const uchar* data, /* in: InnoDB column data */
- ulint len, /* in: length of data, in bytes */
- Field* field) /* in/out: MySQL field */
+ const dict_col_t* col, /*!< in: InnoDB column */
+ const uchar* data, /*!< in: InnoDB column data */
+ ulint len, /*!< in: length of data, in bytes */
+ Field* field) /*!< in/out: MySQL field */
{
uchar* ptr;
uchar* dest = field->ptr;
@@ -122,16 +123,16 @@ innobase_col_to_mysql(
}
}
-/*****************************************************************
+/*************************************************************//**
Copies an InnoDB record to table->record[0]. */
extern "C" UNIV_INTERN
void
innobase_rec_to_mysql(
/*==================*/
- TABLE* table, /* in/out: MySQL table */
- const rec_t* rec, /* in: record */
- const dict_index_t* index, /* in: index */
- const ulint* offsets) /* in: rec_get_offsets(
+ TABLE* table, /*!< in/out: MySQL table */
+ const rec_t* rec, /*!< in: record */
+ const dict_index_t* index, /*!< in: index */
+ const ulint* offsets) /*!< in: rec_get_offsets(
rec, index, ...) */
{
uint n_fields = table->s->fields;
@@ -172,13 +173,13 @@ null_field:
}
}
-/*****************************************************************
+/*************************************************************//**
Resets table->record[0]. */
extern "C" UNIV_INTERN
void
innobase_rec_reset(
/*===============*/
- TABLE* table) /* in/out: MySQL table */
+ TABLE* table) /*!< in/out: MySQL table */
{
uint n_fields = table->s->fields;
uint i;
@@ -188,13 +189,13 @@ innobase_rec_reset(
}
}
-/**********************************************************************
+/******************************************************************//**
Removes the filename encoding of a database and table name. */
static
void
innobase_convert_tablename(
/*=======================*/
- char* s) /* in: identifier; out: decoded identifier */
+ char* s) /*!< in: identifier; out: decoded identifier */
{
uint errors;
@@ -222,15 +223,15 @@ innobase_convert_tablename(
}
}
-/***********************************************************************
-This function checks that index keys are sensible. */
+/*******************************************************************//**
+This function checks that index keys are sensible.
+@return 0 or error number */
static
int
innobase_check_index_keys(
/*======================*/
- /* out: 0 or error number */
- const KEY* key_info, /* in: Indexes to be created */
- ulint num_of_keys) /* in: Number of indexes to
+ const KEY* key_info, /*!< in: Indexes to be created */
+ ulint num_of_keys) /*!< in: Number of indexes to
be created */
{
ulint key_num;
@@ -322,15 +323,15 @@ innobase_check_index_keys(
return(0);
}
-/***********************************************************************
+/*******************************************************************//**
Create index field definition for key part */
static
void
innobase_create_index_field_def(
/*============================*/
- KEY_PART_INFO* key_part, /* in: MySQL key definition */
- mem_heap_t* heap, /* in: memory heap */
- merge_index_field_t* index_field) /* out: index field
+ KEY_PART_INFO* key_part, /*!< in: MySQL key definition */
+ mem_heap_t* heap, /*!< in: memory heap */
+ merge_index_field_t* index_field) /*!< out: index field
definition for key_part */
{
Field* field;
@@ -364,20 +365,20 @@ innobase_create_index_field_def(
DBUG_VOID_RETURN;
}
-/***********************************************************************
+/*******************************************************************//**
Create index definition for key */
static
void
innobase_create_index_def(
/*======================*/
- KEY* key, /* in: key definition */
- bool new_primary, /* in: TRUE=generating
+ KEY* key, /*!< in: key definition */
+ bool new_primary, /*!< in: TRUE=generating
a new primary key
on the table */
- bool key_primary, /* in: TRUE if this key
+ bool key_primary, /*!< in: TRUE if this key
is a primary key */
- merge_index_def_t* index, /* out: index definition */
- mem_heap_t* heap) /* in: heap where memory
+ merge_index_def_t* index, /*!< out: index definition */
+ mem_heap_t* heap) /*!< in: heap where memory
is allocated */
{
ulint i;
@@ -418,14 +419,14 @@ innobase_create_index_def(
DBUG_VOID_RETURN;
}
-/***********************************************************************
+/*******************************************************************//**
Copy index field definition */
static
void
innobase_copy_index_field_def(
/*==========================*/
- const dict_field_t* field, /* in: definition to copy */
- merge_index_field_t* index_field) /* out: copied definition */
+ const dict_field_t* field, /*!< in: definition to copy */
+ merge_index_field_t* index_field) /*!< out: copied definition */
{
DBUG_ENTER("innobase_copy_index_field_def");
DBUG_ASSERT(field != NULL);
@@ -437,15 +438,15 @@ innobase_copy_index_field_def(
DBUG_VOID_RETURN;
}
-/***********************************************************************
+/*******************************************************************//**
Copy index definition for the index */
static
void
innobase_copy_index_def(
/*====================*/
- const dict_index_t* index, /* in: index definition to copy */
- merge_index_def_t* new_index,/* out: Index definition */
- mem_heap_t* heap) /* in: heap where allocated */
+ const dict_index_t* index, /*!< in: index definition to copy */
+ merge_index_def_t* new_index,/*!< out: Index definition */
+ mem_heap_t* heap) /*!< in: heap where allocated */
{
ulint n_fields;
ulint i;
@@ -475,7 +476,7 @@ innobase_copy_index_def(
DBUG_VOID_RETURN;
}
-/***********************************************************************
+/*******************************************************************//**
Create an index table where indexes are ordered as follows:
IF a new primary key is defined for the table THEN
@@ -490,18 +491,18 @@ ELSE
ENDIF
-*/
+
+@return key definitions or NULL */
static
merge_index_def_t*
innobase_create_key_def(
/*====================*/
- /* out: key definitions or NULL */
- trx_t* trx, /* in: trx */
- const dict_table_t*table, /* in: table definition */
- mem_heap_t* heap, /* in: heap where space for key
+ trx_t* trx, /*!< in: trx */
+ const dict_table_t*table, /*!< in: table definition */
+ mem_heap_t* heap, /*!< in: heap where space for key
definitions are allocated */
- KEY* key_info, /* in: Indexes to be created */
- ulint& n_keys) /* in/out: Number of indexes to
+ KEY* key_info, /*!< in: Indexes to be created */
+ ulint& n_keys) /*!< in/out: Number of indexes to
be created */
{
ulint i = 0;
@@ -582,16 +583,16 @@ innobase_create_key_def(
DBUG_RETURN(indexdefs);
}
-/***********************************************************************
-Create a temporary tablename using query id, thread id, and id */
+/*******************************************************************//**
+Create a temporary tablename using query id, thread id, and id
+@return temporary tablename */
static
char*
innobase_create_temporary_tablename(
/*================================*/
- /* out: temporary tablename */
- mem_heap_t* heap, /* in: memory heap */
- char id, /* in: identifier [0-9a-zA-Z] */
- const char* table_name) /* in: table name */
+ mem_heap_t* heap, /*!< in: memory heap */
+ char id, /*!< in: identifier [0-9a-zA-Z] */
+ const char* table_name) /*!< in: table name */
{
char* name;
ulint len;
@@ -607,23 +608,23 @@ innobase_create_temporary_tablename(
return(name);
}
-/***********************************************************************
-Create indexes. */
+/*******************************************************************//**
+Create indexes.
+@return 0 or error number */
UNIV_INTERN
int
ha_innobase::add_index(
/*===================*/
- /* out: 0 or error number */
- TABLE* table, /* in: Table where indexes are created */
- KEY* key_info, /* in: Indexes to be created */
- uint num_of_keys) /* in: Number of indexes to be created */
+ TABLE* table, /*!< in: Table where indexes are created */
+ KEY* key_info, /*!< in: Indexes to be created */
+ uint num_of_keys) /*!< in: Number of indexes to be created */
{
- dict_index_t** index; /* Index to be created */
- dict_table_t* innodb_table; /* InnoDB table in dictionary */
- dict_table_t* indexed_table; /* Table where indexes are created */
- merge_index_def_t* index_defs; /* Index definitions */
- mem_heap_t* heap; /* Heap for index definitions */
- trx_t* trx; /* Transaction */
+ dict_index_t** index; /*!< Index to be created */
+ dict_table_t* innodb_table; /*!< InnoDB table in dictionary */
+ dict_table_t* indexed_table; /*!< Table where indexes are created */
+ merge_index_def_t* index_defs; /*!< Index definitions */
+ mem_heap_t* heap; /*!< Heap for index definitions */
+ trx_t* trx; /*!< Transaction */
ulint num_of_idx;
ulint num_created = 0;
ibool dict_locked = FALSE;
@@ -646,6 +647,7 @@ ha_innobase::add_index(
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads. */
trx_search_latch_release_if_reserved(prebuilt->trx);
+ trx_start_if_not_started(prebuilt->trx);
/* Create a background transaction for the operations on
the data dictionary tables. */
@@ -655,9 +657,13 @@ ha_innobase::add_index(
innodb_table = indexed_table
= dict_table_get(prebuilt->table->name, FALSE);
- /* Check that index keys are sensible */
-
- error = innobase_check_index_keys(key_info, num_of_keys);
+ /* Check if the index name is reserved. */
+ if (innobase_index_name_is_reserved(trx, key_info, num_of_keys)) {
+ error = ER_WRONG_NAME_FOR_INDEX;
+ } else {
+ /* Check that index keys are sensible */
+ error = innobase_check_index_keys(key_info, num_of_keys);
+ }
if (UNIV_UNLIKELY(error)) {
err_exit:
@@ -911,16 +917,16 @@ convert_error:
DBUG_RETURN(error);
}
-/***********************************************************************
-Prepare to drop some indexes of a table. */
+/*******************************************************************//**
+Prepare to drop some indexes of a table.
+@return 0 or error number */
UNIV_INTERN
int
ha_innobase::prepare_drop_index(
/*============================*/
- /* out: 0 or error number */
- TABLE* table, /* in: Table where indexes are dropped */
- uint* key_num, /* in: Key nums to be dropped */
- uint num_of_keys) /* in: Number of keys to be dropped */
+ TABLE* table, /*!< in: Table where indexes are dropped */
+ uint* key_num, /*!< in: Key nums to be dropped */
+ uint num_of_keys) /*!< in: Number of keys to be dropped */
{
trx_t* trx;
int err = 0;
@@ -1112,17 +1118,17 @@ func_exit:
DBUG_RETURN(err);
}
-/***********************************************************************
-Drop the indexes that were passed to a successful prepare_drop_index(). */
+/*******************************************************************//**
+Drop the indexes that were passed to a successful prepare_drop_index().
+@return 0 or error number */
UNIV_INTERN
int
ha_innobase::final_drop_index(
/*==========================*/
- /* out: 0 or error number */
- TABLE* table) /* in: Table where indexes are dropped */
+ TABLE* table) /*!< in: Table where indexes are dropped */
{
- dict_index_t* index; /* Index to be dropped */
- trx_t* trx; /* Transaction */
+ dict_index_t* index; /*!< Index to be dropped */
+ trx_t* trx; /*!< Transaction */
int err;
DBUG_ENTER("ha_innobase::final_drop_index");
@@ -1135,6 +1141,7 @@ ha_innobase::final_drop_index(
update_thd();
trx_search_latch_release_if_reserved(prebuilt->trx);
+ trx_start_if_not_started(prebuilt->trx);
/* Create a background transaction for the operations on
the data dictionary tables. */
diff --git a/storage/xtradb/handler/handler0vars.h b/storage/xtradb/handler/handler0vars.h
index fa7de329e67..bed4f61ab26 100644
--- a/storage/xtradb/handler/handler0vars.h
+++ b/storage/xtradb/handler/handler0vars.h
@@ -16,12 +16,13 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file handler/handler0vars.h
This file contains accessor functions for dynamic plugin on Windows.
***********************************************************************/
#if defined __WIN__ && defined MYSQL_DYNAMIC_PLUGIN
-/***********************************************************************
+/*******************************************************************//**
This is a list of externals that can not be resolved by delay loading.
They have to be resolved indirectly via their addresses in the .map file.
All of them are external variables. */
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index e45f2b4dac0..a46583561cc 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file handler/i_s.cc
InnoDB INFORMATION SCHEMA tables interface to MySQL.
Created July 18, 2007 Vasil Dimov
@@ -125,39 +126,39 @@ bool schema_table_store_record(THD *thd, TABLE *table);
void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
bool check_global_access(THD *thd, ulong want_access);
-/***********************************************************************
+/*******************************************************************//**
Common function to fill any of the dynamic tables:
INFORMATION_SCHEMA.innodb_trx
INFORMATION_SCHEMA.innodb_locks
-INFORMATION_SCHEMA.innodb_lock_waits */
+INFORMATION_SCHEMA.innodb_lock_waits
+@return 0 on success */
static
int
trx_i_s_common_fill_table(
/*======================*/
- /* out: 0 on success */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond); /* in: condition (not used) */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond); /*!< in: condition (not used) */
-/***********************************************************************
-Unbind a dynamic INFORMATION_SCHEMA table. */
+/*******************************************************************//**
+Unbind a dynamic INFORMATION_SCHEMA table.
+@return 0 on success */
static
int
i_s_common_deinit(
/*==============*/
- /* out: 0 on success */
- void* p); /* in/out: table schema object */
+ void* p); /*!< in/out: table schema object */
-/***********************************************************************
+/*******************************************************************//**
Auxiliary function to store time_t value in MYSQL_TYPE_DATETIME
-field. */
+field.
+@return 0 on success */
static
int
field_store_time_t(
/*===============*/
- /* out: 0 on success */
- Field* field, /* in/out: target field for storage */
- time_t time) /* in: value to store */
+ Field* field, /*!< in/out: target field for storage */
+ time_t time) /*!< in: value to store */
{
MYSQL_TIME my_time;
struct tm tm_time;
@@ -176,15 +177,15 @@ field_store_time_t(
return(field->store_time(&my_time, MYSQL_TIMESTAMP_DATETIME));
}
-/***********************************************************************
-Auxiliary function to store char* value in MYSQL_TYPE_STRING field. */
+/*******************************************************************//**
+Auxiliary function to store char* value in MYSQL_TYPE_STRING field.
+@return 0 on success */
static
int
field_store_string(
/*===============*/
- /* out: 0 on success */
- Field* field, /* in/out: target field for storage */
- const char* str) /* in: NUL-terminated utf-8 string,
+ Field* field, /*!< in/out: target field for storage */
+ const char* str) /*!< in: NUL-terminated utf-8 string,
or NULL */
{
int ret;
@@ -203,16 +204,16 @@ field_store_string(
return(ret);
}
-/***********************************************************************
+/*******************************************************************//**
Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field.
-If the value is ULINT_UNDEFINED then the field it set to NULL. */
+If the value is ULINT_UNDEFINED then the field it set to NULL.
+@return 0 on success */
static
int
field_store_ulint(
/*==============*/
- /* out: 0 on success */
- Field* field, /* in/out: target field for storage */
- ulint n) /* in: value to store */
+ Field* field, /*!< in/out: target field for storage */
+ ulint n) /*!< in: value to store */
{
int ret;
@@ -806,7 +807,7 @@ i_s_innodb_buffer_pool_pages_index_fill(
field_store_string(table->field[0], NULL);
p = (char *)index->table_name;
}
- strcpy(table_name_raw, p);
+ 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);
@@ -1214,18 +1215,18 @@ static ST_FIELD_INFO innodb_trx_fields_info[] =
END_OF_ST_FIELD_INFO
};
-/***********************************************************************
+/*******************************************************************//**
Read data from cache buffer and fill the INFORMATION_SCHEMA.innodb_trx
-table with it. */
+table with it.
+@return 0 on success */
static
int
fill_innodb_trx_from_cache(
/*=======================*/
- /* out: 0 on success */
- trx_i_s_cache_t* cache, /* in: cache to read from */
- THD* thd, /* in: used to call
+ trx_i_s_cache_t* cache, /*!< in: cache to read from */
+ THD* thd, /*!< in: used to call
schema_table_store_record() */
- TABLE* table) /* in/out: fill this table */
+ TABLE* table) /*!< in/out: fill this table */
{
Field** fields;
ulint rows_num;
@@ -1299,14 +1300,14 @@ fill_innodb_trx_from_cache(
DBUG_RETURN(0);
}
-/***********************************************************************
-Bind the dynamic table INFORMATION_SCHEMA.innodb_trx */
+/*******************************************************************//**
+Bind the dynamic table INFORMATION_SCHEMA.innodb_trx
+@return 0 on success */
static
int
innodb_trx_init(
/*============*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
ST_SCHEMA_TABLE* schema;
@@ -1467,17 +1468,17 @@ static ST_FIELD_INFO innodb_locks_fields_info[] =
END_OF_ST_FIELD_INFO
};
-/***********************************************************************
+/*******************************************************************//**
Read data from cache buffer and fill the INFORMATION_SCHEMA.innodb_locks
-table with it. */
+table with it.
+@return 0 on success */
static
int
fill_innodb_locks_from_cache(
/*=========================*/
- /* out: 0 on success */
- trx_i_s_cache_t* cache, /* in: cache to read from */
- THD* thd, /* in: MySQL client connection */
- TABLE* table) /* in/out: fill this table */
+ trx_i_s_cache_t* cache, /*!< in: cache to read from */
+ THD* thd, /*!< in: MySQL client connection */
+ TABLE* table) /*!< in/out: fill this table */
{
Field** fields;
ulint rows_num;
@@ -1575,14 +1576,14 @@ fill_innodb_locks_from_cache(
DBUG_RETURN(0);
}
-/***********************************************************************
-Bind the dynamic table INFORMATION_SCHEMA.innodb_locks */
+/*******************************************************************//**
+Bind the dynamic table INFORMATION_SCHEMA.innodb_locks
+@return 0 on success */
static
int
innodb_locks_init(
/*==============*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
ST_SCHEMA_TABLE* schema;
@@ -1687,18 +1688,18 @@ static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
END_OF_ST_FIELD_INFO
};
-/***********************************************************************
+/*******************************************************************//**
Read data from cache buffer and fill the
-INFORMATION_SCHEMA.innodb_lock_waits table with it. */
+INFORMATION_SCHEMA.innodb_lock_waits table with it.
+@return 0 on success */
static
int
fill_innodb_lock_waits_from_cache(
/*==============================*/
- /* out: 0 on success */
- trx_i_s_cache_t* cache, /* in: cache to read from */
- THD* thd, /* in: used to call
+ trx_i_s_cache_t* cache, /*!< in: cache to read from */
+ THD* thd, /*!< in: used to call
schema_table_store_record() */
- TABLE* table) /* in/out: fill this table */
+ TABLE* table) /*!< in/out: fill this table */
{
Field** fields;
ulint rows_num;
@@ -1758,14 +1759,14 @@ fill_innodb_lock_waits_from_cache(
DBUG_RETURN(0);
}
-/***********************************************************************
-Bind the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
+/*******************************************************************//**
+Bind the dynamic table INFORMATION_SCHEMA.innodb_lock_waits
+@return 0 on success */
static
int
innodb_lock_waits_init(
/*===================*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
ST_SCHEMA_TABLE* schema;
@@ -1828,19 +1829,19 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_lock_waits =
STRUCT_FLD(__reserved1, NULL)
};
-/***********************************************************************
+/*******************************************************************//**
Common function to fill any of the dynamic tables:
INFORMATION_SCHEMA.innodb_trx
INFORMATION_SCHEMA.innodb_locks
-INFORMATION_SCHEMA.innodb_lock_waits */
+INFORMATION_SCHEMA.innodb_lock_waits
+@return 0 on success */
static
int
trx_i_s_common_fill_table(
/*======================*/
- /* out: 0 on success */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond) /* in: condition (not used) */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond) /*!< in: condition (not used) */
{
const char* table_name;
int ret;
@@ -1989,18 +1990,18 @@ static ST_FIELD_INFO i_s_cmp_fields_info[] =
};
-/***********************************************************************
+/*******************************************************************//**
Fill the dynamic table information_schema.innodb_cmp or
-innodb_cmp_reset. */
+innodb_cmp_reset.
+@return 0 on success, 1 on failure */
static
int
i_s_cmp_fill_low(
/*=============*/
- /* out: 0 on success, 1 on failure */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond, /* in: condition (ignored) */
- ibool reset) /* in: TRUE=reset cumulated counts */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond, /*!< in: condition (ignored) */
+ ibool reset) /*!< in: TRUE=reset cumulated counts */
{
TABLE* table = (TABLE *) tables->table;
int status = 0;
@@ -2047,42 +2048,42 @@ i_s_cmp_fill_low(
DBUG_RETURN(status);
}
-/***********************************************************************
-Fill the dynamic table information_schema.innodb_cmp. */
+/*******************************************************************//**
+Fill the dynamic table information_schema.innodb_cmp.
+@return 0 on success, 1 on failure */
static
int
i_s_cmp_fill(
/*=========*/
- /* out: 0 on success, 1 on failure */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond) /* in: condition (ignored) */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond) /*!< in: condition (ignored) */
{
return(i_s_cmp_fill_low(thd, tables, cond, FALSE));
}
-/***********************************************************************
-Fill the dynamic table information_schema.innodb_cmp_reset. */
+/*******************************************************************//**
+Fill the dynamic table information_schema.innodb_cmp_reset.
+@return 0 on success, 1 on failure */
static
int
i_s_cmp_reset_fill(
/*===============*/
- /* out: 0 on success, 1 on failure */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond) /* in: condition (ignored) */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond) /*!< in: condition (ignored) */
{
return(i_s_cmp_fill_low(thd, tables, cond, TRUE));
}
-/***********************************************************************
-Bind the dynamic table information_schema.innodb_cmp. */
+/*******************************************************************//**
+Bind the dynamic table information_schema.innodb_cmp.
+@return 0 on success */
static
int
i_s_cmp_init(
/*=========*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
DBUG_ENTER("i_s_cmp_init");
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
@@ -2093,14 +2094,14 @@ i_s_cmp_init(
DBUG_RETURN(0);
}
-/***********************************************************************
-Bind the dynamic table information_schema.innodb_cmp_reset. */
+/*******************************************************************//**
+Bind the dynamic table information_schema.innodb_cmp_reset.
+@return 0 on success */
static
int
i_s_cmp_reset_init(
/*===============*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
DBUG_ENTER("i_s_cmp_reset_init");
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
@@ -2257,18 +2258,18 @@ static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
END_OF_ST_FIELD_INFO
};
-/***********************************************************************
+/*******************************************************************//**
Fill the dynamic table information_schema.innodb_cmpmem or
-innodb_cmpmem_reset. */
+innodb_cmpmem_reset.
+@return 0 on success, 1 on failure */
static
int
i_s_cmpmem_fill_low(
/*================*/
- /* out: 0 on success, 1 on failure */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond, /* in: condition (ignored) */
- ibool reset) /* in: TRUE=reset cumulated counts */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond, /*!< in: condition (ignored) */
+ ibool reset) /*!< in: TRUE=reset cumulated counts */
{
TABLE* table = (TABLE *) tables->table;
int status = 0;
@@ -2315,42 +2316,42 @@ i_s_cmpmem_fill_low(
DBUG_RETURN(status);
}
-/***********************************************************************
-Fill the dynamic table information_schema.innodb_cmpmem. */
+/*******************************************************************//**
+Fill the dynamic table information_schema.innodb_cmpmem.
+@return 0 on success, 1 on failure */
static
int
i_s_cmpmem_fill(
/*============*/
- /* out: 0 on success, 1 on failure */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond) /* in: condition (ignored) */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond) /*!< in: condition (ignored) */
{
return(i_s_cmpmem_fill_low(thd, tables, cond, FALSE));
}
-/***********************************************************************
-Fill the dynamic table information_schema.innodb_cmpmem_reset. */
+/*******************************************************************//**
+Fill the dynamic table information_schema.innodb_cmpmem_reset.
+@return 0 on success, 1 on failure */
static
int
i_s_cmpmem_reset_fill(
/*==================*/
- /* out: 0 on success, 1 on failure */
- THD* thd, /* in: thread */
- TABLE_LIST* tables, /* in/out: tables to fill */
- COND* cond) /* in: condition (ignored) */
+ THD* thd, /*!< in: thread */
+ TABLE_LIST* tables, /*!< in/out: tables to fill */
+ COND* cond) /*!< in: condition (ignored) */
{
return(i_s_cmpmem_fill_low(thd, tables, cond, TRUE));
}
-/***********************************************************************
-Bind the dynamic table information_schema.innodb_cmpmem. */
+/*******************************************************************//**
+Bind the dynamic table information_schema.innodb_cmpmem.
+@return 0 on success */
static
int
i_s_cmpmem_init(
/*============*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
DBUG_ENTER("i_s_cmpmem_init");
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
@@ -2361,14 +2362,14 @@ i_s_cmpmem_init(
DBUG_RETURN(0);
}
-/***********************************************************************
-Bind the dynamic table information_schema.innodb_cmpmem_reset. */
+/*******************************************************************//**
+Bind the dynamic table information_schema.innodb_cmpmem_reset.
+@return 0 on success */
static
int
i_s_cmpmem_reset_init(
/*==================*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
DBUG_ENTER("i_s_cmpmem_reset_init");
ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
@@ -2478,14 +2479,14 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
STRUCT_FLD(__reserved1, NULL)
};
-/***********************************************************************
-Unbind a dynamic INFORMATION_SCHEMA table. */
+/*******************************************************************//**
+Unbind a dynamic INFORMATION_SCHEMA table.
+@return 0 on success */
static
int
i_s_common_deinit(
/*==============*/
- /* out: 0 on success */
- void* p) /* in/out: table schema object */
+ void* p) /*!< in/out: table schema object */
{
DBUG_ENTER("i_s_common_deinit");
diff --git a/storage/xtradb/handler/i_s.h b/storage/xtradb/handler/i_s.h
index 8601cc086ea..7bb03460285 100644
--- a/storage/xtradb/handler/i_s.h
+++ b/storage/xtradb/handler/i_s.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file handler/i_s.h
InnoDB INFORMATION SCHEMA tables interface to MySQL.
Created July 18, 2007 Vasil Dimov
diff --git a/storage/xtradb/handler/innodb_patch_info.h b/storage/xtradb/handler/innodb_patch_info.h
index 770e74f39d1..f8a728d0d27 100644
--- a/storage/xtradb/handler/innodb_patch_info.h
+++ b/storage/xtradb/handler/innodb_patch_info.h
@@ -31,12 +31,12 @@ struct innodb_enhancement {
{"innodb_expand_undo_slots","expandable maximum number of undo slots","from 1024 (default) to about 4000","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_extra_rseg","allow to create extra rollback segments","When create new db, the new parameter allows to create more rollback segments","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"},
-{"innodb_pause_in_spin","use 'pause' instruction during spin loop for x86 (gcc)","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_thread_concurrency_timer_based","use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)","",""},
{"innodb_expand_import","convert .ibd file automatically when import tablespace","the files are generated by xtrabackup export mode.","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_dict_size_limit","Limit dictionary cache size","Variable innodb_dict_size_limit in bytes","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_split_buf_pool_mutex","More fix of buffer_pool mutex","Spliting buf_pool_mutex and optimizing based on innodb_opt_lru_count","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_stats","Additional features about InnoDB statistics/optimizer","","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_recovery_patches","Bugfixes and adjustments about recovery process","","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_purge_thread","Enable to use purge devoted thread","","http://www.percona.com/docs/wiki/percona-xtradb"},
{NULL, NULL, NULL, NULL}
};
diff --git a/storage/xtradb/handler/mysql_addons.cc b/storage/xtradb/handler/mysql_addons.cc
index a5d9c82c3e3..eae1fe9fbc2 100644
--- a/storage/xtradb/handler/mysql_addons.cc
+++ b/storage/xtradb/handler/mysql_addons.cc
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file handler/mysql_addons.cc
This file contains functions that need to be added to
MySQL code but have not been added yet.
diff --git a/storage/xtradb/handler/win_delay_loader.cc b/storage/xtradb/handler/win_delay_loader.cc
index 1572df42e30..9b92f6a9cf2 100644
--- a/storage/xtradb/handler/win_delay_loader.cc
+++ b/storage/xtradb/handler/win_delay_loader.cc
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file handler/win_delay_loader.cc
This file contains functions that implement the delay loader on Windows.
This is a customized version of delay loader with limited functionalities.
@@ -48,7 +49,7 @@ extern "C" {
# include "hash0hash.h"
}
-/***********************************************************************
+/*******************************************************************//**
This following contains a list of externals that can not be resolved by
delay loading. They have to be resolved indirectly via their addresses
in the .map file. All of them are external variables. */
@@ -72,14 +73,8 @@ uint* wdl_lower_case_table_names;
ulong* wdl_specialflag;
int* wdl_my_umask;
-/***********************************************************************
-The following is defined in ha_innodb.cc. It is used for copying the
-system variables from the builtin innodb plugin to the dynamic plugin.
-*/
-extern struct st_mysql_plugin* builtin_innobase_plugin_ptr;
-
-/***********************************************************************
-The preffered load-address defined in PE (portable executable format).*/
+/*******************************************************************//**
+The preferred load-address defined in PE (portable executable format). */
#if defined(_M_IA64)
#pragma section(".base", long, read)
extern "C"
@@ -90,29 +85,34 @@ extern "C"
const IMAGE_DOS_HEADER __ImageBase;
#endif
-/***********************************************************************
+/*******************************************************************//**
A template function for converting a relative address (RVA) to an
absolute address (VA). This is due to the pointers in the delay
descriptor (ImgDelayDescr in delayimp.h) have been changed from
-VAs to RVAs to work on both 32- and 64-bit platforms. */
+VAs to RVAs to work on both 32- and 64-bit platforms.
+@return absolute virtual address */
template <class X>
-X PFromRva(RVA rva) {
+X PFromRva(
+/*=======*/
+ RVA rva) /*!< in: relative virtual address */
+{
return X(PBYTE(&__ImageBase) + rva);
}
-/***********************************************************************
+/*******************************************************************//**
Convert to the old format for convenience. The structure as well as its
element names follow the definition of ImgDelayDescr in delayimp.h. */
-struct InternalImgDelayDescr {
- DWORD grAttrs; /* attributes */
- LPCSTR szName; /* pointer to dll name */
- HMODULE* phmod; /* address of module handle */
- PImgThunkData pIAT; /* address of the IAT */
- PCImgThunkData pINT; /* address of the INT */
- PCImgThunkData pBoundIAT; /* address of the optional bound IAT */
- PCImgThunkData pUnloadIAT; /* address of optional copy of
+struct InternalImgDelayDescr
+{
+ DWORD grAttrs; /*!< attributes */
+ LPCSTR szName; /*!< pointer to dll name */
+ HMODULE* phmod; /*!< address of module handle */
+ PImgThunkData pIAT; /*!< address of the IAT */
+ PCImgThunkData pINT; /*!< address of the INT */
+ PCImgThunkData pBoundIAT; /*!< address of the optional bound IAT */
+ PCImgThunkData pUnloadIAT; /*!< address of optional copy of
original IAT */
- DWORD dwTimeStamp; /* 0 if not bound,
+ DWORD dwTimeStamp; /*!< 0 if not bound,
otherwise date/time stamp of DLL
bound to (Old BIND) */
};
@@ -120,11 +120,11 @@ struct InternalImgDelayDescr {
typedef struct map_hash_chain_struct map_hash_chain_t;
struct map_hash_chain_struct {
- char* symbol; /* pointer to a symbol */
- ulint value; /* address of the symbol */
- map_hash_chain_t* next; /* pointer to the next cell
+ char* symbol; /*!< pointer to a symbol */
+ ulint value; /*!< address of the symbol */
+ map_hash_chain_t* next; /*!< pointer to the next cell
in the same folder. */
- map_hash_chain_t* chain; /* a linear chain used for
+ map_hash_chain_t* chain; /*!< a linear chain used for
cleanup. */
};
@@ -135,7 +135,7 @@ static ibool wdl_init = FALSE;
const ulint MAP_HASH_CELLS_NUM = 10000;
#ifndef DBUG_OFF
-/***********************************************************************
+/*******************************************************************//**
In the dynamic plugin, it is required to call the following dbug functions
in the server:
_db_pargs_
@@ -144,8 +144,7 @@ in the server:
_db_return_
_db_dump_
-The plugin will get those function pointers during the initialization.
-*/
+The plugin will get those function pointers during the initialization. */
typedef void (__cdecl* pfn_db_enter_)(
const char* _func_,
const char* _file_,
@@ -182,19 +181,19 @@ static pfn_db_doprnt_ wdl_db_doprnt_;
static pfn_db_dump_ wdl_db_dump_;
#endif /* !DBUG_OFF */
-/*****************************************************************
+/*************************************************************//**
Creates a hash table with >= n array cells. The actual number of cells is
chosen to be a prime number slightly bigger than n.
This is the same function as hash_create in hash0hash.c, except the
memory allocation. This function is invoked before the engine is
-initialized, and buffer pools are not ready yet. */
+initialized, and buffer pools are not ready yet.
+@return own: created hash table */
static
hash_table_t*
wdl_hash_create(
/*============*/
- /* out, own: created hash table */
- ulint n) /* in: number of array cells */
+ ulint n) /*!< in: number of array cells */
{
hash_cell_t* array;
ulint prime;
@@ -227,13 +226,13 @@ wdl_hash_create(
return(table);
}
-/*****************************************************************
+/*************************************************************//**
Frees a hash table. */
static
void
wdl_hash_table_free(
/*================*/
- hash_table_t* table) /* in, own: hash table */
+ hash_table_t* table) /*!< in, own: hash table */
{
ut_a(table != NULL);
ut_a(table->mutexes == NULL);
@@ -242,14 +241,14 @@ wdl_hash_table_free(
free(table);
}
-/***********************************************************************
-Function for calculating the count of imports given the base of the IAT. */
+/*******************************************************************//**
+Function for calculating the count of imports given the base of the IAT.
+@return number of imports */
static
ulint
wdl_import_count(
/*=============*/
- /* out: number of imports */
- PCImgThunkData pitd_base) /* in: base of the IAT */
+ PCImgThunkData pitd_base) /*!< in: base of the IAT */
{
ulint ret = 0;
PCImgThunkData pitd = pitd_base;
@@ -262,15 +261,14 @@ wdl_import_count(
return(ret);
}
-/***********************************************************************
-Read Mapfile to a hashtable for faster access */
+/*******************************************************************//**
+Read Mapfile to a hashtable for faster access
+@return TRUE if the mapfile is loaded successfully. */
static
ibool
wdl_load_mapfile(
/*=============*/
- /* out: TRUE if the mapfile is
- loaded successfully. */
- const char* filename) /* in: name of the mapfile. */
+ const char* filename) /*!< in: name of the mapfile. */
{
FILE* fp;
const size_t nSize = 256;
@@ -358,7 +356,7 @@ wdl_load_mapfile(
chain_header = map_cell;
map_cell->symbol = strdup(func_name);
- map_cell->value = (ulint) strtoull(tmp_buf, NULL, 0)
+ map_cell->value = (ulint) _strtoui64(tmp_buf, NULL, 0)
- load_addr;
map_fold = ut_fold_string(map_cell->symbol);
@@ -375,7 +373,7 @@ wdl_load_mapfile(
return(TRUE);
}
-/*****************************************************************
+/*************************************************************//**
Cleanup.during DLL unload */
static
void
@@ -397,13 +395,13 @@ wdl_cleanup(void)
}
}
-/***********************************************************************
-Load the mapfile mysqld.map. */
+/*******************************************************************//**
+Load the mapfile mysqld.map.
+@return the module handle */
static
HMODULE
wdl_get_mysqld_mapfile(void)
/*========================*/
- /* out: the module handle */
{
char file_name[MAX_PATH];
char* ext;
@@ -447,17 +445,16 @@ wdl_get_mysqld_mapfile(void)
return(my_hmod);
}
-/***********************************************************************
+/*******************************************************************//**
Retrieves the address of an exported function. It follows the convention
-of GetProcAddress(). */
+of GetProcAddress().
+@return address of exported function. */
static
FARPROC
wdl_get_procaddr_from_map(
/*======================*/
- /* out: address of exported
- function. */
- HANDLE m_handle, /* in: module handle */
- const char* import_proc) /* in: procedure name */
+ HANDLE m_handle, /*!< in: module handle */
+ const char* import_proc) /*!< in: procedure name */
{
map_hash_chain_t* hash_chain;
ulint map_fold;
@@ -511,17 +508,16 @@ wdl_get_procaddr_from_map(
return((FARPROC) ((ulint) m_handle + hash_chain->value));
}
-/***********************************************************************
+/*******************************************************************//**
Retrieves the address of an exported variable.
-Note: It does not follow the Windows call convention FARPROC. */
+Note: It does not follow the Windows call convention FARPROC.
+@return address of exported variable. */
static
void*
wdl_get_varaddr_from_map(
/*=====================*/
- /* out: address of exported
- variable. */
- HANDLE m_handle, /* in: module handle */
- const char* import_variable) /* in: variable name */
+ HANDLE m_handle, /*!< in: module handle */
+ const char* import_variable) /*!< in: variable name */
{
map_hash_chain_t* hash_chain;
ulint map_fold;
@@ -575,13 +571,13 @@ wdl_get_varaddr_from_map(
return((void*) ((ulint) m_handle + hash_chain->value));
}
-/***********************************************************************
-Bind all unresolved external variables from the MySQL executable. */
+/*******************************************************************//**
+Bind all unresolved external variables from the MySQL executable.
+@return TRUE if successful */
static
bool
wdl_get_external_variables(void)
/*============================*/
- /* out: TRUE if successful */
{
HMODULE hmod = wdl_get_mysqld_mapfile();
@@ -643,12 +639,6 @@ wdl_get_external_variables(void)
"?binlog_format_names@@3PAPBDA",
wdl_binlog_format_names, char*);
- /* It is fine if builtin_innobase_plugin is not available. */
- builtin_innobase_plugin_ptr = (struct st_mysql_plugin*)
- wdl_get_varaddr_from_map(
- hmod,
- "?builtin_innobase_plugin@@3PAUst_mysql_plugin@@A");
-
#ifndef DBUG_OFF
GET_PROC_ADDR(_db_enter_);
GET_PROC_ADDR(_db_return_);
@@ -680,7 +670,7 @@ wdl_get_external_variables(void)
#undef GET_PROC_ADDR
}
-/***********************************************************************
+/*******************************************************************//**
The DLL Delayed Loading Helper Function for resolving externals.
The function may fail due to one of the three reasons:
@@ -691,16 +681,15 @@ The function may fail due to one of the three reasons:
* Failed to find an external name in the map file mysqld.map.
Note: this function is called by run-time as well as __HrLoadAllImportsForDll.
-So, it has to follow Windows call convention. */
+So, it has to follow Windows call convention.
+@return the address of the imported function */
extern "C"
FARPROC WINAPI
__delayLoadHelper2(
/*===============*/
- /* out: the address of the imported
- function*/
- PCImgDelayDescr pidd, /* in: a const pointer to a
+ PCImgDelayDescr pidd, /*!< in: a const pointer to a
ImgDelayDescr, see delayimp.h. */
- FARPROC* iat_entry) /* in/out: A pointer to the slot in
+ FARPROC* iat_entry) /*!< in/out: A pointer to the slot in
the delay load import address table
to be updated with the address of the
imported function. */
@@ -824,31 +813,30 @@ __delayLoadHelper2(
return(fun);
}
-/***********************************************************************
-Unload a DLL that was delay loaded. This function is called by run-time. */
+/*******************************************************************//**
+Unload a DLL that was delay loaded. This function is called by run-time.
+@return TRUE is returned if the DLL is found and the IAT matches the
+original one. */
extern "C"
BOOL WINAPI
__FUnloadDelayLoadedDLL2(
/*=====================*/
- /* out: TRUE is returned if the DLL is found
- and the IAT matches the original one. */
- LPCSTR module_name) /* in: DLL name */
+ LPCSTR module_name) /*!< in: DLL name */
{
return(TRUE);
}
-/******************************************************************
+/**************************************************************//**
Load all imports from a DLL that was specified with the /delayload linker
option.
Note: this function is called by run-time. So, it has to follow Windows call
-convention. */
+convention.
+@return S_OK if the DLL matches, otherwise ERROR_MOD_NOT_FOUND is returned. */
extern "C"
HRESULT WINAPI
__HrLoadAllImportsForDll(
/*=====================*/
- /* out: S_OK if the DLL matches, otherwise
- ERROR_MOD_NOT_FOUND is returned. */
- LPCSTR module_name) /* in: DLL name */
+ LPCSTR module_name) /*!< in: DLL name */
{
PIMAGE_NT_HEADERS img;
PCImgDelayDescr pidd;
@@ -908,18 +896,18 @@ __HrLoadAllImportsForDll(
return ret;
}
-/******************************************************************
-The main function of a DLL */
+/**************************************************************//**
+The main function of a DLL
+@return TRUE if the call succeeds */
BOOL
WINAPI
DllMain(
/*====*/
- /* out: TRUE if the call succeeds */
- HINSTANCE hinstDLL, /* in: handle to the DLL module */
- DWORD fdwReason, /* Reason code that indicates why the
+ HINSTANCE hinstDLL, /*!< in: handle to the DLL module */
+ DWORD fdwReason, /*!< Reason code that indicates why the
DLL entry-point function is being
called.*/
- LPVOID lpvReserved) /* in: additional parameter based on
+ LPVOID lpvReserved) /*!< in: additional parameter based on
fdwReason */
{
BOOL success = TRUE;
@@ -939,19 +927,19 @@ DllMain(
}
#ifndef DBUG_OFF
-/******************************************************************
+/**************************************************************//**
Process entry point to user function. It makes the call to _db_enter_
in mysqld.exe. The DBUG functions are defined in my_dbug.h. */
extern "C" UNIV_INTERN
void
_db_enter_(
- const char* _func_, /* in: current function name */
- const char* _file_, /* in: current file name */
- uint _line_, /* in: current source line number */
- const char** _sfunc_, /* out: previous _func_ */
- const char** _sfile_, /* out: previous _file_ */
- uint* _slevel_, /* out: previous nesting level */
- char*** _sframep_) /* out: previous frame pointer */
+ const char* _func_, /*!< in: current function name */
+ const char* _file_, /*!< in: current file name */
+ uint _line_, /*!< in: current source line number */
+ const char** _sfunc_, /*!< out: previous _func_ */
+ const char** _sfile_, /*!< out: previous _file_ */
+ uint* _slevel_, /*!< out: previous nesting level */
+ char*** _sframep_) /*!< out: previous frame pointer */
{
if (wdl_db_enter_ != NULL) {
@@ -960,16 +948,16 @@ _db_enter_(
}
}
-/******************************************************************
+/**************************************************************//**
Process exit from user function. It makes the call to _db_return_()
in the server. */
extern "C" UNIV_INTERN
void
_db_return_(
- uint _line_, /* in: current source line number */
- const char** _sfunc_, /* out: previous _func_ */
- const char** _sfile_, /* out: previous _file_ */
- uint* _slevel_) /* out: previous level */
+ uint _line_, /*!< in: current source line number */
+ const char** _sfunc_, /*!< out: previous _func_ */
+ const char** _sfile_, /*!< out: previous _file_ */
+ uint* _slevel_) /*!< out: previous level */
{
if (wdl_db_return_ != NULL) {
@@ -977,14 +965,14 @@ _db_return_(
}
}
-/******************************************************************
+/**************************************************************//**
Log arguments for subsequent use. It makes the call to _db_pargs_()
in the server. */
extern "C" UNIV_INTERN
void
_db_pargs_(
- uint _line_, /* in: current source line number */
- const char* keyword) /* in: keyword for current macro */
+ uint _line_, /*!< in: current source line number */
+ const char* keyword) /*!< in: keyword for current macro */
{
if (wdl_db_pargs_ != NULL) {
@@ -992,15 +980,15 @@ _db_pargs_(
}
}
-/******************************************************************
+/**************************************************************//**
Handle print of debug lines. It saves the text into a buffer first,
then makes the call to _db_doprnt_() in the server. The text is
truncated to the size of buffer. */
extern "C" UNIV_INTERN
void
_db_doprnt_(
- const char* format, /* in: the format string */
- ...) /* in: list of arguments */
+ const char* format, /*!< in: the format string */
+ ...) /*!< in: list of arguments */
{
va_list argp;
char buffer[512];
@@ -1015,16 +1003,16 @@ _db_doprnt_(
}
}
-/******************************************************************
+/**************************************************************//**
Dump a string in hex. It makes the call to _db_dump_() in the server. */
extern "C" UNIV_INTERN
void
_db_dump_(
- uint _line_, /* in: current source line
+ uint _line_, /*!< in: current source line
number */
- const char* keyword, /* in: keyword list */
- const unsigned char* memory, /* in: memory to dump */
- size_t length) /* in: bytes to dump */
+ const char* keyword, /*!< in: keyword list */
+ const unsigned char* memory, /*!< in: memory to dump */
+ size_t length) /*!< in: bytes to dump */
{
if (wdl_db_dump_ != NULL) {
diff --git a/storage/xtradb/ibuf/ibuf0ibuf.c b/storage/xtradb/ibuf/ibuf0ibuf.c
index 5aacd9ae717..a32efbd061f 100644
--- a/storage/xtradb/ibuf/ibuf0ibuf.c
+++ b/storage/xtradb/ibuf/ibuf0ibuf.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file ibuf/ibuf0ibuf.c
Insert buffer
Created 7/19/1997 Heikki Tuuri
@@ -24,10 +25,20 @@ Created 7/19/1997 Heikki Tuuri
#include "ibuf0ibuf.h"
+/** Number of bits describing a single page */
+#define IBUF_BITS_PER_PAGE 4
+#if IBUF_BITS_PER_PAGE % 2
+# error "IBUF_BITS_PER_PAGE must be an even number!"
+#endif
+/** The start address for an insert buffer bitmap page bitmap */
+#define IBUF_BITMAP PAGE_DATA
+
#ifdef UNIV_NONINL
#include "ibuf0ibuf.ic"
#endif
+#ifndef UNIV_HOTBACKUP
+
#include "buf0buf.h"
#include "buf0rea.h"
#include "fsp0fsp.h"
@@ -150,10 +161,10 @@ level 2 i/o. However, if an OS thread does the i/o handling for itself, i.e.,
it uses synchronous aio, it can access any pages, as long as it obeys the
access order rules. */
-/* Buffer pool size per the maximum insert buffer size */
+/** Buffer pool size per the maximum insert buffer size */
#define IBUF_POOL_SIZE_PER_MAX_SIZE 2
-/* Table name for the insert buffer. */
+/** Table name for the insert buffer. */
#define IBUF_TABLE_NAME "SYS_IBUF_TABLE"
/** Operations that can currently be buffered. */
@@ -162,24 +173,26 @@ UNIV_INTERN ibuf_use_t ibuf_use = IBUF_USE_INSERT;
/** The insert buffer control structure */
UNIV_INTERN ibuf_t* ibuf = NULL;
+/** Counter for ibuf_should_try() */
UNIV_INTERN ulint ibuf_flush_count = 0;
#ifdef UNIV_IBUF_COUNT_DEBUG
-/* Dimensions for the ibuf_count array */
+/** Number of tablespaces in the ibuf_counts array */
#define IBUF_COUNT_N_SPACES 4
+/** Number of pages within each tablespace in the ibuf_counts array */
#define IBUF_COUNT_N_PAGES 130000
-/* Buffered entry counts for file pages, used in debugging */
+/** Buffered entry counts for file pages, used in debugging */
static ulint ibuf_counts[IBUF_COUNT_N_SPACES][IBUF_COUNT_N_PAGES];
-/**********************************************************************
+/******************************************************************//**
Checks that the indexes to ibuf_counts[][] are within limits. */
UNIV_INLINE
void
ibuf_count_check(
/*=============*/
- ulint space_id, /* in: space identifier */
- ulint page_no) /* in: page number */
+ ulint space_id, /*!< in: space identifier */
+ ulint page_no) /*!< in: page number */
{
if (space_id < IBUF_COUNT_N_SPACES && page_no < IBUF_COUNT_N_PAGES) {
return;
@@ -196,52 +209,52 @@ ibuf_count_check(
}
#endif
-/* The start address for an insert buffer bitmap page bitmap */
-#define IBUF_BITMAP PAGE_DATA
-
-/* Offsets in bits for the bits describing a single page in the bitmap */
-#define IBUF_BITMAP_FREE 0
-#define IBUF_BITMAP_BUFFERED 2
-#define IBUF_BITMAP_IBUF 3 /* TRUE if page is a part of the ibuf
- tree, excluding the root page, or is
- in the free list of the ibuf */
-
-/* Number of bits describing a single page */
-#define IBUF_BITS_PER_PAGE 4
-#if IBUF_BITS_PER_PAGE % 2
-# error "IBUF_BITS_PER_PAGE must be an even number!"
-#endif
-
-/* The mutex used to block pessimistic inserts to ibuf trees */
+/** @name Offsets to the per-page bits in the insert buffer bitmap */
+/* @{ */
+#define IBUF_BITMAP_FREE 0 /*!< Bits indicating the
+ amount of free space */
+#define IBUF_BITMAP_BUFFERED 2 /*!< TRUE if there are buffered
+ changes for the page */
+#define IBUF_BITMAP_IBUF 3 /*!< TRUE if page is a part of
+ the ibuf tree, excluding the
+ root page, or is in the free
+ list of the ibuf */
+/* @} */
+
+/** The mutex used to block pessimistic inserts to ibuf trees */
static mutex_t ibuf_pessimistic_insert_mutex;
-/* The mutex protecting the insert buffer structs */
+/** The mutex protecting the insert buffer structs */
static mutex_t ibuf_mutex;
-/* The mutex protecting the insert buffer bitmaps */
+/** The mutex protecting the insert buffer bitmaps */
static mutex_t ibuf_bitmap_mutex;
-/* The area in pages from which contract looks for page numbers for merge */
+/** The area in pages from which contract looks for page numbers for merge */
#define IBUF_MERGE_AREA 8
-/* Inside the merge area, pages which have at most 1 per this number less
+/** Inside the merge area, pages which have at most 1 per this number less
buffered entries compared to maximum volume that can buffered for a single
page are merged along with the page whose buffer became full */
#define IBUF_MERGE_THRESHOLD 4
-/* In ibuf_contract at most this number of pages is read to memory in one
+/** In ibuf_contract at most this number of pages is read to memory in one
batch, in order to merge the entries for them in the insert buffer */
#define IBUF_MAX_N_PAGES_MERGED IBUF_MERGE_AREA
-/* If the combined size of the ibuf trees exceeds ibuf->max_size by this
+/** If the combined size of the ibuf trees exceeds ibuf->max_size by this
many pages, we start to contract it in connection to inserts there, using
non-synchronous contract */
#define IBUF_CONTRACT_ON_INSERT_NON_SYNC 0
-/* Same as above, but use synchronous contract */
+/** If the combined size of the ibuf trees exceeds ibuf->max_size by this
+many pages, we start to contract it in connection to inserts there, using
+synchronous contract */
#define IBUF_CONTRACT_ON_INSERT_SYNC 5
-/* Same as above, but no insert is done, only contract is called */
+/** If the combined size of the ibuf trees exceeds ibuf->max_size by
+this many pages, we start to contract it synchronous contract, but do
+not insert */
#define IBUF_CONTRACT_DO_NOT_INSERT 10
/* TODO: how to cope with drop table if there are records in the insert
@@ -250,7 +263,7 @@ because ibuf merge is done to a page when it is read in, and it is
still physically like the index page even if the index would have been
dropped! So, there seems to be no problem. */
-/**********************************************************************
+/******************************************************************//**
Sets the flag in the current OS thread local storage denoting that it is
inside an insert buffer routine. */
UNIV_INLINE
@@ -267,7 +280,7 @@ ibuf_enter(void)
*ptr = TRUE;
}
-/**********************************************************************
+/******************************************************************//**
Sets the flag in the current OS thread local storage denoting that it is
exiting an insert buffer routine. */
UNIV_INLINE
@@ -284,27 +297,29 @@ ibuf_exit(void)
*ptr = FALSE;
}
-/**********************************************************************
+/******************************************************************//**
Returns TRUE if the current OS thread is performing an insert buffer
-routine. */
+routine.
+
+For instance, a read-ahead of non-ibuf pages is forbidden by threads
+that are executing an insert buffer routine.
+@return TRUE if inside an insert buffer routine */
UNIV_INTERN
ibool
ibuf_inside(void)
/*=============*/
- /* out: TRUE if inside an insert buffer routine: for instance,
- a read-ahead of non-ibuf pages is then forbidden */
{
return(*thr_local_get_in_ibuf_field());
}
-/**********************************************************************
-Gets the ibuf header page and x-latches it. */
+/******************************************************************//**
+Gets the ibuf header page and x-latches it.
+@return insert buffer header page */
static
page_t*
ibuf_header_page_get(
/*=================*/
- /* out: insert buffer header page */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
@@ -317,14 +332,14 @@ ibuf_header_page_get(
return(buf_block_get_frame(block));
}
-/**********************************************************************
-Gets the root page and x-latches it. */
+/******************************************************************//**
+Gets the root page and x-latches it.
+@return insert buffer tree root page */
static
page_t*
ibuf_tree_root_get(
/*===============*/
- /* out: insert buffer tree root page */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
@@ -341,31 +356,31 @@ ibuf_tree_root_get(
}
#ifdef UNIV_IBUF_COUNT_DEBUG
-/**********************************************************************
-Gets the ibuf count for a given page. */
+/******************************************************************//**
+Gets the ibuf count for a given page.
+@return number of entries in the insert buffer currently buffered for
+this page */
UNIV_INTERN
ulint
ibuf_count_get(
/*===========*/
- /* out: number of entries in the insert buffer
- currently buffered for this page */
- ulint space, /* in: space id */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space id */
+ ulint page_no)/*!< in: page number */
{
ibuf_count_check(space, page_no);
return(ibuf_counts[space][page_no]);
}
-/**********************************************************************
+/******************************************************************//**
Sets the ibuf count for a given page. */
static
void
ibuf_count_set(
/*===========*/
- ulint space, /* in: space id */
- ulint page_no,/* in: page number */
- ulint val) /* in: value to set */
+ ulint space, /*!< in: space id */
+ ulint page_no,/*!< in: page number */
+ ulint val) /*!< in: value to set */
{
ibuf_count_check(space, page_no);
ut_a(val < UNIV_PAGE_SIZE);
@@ -374,15 +389,15 @@ ibuf_count_set(
}
#endif
-/**********************************************************************
+/******************************************************************//**
Updates the size information of the ibuf, assuming the segment size has not
changed. */
static
void
ibuf_size_update(
/*=============*/
- const page_t* root, /* in: ibuf tree root */
- mtr_t* mtr) /* in: mtr */
+ const page_t* root, /*!< in: ibuf tree root */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mutex_own(&ibuf_mutex));
@@ -397,7 +412,7 @@ ibuf_size_update(
ibuf->empty = page_get_n_recs(root) == 0;
}
-/**********************************************************************
+/******************************************************************//**
Creates the insert buffer data structure at a database startup and initializes
the data structures for the insert buffer. */
UNIV_INTERN
@@ -495,15 +510,15 @@ ibuf_init_at_db_start(void)
ibuf->index = dict_table_get_first_index(table);
}
-
-/*************************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************************//**
Initializes an ibuf bitmap page. */
UNIV_INTERN
void
ibuf_bitmap_page_init(
/*==================*/
- buf_block_t* block, /* in: bitmap page */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in: bitmap page */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* page;
ulint byte_offset;
@@ -527,20 +542,22 @@ ibuf_bitmap_page_init(
/* The remaining area (up to the page trailer) is uninitialized. */
+#ifndef UNIV_HOTBACKUP
mlog_write_initial_log_record(page, MLOG_IBUF_BITMAP_INIT, mtr);
+#endif /* !UNIV_HOTBACKUP */
}
-/*************************************************************************
-Parses a redo log record of an ibuf bitmap page init. */
+/*********************************************************************//**
+Parses a redo log record of an ibuf bitmap page init.
+@return end of log record or NULL */
UNIV_INTERN
byte*
ibuf_parse_bitmap_init(
/*===================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr __attribute__((unused)), /* in: buffer end */
- buf_block_t* block, /* in: block or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr __attribute__((unused)), /*!< in: buffer end */
+ buf_block_t* block, /*!< in: block or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ut_ad(ptr && end_ptr);
@@ -550,22 +567,22 @@ ibuf_parse_bitmap_init(
return(ptr);
}
-
-/************************************************************************
-Gets the desired bits for a given page from a bitmap page. */
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Gets the desired bits for a given page from a bitmap page.
+@return value of bits */
UNIV_INLINE
ulint
ibuf_bitmap_page_get_bits(
/*======================*/
- /* out: value of bits */
- const page_t* page, /* in: bitmap page */
- ulint page_no,/* in: page whose bits to get */
- ulint zip_size,/* in: compressed page size in bytes;
+ const page_t* page, /*!< in: bitmap page */
+ ulint page_no,/*!< in: page whose bits to get */
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint bit, /* in: IBUF_BITMAP_FREE,
+ ulint bit, /*!< in: IBUF_BITMAP_FREE,
IBUF_BITMAP_BUFFERED, ... */
mtr_t* mtr __attribute__((unused)))
- /* in: mtr containing an
+ /*!< in: mtr containing an
x-latch to the bitmap page */
{
ulint byte_offset;
@@ -606,19 +623,19 @@ ibuf_bitmap_page_get_bits(
return(value);
}
-/************************************************************************
+/********************************************************************//**
Sets the desired bit for a given page in a bitmap page. */
static
void
ibuf_bitmap_page_set_bits(
/*======================*/
- page_t* page, /* in: bitmap page */
- ulint page_no,/* in: page whose bits to set */
- ulint zip_size,/* in: compressed page size in bytes;
+ page_t* page, /*!< in: bitmap page */
+ ulint page_no,/*!< in: page whose bits to set */
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint bit, /* in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ... */
- ulint val, /* in: value to set */
- mtr_t* mtr) /* in: mtr containing an x-latch to the bitmap page */
+ ulint bit, /*!< in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ... */
+ ulint val, /*!< in: value to set */
+ mtr_t* mtr) /*!< in: mtr containing an x-latch to the bitmap page */
{
ulint byte_offset;
ulint bit_offset;
@@ -665,17 +682,16 @@ ibuf_bitmap_page_set_bits(
MLOG_1BYTE, mtr);
}
-/************************************************************************
-Calculates the bitmap page number for a given page number. */
+/********************************************************************//**
+Calculates the bitmap page number for a given page number.
+@return the bitmap page number where the file page is mapped */
UNIV_INLINE
ulint
ibuf_bitmap_page_no_calc(
/*=====================*/
- /* out: the bitmap page number where
- the file page is mapped */
- ulint zip_size, /* in: compressed page size in bytes;
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint page_no) /* in: tablespace page number */
+ ulint page_no) /*!< in: tablespace page number */
{
ut_ad(ut_is_2pow(zip_size));
@@ -688,22 +704,21 @@ ibuf_bitmap_page_no_calc(
}
}
-/************************************************************************
+/********************************************************************//**
Gets the ibuf bitmap page where the bits describing a given file page are
-stored. */
+stored.
+@return bitmap page where the file page is mapped, that is, the bitmap
+page containing the descriptor bits for the file page; the bitmap page
+is x-latched */
static
page_t*
ibuf_bitmap_get_map_page(
/*=====================*/
- /* out: bitmap page where the file page is mapped,
- that is, the bitmap page containing the descriptor
- bits for the file page; the bitmap page is
- x-latched */
- ulint space, /* in: space id of the file page */
- ulint page_no,/* in: page number of the file page */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint space, /*!< in: space id of the file page */
+ ulint page_no,/*!< in: page number of the file page */
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
@@ -715,7 +730,7 @@ ibuf_bitmap_get_map_page(
return(buf_block_get_frame(block));
}
-/****************************************************************************
+/************************************************************************//**
Sets the free bits of the page in the ibuf bitmap. This is done in a separate
mini-transaction, hence this operation does not restrict further work to only
ibuf bitmap operations, which would result if the latch to the bitmap page
@@ -724,13 +739,13 @@ UNIV_INLINE
void
ibuf_set_free_bits_low(
/*===================*/
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- const buf_block_t* block, /* in: index page; free bits are set if
+ const buf_block_t* block, /*!< in: index page; free bits are set if
the index is non-clustered and page
level is 0 */
- ulint val, /* in: value to set: < 4 */
- mtr_t* mtr) /* in/out: mtr */
+ ulint val, /*!< in: value to set: < 4 */
+ mtr_t* mtr) /*!< in/out: mtr */
{
page_t* bitmap_page;
ulint space;
@@ -758,7 +773,7 @@ ibuf_set_free_bits_low(
IBUF_BITMAP_FREE, val, mtr);
}
-/****************************************************************************
+/************************************************************************//**
Sets the free bit of the page in the ibuf bitmap. This is done in a separate
mini-transaction, hence this operation does not restrict further work to only
ibuf bitmap operations, which would result if the latch to the bitmap page
@@ -767,14 +782,14 @@ UNIV_INTERN
void
ibuf_set_free_bits_func(
/*====================*/
- buf_block_t* block, /* in: index page of a non-clustered index;
+ buf_block_t* block, /*!< in: index page of a non-clustered index;
free bit is reset if page level is 0 */
#ifdef UNIV_IBUF_DEBUG
- ulint max_val,/* in: ULINT_UNDEFINED or a maximum
+ ulint max_val,/*!< in: ULINT_UNDEFINED or a maximum
value which the bits must have before
setting; this is for debugging */
#endif /* UNIV_IBUF_DEBUG */
- ulint val) /* in: value to set: < 4 */
+ ulint val) /*!< in: value to set: < 4 */
{
mtr_t mtr;
page_t* page;
@@ -828,7 +843,7 @@ ibuf_set_free_bits_func(
mtr_commit(&mtr);
}
-/****************************************************************************
+/************************************************************************//**
Resets the free bits of the page in the ibuf bitmap. This is done in a
separate mini-transaction, hence this operation does not restrict
further work to only ibuf bitmap operations, which would result if the
@@ -841,14 +856,14 @@ UNIV_INTERN
void
ibuf_reset_free_bits(
/*=================*/
- buf_block_t* block) /* in: index page; free bits are set to 0
+ buf_block_t* block) /*!< in: index page; free bits are set to 0
if the index is a non-clustered
non-unique, and page level is 0 */
{
ibuf_set_free_bits(block, 0, ULINT_UNDEFINED);
}
-/**************************************************************************
+/**********************************************************************//**
Updates the free bits for an uncompressed page to reflect the present
state. Does this in the mtr given, which means that the latching
order rules virtually prevent any further operations for this OS
@@ -860,13 +875,13 @@ UNIV_INTERN
void
ibuf_update_free_bits_low(
/*======================*/
- const buf_block_t* block, /* in: index page */
- ulint max_ins_size, /* in: value of
+ const buf_block_t* block, /*!< in: index page */
+ ulint max_ins_size, /*!< in: value of
maximum insert size
with reorganize before
the latest operation
performed to the page */
- mtr_t* mtr) /* in/out: mtr */
+ mtr_t* mtr) /*!< in/out: mtr */
{
ulint before;
ulint after;
@@ -886,7 +901,7 @@ ibuf_update_free_bits_low(
}
}
-/**************************************************************************
+/**********************************************************************//**
Updates the free bits for a compressed page to reflect the present
state. Does this in the mtr given, which means that the latching
order rules virtually prevent any further operations for this OS
@@ -898,8 +913,8 @@ UNIV_INTERN
void
ibuf_update_free_bits_zip(
/*======================*/
- buf_block_t* block, /* in/out: index page */
- mtr_t* mtr) /* in/out: mtr */
+ buf_block_t* block, /*!< in/out: index page */
+ mtr_t* mtr) /*!< in/out: mtr */
{
page_t* bitmap_page;
ulint space;
@@ -931,7 +946,7 @@ ibuf_update_free_bits_zip(
IBUF_BITMAP_FREE, after, mtr);
}
-/**************************************************************************
+/**********************************************************************//**
Updates the free bits for the two pages to reflect the present state.
Does this in the mtr given, which means that the latching order rules
virtually prevent any further operations until mtr is committed.
@@ -942,11 +957,11 @@ UNIV_INTERN
void
ibuf_update_free_bits_for_two_pages_low(
/*====================================*/
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- buf_block_t* block1, /* in: index page */
- buf_block_t* block2, /* in: index page */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block1, /*!< in: index page */
+ buf_block_t* block2, /*!< in: index page */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint state;
@@ -967,34 +982,34 @@ ibuf_update_free_bits_for_two_pages_low(
mutex_exit(&ibuf_bitmap_mutex);
}
-/**************************************************************************
-Returns TRUE if the page is one of the fixed address ibuf pages. */
+/**********************************************************************//**
+Returns TRUE if the page is one of the fixed address ibuf pages.
+@return TRUE if a fixed address ibuf i/o page */
UNIV_INLINE
ibool
ibuf_fixed_addr_page(
/*=================*/
- /* out: TRUE if a fixed address ibuf i/o page */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint page_no)/* in: page number */
+ ulint page_no)/*!< in: page number */
{
return((space == IBUF_SPACE_ID && page_no == IBUF_TREE_ROOT_PAGE_NO)
|| ibuf_bitmap_page(zip_size, page_no));
}
-/***************************************************************************
+/***********************************************************************//**
Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages.
-Must not be called when recv_no_ibuf_operations==TRUE. */
+Must not be called when recv_no_ibuf_operations==TRUE.
+@return TRUE if level 2 or level 3 page */
UNIV_INTERN
ibool
ibuf_page(
/*======*/
- /* out: TRUE if level 2 or level 3 page */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint page_no,/* in: page number */
- mtr_t* mtr) /* in: mtr which will contain an x-latch to the
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint page_no,/*!< in: page number */
+ mtr_t* mtr) /*!< in: mtr which will contain an x-latch to the
bitmap page if the page is not one of the fixed
address ibuf pages, or NULL, in which case a new
transaction is created. */
@@ -1032,14 +1047,14 @@ ibuf_page(
return(ret);
}
-/************************************************************************
-Returns the page number field of an ibuf record. */
+/********************************************************************//**
+Returns the page number field of an ibuf record.
+@return page number */
static
ulint
ibuf_rec_get_page_no(
/*=================*/
- /* out: page number */
- const rec_t* rec) /* in: ibuf record */
+ const rec_t* rec) /*!< in: ibuf record */
{
const byte* field;
ulint len;
@@ -1066,15 +1081,15 @@ ibuf_rec_get_page_no(
return(mach_read_from_4(field));
}
-/************************************************************************
+/********************************************************************//**
Returns the space id field of an ibuf record. For < 4.1.x format records
-returns 0. */
+returns 0.
+@return space id */
static
ulint
ibuf_rec_get_space(
/*===============*/
- /* out: space id */
- const rec_t* rec) /* in: ibuf record */
+ const rec_t* rec) /*!< in: ibuf record */
{
const byte* field;
ulint len;
@@ -1100,16 +1115,16 @@ ibuf_rec_get_space(
return(0);
}
-/************************************************************************
+/********************************************************************//**
Creates a dummy index for inserting a record to a non-clustered index.
-*/
+
+@return dummy index */
static
dict_index_t*
ibuf_dummy_index_create(
/*====================*/
- /* out: dummy index */
- ulint n, /* in: number of fields */
- ibool comp) /* in: TRUE=use compact record format */
+ ulint n, /*!< in: number of fields */
+ ibool comp) /*!< in: TRUE=use compact record format */
{
dict_table_t* table;
dict_index_t* index;
@@ -1128,15 +1143,15 @@ ibuf_dummy_index_create(
return(index);
}
-/************************************************************************
+/********************************************************************//**
Add a column to the dummy index */
static
void
ibuf_dummy_index_add_col(
/*=====================*/
- dict_index_t* index, /* in: dummy index */
- const dtype_t* type, /* in: the data type of the column */
- ulint len) /* in: length of the column */
+ dict_index_t* index, /*!< in: dummy index */
+ const dtype_t* type, /*!< in: the data type of the column */
+ ulint len) /*!< in: length of the column */
{
ulint i = index->table->n_def;
dict_mem_table_add_col(index->table, NULL, NULL,
@@ -1146,14 +1161,13 @@ ibuf_dummy_index_add_col(
dict_index_add_col(index, index->table,
dict_table_get_nth_col(index->table, i), len);
}
-/************************************************************************
-Deallocates a dummy index for inserting a record to a non-clustered index.
-*/
+/********************************************************************//**
+Deallocates a dummy index for inserting a record to a non-clustered index. */
static
void
ibuf_dummy_index_free(
/*==================*/
- dict_index_t* index) /* in: dummy index */
+ dict_index_t* index) /*!< in, own: dummy index */
{
dict_table_t* table = index->table;
@@ -1161,22 +1175,21 @@ ibuf_dummy_index_free(
dict_mem_table_free(table);
}
-/*************************************************************************
+/*********************************************************************//**
Builds the entry to insert into a non-clustered index when we have the
-corresponding record in an ibuf index. */
+corresponding record in an ibuf index.
+
+NOTE that as we copy pointers to fields in ibuf_rec, the caller must
+hold a latch to the ibuf_rec page as long as the entry is used!
+
+@return own: entry to insert to a non-clustered index */
UNIV_INLINE
dtuple_t*
ibuf_build_entry_pre_4_1_x(
/*=======================*/
- /* out, own: entry to insert to
- a non-clustered index; NOTE that
- as we copy pointers to fields in
- ibuf_rec, the caller must hold a
- latch to the ibuf_rec page as long
- as the entry is used! */
- const rec_t* ibuf_rec, /* in: record in an insert buffer */
- mem_heap_t* heap, /* in: heap where built */
- dict_index_t** pindex) /* out, own: dummy index that
+ const rec_t* ibuf_rec, /*!< in: record in an insert buffer */
+ mem_heap_t* heap, /*!< in: heap where built */
+ dict_index_t** pindex) /*!< out, own: dummy index that
describes the entry */
{
ulint i;
@@ -1214,22 +1227,21 @@ ibuf_build_entry_pre_4_1_x(
return(tuple);
}
-/*************************************************************************
+/*********************************************************************//**
Builds the entry to insert into a non-clustered index when we have the
-corresponding record in an ibuf index. */
+corresponding record in an ibuf index.
+
+NOTE that as we copy pointers to fields in ibuf_rec, the caller must
+hold a latch to the ibuf_rec page as long as the entry is used!
+
+@return own: entry to insert to a non-clustered index */
static
dtuple_t*
ibuf_build_entry_from_ibuf_rec(
/*===========================*/
- /* out, own: entry to insert to
- a non-clustered index; NOTE that
- as we copy pointers to fields in
- ibuf_rec, the caller must hold a
- latch to the ibuf_rec page as long
- as the entry is used! */
- const rec_t* ibuf_rec, /* in: record in an insert buffer */
- mem_heap_t* heap, /* in: heap where built */
- dict_index_t** pindex) /* out, own: dummy index that
+ const rec_t* ibuf_rec, /*!< in: record in an insert buffer */
+ mem_heap_t* heap, /*!< in: heap where built */
+ dict_index_t** pindex) /*!< out, own: dummy index that
describes the entry */
{
dtuple_t* tuple;
@@ -1300,17 +1312,16 @@ ibuf_build_entry_from_ibuf_rec(
return(tuple);
}
-/************************************************************************
+/********************************************************************//**
Returns the space taken by a stored non-clustered index entry if converted to
-an index record. */
+an index record.
+@return size of index record in bytes + an upper limit of the space
+taken in the page directory */
static
ulint
ibuf_rec_get_volume(
/*================*/
- /* out: size of index record in bytes
- + an upper limit of the space taken in the
- page directory */
- const rec_t* ibuf_rec)/* in: ibuf record */
+ const rec_t* ibuf_rec)/*!< in: ibuf record */
{
dtype_t dtype;
ibool new_format = FALSE;
@@ -1320,6 +1331,7 @@ ibuf_rec_get_volume(
const byte* data;
ulint len;
ulint i;
+ ulint comp;
ut_ad(ibuf_inside());
ut_ad(rec_get_n_fields_old(ibuf_rec) > 2);
@@ -1337,6 +1349,7 @@ ibuf_rec_get_volume(
types = rec_get_nth_field_old(ibuf_rec, 1, &len);
ut_ad(len == n_fields * DATA_ORDER_NULL_TYPE_BUF_SIZE);
+ comp = 0;
} else {
/* >= 4.1.x format record */
@@ -1345,8 +1358,10 @@ ibuf_rec_get_volume(
types = rec_get_nth_field_old(ibuf_rec, 3, &len);
- ut_a(len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE <= 1);
- if (len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE) {
+ comp = len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE;
+
+ ut_a(comp <= 1);
+ if (comp) {
/* compact record format */
ulint volume;
dict_index_t* dummy_index;
@@ -1380,7 +1395,7 @@ ibuf_rec_get_volume(
}
if (len == UNIV_SQL_NULL) {
- data_size += dtype_get_sql_null_size(&dtype);
+ data_size += dtype_get_sql_null_size(&dtype, comp);
} else {
data_size += len;
}
@@ -1390,23 +1405,24 @@ ibuf_rec_get_volume(
+ page_dir_calc_reserved_space(1));
}
-/*************************************************************************
+/*********************************************************************//**
Builds the tuple to insert to an ibuf tree when we have an entry for a
-non-clustered index. */
+non-clustered index.
+
+NOTE that the original entry must be kept because we copy pointers to
+its fields.
+
+@return own: entry to insert into an ibuf index tree */
static
dtuple_t*
ibuf_entry_build(
/*=============*/
- /* out, own: entry to insert into an ibuf
- index tree; NOTE that the original entry
- must be kept because we copy pointers to its
- fields */
- dict_index_t* index, /* in: non-clustered index */
- const dtuple_t* entry, /* in: entry for a non-clustered index */
- ulint space, /* in: space id */
- ulint page_no,/* in: index page number where entry should
+ dict_index_t* index, /*!< in: non-clustered index */
+ const dtuple_t* entry, /*!< in: entry for a non-clustered index */
+ ulint space, /*!< in: space id */
+ ulint page_no,/*!< in: index page number where entry should
be inserted */
- mem_heap_t* heap) /* in: heap into which to build */
+ mem_heap_t* heap) /*!< in: heap into which to build */
{
dtuple_t* tuple;
dfield_t* field;
@@ -1530,17 +1546,17 @@ ibuf_entry_build(
return(tuple);
}
-/*************************************************************************
+/*********************************************************************//**
Builds a search tuple used to search buffered inserts for an index page.
-This is for < 4.1.x format records */
+This is for < 4.1.x format records
+@return own: search tuple */
static
dtuple_t*
ibuf_search_tuple_build(
/*====================*/
- /* out, own: search tuple */
- ulint space, /* in: space id */
- ulint page_no,/* in: index page number */
- mem_heap_t* heap) /* in: heap into which to build */
+ ulint space, /*!< in: space id */
+ ulint page_no,/*!< in: index page number */
+ mem_heap_t* heap) /*!< in: heap into which to build */
{
dtuple_t* tuple;
dfield_t* field;
@@ -1567,17 +1583,17 @@ ibuf_search_tuple_build(
return(tuple);
}
-/*************************************************************************
+/*********************************************************************//**
Builds a search tuple used to search buffered inserts for an index page.
-This is for >= 4.1.x format records. */
+This is for >= 4.1.x format records.
+@return own: search tuple */
static
dtuple_t*
ibuf_new_search_tuple_build(
/*========================*/
- /* out, own: search tuple */
- ulint space, /* in: space id */
- ulint page_no,/* in: index page number */
- mem_heap_t* heap) /* in: heap into which to build */
+ ulint space, /*!< in: space id */
+ ulint page_no,/*!< in: index page number */
+ mem_heap_t* heap) /*!< in: heap into which to build */
{
dtuple_t* tuple;
dfield_t* field;
@@ -1622,14 +1638,14 @@ ibuf_new_search_tuple_build(
return(tuple);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if there are enough pages in the free list of the ibuf tree that we
-dare to start a pessimistic insert to the insert buffer. */
+dare to start a pessimistic insert to the insert buffer.
+@return TRUE if enough free pages in list */
UNIV_INLINE
ibool
ibuf_data_enough_free_for_insert(void)
/*==================================*/
- /* out: TRUE if enough free pages in list */
{
ut_ad(mutex_own(&ibuf_mutex));
@@ -1642,29 +1658,28 @@ ibuf_data_enough_free_for_insert(void)
return(ibuf->free_list_len >= (ibuf->size / 2) + 3 * ibuf->height);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if there are enough pages in the free list of the ibuf tree that we
-should remove them and free to the file space management. */
+should remove them and free to the file space management.
+@return TRUE if enough free pages in list */
UNIV_INLINE
ibool
ibuf_data_too_much_free(void)
/*=========================*/
- /* out: TRUE if enough free pages in list */
{
ut_ad(mutex_own(&ibuf_mutex));
return(ibuf->free_list_len >= 3 + (ibuf->size / 2) + 3 * ibuf->height);
}
-/*************************************************************************
+/*********************************************************************//**
Allocates a new page from the ibuf file segment and adds it to the free
-list. */
+list.
+@return DB_SUCCESS, or DB_STRONG_FAIL if no space left */
static
ulint
ibuf_add_free_page(void)
/*====================*/
- /* out: DB_SUCCESS, or DB_STRONG_FAIL
- if no space left */
{
mtr_t mtr;
page_t* header_page;
@@ -1751,7 +1766,7 @@ ibuf_add_free_page(void)
return(DB_SUCCESS);
}
-/*************************************************************************
+/*********************************************************************//**
Removes a page from the free list and frees it to the fsp system. */
static
void
@@ -1876,7 +1891,7 @@ ibuf_remove_free_page(void)
ibuf_exit();
}
-/***************************************************************************
+/***********************************************************************//**
Frees excess pages from the ibuf free list. This function is called when an OS
thread calls fsp services to allocate a new file segment, or a new page to a
file segment, and the thread did not own the fsp latch before this call. */
@@ -1928,28 +1943,28 @@ ibuf_free_excess_pages(void)
}
}
-/*************************************************************************
-Reads page numbers from a leaf in an ibuf tree. */
+/*********************************************************************//**
+Reads page numbers from a leaf in an ibuf tree.
+@return a lower limit for the combined volume of records which will be
+merged */
static
ulint
ibuf_get_merge_page_nos(
/*====================*/
- /* out: a lower limit for the combined volume
- of records which will be merged */
- ibool contract,/* in: TRUE if this function is called to
+ ibool contract,/*!< in: TRUE if this function is called to
contract the tree, FALSE if this is called
when a single page becomes full and we look
if it pays to read also nearby pages */
- rec_t* rec, /* in: record from which we read up and down
+ rec_t* rec, /*!< in: record from which we read up and down
in the chain of records */
- ulint* space_ids,/* in/out: space id's of the pages */
- ib_int64_t* space_versions,/* in/out: tablespace version
+ ulint* space_ids,/*!< in/out: space id's of the pages */
+ ib_int64_t* space_versions,/*!< in/out: tablespace version
timestamps; used to prevent reading in old
pages after DISCARD + IMPORT tablespace */
- ulint* page_nos,/* in/out: buffer for at least
+ ulint* page_nos,/*!< in/out: buffer for at least
IBUF_MAX_N_PAGES_MERGED many page numbers;
the page numbers are in an ascending order */
- ulint* n_stored)/* out: number of page numbers stored to
+ ulint* n_stored)/*!< out: number of page numbers stored to
page_nos in this function */
{
ulint prev_page_no;
@@ -2101,17 +2116,17 @@ ibuf_get_merge_page_nos(
return(sum_volumes);
}
-/*************************************************************************
-Contracts insert buffer trees by reading pages to the buffer pool. */
+/*********************************************************************//**
+Contracts insert buffer trees by reading pages to the buffer pool.
+@return a lower limit for the combined size in bytes of entries which
+will be merged from ibuf trees to the pages read, 0 if ibuf is
+empty */
static
ulint
ibuf_contract_ext(
/*==============*/
- /* out: a lower limit for the combined size in bytes
- of entries which will be merged from ibuf trees to the
- pages read, 0 if ibuf is empty */
- ulint* n_pages,/* out: number of pages to which merged */
- ibool sync) /* in: TRUE if the caller wants to wait for the
+ ulint* n_pages,/*!< out: number of pages to which merged */
+ ibool sync) /*!< in: TRUE if the caller wants to wait for the
issued read with the highest tablespace address
to complete */
{
@@ -2182,16 +2197,16 @@ ibuf_is_empty:
return(sum_sizes + 1);
}
-/*************************************************************************
-Contracts insert buffer trees by reading pages to the buffer pool. */
+/*********************************************************************//**
+Contracts insert buffer trees by reading pages to the buffer pool.
+@return a lower limit for the combined size in bytes of entries which
+will be merged from ibuf trees to the pages read, 0 if ibuf is
+empty */
UNIV_INTERN
ulint
ibuf_contract(
/*==========*/
- /* out: a lower limit for the combined size in bytes
- of entries which will be merged from ibuf trees to the
- pages read, 0 if ibuf is empty */
- ibool sync) /* in: TRUE if the caller wants to wait for the
+ ibool sync) /*!< in: TRUE if the caller wants to wait for the
issued read with the highest tablespace address
to complete */
{
@@ -2200,19 +2215,19 @@ ibuf_contract(
return(ibuf_contract_ext(&n_pages, sync));
}
-/*************************************************************************
-Contracts insert buffer trees by reading pages to the buffer pool. */
+/*********************************************************************//**
+Contracts insert buffer trees by reading pages to the buffer pool.
+@return a lower limit for the combined size in bytes of entries which
+will be merged from ibuf trees to the pages read, 0 if ibuf is
+empty */
UNIV_INTERN
ulint
ibuf_contract_for_n_pages(
/*======================*/
- /* out: a lower limit for the combined size in bytes
- of entries which will be merged from ibuf trees to the
- pages read, 0 if ibuf is empty */
- ibool sync, /* in: TRUE if the caller wants to wait for the
+ ibool sync, /*!< in: TRUE if the caller wants to wait for the
issued read with the highest tablespace address
to complete */
- ulint n_pages)/* in: try to read at least this many pages to
+ ulint n_pages)/*!< in: try to read at least this many pages to
the buffer pool and merge the ibuf contents to
them */
{
@@ -2235,13 +2250,13 @@ ibuf_contract_for_n_pages(
return(sum_bytes);
}
-/*************************************************************************
+/*********************************************************************//**
Contract insert buffer trees after insert if they are too big. */
UNIV_INLINE
void
ibuf_contract_after_insert(
/*=======================*/
- ulint entry_size) /* in: size of a record which was inserted
+ ulint entry_size) /*!< in: size of a record which was inserted
into an ibuf tree */
{
ibool sync;
@@ -2278,26 +2293,24 @@ ibuf_contract_after_insert(
}
}
-/*************************************************************************
+/*********************************************************************//**
Gets an upper limit for the combined size of entries buffered in the insert
-buffer for a given page. */
+buffer for a given page.
+@return upper limit for the volume of buffered inserts for the index
+page, in bytes; UNIV_PAGE_SIZE, if the entries for the index page span
+several pages in the insert buffer */
static
ulint
ibuf_get_volume_buffered(
/*=====================*/
- /* out: upper limit for the volume of
- buffered inserts for the index page, in bytes;
- we may also return UNIV_PAGE_SIZE, if the
- entries for the index page span on several
- pages in the insert buffer */
- btr_pcur_t* pcur, /* in: pcur positioned at a place in an
+ btr_pcur_t* pcur, /*!< in: pcur positioned at a place in an
insert buffer tree where we would insert an
entry for the index page whose number is
page_no, latch mode has to be BTR_MODIFY_PREV
or BTR_MODIFY_TREE */
- ulint space, /* in: space id */
- ulint page_no,/* in: page number of an index page */
- mtr_t* mtr) /* in: mtr */
+ ulint space, /*!< in: space id */
+ ulint page_no,/*!< in: page number of an index page */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint volume;
rec_t* rec;
@@ -2463,7 +2476,7 @@ count_later:
}
}
-/*************************************************************************
+/*********************************************************************//**
Reads the biggest tablespace id from the high end of the insert buffer
tree and updates the counter in fil_system. */
UNIV_INTERN
@@ -2511,24 +2524,24 @@ ibuf_update_max_tablespace_id(void)
fil_set_max_space_id_if_bigger(max_space_id);
}
-/*************************************************************************
+/*********************************************************************//**
Makes an index insert to the insert buffer, instead of directly to the disk
-page, if this is possible. */
+page, if this is possible.
+@return DB_SUCCESS, DB_FAIL, DB_STRONG_FAIL */
static
ulint
ibuf_insert_low(
/*============*/
- /* out: DB_SUCCESS, DB_FAIL, DB_STRONG_FAIL */
- ulint mode, /* in: BTR_MODIFY_PREV or BTR_MODIFY_TREE */
- const dtuple_t* entry, /* in: index entry to insert */
+ ulint mode, /*!< in: BTR_MODIFY_PREV or BTR_MODIFY_TREE */
+ const dtuple_t* entry, /*!< in: index entry to insert */
ulint entry_size,
- /* in: rec_get_converted_size(index, entry) */
- dict_index_t* index, /* in: index where to insert; must not be
+ /*!< in: rec_get_converted_size(index, entry) */
+ dict_index_t* index, /*!< in: index where to insert; must not be
unique or clustered */
- ulint space, /* in: space id where to insert */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint page_no,/* in: page number where to insert */
- que_thr_t* thr) /* in: query thread */
+ ulint space, /*!< in: space id where to insert */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint page_no,/*!< in: page number where to insert */
+ que_thr_t* thr) /*!< in: query thread */
{
big_rec_t* dummy_big_rec;
btr_pcur_t pcur;
@@ -2690,7 +2703,7 @@ ibuf_insert_low(
if (err == DB_SUCCESS) {
/* Update the page max trx id field */
page_update_max_trx_id(btr_cur_get_block(cursor), NULL,
- thr_get_trx(thr)->id);
+ thr_get_trx(thr)->id, &mtr);
}
} else {
ut_ad(mode == BTR_MODIFY_TREE);
@@ -2710,7 +2723,7 @@ ibuf_insert_low(
if (err == DB_SUCCESS) {
/* Update the page max trx id field */
page_update_max_trx_id(btr_cur_get_block(cursor), NULL,
- thr_get_trx(thr)->id);
+ thr_get_trx(thr)->id, &mtr);
}
ibuf_size_update(root, &mtr);
@@ -2764,21 +2777,21 @@ function_exit:
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Makes an index insert to the insert buffer, instead of directly to the disk
page, if this is possible. Does not do insert if the index is clustered
-or unique. */
+or unique.
+@return TRUE if success */
UNIV_INTERN
ibool
ibuf_insert(
/*========*/
- /* out: TRUE if success */
- const dtuple_t* entry, /* in: index entry to insert */
- dict_index_t* index, /* in: index where to insert */
- ulint space, /* in: space id where to insert */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint page_no,/* in: page number where to insert */
- que_thr_t* thr) /* in: query thread */
+ const dtuple_t* entry, /*!< in: index entry to insert */
+ dict_index_t* index, /*!< in: index where to insert */
+ ulint space, /*!< in: space id where to insert */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint page_no,/*!< in: page number where to insert */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
ulint entry_size;
@@ -2830,18 +2843,18 @@ do_insert:
}
}
-/************************************************************************
+/********************************************************************//**
During merge, inserts to an index page a secondary index entry extracted
from the insert buffer. */
static
void
ibuf_insert_to_index_page(
/*======================*/
- dtuple_t* entry, /* in: buffered entry to insert */
- buf_block_t* block, /* in/out: index page where the buffered entry
+ dtuple_t* entry, /*!< in: buffered entry to insert */
+ buf_block_t* block, /*!< in/out: index page where the buffered entry
should be placed */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_cur_t page_cur;
ulint low_match;
@@ -2957,24 +2970,23 @@ dump:
}
}
-/*************************************************************************
+/*********************************************************************//**
Deletes from ibuf the record on which pcur is positioned. If we have to
resort to a pessimistic delete, this function commits mtr and closes
-the cursor. */
+the cursor.
+@return TRUE if mtr was committed and pcur closed in this operation */
static
ibool
ibuf_delete_rec(
/*============*/
- /* out: TRUE if mtr was committed and pcur
- closed in this operation */
- ulint space, /* in: space id */
- ulint page_no,/* in: index page number where the record
+ ulint space, /*!< in: space id */
+ ulint page_no,/*!< in: index page number where the record
should belong */
- btr_pcur_t* pcur, /* in: pcur positioned on the record to
+ btr_pcur_t* pcur, /*!< in: pcur positioned on the record to
delete, having latch mode BTR_MODIFY_LEAF */
const dtuple_t* search_tuple,
- /* in: search tuple for entries of page_no */
- mtr_t* mtr) /* in: mtr */
+ /*!< in: search tuple for entries of page_no */
+ mtr_t* mtr) /*!< in: mtr */
{
ibool success;
page_t* root;
@@ -3073,7 +3085,7 @@ func_exit:
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
When an index page is read from a disk to the buffer pool, this function
inserts to the page the possible index entries buffered in the insert buffer.
The entries are deleted from the insert buffer. If the page is not read, but
@@ -3084,14 +3096,14 @@ UNIV_INTERN
void
ibuf_merge_or_delete_for_page(
/*==========================*/
- buf_block_t* block, /* in: if page has been read from
+ buf_block_t* block, /*!< in: if page has been read from
disk, pointer to the page x-latched,
else NULL */
- ulint space, /* in: space id of the index page */
- ulint page_no,/* in: page number of the index page */
- ulint zip_size,/* in: compressed page size in bytes,
+ ulint space, /*!< in: space id of the index page */
+ ulint page_no,/*!< in: page number of the index page */
+ ulint zip_size,/*!< in: compressed page size in bytes,
or 0 */
- ibool update_ibuf_bitmap)/* in: normally this is set
+ ibool update_ibuf_bitmap)/*!< in: normally this is set
to TRUE, but if we have deleted or are
deleting the tablespace, then we
naturally do not want to update a
@@ -3312,11 +3324,12 @@ loop:
keep the latch to the rec page until the
insertion is finished! */
dtuple_t* entry;
- dulint max_trx_id;
+ trx_id_t max_trx_id;
dict_index_t* dummy_index;
max_trx_id = page_get_max_trx_id(page_align(rec));
- page_update_max_trx_id(block, page_zip, max_trx_id);
+ page_update_max_trx_id(block, page_zip, max_trx_id,
+ &mtr);
entry = ibuf_build_entry_from_ibuf_rec(
rec, heap, &dummy_index);
@@ -3405,7 +3418,7 @@ reset_bit:
#endif
}
-/*************************************************************************
+/*********************************************************************//**
Deletes all entries in the insert buffer for a given space id. This is used
in DISCARD TABLESPACE and IMPORT TABLESPACE.
NOTE: this does not update the page free bitmaps in the space. The space will
@@ -3414,7 +3427,7 @@ UNIV_INTERN
void
ibuf_delete_for_discarded_space(
/*============================*/
- ulint space) /* in: space id */
+ ulint space) /*!< in: space id */
{
mem_heap_t* heap;
btr_pcur_t pcur;
@@ -3504,13 +3517,13 @@ leave_loop:
mem_heap_free(heap);
}
-/**********************************************************************
-Looks if the insert buffer is empty. */
+/******************************************************************//**
+Looks if the insert buffer is empty.
+@return TRUE if empty */
UNIV_INTERN
ibool
ibuf_is_empty(void)
/*===============*/
- /* out: TRUE if empty */
{
ibool is_empty;
const page_t* root;
@@ -3551,13 +3564,13 @@ ibuf_is_empty(void)
return(is_empty);
}
-/**********************************************************************
+/******************************************************************//**
Prints info of ibuf. */
UNIV_INTERN
void
ibuf_print(
/*=======*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
#ifdef UNIV_IBUF_COUNT_DEBUG
ulint i;
@@ -3592,3 +3605,4 @@ ibuf_print(
mutex_exit(&ibuf_mutex);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/btr0btr.h b/storage/xtradb/include/btr0btr.h
index 298942bd542..d5c8258513c 100644
--- a/storage/xtradb/include/btr0btr.h
+++ b/storage/xtradb/include/btr0btr.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/btr0btr.h
The B-tree
Created 6/2/1994 Heikki Tuuri
@@ -33,315 +34,327 @@ Created 6/2/1994 Heikki Tuuri
#include "mtr0mtr.h"
#include "btr0types.h"
-/* Maximum record size which can be stored on a page, without using the
+#ifndef UNIV_HOTBACKUP
+/** Maximum record size which can be stored on a page, without using the
special big record storage structure */
-
#define BTR_PAGE_MAX_REC_SIZE (UNIV_PAGE_SIZE / 2 - 200)
-/* Maximum depth of a B-tree in InnoDB. Note that this isn't a maximum as
-such; none of the tree operations avoid producing trees bigger than this. It
-is instead a "max depth that other code must work with", useful for e.g.
-fixed-size arrays that must store some information about each level in a
-tree. In other words: if a B-tree with bigger depth than this is
-encountered, it is not acceptable for it to lead to mysterious memory
-corruption, but it is acceptable for the program to die with a clear assert
-failure. */
+/** @brief Maximum depth of a B-tree in InnoDB.
+
+Note that this isn't a maximum as such; none of the tree operations
+avoid producing trees bigger than this. It is instead a "max depth
+that other code must work with", useful for e.g. fixed-size arrays
+that must store some information about each level in a tree. In other
+words: if a B-tree with bigger depth than this is encountered, it is
+not acceptable for it to lead to mysterious memory corruption, but it
+is acceptable for the program to die with a clear assert failure. */
#define BTR_MAX_LEVELS 100
-/* Latching modes for btr_cur_search_to_nth_level(). */
-#define BTR_SEARCH_LEAF RW_S_LATCH
-#define BTR_MODIFY_LEAF RW_X_LATCH
-#define BTR_NO_LATCHES RW_NO_LATCH
-#define BTR_MODIFY_TREE 33
-#define BTR_CONT_MODIFY_TREE 34
-#define BTR_SEARCH_PREV 35
-#define BTR_MODIFY_PREV 36
+/** Latching modes for btr_cur_search_to_nth_level(). */
+enum btr_latch_mode {
+ /** Search a record on a leaf page and S-latch it. */
+ BTR_SEARCH_LEAF = RW_S_LATCH,
+ /** (Prepare to) modify a record on a leaf page and X-latch it. */
+ BTR_MODIFY_LEAF = RW_X_LATCH,
+ /** Obtain no latches. */
+ BTR_NO_LATCHES = RW_NO_LATCH,
+ /** Start modifying the entire B-tree. */
+ BTR_MODIFY_TREE = 33,
+ /** Continue modifying the entire B-tree. */
+ BTR_CONT_MODIFY_TREE = 34,
+ /** Search the previous record. */
+ BTR_SEARCH_PREV = 35,
+ /** Modify the previous record. */
+ BTR_MODIFY_PREV = 36
+};
-/* If this is ORed to the latch mode, it means that the search tuple will be
-inserted to the index, at the searched position */
+/** If this is ORed to btr_latch_mode, it means that the search tuple
+will be inserted to the index, at the searched position */
#define BTR_INSERT 512
-/* This flag ORed to latch mode says that we do the search in query
+/** This flag ORed to btr_latch_mode says that we do the search in query
optimization */
#define BTR_ESTIMATE 1024
-/* This flag ORed to latch mode says that we can ignore possible
-UNIQUE definition on secondary indexes when we decide if we can use the
-insert buffer to speed up inserts */
+/** This flag ORed to btr_latch_mode says that we can ignore possible
+UNIQUE definition on secondary indexes when we decide if we can use
+the insert buffer to speed up inserts */
#define BTR_IGNORE_SEC_UNIQUE 2048
-/******************************************************************
-Gets the root node of a tree and x-latches it. */
+/**************************************************************//**
+Gets the root node of a tree and x-latches it.
+@return root page, x-latched */
UNIV_INTERN
page_t*
btr_root_get(
/*=========*/
- /* out: root page, x-latched */
- dict_index_t* index, /* in: index tree */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ dict_index_t* index, /*!< in: index tree */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
Gets a buffer page and declares its latching order level. */
UNIV_INLINE
buf_block_t*
btr_block_get(
/*==========*/
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- ulint mode, /* in: latch mode */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ ulint page_no, /*!< in: page number */
+ ulint mode, /*!< in: latch mode */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
Gets a buffer page and declares its latching order level. */
UNIV_INLINE
page_t*
btr_page_get(
/*=========*/
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- ulint mode, /* in: latch mode */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
-Gets the index id field of a page. */
+ ulint page_no, /*!< in: page number */
+ ulint mode, /*!< in: latch mode */
+ mtr_t* mtr); /*!< in: mtr */
+#endif /* !UNIV_HOTBACKUP */
+/**************************************************************//**
+Gets the index id field of a page.
+@return index id */
UNIV_INLINE
dulint
btr_page_get_index_id(
/*==================*/
- /* out: index id */
- const page_t* page); /* in: index page */
-/************************************************************
-Gets the node level field in an index page. */
+ const page_t* page); /*!< in: index page */
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
+Gets the node level field in an index page.
+@return level, leaf level == 0 */
UNIV_INLINE
ulint
btr_page_get_level_low(
/*===================*/
- /* out: level, leaf level == 0 */
- const page_t* page); /* in: index page */
-/************************************************************
-Gets the node level field in an index page. */
+ const page_t* page); /*!< in: index page */
+/********************************************************//**
+Gets the node level field in an index page.
+@return level, leaf level == 0 */
UNIV_INLINE
ulint
btr_page_get_level(
/*===============*/
- /* out: level, leaf level == 0 */
- const page_t* page, /* in: index page */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
-Gets the next index page number. */
+ const page_t* page, /*!< in: index page */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
+Gets the next index page number.
+@return next page number */
UNIV_INLINE
ulint
btr_page_get_next(
/*==============*/
- /* out: next page number */
- const page_t* page, /* in: index page */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
-Gets the previous index page number. */
+ const page_t* page, /*!< in: index page */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
+Gets the previous index page number.
+@return prev page number */
UNIV_INLINE
ulint
btr_page_get_prev(
/*==============*/
- /* out: prev page number */
- const page_t* page, /* in: index page */
- mtr_t* mtr); /* in: mini-transaction handle */
-/*****************************************************************
+ const page_t* page, /*!< in: index page */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/*************************************************************//**
Gets pointer to the previous user record in the tree. It is assumed
-that the caller has appropriate latches on the page and its neighbor. */
+that the caller has appropriate latches on the page and its neighbor.
+@return previous user record, NULL if there is none */
UNIV_INTERN
rec_t*
btr_get_prev_user_rec(
/*==================*/
- /* out: previous user record, NULL if there is none */
- rec_t* rec, /* in: record on leaf level */
- mtr_t* mtr); /* in: mtr holding a latch on the page, and if
+ rec_t* rec, /*!< in: record on leaf level */
+ mtr_t* mtr); /*!< in: mtr holding a latch on the page, and if
needed, also to the previous page */
-/*****************************************************************
+/*************************************************************//**
Gets pointer to the next user record in the tree. It is assumed
-that the caller has appropriate latches on the page and its neighbor. */
+that the caller has appropriate latches on the page and its neighbor.
+@return next user record, NULL if there is none */
UNIV_INTERN
rec_t*
btr_get_next_user_rec(
/*==================*/
- /* out: next user record, NULL if there is none */
- rec_t* rec, /* in: record on leaf level */
- mtr_t* mtr); /* in: mtr holding a latch on the page, and if
+ rec_t* rec, /*!< in: record on leaf level */
+ mtr_t* mtr); /*!< in: mtr holding a latch on the page, and if
needed, also to the next page */
-/******************************************************************
+/**************************************************************//**
Releases the latch on a leaf page and bufferunfixes it. */
UNIV_INLINE
void
btr_leaf_page_release(
/*==================*/
- buf_block_t* block, /* in: buffer block */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF or
+ buf_block_t* block, /*!< in: buffer block */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
-Gets the child node file address in a node pointer. */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
+Gets the child node file address in a node pointer.
+@return child node address */
UNIV_INLINE
ulint
btr_node_ptr_get_child_page_no(
/*===========================*/
- /* out: child node address */
- const rec_t* rec, /* in: node pointer record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/****************************************************************
-Creates the root node for a new index tree. */
+ const rec_t* rec, /*!< in: node pointer record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/************************************************************//**
+Creates the root node for a new index tree.
+@return page number of the created root, FIL_NULL if did not succeed */
UNIV_INTERN
ulint
btr_create(
/*=======*/
- /* out: page number of the created root,
- FIL_NULL if did not succeed */
- ulint type, /* in: type of the index */
- ulint space, /* in: space where created */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint type, /*!< in: type of the index */
+ ulint space, /*!< in: space where created */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- dulint index_id,/* in: index id */
- dict_index_t* index, /* in: index */
- mtr_t* mtr); /* in: mini-transaction handle */
-/****************************************************************
+ dulint index_id,/*!< in: index id */
+ dict_index_t* index, /*!< in: index */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/************************************************************//**
Frees a B-tree except the root page, which MUST be freed after this
by calling btr_free_root. */
UNIV_INTERN
void
btr_free_but_not_root(
/*==================*/
- ulint space, /* in: space where created */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where created */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint root_page_no); /* in: root page number */
-/****************************************************************
+ ulint root_page_no); /*!< in: root page number */
+/************************************************************//**
Frees the B-tree root page. Other tree MUST already have been freed. */
UNIV_INTERN
void
btr_free_root(
/*==========*/
- ulint space, /* in: space where created */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where created */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint root_page_no, /* in: root page number */
- mtr_t* mtr); /* in: a mini-transaction which has already
+ ulint root_page_no, /*!< in: root page number */
+ mtr_t* mtr); /*!< in: a mini-transaction which has already
been started */
-/*****************************************************************
+/*************************************************************//**
Makes tree one level higher by splitting the root, and inserts
the tuple. It is assumed that mtr contains an x-latch on the tree.
NOTE that the operation of this function must always succeed,
we cannot reverse it: therefore enough free disk space must be
-guaranteed to be available before this function is called. */
+guaranteed to be available before this function is called.
+@return inserted record */
UNIV_INTERN
rec_t*
btr_root_raise_and_insert(
/*======================*/
- /* out: inserted record */
- btr_cur_t* cursor, /* in: cursor at which to insert: must be
+ btr_cur_t* cursor, /*!< in: cursor at which to insert: must be
on the root page; when the function returns,
the cursor is positioned on the predecessor
of the inserted record */
- const dtuple_t* tuple, /* in: tuple to insert */
- ulint n_ext, /* in: number of externally stored columns */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
+ const dtuple_t* tuple, /*!< in: tuple to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ mtr_t* mtr); /*!< in: mtr */
+/*************************************************************//**
Reorganizes an index page.
IMPORTANT: if btr_page_reorganize() is invoked on a compressed leaf
page of a non-clustered index, the caller must update the insert
buffer free bits in the same mini-transaction in such a way that the
-modification will be redo-logged. */
+modification will be redo-logged.
+@return TRUE on success, FALSE on failure */
UNIV_INTERN
ibool
btr_page_reorganize(
/*================*/
- /* out: TRUE on success, FALSE on failure */
- buf_block_t* block, /* in: page to be reorganized */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
+ buf_block_t* block, /*!< in: page to be reorganized */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr); /*!< in: mtr */
+/*************************************************************//**
Decides if the page should be split at the convergence point of
-inserts converging to left. */
+inserts converging to left.
+@return TRUE if split recommended */
UNIV_INTERN
ibool
btr_page_get_split_rec_to_left(
/*===========================*/
- /* out: TRUE if split recommended */
- btr_cur_t* cursor, /* in: cursor at which to insert */
- rec_t** split_rec);/* out: if split recommended,
+ btr_cur_t* cursor, /*!< in: cursor at which to insert */
+ rec_t** split_rec);/*!< out: if split recommended,
the first record on upper half page,
or NULL if tuple should be first */
-/*****************************************************************
+/*************************************************************//**
Decides if the page should be split at the convergence point of
-inserts converging to right. */
+inserts converging to right.
+@return TRUE if split recommended */
UNIV_INTERN
ibool
btr_page_get_split_rec_to_right(
/*============================*/
- /* out: TRUE if split recommended */
- btr_cur_t* cursor, /* in: cursor at which to insert */
- rec_t** split_rec);/* out: if split recommended,
+ btr_cur_t* cursor, /*!< in: cursor at which to insert */
+ rec_t** split_rec);/*!< out: if split recommended,
the first record on upper half page,
or NULL if tuple should be first */
-/*****************************************************************
+/*************************************************************//**
Splits an index page to halves and inserts the tuple. It is assumed
-that mtr holds an x-latch to the index tree. NOTE: the tree x-latch
-is released within this function! NOTE that the operation of this
-function must always succeed, we cannot reverse it: therefore
-enough free disk space must be guaranteed to be available before
-this function is called. */
+that mtr holds an x-latch to the index tree. NOTE: the tree x-latch is
+released within this function! NOTE that the operation of this
+function must always succeed, we cannot reverse it: therefore enough
+free disk space (2 pages) must be guaranteed to be available before
+this function is called.
+
+@return inserted record */
UNIV_INTERN
rec_t*
btr_page_split_and_insert(
/*======================*/
- /* out: inserted record; NOTE: the tree
- x-latch is released! NOTE: 2 free disk
- pages must be available! */
- btr_cur_t* cursor, /* in: cursor at which to insert; when the
+ btr_cur_t* cursor, /*!< in: cursor at which to insert; when the
function returns, the cursor is positioned
on the predecessor of the inserted record */
- const dtuple_t* tuple, /* in: tuple to insert */
- ulint n_ext, /* in: number of externally stored columns */
- mtr_t* mtr); /* in: mtr */
-/***********************************************************
+ const dtuple_t* tuple, /*!< in: tuple to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ mtr_t* mtr); /*!< in: mtr */
+/*******************************************************//**
Inserts a data tuple to a tree on a non-leaf level. It is assumed
that mtr holds an x-latch on the tree. */
UNIV_INTERN
void
btr_insert_on_non_leaf_level(
/*=========================*/
- dict_index_t* index, /* in: index */
- ulint level, /* in: level, must be > 0 */
- dtuple_t* tuple, /* in: the record to be inserted */
- mtr_t* mtr); /* in: mtr */
-/********************************************************************
+ dict_index_t* index, /*!< in: index */
+ ulint level, /*!< in: level, must be > 0 */
+ dtuple_t* tuple, /*!< in: the record to be inserted */
+ mtr_t* mtr); /*!< in: mtr */
+#endif /* !UNIV_HOTBACKUP */
+/****************************************************************//**
Sets a record as the predefined minimum record. */
UNIV_INTERN
void
btr_set_min_rec_mark(
/*=================*/
- rec_t* rec, /* in/out: record */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
+ rec_t* rec, /*!< in/out: record */
+ mtr_t* mtr); /*!< in: mtr */
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Deletes on the upper level the node pointer to a page. */
UNIV_INTERN
void
btr_node_ptr_delete(
/*================*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: page whose node pointer is deleted */
- mtr_t* mtr); /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: page whose node pointer is deleted */
+ mtr_t* mtr); /*!< in: mtr */
#ifdef UNIV_DEBUG
-/****************************************************************
-Checks that the node pointer to a page is appropriate. */
+/************************************************************//**
+Checks that the node pointer to a page is appropriate.
+@return TRUE */
UNIV_INTERN
ibool
btr_check_node_ptr(
/*===============*/
- /* out: TRUE */
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: index page */
- mtr_t* mtr); /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: index page */
+ mtr_t* mtr); /*!< in: mtr */
#endif /* UNIV_DEBUG */
-/*****************************************************************
+/*************************************************************//**
Tries to merge the page first to the left immediate brother if such a
brother exists, and the node pointers to the current page and to the
brother reside on the same page. If the left brother does not satisfy these
@@ -349,18 +362,18 @@ conditions, looks at the right brother. If the page is the only one on that
level lifts the records of the page to the father page, thus reducing the
tree height. It is assumed that mtr holds an x-latch on the tree and on the
page. If cursor is on the leaf level, mtr must also hold x-latches to
-the brothers, if they exist. */
+the brothers, if they exist.
+@return TRUE on success */
UNIV_INTERN
ibool
btr_compress(
/*=========*/
- /* out: TRUE on success */
- btr_cur_t* cursor, /* in: cursor on the page to merge or lift;
+ btr_cur_t* cursor, /*!< in: cursor on the page to merge or lift;
the page must not be empty: in record delete
use btr_discard_page if the page would become
empty */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*************************************************************//**
Discards a page from a B-tree. This is used to remove the last record from
a B-tree page: the whole page must be removed at the same time. This cannot
be used for the root page, which is allowed to be empty. */
@@ -368,70 +381,71 @@ UNIV_INTERN
void
btr_discard_page(
/*=============*/
- btr_cur_t* cursor, /* in: cursor on the page to discard: not on
+ btr_cur_t* cursor, /*!< in: cursor on the page to discard: not on
the root page */
- mtr_t* mtr); /* in: mtr */
-/********************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+#endif /* !UNIV_HOTBACKUP */
+/****************************************************************//**
Parses the redo log record for setting an index record as the predefined
-minimum record. */
+minimum record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_parse_set_min_rec_mark(
/*=======================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- ulint comp, /* in: nonzero=compact page format */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
-/***************************************************************
-Parses a redo log record of reorganizing a page. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ ulint comp, /*!< in: nonzero=compact page format */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+/***********************************************************//**
+Parses a redo log record of reorganizing a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_parse_page_reorganize(
/*======================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- dict_index_t* index, /* in: record descriptor */
- buf_block_t* block, /* in: page to be reorganized, or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
-/******************************************************************
-Gets the number of pages in a B-tree. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ dict_index_t* index, /*!< in: record descriptor */
+ buf_block_t* block, /*!< in: page to be reorganized, or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+#ifndef UNIV_HOTBACKUP
+/**************************************************************//**
+Gets the number of pages in a B-tree.
+@return number of pages */
UNIV_INTERN
ulint
btr_get_size(
/*=========*/
- /* out: number of pages */
- dict_index_t* index, /* in: index */
- ulint flag); /* in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
-/******************************************************************
+ dict_index_t* index, /*!< in: index */
+ ulint flag); /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
+/**************************************************************//**
Allocates a new file page to be used in an index tree. NOTE: we assume
-that the caller has made the reservation for free extents! */
+that the caller has made the reservation for free extents!
+@return new allocated block, x-latched; NULL if out of space */
UNIV_INTERN
buf_block_t*
btr_page_alloc(
/*===========*/
- /* out: new allocated block, x-latched;
- NULL if out of space */
- dict_index_t* index, /* in: index tree */
- ulint hint_page_no, /* in: hint of a good page */
- byte file_direction, /* in: direction where a possible
+ dict_index_t* index, /*!< in: index tree */
+ ulint hint_page_no, /*!< in: hint of a good page */
+ byte file_direction, /*!< in: direction where a possible
page split is made */
- ulint level, /* in: level where the page is placed
+ ulint level, /*!< in: level where the page is placed
in the tree */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
Frees a file page used in an index tree. NOTE: cannot free field external
storage pages because the page must contain info on its level. */
UNIV_INTERN
void
btr_page_free(
/*==========*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: block to be freed, x-latched */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: block to be freed, x-latched */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
Frees a file page used in an index tree. Can be used also to BLOB
external storage pages, because the page level 0 can be given as an
argument. */
@@ -439,53 +453,54 @@ UNIV_INTERN
void
btr_page_free_low(
/*==============*/
- dict_index_t* index, /* in: index tree */
- buf_block_t* block, /* in: block to be freed, x-latched */
- ulint level, /* in: page level */
- mtr_t* mtr); /* in: mtr */
+ dict_index_t* index, /*!< in: index tree */
+ buf_block_t* block, /*!< in: block to be freed, x-latched */
+ ulint level, /*!< in: page level */
+ mtr_t* mtr); /*!< in: mtr */
#ifdef UNIV_BTR_PRINT
-/*****************************************************************
+/*************************************************************//**
Prints size info of a B-tree. */
UNIV_INTERN
void
btr_print_size(
/*===========*/
- dict_index_t* index); /* in: index tree */
-/******************************************************************
+ dict_index_t* index); /*!< in: index tree */
+/**************************************************************//**
Prints directories and other info of all nodes in the index. */
UNIV_INTERN
void
btr_print_index(
/*============*/
- dict_index_t* index, /* in: index */
- ulint width); /* in: print this many entries from start
+ dict_index_t* index, /*!< in: index */
+ ulint width); /*!< in: print this many entries from start
and end */
#endif /* UNIV_BTR_PRINT */
-/****************************************************************
+/************************************************************//**
Checks the size and number of fields in a record based on the definition of
-the index. */
+the index.
+@return TRUE if ok */
UNIV_INTERN
ibool
btr_index_rec_validate(
/*===================*/
- /* out: TRUE if ok */
- const rec_t* rec, /* in: index record */
- const dict_index_t* index, /* in: index */
- ibool dump_on_error); /* in: TRUE if the function
+ const rec_t* rec, /*!< in: index record */
+ const dict_index_t* index, /*!< in: index */
+ ibool dump_on_error); /*!< in: TRUE if the function
should print hex dump of record
and page on error */
-/******************************************************************
-Checks the consistency of an index tree. */
+/**************************************************************//**
+Checks the consistency of an index tree.
+@return TRUE if ok */
UNIV_INTERN
ibool
btr_validate_index(
/*===============*/
- /* out: TRUE if ok */
- dict_index_t* index, /* in: index */
- trx_t* trx); /* in: transaction or NULL */
+ dict_index_t* index, /*!< in: index */
+ trx_t* trx); /*!< in: transaction or NULL */
#define BTR_N_LEAF_PAGES 1
#define BTR_TOTAL_SIZE 2
+#endif /* !UNIV_HOTBACKUP */
#ifndef UNIV_NONINL
#include "btr0btr.ic"
diff --git a/storage/xtradb/include/btr0btr.ic b/storage/xtradb/include/btr0btr.ic
index a8d934ecc87..2259d22c9a6 100644
--- a/storage/xtradb/include/btr0btr.ic
+++ b/storage/xtradb/include/btr0btr.ic
@@ -16,31 +16,37 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/btr0btr.ic
The B-tree
Created 6/2/1994 Heikki Tuuri
*******************************************************/
#include "mach0data.h"
+#ifndef UNIV_HOTBACKUP
#include "mtr0mtr.h"
#include "mtr0log.h"
#include "page0zip.h"
-#define BTR_MAX_NODE_LEVEL 50 /* used in debug checking */
+#define BTR_MAX_NODE_LEVEL 50 /*!< Maximum B-tree page level
+ (not really a hard limit).
+ Used in debug assertions
+ in btr_page_set_level and
+ btr_page_get_level_low */
-/******************************************************************
+/**************************************************************//**
Gets a buffer page and declares its latching order level. */
UNIV_INLINE
buf_block_t*
btr_block_get(
/*==========*/
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- ulint mode, /* in: latch mode */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number */
+ ulint mode, /*!< in: latch mode */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
@@ -54,34 +60,34 @@ btr_block_get(
return(block);
}
-/******************************************************************
+/**************************************************************//**
Gets a buffer page and declares its latching order level. */
UNIV_INLINE
page_t*
btr_page_get(
/*=========*/
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- ulint mode, /* in: latch mode */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number */
+ ulint mode, /*!< in: latch mode */
+ mtr_t* mtr) /*!< in: mtr */
{
return(buf_block_get_frame(btr_block_get(space, zip_size, page_no,
mode, mtr)));
}
-/******************************************************************
+/**************************************************************//**
Sets the index id field of a page. */
UNIV_INLINE
void
btr_page_set_index_id(
/*==================*/
- page_t* page, /* in: page to be created */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ page_t* page, /*!< in: page to be created */
+ page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- dulint id, /* in: index id */
- mtr_t* mtr) /* in: mtr */
+ dulint id, /*!< in: index id */
+ mtr_t* mtr) /*!< in: mtr */
{
if (UNIV_LIKELY_NULL(page_zip)) {
mach_write_to_8(page + (PAGE_HEADER + PAGE_INDEX_ID), id);
@@ -93,27 +99,29 @@ btr_page_set_index_id(
id, mtr);
}
}
+#endif /* !UNIV_HOTBACKUP */
-/******************************************************************
-Gets the index id field of a page. */
+/**************************************************************//**
+Gets the index id field of a page.
+@return index id */
UNIV_INLINE
dulint
btr_page_get_index_id(
/*==================*/
- /* out: index id */
- const page_t* page) /* in: index page */
+ const page_t* page) /*!< in: index page */
{
return(mach_read_from_8(page + PAGE_HEADER + PAGE_INDEX_ID));
}
-/************************************************************
-Gets the node level field in an index page. */
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
+Gets the node level field in an index page.
+@return level, leaf level == 0 */
UNIV_INLINE
ulint
btr_page_get_level_low(
/*===================*/
- /* out: level, leaf level == 0 */
- const page_t* page) /* in: index page */
+ const page_t* page) /*!< in: index page */
{
ulint level;
@@ -126,33 +134,33 @@ btr_page_get_level_low(
return(level);
}
-/************************************************************
-Gets the node level field in an index page. */
+/********************************************************//**
+Gets the node level field in an index page.
+@return level, leaf level == 0 */
UNIV_INLINE
ulint
btr_page_get_level(
/*===============*/
- /* out: level, leaf level == 0 */
- const page_t* page, /* in: index page */
+ const page_t* page, /*!< in: index page */
mtr_t* mtr __attribute__((unused)))
- /* in: mini-transaction handle */
+ /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
return(btr_page_get_level_low(page));
}
-/************************************************************
+/********************************************************//**
Sets the node level field in an index page. */
UNIV_INLINE
void
btr_page_set_level(
/*===============*/
- page_t* page, /* in: index page */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ page_t* page, /*!< in: index page */
+ page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- ulint level, /* in: level, leaf level == 0 */
- mtr_t* mtr) /* in: mini-transaction handle */
+ ulint level, /*!< in: level, leaf level == 0 */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
ut_ad(level <= BTR_MAX_NODE_LEVEL);
@@ -168,16 +176,16 @@ btr_page_set_level(
}
}
-/************************************************************
-Gets the next index page number. */
+/********************************************************//**
+Gets the next index page number.
+@return next page number */
UNIV_INLINE
ulint
btr_page_get_next(
/*==============*/
- /* out: next page number */
- const page_t* page, /* in: index page */
+ const page_t* page, /*!< in: index page */
mtr_t* mtr __attribute__((unused)))
- /* in: mini-transaction handle */
+ /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX)
@@ -186,17 +194,17 @@ btr_page_get_next(
return(mach_read_from_4(page + FIL_PAGE_NEXT));
}
-/************************************************************
+/********************************************************//**
Sets the next index page field. */
UNIV_INLINE
void
btr_page_set_next(
/*==============*/
- page_t* page, /* in: index page */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ page_t* page, /*!< in: index page */
+ page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- ulint next, /* in: next page number */
- mtr_t* mtr) /* in: mini-transaction handle */
+ ulint next, /*!< in: next page number */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
@@ -208,32 +216,32 @@ btr_page_set_next(
}
}
-/************************************************************
-Gets the previous index page number. */
+/********************************************************//**
+Gets the previous index page number.
+@return prev page number */
UNIV_INLINE
ulint
btr_page_get_prev(
/*==============*/
- /* out: prev page number */
- const page_t* page, /* in: index page */
- mtr_t* mtr __attribute__((unused))) /* in: mini-transaction handle */
+ const page_t* page, /*!< in: index page */
+ mtr_t* mtr __attribute__((unused))) /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
return(mach_read_from_4(page + FIL_PAGE_PREV));
}
-/************************************************************
+/********************************************************//**
Sets the previous index page field. */
UNIV_INLINE
void
btr_page_set_prev(
/*==============*/
- page_t* page, /* in: index page */
- page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
+ page_t* page, /*!< in: index page */
+ page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
part will be updated, or NULL */
- ulint prev, /* in: previous page number */
- mtr_t* mtr) /* in: mini-transaction handle */
+ ulint prev, /*!< in: previous page number */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ut_ad(page && mtr);
@@ -245,15 +253,15 @@ btr_page_set_prev(
}
}
-/******************************************************************
-Gets the child node file address in a node pointer. */
+/**************************************************************//**
+Gets the child node file address in a node pointer.
+@return child node address */
UNIV_INLINE
ulint
btr_node_ptr_get_child_page_no(
/*===========================*/
- /* out: child node address */
- const rec_t* rec, /* in: node pointer record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const rec_t* rec, /*!< in: node pointer record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
const byte* field;
ulint len;
@@ -280,16 +288,16 @@ btr_node_ptr_get_child_page_no(
return(page_no);
}
-/******************************************************************
+/**************************************************************//**
Releases the latches on a leaf page and bufferunfixes it. */
UNIV_INLINE
void
btr_leaf_page_release(
/*==================*/
- buf_block_t* block, /* in: buffer block */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF or
+ buf_block_t* block, /*!< in: buffer block */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(latch_mode == BTR_SEARCH_LEAF || latch_mode == BTR_MODIFY_LEAF);
ut_ad(!mtr_memo_contains(mtr, block, MTR_MEMO_MODIFY));
@@ -299,3 +307,4 @@ btr_leaf_page_release(
? MTR_MEMO_PAGE_S_FIX
: MTR_MEMO_PAGE_X_FIX);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/btr0cur.h b/storage/xtradb/include/btr0cur.h
index c3a478c4bb7..b2d43ae3254 100644
--- a/storage/xtradb/include/btr0cur.h
+++ b/storage/xtradb/include/btr0cur.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/btr0cur.h
The index tree cursor
Created 10/16/1994 Heikki Tuuri
@@ -29,9 +30,6 @@ Created 10/16/1994 Heikki Tuuri
#include "dict0dict.h"
#include "page0cur.h"
#include "btr0types.h"
-#include "que0types.h"
-#include "row0types.h"
-#include "ha0ha.h"
/* Mode flags for btr_cur operations; these can be ORed */
#define BTR_NO_UNDO_LOG_FLAG 1 /* do no undo logging */
@@ -39,81 +37,84 @@ Created 10/16/1994 Heikki Tuuri
#define BTR_KEEP_SYS_FLAG 4 /* sys fields will be found from the
update vector or inserted entry */
+#ifndef UNIV_HOTBACKUP
+#include "que0types.h"
+#include "row0types.h"
+#include "ha0ha.h"
+
#define BTR_CUR_ADAPT
#define BTR_CUR_HASH_ADAPT
#ifdef UNIV_DEBUG
-/*************************************************************
-Returns the page cursor component of a tree cursor. */
+/*********************************************************//**
+Returns the page cursor component of a tree cursor.
+@return pointer to page cursor component */
UNIV_INLINE
page_cur_t*
btr_cur_get_page_cur(
/*=================*/
- /* out: pointer to page cursor
- component */
- const btr_cur_t* cursor);/* in: tree cursor */
+ const btr_cur_t* cursor);/*!< in: tree cursor */
#else /* UNIV_DEBUG */
# define btr_cur_get_page_cur(cursor) (&(cursor)->page_cur)
#endif /* UNIV_DEBUG */
-/*************************************************************
-Returns the buffer block on which the tree cursor is positioned. */
+/*********************************************************//**
+Returns the buffer block on which the tree cursor is positioned.
+@return pointer to buffer block */
UNIV_INLINE
buf_block_t*
btr_cur_get_block(
/*==============*/
- /* out: pointer to buffer block */
- btr_cur_t* cursor);/* in: tree cursor */
-/*************************************************************
-Returns the record pointer of a tree cursor. */
+ btr_cur_t* cursor);/*!< in: tree cursor */
+/*********************************************************//**
+Returns the record pointer of a tree cursor.
+@return pointer to record */
UNIV_INLINE
rec_t*
btr_cur_get_rec(
/*============*/
- /* out: pointer to record */
- btr_cur_t* cursor);/* in: tree cursor */
-/*************************************************************
-Returns the compressed page on which the tree cursor is positioned. */
+ btr_cur_t* cursor);/*!< in: tree cursor */
+/*********************************************************//**
+Returns the compressed page on which the tree cursor is positioned.
+@return pointer to compressed page, or NULL if the page is not compressed */
UNIV_INLINE
page_zip_des_t*
btr_cur_get_page_zip(
/*=================*/
- /* out: pointer to compressed page,
- or NULL if the page is not compressed */
- btr_cur_t* cursor);/* in: tree cursor */
-/*************************************************************
+ btr_cur_t* cursor);/*!< in: tree cursor */
+/*********************************************************//**
Invalidates a tree cursor by setting record pointer to NULL. */
UNIV_INLINE
void
btr_cur_invalidate(
/*===============*/
- btr_cur_t* cursor);/* in: tree cursor */
-/*************************************************************
-Returns the page of a tree cursor. */
+ btr_cur_t* cursor);/*!< in: tree cursor */
+/*********************************************************//**
+Returns the page of a tree cursor.
+@return pointer to page */
UNIV_INLINE
page_t*
btr_cur_get_page(
/*=============*/
- /* out: pointer to page */
- btr_cur_t* cursor);/* in: tree cursor */
-/*************************************************************
-Returns the index of a cursor. */
+ btr_cur_t* cursor);/*!< in: tree cursor */
+/*********************************************************//**
+Returns the index of a cursor.
+@return index */
UNIV_INLINE
dict_index_t*
btr_cur_get_index(
/*==============*/
- /* out: index */
- btr_cur_t* cursor);/* in: B-tree cursor */
-/*************************************************************
+ btr_cur_t* cursor);/*!< in: B-tree cursor */
+/*********************************************************//**
Positions a tree cursor at a given record. */
UNIV_INLINE
void
btr_cur_position(
/*=============*/
- dict_index_t* index, /* in: index */
- rec_t* rec, /* in: record in tree */
- buf_block_t* block, /* in: buffer block of rec */
- btr_cur_t* cursor);/* in: cursor */
-/************************************************************************
+ dict_index_t* index, /*!< in: index */
+ rec_t* rec, /*!< in: record in tree */
+ buf_block_t* block, /*!< in: buffer block of rec */
+ btr_cur_t* cursor);/*!< in: cursor */
+/********************************************************************//**
Searches an index tree and positions a tree cursor on a given level.
NOTE: n_fields_cmp in tuple must be set so that it cannot be compared
to node pointer page number fields on the upper levels of the tree!
@@ -124,19 +125,19 @@ UNIV_INTERN
void
btr_cur_search_to_nth_level(
/*========================*/
- dict_index_t* index, /* in: index */
- ulint level, /* in: the tree level of search */
- const dtuple_t* tuple, /* in: data tuple; NOTE: n_fields_cmp in
+ dict_index_t* index, /*!< in: index */
+ ulint level, /*!< in: the tree level of search */
+ const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
tuple must be set so that it cannot get
compared to the node ptr page number field! */
- ulint mode, /* in: PAGE_CUR_L, ...;
+ ulint mode, /*!< in: PAGE_CUR_L, ...;
NOTE that if the search is made using a unique
prefix of a record, mode should be PAGE_CUR_LE,
not PAGE_CUR_GE, as the latter may end up on
the previous page of the record! Inserts
should always be made using PAGE_CUR_LE to
search the position! */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ..., ORed with
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ..., ORed with
BTR_INSERT and BTR_ESTIMATE;
cursor->left_block is used to store a pointer
to the left neighbor page, in the cases
@@ -146,309 +147,305 @@ btr_cur_search_to_nth_level(
on the cursor page, we assume
the caller uses his search latch
to protect the record! */
- btr_cur_t* cursor, /* in/out: tree cursor; the cursor page is
+ btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
s- or x-latched, but see also above! */
- ulint has_search_latch,/* in: latch mode the caller
+ ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch:
RW_S_LATCH, or 0 */
- mtr_t* mtr); /* in: mtr */
-/*********************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
Opens a cursor at either end of an index. */
UNIV_INTERN
void
btr_cur_open_at_index_side(
/*=======================*/
- ibool from_left, /* in: TRUE if open to the low end,
+ ibool from_left, /*!< in: TRUE if open to the low end,
FALSE if to the high end */
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: latch mode */
- btr_cur_t* cursor, /* in: cursor */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: latch mode */
+ btr_cur_t* cursor, /*!< in: cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Positions a cursor at a randomly chosen position within a B-tree. */
UNIV_INTERN
void
btr_cur_open_at_rnd_pos(
/*====================*/
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_cur_t* cursor, /* in/out: B-tree cursor */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_cur_t* cursor, /*!< in/out: B-tree cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/*************************************************************//**
Tries to perform an insert to a page in an index tree, next to cursor.
It is assumed that mtr holds an x-latch on the page. The operation does
not succeed if there is too little space on the page. If there is just
one record on the page, the insert will always succeed; this is to
-prevent trying to split a page with just one record. */
+prevent trying to split a page with just one record.
+@return DB_SUCCESS, DB_WAIT_LOCK, DB_FAIL, or error number */
UNIV_INTERN
ulint
btr_cur_optimistic_insert(
/*======================*/
- /* out: DB_SUCCESS, DB_WAIT_LOCK,
- DB_FAIL, or error number */
- ulint flags, /* in: undo logging and locking flags: if not
+ ulint flags, /*!< in: undo logging and locking flags: if not
zero, the parameters index and thr should be
specified */
- btr_cur_t* cursor, /* in: cursor on page after which to insert;
+ btr_cur_t* cursor, /*!< in: cursor on page after which to insert;
cursor stays valid */
- dtuple_t* entry, /* in/out: entry to insert */
- rec_t** rec, /* out: pointer to inserted record if
+ dtuple_t* entry, /*!< in/out: entry to insert */
+ rec_t** rec, /*!< out: pointer to inserted record if
succeed */
- big_rec_t** big_rec,/* out: big rec vector whose fields have to
+ big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or
NULL */
- ulint n_ext, /* in: number of externally stored columns */
- que_thr_t* thr, /* in: query thread or NULL */
- mtr_t* mtr); /* in: mtr; if this function returns
+ ulint n_ext, /*!< in: number of externally stored columns */
+ que_thr_t* thr, /*!< in: query thread or NULL */
+ mtr_t* mtr); /*!< in: mtr; if this function returns
DB_SUCCESS on a leaf page of a secondary
index in a compressed tablespace, the
mtr must be committed before latching
any further pages */
-/*****************************************************************
+/*************************************************************//**
Performs an insert on a page of an index tree. It is assumed that mtr
holds an x-latch on the tree and on the cursor page. If the insert is
made on the leaf level, to avoid deadlocks, mtr must also own x-latches
-to brothers of page, if those brothers exist. */
+to brothers of page, if those brothers exist.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
btr_cur_pessimistic_insert(
/*=======================*/
- /* out: DB_SUCCESS or error number */
- ulint flags, /* in: undo logging and locking flags: if not
+ ulint flags, /*!< in: undo logging and locking flags: if not
zero, the parameter thr should be
specified; if no undo logging is specified,
then the caller must have reserved enough
free extents in the file space so that the
insertion will certainly succeed */
- btr_cur_t* cursor, /* in: cursor after which to insert;
+ btr_cur_t* cursor, /*!< in: cursor after which to insert;
cursor stays valid */
- dtuple_t* entry, /* in/out: entry to insert */
- rec_t** rec, /* out: pointer to inserted record if
+ dtuple_t* entry, /*!< in/out: entry to insert */
+ rec_t** rec, /*!< out: pointer to inserted record if
succeed */
- big_rec_t** big_rec,/* out: big rec vector whose fields have to
+ big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or
NULL */
- ulint n_ext, /* in: number of externally stored columns */
- que_thr_t* thr, /* in: query thread or NULL */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
-Updates a record when the update causes no size changes in its fields. */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ que_thr_t* thr, /*!< in: query thread or NULL */
+ mtr_t* mtr); /*!< in: mtr */
+/*************************************************************//**
+Updates a record when the update causes no size changes in its fields.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
btr_cur_update_in_place(
/*====================*/
- /* out: DB_SUCCESS or error number */
- ulint flags, /* in: undo logging and locking flags */
- btr_cur_t* cursor, /* in: cursor on the record to update;
+ ulint flags, /*!< in: undo logging and locking flags */
+ btr_cur_t* cursor, /*!< in: cursor on the record to update;
cursor stays valid and positioned on the
same record */
- const upd_t* update, /* in: update vector */
- ulint cmpl_info,/* in: compiler info on secondary index
+ const upd_t* update, /*!< in: update vector */
+ ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr); /* in: mtr; must be committed before
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr); /*!< in: mtr; must be committed before
latching any further pages */
-/*****************************************************************
+/*************************************************************//**
Tries to update a record on a page in an index tree. It is assumed that mtr
holds an x-latch on the page. The operation does not succeed if there is too
little space on the page or if the update would result in too empty a page,
-so that tree compression is recommended. */
+so that tree compression is recommended.
+@return DB_SUCCESS, or DB_OVERFLOW if the updated record does not fit,
+DB_UNDERFLOW if the page would become too empty, or DB_ZIP_OVERFLOW if
+there is not enough space left on the compressed page */
UNIV_INTERN
ulint
btr_cur_optimistic_update(
/*======================*/
- /* out: DB_SUCCESS, or DB_OVERFLOW if the
- updated record does not fit, DB_UNDERFLOW
- if the page would become too empty, or
- DB_ZIP_OVERFLOW if there is not enough
- space left on the compressed page */
- ulint flags, /* in: undo logging and locking flags */
- btr_cur_t* cursor, /* in: cursor on the record to update;
+ ulint flags, /*!< in: undo logging and locking flags */
+ btr_cur_t* cursor, /*!< in: cursor on the record to update;
cursor stays valid and positioned on the
same record */
- const upd_t* update, /* in: update vector; this must also
+ const upd_t* update, /*!< in: update vector; this must also
contain trx id and roll ptr fields */
- ulint cmpl_info,/* in: compiler info on secondary index
+ ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr); /* in: mtr; must be committed before
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr); /*!< in: mtr; must be committed before
latching any further pages */
-/*****************************************************************
+/*************************************************************//**
Performs an update of a record on a page of a tree. It is assumed
that mtr holds an x-latch on the tree and on the cursor page. If the
update is made on the leaf level, to avoid deadlocks, mtr must also
-own x-latches to brothers of page, if those brothers exist. */
+own x-latches to brothers of page, if those brothers exist.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
btr_cur_pessimistic_update(
/*=======================*/
- /* out: DB_SUCCESS or error code */
- ulint flags, /* in: undo logging, locking, and rollback
+ ulint flags, /*!< in: undo logging, locking, and rollback
flags */
- btr_cur_t* cursor, /* in: cursor on the record to update */
- mem_heap_t** heap, /* in/out: pointer to memory heap, or NULL */
- big_rec_t** big_rec,/* out: big rec vector whose fields have to
+ btr_cur_t* cursor, /*!< in: cursor on the record to update */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
+ big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or NULL */
- const upd_t* update, /* in: update vector; this is allowed also
+ const upd_t* update, /*!< in: update vector; this is allowed also
contain trx id and roll ptr fields, but
the values in update vector have no effect */
- ulint cmpl_info,/* in: compiler info on secondary index
+ ulint cmpl_info,/*!< in: compiler info on secondary index
updates */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr); /* in: mtr; must be committed before
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr); /*!< in: mtr; must be committed before
latching any further pages */
-/***************************************************************
+/***********************************************************//**
Marks a clustered index record deleted. Writes an undo log record to
undo log on this delete marking. Writes in the trx id field the id
of the deleting transaction, and in the roll ptr field pointer to the
-undo log record created. */
+undo log record created.
+@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
UNIV_INTERN
ulint
btr_cur_del_mark_set_clust_rec(
/*===========================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
- number */
- ulint flags, /* in: undo logging and locking flags */
- btr_cur_t* cursor, /* in: cursor */
- ibool val, /* in: value to set */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr); /* in: mtr */
-/***************************************************************
-Sets a secondary index record delete mark to TRUE or FALSE. */
+ ulint flags, /*!< in: undo logging and locking flags */
+ btr_cur_t* cursor, /*!< in: cursor */
+ ibool val, /*!< in: value to set */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr); /*!< in: mtr */
+/***********************************************************//**
+Sets a secondary index record delete mark to TRUE or FALSE.
+@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
UNIV_INTERN
ulint
btr_cur_del_mark_set_sec_rec(
/*=========================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
- number */
- ulint flags, /* in: locking flag */
- btr_cur_t* cursor, /* in: cursor */
- ibool val, /* in: value to set */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr); /* in: mtr */
-/***************************************************************
+ ulint flags, /*!< in: locking flag */
+ btr_cur_t* cursor, /*!< in: cursor */
+ ibool val, /*!< in: value to set */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr); /*!< in: mtr */
+/***********************************************************//**
Clear a secondary index record's delete mark. This function is only
used by the insert buffer insert merge mechanism. */
UNIV_INTERN
void
btr_cur_del_unmark_for_ibuf(
/*========================*/
- rec_t* rec, /* in/out: record to delete unmark */
- page_zip_des_t* page_zip, /* in/out: compressed page
+ rec_t* rec, /*!< in/out: record to delete unmark */
+ page_zip_des_t* page_zip, /*!< in/out: compressed page
corresponding to rec, or NULL
when the tablespace is
uncompressed */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*************************************************************//**
Tries to compress a page of the tree if it seems useful. It is assumed
that mtr holds an x-latch on the tree and on the cursor page. To avoid
deadlocks, mtr must also own x-latches to brothers of page, if those
brothers exist. NOTE: it is assumed that the caller has reserved enough
-free extents so that the compression will always succeed if done! */
+free extents so that the compression will always succeed if done!
+@return TRUE if compression occurred */
UNIV_INTERN
ibool
btr_cur_compress_if_useful(
/*=======================*/
- /* out: TRUE if compression occurred */
- btr_cur_t* cursor, /* in: cursor on the page to compress;
+ btr_cur_t* cursor, /*!< in: cursor on the page to compress;
cursor does not stay valid if compression
occurs */
- mtr_t* mtr); /* in: mtr */
-/***********************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*******************************************************//**
Removes the record on which the tree cursor is positioned. It is assumed
that the mtr has an x-latch on the page where the cursor is positioned,
-but no latch on the whole tree. */
+but no latch on the whole tree.
+@return TRUE if success, i.e., the page did not become too empty */
UNIV_INTERN
ibool
btr_cur_optimistic_delete(
/*======================*/
- /* out: TRUE if success, i.e., the page
- did not become too empty */
- btr_cur_t* cursor, /* in: cursor on the record to delete;
+ btr_cur_t* cursor, /*!< in: cursor on the record to delete;
cursor stays valid: if deletion succeeds,
on function exit it points to the successor
of the deleted record */
- mtr_t* mtr); /* in: mtr; if this function returns
+ mtr_t* mtr); /*!< in: mtr; if this function returns
TRUE on a leaf page of a secondary
index, the mtr must be committed
before latching any further pages */
-/*****************************************************************
+/*************************************************************//**
Removes the record on which the tree cursor is positioned. Tries
to compress the page if its fillfactor drops below a threshold
or if it is the only page on the level. It is assumed that mtr holds
an x-latch on the tree and on the cursor page. To avoid deadlocks,
mtr must also own x-latches to brothers of page, if those brothers
-exist. */
+exist.
+@return TRUE if compression occurred */
UNIV_INTERN
ibool
btr_cur_pessimistic_delete(
/*=======================*/
- /* out: TRUE if compression occurred */
- ulint* err, /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
+ ulint* err, /*!< out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
the latter may occur because we may have
to update node pointers on upper levels,
and in the case of variable length keys
these may actually grow in size */
- ibool has_reserved_extents, /* in: TRUE if the
+ ibool has_reserved_extents, /*!< in: TRUE if the
caller has already reserved enough free
extents so that he knows that the operation
will succeed */
- btr_cur_t* cursor, /* in: cursor on the record to delete;
+ btr_cur_t* cursor, /*!< in: cursor on the record to delete;
if compression does not occur, the cursor
stays valid: it points to successor of
deleted record on function exit */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* mtr); /* in: mtr */
-/***************************************************************
-Parses a redo log record of updating a record in-place. */
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* mtr); /*!< in: mtr */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************//**
+Parses a redo log record of updating a record in-place.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_cur_parse_update_in_place(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in/out: page or NULL */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- dict_index_t* index); /* in: index corresponding to page */
-/********************************************************************
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in/out: page or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ dict_index_t* index); /*!< in: index corresponding to page */
+/****************************************************************//**
Parses the redo log record for delete marking or unmarking of a clustered
-index record. */
+index record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_cur_parse_del_mark_set_clust_rec(
/*=================================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in/out: page or NULL */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- dict_index_t* index); /* in: index corresponding to page */
-/********************************************************************
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in/out: page or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ dict_index_t* index); /*!< in: index corresponding to page */
+/****************************************************************//**
Parses the redo log record for delete marking or unmarking of a secondary
-index record. */
+index record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
btr_cur_parse_del_mark_set_sec_rec(
/*===============================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in/out: page or NULL */
- page_zip_des_t* page_zip);/* in/out: compressed page, or NULL */
-/***********************************************************************
-Estimates the number of rows in a given index range. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in/out: page or NULL */
+ page_zip_des_t* page_zip);/*!< in/out: compressed page, or NULL */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
+Estimates the number of rows in a given index range.
+@return estimated number of rows */
UNIV_INTERN
ib_int64_t
btr_estimate_n_rows_in_range(
/*=========================*/
- /* out: estimated number of rows */
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple1, /* in: range start, may also be empty tuple */
- ulint mode1, /* in: search mode for range start */
- const dtuple_t* tuple2, /* in: range end, may also be empty tuple */
- ulint mode2); /* in: search mode for range end */
-/***********************************************************************
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
+ ulint mode1, /*!< in: search mode for range start */
+ const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
+ ulint mode2); /*!< in: search mode for range end */
+/*******************************************************************//**
Estimates the number of different key values in a given index, for
each n-column prefix of the index where n <= dict_index_get_n_unique(index).
The estimates are stored in the array index->stat_n_diff_key_vals. */
@@ -456,8 +453,8 @@ UNIV_INTERN
void
btr_estimate_number_of_different_key_vals(
/*======================================*/
- dict_index_t* index); /* in: index */
-/***********************************************************************
+ dict_index_t* index); /*!< in: index */
+/*******************************************************************//**
Marks not updated extern fields as not-owned by this record. The ownership
is transferred to the updated record which is inserted elsewhere in the
index tree. In purge only the owner of externally stored field is allowed
@@ -466,14 +463,14 @@ UNIV_INTERN
void
btr_cur_mark_extern_inherited_fields(
/*=================================*/
- page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
part will be updated, or NULL */
- rec_t* rec, /* in/out: record in a clustered index */
- dict_index_t* index, /* in: index of the page */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- const upd_t* update, /* in: update vector */
- mtr_t* mtr); /* in: mtr, or NULL if not logged */
-/***********************************************************************
+ rec_t* rec, /*!< in/out: record in a clustered index */
+ dict_index_t* index, /*!< in: index of the page */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const upd_t* update, /*!< in: update vector */
+ mtr_t* mtr); /*!< in: mtr, or NULL if not logged */
+/*******************************************************************//**
The complement of the previous function: in an update entry may inherit
some externally stored fields from a record. We must mark them as inherited
in entry, so that they are not freed in a rollback. */
@@ -481,39 +478,39 @@ UNIV_INTERN
void
btr_cur_mark_dtuple_inherited_extern(
/*=================================*/
- dtuple_t* entry, /* in/out: updated entry to be
+ dtuple_t* entry, /*!< in/out: updated entry to be
inserted to clustered index */
- const upd_t* update); /* in: update vector */
-/***********************************************************************
+ const upd_t* update); /*!< in: update vector */
+/*******************************************************************//**
Marks all extern fields in a dtuple as owned by the record. */
UNIV_INTERN
void
btr_cur_unmark_dtuple_extern_fields(
/*================================*/
- dtuple_t* entry); /* in/out: clustered index entry */
-/***********************************************************************
+ dtuple_t* entry); /*!< in/out: clustered index entry */
+/*******************************************************************//**
Stores the fields in big_rec_vec to the tablespace and puts pointers to
them in rec. The extern flags in rec will have to be set beforehand.
The fields are stored on pages allocated from leaf node
-file segment of the index tree. */
+file segment of the index tree.
+@return DB_SUCCESS or error */
UNIV_INTERN
ulint
btr_store_big_rec_extern_fields(
/*============================*/
- /* out: DB_SUCCESS or error */
- dict_index_t* index, /* in: index of rec; the index tree
+ dict_index_t* index, /*!< in: index of rec; the index tree
MUST be X-latched */
- buf_block_t* rec_block, /* in/out: block containing rec */
- rec_t* rec, /* in: record */
- const ulint* offsets, /* in: rec_get_offsets(rec, index);
+ buf_block_t* rec_block, /*!< in/out: block containing rec */
+ rec_t* rec, /*!< in: record */
+ const ulint* offsets, /*!< in: rec_get_offsets(rec, index);
the "external storage" flags in offsets
will not correspond to rec when
this function returns */
- big_rec_t* big_rec_vec, /* in: vector containing fields
+ big_rec_t* big_rec_vec, /*!< in: vector containing fields
to be stored externally */
- mtr_t* local_mtr); /* in: mtr containing the latch to
+ mtr_t* local_mtr); /*!< in: mtr containing the latch to
rec and to the tree */
-/***********************************************************************
+/*******************************************************************//**
Frees the space in an externally stored field to the file space
management if the field in data is owned the externally stored field,
in a rollback we may have the additional condition that the field must
@@ -522,7 +519,7 @@ UNIV_INTERN
void
btr_free_externally_stored_field(
/*=============================*/
- dict_index_t* index, /* in: index of the data, the index
+ dict_index_t* index, /*!< in: index of the data, the index
tree MUST be X-latched; if the tree
height is 1, then also the root page
must be X-latched! (this is relevant
@@ -530,120 +527,131 @@ btr_free_externally_stored_field(
from purge where 'data' is located on
an undo log page, not an index
page) */
- byte* field_ref, /* in/out: field reference */
- const rec_t* rec, /* in: record containing field_ref, for
+ byte* field_ref, /*!< in/out: field reference */
+ const rec_t* rec, /*!< in: record containing field_ref, for
page_zip_write_blob_ptr(), or NULL */
- const ulint* offsets, /* in: rec_get_offsets(rec, index),
+ const ulint* offsets, /*!< in: rec_get_offsets(rec, index),
or NULL */
- page_zip_des_t* page_zip, /* in: compressed page corresponding
+ page_zip_des_t* page_zip, /*!< in: compressed page corresponding
to rec, or NULL if rec == NULL */
- ulint i, /* in: field number of field_ref;
+ ulint i, /*!< in: field number of field_ref;
ignored if rec == NULL */
- enum trx_rb_ctx rb_ctx, /* in: rollback context */
- mtr_t* local_mtr); /* in: mtr containing the latch to
+ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
+ mtr_t* local_mtr); /*!< in: mtr containing the latch to
data an an X-latch to the index
tree */
-/***********************************************************************
+/*******************************************************************//**
Copies the prefix of an externally stored field of a record. The
-clustered index record must be protected by a lock or a page latch. */
+clustered index record must be protected by a lock or a page latch.
+@return the length of the copied field, or 0 if the column was being
+or has been deleted */
UNIV_INTERN
ulint
btr_copy_externally_stored_field_prefix(
/*====================================*/
- /* out: the length of the copied field,
- or 0 if the column is being or has been
- deleted */
- byte* buf, /* out: the field, or a prefix of it */
- ulint len, /* in: length of buf, in bytes */
- ulint zip_size,/* in: nonzero=compressed BLOB page size,
+ byte* buf, /*!< out: the field, or a prefix of it */
+ ulint len, /*!< in: length of buf, in bytes */
+ ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
- const byte* data, /* in: 'internally' stored part of the
+ const byte* data, /*!< in: 'internally' stored part of the
field containing also the reference to
the external part; must be protected by
a lock or a page latch */
- ulint local_len);/* in: length of data, in bytes */
-/***********************************************************************
-Copies an externally stored field of a record to mem heap. */
+ 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 */
UNIV_INTERN
byte*
btr_rec_copy_externally_stored_field(
/*=================================*/
- /* out: the field copied to heap */
- const rec_t* rec, /* in: record in a clustered index;
+ const rec_t* rec, /*!< in: record in a clustered index;
must be protected by a lock or a page latch */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint zip_size,/* in: nonzero=compressed BLOB page size,
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
- ulint no, /* in: field number */
- ulint* len, /* out: length of the field */
- mem_heap_t* heap); /* in: mem heap */
-/***********************************************************************
+ ulint no, /*!< in: field number */
+ ulint* len, /*!< out: length of the field */
+ mem_heap_t* heap); /*!< in: mem heap */
+/*******************************************************************//**
Flags the data tuple fields that are marked as extern storage in the
update vector. We use this function to remember which fields we must
-mark as extern storage in a record inserted for an update. */
+mark as extern storage in a record inserted for an update.
+@return number of flagged external columns */
UNIV_INTERN
ulint
btr_push_update_extern_fields(
/*==========================*/
- /* out: number of flagged external columns */
- dtuple_t* tuple, /* in/out: data tuple */
- const upd_t* update, /* in: update vector */
- mem_heap_t* heap) /* in: memory heap */
+ dtuple_t* tuple, /*!< in/out: data tuple */
+ const upd_t* update, /*!< in: update vector */
+ mem_heap_t* heap) /*!< in: memory heap */
__attribute__((nonnull));
/*######################################################################*/
-/* In the pessimistic delete, if the page data size drops below this
+/** In the pessimistic delete, if the page data size drops below this
limit, merging it to a neighbor is tried */
-
#define BTR_CUR_PAGE_COMPRESS_LIMIT (UNIV_PAGE_SIZE / 2)
-/* A slot in the path array. We store here info on a search path down the
+/** A slot in the path array. We store here info on a search path down the
tree. Each slot contains data on a single level of the tree. */
typedef struct btr_path_struct btr_path_t;
struct btr_path_struct{
- ulint nth_rec; /* index of the record
+ ulint nth_rec; /*!< index of the record
where the page cursor stopped on
this level (index in alphabetical
order); value ULINT_UNDEFINED
denotes array end */
- ulint n_recs; /* number of records on the page */
+ ulint n_recs; /*!< number of records on the page */
};
-#define BTR_PATH_ARRAY_N_SLOTS 250 /* size of path array (in slots) */
+#define BTR_PATH_ARRAY_N_SLOTS 250 /*!< size of path array (in slots) */
-/* The tree cursor: the definition appears here only for the compiler
-to know struct size! */
+/** Values for the flag documenting the used search method */
+enum btr_cur_method {
+ BTR_CUR_HASH = 1, /*!< successful shortcut using
+ the hash index */
+ BTR_CUR_HASH_FAIL, /*!< failure using hash, success using
+ binary search: the misleading hash
+ reference is stored in the field
+ hash_node, and might be necessary to
+ update */
+ BTR_CUR_BINARY, /*!< success using the binary search */
+ BTR_CUR_INSERT_TO_IBUF, /*!< performed the intended insert to
+ the insert buffer */
+};
+/** The tree cursor: the definition appears here only for the compiler
+to know struct size! */
struct btr_cur_struct {
- dict_index_t* index; /* index where positioned */
- page_cur_t page_cur; /* page cursor */
- buf_block_t* left_block; /* this field is used to store
+ dict_index_t* index; /*!< index where positioned */
+ page_cur_t page_cur; /*!< page cursor */
+ buf_block_t* left_block; /*!< this field is used to store
a pointer to the left neighbor
page, in the cases
BTR_SEARCH_PREV and
BTR_MODIFY_PREV */
/*------------------------------*/
- que_thr_t* thr; /* this field is only used when
- btr_cur_search_... is called for an
- index entry insertion: the calling
- query thread is passed here to be
+ que_thr_t* thr; /*!< this field is only used
+ when btr_cur_search_to_nth_level
+ is called for an index entry
+ insertion: the calling query
+ thread is passed here to be
used in the insert buffer */
/*------------------------------*/
- /* The following fields are used in btr_cur_search... to pass
- information: */
- ulint flag; /* BTR_CUR_HASH, BTR_CUR_HASH_FAIL,
- BTR_CUR_BINARY, or
- BTR_CUR_INSERT_TO_IBUF */
- ulint tree_height; /* Tree height if the search is done
+ /** The following fields are used in
+ btr_cur_search_to_nth_level to pass information: */
+ /* @{ */
+ enum btr_cur_method flag; /*!< Search method used */
+ ulint tree_height; /*!< Tree height if the search is done
for a pessimistic insert or update
operation */
- ulint up_match; /* If the search mode was PAGE_CUR_LE,
+ ulint up_match; /*!< If the search mode was PAGE_CUR_LE,
the number of matched fields to the
the first user record to the right of
the cursor record after
- btr_cur_search_...;
+ btr_cur_search_to_nth_level;
for the mode PAGE_CUR_GE, the matched
fields to the first user record AT THE
CURSOR or to the right of it;
@@ -653,87 +661,90 @@ struct btr_cur_struct {
record if that record is on a
different leaf page! (See the note in
row_ins_duplicate_key.) */
- ulint up_bytes; /* number of matched bytes to the
+ ulint up_bytes; /*!< number of matched bytes to the
right at the time cursor positioned;
only used internally in searches: not
defined after the search */
- ulint low_match; /* if search mode was PAGE_CUR_LE,
+ ulint low_match; /*!< if search mode was PAGE_CUR_LE,
the number of matched fields to the
first user record AT THE CURSOR or
to the left of it after
- btr_cur_search_...;
+ btr_cur_search_to_nth_level;
NOT defined for PAGE_CUR_GE or any
other search modes; see also the NOTE
in up_match! */
- ulint low_bytes; /* number of matched bytes to the
+ ulint low_bytes; /*!< number of matched bytes to the
right at the time cursor positioned;
only used internally in searches: not
defined after the search */
- ulint n_fields; /* prefix length used in a hash
+ ulint n_fields; /*!< prefix length used in a hash
search if hash_node != NULL */
- ulint n_bytes; /* hash prefix bytes if hash_node !=
+ ulint n_bytes; /*!< hash prefix bytes if hash_node !=
NULL */
- ulint fold; /* fold value used in the search if
+ ulint fold; /*!< fold value used in the search if
flag is BTR_CUR_HASH */
/*------------------------------*/
- btr_path_t* path_arr; /* in estimating the number of
+ /* @} */
+ btr_path_t* path_arr; /*!< in estimating the number of
rows in range, we store in this array
information of the path through
the tree */
};
-/* Values for the flag documenting the used search method */
-#define BTR_CUR_HASH 1 /* successful shortcut using the hash
- index */
-#define BTR_CUR_HASH_FAIL 2 /* failure using hash, success using
- binary search: the misleading hash
- reference is stored in the field
- hash_node, and might be necessary to
- update */
-#define BTR_CUR_BINARY 3 /* success using the binary search */
-#define BTR_CUR_INSERT_TO_IBUF 4 /* performed the intended insert to
- the insert buffer */
-
-/* If pessimistic delete fails because of lack of file space,
-there is still a good change of success a little later: try this many times,
-and sleep this many microseconds in between */
+/** If pessimistic delete fails because of lack of file space, there
+is still a good change of success a little later. Try this many
+times. */
#define BTR_CUR_RETRY_DELETE_N_TIMES 100
+/** If pessimistic delete fails because of lack of file space, there
+is still a good change of success a little later. Sleep this many
+microseconds between retries. */
#define BTR_CUR_RETRY_SLEEP_TIME 50000
-/* The reference in a field for which data is stored on a different page.
+/** The reference in a field for which data is stored on a different page.
The reference is at the end of the 'locally' stored part of the field.
'Locally' means storage in the index record.
We store locally a long enough prefix of each column so that we can determine
the ordering parts of each index record without looking into the externally
stored part. */
-
-/*--------------------------------------*/
-#define BTR_EXTERN_SPACE_ID 0 /* space id where stored */
-#define BTR_EXTERN_PAGE_NO 4 /* page no where stored */
-#define BTR_EXTERN_OFFSET 8 /* offset of BLOB header
+/*-------------------------------------- @{ */
+#define BTR_EXTERN_SPACE_ID 0 /*!< space id where stored */
+#define BTR_EXTERN_PAGE_NO 4 /*!< page no where stored */
+#define BTR_EXTERN_OFFSET 8 /*!< offset of BLOB header
on that page */
-#define BTR_EXTERN_LEN 12 /* 8 bytes containing the
+#define BTR_EXTERN_LEN 12 /*!< 8 bytes containing the
length of the externally
stored part of the BLOB.
The 2 highest bits are
reserved to the flags below. */
-/*--------------------------------------*/
+/*-------------------------------------- @} */
/* #define BTR_EXTERN_FIELD_REF_SIZE 20 // moved to btr0types.h */
-/* The highest bit of BTR_EXTERN_LEN (i.e., the highest bit of the byte
-at lowest address) is set to 1 if this field does not 'own' the externally
-stored field; only the owner field is allowed to free the field in purge!
-If the 2nd highest bit is 1 then it means that the externally stored field
-was inherited from an earlier version of the row. In rollback we are not
-allowed to free an inherited external field. */
-
+/** The most significant bit of BTR_EXTERN_LEN (i.e., the most
+significant bit of the byte at smallest address) is set to 1 if this
+field does not 'own' the externally stored field; only the owner field
+is allowed to free the field in purge! */
#define BTR_EXTERN_OWNER_FLAG 128
+/** If the second most significant bit of BTR_EXTERN_LEN (i.e., the
+second most significant bit of the byte at smallest address) is 1 then
+it means that the externally stored field was inherited from an
+earlier version of the row. In rollback we are not allowed to free an
+inherited external field. */
#define BTR_EXTERN_INHERITED_FLAG 64
+/** Number of searches down the B-tree in btr_cur_search_to_nth_level(). */
extern ulint btr_cur_n_non_sea;
+/** Number of successful adaptive hash index lookups in
+btr_cur_search_to_nth_level(). */
extern ulint btr_cur_n_sea;
+/** Old value of btr_cur_n_non_sea. Copied by
+srv_refresh_innodb_monitor_stats(). Referenced by
+srv_printf_innodb_monitor(). */
extern ulint btr_cur_n_non_sea_old;
+/** Old value of btr_cur_n_sea. Copied by
+srv_refresh_innodb_monitor_stats(). Referenced by
+srv_printf_innodb_monitor(). */
extern ulint btr_cur_n_sea_old;
+#endif /* !UNIV_HOTBACKUP */
#ifndef UNIV_NONINL
#include "btr0cur.ic"
diff --git a/storage/xtradb/include/btr0cur.ic b/storage/xtradb/include/btr0cur.ic
index 84a3a5cba0b..280583f6ccf 100644
--- a/storage/xtradb/include/btr0cur.ic
+++ b/storage/xtradb/include/btr0cur.ic
@@ -16,110 +16,110 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/btr0cur.ic
The index tree cursor
Created 10/16/1994 Heikki Tuuri
*******************************************************/
+#ifndef UNIV_HOTBACKUP
#include "btr0btr.h"
#ifdef UNIV_DEBUG
-/*************************************************************
-Returns the page cursor component of a tree cursor. */
+/*********************************************************//**
+Returns the page cursor component of a tree cursor.
+@return pointer to page cursor component */
UNIV_INLINE
page_cur_t*
btr_cur_get_page_cur(
/*=================*/
- /* out: pointer to page cursor
- component */
- const btr_cur_t* cursor) /* in: tree cursor */
+ const btr_cur_t* cursor) /*!< in: tree cursor */
{
return(&((btr_cur_t*) cursor)->page_cur);
}
#endif /* UNIV_DEBUG */
-/*************************************************************
-Returns the buffer block on which the tree cursor is positioned. */
+/*********************************************************//**
+Returns the buffer block on which the tree cursor is positioned.
+@return pointer to buffer block */
UNIV_INLINE
buf_block_t*
btr_cur_get_block(
/*==============*/
- /* out: pointer to buffer block */
- btr_cur_t* cursor) /* in: tree cursor */
+ btr_cur_t* cursor) /*!< in: tree cursor */
{
return(page_cur_get_block(btr_cur_get_page_cur(cursor)));
}
-/*************************************************************
-Returns the record pointer of a tree cursor. */
+/*********************************************************//**
+Returns the record pointer of a tree cursor.
+@return pointer to record */
UNIV_INLINE
rec_t*
btr_cur_get_rec(
/*============*/
- /* out: pointer to record */
- btr_cur_t* cursor) /* in: tree cursor */
+ btr_cur_t* cursor) /*!< in: tree cursor */
{
return(page_cur_get_rec(&(cursor->page_cur)));
}
-/*************************************************************
-Returns the compressed page on which the tree cursor is positioned. */
+/*********************************************************//**
+Returns the compressed page on which the tree cursor is positioned.
+@return pointer to compressed page, or NULL if the page is not compressed */
UNIV_INLINE
page_zip_des_t*
btr_cur_get_page_zip(
/*=================*/
- /* out: pointer to compressed page,
- or NULL if the page is not compressed */
- btr_cur_t* cursor) /* in: tree cursor */
+ btr_cur_t* cursor) /*!< in: tree cursor */
{
return(buf_block_get_page_zip(btr_cur_get_block(cursor)));
}
-/*************************************************************
+/*********************************************************//**
Invalidates a tree cursor by setting record pointer to NULL. */
UNIV_INLINE
void
btr_cur_invalidate(
/*===============*/
- btr_cur_t* cursor) /* in: tree cursor */
+ btr_cur_t* cursor) /*!< in: tree cursor */
{
page_cur_invalidate(&(cursor->page_cur));
}
-/*************************************************************
-Returns the page of a tree cursor. */
+/*********************************************************//**
+Returns the page of a tree cursor.
+@return pointer to page */
UNIV_INLINE
page_t*
btr_cur_get_page(
/*=============*/
- /* out: pointer to page */
- btr_cur_t* cursor) /* in: tree cursor */
+ btr_cur_t* cursor) /*!< in: tree cursor */
{
return(page_align(page_cur_get_rec(&(cursor->page_cur))));
}
-/*************************************************************
-Returns the index of a cursor. */
+/*********************************************************//**
+Returns the index of a cursor.
+@return index */
UNIV_INLINE
dict_index_t*
btr_cur_get_index(
/*==============*/
- /* out: index */
- btr_cur_t* cursor) /* in: B-tree cursor */
+ btr_cur_t* cursor) /*!< in: B-tree cursor */
{
return(cursor->index);
}
-/*************************************************************
+/*********************************************************//**
Positions a tree cursor at a given record. */
UNIV_INLINE
void
btr_cur_position(
/*=============*/
- dict_index_t* index, /* in: index */
- rec_t* rec, /* in: record in tree */
- buf_block_t* block, /* in: buffer block of rec */
- btr_cur_t* cursor) /* out: cursor */
+ dict_index_t* index, /*!< in: index */
+ rec_t* rec, /*!< in: record in tree */
+ buf_block_t* block, /*!< in: buffer block of rec */
+ btr_cur_t* cursor) /*!< out: cursor */
{
ut_ad(page_align(rec) == block->frame);
@@ -128,16 +128,16 @@ btr_cur_position(
cursor->index = index;
}
-/*************************************************************************
+/*********************************************************************//**
Checks if compressing an index page where a btr cursor is placed makes
-sense. */
+sense.
+@return TRUE if compression is recommended */
UNIV_INLINE
ibool
btr_cur_compress_recommendation(
/*============================*/
- /* out: TRUE if compression is recommended */
- btr_cur_t* cursor, /* in: btr cursor */
- mtr_t* mtr) /* in: mtr */
+ btr_cur_t* cursor, /*!< in: btr cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* page;
@@ -162,18 +162,17 @@ btr_cur_compress_recommendation(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if the record on which the cursor is placed can be deleted without
-making tree compression necessary (or, recommended). */
+making tree compression necessary (or, recommended).
+@return TRUE if can be deleted without recommended compression */
UNIV_INLINE
ibool
btr_cur_can_delete_without_compress(
/*================================*/
- /* out: TRUE if can be deleted without
- recommended compression */
- btr_cur_t* cursor, /* in: btr cursor */
- ulint rec_size,/* in: rec_get_size(btr_cur_get_rec(cursor))*/
- mtr_t* mtr) /* in: mtr */
+ btr_cur_t* cursor, /*!< in: btr cursor */
+ ulint rec_size,/*!< in: rec_get_size(btr_cur_get_rec(cursor))*/
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* page;
@@ -198,3 +197,4 @@ btr_cur_can_delete_without_compress(
return(TRUE);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/btr0pcur.h b/storage/xtradb/include/btr0pcur.h
index 1fdd102d32a..12b1375d8b7 100644
--- a/storage/xtradb/include/btr0pcur.h
+++ b/storage/xtradb/include/btr0pcur.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/btr0pcur.h
The index tree persistent cursor
Created 2/23/1996 Heikki Tuuri
@@ -45,114 +46,112 @@ of a scroll cursor easier */
#define BTR_PCUR_BEFORE_FIRST_IN_TREE 4 /* in an empty tree */
#define BTR_PCUR_AFTER_LAST_IN_TREE 5 /* in an empty tree */
-/******************************************************************
-Allocates memory for a persistent cursor object and initializes the cursor. */
+/**************************************************************//**
+Allocates memory for a persistent cursor object and initializes the cursor.
+@return own: persistent cursor */
UNIV_INTERN
btr_pcur_t*
btr_pcur_create_for_mysql(void);
/*============================*/
- /* out, own: persistent cursor */
-/******************************************************************
+/**************************************************************//**
Frees the memory for a persistent cursor object. */
UNIV_INTERN
void
btr_pcur_free_for_mysql(
/*====================*/
- btr_pcur_t* cursor); /* in, own: persistent cursor */
-/******************************************************************
+ btr_pcur_t* cursor); /*!< in, own: persistent cursor */
+/**************************************************************//**
Copies the stored position of a pcur to another pcur. */
UNIV_INTERN
void
btr_pcur_copy_stored_position(
/*==========================*/
- btr_pcur_t* pcur_receive, /* in: pcur which will receive the
+ btr_pcur_t* pcur_receive, /*!< in: pcur which will receive the
position info */
- btr_pcur_t* pcur_donate); /* in: pcur from which the info is
+ btr_pcur_t* pcur_donate); /*!< in: pcur from which the info is
copied */
-/******************************************************************
+/**************************************************************//**
Sets the old_rec_buf field to NULL. */
UNIV_INLINE
void
btr_pcur_init(
/*==========*/
- btr_pcur_t* pcur); /* in: persistent cursor */
-/******************************************************************
+ btr_pcur_t* pcur); /*!< in: persistent cursor */
+/**************************************************************//**
Initializes and opens a persistent cursor to an index tree. It should be
closed with btr_pcur_close. */
UNIV_INLINE
void
btr_pcur_open(
/*==========*/
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple, /* in: tuple on which search done */
- ulint mode, /* in: PAGE_CUR_L, ...;
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple, /*!< in: tuple on which search done */
+ ulint mode, /*!< in: PAGE_CUR_L, ...;
NOTE that if the search is made using a unique
prefix of a record, mode should be
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page from the
record! */
- ulint latch_mode,/* in: BTR_SEARCH_LEAF, ... */
- btr_pcur_t* cursor, /* in: memory buffer for persistent cursor */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
+ btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
Opens an persistent cursor to an index tree without initializing the
cursor. */
UNIV_INLINE
void
btr_pcur_open_with_no_init(
/*=======================*/
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple, /* in: tuple on which search done */
- ulint mode, /* in: PAGE_CUR_L, ...;
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple, /*!< in: tuple on which search done */
+ ulint mode, /*!< in: PAGE_CUR_L, ...;
NOTE that if the search is made using a unique
prefix of a record, mode should be
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page of the
record! */
- ulint latch_mode,/* in: BTR_SEARCH_LEAF, ...;
+ ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
NOTE that if has_search_latch != 0 then
we maybe do not acquire a latch on the cursor
page, but assume that the caller uses his
btr search latch to protect the record! */
- btr_pcur_t* cursor, /* in: memory buffer for persistent cursor */
- ulint has_search_latch,/* in: latch mode the caller
+ btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
+ ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch:
RW_S_LATCH, or 0 */
- mtr_t* mtr); /* in: mtr */
-/*********************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
Opens a persistent cursor at either end of an index. */
UNIV_INLINE
void
btr_pcur_open_at_index_side(
/*========================*/
- ibool from_left, /* in: TRUE if open to the low end,
+ ibool from_left, /*!< in: TRUE if open to the low end,
FALSE if to the high end */
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: latch mode */
- btr_pcur_t* pcur, /* in: cursor */
- ibool do_init, /* in: TRUE if should be initialized */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
-Gets the up_match value for a pcur after a search. */
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: latch mode */
+ btr_pcur_t* pcur, /*!< in: cursor */
+ ibool do_init, /*!< in: TRUE if should be initialized */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
+Gets the up_match value for a pcur after a search.
+@return number of matched fields at the cursor or to the right if
+search mode was PAGE_CUR_GE, otherwise undefined */
UNIV_INLINE
ulint
btr_pcur_get_up_match(
/*==================*/
- /* out: number of matched fields at the cursor
- or to the right if search mode was PAGE_CUR_GE,
- otherwise undefined */
- btr_pcur_t* cursor); /* in: memory buffer for persistent cursor */
-/******************************************************************
-Gets the low_match value for a pcur after a search. */
+ btr_pcur_t* cursor); /*!< in: memory buffer for persistent cursor */
+/**************************************************************//**
+Gets the low_match value for a pcur after a search.
+@return number of matched fields at the cursor or to the right if
+search mode was PAGE_CUR_LE, otherwise undefined */
UNIV_INLINE
ulint
btr_pcur_get_low_match(
/*===================*/
- /* out: number of matched fields at the cursor
- or to the right if search mode was PAGE_CUR_LE,
- otherwise undefined */
- btr_pcur_t* cursor); /* in: memory buffer for persistent cursor */
-/******************************************************************
+ btr_pcur_t* cursor); /*!< in: memory buffer for persistent cursor */
+/**************************************************************//**
If mode is PAGE_CUR_G or PAGE_CUR_GE, opens a persistent cursor on the first
user record satisfying the search condition, in the case PAGE_CUR_L or
PAGE_CUR_LE, on the last user record. If no such user record exists, then
@@ -163,33 +162,33 @@ UNIV_INTERN
void
btr_pcur_open_on_user_rec(
/*======================*/
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple, /* in: tuple on which search done */
- ulint mode, /* in: PAGE_CUR_L, ... */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF or
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple, /*!< in: tuple on which search done */
+ ulint mode, /*!< in: PAGE_CUR_L, ... */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */
- btr_pcur_t* cursor, /* in: memory buffer for persistent
+ btr_pcur_t* cursor, /*!< in: memory buffer for persistent
cursor */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Positions a cursor at a randomly chosen position within a B-tree. */
UNIV_INLINE
void
btr_pcur_open_at_rnd_pos(
/*=====================*/
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_pcur_t* cursor, /* in/out: B-tree pcur */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_pcur_t* cursor, /*!< in/out: B-tree pcur */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
Frees the possible old_rec_buf buffer of a persistent cursor and sets the
latch mode of the persistent cursor to BTR_NO_LATCHES. */
UNIV_INLINE
void
btr_pcur_close(
/*===========*/
- btr_pcur_t* cursor); /* in: persistent cursor */
-/******************************************************************
+ btr_pcur_t* cursor); /*!< in: persistent cursor */
+/**************************************************************//**
The position of the cursor is stored by taking an initial segment of the
record the cursor is positioned on, before, or after, and copying it to the
cursor data structure, or just setting a flag if the cursor id before the
@@ -200,9 +199,9 @@ UNIV_INTERN
void
btr_pcur_store_position(
/*====================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
Restores the stored position of a persistent cursor bufferfixing the page and
obtaining the specified latches. If the cursor position was saved when the
(1) cursor was positioned on a user record: this function restores the position
@@ -213,20 +212,18 @@ infimum;
(3) cursor was positioned on the page supremum: restores to the first record
GREATER than the user record which was the predecessor of the supremum.
(4) cursor was positioned before the first or after the last in an empty tree:
-restores to before first or after the last in the tree. */
+restores to before first or after the last in the tree.
+@return TRUE if the cursor position was stored when it was on a user
+record and it can be restored on a user record whose ordering fields
+are identical to the ones of the original user record */
UNIV_INTERN
ibool
btr_pcur_restore_position(
/*======================*/
- /* out: TRUE if the cursor position
- was stored when it was on a user record
- and it can be restored on a user record
- whose ordering fields are identical to
- the ones of the original user record */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_pcur_t* cursor, /* in: detached persistent cursor */
- mtr_t* mtr); /* in: mtr */
-/******************************************************************
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_pcur_t* cursor, /*!< in: detached persistent cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/**************************************************************//**
If the latch mode of the cursor is BTR_LEAF_SEARCH or BTR_LEAF_MODIFY,
releases the page latch and bufferfix reserved by the cursor.
NOTE! In the case of BTR_LEAF_MODIFY, there should not exist changes
@@ -236,33 +233,33 @@ UNIV_INTERN
void
btr_pcur_release_leaf(
/*==================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
-Gets the rel_pos field for a cursor whose position has been stored. */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
+Gets the rel_pos field for a cursor whose position has been stored.
+@return BTR_PCUR_ON, ... */
UNIV_INLINE
ulint
btr_pcur_get_rel_pos(
/*=================*/
- /* out: BTR_PCUR_ON, ... */
- const btr_pcur_t* cursor);/* in: persistent cursor */
-/*************************************************************
+ const btr_pcur_t* cursor);/*!< in: persistent cursor */
+/*********************************************************//**
Sets the mtr field for a pcur. */
UNIV_INLINE
void
btr_pcur_set_mtr(
/*=============*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr); /* in, own: mtr */
-/*************************************************************
-Gets the mtr field for a pcur. */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr); /*!< in, own: mtr */
+/*********************************************************//**
+Gets the mtr field for a pcur.
+@return mtr */
UNIV_INLINE
mtr_t*
btr_pcur_get_mtr(
/*=============*/
- /* out: mtr */
- btr_pcur_t* cursor); /* in: persistent cursor */
-/******************************************************************
+ btr_pcur_t* cursor); /*!< in: persistent cursor */
+/**************************************************************//**
Commits the pcur mtr and sets the pcur latch mode to BTR_NO_LATCHES,
that is, the cursor becomes detached. If there have been modifications
to the page where pcur is positioned, this can be used instead of
@@ -272,68 +269,65 @@ UNIV_INLINE
void
btr_pcur_commit(
/*============*/
- btr_pcur_t* pcur); /* in: persistent cursor */
-/******************************************************************
+ btr_pcur_t* pcur); /*!< in: persistent cursor */
+/**************************************************************//**
Differs from btr_pcur_commit in that we can specify the mtr to commit. */
UNIV_INLINE
void
btr_pcur_commit_specify_mtr(
/*========================*/
- btr_pcur_t* pcur, /* in: persistent cursor */
- mtr_t* mtr); /* in: mtr to commit */
-/******************************************************************
-Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES. */
+ btr_pcur_t* pcur, /*!< in: persistent cursor */
+ mtr_t* mtr); /*!< in: mtr to commit */
+/**************************************************************//**
+Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES.
+@return TRUE if detached */
UNIV_INLINE
ibool
btr_pcur_is_detached(
/*=================*/
- /* out: TRUE if detached */
- btr_pcur_t* pcur); /* in: persistent cursor */
-/*************************************************************
+ btr_pcur_t* pcur); /*!< in: persistent cursor */
+/*********************************************************//**
Moves the persistent cursor to the next record in the tree. If no records are
-left, the cursor stays 'after last in tree'. */
+left, the cursor stays 'after last in tree'.
+@return TRUE if the cursor was not after last in tree */
UNIV_INLINE
ibool
btr_pcur_move_to_next(
/*==================*/
- /* out: TRUE if the cursor was not after last
- in tree */
- btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
Moves the persistent cursor to the previous record in the tree. If no records
-are left, the cursor stays 'before first in tree'. */
+are left, the cursor stays 'before first in tree'.
+@return TRUE if the cursor was not before first in tree */
UNIV_INTERN
ibool
btr_pcur_move_to_prev(
/*==================*/
- /* out: TRUE if the cursor was not before first
- in tree */
- btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
Moves the persistent cursor to the last record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_last_on_page(
/*==========================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
Moves the persistent cursor to the next user record in the tree. If no user
-records are left, the cursor ends up 'after last in tree'. */
+records are left, the cursor ends up 'after last in tree'.
+@return TRUE if the cursor moved forward, ending on a user record */
UNIV_INLINE
ibool
btr_pcur_move_to_next_user_rec(
/*===========================*/
- /* out: TRUE if the cursor moved forward,
- ending on a user record */
- btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
Moves the persistent cursor to the first record on the next page.
Releases the latch on the current page, and bufferunfixes it.
Note that there must not be modifications on the current page,
@@ -342,10 +336,10 @@ UNIV_INTERN
void
btr_pcur_move_to_next_page(
/*=======================*/
- btr_pcur_t* cursor, /* in: persistent cursor; must be on the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; must be on the
last record of the current page */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
Moves the persistent cursor backward if it is on the first record
of the page. Releases the latch on the current page, and bufferunfixes
it. Note that to prevent a possible deadlock, the operation first
@@ -359,119 +353,117 @@ UNIV_INTERN
void
btr_pcur_move_backward_from_page(
/*=============================*/
- btr_pcur_t* cursor, /* in: persistent cursor, must be on the
+ btr_pcur_t* cursor, /*!< in: persistent cursor, must be on the
first record of the current page */
- mtr_t* mtr); /* in: mtr */
+ mtr_t* mtr); /*!< in: mtr */
#ifdef UNIV_DEBUG
-/*************************************************************
-Returns the btr cursor component of a persistent cursor. */
+/*********************************************************//**
+Returns the btr cursor component of a persistent cursor.
+@return pointer to btr cursor component */
UNIV_INLINE
btr_cur_t*
btr_pcur_get_btr_cur(
/*=================*/
- /* out: pointer to
- btr cursor component */
- const btr_pcur_t* cursor); /* in: persistent cursor */
-/*************************************************************
-Returns the page cursor component of a persistent cursor. */
+ const btr_pcur_t* cursor); /*!< in: persistent cursor */
+/*********************************************************//**
+Returns the page cursor component of a persistent cursor.
+@return pointer to page cursor component */
UNIV_INLINE
page_cur_t*
btr_pcur_get_page_cur(
/*==================*/
- /* out: pointer to
- page cursor component */
- const btr_pcur_t* cursor); /* in: persistent cursor */
+ const btr_pcur_t* cursor); /*!< in: persistent cursor */
#else /* UNIV_DEBUG */
# define btr_pcur_get_btr_cur(cursor) (&(cursor)->btr_cur)
# define btr_pcur_get_page_cur(cursor) (&(cursor)->btr_cur.page_cur)
#endif /* UNIV_DEBUG */
-/*************************************************************
-Returns the page of a persistent cursor. */
+/*********************************************************//**
+Returns the page of a persistent cursor.
+@return pointer to the page */
UNIV_INLINE
page_t*
btr_pcur_get_page(
/*==============*/
- /* out: pointer to the page */
- btr_pcur_t* cursor);/* in: persistent cursor */
-/*************************************************************
-Returns the buffer block of a persistent cursor. */
+ btr_pcur_t* cursor);/*!< in: persistent cursor */
+/*********************************************************//**
+Returns the buffer block of a persistent cursor.
+@return pointer to the block */
UNIV_INLINE
buf_block_t*
btr_pcur_get_block(
/*===============*/
- /* out: pointer to the block */
- btr_pcur_t* cursor);/* in: persistent cursor */
-/*************************************************************
-Returns the record of a persistent cursor. */
+ btr_pcur_t* cursor);/*!< in: persistent cursor */
+/*********************************************************//**
+Returns the record of a persistent cursor.
+@return pointer to the record */
UNIV_INLINE
rec_t*
btr_pcur_get_rec(
/*=============*/
- /* out: pointer to the record */
- btr_pcur_t* cursor);/* in: persistent cursor */
-/*************************************************************
+ btr_pcur_t* cursor);/*!< in: persistent cursor */
+/*********************************************************//**
Checks if the persistent cursor is on a user record. */
UNIV_INLINE
ibool
btr_pcur_is_on_user_rec(
/*====================*/
- const btr_pcur_t* cursor);/* in: persistent cursor */
-/*************************************************************
+ const btr_pcur_t* cursor);/*!< in: persistent cursor */
+/*********************************************************//**
Checks if the persistent cursor is after the last user record on
a page. */
UNIV_INLINE
ibool
btr_pcur_is_after_last_on_page(
/*===========================*/
- const btr_pcur_t* cursor);/* in: persistent cursor */
-/*************************************************************
+ const btr_pcur_t* cursor);/*!< in: persistent cursor */
+/*********************************************************//**
Checks if the persistent cursor is before the first user record on
a page. */
UNIV_INLINE
ibool
btr_pcur_is_before_first_on_page(
/*=============================*/
- const btr_pcur_t* cursor);/* in: persistent cursor */
-/*************************************************************
+ const btr_pcur_t* cursor);/*!< in: persistent cursor */
+/*********************************************************//**
Checks if the persistent cursor is before the first user record in
the index tree. */
UNIV_INLINE
ibool
btr_pcur_is_before_first_in_tree(
/*=============================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
Checks if the persistent cursor is after the last user record in
the index tree. */
UNIV_INLINE
ibool
btr_pcur_is_after_last_in_tree(
/*===========================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************//**
Moves the persistent cursor to the next record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_next_on_page(
/*==========================*/
- btr_pcur_t* cursor);/* in/out: persistent cursor */
-/*************************************************************
+ btr_pcur_t* cursor);/*!< in/out: persistent cursor */
+/*********************************************************//**
Moves the persistent cursor to the previous record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_prev_on_page(
/*==========================*/
- btr_pcur_t* cursor);/* in/out: persistent cursor */
+ btr_pcur_t* cursor);/*!< in/out: persistent cursor */
/* The persistent B-tree cursor structure. This is used mainly for SQL
selects, updates, and deletes. */
struct btr_pcur_struct{
- btr_cur_t btr_cur; /* a B-tree cursor */
- ulint latch_mode; /* see TODO note below!
+ btr_cur_t btr_cur; /*!< a B-tree cursor */
+ ulint latch_mode; /*!< see TODO note below!
BTR_SEARCH_LEAF, BTR_MODIFY_LEAF,
BTR_MODIFY_TREE, or BTR_NO_LATCHES,
depending on the latching state of
@@ -482,28 +474,28 @@ struct btr_pcur_struct{
detached; it can be restored to
attached if the old position was
stored in old_rec */
- ulint old_stored; /* BTR_PCUR_OLD_STORED
+ ulint old_stored; /*!< BTR_PCUR_OLD_STORED
or BTR_PCUR_OLD_NOT_STORED */
- rec_t* old_rec; /* if cursor position is stored,
+ rec_t* old_rec; /*!< if cursor position is stored,
contains an initial segment of the
latest record cursor was positioned
either on, before, or after */
- ulint old_n_fields; /* number of fields in old_rec */
- ulint rel_pos; /* BTR_PCUR_ON, BTR_PCUR_BEFORE, or
+ ulint old_n_fields; /*!< number of fields in old_rec */
+ ulint rel_pos; /*!< BTR_PCUR_ON, BTR_PCUR_BEFORE, or
BTR_PCUR_AFTER, depending on whether
cursor was on, before, or after the
old_rec record */
buf_block_t* block_when_stored;/* buffer block when the position was
stored */
- ib_uint64_t modify_clock; /* the modify clock value of the
+ ib_uint64_t modify_clock; /*!< the modify clock value of the
buffer block when the cursor position
was stored */
- ulint pos_state; /* see TODO note below!
+ ulint pos_state; /*!< see TODO note below!
BTR_PCUR_IS_POSITIONED,
BTR_PCUR_WAS_POSITIONED,
BTR_PCUR_NOT_POSITIONED */
- ulint search_mode; /* PAGE_CUR_G, ... */
- trx_t* trx_if_known; /* the transaction, if we know it;
+ ulint search_mode; /*!< PAGE_CUR_G, ... */
+ trx_t* trx_if_known; /*!< the transaction, if we know it;
otherwise this field is not defined;
can ONLY BE USED in error prints in
fatal assertion failures! */
@@ -511,12 +503,12 @@ struct btr_pcur_struct{
/* NOTE that the following fields may possess dynamically allocated
memory which should be freed if not needed anymore! */
- mtr_t* mtr; /* NULL, or this field may contain
+ mtr_t* mtr; /*!< NULL, or this field may contain
a mini-transaction which holds the
latch on the cursor page */
- byte* old_rec_buf; /* NULL, or a dynamically allocated
+ byte* old_rec_buf; /*!< NULL, or a dynamically allocated
buffer for old_rec */
- ulint buf_size; /* old_rec_buf size if old_rec_buf
+ ulint buf_size; /*!< old_rec_buf size if old_rec_buf
is not NULL */
};
diff --git a/storage/xtradb/include/btr0pcur.ic b/storage/xtradb/include/btr0pcur.ic
index bde7413820a..0ca7223f861 100644
--- a/storage/xtradb/include/btr0pcur.ic
+++ b/storage/xtradb/include/btr0pcur.ic
@@ -16,21 +16,22 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/btr0pcur.ic
The index tree persistent cursor
Created 2/23/1996 Heikki Tuuri
*******************************************************/
-/*************************************************************
-Gets the rel_pos field for a cursor whose position has been stored. */
+/*********************************************************//**
+Gets the rel_pos field for a cursor whose position has been stored.
+@return BTR_PCUR_ON, ... */
UNIV_INLINE
ulint
btr_pcur_get_rel_pos(
/*=================*/
- /* out: BTR_PCUR_ON, ... */
- const btr_pcur_t* cursor) /* in: persistent cursor */
+ const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor);
ut_ad(cursor->old_rec);
@@ -41,28 +42,28 @@ btr_pcur_get_rel_pos(
return(cursor->rel_pos);
}
-/*************************************************************
+/*********************************************************//**
Sets the mtr field for a pcur. */
UNIV_INLINE
void
btr_pcur_set_mtr(
/*=============*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr) /* in, own: mtr */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr) /*!< in, own: mtr */
{
ut_ad(cursor);
cursor->mtr = mtr;
}
-/*************************************************************
-Gets the mtr field for a pcur. */
+/*********************************************************//**
+Gets the mtr field for a pcur.
+@return mtr */
UNIV_INLINE
mtr_t*
btr_pcur_get_mtr(
/*=============*/
- /* out: mtr */
- btr_pcur_t* cursor) /* in: persistent cursor */
+ btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor);
@@ -70,69 +71,67 @@ btr_pcur_get_mtr(
}
#ifdef UNIV_DEBUG
-/*************************************************************
-Returns the btr cursor component of a persistent cursor. */
+/*********************************************************//**
+Returns the btr cursor component of a persistent cursor.
+@return pointer to btr cursor component */
UNIV_INLINE
btr_cur_t*
btr_pcur_get_btr_cur(
/*=================*/
- /* out: pointer to
- btr cursor component */
- const btr_pcur_t* cursor) /* in: persistent cursor */
+ const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
const btr_cur_t* btr_cur = &cursor->btr_cur;
return((btr_cur_t*) btr_cur);
}
-/*************************************************************
-Returns the page cursor component of a persistent cursor. */
+/*********************************************************//**
+Returns the page cursor component of a persistent cursor.
+@return pointer to page cursor component */
UNIV_INLINE
page_cur_t*
btr_pcur_get_page_cur(
/*==================*/
- /* out: pointer to page cursor
- component */
- const btr_pcur_t* cursor) /* in: persistent cursor */
+ const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
return(btr_cur_get_page_cur(btr_pcur_get_btr_cur(cursor)));
}
#endif /* UNIV_DEBUG */
-/*************************************************************
-Returns the page of a persistent cursor. */
+/*********************************************************//**
+Returns the page of a persistent cursor.
+@return pointer to the page */
UNIV_INLINE
page_t*
btr_pcur_get_page(
/*==============*/
- /* out: pointer to the page */
- btr_pcur_t* cursor) /* in: persistent cursor */
+ btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
return(btr_cur_get_page(btr_pcur_get_btr_cur(cursor)));
}
-/*************************************************************
-Returns the buffer block of a persistent cursor. */
+/*********************************************************//**
+Returns the buffer block of a persistent cursor.
+@return pointer to the block */
UNIV_INLINE
buf_block_t*
btr_pcur_get_block(
/*===============*/
- /* out: pointer to the block */
- btr_pcur_t* cursor) /* in: persistent cursor */
+ btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
return(btr_cur_get_block(btr_pcur_get_btr_cur(cursor)));
}
-/*************************************************************
-Returns the record of a persistent cursor. */
+/*********************************************************//**
+Returns the record of a persistent cursor.
+@return pointer to the record */
UNIV_INLINE
rec_t*
btr_pcur_get_rec(
/*=============*/
- /* out: pointer to the record */
- btr_pcur_t* cursor) /* in: persistent cursor */
+ btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -140,16 +139,15 @@ btr_pcur_get_rec(
return(btr_cur_get_rec(btr_pcur_get_btr_cur(cursor)));
}
-/******************************************************************
-Gets the up_match value for a pcur after a search. */
+/**************************************************************//**
+Gets the up_match value for a pcur after a search.
+@return number of matched fields at the cursor or to the right if
+search mode was PAGE_CUR_GE, otherwise undefined */
UNIV_INLINE
ulint
btr_pcur_get_up_match(
/*==================*/
- /* out: number of matched fields at the cursor
- or to the right if search mode was PAGE_CUR_GE,
- otherwise undefined */
- btr_pcur_t* cursor) /* in: memory buffer for persistent cursor */
+ btr_pcur_t* cursor) /*!< in: memory buffer for persistent cursor */
{
btr_cur_t* btr_cursor;
@@ -163,16 +161,15 @@ btr_pcur_get_up_match(
return(btr_cursor->up_match);
}
-/******************************************************************
-Gets the low_match value for a pcur after a search. */
+/**************************************************************//**
+Gets the low_match value for a pcur after a search.
+@return number of matched fields at the cursor or to the right if
+search mode was PAGE_CUR_LE, otherwise undefined */
UNIV_INLINE
ulint
btr_pcur_get_low_match(
/*===================*/
- /* out: number of matched fields at the cursor
- or to the right if search mode was PAGE_CUR_LE,
- otherwise undefined */
- btr_pcur_t* cursor) /* in: memory buffer for persistent cursor */
+ btr_pcur_t* cursor) /*!< in: memory buffer for persistent cursor */
{
btr_cur_t* btr_cursor;
@@ -185,14 +182,14 @@ btr_pcur_get_low_match(
return(btr_cursor->low_match);
}
-/*************************************************************
+/*********************************************************//**
Checks if the persistent cursor is after the last user record on
a page. */
UNIV_INLINE
ibool
btr_pcur_is_after_last_on_page(
/*===========================*/
- const btr_pcur_t* cursor) /* in: persistent cursor */
+ const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -200,14 +197,14 @@ btr_pcur_is_after_last_on_page(
return(page_cur_is_after_last(btr_pcur_get_page_cur(cursor)));
}
-/*************************************************************
+/*********************************************************//**
Checks if the persistent cursor is before the first user record on
a page. */
UNIV_INLINE
ibool
btr_pcur_is_before_first_on_page(
/*=============================*/
- const btr_pcur_t* cursor) /* in: persistent cursor */
+ const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -215,13 +212,13 @@ btr_pcur_is_before_first_on_page(
return(page_cur_is_before_first(btr_pcur_get_page_cur(cursor)));
}
-/*************************************************************
+/*********************************************************//**
Checks if the persistent cursor is on a user record. */
UNIV_INLINE
ibool
btr_pcur_is_on_user_rec(
/*====================*/
- const btr_pcur_t* cursor) /* in: persistent cursor */
+ const btr_pcur_t* cursor) /*!< in: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -235,15 +232,15 @@ btr_pcur_is_on_user_rec(
return(TRUE);
}
-/*************************************************************
+/*********************************************************//**
Checks if the persistent cursor is before the first user record in
the index tree. */
UNIV_INLINE
ibool
btr_pcur_is_before_first_in_tree(
/*=============================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr) /* in: mtr */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -256,15 +253,15 @@ btr_pcur_is_before_first_in_tree(
return(page_cur_is_before_first(btr_pcur_get_page_cur(cursor)));
}
-/*************************************************************
+/*********************************************************//**
Checks if the persistent cursor is after the last user record in
the index tree. */
UNIV_INLINE
ibool
btr_pcur_is_after_last_in_tree(
/*===========================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr) /* in: mtr */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -277,13 +274,13 @@ btr_pcur_is_after_last_in_tree(
return(page_cur_is_after_last(btr_pcur_get_page_cur(cursor)));
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor to the next record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_next_on_page(
/*==========================*/
- btr_pcur_t* cursor) /* in/out: persistent cursor */
+ btr_pcur_t* cursor) /*!< in/out: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -293,13 +290,13 @@ btr_pcur_move_to_next_on_page(
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor to the previous record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_prev_on_page(
/*==========================*/
- btr_pcur_t* cursor) /* in/out: persistent cursor */
+ btr_pcur_t* cursor) /*!< in/out: persistent cursor */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -309,14 +306,14 @@ btr_pcur_move_to_prev_on_page(
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor to the last record on the same page. */
UNIV_INLINE
void
btr_pcur_move_to_last_on_page(
/*==========================*/
- btr_pcur_t* cursor, /* in: persistent cursor */
- mtr_t* mtr) /* in: mtr */
+ btr_pcur_t* cursor, /*!< in: persistent cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
UT_NOT_USED(mtr);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -327,18 +324,17 @@ btr_pcur_move_to_last_on_page(
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor to the next user record in the tree. If no user
-records are left, the cursor ends up 'after last in tree'. */
+records are left, the cursor ends up 'after last in tree'.
+@return TRUE if the cursor moved forward, ending on a user record */
UNIV_INLINE
ibool
btr_pcur_move_to_next_user_rec(
/*===========================*/
- /* out: TRUE if the cursor moved forward,
- ending on a user record */
- btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -364,18 +360,17 @@ loop:
goto loop;
}
-/*************************************************************
+/*********************************************************//**
Moves the persistent cursor to the next record in the tree. If no records are
-left, the cursor stays 'after last in tree'. */
+left, the cursor stays 'after last in tree'.
+@return TRUE if the cursor was not after last in tree */
UNIV_INLINE
ibool
btr_pcur_move_to_next(
/*==================*/
- /* out: TRUE if the cursor was not after last
- in tree */
- btr_pcur_t* cursor, /* in: persistent cursor; NOTE that the
+ btr_pcur_t* cursor, /*!< in: persistent cursor; NOTE that the
function may release the page latch */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -399,7 +394,7 @@ btr_pcur_move_to_next(
return(TRUE);
}
-/******************************************************************
+/**************************************************************//**
Commits the pcur mtr and sets the pcur latch mode to BTR_NO_LATCHES,
that is, the cursor becomes detached. If there have been modifications
to the page where pcur is positioned, this can be used instead of
@@ -409,7 +404,7 @@ UNIV_INLINE
void
btr_pcur_commit(
/*============*/
- btr_pcur_t* pcur) /* in: persistent cursor */
+ btr_pcur_t* pcur) /*!< in: persistent cursor */
{
ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
@@ -420,14 +415,14 @@ btr_pcur_commit(
pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
}
-/******************************************************************
+/**************************************************************//**
Differs from btr_pcur_commit in that we can specify the mtr to commit. */
UNIV_INLINE
void
btr_pcur_commit_specify_mtr(
/*========================*/
- btr_pcur_t* pcur, /* in: persistent cursor */
- mtr_t* mtr) /* in: mtr to commit */
+ btr_pcur_t* pcur, /*!< in: persistent cursor */
+ mtr_t* mtr) /*!< in: mtr to commit */
{
ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
@@ -438,13 +433,13 @@ btr_pcur_commit_specify_mtr(
pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
}
-/******************************************************************
+/**************************************************************//**
Sets the pcur latch mode to BTR_NO_LATCHES. */
UNIV_INLINE
void
btr_pcur_detach(
/*============*/
- btr_pcur_t* pcur) /* in: persistent cursor */
+ btr_pcur_t* pcur) /*!< in: persistent cursor */
{
ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
@@ -453,14 +448,14 @@ btr_pcur_detach(
pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
}
-/******************************************************************
-Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES. */
+/**************************************************************//**
+Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES.
+@return TRUE if detached */
UNIV_INLINE
ibool
btr_pcur_is_detached(
/*=================*/
- /* out: TRUE if detached */
- btr_pcur_t* pcur) /* in: persistent cursor */
+ btr_pcur_t* pcur) /*!< in: persistent cursor */
{
if (pcur->latch_mode == BTR_NO_LATCHES) {
@@ -470,37 +465,37 @@ btr_pcur_is_detached(
return(FALSE);
}
-/******************************************************************
+/**************************************************************//**
Sets the old_rec_buf field to NULL. */
UNIV_INLINE
void
btr_pcur_init(
/*==========*/
- btr_pcur_t* pcur) /* in: persistent cursor */
+ btr_pcur_t* pcur) /*!< in: persistent cursor */
{
pcur->old_stored = BTR_PCUR_OLD_NOT_STORED;
pcur->old_rec_buf = NULL;
pcur->old_rec = NULL;
}
-/******************************************************************
+/**************************************************************//**
Initializes and opens a persistent cursor to an index tree. It should be
closed with btr_pcur_close. */
UNIV_INLINE
void
btr_pcur_open(
/*==========*/
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple, /* in: tuple on which search done */
- ulint mode, /* in: PAGE_CUR_L, ...;
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple, /*!< in: tuple on which search done */
+ ulint mode, /*!< in: PAGE_CUR_L, ...;
NOTE that if the search is made using a unique
prefix of a record, mode should be
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page from the
record! */
- ulint latch_mode,/* in: BTR_SEARCH_LEAF, ... */
- btr_pcur_t* cursor, /* in: memory buffer for persistent cursor */
- mtr_t* mtr) /* in: mtr */
+ ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ... */
+ btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
+ mtr_t* mtr) /*!< in: mtr */
{
btr_cur_t* btr_cursor;
@@ -522,31 +517,31 @@ btr_pcur_open(
cursor->trx_if_known = NULL;
}
-/******************************************************************
+/**************************************************************//**
Opens an persistent cursor to an index tree without initializing the
cursor. */
UNIV_INLINE
void
btr_pcur_open_with_no_init(
/*=======================*/
- dict_index_t* index, /* in: index */
- const dtuple_t* tuple, /* in: tuple on which search done */
- ulint mode, /* in: PAGE_CUR_L, ...;
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* tuple, /*!< in: tuple on which search done */
+ ulint mode, /*!< in: PAGE_CUR_L, ...;
NOTE that if the search is made using a unique
prefix of a record, mode should be
PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
may end up on the previous page of the
record! */
- ulint latch_mode,/* in: BTR_SEARCH_LEAF, ...;
+ ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...;
NOTE that if has_search_latch != 0 then
we maybe do not acquire a latch on the cursor
page, but assume that the caller uses his
btr search latch to protect the record! */
- btr_pcur_t* cursor, /* in: memory buffer for persistent cursor */
- ulint has_search_latch,/* in: latch mode the caller
+ btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */
+ ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch:
RW_S_LATCH, or 0 */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
btr_cur_t* btr_cursor;
@@ -566,19 +561,19 @@ btr_pcur_open_with_no_init(
cursor->trx_if_known = NULL;
}
-/*********************************************************************
+/*****************************************************************//**
Opens a persistent cursor at either end of an index. */
UNIV_INLINE
void
btr_pcur_open_at_index_side(
/*========================*/
- ibool from_left, /* in: TRUE if open to the low end,
+ ibool from_left, /*!< in: TRUE if open to the low end,
FALSE if to the high end */
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: latch mode */
- btr_pcur_t* pcur, /* in: cursor */
- ibool do_init, /* in: TRUE if should be initialized */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: latch mode */
+ btr_pcur_t* pcur, /*!< in: cursor */
+ ibool do_init, /*!< in: TRUE if should be initialized */
+ mtr_t* mtr) /*!< in: mtr */
{
pcur->latch_mode = latch_mode;
@@ -601,16 +596,16 @@ btr_pcur_open_at_index_side(
pcur->trx_if_known = NULL;
}
-/**************************************************************************
+/**********************************************************************//**
Positions a cursor at a randomly chosen position within a B-tree. */
UNIV_INLINE
void
btr_pcur_open_at_rnd_pos(
/*=====================*/
- dict_index_t* index, /* in: index */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_pcur_t* cursor, /* in/out: B-tree pcur */
- mtr_t* mtr) /* in: mtr */
+ dict_index_t* index, /*!< in: index */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_pcur_t* cursor, /*!< in/out: B-tree pcur */
+ mtr_t* mtr) /*!< in: mtr */
{
/* Initialize the cursor */
@@ -627,14 +622,14 @@ btr_pcur_open_at_rnd_pos(
cursor->trx_if_known = NULL;
}
-/******************************************************************
+/**************************************************************//**
Frees the possible memory heap of a persistent cursor and sets the latch
mode of the persistent cursor to BTR_NO_LATCHES. */
UNIV_INLINE
void
btr_pcur_close(
/*===========*/
- btr_pcur_t* cursor) /* in: persistent cursor */
+ btr_pcur_t* cursor) /*!< in: persistent cursor */
{
if (cursor->old_rec_buf != NULL) {
diff --git a/storage/xtradb/include/btr0sea.h b/storage/xtradb/include/btr0sea.h
index 074e6595258..5c50829e874 100644
--- a/storage/xtradb/include/btr0sea.h
+++ b/storage/xtradb/include/btr0sea.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/btr0sea.h
The index tree adaptive search
Created 2/17/1996 Heikki Tuuri
@@ -33,81 +34,81 @@ Created 2/17/1996 Heikki Tuuri
#include "mtr0mtr.h"
#include "ha0ha.h"
-/*********************************************************************
+/*****************************************************************//**
Creates and initializes the adaptive search system at a database start. */
UNIV_INTERN
void
btr_search_sys_create(
/*==================*/
- ulint hash_size); /* in: hash index hash table size */
+ ulint hash_size); /*!< in: hash index hash table size */
-/************************************************************************
+/********************************************************************//**
Disable the adaptive hash search system and empty the index. */
UNIV_INTERN
void
btr_search_disable(void);
/*====================*/
-/************************************************************************
+/********************************************************************//**
Enable the adaptive hash search system. */
UNIV_INTERN
void
btr_search_enable(void);
/*====================*/
-/************************************************************************
-Returns search info for an index. */
+/********************************************************************//**
+Returns search info for an index.
+@return search info; search mutex reserved */
UNIV_INLINE
btr_search_t*
btr_search_get_info(
/*================*/
- /* out: search info; search mutex reserved */
- dict_index_t* index); /* in: index */
-/*********************************************************************
-Creates and initializes a search info struct. */
+ dict_index_t* index); /*!< in: index */
+/*****************************************************************//**
+Creates and initializes a search info struct.
+@return own: search info struct */
UNIV_INTERN
btr_search_t*
btr_search_info_create(
/*===================*/
- /* out, own: search info struct */
- mem_heap_t* heap); /* in: heap where created */
-/*********************************************************************
+ mem_heap_t* heap); /*!< in: heap where created */
+/*****************************************************************//**
Returns the value of ref_count. The value is protected by
-btr_search_latch. */
+btr_search_latch.
+@return ref_count value. */
UNIV_INTERN
ulint
btr_search_info_get_ref_count(
/*==========================*/
- /* out: ref_count value. */
- btr_search_t* info); /* in: search info. */
-/*************************************************************************
+ btr_search_t* info); /*!< in: search info. */
+/*********************************************************************//**
Updates the search info. */
UNIV_INLINE
void
btr_search_info_update(
/*===================*/
- dict_index_t* index, /* in: index of the cursor */
- btr_cur_t* cursor);/* in: cursor which was just positioned */
-/**********************************************************************
+ dict_index_t* index, /*!< in: index of the cursor */
+ btr_cur_t* cursor);/*!< in: cursor which was just positioned */
+/******************************************************************//**
Tries to guess the right search position based on the hash search info
of the index. Note that if mode is PAGE_CUR_LE, which is used in inserts,
and the function returns TRUE, then cursor->up_match and cursor->low_match
-both have sensible values. */
+both have sensible values.
+@return TRUE if succeeded */
UNIV_INTERN
ibool
btr_search_guess_on_hash(
/*=====================*/
- /* out: TRUE if succeeded */
- dict_index_t* index, /* in: index */
- btr_search_t* info, /* in: index search info */
- const dtuple_t* tuple, /* in: logical record */
- ulint mode, /* in: PAGE_CUR_L, ... */
- ulint latch_mode, /* in: BTR_SEARCH_LEAF, ... */
- btr_cur_t* cursor, /* out: tree cursor */
- ulint has_search_latch,/* in: latch mode the caller
+ dict_index_t* index, /*!< in: index */
+ btr_search_t* info, /*!< in: index search info */
+ const dtuple_t* tuple, /*!< in: logical record */
+ ulint mode, /*!< in: PAGE_CUR_L, ... */
+ ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
+ btr_cur_t* cursor, /*!< out: tree cursor */
+ ulint has_search_latch,/*!< in: latch mode the caller
currently has on btr_search_latch:
RW_S_LATCH, RW_X_LATCH, or 0 */
- mtr_t* mtr); /* in: mtr */
-/************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/********************************************************************//**
Moves or deletes hash entries for moved records. If new_page is already hashed,
then the hash index for page, if any, is dropped. If new_page is not hashed,
and page is hashed, then a new hash index is built to new_page with the same
@@ -116,139 +117,153 @@ UNIV_INTERN
void
btr_search_move_or_delete_hash_entries(
/*===================================*/
- buf_block_t* new_block, /* in: records are copied
+ buf_block_t* new_block, /*!< in: records are copied
to this page */
- buf_block_t* block, /* in: index page from which
+ buf_block_t* block, /*!< in: index page from which
records were copied, and the
copied records will be deleted
from this page */
- dict_index_t* index); /* in: record descriptor */
-/************************************************************************
+ dict_index_t* index); /*!< in: record descriptor */
+/********************************************************************//**
Drops a page hash index. */
UNIV_INTERN
void
btr_search_drop_page_hash_index(
/*============================*/
- buf_block_t* block); /* in: block containing index page,
+ buf_block_t* block); /*!< in: block containing index page,
s- or x-latched, or an index page
for which we know that
block->buf_fix_count == 0 */
/************************************************************************
+Drops a page hash index based on index */
+UNIV_INTERN
+void
+btr_search_drop_page_hash_index_on_index(
+/*=====================================*/
+ dict_index_t* index); /* in: record descriptor */
+/********************************************************************//**
Drops a page hash index when a page is freed from a fseg to the file system.
Drops possible hash index if the page happens to be in the buffer pool. */
UNIV_INTERN
void
btr_search_drop_page_hash_when_freed(
/*=================================*/
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no); /* in: page number */
-/************************************************************************
+ ulint page_no); /*!< in: page number */
+/********************************************************************//**
Updates the page hash index when a single record is inserted on a page. */
UNIV_INTERN
void
btr_search_update_hash_node_on_insert(
/*==================================*/
- btr_cur_t* cursor);/* in: cursor which was positioned to the
+ btr_cur_t* cursor);/*!< in: cursor which was positioned to the
place to insert using btr_cur_search_...,
and the new record has been inserted next
to the cursor */
-/************************************************************************
+/********************************************************************//**
Updates the page hash index when a single record is inserted on a page. */
UNIV_INTERN
void
btr_search_update_hash_on_insert(
/*=============================*/
- btr_cur_t* cursor);/* in: cursor which was positioned to the
+ btr_cur_t* cursor);/*!< in: cursor which was positioned to the
place to insert using btr_cur_search_...,
and the new record has been inserted next
to the cursor */
-/************************************************************************
+/********************************************************************//**
Updates the page hash index when a single record is deleted from a page. */
UNIV_INTERN
void
btr_search_update_hash_on_delete(
/*=============================*/
- btr_cur_t* cursor);/* in: cursor which was positioned on the
+ btr_cur_t* cursor);/*!< in: cursor which was positioned on the
record to delete using btr_cur_search_...,
the record is not yet deleted */
-/************************************************************************
-Validates the search system. */
+/********************************************************************//**
+Validates the search system.
+@return TRUE if ok */
UNIV_INTERN
ibool
btr_search_validate(void);
/*======================*/
- /* out: TRUE if ok */
-/* Flag: has the search system been enabled?
+/** Flag: has the search system been enabled?
Protected by btr_search_latch and btr_search_enabled_mutex. */
extern char btr_search_enabled;
-/* The search info struct in an index */
-
+/** The search info struct in an index */
struct btr_search_struct{
- ulint ref_count; /* Number of blocks in this index tree
+ ulint ref_count; /*!< Number of blocks in this index tree
that have search index built
i.e. block->index points to this index.
Protected by btr_search_latch except
when during initialization in
btr_search_info_create(). */
- /* The following fields are not protected by any latch.
+ /* @{ The following fields are not protected by any latch.
Unfortunately, this means that they must be aligned to
the machine word, i.e., they cannot be turned into bit-fields. */
- buf_block_t* root_guess;/* the root page frame when it was last time
+ buf_block_t* root_guess;/*!< the root page frame when it was last time
fetched, or NULL */
- ulint hash_analysis; /* when this exceeds BTR_SEARCH_HASH_ANALYSIS,
- the hash analysis starts; this is reset if no
+ ulint hash_analysis; /*!< when this exceeds
+ BTR_SEARCH_HASH_ANALYSIS, the hash
+ analysis starts; this is reset if no
success noticed */
- ibool last_hash_succ; /* TRUE if the last search would have
+ ibool last_hash_succ; /*!< TRUE if the last search would have
succeeded, or did succeed, using the hash
index; NOTE that the value here is not exact:
it is not calculated for every search, and the
calculation itself is not always accurate! */
ulint n_hash_potential;
- /* number of consecutive searches
+ /*!< number of consecutive searches
which would have succeeded, or did succeed,
using the hash index;
the range is 0 .. BTR_SEARCH_BUILD_LIMIT + 5 */
- /*----------------------*/
- ulint n_fields; /* recommended prefix length for hash search:
+ /* @} */
+ /*---------------------- @{ */
+ ulint n_fields; /*!< recommended prefix length for hash search:
number of full fields */
- ulint n_bytes; /* recommended prefix: number of bytes in
- an incomplete field;
- see also BTR_PAGE_MAX_REC_SIZE */
- ibool left_side; /* TRUE or FALSE, depending on whether
+ ulint n_bytes; /*!< recommended prefix: number of bytes in
+ an incomplete field
+ @see BTR_PAGE_MAX_REC_SIZE */
+ ibool left_side; /*!< TRUE or FALSE, depending on whether
the leftmost record of several records with
the same prefix should be indexed in the
hash index */
- /*----------------------*/
+ /*---------------------- @} */
#ifdef UNIV_SEARCH_PERF_STAT
- ulint n_hash_succ; /* number of successful hash searches thus
+ ulint n_hash_succ; /*!< number of successful hash searches thus
far */
- ulint n_hash_fail; /* number of failed hash searches */
- ulint n_patt_succ; /* number of successful pattern searches thus
+ ulint n_hash_fail; /*!< number of failed hash searches */
+ ulint n_patt_succ; /*!< number of successful pattern searches thus
far */
- ulint n_searches; /* number of searches */
+ ulint n_searches; /*!< number of searches */
#endif /* UNIV_SEARCH_PERF_STAT */
#ifdef UNIV_DEBUG
- ulint magic_n; /* magic number */
+ ulint magic_n; /*!< magic number @see BTR_SEARCH_MAGIC_N */
+/** value of btr_search_struct::magic_n, used in assertions */
# define BTR_SEARCH_MAGIC_N 1112765
#endif /* UNIV_DEBUG */
};
-/* The hash index system */
-
+/** The hash index system */
typedef struct btr_search_sys_struct btr_search_sys_t;
+/** The hash index system */
struct btr_search_sys_struct{
- hash_table_t* hash_index;
+ hash_table_t* hash_index; /*!< the adaptive hash index,
+ mapping dtuple_fold values
+ to rec_t pointers on index pages */
};
+/** The adaptive hash index */
extern btr_search_sys_t* btr_search_sys;
-/* The latch protecting the adaptive search system: this latch protects the
+/** @brief The latch protecting the adaptive search system
+
+This latch protects the
(1) hash index;
(2) columns of a record to which we have a pointer in the hash index;
@@ -259,36 +274,34 @@ but does NOT protect:
Bear in mind (3) and (4) when using the hash index.
*/
-
extern rw_lock_t* btr_search_latch_temp;
+/** The latch protecting the adaptive search system */
#define btr_search_latch (*btr_search_latch_temp)
#ifdef UNIV_SEARCH_PERF_STAT
+/** Number of successful adaptive hash index lookups */
extern ulint btr_search_n_succ;
+/** Number of failed adaptive hash index lookups */
extern ulint btr_search_n_hash_fail;
#endif /* UNIV_SEARCH_PERF_STAT */
-/* After change in n_fields or n_bytes in info, this many rounds are waited
+/** After change in n_fields or n_bytes in info, this many rounds are waited
before starting the hash analysis again: this is to save CPU time when there
is no hope in building a hash index. */
-
#define BTR_SEARCH_HASH_ANALYSIS 17
-/* Limit of consecutive searches for trying a search shortcut on the search
+/** Limit of consecutive searches for trying a search shortcut on the search
pattern */
-
#define BTR_SEARCH_ON_PATTERN_LIMIT 3
-/* Limit of consecutive searches for trying a search shortcut using the hash
-index */
-
+/** Limit of consecutive searches for trying a search shortcut using
+the hash index */
#define BTR_SEARCH_ON_HASH_LIMIT 3
-/* We do this many searches before trying to keep the search latch over calls
-from MySQL. If we notice someone waiting for the latch, we again set this
-much timeout. This is to reduce contention. */
-
+/** We do this many searches before trying to keep the search latch
+over calls from MySQL. If we notice someone waiting for the latch, we
+again set this much timeout. This is to reduce contention. */
#define BTR_SEA_TIMEOUT 10000
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/btr0sea.ic b/storage/xtradb/include/btr0sea.ic
index c948d7e92af..beadeeb8d02 100644
--- a/storage/xtradb/include/btr0sea.ic
+++ b/storage/xtradb/include/btr0sea.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/btr0sea.ic
The index tree adaptive search
Created 2/17/1996 Heikki Tuuri
@@ -26,37 +27,37 @@ Created 2/17/1996 Heikki Tuuri
#include "btr0cur.h"
#include "buf0buf.h"
-/*************************************************************************
+/*********************************************************************//**
Updates the search info. */
UNIV_INTERN
void
btr_search_info_update_slow(
/*========================*/
- btr_search_t* info, /* in/out: search info */
- btr_cur_t* cursor);/* in: cursor which was just positioned */
+ btr_search_t* info, /*!< in/out: search info */
+ btr_cur_t* cursor);/*!< in: cursor which was just positioned */
-/************************************************************************
-Returns search info for an index. */
+/********************************************************************//**
+Returns search info for an index.
+@return search info; search mutex reserved */
UNIV_INLINE
btr_search_t*
btr_search_get_info(
/*================*/
- /* out: search info; search mutex reserved */
- dict_index_t* index) /* in: index */
+ dict_index_t* index) /*!< in: index */
{
ut_ad(index);
return(index->search_info);
}
-/*************************************************************************
+/*********************************************************************//**
Updates the search info. */
UNIV_INLINE
void
btr_search_info_update(
/*===================*/
- dict_index_t* index, /* in: index of the cursor */
- btr_cur_t* cursor) /* in: cursor which was just positioned */
+ dict_index_t* index, /*!< in: index of the cursor */
+ btr_cur_t* cursor) /*!< in: cursor which was just positioned */
{
btr_search_t* info;
diff --git a/storage/xtradb/include/btr0types.h b/storage/xtradb/include/btr0types.h
index 074b15fa68d..ef4a6b04b34 100644
--- a/storage/xtradb/include/btr0types.h
+++ b/storage/xtradb/include/btr0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/btr0types.h
The index tree general types
Created 2/17/1996 Heikki Tuuri
@@ -30,16 +31,19 @@ Created 2/17/1996 Heikki Tuuri
#include "rem0types.h"
#include "page0types.h"
+/** Persistent cursor */
typedef struct btr_pcur_struct btr_pcur_t;
+/** B-tree cursor */
typedef struct btr_cur_struct btr_cur_t;
+/** B-tree search information for the adaptive hash index */
typedef struct btr_search_struct btr_search_t;
-/* The size of a reference to data stored on a different page.
+/** The size of a reference to data stored on a different page.
The reference is stored at the end of the prefix of the field
in the index record. */
#define BTR_EXTERN_FIELD_REF_SIZE 20
-/* A BLOB field reference full of zero, for use in assertions and tests.
+/** A BLOB field reference full of zero, for use in assertions and tests.
Initially, BLOB field references are set to zero, in
dtuple_convert_big_rec(). */
extern const byte field_ref_zero[BTR_EXTERN_FIELD_REF_SIZE];
diff --git a/storage/xtradb/include/buf0buddy.h b/storage/xtradb/include/buf0buddy.h
index 2afef7913fc..a3b9fe1c9cd 100644
--- a/storage/xtradb/include/buf0buddy.h
+++ b/storage/xtradb/include/buf0buddy.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0buddy.h
Binary buddy allocator for compressed pages
Created December 2006 by Marko Makela
@@ -33,7 +34,7 @@ Created December 2006 by Marko Makela
#include "univ.i"
#include "buf0types.h"
-/**************************************************************************
+/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any
block->mutex. The buf_pool_mutex may only be released and reacquired
@@ -41,30 +42,29 @@ if lru != NULL. This function should only be used for allocating
compressed page frames or control blocks (buf_page_t). Allocated
control blocks must be properly initialized immediately after
buf_buddy_alloc() has returned the memory, before releasing
-buf_pool_mutex. */
+buf_pool_mutex.
+@return allocated block, possibly NULL if lru == NULL */
UNIV_INLINE
void*
buf_buddy_alloc(
/*============*/
- /* out: allocated block,
- possibly NULL if lru == NULL */
- ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
- ibool* lru, /* in: pointer to a variable that will be assigned
+ ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
+ ibool* lru, /*!< in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released,
or NULL if the LRU list should not be used */
ibool have_page_hash_mutex)
__attribute__((malloc));
-/**************************************************************************
+/**********************************************************************//**
Release a block. */
UNIV_INLINE
void
buf_buddy_free(
/*===========*/
- void* buf, /* in: block to be freed, must not be
+ void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
- ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
+ ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
ibool have_page_hash_mutex)
__attribute__((nonnull));
@@ -78,6 +78,7 @@ struct buf_buddy_stat_struct {
ib_uint64_t relocated_usec;
};
+/** Statistics of buddy blocks of a given size. */
typedef struct buf_buddy_stat_struct buf_buddy_stat_t;
/** Statistics of the buddy system, indexed by block size.
diff --git a/storage/xtradb/include/buf0buddy.ic b/storage/xtradb/include/buf0buddy.ic
index 668959cdba2..69659fb69d6 100644
--- a/storage/xtradb/include/buf0buddy.ic
+++ b/storage/xtradb/include/buf0buddy.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0buddy.ic
Binary buddy allocator for compressed pages
Created December 2006 by Marko Makela
@@ -32,47 +33,45 @@ Created December 2006 by Marko Makela
#include "ut0ut.h"
#include "sync0sync.h"
-/**************************************************************************
+/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any block->mutex.
-The buf_pool_mutex may only be released and reacquired if lru != NULL. */
+The buf_pool_mutex may only be released and reacquired if lru != NULL.
+@return allocated block, possibly NULL if lru==NULL */
UNIV_INTERN
void*
buf_buddy_alloc_low(
/*================*/
- /* out: allocated block,
- possibly NULL if lru==NULL */
- ulint i, /* in: index of buf_pool->zip_free[],
+ ulint i, /*!< in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
- ibool* lru, /* in: pointer to a variable that will be assigned
+ ibool* lru, /*!< in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released,
or NULL if the LRU list should not be used */
ibool have_page_hash_mutex)
__attribute__((malloc));
-/**************************************************************************
+/**********************************************************************//**
Deallocate a block. */
UNIV_INTERN
void
buf_buddy_free_low(
/*===============*/
- void* buf, /* in: block to be freed, must not be
+ void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
- ulint i, /* in: index of buf_pool->zip_free[],
+ ulint i, /*!< in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
ibool have_page_hash_mutex)
__attribute__((nonnull));
-/**************************************************************************
-Get the index of buf_pool->zip_free[] for a given block size. */
+/**********************************************************************//**
+Get the index of buf_pool->zip_free[] for a given block size.
+@return index of buf_pool->zip_free[], or BUF_BUDDY_SIZES */
UNIV_INLINE
ulint
buf_buddy_get_slot(
/*===============*/
- /* out: index of buf_pool->zip_free[],
- or BUF_BUDDY_SIZES */
- ulint size) /* in: block size */
+ ulint size) /*!< in: block size */
{
ulint i;
ulint s;
@@ -84,7 +83,7 @@ buf_buddy_get_slot(
return(i);
}
-/**************************************************************************
+/**********************************************************************//**
Allocate a block. The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any
block->mutex. The buf_pool_mutex may only be released and reacquired
@@ -92,15 +91,14 @@ if lru != NULL. This function should only be used for allocating
compressed page frames or control blocks (buf_page_t). Allocated
control blocks must be properly initialized immediately after
buf_buddy_alloc() has returned the memory, before releasing
-buf_pool_mutex. */
+buf_pool_mutex.
+@return allocated block, possibly NULL if lru == NULL */
UNIV_INLINE
void*
buf_buddy_alloc(
/*============*/
- /* out: allocated block,
- possibly NULL if lru == NULL */
- ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
- ibool* lru, /* in: pointer to a variable that will be assigned
+ ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
+ ibool* lru, /*!< in: pointer to a variable that will be assigned
TRUE if storage was allocated from the LRU list
and buf_pool_mutex was temporarily released,
or NULL if the LRU list should not be used */
@@ -111,15 +109,15 @@ buf_buddy_alloc(
return(buf_buddy_alloc_low(buf_buddy_get_slot(size), lru, have_page_hash_mutex));
}
-/**************************************************************************
+/**********************************************************************//**
Deallocate a block. */
UNIV_INLINE
void
buf_buddy_free(
/*===========*/
- void* buf, /* in: block to be freed, must not be
+ void* buf, /*!< in: block to be freed, must not be
pointed to by the buffer pool */
- ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
+ ulint size, /*!< in: block size, up to UNIV_PAGE_SIZE */
ibool have_page_hash_mutex)
{
//ut_ad(buf_pool_mutex_own());
diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h
index f89e772513a..8063f9ec2c8 100644
--- a/storage/xtradb/include/buf0buf.h
+++ b/storage/xtradb/include/buf0buf.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0buf.h
The database buffer pool high-level routines
Created 11/5/1995 Heikki Tuuri
@@ -29,64 +30,85 @@ Created 11/5/1995 Heikki Tuuri
#include "fil0fil.h"
#include "mtr0types.h"
#include "buf0types.h"
-#include "sync0rw.h"
#include "hash0hash.h"
#include "ut0byte.h"
-#include "os0proc.h"
#include "page0types.h"
+#ifndef UNIV_HOTBACKUP
+#include "os0proc.h"
-/* Modes for buf_page_get_gen */
-#define BUF_GET 10 /* get always */
-#define BUF_GET_IF_IN_POOL 11 /* get if in pool */
-#define BUF_GET_NO_LATCH 14 /* get and bufferfix, but set no latch;
- we have separated this case, because
- it is error-prone programming not to
- set a latch, and it should be used
- with care */
-/* Modes for buf_page_get_known_nowait */
-#define BUF_MAKE_YOUNG 51
-#define BUF_KEEP_OLD 52
-/* Magic value to use instead of checksums when they are disabled */
-#define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL
-
-extern buf_pool_t* buf_pool; /* The buffer pool of the database */
+/** @name Modes for buf_page_get_gen */
+/* @{ */
+#define BUF_GET 10 /*!< get always */
+#define BUF_GET_IF_IN_POOL 11 /*!< get if in pool */
+#define BUF_GET_NO_LATCH 14 /*!< get and bufferfix, but
+ set no latch; we have
+ separated this case, because
+ it is error-prone programming
+ not to set a latch, and it
+ should be used with care */
+/* @} */
+/** @name Modes for buf_page_get_known_nowait */
+/* @{ */
+#define BUF_MAKE_YOUNG 51 /*!< Move the block to the
+ start of the LRU list if there
+ is a danger that the block
+ would drift out of the buffer
+ pool*/
+#define BUF_KEEP_OLD 52 /*!< Preserve the current LRU
+ position of the block. */
+/* @} */
+
+extern buf_pool_t* buf_pool; /*!< The buffer pool of the database */
#ifdef UNIV_DEBUG
-extern ibool buf_debug_prints;/* If this is set TRUE, the program
+extern ibool buf_debug_prints;/*!< If this is set TRUE, the program
prints info whenever read or flush
occurs */
#endif /* UNIV_DEBUG */
-extern ulint srv_buf_pool_write_requests; /* variable to count write request
+extern ulint srv_buf_pool_write_requests; /*!< variable to count write request
issued */
+#else /* !UNIV_HOTBACKUP */
+extern buf_block_t* back_block1; /*!< first block, for --apply-log */
+extern buf_block_t* back_block2; /*!< second block, for page reorganize */
+#endif /* !UNIV_HOTBACKUP */
+
+/** Magic value to use instead of checksums when they are disabled */
+#define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL
+
+/** @brief States of a control block
+@see buf_page_struct
-/* States of a control block (@see buf_page_struct).
The enumeration values must be 0..7. */
enum buf_page_state {
- BUF_BLOCK_ZIP_FREE = 0, /* contains a free compressed page */
- BUF_BLOCK_ZIP_PAGE, /* contains a clean compressed page */
- BUF_BLOCK_ZIP_DIRTY, /* contains a compressed page that is
- in the buf_pool->flush_list */
-
- /* The constants for compressed-only pages must precede
- BUF_BLOCK_NOT_USED; @see buf_block_state_valid() */
-
- BUF_BLOCK_NOT_USED, /* is in the free list */
- BUF_BLOCK_READY_FOR_USE, /* when buf_LRU_get_free_block returns
- a block, it is in this state */
- BUF_BLOCK_FILE_PAGE, /* contains a buffered file page */
- BUF_BLOCK_MEMORY, /* contains some main memory object */
- BUF_BLOCK_REMOVE_HASH /* hash index should be removed
+ BUF_BLOCK_ZIP_FREE = 0, /*!< contains a free
+ compressed page */
+ BUF_BLOCK_ZIP_PAGE, /*!< contains a clean
+ compressed page */
+ BUF_BLOCK_ZIP_DIRTY, /*!< contains a compressed
+ page that is in the
+ buf_pool->flush_list */
+
+ BUF_BLOCK_NOT_USED, /*!< is in the free list;
+ must be after the BUF_BLOCK_ZIP_
+ constants for compressed-only pages
+ @see buf_block_state_valid() */
+ BUF_BLOCK_READY_FOR_USE, /*!< when buf_LRU_get_free_block
+ returns a block, it is in this state */
+ BUF_BLOCK_FILE_PAGE, /*!< contains a buffered file page */
+ BUF_BLOCK_MEMORY, /*!< contains some main memory
+ object */
+ BUF_BLOCK_REMOVE_HASH /*!< hash index should be removed
before putting to the free list */
};
-/************************************************************************
-Creates the buffer pool. */
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Creates the buffer pool.
+@return own: buf_pool object, NULL if not enough memory or error */
UNIV_INTERN
buf_pool_t*
buf_pool_init(void);
/*===============*/
- /* out, own: buf_pool object, NULL if not
- enough memory or error */
-/************************************************************************
+/********************************************************************//**
Frees the buffer pool at shutdown. This must not be invoked before
freeing all mutexes. */
UNIV_INTERN
@@ -94,7 +116,7 @@ void
buf_pool_free(void);
/*===============*/
-/************************************************************************
+/********************************************************************//**
Drops the adaptive hash index. To prevent a livelock, this function
is only to be called while holding btr_search_latch and while
btr_search_enabled == FALSE. */
@@ -103,7 +125,7 @@ void
buf_pool_drop_hash_index(void);
/*==========================*/
-/************************************************************************
+/********************************************************************//**
Relocate a buffer control block. Relocates the block on the LRU list
and in buf_pool->page_hash. Does not relocate bpage->list.
The caller must take care of relocating bpage->list. */
@@ -111,67 +133,67 @@ UNIV_INTERN
void
buf_relocate(
/*=========*/
- buf_page_t* bpage, /* in/out: control block being relocated;
+ buf_page_t* bpage, /*!< in/out: control block being relocated;
buf_page_get_state(bpage) must be
BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_ZIP_PAGE */
- buf_page_t* dpage) /* in/out: destination control block */
+ buf_page_t* dpage) /*!< in/out: destination control block */
__attribute__((nonnull));
-/************************************************************************
+/********************************************************************//**
Resizes the buffer pool. */
UNIV_INTERN
void
buf_pool_resize(void);
/*=================*/
-/*************************************************************************
-Gets the current size of buffer buf_pool in bytes. */
+/*********************************************************************//**
+Gets the current size of buffer buf_pool in bytes.
+@return size in bytes */
UNIV_INLINE
ulint
buf_pool_get_curr_size(void);
/*========================*/
- /* out: size in bytes */
-/************************************************************************
+/********************************************************************//**
Gets the smallest oldest_modification lsn for any page in the pool. Returns
-zero if all modified pages have been flushed to disk. */
+zero if all modified pages have been flushed to disk.
+@return oldest modification in pool, zero if none */
UNIV_INLINE
ib_uint64_t
buf_pool_get_oldest_modification(void);
/*==================================*/
- /* out: oldest modification in pool,
- zero if none */
-/************************************************************************
-Allocates a buffer block. */
+/********************************************************************//**
+Allocates a buffer block.
+@return own: the allocated block, in state BUF_BLOCK_MEMORY */
UNIV_INLINE
buf_block_t*
buf_block_alloc(
/*============*/
- /* out, own: the allocated block,
- in state BUF_BLOCK_MEMORY */
- ulint zip_size); /* in: compressed page size in bytes,
+ ulint zip_size); /*!< in: compressed page size in bytes,
or 0 if uncompressed tablespace */
-/************************************************************************
+/********************************************************************//**
Frees a buffer block which does not contain a file page. */
UNIV_INLINE
void
buf_block_free(
/*===========*/
- buf_block_t* block); /* in, own: block to be freed */
-/*************************************************************************
-Copies contents of a buffer frame to a given buffer. */
+ buf_block_t* block); /*!< in, own: block to be freed */
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************************//**
+Copies contents of a buffer frame to a given buffer.
+@return buf */
UNIV_INLINE
byte*
buf_frame_copy(
/*===========*/
- /* out: buf */
- byte* buf, /* in: buffer to copy to */
- const buf_frame_t* frame); /* in: buffer frame */
-/******************************************************************
+ byte* buf, /*!< in: buffer to copy to */
+ const buf_frame_t* frame); /*!< in: buffer frame */
+#ifndef UNIV_HOTBACKUP
+/**************************************************************//**
NOTE! The following macros should be used instead of buf_page_get_gen,
to improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed
in LA! */
#define buf_page_get(SP, ZS, OF, LA, MTR) buf_page_get_gen(\
SP, ZS, OF, LA, NULL,\
BUF_GET, __FILE__, __LINE__, MTR)
-/******************************************************************
+/**************************************************************//**
Use these macros to bufferfix a page with no latching. Remember not to
read the contents of the page unless you know it is safe. Do not modify
the contents of the page! We have separated this case, because it is
@@ -180,142 +202,149 @@ with care. */
#define buf_page_get_with_no_latch(SP, ZS, OF, MTR) buf_page_get_gen(\
SP, ZS, OF, RW_NO_LATCH, NULL,\
BUF_GET_NO_LATCH, __FILE__, __LINE__, MTR)
-/******************************************************************
+/**************************************************************//**
NOTE! The following macros should be used instead of
buf_page_optimistic_get_func, to improve debugging. Only values RW_S_LATCH and
RW_X_LATCH are allowed as LA! */
#define buf_page_optimistic_get(LA, BL, MC, MTR) \
buf_page_optimistic_get_func(LA, BL, MC, __FILE__, __LINE__, MTR)
-/************************************************************************
+/********************************************************************//**
This is the general function used to get optimistic access to a database
-page. */
+page.
+@return TRUE if success */
UNIV_INTERN
ibool
buf_page_optimistic_get_func(
/*=========================*/
- /* out: TRUE if success */
- ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */
- buf_block_t* block, /* in: guessed block */
- ib_uint64_t modify_clock,/* in: modify clock value if mode is
+ ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
+ buf_block_t* block, /*!< in: guessed block */
+ ib_uint64_t modify_clock,/*!< in: modify clock value if mode is
..._GUESS_ON_CLOCK */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr); /* in: mini-transaction */
-/************************************************************************
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr); /*!< in: mini-transaction */
+/********************************************************************//**
This is used to get access to a known database page, when no waiting can be
-done. */
+done.
+@return TRUE if success */
UNIV_INTERN
ibool
buf_page_get_known_nowait(
/*======================*/
- /* out: TRUE if success */
- ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */
- buf_block_t* block, /* in: the known page */
- ulint mode, /* in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr); /* in: mini-transaction */
-
-/***********************************************************************
+ ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
+ buf_block_t* block, /*!< in: the known page */
+ ulint mode, /*!< in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr); /*!< in: mini-transaction */
+
+/*******************************************************************//**
Given a tablespace id and page number tries to get that page. If the
page is not in the buffer pool it is not loaded and NULL is returned.
Suitable for using when holding the kernel mutex. */
-
+UNIV_INTERN
const buf_block_t*
buf_page_try_get_func(
/*==================*/
- ulint space_id,/* in: tablespace id */
- ulint page_no,/* in: page number */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr); /* in: mini-transaction */
-
+ ulint space_id,/*!< in: tablespace id */
+ ulint page_no,/*!< in: page number */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr); /*!< in: mini-transaction */
+
+/** Tries to get a page. If the page is not in the buffer pool it is
+not loaded. Suitable for using when holding the kernel mutex.
+@param space_id in: tablespace id
+@param page_no in: page number
+@param mtr in: mini-transaction
+@return the page if in buffer pool, NULL if not */
#define buf_page_try_get(space_id, page_no, mtr) \
buf_page_try_get_func(space_id, page_no, __FILE__, __LINE__, mtr);
-/************************************************************************
+/********************************************************************//**
Get read access to a compressed page (usually of type
FIL_PAGE_TYPE_ZBLOB or FIL_PAGE_TYPE_ZBLOB2).
The page must be released with buf_page_release_zip().
NOTE: the page is not protected by any latch. Mutual exclusion has to
be implemented at a higher level. In other words, all possible
accesses to a given page through this function must be protected by
-the same set of mutexes or latches. */
+the same set of mutexes or latches.
+@return pointer to the block, or NULL if not compressed */
UNIV_INTERN
buf_page_t*
buf_page_get_zip(
/*=============*/
- /* out: pointer to the block,
- or NULL if not compressed */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size */
- ulint offset);/* in: page number */
-/************************************************************************
-This is the general function used to get access to a database page. */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size */
+ ulint offset);/*!< in: page number */
+/********************************************************************//**
+This is the general function used to get access to a database page.
+@return pointer to the block or NULL */
UNIV_INTERN
buf_block_t*
buf_page_get_gen(
/*=============*/
- /* out: pointer to the block or NULL */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint offset, /* in: page number */
- ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
- buf_block_t* guess, /* in: guessed block or NULL */
- ulint mode, /* in: BUF_GET, BUF_GET_IF_IN_POOL,
+ ulint offset, /*!< in: page number */
+ ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
+ buf_block_t* guess, /*!< in: guessed block or NULL */
+ ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
BUF_GET_NO_LATCH */
- const char* file, /* in: file name */
- ulint line, /* in: line where called */
- mtr_t* mtr); /* in: mini-transaction */
-/************************************************************************
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr); /*!< in: mini-transaction */
+/********************************************************************//**
Initializes a page to the buffer buf_pool. The page is usually not read
from a file even if it cannot be found in the buffer buf_pool. This is one
of the functions which perform to a block a state transition NOT_USED =>
-FILE_PAGE (the other is buf_page_get_gen). */
+FILE_PAGE (the other is buf_page_get_gen).
+@return pointer to the block, page bufferfixed */
UNIV_INTERN
buf_block_t*
buf_page_create(
/*============*/
- /* out: pointer to the block, page bufferfixed */
- ulint space, /* in: space id */
- ulint offset, /* in: offset of the page within space in units of
+ ulint space, /*!< in: space id */
+ ulint offset, /*!< in: offset of the page within space in units of
a page */
- ulint zip_size,/* in: compressed page size, or 0 */
- mtr_t* mtr); /* in: mini-transaction handle */
-#ifdef UNIV_HOTBACKUP
-/************************************************************************
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+#else /* !UNIV_HOTBACKUP */
+/********************************************************************//**
Inits a page to the buffer buf_pool, for use in ibbackup --restore. */
UNIV_INTERN
void
buf_page_init_for_backup_restore(
/*=============================*/
- ulint space, /* in: space id */
- ulint offset, /* in: offset of the page within space
+ ulint space, /*!< in: space id */
+ ulint offset, /*!< in: offset of the page within space
in units of a page */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- buf_block_t* block); /* in: block to init */
-#endif /* UNIV_HOTBACKUP */
-/************************************************************************
+ buf_block_t* block); /*!< in: block to init */
+#endif /* !UNIV_HOTBACKUP */
+
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Releases a compressed-only page acquired with buf_page_get_zip(). */
UNIV_INLINE
void
buf_page_release_zip(
/*=================*/
- buf_page_t* bpage); /* in: buffer block */
-/************************************************************************
+ buf_page_t* bpage); /*!< in: buffer block */
+/********************************************************************//**
Decrements the bufferfix count of a buffer control block and releases
a latch, if specified. */
UNIV_INLINE
void
buf_page_release(
/*=============*/
- buf_block_t* block, /* in: buffer block */
- ulint rw_latch, /* in: RW_S_LATCH, RW_X_LATCH,
+ buf_block_t* block, /*!< in: buffer block */
+ ulint rw_latch, /*!< in: RW_S_LATCH, RW_X_LATCH,
RW_NO_LATCH */
- mtr_t* mtr); /* in: mtr */
-/************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/********************************************************************//**
Moves a page to the start of the buffer pool LRU list. This high-level
function can be used to prevent an important page from from slipping out of
the buffer pool. */
@@ -323,109 +352,106 @@ UNIV_INTERN
void
buf_page_make_young(
/*================*/
- buf_page_t* bpage); /* in: buffer block of a file page */
-/************************************************************************
-Returns TRUE if the page can be found in the buffer pool hash table. NOTE
-that it is possible that the page is not yet read from disk, though. */
+ buf_page_t* bpage); /*!< in: buffer block of a file page */
+/********************************************************************//**
+Returns TRUE if the page can be found in the buffer pool hash table.
+
+NOTE that it is possible that the page is not yet read from disk,
+though.
+
+@return TRUE if found in the page hash table */
UNIV_INLINE
ibool
buf_page_peek(
/*==========*/
- /* out: TRUE if found from page hash table,
- NOTE that the page is not necessarily yet read
- from disk! */
- ulint space, /* in: space id */
- ulint offset);/* in: page number */
-/************************************************************************
+ ulint space, /*!< in: space id */
+ ulint offset);/*!< in: page number */
+/********************************************************************//**
Resets the check_index_page_at_flush field of a page if found in the buffer
pool. */
UNIV_INTERN
void
buf_reset_check_index_page_at_flush(
/*================================*/
- ulint space, /* in: space id */
- ulint offset);/* in: page number */
+ ulint space, /*!< in: space id */
+ ulint offset);/*!< in: page number */
#ifdef UNIV_DEBUG_FILE_ACCESSES
-/************************************************************************
+/********************************************************************//**
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
-reallocated. */
+reallocated.
+@return control block if found in page hash table, otherwise NULL */
UNIV_INTERN
buf_page_t*
buf_page_set_file_page_was_freed(
/*=============================*/
- /* out: control block if found in page hash table,
- otherwise NULL */
- ulint space, /* in: space id */
- ulint offset);/* in: page number */
-/************************************************************************
+ ulint space, /*!< in: space id */
+ ulint offset);/*!< in: page number */
+/********************************************************************//**
Sets file_page_was_freed FALSE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
-reallocated. */
+reallocated.
+@return control block if found in page hash table, otherwise NULL */
UNIV_INTERN
buf_page_t*
buf_page_reset_file_page_was_freed(
/*===============================*/
- /* out: control block if found in page hash table,
- otherwise NULL */
- ulint space, /* in: space id */
- ulint offset); /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint offset); /*!< in: page number */
#endif /* UNIV_DEBUG_FILE_ACCESSES */
-/************************************************************************
-Reads the freed_page_clock of a buffer block. */
+/********************************************************************//**
+Reads the freed_page_clock of a buffer block.
+@return freed_page_clock */
UNIV_INLINE
ulint
buf_page_get_freed_page_clock(
/*==========================*/
- /* out: freed_page_clock */
- const buf_page_t* bpage) /* in: block */
+ const buf_page_t* bpage) /*!< in: block */
__attribute__((pure));
-/************************************************************************
-Reads the freed_page_clock of a buffer block. */
+/********************************************************************//**
+Reads the freed_page_clock of a buffer block.
+@return freed_page_clock */
UNIV_INLINE
ulint
buf_block_get_freed_page_clock(
/*===========================*/
- /* out: freed_page_clock */
- const buf_block_t* block) /* in: block */
+ const buf_block_t* block) /*!< in: block */
__attribute__((pure));
-/************************************************************************
+/********************************************************************//**
Recommends a move of a block to the start of the LRU list if there is danger
of dropping from the buffer pool. NOTE: does not reserve the buffer pool
-mutex. */
+mutex.
+@return TRUE if should be made younger */
UNIV_INLINE
ibool
buf_page_peek_if_too_old(
/*=====================*/
- /* out: TRUE if should be made
- younger */
- const buf_page_t* bpage); /* in: block to make younger */
-/************************************************************************
+ const buf_page_t* bpage); /*!< in: block to make younger */
+/********************************************************************//**
Returns the current state of is_hashed of a page. FALSE if the page is
not in the pool. NOTE that this operation does not fix the page in the
-pool if it is found there. */
+pool if it is found there.
+@return TRUE if page hash index is built in search system */
UNIV_INTERN
ibool
buf_page_peek_if_search_hashed(
/*===========================*/
- /* out: TRUE if page hash index is built in search
- system */
- ulint space, /* in: space id */
- ulint offset);/* in: page number */
-/************************************************************************
+ ulint space, /*!< in: space id */
+ ulint offset);/*!< in: page number */
+/********************************************************************//**
Gets the youngest modification log sequence number for a frame.
-Returns zero if not file page or no modification occurred yet. */
+Returns zero if not file page or no modification occurred yet.
+@return newest modification to page */
UNIV_INLINE
ib_uint64_t
buf_page_get_newest_modification(
/*=============================*/
- /* out: newest modification to page */
- const buf_page_t* bpage); /* in: block containing the
+ const buf_page_t* bpage); /*!< in: block containing the
page frame */
-/************************************************************************
+/********************************************************************//**
Increments the modify clock of a frame by 1. The caller must (1) own the
buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock
on the block. */
@@ -433,155 +459,174 @@ UNIV_INLINE
void
buf_block_modify_clock_inc(
/*=======================*/
- buf_block_t* block); /* in: block */
-/************************************************************************
+ buf_block_t* block); /*!< in: block */
+/********************************************************************//**
Returns the value of the modify clock. The caller must have an s-lock
-or x-lock on the block. */
+or x-lock on the block.
+@return value */
UNIV_INLINE
ib_uint64_t
buf_block_get_modify_clock(
/*=======================*/
- /* out: value */
- buf_block_t* block); /* in: block */
-/************************************************************************
+ buf_block_t* block); /*!< in: block */
+#else /* !UNIV_HOTBACKUP */
+# define buf_block_modify_clock_inc(block) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
Calculates a page checksum which is stored to the page when it is written
to a file. Note that we must be careful to calculate the same value
-on 32-bit and 64-bit architectures. */
+on 32-bit and 64-bit architectures.
+@return checksum */
UNIV_INTERN
ulint
buf_calc_page_new_checksum(
/*=======================*/
- /* out: checksum */
- const byte* page); /* in: buffer page */
-/************************************************************************
+ const byte* page); /*!< in: buffer page */
+/********************************************************************//**
In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
looked at the first few bytes of the page. This calculates that old
checksum.
NOTE: we must first store the new formula checksum to
FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum
-because this takes that field as an input! */
+because this takes that field as an input!
+@return checksum */
UNIV_INTERN
ulint
buf_calc_page_old_checksum(
/*=======================*/
- /* out: checksum */
- const byte* page); /* in: buffer page */
-/************************************************************************
-Checks if a page is corrupt. */
+ const byte* page); /*!< in: buffer page */
+/********************************************************************//**
+Checks if a page is corrupt.
+@return TRUE if corrupted */
UNIV_INTERN
ibool
buf_page_is_corrupted(
/*==================*/
- /* out: TRUE if corrupted */
- const byte* read_buf, /* in: a database page */
- ulint zip_size); /* in: size of compressed page;
+ const byte* read_buf, /*!< in: a database page */
+ ulint zip_size); /*!< in: size of compressed page;
0 for uncompressed pages */
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Gets the space id, page offset, and byte offset within page of a
pointer pointing to a buffer frame containing a file page. */
UNIV_INLINE
void
buf_ptr_get_fsp_addr(
/*=================*/
- const void* ptr, /* in: pointer to a buffer frame */
- ulint* space, /* out: space id */
- fil_addr_t* addr); /* out: page offset and byte offset */
-/**************************************************************************
+ const void* ptr, /*!< in: pointer to a buffer frame */
+ ulint* space, /*!< out: space id */
+ fil_addr_t* addr); /*!< out: page offset and byte offset */
+/**********************************************************************//**
Gets the hash value of a block. This can be used in searches in the
-lock hash table. */
+lock hash table.
+@return lock hash value */
UNIV_INLINE
ulint
buf_block_get_lock_hash_val(
/*========================*/
- /* out: lock hash value */
- const buf_block_t* block) /* in: block */
+ const buf_block_t* block) /*!< in: block */
__attribute__((pure));
#ifdef UNIV_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Finds a block in the buffer pool that points to a
-given compressed page. */
+given compressed page.
+@return buffer block pointing to the compressed page, or NULL */
UNIV_INTERN
buf_block_t*
buf_pool_contains_zip(
/*==================*/
- /* out: buffer block pointing to
- the compressed page, or NULL */
- const void* data); /* in: pointer to compressed page */
+ const void* data); /*!< in: pointer to compressed page */
#endif /* UNIV_DEBUG */
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/*************************************************************************
-Validates the buffer pool data structure. */
+/*********************************************************************//**
+Validates the buffer pool data structure.
+@return TRUE */
UNIV_INTERN
ibool
buf_validate(void);
/*==============*/
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Prints info of the buffer pool data structure. */
UNIV_INTERN
void
buf_print(void);
/*============*/
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
-/************************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
Prints a page to stderr. */
UNIV_INTERN
void
buf_page_print(
/*===========*/
- const byte* read_buf, /* in: a database page */
- ulint zip_size); /* in: compressed page size, or
+ const byte* read_buf, /*!< in: a database page */
+ ulint zip_size); /*!< in: compressed page size, or
0 for uncompressed pages */
+/********************************************************************//**
+Decompress a block.
+@return TRUE if successful */
+UNIV_INTERN
+ibool
+buf_zip_decompress(
+/*===============*/
+ buf_block_t* block, /*!< in/out: block */
+ ibool check); /*!< in: TRUE=verify the page checksum */
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_DEBUG
-/*************************************************************************
-Returns the number of latched pages in the buffer pool. */
+/*********************************************************************//**
+Returns the number of latched pages in the buffer pool.
+@return number of latched pages */
UNIV_INTERN
ulint
buf_get_latched_pages_number(void);
/*==============================*/
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Returns the number of pending buf pool ios. */
+/*********************************************************************//**
+Returns the number of pending buf pool ios.
+@return number of pending I/O operations */
UNIV_INTERN
ulint
buf_get_n_pending_ios(void);
/*=======================*/
-/*************************************************************************
+/*********************************************************************//**
Prints info of the buffer i/o. */
UNIV_INTERN
void
buf_print_io(
/*=========*/
- FILE* file); /* in: file where to print */
-/*************************************************************************
+ FILE* file); /*!< in: file where to print */
+/*********************************************************************//**
Returns the ratio in percents of modified pages in the buffer pool /
-database pages in the buffer pool. */
+database pages in the buffer pool.
+@return modified page percentage ratio */
UNIV_INTERN
ulint
buf_get_modified_ratio_pct(void);
/*============================*/
-/**************************************************************************
+/**********************************************************************//**
Refreshes the statistics used to print per-second averages. */
UNIV_INTERN
void
buf_refresh_io_stats(void);
/*======================*/
-/*************************************************************************
-Checks that all file pages in the buffer are in a replaceable state. */
+/*********************************************************************//**
+Asserts that all file pages in the buffer are in a replaceable state.
+@return TRUE */
UNIV_INTERN
ibool
buf_all_freed(void);
/*===============*/
-/*************************************************************************
+/*********************************************************************//**
Checks that there currently are no pending i/o-operations for the buffer
-pool. */
+pool.
+@return TRUE if there is no pending i/o */
UNIV_INTERN
ibool
buf_pool_check_no_pending_io(void);
/*==============================*/
- /* out: TRUE if there is no pending i/o */
-/*************************************************************************
+/*********************************************************************//**
Invalidates the file pages in the buffer pool when an archive recovery is
completed. All the file pages buffered must be in a replaceable state when
this function is called: not latched and not modified. */
@@ -589,13 +634,14 @@ UNIV_INTERN
void
buf_pool_invalidate(void);
/*=====================*/
+#endif /* !UNIV_HOTBACKUP */
/*========================================================================
--------------------------- LOWER LEVEL ROUTINES -------------------------
=========================================================================*/
#ifdef UNIV_SYNC_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Adds latch level info for the rw-lock protecting the buffer frame. This
should be called in the debug version after a successful latching of a
page if we know the latching order level of the acquired latch. */
@@ -603,301 +649,323 @@ UNIV_INLINE
void
buf_block_dbg_add_level(
/*====================*/
- buf_block_t* block, /* in: buffer page
+ buf_block_t* block, /*!< in: buffer page
where we have acquired latch */
- ulint level); /* in: latching order level */
+ ulint level); /*!< in: latching order level */
#else /* UNIV_SYNC_DEBUG */
# define buf_block_dbg_add_level(block, level) /* nothing */
#endif /* UNIV_SYNC_DEBUG */
-/*************************************************************************
-Gets the state of a block. */
+/*********************************************************************//**
+Gets the state of a block.
+@return state */
UNIV_INLINE
enum buf_page_state
buf_page_get_state(
/*===============*/
- /* out: state */
- const buf_page_t* bpage); /* in: pointer to the control block */
-/*************************************************************************
-Gets the state of a block. */
+ const buf_page_t* bpage); /*!< in: pointer to the control block */
+/*********************************************************************//**
+Gets the state of a block.
+@return state */
UNIV_INLINE
enum buf_page_state
buf_block_get_state(
/*================*/
- /* out: state */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
+/*********************************************************************//**
Sets the state of a block. */
UNIV_INLINE
void
buf_page_set_state(
/*===============*/
- buf_page_t* bpage, /* in/out: pointer to control block */
- enum buf_page_state state); /* in: state */
-/*************************************************************************
+ buf_page_t* bpage, /*!< in/out: pointer to control block */
+ enum buf_page_state state); /*!< in: state */
+/*********************************************************************//**
Sets the state of a block. */
UNIV_INLINE
void
buf_block_set_state(
/*================*/
- buf_block_t* block, /* in/out: pointer to control block */
- enum buf_page_state state); /* in: state */
-/*************************************************************************
-Determines if a block is mapped to a tablespace. */
+ buf_block_t* block, /*!< in/out: pointer to control block */
+ enum buf_page_state state); /*!< in: state */
+/*********************************************************************//**
+Determines if a block is mapped to a tablespace.
+@return TRUE if mapped */
UNIV_INLINE
ibool
buf_page_in_file(
/*=============*/
- /* out: TRUE if mapped */
- const buf_page_t* bpage) /* in: pointer to control block */
+ const buf_page_t* bpage) /*!< in: pointer to control block */
__attribute__((pure));
-/*************************************************************************
-Determines if a block should be on unzip_LRU list. */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
+Determines if a block should be on unzip_LRU list.
+@return TRUE if block belongs to unzip_LRU */
UNIV_INLINE
ibool
buf_page_belongs_to_unzip_LRU(
/*==========================*/
- /* out: TRUE if block belongs
- to unzip_LRU */
- const buf_page_t* bpage) /* in: pointer to control block */
+ const buf_page_t* bpage) /*!< in: pointer to control block */
__attribute__((pure));
-/*************************************************************************
-Determine the approximate LRU list position of a block. */
+/*********************************************************************//**
+Determine the approximate LRU list position of a block.
+@return LRU list position */
UNIV_INLINE
ulint
buf_page_get_LRU_position(
/*======================*/
- /* out: LRU list position */
- const buf_page_t* bpage) /* in: control block */
+ const buf_page_t* bpage) /*!< in: control block */
__attribute__((pure));
-/*************************************************************************
-Gets the mutex of a block. */
+/*********************************************************************//**
+Gets the mutex of a block.
+@return pointer to mutex protecting bpage */
UNIV_INLINE
mutex_t*
buf_page_get_mutex(
/*===============*/
- /* out: pointer to mutex
- protecting bpage */
- const buf_page_t* bpage) /* in: pointer to control block */
+ const buf_page_t* bpage) /*!< in: pointer to control block */
__attribute__((pure));
/*************************************************************************
-Get the flush type of a page. */
+Gets the mutex of a block and enter the mutex with consistency. */
+UNIV_INLINE
+mutex_t*
+buf_page_get_mutex_enter(
+/*=========================*/
+ const buf_page_t* bpage) /*!< in: pointer to control block */
+ __attribute__((pure));
+
+/*********************************************************************//**
+Get the flush type of a page.
+@return flush type */
UNIV_INLINE
enum buf_flush
buf_page_get_flush_type(
/*====================*/
- /* out: flush type */
- const buf_page_t* bpage) /* in: buffer page */
+ const buf_page_t* bpage) /*!< in: buffer page */
__attribute__((pure));
-/*************************************************************************
+/*********************************************************************//**
Set the flush type of a page. */
UNIV_INLINE
void
buf_page_set_flush_type(
/*====================*/
- buf_page_t* bpage, /* in: buffer page */
- enum buf_flush flush_type); /* in: flush type */
-/*************************************************************************
+ buf_page_t* bpage, /*!< in: buffer page */
+ enum buf_flush flush_type); /*!< in: flush type */
+/*********************************************************************//**
Map a block to a file page. */
UNIV_INLINE
void
buf_block_set_file_page(
/*====================*/
- buf_block_t* block, /* in/out: pointer to control block */
- ulint space, /* in: tablespace id */
- ulint page_no);/* in: page number */
-/*************************************************************************
-Gets the io_fix state of a block. */
+ buf_block_t* block, /*!< in/out: pointer to control block */
+ ulint space, /*!< in: tablespace id */
+ ulint page_no);/*!< in: page number */
+/*********************************************************************//**
+Gets the io_fix state of a block.
+@return io_fix state */
UNIV_INLINE
enum buf_io_fix
buf_page_get_io_fix(
/*================*/
- /* out: io_fix state */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
-Gets the io_fix state of a block. */
+/*********************************************************************//**
+Gets the io_fix state of a block.
+@return io_fix state */
UNIV_INLINE
enum buf_io_fix
buf_block_get_io_fix(
/*================*/
- /* out: io_fix state */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
+/*********************************************************************//**
Sets the io_fix state of a block. */
UNIV_INLINE
void
buf_page_set_io_fix(
/*================*/
- buf_page_t* bpage, /* in/out: control block */
- enum buf_io_fix io_fix);/* in: io_fix state */
-/*************************************************************************
+ buf_page_t* bpage, /*!< in/out: control block */
+ enum buf_io_fix io_fix);/*!< in: io_fix state */
+/*********************************************************************//**
Sets the io_fix state of a block. */
UNIV_INLINE
void
buf_block_set_io_fix(
/*=================*/
- buf_block_t* block, /* in/out: control block */
- enum buf_io_fix io_fix);/* in: io_fix state */
+ buf_block_t* block, /*!< in/out: control block */
+ enum buf_io_fix io_fix);/*!< in: io_fix state */
-/************************************************************************
+/********************************************************************//**
Determine if a buffer block can be relocated in memory. The block
can be dirty, but it must not be I/O-fixed or bufferfixed. */
UNIV_INLINE
ibool
buf_page_can_relocate(
/*==================*/
- const buf_page_t* bpage) /* control block being relocated */
+ const buf_page_t* bpage) /*!< control block being relocated */
__attribute__((pure));
-/*************************************************************************
-Determine if a block has been flagged old. */
+/*********************************************************************//**
+Determine if a block has been flagged old.
+@return TRUE if old */
UNIV_INLINE
ibool
buf_page_is_old(
/*============*/
- /* out: TRUE if old */
- const buf_page_t* bpage) /* in: control block */
+ const buf_page_t* bpage) /*!< in: control block */
__attribute__((pure));
-/*************************************************************************
+/*********************************************************************//**
Flag a block old. */
UNIV_INLINE
void
buf_page_set_old(
/*=============*/
- buf_page_t* bpage, /* in/out: control block */
- ibool old); /* in: old */
-/*************************************************************************
-Determine if a block has been accessed in the buffer pool. */
+ buf_page_t* bpage, /*!< in/out: control block */
+ ibool old); /*!< in: old */
+/*********************************************************************//**
+Determine if a block has been accessed in the buffer pool.
+@return TRUE if accessed */
UNIV_INLINE
ibool
buf_page_is_accessed(
/*=================*/
- /* out: TRUE if accessed */
- const buf_page_t* bpage) /* in: control block */
+ const buf_page_t* bpage) /*!< in: control block */
__attribute__((pure));
-/*************************************************************************
+/*********************************************************************//**
Flag a block accessed. */
UNIV_INLINE
void
buf_page_set_accessed(
/*==================*/
- buf_page_t* bpage, /* in/out: control block */
- ibool accessed); /* in: accessed */
-/*************************************************************************
+ buf_page_t* bpage, /*!< in/out: control block */
+ ibool accessed); /*!< in: accessed */
+/*********************************************************************//**
Gets the buf_block_t handle of a buffered file block if an uncompressed
-page frame exists, or NULL. */
+page frame exists, or NULL.
+@return control block, or NULL */
UNIV_INLINE
buf_block_t*
buf_page_get_block(
/*===============*/
- /* out: control block, or NULL */
- buf_page_t* bpage) /* in: control block, or NULL */
+ buf_page_t* bpage) /*!< in: control block, or NULL */
__attribute__((pure));
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
-/*************************************************************************
-Gets a pointer to the memory frame of a block. */
+/*********************************************************************//**
+Gets a pointer to the memory frame of a block.
+@return pointer to the frame */
UNIV_INLINE
buf_frame_t*
buf_block_get_frame(
/*================*/
- /* out: pointer to the frame */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
#else /* UNIV_DEBUG */
# define buf_block_get_frame(block) (block)->frame
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Gets the space id of a block. */
+/*********************************************************************//**
+Gets the space id of a block.
+@return space id */
UNIV_INLINE
ulint
buf_page_get_space(
/*===============*/
- /* out: space id */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
-Gets the space id of a block. */
+/*********************************************************************//**
+Gets the space id of a block.
+@return space id */
UNIV_INLINE
ulint
buf_block_get_space(
/*================*/
- /* out: space id */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
-Gets the page number of a block. */
+/*********************************************************************//**
+Gets the page number of a block.
+@return page number */
UNIV_INLINE
ulint
buf_page_get_page_no(
/*=================*/
- /* out: page number */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
-Gets the page number of a block. */
+/*********************************************************************//**
+Gets the page number of a block.
+@return page number */
UNIV_INLINE
ulint
buf_block_get_page_no(
/*==================*/
- /* out: page number */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
-Gets the compressed page size of a block. */
+/*********************************************************************//**
+Gets the compressed page size of a block.
+@return compressed page size, or 0 */
UNIV_INLINE
ulint
buf_page_get_zip_size(
/*==================*/
- /* out: compressed page size, or 0 */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
-Gets the compressed page size of a block. */
+/*********************************************************************//**
+Gets the compressed page size of a block.
+@return compressed page size, or 0 */
UNIV_INLINE
ulint
buf_block_get_zip_size(
/*===================*/
- /* out: compressed page size, or 0 */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
-/*************************************************************************
+/*********************************************************************//**
Gets the compressed page descriptor corresponding to an uncompressed page
if applicable. */
#define buf_block_get_page_zip(block) \
(UNIV_LIKELY_NULL((block)->page.zip.data) ? &(block)->page.zip : NULL)
-/***********************************************************************
-Gets the block to whose frame the pointer is pointing to. */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
+Gets the block to whose frame the pointer is pointing to.
+@return pointer to block, never NULL */
UNIV_INTERN
buf_block_t*
buf_block_align(
/*============*/
- /* out: pointer to block, never NULL */
- const byte* ptr); /* in: pointer to a frame */
+ const byte* ptr); /*!< in: pointer to a frame */
+/********************************************************************//**
+Find out if a pointer belongs to a buf_block_t. It can be a pointer to
+the buf_block_t itself or a member of it
+@return TRUE if ptr belongs to a buf_block_t struct */
+UNIV_INTERN
+ibool
+buf_pointer_is_block_field(
+/*=======================*/
+ const void* ptr); /*!< in: pointer not
+ dereferenced */
+/** Find out if a pointer corresponds to a buf_block_t::mutex.
+@param m in: mutex candidate
+@return TRUE if m is a buf_block_t::mutex */
+#define buf_pool_is_block_mutex(m) \
+ buf_pointer_is_block_field((const void*)(m))
+/** Find out if a pointer corresponds to a buf_block_t::lock.
+@param l in: rw-lock candidate
+@return TRUE if l is a buf_block_t::lock */
+#define buf_pool_is_block_lock(l) \
+ buf_pointer_is_block_field((const void*)(l))
+
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Gets the compressed page descriptor corresponding to an uncompressed page
-if applicable. */
+if applicable.
+@return compressed page descriptor, or NULL */
UNIV_INLINE
const page_zip_des_t*
buf_frame_get_page_zip(
/*===================*/
- /* out: compressed page descriptor, or NULL */
- const byte* ptr); /* in: pointer to the page */
+ const byte* ptr); /*!< in: pointer to the page */
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
-/************************************************************************
-This function is used to get info if there is an io operation
-going on on a buffer page. */
-UNIV_INLINE
-ibool
-buf_page_io_query(
-/*==============*/
- /* out: TRUE if io going on */
- buf_page_t* bpage); /* in: pool block, must be bufferfixed */
-/************************************************************************
+/********************************************************************//**
Function which inits a page for read to the buffer buf_pool. If the page is
(1) already in buf_pool, or
(2) if we specify to read only ibuf pages and the page is not an ibuf page, or
@@ -905,240 +973,265 @@ Function which inits a page for read to the buffer buf_pool. If the page is
then this function does nothing.
Sets the io_fix flag to BUF_IO_READ and sets a non-recursive exclusive lock
on the buffer frame. The io-handler must take care that the flag is cleared
-and the lock released later. */
+and the lock released later.
+@return pointer to the block or NULL */
UNIV_INTERN
buf_page_t*
buf_page_init_for_read(
/*===================*/
- /* out: pointer to the block or NULL */
- ulint* err, /* out: DB_SUCCESS or DB_TABLESPACE_DELETED */
- ulint mode, /* in: BUF_READ_IBUF_PAGES_ONLY, ... */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size, or 0 */
- ibool unzip, /* in: TRUE=request uncompressed page */
- ib_int64_t tablespace_version,/* in: prevents reading from a wrong
+ ulint* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED */
+ ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ... */
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
+ ibool unzip, /*!< in: TRUE=request uncompressed page */
+ ib_int64_t tablespace_version,/*!< in: prevents reading from a wrong
version of the tablespace in case we have done
DISCARD + IMPORT */
- ulint offset);/* in: page number */
-/************************************************************************
+ ulint offset);/*!< in: page number */
+/********************************************************************//**
Completes an asynchronous read or write request of a file page to or from
the buffer pool. */
UNIV_INTERN
void
buf_page_io_complete(
/*=================*/
- buf_page_t* bpage); /* in: pointer to the block in question */
-/************************************************************************
+ buf_page_t* bpage); /*!< in: pointer to the block in question */
+/********************************************************************//**
Calculates a folded value of a file page address to use in the page hash
-table. */
+table.
+@return the folded value */
UNIV_INLINE
ulint
buf_page_address_fold(
/*==================*/
- /* out: the folded value */
- ulint space, /* in: space id */
- ulint offset) /* in: offset of the page within space */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: offset of the page within space */
__attribute__((const));
-/**********************************************************************
-Returns the control block of a file page, NULL if not found. */
+/******************************************************************//**
+Returns the control block of a file page, NULL if not found.
+@return block, NULL if not found */
UNIV_INLINE
buf_page_t*
buf_page_hash_get(
/*==============*/
- /* out: block, NULL if not found */
- ulint space, /* in: space id */
- ulint offset);/* in: offset of the page within space */
-/**********************************************************************
+ ulint space, /*!< in: space id */
+ ulint offset);/*!< in: offset of the page within space */
+/******************************************************************//**
Returns the control block of a file page, NULL if not found
-or an uncompressed page frame does not exist. */
+or an uncompressed page frame does not exist.
+@return block, NULL if not found */
UNIV_INLINE
buf_block_t*
buf_block_hash_get(
/*===============*/
- /* out: block, NULL if not found */
- ulint space, /* in: space id */
- ulint offset);/* in: offset of the page within space */
-/***********************************************************************
+ ulint space, /*!< in: space id */
+ ulint offset);/*!< in: offset of the page within space */
+/*******************************************************************//**
Increments the pool clock by one and returns its new value. Remember that
-in the 32 bit version the clock wraps around at 4 billion! */
+in the 32 bit version the clock wraps around at 4 billion!
+@return new clock value */
UNIV_INLINE
ulint
buf_pool_clock_tic(void);
/*====================*/
- /* out: new clock value */
-/*************************************************************************
-Gets the current length of the free list of buffer blocks. */
+/*********************************************************************//**
+Gets the current length of the free list of buffer blocks.
+@return length of the free list */
UNIV_INTERN
ulint
buf_get_free_list_len(void);
/*=======================*/
+#endif /* !UNIV_HOTBACKUP */
-
-/* The common buffer control block structure
+/** The common buffer control block structure
for compressed and uncompressed frames */
struct buf_page_struct{
- /* None of the following bit-fields must be modified without
- holding buf_page_get_mutex() [block->mutex or buf_pool_zip_mutex],
- since they can be stored in the same machine word. Some of them are
- additionally protected by buf_pool_mutex. */
-
- unsigned space:32; /* tablespace id; also protected
+ /** @name General fields
+ None of these bit-fields must be modified without holding
+ buf_page_get_mutex() [buf_block_struct::mutex or
+ buf_pool_zip_mutex], since they can be stored in the same
+ machine word. Some of these fields are additionally protected
+ by buf_pool_mutex. */
+ /* @{ */
+
+ unsigned space:32; /*!< tablespace id; also protected
by buf_pool_mutex. */
- unsigned offset:32; /* page number; also protected
+ unsigned offset:32; /*!< page number; also protected
by buf_pool_mutex. */
- unsigned state:3; /* state of the control block
- (@see enum buf_page_state); also
+ unsigned state:3; /*!< state of the control block; also
protected by buf_pool_mutex.
State transitions from
BUF_BLOCK_READY_FOR_USE to
BUF_BLOCK_MEMORY need not be
- protected by buf_page_get_mutex(). */
- unsigned flush_type:2; /* if this block is currently being
+ protected by buf_page_get_mutex().
+ @see enum buf_page_state */
+#ifndef UNIV_HOTBACKUP
+ unsigned flush_type:2; /*!< if this block is currently being
flushed to disk, this tells the
- flush_type (@see enum buf_flush) */
- unsigned accessed:1; /* TRUE if the page has been accessed
+ flush_type.
+ @see enum buf_flush */
+ unsigned accessed:1; /*!< TRUE if the page has been accessed
while in the buffer pool: read-ahead
may read in pages which have not been
accessed yet; a thread is allowed to
read this for heuristic purposes
without holding any mutex or latch */
- unsigned io_fix:2; /* type of pending I/O operation
- (@see enum buf_io_fix); also
- protected by buf_pool_mutex */
- unsigned buf_fix_count:24;/* count of how manyfold this block
+ unsigned io_fix:2; /*!< type of pending I/O operation;
+ also protected by buf_pool_mutex
+ @see enum buf_io_fix */
+ unsigned buf_fix_count:24;/*!< count of how manyfold this block
is currently bufferfixed */
-
- page_zip_des_t zip; /* compressed page; zip.data
+ /* @} */
+#endif /* !UNIV_HOTBACKUP */
+ page_zip_des_t zip; /*!< compressed page; zip.data
(but not the data it points to) is
also protected by buf_pool_mutex */
- buf_page_t* hash; /* node used in chaining to
+#ifndef UNIV_HOTBACKUP
+ buf_page_t* hash; /*!< node used in chaining to
buf_pool->page_hash or
buf_pool->zip_hash */
#ifdef UNIV_DEBUG
- ibool in_page_hash; /* TRUE if in buf_pool->page_hash */
- ibool in_zip_hash; /* TRUE if in buf_pool->zip_hash */
+ ibool in_page_hash; /*!< TRUE if in buf_pool->page_hash */
+ ibool in_zip_hash; /*!< TRUE if in buf_pool->zip_hash */
#endif /* UNIV_DEBUG */
- /* 2. Page flushing fields; protected by buf_pool_mutex */
+ /** @name Page flushing fields
+ All these are protected by buf_pool_mutex. */
+ /* @{ */
/* UT_LIST_NODE_T(buf_page_t) list; */
- /* based on state, this is a list
- node in one of the following lists
- in buf_pool:
-
- BUF_BLOCK_NOT_USED: free
- BUF_BLOCK_FILE_PAGE: flush_list
- BUF_BLOCK_ZIP_DIRTY: flush_list
- BUF_BLOCK_ZIP_PAGE: zip_clean
- BUF_BLOCK_ZIP_FREE: zip_free[] */
+ /*!< based on state, this is a
+ list node, protected only by
+ buf_pool_mutex, in one of the
+ following lists in buf_pool:
+
+ - BUF_BLOCK_NOT_USED: free
+ - BUF_BLOCK_FILE_PAGE: flush_list
+ - BUF_BLOCK_ZIP_DIRTY: flush_list
+ - BUF_BLOCK_ZIP_PAGE: zip_clean
+ - BUF_BLOCK_ZIP_FREE: zip_free[] */
/* resplit for optimistic use */
UT_LIST_NODE_T(buf_page_t) free;
UT_LIST_NODE_T(buf_page_t) flush_list;
UT_LIST_NODE_T(buf_page_t) zip_list; /* zip_clean or zip_free[] */
#ifdef UNIV_DEBUG
- ibool in_flush_list; /* TRUE if in buf_pool->flush_list;
+ ibool in_flush_list; /*!< TRUE if in buf_pool->flush_list;
when buf_pool_mutex is free, the
following should hold: in_flush_list
== (state == BUF_BLOCK_FILE_PAGE
|| state == BUF_BLOCK_ZIP_DIRTY) */
- ibool in_free_list; /* TRUE if in buf_pool->free; when
+ ibool in_free_list; /*!< TRUE if in buf_pool->free; when
buf_pool_mutex is free, the following
should hold: in_free_list
== (state == BUF_BLOCK_NOT_USED) */
#endif /* UNIV_DEBUG */
ib_uint64_t newest_modification;
- /* log sequence number of the youngest
- modification to this block, zero if
- not modified */
+ /*!< log sequence number of
+ the youngest modification to
+ this block, zero if not
+ modified */
ib_uint64_t oldest_modification;
- /* log sequence number of the START of
- the log entry written of the oldest
- modification to this block which has
- not yet been flushed on disk; zero if
- all modifications are on disk */
-
- /* 3. LRU replacement algorithm fields; protected by
- buf_pool_mutex only (not buf_pool_zip_mutex or block->mutex) */
+ /*!< log sequence number of
+ the START of the log entry
+ written of the oldest
+ modification to this block
+ which has not yet been flushed
+ on disk; zero if all
+ modifications are on disk */
+ /* @} */
+ /** @name LRU replacement algorithm fields
+ These fields are protected by buf_pool_mutex only (not
+ buf_pool_zip_mutex or buf_block_struct::mutex). */
+ /* @{ */
UT_LIST_NODE_T(buf_page_t) LRU;
- /* node of the LRU list */
+ /*!< node of the LRU list */
//#ifdef UNIV_DEBUG
- ibool in_LRU_list; /* TRUE if the page is in the LRU list;
- used in debugging */
+ ibool in_LRU_list; /*!< TRUE if the page is in
+ the LRU list; used in
+ debugging */
//#endif /* UNIV_DEBUG */
- unsigned old:1; /* TRUE if the block is in the old
+ unsigned old:1; /*!< TRUE if the block is in the old
blocks in the LRU list */
- unsigned LRU_position:31;/* value which monotonically decreases
- (or may stay constant if old==TRUE)
- toward the end of the LRU list, if
- buf_pool->ulint_clock has not wrapped
- around: NOTE that this value can only
- be used in heuristic algorithms,
- because of the possibility of a
+ unsigned LRU_position:31;/*!< value which monotonically
+ decreases (or may stay
+ constant if old==TRUE) toward
+ the end of the LRU list, if
+ buf_pool->ulint_clock has not
+ wrapped around: NOTE that this
+ value can only be used in
+ heuristic algorithms, because
+ of the possibility of a
wrap-around! */
- unsigned freed_page_clock:32;/* the value of
- buf_pool->freed_page_clock when this
- block was the last time put to the
- head of the LRU list; a thread is
- allowed to read this for heuristic
- purposes without holding any mutex or
- latch */
-#ifdef UNIV_DEBUG_FILE_ACCESSES
+ unsigned freed_page_clock:32;/*!< the value of
+ buf_pool->freed_page_clock
+ when this block was the last
+ time put to the head of the
+ LRU list; a thread is allowed
+ to read this for heuristic
+ purposes without holding any
+ mutex or latch */
+ /* @} */
+# ifdef UNIV_DEBUG_FILE_ACCESSES
ibool file_page_was_freed;
- /* this is set to TRUE when fsp
+ /*!< this is set to TRUE when fsp
frees a page in buffer pool */
-#endif /* UNIV_DEBUG_FILE_ACCESSES */
+# endif /* UNIV_DEBUG_FILE_ACCESSES */
+#endif /* !UNIV_HOTBACKUP */
};
-/* The buffer control block structure */
+/** The buffer control block structure */
struct buf_block_struct{
- /* 1. General fields */
+ /** @name General fields */
+ /* @{ */
- buf_page_t page; /* page information; this must
+ buf_page_t page; /*!< page information; this must
be the first field, so that
buf_pool->page_hash can point
to buf_page_t or buf_block_t */
+ byte* frame; /*!< pointer to buffer frame which
+ is of size UNIV_PAGE_SIZE, and
+ aligned to an address divisible by
+ UNIV_PAGE_SIZE */
+#ifndef UNIV_HOTBACKUP
UT_LIST_NODE_T(buf_block_t) unzip_LRU;
- /* node of the decompressed LRU list;
+ /*!< node of the decompressed LRU list;
a block is in the unzip_LRU list
if page.state == BUF_BLOCK_FILE_PAGE
and page.zip.data != NULL */
//#ifdef UNIV_DEBUG
- ibool in_unzip_LRU_list;/* TRUE if the page is in the
+ ibool in_unzip_LRU_list;/*!< TRUE if the page is in the
decompressed LRU list;
used in debugging */
//#endif /* UNIV_DEBUG */
- byte* frame; /* pointer to buffer frame which
- is of size UNIV_PAGE_SIZE, and
- aligned to an address divisible by
- UNIV_PAGE_SIZE */
- mutex_t mutex; /* mutex protecting this block:
+ mutex_t mutex; /*!< mutex protecting this block:
state (also protected by the buffer
pool mutex), io_fix, buf_fix_count,
and accessed; we introduce this new
mutex in InnoDB-5.1 to relieve
contention on the buffer pool mutex */
- rw_lock_t lock; /* read-write lock of the buffer
+ rw_lock_t lock; /*!< read-write lock of the buffer
frame */
- unsigned lock_hash_val:32;/* hashed value of the page address
+ unsigned lock_hash_val:32;/*!< hashed value of the page address
in the record lock hash table */
unsigned check_index_page_at_flush:1;
- /* TRUE if we know that this is
+ /*!< TRUE if we know that this is
an index page, and want the database
to check its consistency before flush;
note that there may be pages in the
buffer pool which are index pages,
but this flag is not set because
we do not keep track of all pages */
+ /* @} */
+ /** @name Optimistic search field */
+ /* @{ */
- /* 2. Optimistic search field */
-
- ib_uint64_t modify_clock; /* this clock is incremented every
+ ib_uint64_t modify_clock; /*!< this clock is incremented every
time a pointer to a record on the
page may become obsolete; this is
used in the optimistic cursor
@@ -1149,150 +1242,176 @@ struct buf_block_struct{
pool mutex and the page is not
bufferfixed, or (2) the thread has an
x-latch on the block */
+ /* @} */
+ /** @name Hash search fields (unprotected)
+ NOTE that these fields are NOT protected by any semaphore! */
+ /* @{ */
- /* 3. Hash search fields: NOTE that the first 4 fields are NOT
- protected by any semaphore! */
-
- ulint n_hash_helps; /* counter which controls building
+ ulint n_hash_helps; /*!< counter which controls building
of a new hash index for the page */
- ulint n_fields; /* recommended prefix length for hash
+ ulint n_fields; /*!< recommended prefix length for hash
search: number of full fields */
- ulint n_bytes; /* recommended prefix: number of bytes
+ ulint n_bytes; /*!< recommended prefix: number of bytes
in an incomplete field */
- ibool left_side; /* TRUE or FALSE, depending on
+ ibool left_side; /*!< TRUE or FALSE, depending on
whether the leftmost record of several
records with the same prefix should be
indexed in the hash index */
+ /* @} */
- /* These 6 fields may only be modified when we have
+ /** @name Hash search fields
+ These 6 fields may only be modified when we have
an x-latch on btr_search_latch AND
- a) we are holding an s-latch or x-latch on block->lock or
- b) we know that block->buf_fix_count == 0.
+ - we are holding an s-latch or x-latch on buf_block_struct::lock or
+ - we know that buf_block_struct::buf_fix_count == 0.
An exception to this is when we init or create a page
in the buffer pool in buf0buf.c. */
+ /* @{ */
+
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- ulint n_pointers; /* used in debugging: the number of
+ ulint n_pointers; /*!< used in debugging: the number of
pointers in the adaptive hash index
pointing to this frame */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- unsigned is_hashed:1; /* TRUE if hash index has already been
- built on this page; note that it does
- not guarantee that the index is
- complete, though: there may have been
- hash collisions, record deletions,
- etc. */
- unsigned curr_n_fields:10;/* prefix length for hash indexing:
+ unsigned is_hashed:1; /*!< TRUE if hash index has
+ already been built on this
+ page; note that it does not
+ guarantee that the index is
+ complete, though: there may
+ have been hash collisions,
+ record deletions, etc. */
+ unsigned curr_n_fields:10;/*!< prefix length for hash indexing:
number of full fields */
- unsigned curr_n_bytes:15;/* number of bytes in hash indexing */
- unsigned curr_left_side:1;/* TRUE or FALSE in hash indexing */
- dict_index_t* index; /* Index for which the adaptive
+ unsigned curr_n_bytes:15;/*!< number of bytes in hash
+ indexing */
+ unsigned curr_left_side:1;/*!< TRUE or FALSE in hash indexing */
+ dict_index_t* index; /*!< Index for which the adaptive
hash index has been created. */
- /* 4. Debug fields */
-#ifdef UNIV_SYNC_DEBUG
- rw_lock_t debug_latch; /* in the debug version, each thread
+ /* @} */
+# ifdef UNIV_SYNC_DEBUG
+ /** @name Debug fields */
+ /* @{ */
+ rw_lock_t debug_latch; /*!< in the debug version, each thread
which bufferfixes the block acquires
an s-latch here; so we can use the
debug utilities in sync0rw */
-#endif
+ /* @} */
+# endif
+#endif /* !UNIV_HOTBACKUP */
};
-/* Check if a buf_block_t object is in a valid state. */
+/** Check if a buf_block_t object is in a valid state
+@param block buffer block
+@return TRUE if valid */
#define buf_block_state_valid(block) \
(buf_block_get_state(block) >= BUF_BLOCK_NOT_USED \
&& (buf_block_get_state(block) <= BUF_BLOCK_REMOVE_HASH))
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Compute the hash fold value for blocks in buf_pool->zip_hash. */
+/* @{ */
#define BUF_POOL_ZIP_FOLD_PTR(ptr) ((ulint) (ptr) / 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))
+/* @} */
+
+/** @brief The buffer pool structure.
-/* The buffer pool structure. NOTE! The definition appears here only for
-other modules of this directory (buf) to see it. Do not use from outside! */
+NOTE! The definition appears here only for other modules of this
+directory (buf) to see it. Do not use from outside! */
struct buf_pool_struct{
- /* 1. General fields */
+ /** @name General fields */
+ /* @{ */
- ulint n_chunks; /* number of buffer pool chunks */
- buf_chunk_t* chunks; /* buffer pool chunks */
- ulint curr_size; /* current pool size in pages */
- hash_table_t* page_hash; /* hash table of buf_page_t or
+ ulint n_chunks; /*!< number of buffer pool chunks */
+ buf_chunk_t* chunks; /*!< buffer pool chunks */
+ ulint curr_size; /*!< current pool size in pages */
+ hash_table_t* page_hash; /*!< hash table of buf_page_t or
buf_block_t file pages,
buf_page_in_file() == TRUE,
indexed by (space_id, offset) */
- hash_table_t* zip_hash; /* hash table of buf_block_t blocks
+ hash_table_t* zip_hash; /*!< hash table of buf_block_t blocks
whose frames are allocated to the
zip buddy system,
indexed by block->frame */
- ulint n_pend_reads; /* number of pending read operations */
- ulint n_pend_unzip; /* number of pending decompressions */
+ ulint n_pend_reads; /*!< number of pending read operations */
+ ulint n_pend_unzip; /*!< number of pending decompressions */
- time_t last_printout_time; /* when buf_print was last time
+ time_t last_printout_time; /*!< when buf_print was last time
called */
- ulint n_pages_read; /* number read operations */
- ulint n_pages_written;/* number write operations */
- ulint n_pages_created;/* number of pages created in the pool
- with no read */
- ulint n_page_gets; /* number of page gets performed;
+ ulint n_pages_read; /*!< number read operations */
+ ulint n_pages_written;/*!< number write operations */
+ ulint n_pages_created;/*!< number of pages created
+ in the pool with no read */
+ ulint n_page_gets; /*!< number of page gets performed;
also successful searches through
the adaptive hash index are
counted as page gets; this field
is NOT protected by the buffer
pool mutex */
- ulint n_page_gets_old;/* n_page_gets when buf_print was
+ ulint n_page_gets_old;/*!< n_page_gets when buf_print was
last time called: used to calculate
hit rate */
- ulint n_pages_read_old;/* n_pages_read when buf_print was
+ ulint n_pages_read_old;/*!< n_pages_read when buf_print was
last time called */
- ulint n_pages_written_old;/* number write operations */
- ulint n_pages_created_old;/* number of pages created in
+ ulint n_pages_written_old;/*!< number write operations */
+ ulint n_pages_created_old;/*!< number of pages created in
the pool with no read */
- /* 2. Page flushing algorithm fields */
+ /* @} */
+ /** @name Page flushing algorithm fields */
+ /* @{ */
UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
- /* base node of the modified block
+ /*!< base node of the modified block
list */
ibool init_flush[BUF_FLUSH_N_TYPES];
- /* this is TRUE when a flush of the
+ /*!< this is TRUE when a flush of the
given type is being initialized */
ulint n_flush[BUF_FLUSH_N_TYPES];
- /* this is the number of pending
+ /*!< this is the number of pending
writes in the given flush type */
os_event_t no_flush[BUF_FLUSH_N_TYPES];
- /* this is in the set state when there
- is no flush batch of the given type
- running */
- ulint ulint_clock; /* a sequence number used to count
+ /*!< this is in the set state
+ when there is no flush batch
+ of the given type running */
+ ulint ulint_clock; /*!< a sequence number used to count
time. NOTE! This counter wraps
around at 4 billion (if ulint ==
32 bits)! */
- ulint freed_page_clock;/* a sequence number used to count the
- number of buffer blocks removed from
- the end of the LRU list; NOTE that
- this counter may wrap around at 4
- billion! A thread is allowed to
- read this for heuristic purposes
- without holding any mutex or latch */
- ulint LRU_flush_ended;/* when an LRU flush ends for a page,
+ ulint freed_page_clock;/*!< a sequence number used
+ to count the number of buffer
+ blocks removed from the end of
+ the LRU list; NOTE that this
+ counter may wrap around at 4
+ billion! A thread is allowed
+ to read this for heuristic
+ purposes without holding any
+ mutex or latch */
+ ulint LRU_flush_ended;/*!< when an LRU flush ends for a page,
this is incremented by one; this is
set to zero when a buffer block is
allocated */
- /* 3. LRU replacement algorithm fields */
+ /* @} */
+ /** @name LRU replacement algorithm fields */
+ /* @{ */
UT_LIST_BASE_NODE_T(buf_page_t) free;
- /* base node of the free block list */
+ /*!< base node of the free
+ block list */
UT_LIST_BASE_NODE_T(buf_page_t) LRU;
- /* base node of the LRU list */
- buf_page_t* LRU_old; /* pointer to the about 3/8 oldest
+ /*!< base node of the LRU list */
+ buf_page_t* LRU_old; /*!< pointer to the about 3/8 oldest
blocks in the LRU list; NULL if LRU
length less than BUF_LRU_OLD_MIN_LEN;
NOTE: when LRU_old != NULL, its length
should always equal LRU_old_len */
- ulint LRU_old_len; /* length of the LRU list from
+ ulint LRU_old_len; /*!< length of the LRU list from
the block to which LRU_old points
onward, including that block;
see buf0lru.c for the restrictions
@@ -1302,22 +1421,29 @@ struct buf_pool_struct{
whenever LRU_old shrinks or grows! */
UT_LIST_BASE_NODE_T(buf_block_t) unzip_LRU;
- /* base node of the unzip_LRU list */
-
- /* 4. Fields for the buddy allocator of compressed pages */
+ /*!< base node of the
+ unzip_LRU list */
+
+ /* @} */
+ /** @name Buddy allocator fields
+ The buddy allocator is used for allocating compressed page
+ frames and buf_page_t descriptors of blocks that exist
+ in the buffer pool only in compressed form. */
+ /* @{ */
UT_LIST_BASE_NODE_T(buf_page_t) zip_clean;
- /* unmodified compressed pages */
+ /*!< unmodified compressed pages */
UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES];
- /* buddy free lists */
+ /*!< buddy free lists */
#if BUF_BUDDY_HIGH != UNIV_PAGE_SIZE
# error "BUF_BUDDY_HIGH != UNIV_PAGE_SIZE"
#endif
#if BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE
# error "BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE"
#endif
+ /* @} */
};
-/* mutex protecting the buffer pool struct and control blocks, except the
+/** mutex protecting the buffer pool struct and control blocks, except the
read-write lock in them */
extern mutex_t buf_pool_mutex;
extern mutex_t LRU_list_mutex;
@@ -1326,16 +1452,17 @@ extern rw_lock_t page_hash_latch;
extern mutex_t free_list_mutex;
extern mutex_t zip_free_mutex;
extern mutex_t zip_hash_mutex;
-/* mutex protecting the control blocks of compressed-only pages
+/** mutex protecting the control blocks of compressed-only pages
(of type buf_page_t, not buf_block_t) */
extern mutex_t buf_pool_zip_mutex;
-/* Accessors for buf_pool_mutex. Use these instead of accessing
-buf_pool_mutex directly. */
+/** @name Accessors for buf_pool_mutex.
+Use these instead of accessing buf_pool_mutex directly. */
+/* @{ */
-/* Test if buf_pool_mutex is owned. */
+/** Test if buf_pool_mutex is owned. */
#define buf_pool_mutex_own() mutex_own(&buf_pool_mutex)
-/* Acquire the buffer pool mutex. */
+/** Acquire the buffer pool mutex. */
#define buf_pool_mutex_enter() do { \
ut_ad(!mutex_own(&buf_pool_zip_mutex)); \
mutex_enter(&buf_pool_mutex); \
@@ -1345,32 +1472,34 @@ buf_pool_mutex directly. */
/** Flag to forbid the release of the buffer pool mutex.
Protected by buf_pool_mutex. */
extern ulint buf_pool_mutex_exit_forbidden;
-/* Forbid the release of the buffer pool mutex. */
+/** Forbid the release of the buffer pool mutex. */
# define buf_pool_mutex_exit_forbid() do { \
ut_ad(buf_pool_mutex_own()); \
buf_pool_mutex_exit_forbidden++; \
} while (0)
-/* Allow the release of the buffer pool mutex. */
+/** Allow the release of the buffer pool mutex. */
# define buf_pool_mutex_exit_allow() do { \
ut_ad(buf_pool_mutex_own()); \
ut_a(buf_pool_mutex_exit_forbidden); \
buf_pool_mutex_exit_forbidden--; \
} while (0)
-/* Release the buffer pool mutex. */
+/** Release the buffer pool mutex. */
# define buf_pool_mutex_exit() do { \
ut_a(!buf_pool_mutex_exit_forbidden); \
mutex_exit(&buf_pool_mutex); \
} while (0)
#else
-/* Forbid the release of the buffer pool mutex. */
+/** Forbid the release of the buffer pool mutex. */
# define buf_pool_mutex_exit_forbid() ((void) 0)
-/* Allow the release of the buffer pool mutex. */
+/** Allow the release of the buffer pool mutex. */
# define buf_pool_mutex_exit_allow() ((void) 0)
-/* Release the buffer pool mutex. */
+/** Release the buffer pool mutex. */
# define buf_pool_mutex_exit() mutex_exit(&buf_pool_mutex)
#endif
+#endif /* !UNIV_HOTBACKUP */
+/* @} */
-/************************************************************************
+/**********************************************************************
Let us list the consistency conditions for different control block states.
NOT_USED: is in free list, not in LRU list, not in flush list, nor
diff --git a/storage/xtradb/include/buf0buf.ic b/storage/xtradb/include/buf0buf.ic
index d7ac80becce..1a2b2556839 100644
--- a/storage/xtradb/include/buf0buf.ic
+++ b/storage/xtradb/include/buf0buf.ic
@@ -23,79 +23,79 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0buf.ic
The database buffer buf_pool
Created 11/5/1995 Heikki Tuuri
*******************************************************/
+#include "mtr0mtr.h"
+#ifndef UNIV_HOTBACKUP
#include "buf0flu.h"
#include "buf0lru.h"
#include "buf0rea.h"
-#include "mtr0mtr.h"
-/************************************************************************
-Reads the freed_page_clock of a buffer block. */
+/********************************************************************//**
+Reads the freed_page_clock of a buffer block.
+@return freed_page_clock */
UNIV_INLINE
ulint
buf_page_get_freed_page_clock(
/*==========================*/
- /* out: freed_page_clock */
- const buf_page_t* bpage) /* in: block */
+ const buf_page_t* bpage) /*!< in: block */
{
/* This is sometimes read without holding buf_pool_mutex. */
return(bpage->freed_page_clock);
}
-/************************************************************************
-Reads the freed_page_clock of a buffer block. */
+/********************************************************************//**
+Reads the freed_page_clock of a buffer block.
+@return freed_page_clock */
UNIV_INLINE
ulint
buf_block_get_freed_page_clock(
/*===========================*/
- /* out: freed_page_clock */
- const buf_block_t* block) /* in: block */
+ const buf_block_t* block) /*!< in: block */
{
return(buf_page_get_freed_page_clock(&block->page));
}
-/************************************************************************
+/********************************************************************//**
Recommends a move of a block to the start of the LRU list if there is danger
of dropping from the buffer pool. NOTE: does not reserve the buffer pool
-mutex. */
+mutex.
+@return TRUE if should be made younger */
UNIV_INLINE
ibool
buf_page_peek_if_too_old(
/*=====================*/
- /* out: TRUE if should be made
- younger */
- const buf_page_t* bpage) /* in: block to make younger */
+ const buf_page_t* bpage) /*!< in: block to make younger */
{
return(buf_pool->freed_page_clock
>= buf_page_get_freed_page_clock(bpage)
+ 1 + (buf_pool->curr_size / 4));
}
-/*************************************************************************
-Gets the current size of buffer buf_pool in bytes. */
+/*********************************************************************//**
+Gets the current size of buffer buf_pool in bytes.
+@return size in bytes */
UNIV_INLINE
ulint
buf_pool_get_curr_size(void)
/*========================*/
- /* out: size in bytes */
{
return(buf_pool->curr_size * UNIV_PAGE_SIZE);
}
-/************************************************************************
+/********************************************************************//**
Gets the smallest oldest_modification lsn for any page in the pool. Returns
-zero if all modified pages have been flushed to disk. */
+zero if all modified pages have been flushed to disk.
+@return oldest modification in pool, zero if none */
UNIV_INLINE
ib_uint64_t
buf_pool_get_oldest_modification(void)
/*==================================*/
- /* out: oldest modification in pool,
- zero if none */
{
buf_page_t* bpage;
ib_uint64_t lsn;
@@ -126,14 +126,14 @@ try_again:
return(lsn);
}
-/***********************************************************************
+/*******************************************************************//**
Increments the buf_pool clock by one and returns its new value. Remember
-that in the 32 bit version the clock wraps around at 4 billion! */
+that in the 32 bit version the clock wraps around at 4 billion!
+@return new clock value */
UNIV_INLINE
ulint
buf_pool_clock_tic(void)
/*====================*/
- /* out: new clock value */
{
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(&LRU_list_mutex));
@@ -142,15 +142,16 @@ buf_pool_clock_tic(void)
return(buf_pool->ulint_clock);
}
+#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
-Gets the state of a block. */
+/*********************************************************************//**
+Gets the state of a block.
+@return state */
UNIV_INLINE
enum buf_page_state
buf_page_get_state(
/*===============*/
- /* out: state */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
{
enum buf_page_state state = (enum buf_page_state) bpage->state;
@@ -172,25 +173,25 @@ buf_page_get_state(
return(state);
}
-/*************************************************************************
-Gets the state of a block. */
+/*********************************************************************//**
+Gets the state of a block.
+@return state */
UNIV_INLINE
enum buf_page_state
buf_block_get_state(
/*================*/
- /* out: state */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
{
return(buf_page_get_state(&block->page));
}
-/*************************************************************************
+/*********************************************************************//**
Sets the state of a block. */
UNIV_INLINE
void
buf_page_set_state(
/*===============*/
- buf_page_t* bpage, /* in/out: pointer to control block */
- enum buf_page_state state) /* in: state */
+ buf_page_t* bpage, /*!< in/out: pointer to control block */
+ enum buf_page_state state) /*!< in: state */
{
#ifdef UNIV_DEBUG
enum buf_page_state old_state = buf_page_get_state(bpage);
@@ -229,26 +230,26 @@ buf_page_set_state(
ut_ad(buf_page_get_state(bpage) == state);
}
-/*************************************************************************
+/*********************************************************************//**
Sets the state of a block. */
UNIV_INLINE
void
buf_block_set_state(
/*================*/
- buf_block_t* block, /* in/out: pointer to control block */
- enum buf_page_state state) /* in: state */
+ buf_block_t* block, /*!< in/out: pointer to control block */
+ enum buf_page_state state) /*!< in: state */
{
buf_page_set_state(&block->page, state);
}
-/*************************************************************************
-Determines if a block is mapped to a tablespace. */
+/*********************************************************************//**
+Determines if a block is mapped to a tablespace.
+@return TRUE if mapped */
UNIV_INLINE
ibool
buf_page_in_file(
/*=============*/
- /* out: TRUE if mapped */
- const buf_page_t* bpage) /* in: pointer to control block */
+ const buf_page_t* bpage) /*!< in: pointer to control block */
{
switch (buf_page_get_state(bpage)) {
case BUF_BLOCK_ZIP_FREE:
@@ -270,15 +271,15 @@ buf_page_in_file(
return(FALSE);
}
-/*************************************************************************
-Determines if a block should be on unzip_LRU list. */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
+Determines if a block should be on unzip_LRU list.
+@return TRUE if block belongs to unzip_LRU */
UNIV_INLINE
ibool
buf_page_belongs_to_unzip_LRU(
/*==========================*/
- /* out: TRUE if block belongs
- to unzip_LRU */
- const buf_page_t* bpage) /* in: pointer to control block */
+ const buf_page_t* bpage) /*!< in: pointer to control block */
{
ut_ad(buf_page_in_file(bpage));
@@ -286,14 +287,14 @@ buf_page_belongs_to_unzip_LRU(
&& buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
}
-/*************************************************************************
-Determine the approximate LRU list position of a block. */
+/*********************************************************************//**
+Determine the approximate LRU list position of a block.
+@return LRU list position */
UNIV_INLINE
ulint
buf_page_get_LRU_position(
/*======================*/
- /* out: LRU list position */
- const buf_page_t* bpage) /* in: control block */
+ const buf_page_t* bpage) /*!< in: control block */
{
ut_ad(buf_page_in_file(bpage));
//ut_ad(buf_pool_mutex_own()); /* This is used in optimistic */
@@ -301,15 +302,14 @@ buf_page_get_LRU_position(
return(bpage->LRU_position);
}
-/*************************************************************************
-Gets the mutex of a block. */
+/*********************************************************************//**
+Gets the mutex of a block.
+@return pointer to mutex protecting bpage */
UNIV_INLINE
mutex_t*
buf_page_get_mutex(
/*===============*/
- /* out: pointer to mutex
- protecting bpage */
- const buf_page_t* bpage) /* in: pointer to control block */
+ const buf_page_t* bpage) /*!< in: pointer to control block */
{
switch (buf_page_get_state(bpage)) {
case BUF_BLOCK_ZIP_FREE:
@@ -324,13 +324,35 @@ buf_page_get_mutex(
}
/*************************************************************************
-Get the flush type of a page. */
+Gets the mutex of a block and enter the mutex with consistency. */
+UNIV_INLINE
+mutex_t*
+buf_page_get_mutex_enter(
+/*=========================*/
+ const buf_page_t* bpage) /*!< in: pointer to control block */
+{
+ mutex_t* block_mutex;
+
+ while(1) {
+ block_mutex = buf_page_get_mutex(bpage);
+ if (!block_mutex)
+ return block_mutex;
+
+ mutex_enter(block_mutex);
+ if (block_mutex == buf_page_get_mutex(bpage))
+ return block_mutex;
+ mutex_exit(block_mutex);
+ }
+}
+
+/*********************************************************************//**
+Get the flush type of a page.
+@return flush type */
UNIV_INLINE
enum buf_flush
buf_page_get_flush_type(
/*====================*/
- /* out: flush type */
- const buf_page_t* bpage) /* in: buffer page */
+ const buf_page_t* bpage) /*!< in: buffer page */
{
enum buf_flush flush_type = (enum buf_flush) bpage->flush_type;
@@ -347,42 +369,42 @@ buf_page_get_flush_type(
#endif /* UNIV_DEBUG */
return(flush_type);
}
-/*************************************************************************
+/*********************************************************************//**
Set the flush type of a page. */
UNIV_INLINE
void
buf_page_set_flush_type(
/*====================*/
- buf_page_t* bpage, /* in: buffer page */
- enum buf_flush flush_type) /* in: flush type */
+ buf_page_t* bpage, /*!< in: buffer page */
+ enum buf_flush flush_type) /*!< in: flush type */
{
bpage->flush_type = flush_type;
ut_ad(buf_page_get_flush_type(bpage) == flush_type);
}
-/*************************************************************************
+/*********************************************************************//**
Map a block to a file page. */
UNIV_INLINE
void
buf_block_set_file_page(
/*====================*/
- buf_block_t* block, /* in/out: pointer to control block */
- ulint space, /* in: tablespace id */
- ulint page_no)/* in: page number */
+ buf_block_t* block, /*!< in/out: pointer to control block */
+ ulint space, /*!< in: tablespace id */
+ ulint page_no)/*!< in: page number */
{
buf_block_set_state(block, BUF_BLOCK_FILE_PAGE);
block->page.space = space;
block->page.offset = page_no;
}
-/*************************************************************************
-Gets the io_fix state of a block. */
+/*********************************************************************//**
+Gets the io_fix state of a block.
+@return io_fix state */
UNIV_INLINE
enum buf_io_fix
buf_page_get_io_fix(
/*================*/
- /* out: io_fix state */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
{
enum buf_io_fix io_fix = (enum buf_io_fix) bpage->io_fix;
#ifdef UNIV_DEBUG
@@ -397,26 +419,26 @@ buf_page_get_io_fix(
return(io_fix);
}
-/*************************************************************************
-Gets the io_fix state of a block. */
+/*********************************************************************//**
+Gets the io_fix state of a block.
+@return io_fix state */
UNIV_INLINE
enum buf_io_fix
buf_block_get_io_fix(
/*================*/
- /* out: io_fix state */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
{
return(buf_page_get_io_fix(&block->page));
}
-/*************************************************************************
+/*********************************************************************//**
Sets the io_fix state of a block. */
UNIV_INLINE
void
buf_page_set_io_fix(
/*================*/
- buf_page_t* bpage, /* in/out: control block */
- enum buf_io_fix io_fix) /* in: io_fix state */
+ buf_page_t* bpage, /*!< in/out: control block */
+ enum buf_io_fix io_fix) /*!< in: io_fix state */
{
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
@@ -425,26 +447,26 @@ buf_page_set_io_fix(
ut_ad(buf_page_get_io_fix(bpage) == io_fix);
}
-/*************************************************************************
+/*********************************************************************//**
Sets the io_fix state of a block. */
UNIV_INLINE
void
buf_block_set_io_fix(
/*=================*/
- buf_block_t* block, /* in/out: control block */
- enum buf_io_fix io_fix) /* in: io_fix state */
+ buf_block_t* block, /*!< in/out: control block */
+ enum buf_io_fix io_fix) /*!< in: io_fix state */
{
buf_page_set_io_fix(&block->page, io_fix);
}
-/************************************************************************
+/********************************************************************//**
Determine if a buffer block can be relocated in memory. The block
can be dirty, but it must not be I/O-fixed or bufferfixed. */
UNIV_INLINE
ibool
buf_page_can_relocate(
/*==================*/
- const buf_page_t* bpage) /* control block being relocated */
+ const buf_page_t* bpage) /*!< control block being relocated */
{
//ut_ad(buf_pool_mutex_own());
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
@@ -456,14 +478,14 @@ buf_page_can_relocate(
&& bpage->buf_fix_count == 0);
}
-/*************************************************************************
-Determine if a block has been flagged old. */
+/*********************************************************************//**
+Determine if a block has been flagged old.
+@return TRUE if old */
UNIV_INLINE
ibool
buf_page_is_old(
/*============*/
- /* out: TRUE if old */
- const buf_page_t* bpage) /* in: control block */
+ const buf_page_t* bpage) /*!< in: control block */
{
ut_ad(buf_page_in_file(bpage));
//ut_ad(buf_pool_mutex_own()); /* This is used in optimistic */
@@ -471,14 +493,14 @@ buf_page_is_old(
return(bpage->old);
}
-/*************************************************************************
+/*********************************************************************//**
Flag a block old. */
UNIV_INLINE
void
buf_page_set_old(
/*=============*/
- buf_page_t* bpage, /* in/out: control block */
- ibool old) /* in: old */
+ buf_page_t* bpage, /*!< in/out: control block */
+ ibool old) /*!< in: old */
{
ut_a(buf_page_in_file(bpage));
//ut_ad(buf_pool_mutex_own());
@@ -496,28 +518,28 @@ buf_page_set_old(
bpage->old = old;
}
-/*************************************************************************
-Determine if a block has been accessed in the buffer pool. */
+/*********************************************************************//**
+Determine if a block has been accessed in the buffer pool.
+@return TRUE if accessed */
UNIV_INLINE
ibool
buf_page_is_accessed(
/*=================*/
- /* out: TRUE if accessed */
- const buf_page_t* bpage) /* in: control block */
+ const buf_page_t* bpage) /*!< in: control block */
{
ut_ad(buf_page_in_file(bpage));
return(bpage->accessed);
}
-/*************************************************************************
+/*********************************************************************//**
Flag a block accessed. */
UNIV_INLINE
void
buf_page_set_accessed(
/*==================*/
- buf_page_t* bpage, /* in/out: control block */
- ibool accessed) /* in: accessed */
+ buf_page_t* bpage, /*!< in/out: control block */
+ ibool accessed) /*!< in: accessed */
{
ut_a(buf_page_in_file(bpage));
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
@@ -525,15 +547,15 @@ buf_page_set_accessed(
bpage->accessed = accessed;
}
-/*************************************************************************
+/*********************************************************************//**
Gets the buf_block_t handle of a buffered file block if an uncompressed
-page frame exists, or NULL. */
+page frame exists, or NULL.
+@return control block, or NULL */
UNIV_INLINE
buf_block_t*
buf_page_get_block(
/*===============*/
- /* out: control block, or NULL */
- buf_page_t* bpage) /* in: control block, or NULL */
+ buf_page_t* bpage) /*!< in: control block, or NULL */
{
if (UNIV_LIKELY(bpage != NULL)) {
ut_ad(buf_page_in_file(bpage));
@@ -545,16 +567,17 @@ buf_page_get_block(
return(NULL);
}
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
-/*************************************************************************
-Gets a pointer to the memory frame of a block. */
+/*********************************************************************//**
+Gets a pointer to the memory frame of a block.
+@return pointer to the frame */
UNIV_INLINE
buf_frame_t*
buf_block_get_frame(
/*================*/
- /* out: pointer to the frame */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
{
ut_ad(block);
@@ -566,7 +589,9 @@ buf_block_get_frame(
ut_error;
break;
case BUF_BLOCK_FILE_PAGE:
+# ifndef UNIV_HOTBACKUP
ut_a(block->page.buf_fix_count > 0);
+# endif /* !UNIV_HOTBACKUP */
/* fall through */
case BUF_BLOCK_READY_FOR_USE:
case BUF_BLOCK_MEMORY:
@@ -579,14 +604,14 @@ ok:
}
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Gets the space id of a block. */
+/*********************************************************************//**
+Gets the space id of a block.
+@return space id */
UNIV_INLINE
ulint
buf_page_get_space(
/*===============*/
- /* out: space id */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
{
ut_ad(bpage);
ut_a(buf_page_in_file(bpage));
@@ -594,14 +619,14 @@ buf_page_get_space(
return(bpage->space);
}
-/*************************************************************************
-Gets the space id of a block. */
+/*********************************************************************//**
+Gets the space id of a block.
+@return space id */
UNIV_INLINE
ulint
buf_block_get_space(
/*================*/
- /* out: space id */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
{
ut_ad(block);
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
@@ -609,14 +634,14 @@ buf_block_get_space(
return(block->page.space);
}
-/*************************************************************************
-Gets the page number of a block. */
+/*********************************************************************//**
+Gets the page number of a block.
+@return page number */
UNIV_INLINE
ulint
buf_page_get_page_no(
/*=================*/
- /* out: page number */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
{
ut_ad(bpage);
ut_a(buf_page_in_file(bpage));
@@ -624,14 +649,14 @@ buf_page_get_page_no(
return(bpage->offset);
}
-/*************************************************************************
-Gets the page number of a block. */
+/*********************************************************************//**
+Gets the page number of a block.
+@return page number */
UNIV_INLINE
ulint
buf_block_get_page_no(
/*==================*/
- /* out: page number */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
{
ut_ad(block);
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
@@ -639,55 +664,57 @@ buf_block_get_page_no(
return(block->page.offset);
}
-/*************************************************************************
-Gets the compressed page size of a block. */
+/*********************************************************************//**
+Gets the compressed page size of a block.
+@return compressed page size, or 0 */
UNIV_INLINE
ulint
buf_page_get_zip_size(
/*==================*/
- /* out: compressed page size, or 0 */
- const buf_page_t* bpage) /* in: pointer to the control block */
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
{
return(bpage->zip.ssize ? 512 << bpage->zip.ssize : 0);
}
-/*************************************************************************
-Gets the compressed page size of a block. */
+/*********************************************************************//**
+Gets the compressed page size of a block.
+@return compressed page size, or 0 */
UNIV_INLINE
ulint
buf_block_get_zip_size(
/*===================*/
- /* out: compressed page size, or 0 */
- const buf_block_t* block) /* in: pointer to the control block */
+ const buf_block_t* block) /*!< in: pointer to the control block */
{
return(block->page.zip.ssize ? 512 << block->page.zip.ssize : 0);
}
+#ifndef UNIV_HOTBACKUP
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Gets the compressed page descriptor corresponding to an uncompressed page
-if applicable. */
+if applicable.
+@return compressed page descriptor, or NULL */
UNIV_INLINE
const page_zip_des_t*
buf_frame_get_page_zip(
/*===================*/
- /* out: compressed page descriptor, or NULL */
- const byte* ptr) /* in: pointer to the page */
+ const byte* ptr) /*!< in: pointer to the page */
{
return(buf_block_get_page_zip(buf_block_align(ptr)));
}
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Gets the space id, page offset, and byte offset within page of a
pointer pointing to a buffer frame containing a file page. */
UNIV_INLINE
void
buf_ptr_get_fsp_addr(
/*=================*/
- const void* ptr, /* in: pointer to a buffer frame */
- ulint* space, /* out: space id */
- fil_addr_t* addr) /* out: page offset and byte offset */
+ const void* ptr, /*!< in: pointer to a buffer frame */
+ ulint* space, /*!< out: space id */
+ fil_addr_t* addr) /*!< out: page offset and byte offset */
{
const page_t* page = (const page_t*) ut_align_down(ptr,
UNIV_PAGE_SIZE);
@@ -697,28 +724,28 @@ buf_ptr_get_fsp_addr(
addr->boffset = ut_align_offset(ptr, UNIV_PAGE_SIZE);
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Gets the hash value of the page the pointer is pointing to. This can be used
-in searches in the lock hash table. */
+in searches in the lock hash table.
+@return lock hash value */
UNIV_INLINE
ulint
buf_block_get_lock_hash_val(
/*========================*/
- /* out: lock hash value */
- const buf_block_t* block) /* in: block */
+ const buf_block_t* block) /*!< in: block */
{
return(block->lock_hash_val);
}
-/************************************************************************
-Allocates a buffer block. */
+/********************************************************************//**
+Allocates a buffer block.
+@return own: the allocated block, in state BUF_BLOCK_MEMORY */
UNIV_INLINE
buf_block_t*
buf_block_alloc(
/*============*/
- /* out, own: the allocated block,
- in state BUF_BLOCK_MEMORY */
- ulint zip_size) /* in: compressed page size in bytes,
+ ulint zip_size) /*!< in: compressed page size in bytes,
or 0 if uncompressed tablespace */
{
buf_block_t* block;
@@ -730,13 +757,13 @@ buf_block_alloc(
return(block);
}
-/************************************************************************
+/********************************************************************//**
Frees a buffer block which does not contain a file page. */
UNIV_INLINE
void
buf_block_free(
/*===========*/
- buf_block_t* block) /* in, own: block to be freed */
+ buf_block_t* block) /*!< in, own: block to be freed */
{
//buf_pool_mutex_enter();
@@ -750,16 +777,17 @@ buf_block_free(
//buf_pool_mutex_exit();
}
+#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
-Copies contents of a buffer frame to a given buffer. */
+/*********************************************************************//**
+Copies contents of a buffer frame to a given buffer.
+@return buf */
UNIV_INLINE
byte*
buf_frame_copy(
/*===========*/
- /* out: buf */
- byte* buf, /* in: buffer to copy to */
- const buf_frame_t* frame) /* in: buffer frame */
+ byte* buf, /*!< in: buffer to copy to */
+ const buf_frame_t* frame) /*!< in: buffer frame */
{
ut_ad(buf && frame);
@@ -768,73 +796,36 @@ buf_frame_copy(
return(buf);
}
-/************************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Calculates a folded value of a file page address to use in the page hash
-table. */
+table.
+@return the folded value */
UNIV_INLINE
ulint
buf_page_address_fold(
/*==================*/
- /* out: the folded value */
- ulint space, /* in: space id */
- ulint offset) /* in: offset of the page within space */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: offset of the page within space */
{
return((space << 20) + space + offset);
}
-/************************************************************************
-This function is used to get info if there is an io operation
-going on on a buffer page. */
-UNIV_INLINE
-ibool
-buf_page_io_query(
-/*==============*/
- /* out: TRUE if io going on */
- buf_page_t* bpage) /* in: buf_pool block, must be bufferfixed */
-{
- ibool io_fixed;
- mutex_t* block_mutex = buf_page_get_mutex(bpage);
-
- //buf_pool_mutex_enter();
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
-
- ut_ad(buf_page_in_file(bpage));
- ut_ad(bpage->buf_fix_count > 0);
-
- io_fixed = buf_page_get_io_fix(bpage) != BUF_IO_NONE;
- //buf_pool_mutex_exit();
- mutex_exit(block_mutex);
-
- return(io_fixed);
-}
-
-/************************************************************************
+/********************************************************************//**
Gets the youngest modification log sequence number for a frame.
-Returns zero if not file page or no modification occurred yet. */
+Returns zero if not file page or no modification occurred yet.
+@return newest modification to page */
UNIV_INLINE
ib_uint64_t
buf_page_get_newest_modification(
/*=============================*/
- /* out: newest modification to page */
- const buf_page_t* bpage) /* in: block containing the
+ const buf_page_t* bpage) /*!< in: block containing the
page frame */
{
ib_uint64_t lsn;
- mutex_t* block_mutex = buf_page_get_mutex(bpage);
+ mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
-retry_lock:
- mutex_enter(block_mutex);
- if (block_mutex != buf_page_get_mutex(bpage)) {
- mutex_exit(block_mutex);
- block_mutex = buf_page_get_mutex(bpage);
- goto retry_lock;
- }
+ ut_a(block_mutex);
if (buf_page_in_file(bpage)) {
lsn = bpage->newest_modification;
@@ -847,7 +838,7 @@ retry_lock:
return(lsn);
}
-/************************************************************************
+/********************************************************************//**
Increments the modify clock of a frame by 1. The caller must (1) own the
buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock
on the block. */
@@ -855,7 +846,7 @@ UNIV_INLINE
void
buf_block_modify_clock_inc(
/*=======================*/
- buf_block_t* block) /* in: block */
+ buf_block_t* block) /*!< in: block */
{
#ifdef UNIV_SYNC_DEBUG
ut_ad((mutex_own(&LRU_list_mutex)
@@ -866,15 +857,15 @@ buf_block_modify_clock_inc(
block->modify_clock++;
}
-/************************************************************************
+/********************************************************************//**
Returns the value of the modify clock. The caller must have an s-lock
-or x-lock on the block. */
+or x-lock on the block.
+@return value */
UNIV_INLINE
ib_uint64_t
buf_block_get_modify_clock(
/*=======================*/
- /* out: value */
- buf_block_t* block) /* in: block */
+ buf_block_t* block) /*!< in: block */
{
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
@@ -884,17 +875,17 @@ buf_block_get_modify_clock(
return(block->modify_clock);
}
-/***********************************************************************
+/*******************************************************************//**
Increments the bufferfix count. */
UNIV_INLINE
void
buf_block_buf_fix_inc_func(
/*=======================*/
#ifdef UNIV_SYNC_DEBUG
- const char* file, /* in: file name */
- ulint line, /* in: line */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line */
#endif /* UNIV_SYNC_DEBUG */
- buf_block_t* block) /* in: block to bufferfix */
+ buf_block_t* block) /*!< in/out: block to bufferfix */
{
#ifdef UNIV_SYNC_DEBUG
ibool ret;
@@ -907,18 +898,26 @@ buf_block_buf_fix_inc_func(
block->page.buf_fix_count++;
}
#ifdef UNIV_SYNC_DEBUG
+/** Increments the bufferfix count.
+@param b in/out: block to bufferfix
+@param f in: file name where requested
+@param l in: line number where requested */
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
#else /* UNIV_SYNC_DEBUG */
+/** Increments the bufferfix count.
+@param b in/out: block to bufferfix
+@param f in: file name where requested
+@param l in: line number where requested */
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
#endif /* UNIV_SYNC_DEBUG */
-/***********************************************************************
+/*******************************************************************//**
Decrements the bufferfix count. */
UNIV_INLINE
void
buf_block_buf_fix_dec(
/*==================*/
- buf_block_t* block) /* in: block to bufferunfix */
+ buf_block_t* block) /*!< in/out: block to bufferunfix */
{
ut_ad(mutex_own(&block->mutex));
@@ -928,15 +927,15 @@ buf_block_buf_fix_dec(
#endif
}
-/**********************************************************************
-Returns the control block of a file page, NULL if not found. */
+/******************************************************************//**
+Returns the control block of a file page, NULL if not found.
+@return block, NULL if not found */
UNIV_INLINE
buf_page_t*
buf_page_hash_get(
/*==============*/
- /* out: block, NULL if not found */
- ulint space, /* in: space id */
- ulint offset) /* in: offset of the page within space */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: offset of the page within space */
{
buf_page_t* bpage;
ulint fold;
@@ -966,32 +965,33 @@ buf_page_hash_get(
return(bpage);
}
-/**********************************************************************
+/******************************************************************//**
Returns the control block of a file page, NULL if not found
-or an uncompressed page frame does not exist. */
+or an uncompressed page frame does not exist.
+@return block, NULL if not found */
UNIV_INLINE
buf_block_t*
buf_block_hash_get(
/*===============*/
- /* out: block, NULL if not found */
- ulint space, /* in: space id */
- ulint offset) /* in: offset of the page within space */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: offset of the page within space */
{
return(buf_page_get_block(buf_page_hash_get(space, offset)));
}
-/************************************************************************
-Returns TRUE if the page can be found in the buffer pool hash table. NOTE
-that it is possible that the page is not yet read from disk, though. */
+/********************************************************************//**
+Returns TRUE if the page can be found in the buffer pool hash table.
+
+NOTE that it is possible that the page is not yet read from disk,
+though.
+
+@return TRUE if found in the page hash table */
UNIV_INLINE
ibool
buf_page_peek(
/*==========*/
- /* out: TRUE if found from page hash table,
- NOTE that the page is not necessarily yet read
- from disk! */
- ulint space, /* in: space id */
- ulint offset) /* in: page number */
+ ulint space, /*!< in: space id */
+ ulint offset) /*!< in: page number */
{
const buf_page_t* bpage;
@@ -1006,13 +1006,13 @@ buf_page_peek(
return(bpage != NULL);
}
-/************************************************************************
+/********************************************************************//**
Releases a compressed-only page acquired with buf_page_get_zip(). */
UNIV_INLINE
void
buf_page_release_zip(
/*=================*/
- buf_page_t* bpage) /* in: buffer block */
+ buf_page_t* bpage) /*!< in: buffer block */
{
buf_block_t* block;
@@ -1046,17 +1046,17 @@ buf_page_release_zip(
ut_error;
}
-/************************************************************************
+/********************************************************************//**
Decrements the bufferfix count of a buffer control block and releases
a latch, if specified. */
UNIV_INLINE
void
buf_page_release(
/*=============*/
- buf_block_t* block, /* in: buffer block */
- ulint rw_latch, /* in: RW_S_LATCH, RW_X_LATCH,
+ buf_block_t* block, /*!< in: buffer block */
+ ulint rw_latch, /*!< in: RW_S_LATCH, RW_X_LATCH,
RW_NO_LATCH */
- mtr_t* mtr __attribute__((unused))) /* in: mtr */
+ mtr_t* mtr __attribute__((unused))) /*!< in: mtr */
{
ut_ad(block);
@@ -1079,10 +1079,6 @@ buf_page_release(
#endif
block->page.buf_fix_count--;
- /* Dirty blocks should be in the flush list. */
- ut_ad(!block->page.oldest_modification
- || block->page.in_flush_list);
-
mutex_exit(&block->mutex);
if (rw_latch == RW_S_LATCH) {
@@ -1093,7 +1089,7 @@ buf_page_release(
}
#ifdef UNIV_SYNC_DEBUG
-/*************************************************************************
+/*********************************************************************//**
Adds latch level info for the rw-lock protecting the buffer frame. This
should be called in the debug version after a successful latching of a
page if we know the latching order level of the acquired latch. */
@@ -1101,10 +1097,11 @@ UNIV_INLINE
void
buf_block_dbg_add_level(
/*====================*/
- buf_block_t* block, /* in: buffer page
+ buf_block_t* block, /*!< in: buffer page
where we have acquired latch */
- ulint level) /* in: latching order level */
+ ulint level) /*!< in: latching order level */
{
sync_thread_add_level(&block->lock, level);
}
#endif /* UNIV_SYNC_DEBUG */
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/buf0flu.h b/storage/xtradb/include/buf0flu.h
index 11a37351479..cac4bf9fe4b 100644
--- a/storage/xtradb/include/buf0flu.h
+++ b/storage/xtradb/include/buf0flu.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0flu.h
The database buffer pool flush algorithm
Created 11/5/1995 Heikki Tuuri
@@ -26,25 +27,26 @@ Created 11/5/1995 Heikki Tuuri
#define buf0flu_h
#include "univ.i"
-#include "buf0types.h"
#include "ut0byte.h"
+#ifndef UNIV_HOTBACKUP
#include "mtr0types.h"
+#include "buf0types.h"
-/************************************************************************
+/********************************************************************//**
Remove a block from the flush list of modified blocks. */
UNIV_INTERN
void
buf_flush_remove(
/*=============*/
- buf_page_t* bpage); /* in: pointer to the block in question */
-/************************************************************************
+ buf_page_t* bpage); /*!< in: pointer to the block in question */
+/********************************************************************//**
Updates the flush system data structures when a write is completed. */
UNIV_INTERN
void
buf_flush_write_complete(
/*=====================*/
- buf_page_t* bpage); /* in: pointer to the block in question */
-/*************************************************************************
+ buf_page_t* bpage); /*!< in: pointer to the block in question */
+/*********************************************************************//**
Flushes pages from the end of the LRU list if there is too small
a margin of replaceable pages there. */
UNIV_INTERN
@@ -52,50 +54,50 @@ void
buf_flush_free_margin(
/*=======================*/
ibool wait);
-/************************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
Initializes a page for writing to the tablespace. */
UNIV_INTERN
void
buf_flush_init_for_writing(
/*=======================*/
- byte* page, /* in/out: page */
- void* page_zip_, /* in/out: compressed page, or NULL */
- ib_uint64_t newest_lsn); /* in: newest modification lsn
+ byte* page, /*!< in/out: page */
+ void* page_zip_, /*!< in/out: compressed page, or NULL */
+ ib_uint64_t newest_lsn); /*!< in: newest modification lsn
to the page */
-/***********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
This utility flushes dirty blocks from the end of the LRU list or flush_list.
NOTE 1: in the case of an LRU flush the calling thread may own latches to
pages: to avoid deadlocks, this function must be written so that it cannot
end up waiting for these latches! NOTE 2: in the case of a flush list flush,
-the calling thread is not allowed to own any latches on pages! */
+the calling thread is not allowed to own any latches on pages!
+@return number of blocks for which the write request was queued;
+ULINT_UNDEFINED if there was a flush of the same type already running */
UNIV_INTERN
ulint
buf_flush_batch(
/*============*/
- /* out: number of blocks for which the
- write request was queued;
- ULINT_UNDEFINED if there was a flush
- of the same type already running */
- enum buf_flush flush_type, /* in: BUF_FLUSH_LRU or
+ enum buf_flush flush_type, /*!< in: BUF_FLUSH_LRU or
BUF_FLUSH_LIST; if BUF_FLUSH_LIST,
then the caller must not own any
latches on pages */
- ulint min_n, /* in: wished minimum mumber of blocks
+ ulint min_n, /*!< in: wished minimum mumber of blocks
flushed (it is not guaranteed that the
actual number is that big, though) */
- ib_uint64_t lsn_limit); /* in the case BUF_FLUSH_LIST all
+ ib_uint64_t lsn_limit); /*!< in the case BUF_FLUSH_LIST all
blocks whose oldest_modification is
smaller than this should be flushed
(if their number does not exceed
min_n), otherwise ignored */
-/**********************************************************************
+/******************************************************************//**
Waits until a flush batch of the given type ends */
UNIV_INTERN
void
buf_flush_wait_batch_end(
/*=====================*/
- enum buf_flush type); /* in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
-/************************************************************************
+ enum buf_flush type); /*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
+/********************************************************************//**
This function should be called at a mini-transaction commit, if a page was
modified in it. Puts the block to the list of modified blocks, if it not
already in it. */
@@ -103,46 +105,85 @@ UNIV_INLINE
void
buf_flush_note_modification(
/*========================*/
- buf_block_t* block, /* in: block which is modified */
- mtr_t* mtr); /* in: mtr */
-/************************************************************************
+ buf_block_t* block, /*!< in: block which is modified */
+ mtr_t* mtr); /*!< in: mtr */
+/********************************************************************//**
This function should be called when recovery has modified a buffer page. */
UNIV_INLINE
void
buf_flush_recv_note_modification(
/*=============================*/
- buf_block_t* block, /* in: block which is modified */
- ib_uint64_t start_lsn, /* in: start lsn of the first mtr in a
+ buf_block_t* block, /*!< in: block which is modified */
+ ib_uint64_t start_lsn, /*!< in: start lsn of the first mtr in a
set of mtr's */
- ib_uint64_t end_lsn); /* in: end lsn of the last mtr in the
+ ib_uint64_t end_lsn); /*!< in: end lsn of the last mtr in the
set of mtr's */
-/************************************************************************
+/********************************************************************//**
Returns TRUE if the file page block is immediately suitable for replacement,
-i.e., transition FILE_PAGE => NOT_USED allowed. */
+i.e., transition FILE_PAGE => NOT_USED allowed.
+@return TRUE if can replace immediately */
UNIV_INTERN
ibool
buf_flush_ready_for_replace(
/*========================*/
- /* out: TRUE if can replace immediately */
- buf_page_t* bpage); /* in: buffer control block, must be
+ buf_page_t* bpage); /*!< in: buffer control block, must be
buf_page_in_file(bpage) and in the LRU list */
+
+/** @brief Statistics for selecting flush rate based on redo log
+generation speed.
+
+These statistics are generated for heuristics used in estimating the
+rate at which we should flush the dirty blocks to avoid bursty IO
+activity. Note that the rate of flushing not only depends on how many
+dirty pages we have in the buffer pool but it is also a fucntion of
+how much redo the workload is generating and at what rate. */
+
+struct buf_flush_stat_struct
+{
+ ib_uint64_t redo; /**< amount of redo generated. */
+ ulint n_flushed; /**< number of pages flushed. */
+};
+
+/** Statistics for selecting flush rate of dirty pages. */
+typedef struct buf_flush_stat_struct buf_flush_stat_t;
+/*********************************************************************
+Update the historical stats that we are collecting for flush rate
+heuristics at the end of each interval. */
+UNIV_INTERN
+void
+buf_flush_stat_update(void);
+/*=======================*/
+/*********************************************************************
+Determines the fraction of dirty pages that need to be flushed based
+on the speed at which we generate redo log. Note that if redo log
+is generated at significant rate without a corresponding increase
+in the number of dirty pages (for example, an in-memory workload)
+it can cause IO bursts of flushing. This function implements heuristics
+to avoid this burstiness.
+@return number of dirty pages to be flushed / second */
+UNIV_INTERN
+ulint
+buf_flush_get_desired_flush_rate(void);
+/*==================================*/
+
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**********************************************************************
-Validates the flush list. */
+/******************************************************************//**
+Validates the flush list.
+@return TRUE if ok */
UNIV_INTERN
ibool
buf_flush_validate(void);
/*====================*/
- /* out: TRUE if ok */
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
-/* When buf_flush_free_margin is called, it tries to make this many blocks
+/** When buf_flush_free_margin is called, it tries to make this many blocks
available to replacement in the free list and at the end of the LRU list (to
make sure that a read-ahead batch can be read efficiently in a single
sweep). */
-
#define BUF_FLUSH_FREE_BLOCK_MARGIN (5 + BUF_READ_AHEAD_AREA)
+/** Extra margin to apply above BUF_FLUSH_FREE_BLOCK_MARGIN */
#define BUF_FLUSH_EXTRA_MARGIN (BUF_FLUSH_FREE_BLOCK_MARGIN / 4 + 100)
+#endif /* !UNIV_HOTBACKUP */
#ifndef UNIV_NONINL
#include "buf0flu.ic"
diff --git a/storage/xtradb/include/buf0flu.ic b/storage/xtradb/include/buf0flu.ic
index c466caae347..4ad0814f344 100644
--- a/storage/xtradb/include/buf0flu.ic
+++ b/storage/xtradb/include/buf0flu.ic
@@ -16,23 +16,25 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0flu.ic
The database buffer pool flush algorithm
Created 11/5/1995 Heikki Tuuri
*******************************************************/
+#ifndef UNIV_HOTBACKUP
#include "buf0buf.h"
#include "mtr0mtr.h"
-/************************************************************************
+/********************************************************************//**
Inserts a modified block into the flush list. */
UNIV_INTERN
void
buf_flush_insert_into_flush_list(
/*=============================*/
- buf_block_t* block); /* in/out: block which is modified */
-/************************************************************************
+ buf_block_t* block); /*!< in/out: block which is modified */
+/********************************************************************//**
Inserts a modified block into the flush list in the right sorted position.
This function is used by recovery, because there the modifications do not
necessarily come in the order of lsn's. */
@@ -40,9 +42,9 @@ UNIV_INTERN
void
buf_flush_insert_sorted_into_flush_list(
/*====================================*/
- buf_block_t* block); /* in/out: block which is modified */
+ buf_block_t* block); /*!< in/out: block which is modified */
-/************************************************************************
+/********************************************************************//**
This function should be called at a mini-transaction commit, if a page was
modified in it. Puts the block to the list of modified blocks, if it is not
already in it. */
@@ -50,8 +52,8 @@ UNIV_INLINE
void
buf_flush_note_modification(
/*========================*/
- buf_block_t* block, /* in: block which is modified */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* block, /*!< in: block which is modified */
+ mtr_t* mtr) /*!< in: mtr */
{
ibool use_LRU_mutex = FALSE;
@@ -97,16 +99,16 @@ buf_flush_note_modification(
mutex_exit(&LRU_list_mutex);
}
-/************************************************************************
+/********************************************************************//**
This function should be called when recovery has modified a buffer page. */
UNIV_INLINE
void
buf_flush_recv_note_modification(
/*=============================*/
- buf_block_t* block, /* in: block which is modified */
- ib_uint64_t start_lsn, /* in: start lsn of the first mtr in a
+ buf_block_t* block, /*!< in: block which is modified */
+ ib_uint64_t start_lsn, /*!< in: start lsn of the first mtr in a
set of mtr's */
- ib_uint64_t end_lsn) /* in: end lsn of the last mtr in the
+ ib_uint64_t end_lsn) /*!< in: end lsn of the last mtr in the
set of mtr's */
{
ibool use_LRU_mutex = FALSE;
@@ -150,3 +152,4 @@ buf_flush_recv_note_modification(
mutex_exit(&LRU_list_mutex);
mutex_exit(&(block->mutex));
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/buf0lru.h b/storage/xtradb/include/buf0lru.h
index 3fd534a215d..cde88824b64 100644
--- a/storage/xtradb/include/buf0lru.h
+++ b/storage/xtradb/include/buf0lru.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0lru.h
The database buffer pool LRU replacement algorithm
Created 11/5/1995 Heikki Tuuri
@@ -41,7 +42,7 @@ enum buf_lru_free_block_status {
BUF_LRU_NOT_FREED
};
-/**********************************************************************
+/******************************************************************//**
Tries to remove LRU flushed blocks from the end of the LRU list and put them
to the free list. This is beneficial for the efficiency of the insert buffer
operation, as flushed pages from non-unique non-clustered indexes are here
@@ -53,28 +54,27 @@ UNIV_INTERN
void
buf_LRU_try_free_flushed_blocks(void);
/*==================================*/
-/**********************************************************************
+/******************************************************************//**
Returns TRUE if less than 25 % of the buffer pool is available. This can be
used in heuristics to prevent huge transactions eating up the whole buffer
-pool for their locks. */
+pool for their locks.
+@return TRUE if less than 25 % of buffer pool left */
UNIV_INTERN
ibool
buf_LRU_buf_pool_running_out(void);
/*==============================*/
- /* out: TRUE if less than 25 % of buffer pool
- left */
/*#######################################################################
These are low-level functions
#########################################################################*/
-/* Minimum LRU list length for which the LRU_old pointer is defined */
-
+/** Minimum LRU list length for which the LRU_old pointer is defined */
#define BUF_LRU_OLD_MIN_LEN 80
+/** Maximum LRU list search length in buf_flush_LRU_recommendation() */
#define BUF_LRU_FREE_SEARCH_LEN (5 + 2 * BUF_READ_AHEAD_AREA)
-/**********************************************************************
+/******************************************************************//**
Invalidates all pages belonging to a given tablespace when we are deleting
the data file(s) of that tablespace. A PROBLEM: if readahead is being started,
what guarantees that it will not try to read in pages after this operation has
@@ -83,25 +83,25 @@ UNIV_INTERN
void
buf_LRU_invalidate_tablespace(
/*==========================*/
- ulint id); /* in: space id */
-/**********************************************************************
+ ulint id); /*!< in: space id */
+/******************************************************************//**
Gets the minimum LRU_position field for the blocks in an initial segment
(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
-guaranteed to be precise, because the ulint_clock may wrap around. */
+guaranteed to be precise, because the ulint_clock may wrap around.
+@return the limit; zero if could not determine it */
UNIV_INTERN
ulint
buf_LRU_get_recent_limit(void);
/*==========================*/
- /* out: the limit; zero if could not determine it */
-/************************************************************************
+/********************************************************************//**
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
UNIV_INTERN
void
buf_LRU_insert_zip_clean(
/*=====================*/
- buf_page_t* bpage); /* in: pointer to the block in question */
+ buf_page_t* bpage); /*!< in: pointer to the block in question */
-/**********************************************************************
+/******************************************************************//**
Try to free a block. If bpage is a descriptor of a compressed-only
page, the descriptor object will be freed as well.
@@ -111,30 +111,29 @@ accessible via bpage.
The caller must hold buf_pool_mutex and buf_page_get_mutex(bpage) and
release these two mutexes after the call. No other
-buf_page_get_mutex() may be held when calling this function. */
+buf_page_get_mutex() may be held when calling this function.
+@return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or
+BUF_LRU_NOT_FREED otherwise. */
UNIV_INTERN
enum buf_lru_free_block_status
buf_LRU_free_block(
/*===============*/
- /* out: BUF_LRU_FREED if freed,
- BUF_LRU_CANNOT_RELOCATE or
- BUF_LRU_NOT_FREED otherwise. */
- buf_page_t* bpage, /* in: block to be freed */
- ibool zip, /* in: TRUE if should remove also the
+ buf_page_t* bpage, /*!< in: block to be freed */
+ ibool zip, /*!< in: TRUE if should remove also the
compressed page of an uncompressed page */
ibool* buf_pool_mutex_released,
- /* in: pointer to a variable that will
+ /*!< in: pointer to a variable that will
be assigned TRUE if buf_pool_mutex
was temporarily released, or NULL */
ibool have_LRU_mutex);
-/**********************************************************************
-Try to free a replaceable block. */
+/******************************************************************//**
+Try to free a replaceable block.
+@return TRUE if found and freed */
UNIV_INTERN
ibool
buf_LRU_search_and_free_block(
/*==========================*/
- /* out: TRUE if found and freed */
- ulint n_iterations); /* in: how many times this has been called
+ ulint n_iterations); /*!< in: how many times this has been called
repeatedly without result: a high value means
that we should search farther; if
n_iterations < 10, then we search
@@ -142,71 +141,69 @@ buf_LRU_search_and_free_block(
pages from the end of the LRU list; if
n_iterations < 5, then we will also search
n_iterations / 5 of the unzip_LRU list. */
-/**********************************************************************
+/******************************************************************//**
Returns a free block from the buf_pool. The block is taken off the
-free list. If it is empty, returns NULL. */
+free list. If it is empty, returns NULL.
+@return a free control block, or NULL if the buf_block->free list is empty */
UNIV_INTERN
buf_block_t*
buf_LRU_get_free_only(void);
/*=======================*/
- /* out: a free control block, or NULL
- if the buf_block->free list is empty */
-/**********************************************************************
+/******************************************************************//**
Returns a free block from the buf_pool. The block is taken off the
free list. If it is empty, blocks are moved from the end of the
-LRU list to the free list. */
+LRU list to the free list.
+@return the free control block, in state BUF_BLOCK_READY_FOR_USE */
UNIV_INTERN
buf_block_t*
buf_LRU_get_free_block(
/*===================*/
- /* out: the free control block,
- in state BUF_BLOCK_READY_FOR_USE */
- ulint zip_size); /* in: compressed page size in bytes,
+ ulint zip_size); /*!< in: compressed page size in bytes,
or 0 if uncompressed tablespace */
-/**********************************************************************
+/******************************************************************//**
Puts a block back to the free list. */
UNIV_INTERN
void
buf_LRU_block_free_non_file_page(
/*=============================*/
- buf_block_t* block, /* in: block, must not contain a file page */
+ buf_block_t* block, /*!< in: block, must not contain a file page */
ibool have_page_hash_mutex);
-/**********************************************************************
+/******************************************************************//**
Adds a block to the LRU list. */
UNIV_INTERN
void
buf_LRU_add_block(
/*==============*/
- buf_page_t* bpage, /* in: control block */
- ibool old); /* in: TRUE if should be put to the old
+ buf_page_t* bpage, /*!< in: control block */
+ ibool old); /*!< in: TRUE if should be put to the old
blocks in the LRU list, else put to the
start; if the LRU list is very short, added to
the start regardless of this parameter */
-/**********************************************************************
+/******************************************************************//**
Adds a block to the LRU list of decompressed zip pages. */
UNIV_INTERN
void
buf_unzip_LRU_add_block(
/*====================*/
- buf_block_t* block, /* in: control block */
- ibool old); /* in: TRUE if should be put to the end
+ buf_block_t* block, /*!< in: control block */
+ ibool old); /*!< in: TRUE if should be put to the end
of the list, else put to the start */
-/**********************************************************************
+/******************************************************************//**
Moves a block to the start of the LRU list. */
UNIV_INTERN
void
buf_LRU_make_block_young(
/*=====================*/
- buf_page_t* bpage); /* in: control block */
-/**********************************************************************
+ buf_page_t* bpage); /*!< in: control block */
+/******************************************************************//**
Moves a block to the end of the LRU list. */
UNIV_INTERN
void
buf_LRU_make_block_old(
/*===================*/
- buf_page_t* bpage); /* in: control block */
-/************************************************************************
+ buf_page_t* bpage); /*!< in: control block */
+/********************************************************************//**
Update the historical stats that we are collecting for LRU eviction
policy at the end of each interval. */
UNIV_INTERN
@@ -215,15 +212,16 @@ buf_LRU_stat_update(void);
/*=====================*/
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**************************************************************************
-Validates the LRU list. */
+/**********************************************************************//**
+Validates the LRU list.
+@return TRUE */
UNIV_INTERN
ibool
buf_LRU_validate(void);
/*==================*/
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Prints the LRU list. */
UNIV_INTERN
void
@@ -231,18 +229,18 @@ buf_LRU_print(void);
/*===============*/
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
-/**********************************************************************
+/** @brief Statistics for selecting the LRU list for eviction.
+
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
and page_zip_decompress() operations. Based on the statistics we decide
if we want to evict from buf_pool->unzip_LRU or buf_pool->LRU. */
-
-/** Statistics for selecting the LRU list for eviction. */
struct buf_LRU_stat_struct
{
ulint io; /**< Counter of buffer pool I/O operations. */
ulint unzip; /**< Counter of page_zip_decompress operations. */
};
+/** Statistics for selecting the LRU list for eviction. */
typedef struct buf_LRU_stat_struct buf_LRU_stat_t;
/** Current operation counters. Not protected by any mutex.
@@ -253,10 +251,10 @@ extern buf_LRU_stat_t buf_LRU_stat_cur;
Updated by buf_LRU_stat_update(). Protected by buf_pool_mutex. */
extern buf_LRU_stat_t buf_LRU_stat_sum;
-/************************************************************************
+/********************************************************************//**
Increments the I/O counter in buf_LRU_stat_cur. */
#define buf_LRU_stat_inc_io() buf_LRU_stat_cur.io++
-/************************************************************************
+/********************************************************************//**
Increments the page_zip_decompress() counter in buf_LRU_stat_cur. */
#define buf_LRU_stat_inc_unzip() buf_LRU_stat_cur.unzip++
diff --git a/storage/xtradb/include/buf0lru.ic b/storage/xtradb/include/buf0lru.ic
index f4c40e0b606..556f45d987f 100644
--- a/storage/xtradb/include/buf0lru.ic
+++ b/storage/xtradb/include/buf0lru.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0lru.ic
The database buffer replacement algorithm
Created 11/5/1995 Heikki Tuuri
diff --git a/storage/xtradb/include/buf0rea.h b/storage/xtradb/include/buf0rea.h
index 6d138a3a02b..b4d25e6fde0 100644
--- a/storage/xtradb/include/buf0rea.h
+++ b/storage/xtradb/include/buf0rea.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0rea.h
The database buffer read
Created 11/5/1995 Heikki Tuuri
@@ -28,22 +29,22 @@ Created 11/5/1995 Heikki Tuuri
#include "univ.i"
#include "buf0types.h"
-/************************************************************************
+/********************************************************************//**
High-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
released by the i/o-handler thread. Does a random read-ahead if it seems
-sensible. */
+sensible.
+@return number of page read requests issued: this can be greater than
+1 if read-ahead occurred */
UNIV_INTERN
ulint
buf_read_page(
/*==========*/
- /* out: number of page read requests issued: this can
- be > 1 if read-ahead occurred */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint offset);/* in: page number */
-/************************************************************************
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint offset);/*!< in: page number */
+/********************************************************************//**
Applies linear read-ahead if in the buf_pool the page is a border page of
a linear read-ahead area and all the pages in the area have been accessed.
Does not read any page if the read-ahead mechanism is not activated. Note
@@ -65,17 +66,17 @@ function must be written such that it cannot end up waiting for these
latches!
NOTE 3: the calling thread must want access to the page given: this rule is
set to prevent unintended read-aheads performed by ibuf routines, a situation
-which could result in a deadlock if the OS does not support asynchronous io. */
+which could result in a deadlock if the OS does not support asynchronous io.
+@return number of page read requests issued */
UNIV_INTERN
ulint
buf_read_ahead_linear(
/*==================*/
- /* out: number of page read requests issued */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint offset);/* in: page number of a page; NOTE: the current thread
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint offset);/*!< in: page number of a page; NOTE: the current thread
must want access to this page (see NOTE 3 above) */
-/************************************************************************
+/********************************************************************//**
Issues read requests for pages which the ibuf module wants to read in, in
order to contract the insert buffer tree. Technically, this function is like
a read-ahead function. */
@@ -83,54 +84,56 @@ UNIV_INTERN
void
buf_read_ibuf_merge_pages(
/*======================*/
- ibool sync, /* in: TRUE if the caller
+ ibool sync, /*!< in: TRUE if the caller
wants this function to wait
for the highest address page
to get read in, before this
function returns */
- const ulint* space_ids, /* in: array of space ids */
- const ib_int64_t* space_versions,/* in: the spaces must have
+ const ulint* space_ids, /*!< in: array of space ids */
+ const ib_int64_t* space_versions,/*!< in: the spaces must have
this version number
(timestamp), otherwise we
discard the read; we use this
to cancel reads if DISCARD +
IMPORT may have changed the
tablespace size */
- const ulint* page_nos, /* in: array of page numbers
+ const ulint* page_nos, /*!< in: array of page numbers
to read, with the highest page
number the last in the
array */
- ulint n_stored); /* in: number of elements
+ ulint n_stored); /*!< in: number of elements
in the arrays */
-/************************************************************************
+/********************************************************************//**
Issues read requests for pages which recovery wants to read in. */
UNIV_INTERN
void
buf_read_recv_pages(
/*================*/
- ibool sync, /* in: TRUE if the caller
+ ibool sync, /*!< in: TRUE if the caller
wants this function to wait
for the highest address page
to get read in, before this
function returns */
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in
bytes, or 0 */
- const ulint* page_nos, /* in: array of page numbers
+ const ulint* page_nos, /*!< in: array of page numbers
to read, with the highest page
number the last in the
array */
- ulint n_stored); /* in: number of page numbers
+ ulint n_stored); /*!< in: number of page numbers
in the array */
-/* The size in pages of the area which the read-ahead algorithms read if
+/** 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))
-/* Modes used in read-ahead */
+/** @name Modes used in read-ahead @{ */
+/** read only pages belonging to the insert buffer tree */
#define BUF_READ_IBUF_PAGES_ONLY 131
+/** read any page */
#define BUF_READ_ANY_PAGE 132
+/* @} */
#endif
diff --git a/storage/xtradb/include/buf0types.h b/storage/xtradb/include/buf0types.h
index f2721da85f9..e7167d716a0 100644
--- a/storage/xtradb/include/buf0types.h
+++ b/storage/xtradb/include/buf0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/buf0types.h
The database buffer pool global types for the directory
Created 11/17/1995 Heikki Tuuri
@@ -25,46 +26,55 @@ Created 11/17/1995 Heikki Tuuri
#ifndef buf0types_h
#define buf0types_h
+/** Buffer page (uncompressed or compressed) */
typedef struct buf_page_struct buf_page_t;
+/** Buffer block for which an uncompressed page exists */
typedef struct buf_block_struct buf_block_t;
+/** Buffer pool chunk comprising buf_block_t */
typedef struct buf_chunk_struct buf_chunk_t;
+/** Buffer pool comprising buf_chunk_t */
typedef struct buf_pool_struct buf_pool_t;
-/* The 'type' used of a buffer frame */
+/** A buffer frame. @see page_t */
typedef byte buf_frame_t;
-/* Flags for flush types */
+/** Flags for flush types */
enum buf_flush {
- BUF_FLUSH_LRU = 0,
- BUF_FLUSH_SINGLE_PAGE,
- BUF_FLUSH_LIST,
- BUF_FLUSH_N_TYPES /* index of last element + 1 */
+ BUF_FLUSH_LRU = 0, /*!< flush via the LRU list */
+ BUF_FLUSH_SINGLE_PAGE, /*!< flush a single page */
+ BUF_FLUSH_LIST, /*!< flush via the flush list
+ of dirty blocks */
+ BUF_FLUSH_N_TYPES /*!< index of last element + 1 */
};
-/* Flags for io_fix types */
+/** Flags for io_fix types */
enum buf_io_fix {
BUF_IO_NONE = 0, /**< no pending I/O */
BUF_IO_READ, /**< read pending */
BUF_IO_WRITE /**< write pending */
};
-/* Parameters of binary buddy system for compressed pages (buf0buddy.h) */
+/** Parameters of binary buddy system for compressed pages (buf0buddy.h) */
+/* @{ */
#if UNIV_WORD_SIZE <= 4 /* 32-bit system */
+/** Base-2 logarithm of the smallest buddy block size */
# define BUF_BUDDY_LOW_SHIFT 6
#else /* 64-bit system */
+/** Base-2 logarithm of the smallest buddy block size */
# define BUF_BUDDY_LOW_SHIFT 7
#endif
#define BUF_BUDDY_LOW (1 << BUF_BUDDY_LOW_SHIFT)
- /* minimum block size in the binary
+ /*!< minimum block size in the binary
buddy system; must be at least
sizeof(buf_page_t) */
#define BUF_BUDDY_SIZES (UNIV_PAGE_SIZE_SHIFT - BUF_BUDDY_LOW_SHIFT)
- /* number of buddy sizes */
+ /*!< number of buddy sizes */
-/* twice the maximum block size of the buddy system;
+/** twice the maximum block size of the buddy system;
the underlying memory is aligned by this amount:
this must be equal to UNIV_PAGE_SIZE */
#define BUF_BUDDY_HIGH (BUF_BUDDY_LOW << BUF_BUDDY_SIZES)
+/* @} */
#endif
diff --git a/storage/xtradb/include/data0data.h b/storage/xtradb/include/data0data.h
index 1190a7ae45a..f9fce3f3657 100644
--- a/storage/xtradb/include/data0data.h
+++ b/storage/xtradb/include/data0data.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/data0data.h
SQL data field and tuple
Created 5/30/1994 Heikki Tuuri
@@ -32,376 +33,375 @@ Created 5/30/1994 Heikki Tuuri
#include "mem0mem.h"
#include "dict0types.h"
+/** Storage for overflow data in a big record, that is, a clustered
+index record which needs external storage of data fields */
typedef struct big_rec_struct big_rec_t;
#ifdef UNIV_DEBUG
-/*************************************************************************
-Gets pointer to the type struct of SQL data field. */
+/*********************************************************************//**
+Gets pointer to the type struct of SQL data field.
+@return pointer to the type struct */
UNIV_INLINE
dtype_t*
dfield_get_type(
/*============*/
- /* out: pointer to the type struct */
- const dfield_t* field); /* in: SQL data field */
-/*************************************************************************
-Gets pointer to the data in a field. */
+ const dfield_t* field); /*!< in: SQL data field */
+/*********************************************************************//**
+Gets pointer to the data in a field.
+@return pointer to data */
UNIV_INLINE
void*
dfield_get_data(
/*============*/
- /* out: pointer to data */
- const dfield_t* field); /* in: field */
+ const dfield_t* field); /*!< in: field */
#else /* UNIV_DEBUG */
# define dfield_get_type(field) (&(field)->type)
# define dfield_get_data(field) ((field)->data)
#endif /* UNIV_DEBUG */
-/*************************************************************************
+/*********************************************************************//**
Sets the type struct of SQL data field. */
UNIV_INLINE
void
dfield_set_type(
/*============*/
- dfield_t* field, /* in: SQL data field */
- dtype_t* type); /* in: pointer to data type struct */
-/*************************************************************************
-Gets length of field data. */
+ dfield_t* field, /*!< in: SQL data field */
+ dtype_t* type); /*!< in: pointer to data type struct */
+/*********************************************************************//**
+Gets length of field data.
+@return length of data; UNIV_SQL_NULL if SQL null data */
UNIV_INLINE
ulint
dfield_get_len(
/*===========*/
- /* out: length of data; UNIV_SQL_NULL if
- SQL null data */
- const dfield_t* field); /* in: field */
-/*************************************************************************
+ const dfield_t* field); /*!< in: field */
+/*********************************************************************//**
Sets length in a field. */
UNIV_INLINE
void
dfield_set_len(
/*===========*/
- dfield_t* field, /* in: field */
- ulint len); /* in: length or UNIV_SQL_NULL */
-/*************************************************************************
-Determines if a field is SQL NULL */
+ dfield_t* field, /*!< in: field */
+ ulint len); /*!< in: length or UNIV_SQL_NULL */
+/*********************************************************************//**
+Determines if a field is SQL NULL
+@return nonzero if SQL null data */
UNIV_INLINE
ulint
dfield_is_null(
/*===========*/
- /* out: nonzero if SQL null data */
- const dfield_t* field); /* in: field */
-/*************************************************************************
-Determines if a field is externally stored */
+ const dfield_t* field); /*!< in: field */
+/*********************************************************************//**
+Determines if a field is externally stored
+@return nonzero if externally stored */
UNIV_INLINE
ulint
dfield_is_ext(
/*==========*/
- /* out: nonzero if externally stored */
- const dfield_t* field); /* in: field */
-/*************************************************************************
+ const dfield_t* field); /*!< in: field */
+/*********************************************************************//**
Sets the "external storage" flag */
UNIV_INLINE
void
dfield_set_ext(
/*===========*/
- dfield_t* field); /* in/out: field */
-/*************************************************************************
+ dfield_t* field); /*!< in/out: field */
+/*********************************************************************//**
Sets pointer to the data and length in a field. */
UNIV_INLINE
void
dfield_set_data(
/*============*/
- dfield_t* field, /* in: field */
- const void* data, /* in: data */
- ulint len); /* in: length or UNIV_SQL_NULL */
-/*************************************************************************
+ dfield_t* field, /*!< in: field */
+ const void* data, /*!< in: data */
+ ulint len); /*!< in: length or UNIV_SQL_NULL */
+/*********************************************************************//**
Sets a data field to SQL NULL. */
UNIV_INLINE
void
dfield_set_null(
/*============*/
- dfield_t* field); /* in/out: field */
-/**************************************************************************
+ dfield_t* field); /*!< in/out: field */
+/**********************************************************************//**
Writes an SQL null field full of zeros. */
UNIV_INLINE
void
data_write_sql_null(
/*================*/
- byte* data, /* in: pointer to a buffer of size len */
- ulint len); /* in: SQL null size in bytes */
-/*************************************************************************
+ byte* data, /*!< in: pointer to a buffer of size len */
+ ulint len); /*!< in: SQL null size in bytes */
+/*********************************************************************//**
Copies the data and len fields. */
UNIV_INLINE
void
dfield_copy_data(
/*=============*/
- dfield_t* field1, /* out: field to copy to */
- const dfield_t* field2);/* in: field to copy from */
-/*************************************************************************
+ dfield_t* field1, /*!< out: field to copy to */
+ const dfield_t* field2);/*!< in: field to copy from */
+/*********************************************************************//**
Copies a data field to another. */
UNIV_INLINE
void
dfield_copy(
/*========*/
- dfield_t* field1, /* out: field to copy to */
- const dfield_t* field2);/* in: field to copy from */
-/*************************************************************************
+ dfield_t* field1, /*!< out: field to copy to */
+ const dfield_t* field2);/*!< in: field to copy from */
+/*********************************************************************//**
Copies the data pointed to by a data field. */
UNIV_INLINE
void
dfield_dup(
/*=======*/
- dfield_t* field, /* in/out: data field */
- mem_heap_t* heap); /* in: memory heap where allocated */
-/*************************************************************************
-Tests if data length and content is equal for two dfields. */
+ dfield_t* field, /*!< in/out: data field */
+ mem_heap_t* heap); /*!< in: memory heap where allocated */
+/*********************************************************************//**
+Tests if data length and content is equal for two dfields.
+@return TRUE if equal */
UNIV_INLINE
ibool
dfield_datas_are_binary_equal(
/*==========================*/
- /* out: TRUE if equal */
- const dfield_t* field1, /* in: field */
- const dfield_t* field2);/* in: field */
-/*************************************************************************
-Tests if dfield data length and content is equal to the given. */
+ const dfield_t* field1, /*!< in: field */
+ const dfield_t* field2);/*!< in: field */
+/*********************************************************************//**
+Tests if dfield data length and content is equal to the given.
+@return TRUE if equal */
UNIV_INTERN
ibool
dfield_data_is_binary_equal(
/*========================*/
- /* out: TRUE if equal */
- const dfield_t* field, /* in: field */
- ulint len, /* in: data length or UNIV_SQL_NULL */
- const byte* data); /* in: data */
-/*************************************************************************
-Gets number of fields in a data tuple. */
+ const dfield_t* field, /*!< in: field */
+ ulint len, /*!< in: data length or UNIV_SQL_NULL */
+ const byte* data); /*!< in: data */
+/*********************************************************************//**
+Gets number of fields in a data tuple.
+@return number of fields */
UNIV_INLINE
ulint
dtuple_get_n_fields(
/*================*/
- /* out: number of fields */
- const dtuple_t* tuple); /* in: tuple */
+ const dtuple_t* tuple); /*!< in: tuple */
#ifdef UNIV_DEBUG
-/*************************************************************************
-Gets nth field of a tuple. */
+/*********************************************************************//**
+Gets nth field of a tuple.
+@return nth field */
UNIV_INLINE
dfield_t*
dtuple_get_nth_field(
/*=================*/
- /* out: nth field */
- const dtuple_t* tuple, /* in: tuple */
- ulint n); /* in: index of field */
+ const dtuple_t* tuple, /*!< in: tuple */
+ ulint n); /*!< in: index of field */
#else /* UNIV_DEBUG */
# define dtuple_get_nth_field(tuple, n) ((tuple)->fields + (n))
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Gets info bits in a data tuple. */
+/*********************************************************************//**
+Gets info bits in a data tuple.
+@return info bits */
UNIV_INLINE
ulint
dtuple_get_info_bits(
/*=================*/
- /* out: info bits */
- const dtuple_t* tuple); /* in: tuple */
-/*************************************************************************
+ const dtuple_t* tuple); /*!< in: tuple */
+/*********************************************************************//**
Sets info bits in a data tuple. */
UNIV_INLINE
void
dtuple_set_info_bits(
/*=================*/
- dtuple_t* tuple, /* in: tuple */
- ulint info_bits); /* in: info bits */
-/*************************************************************************
-Gets number of fields used in record comparisons. */
+ dtuple_t* tuple, /*!< in: tuple */
+ ulint info_bits); /*!< in: info bits */
+/*********************************************************************//**
+Gets number of fields used in record comparisons.
+@return number of fields used in comparisons in rem0cmp.* */
UNIV_INLINE
ulint
dtuple_get_n_fields_cmp(
/*====================*/
- /* out: number of fields used in comparisons
- in rem0cmp.* */
- const dtuple_t* tuple); /* in: tuple */
-/*************************************************************************
+ const dtuple_t* tuple); /*!< in: tuple */
+/*********************************************************************//**
Gets number of fields used in record comparisons. */
UNIV_INLINE
void
dtuple_set_n_fields_cmp(
/*====================*/
- dtuple_t* tuple, /* in: tuple */
- ulint n_fields_cmp); /* in: number of fields used in
+ dtuple_t* tuple, /*!< in: tuple */
+ ulint n_fields_cmp); /*!< in: number of fields used in
comparisons in rem0cmp.* */
-/**************************************************************
+/**********************************************************//**
Creates a data tuple to a memory heap. The default value for number
-of fields used in record comparisons for this tuple is n_fields. */
+of fields used in record comparisons for this tuple is n_fields.
+@return own: created tuple */
UNIV_INLINE
dtuple_t*
dtuple_create(
/*==========*/
- /* out, own: created tuple */
- mem_heap_t* heap, /* in: memory heap where the tuple
+ mem_heap_t* heap, /*!< in: memory heap where the tuple
is created */
- ulint n_fields); /* in: number of fields */
+ ulint n_fields); /*!< in: number of fields */
-/**************************************************************
+/**********************************************************//**
Wrap data fields in a tuple. The default value for number
-of fields used in record comparisons for this tuple is n_fields. */
+of fields used in record comparisons for this tuple is n_fields.
+@return data tuple */
UNIV_INLINE
const dtuple_t*
dtuple_from_fields(
/*===============*/
- /* out: data tuple */
- dtuple_t* tuple, /* in: storage for data tuple */
- const dfield_t* fields, /* in: fields */
- ulint n_fields); /* in: number of fields */
+ dtuple_t* tuple, /*!< in: storage for data tuple */
+ const dfield_t* fields, /*!< in: fields */
+ ulint n_fields); /*!< in: number of fields */
-/*************************************************************************
+/*********************************************************************//**
Sets number of fields used in a tuple. Normally this is set in
dtuple_create, but if you want later to set it smaller, you can use this. */
UNIV_INTERN
void
dtuple_set_n_fields(
/*================*/
- dtuple_t* tuple, /* in: tuple */
- ulint n_fields); /* in: number of fields */
-/*************************************************************************
+ dtuple_t* tuple, /*!< in: tuple */
+ ulint n_fields); /*!< in: number of fields */
+/*********************************************************************//**
Copies a data tuple to another. This is a shallow copy; if a deep copy
-is desired, dfield_dup() will have to be invoked on each field. */
+is desired, dfield_dup() will have to be invoked on each field.
+@return own: copy of tuple */
UNIV_INLINE
dtuple_t*
dtuple_copy(
/*========*/
- /* out, own: copy of tuple */
- const dtuple_t* tuple, /* in: tuple to copy from */
- mem_heap_t* heap); /* in: memory heap
+ const dtuple_t* tuple, /*!< in: tuple to copy from */
+ mem_heap_t* heap); /*!< in: memory heap
where the tuple is created */
-/**************************************************************
+/**********************************************************//**
The following function returns the sum of data lengths of a tuple. The space
-occupied by the field structs or the tuple struct is not counted. */
+occupied by the field structs or the tuple struct is not counted.
+@return sum of data lens */
UNIV_INLINE
ulint
dtuple_get_data_size(
/*=================*/
- /* out: sum of data lens */
- const dtuple_t* tuple); /* in: typed data tuple */
-/*************************************************************************
-Computes the number of externally stored fields in a data tuple. */
+ const dtuple_t* tuple, /*!< in: typed data tuple */
+ ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
+/*********************************************************************//**
+Computes the number of externally stored fields in a data tuple.
+@return number of fields */
UNIV_INLINE
ulint
dtuple_get_n_ext(
/*=============*/
- /* out: number of fields */
- const dtuple_t* tuple); /* in: tuple */
-/****************************************************************
-Compare two data tuples, respecting the collation of character fields. */
+ const dtuple_t* tuple); /*!< in: tuple */
+/************************************************************//**
+Compare two data tuples, respecting the collation of character fields.
+@return 1, 0 , -1 if tuple1 is greater, equal, less, respectively,
+than tuple2 */
UNIV_INTERN
int
dtuple_coll_cmp(
/*============*/
- /* out: 1, 0 , -1 if tuple1 is greater, equal,
- less, respectively, than tuple2 */
- const dtuple_t* tuple1, /* in: tuple 1 */
- const dtuple_t* tuple2);/* in: tuple 2 */
-/****************************************************************
-Folds a prefix given as the number of fields of a tuple. */
+ const dtuple_t* tuple1, /*!< in: tuple 1 */
+ const dtuple_t* tuple2);/*!< in: tuple 2 */
+/************************************************************//**
+Folds a prefix given as the number of fields of a tuple.
+@return the folded value */
UNIV_INLINE
ulint
dtuple_fold(
/*========*/
- /* out: the folded value */
- const dtuple_t* tuple, /* in: the tuple */
- ulint n_fields,/* in: number of complete fields to fold */
- ulint n_bytes,/* in: number of bytes to fold in an
+ const dtuple_t* tuple, /*!< in: the tuple */
+ ulint n_fields,/*!< in: number of complete fields to fold */
+ ulint n_bytes,/*!< in: number of bytes to fold in an
incomplete last field */
- dulint tree_id)/* in: index tree id */
+ dulint tree_id)/*!< in: index tree id */
__attribute__((pure));
-/***********************************************************************
+/*******************************************************************//**
Sets types of fields binary in a tuple. */
UNIV_INLINE
void
dtuple_set_types_binary(
/*====================*/
- dtuple_t* tuple, /* in: data tuple */
- ulint n); /* in: number of fields to set */
-/**************************************************************************
-Checks if a dtuple contains an SQL null value. */
+ dtuple_t* tuple, /*!< in: data tuple */
+ ulint n); /*!< in: number of fields to set */
+/**********************************************************************//**
+Checks if a dtuple contains an SQL null value.
+@return TRUE if some field is SQL null */
UNIV_INLINE
ibool
dtuple_contains_null(
/*=================*/
- /* out: TRUE if some field is SQL null */
- const dtuple_t* tuple); /* in: dtuple */
-/**************************************************************
-Checks that a data field is typed. Asserts an error if not. */
+ const dtuple_t* tuple); /*!< in: dtuple */
+/**********************************************************//**
+Checks that a data field is typed. Asserts an error if not.
+@return TRUE if ok */
UNIV_INTERN
ibool
dfield_check_typed(
/*===============*/
- /* out: TRUE if ok */
- const dfield_t* field); /* in: data field */
-/**************************************************************
-Checks that a data tuple is typed. Asserts an error if not. */
+ const dfield_t* field); /*!< in: data field */
+/**********************************************************//**
+Checks that a data tuple is typed. Asserts an error if not.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_check_typed(
/*===============*/
- /* out: TRUE if ok */
- const dtuple_t* tuple); /* in: tuple */
-/**************************************************************
-Checks that a data tuple is typed. */
+ const dtuple_t* tuple); /*!< in: tuple */
+/**********************************************************//**
+Checks that a data tuple is typed.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_check_typed_no_assert(
/*=========================*/
- /* out: TRUE if ok */
- const dtuple_t* tuple); /* in: tuple */
+ const dtuple_t* tuple); /*!< in: tuple */
#ifdef UNIV_DEBUG
-/**************************************************************
+/**********************************************************//**
Validates the consistency of a tuple which must be complete, i.e,
-all fields must have been set. */
+all fields must have been set.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtuple_validate(
/*============*/
- /* out: TRUE if ok */
- const dtuple_t* tuple); /* in: tuple */
+ const dtuple_t* tuple); /*!< in: tuple */
#endif /* UNIV_DEBUG */
-/*****************************************************************
+/*************************************************************//**
Pretty prints a dfield value according to its data type. */
UNIV_INTERN
void
dfield_print(
/*=========*/
- const dfield_t* dfield);/* in: dfield */
-/*****************************************************************
+ const dfield_t* dfield);/*!< in: dfield */
+/*************************************************************//**
Pretty prints a dfield value according to its data type. Also the hex string
is printed if a string contains non-printable characters. */
UNIV_INTERN
void
dfield_print_also_hex(
/*==================*/
- const dfield_t* dfield); /* in: dfield */
-/**************************************************************
+ const dfield_t* dfield); /*!< in: dfield */
+/**********************************************************//**
The following function prints the contents of a tuple. */
UNIV_INTERN
void
dtuple_print(
/*=========*/
- FILE* f, /* in: output stream */
- const dtuple_t* tuple); /* in: tuple */
-/******************************************************************
+ FILE* f, /*!< in: output stream */
+ const dtuple_t* tuple); /*!< in: tuple */
+/**************************************************************//**
Moves parts of long fields in entry to the big record vector so that
the size of tuple drops below the maximum record size allowed in the
database. Moves data only from those fields which are not necessary
-to determine uniquely the insertion place of the tuple in the index. */
+to determine uniquely the insertion place of the tuple in the index.
+@return own: created big record vector, NULL if we are not able to
+shorten the entry enough, i.e., if there are too many fixed-length or
+short fields in entry or the index is clustered */
UNIV_INTERN
big_rec_t*
dtuple_convert_big_rec(
/*===================*/
- /* out, own: created big record vector,
- NULL if we are not able to shorten
- the entry enough, i.e., if there are
- too many fixed-length or short fields
- in entry or the index is clustered */
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in/out: index entry */
- ulint* n_ext); /* in/out: number of
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in/out: index entry */
+ ulint* n_ext); /*!< in/out: number of
externally stored columns */
-/******************************************************************
+/**************************************************************//**
Puts back to entry the data stored in vector. Note that to ensure the
fields in entry can accommodate the data, vector must have been created
from entry with dtuple_convert_big_rec. */
@@ -409,68 +409,71 @@ UNIV_INTERN
void
dtuple_convert_back_big_rec(
/*========================*/
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in: entry whose data was put to vector */
- big_rec_t* vector);/* in, own: big rec vector; it is
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in: entry whose data was put to vector */
+ big_rec_t* vector);/*!< in, own: big rec vector; it is
freed in this function */
-/******************************************************************
+/**************************************************************//**
Frees the memory in a big rec vector. */
UNIV_INLINE
void
dtuple_big_rec_free(
/*================*/
- big_rec_t* vector); /* in, own: big rec vector; it is
+ big_rec_t* vector); /*!< in, own: big rec vector; it is
freed in this function */
/*######################################################################*/
-/* Structure for an SQL data field */
+/** Structure for an SQL data field */
struct dfield_struct{
- void* data; /* pointer to data */
- unsigned ext:1; /* TRUE=externally stored, FALSE=local */
- unsigned len:32; /* data length; UNIV_SQL_NULL if SQL null */
- dtype_t type; /* type of data */
+ void* data; /*!< pointer to data */
+ unsigned ext:1; /*!< TRUE=externally stored, FALSE=local */
+ unsigned len:32; /*!< data length; UNIV_SQL_NULL if SQL null */
+ dtype_t type; /*!< type of data */
};
+/** Structure for an SQL data tuple of fields (logical record) */
struct dtuple_struct {
- ulint info_bits; /* info bits of an index record:
+ ulint info_bits; /*!< info bits of an index record:
the default is 0; this field is used
if an index record is built from
a data tuple */
- ulint n_fields; /* number of fields in dtuple */
- ulint n_fields_cmp; /* number of fields which should
+ ulint n_fields; /*!< number of fields in dtuple */
+ ulint n_fields_cmp; /*!< number of fields which should
be used in comparison services
of rem0cmp.*; the index search
is performed by comparing only these
fields, others are ignored; the
default value in dtuple creation is
the same value as n_fields */
- dfield_t* fields; /* fields */
+ dfield_t* fields; /*!< fields */
UT_LIST_NODE_T(dtuple_t) tuple_list;
- /* data tuples can be linked into a
+ /*!< data tuples can be linked into a
list using this field */
#ifdef UNIV_DEBUG
- ulint magic_n;
+ ulint magic_n; /*!< magic number, used in
+ debug assertions */
+/** Value of dtuple_struct::magic_n */
# define DATA_TUPLE_MAGIC_N 65478679
#endif /* UNIV_DEBUG */
};
-/* A slot for a field in a big rec vector */
-
+/** A slot for a field in a big rec vector */
typedef struct big_rec_field_struct big_rec_field_t;
+/** A slot for a field in a big rec vector */
struct big_rec_field_struct {
- ulint field_no; /* field number in record */
- ulint len; /* stored data len */
- const void* data; /* stored data */
+ ulint field_no; /*!< field number in record */
+ ulint len; /*!< stored data length, in bytes */
+ const void* data; /*!< stored data */
};
-/* Storage format for overflow data in a big record, that is, a record
-which needs external storage of data fields */
-
+/** Storage format for overflow data in a big record, that is, a
+clustered index record which needs external storage of data fields */
struct big_rec_struct {
- mem_heap_t* heap; /* memory heap from which allocated */
- ulint n_fields; /* number of stored fields */
- big_rec_field_t* fields; /* stored fields */
+ mem_heap_t* heap; /*!< memory heap from which
+ allocated */
+ ulint n_fields; /*!< number of stored fields */
+ big_rec_field_t*fields; /*!< stored fields */
};
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/data0data.ic b/storage/xtradb/include/data0data.ic
index f11dbd9fce6..da79aa33702 100644
--- a/storage/xtradb/include/data0data.ic
+++ b/storage/xtradb/include/data0data.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/data0data.ic
SQL data field and tuple
Created 5/30/1994 Heikki Tuuri
@@ -26,16 +27,19 @@ Created 5/30/1994 Heikki Tuuri
#include "ut0rnd.h"
#ifdef UNIV_DEBUG
+/** Dummy variable to catch access to uninitialized fields. In the
+debug version, dtuple_create() will make all fields of dtuple_t point
+to data_error. */
extern byte data_error;
-/*************************************************************************
-Gets pointer to the type struct of SQL data field. */
+/*********************************************************************//**
+Gets pointer to the type struct of SQL data field.
+@return pointer to the type struct */
UNIV_INLINE
dtype_t*
dfield_get_type(
/*============*/
- /* out: pointer to the type struct */
- const dfield_t* field) /* in: SQL data field */
+ const dfield_t* field) /*!< in: SQL data field */
{
ut_ad(field);
@@ -43,14 +47,14 @@ dfield_get_type(
}
#endif /* UNIV_DEBUG */
-/*************************************************************************
+/*********************************************************************//**
Sets the type struct of SQL data field. */
UNIV_INLINE
void
dfield_set_type(
/*============*/
- dfield_t* field, /* in: SQL data field */
- dtype_t* type) /* in: pointer to data type struct */
+ dfield_t* field, /*!< in: SQL data field */
+ dtype_t* type) /*!< in: pointer to data type struct */
{
ut_ad(field && type);
@@ -58,14 +62,14 @@ dfield_set_type(
}
#ifdef UNIV_DEBUG
-/*************************************************************************
-Gets pointer to the data in a field. */
+/*********************************************************************//**
+Gets pointer to the data in a field.
+@return pointer to data */
UNIV_INLINE
void*
dfield_get_data(
/*============*/
- /* out: pointer to data */
- const dfield_t* field) /* in: field */
+ const dfield_t* field) /*!< in: field */
{
ut_ad(field);
ut_ad((field->len == UNIV_SQL_NULL)
@@ -75,15 +79,14 @@ dfield_get_data(
}
#endif /* UNIV_DEBUG */
-/*************************************************************************
-Gets length of field data. */
+/*********************************************************************//**
+Gets length of field data.
+@return length of data; UNIV_SQL_NULL if SQL null data */
UNIV_INLINE
ulint
dfield_get_len(
/*===========*/
- /* out: length of data; UNIV_SQL_NULL if
- SQL null data */
- const dfield_t* field) /* in: field */
+ const dfield_t* field) /*!< in: field */
{
ut_ad(field);
ut_ad((field->len == UNIV_SQL_NULL)
@@ -92,14 +95,14 @@ dfield_get_len(
return(field->len);
}
-/*************************************************************************
+/*********************************************************************//**
Sets length in a field. */
UNIV_INLINE
void
dfield_set_len(
/*===========*/
- dfield_t* field, /* in: field */
- ulint len) /* in: length or UNIV_SQL_NULL */
+ dfield_t* field, /*!< in: field */
+ ulint len) /*!< in: length or UNIV_SQL_NULL */
{
ut_ad(field);
#ifdef UNIV_VALGRIND_DEBUG
@@ -110,56 +113,56 @@ dfield_set_len(
field->len = len;
}
-/*************************************************************************
-Determines if a field is SQL NULL */
+/*********************************************************************//**
+Determines if a field is SQL NULL
+@return nonzero if SQL null data */
UNIV_INLINE
ulint
dfield_is_null(
/*===========*/
- /* out: nonzero if SQL null data */
- const dfield_t* field) /* in: field */
+ const dfield_t* field) /*!< in: field */
{
ut_ad(field);
return(field->len == UNIV_SQL_NULL);
}
-/*************************************************************************
-Determines if a field is externally stored */
+/*********************************************************************//**
+Determines if a field is externally stored
+@return nonzero if externally stored */
UNIV_INLINE
ulint
dfield_is_ext(
/*==========*/
- /* out: nonzero if externally stored */
- const dfield_t* field) /* in: field */
+ const dfield_t* field) /*!< in: field */
{
ut_ad(field);
return(UNIV_UNLIKELY(field->ext));
}
-/*************************************************************************
+/*********************************************************************//**
Sets the "external storage" flag */
UNIV_INLINE
void
dfield_set_ext(
/*===========*/
- dfield_t* field) /* in/out: field */
+ dfield_t* field) /*!< in/out: field */
{
ut_ad(field);
field->ext = 1;
}
-/*************************************************************************
+/*********************************************************************//**
Sets pointer to the data and length in a field. */
UNIV_INLINE
void
dfield_set_data(
/*============*/
- dfield_t* field, /* in: field */
- const void* data, /* in: data */
- ulint len) /* in: length or UNIV_SQL_NULL */
+ dfield_t* field, /*!< in: field */
+ const void* data, /*!< in: data */
+ ulint len) /*!< in: length or UNIV_SQL_NULL */
{
ut_ad(field);
@@ -171,25 +174,25 @@ dfield_set_data(
field->len = len;
}
-/*************************************************************************
+/*********************************************************************//**
Sets a data field to SQL NULL. */
UNIV_INLINE
void
dfield_set_null(
/*============*/
- dfield_t* field) /* in/out: field */
+ dfield_t* field) /*!< in/out: field */
{
dfield_set_data(field, NULL, UNIV_SQL_NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Copies the data and len fields. */
UNIV_INLINE
void
dfield_copy_data(
/*=============*/
- dfield_t* field1, /* out: field to copy to */
- const dfield_t* field2) /* in: field to copy from */
+ dfield_t* field1, /*!< out: field to copy to */
+ const dfield_t* field2) /*!< in: field to copy from */
{
ut_ad(field1 && field2);
@@ -198,26 +201,26 @@ dfield_copy_data(
field1->ext = field2->ext;
}
-/*************************************************************************
+/*********************************************************************//**
Copies a data field to another. */
UNIV_INLINE
void
dfield_copy(
/*========*/
- dfield_t* field1, /* out: field to copy to */
- const dfield_t* field2) /* in: field to copy from */
+ dfield_t* field1, /*!< out: field to copy to */
+ const dfield_t* field2) /*!< in: field to copy from */
{
*field1 = *field2;
}
-/*************************************************************************
+/*********************************************************************//**
Copies the data pointed to by a data field. */
UNIV_INLINE
void
dfield_dup(
/*=======*/
- dfield_t* field, /* in/out: data field */
- mem_heap_t* heap) /* in: memory heap where allocated */
+ dfield_t* field, /*!< in/out: data field */
+ mem_heap_t* heap) /*!< in: memory heap where allocated */
{
if (!dfield_is_null(field)) {
UNIV_MEM_ASSERT_RW(field->data, field->len);
@@ -225,15 +228,15 @@ dfield_dup(
}
}
-/*************************************************************************
-Tests if data length and content is equal for two dfields. */
+/*********************************************************************//**
+Tests if data length and content is equal for two dfields.
+@return TRUE if equal */
UNIV_INLINE
ibool
dfield_datas_are_binary_equal(
/*==========================*/
- /* out: TRUE if equal */
- const dfield_t* field1, /* in: field */
- const dfield_t* field2) /* in: field */
+ const dfield_t* field1, /*!< in: field */
+ const dfield_t* field2) /*!< in: field */
{
ulint len;
@@ -244,57 +247,56 @@ dfield_datas_are_binary_equal(
|| !memcmp(field1->data, field2->data, len)));
}
-/*************************************************************************
-Gets info bits in a data tuple. */
+/*********************************************************************//**
+Gets info bits in a data tuple.
+@return info bits */
UNIV_INLINE
ulint
dtuple_get_info_bits(
/*=================*/
- /* out: info bits */
- const dtuple_t* tuple) /* in: tuple */
+ const dtuple_t* tuple) /*!< in: tuple */
{
ut_ad(tuple);
return(tuple->info_bits);
}
-/*************************************************************************
+/*********************************************************************//**
Sets info bits in a data tuple. */
UNIV_INLINE
void
dtuple_set_info_bits(
/*=================*/
- dtuple_t* tuple, /* in: tuple */
- ulint info_bits) /* in: info bits */
+ dtuple_t* tuple, /*!< in: tuple */
+ ulint info_bits) /*!< in: info bits */
{
ut_ad(tuple);
tuple->info_bits = info_bits;
}
-/*************************************************************************
-Gets number of fields used in record comparisons. */
+/*********************************************************************//**
+Gets number of fields used in record comparisons.
+@return number of fields used in comparisons in rem0cmp.* */
UNIV_INLINE
ulint
dtuple_get_n_fields_cmp(
/*====================*/
- /* out: number of fields used in comparisons
- in rem0cmp.* */
- const dtuple_t* tuple) /* in: tuple */
+ const dtuple_t* tuple) /*!< in: tuple */
{
ut_ad(tuple);
return(tuple->n_fields_cmp);
}
-/*************************************************************************
+/*********************************************************************//**
Sets number of fields used in record comparisons. */
UNIV_INLINE
void
dtuple_set_n_fields_cmp(
/*====================*/
- dtuple_t* tuple, /* in: tuple */
- ulint n_fields_cmp) /* in: number of fields used in
+ dtuple_t* tuple, /*!< in: tuple */
+ ulint n_fields_cmp) /*!< in: number of fields used in
comparisons in rem0cmp.* */
{
ut_ad(tuple);
@@ -303,14 +305,14 @@ dtuple_set_n_fields_cmp(
tuple->n_fields_cmp = n_fields_cmp;
}
-/*************************************************************************
-Gets number of fields in a data tuple. */
+/*********************************************************************//**
+Gets number of fields in a data tuple.
+@return number of fields */
UNIV_INLINE
ulint
dtuple_get_n_fields(
/*================*/
- /* out: number of fields */
- const dtuple_t* tuple) /* in: tuple */
+ const dtuple_t* tuple) /*!< in: tuple */
{
ut_ad(tuple);
@@ -318,15 +320,15 @@ dtuple_get_n_fields(
}
#ifdef UNIV_DEBUG
-/*************************************************************************
-Gets nth field of a tuple. */
+/*********************************************************************//**
+Gets nth field of a tuple.
+@return nth field */
UNIV_INLINE
dfield_t*
dtuple_get_nth_field(
/*=================*/
- /* out: nth field */
- const dtuple_t* tuple, /* in: tuple */
- ulint n) /* in: index of field */
+ const dtuple_t* tuple, /*!< in: tuple */
+ ulint n) /*!< in: index of field */
{
ut_ad(tuple);
ut_ad(n < tuple->n_fields);
@@ -335,17 +337,17 @@ dtuple_get_nth_field(
}
#endif /* UNIV_DEBUG */
-/**************************************************************
+/**********************************************************//**
Creates a data tuple to a memory heap. The default value for number
-of fields used in record comparisons for this tuple is n_fields. */
+of fields used in record comparisons for this tuple is n_fields.
+@return own: created tuple */
UNIV_INLINE
dtuple_t*
dtuple_create(
/*==========*/
- /* out, own: created tuple */
- mem_heap_t* heap, /* in: memory heap where the tuple
+ mem_heap_t* heap, /*!< in: memory heap where the tuple
is created */
- ulint n_fields) /* in: number of fields */
+ ulint n_fields) /*!< in: number of fields */
{
dtuple_t* tuple;
@@ -380,17 +382,17 @@ dtuple_create(
return(tuple);
}
-/**************************************************************
+/**********************************************************//**
Wrap data fields in a tuple. The default value for number
-of fields used in record comparisons for this tuple is n_fields. */
+of fields used in record comparisons for this tuple is n_fields.
+@return data tuple */
UNIV_INLINE
const dtuple_t*
dtuple_from_fields(
/*===============*/
- /* out: data tuple */
- dtuple_t* tuple, /* in: storage for data tuple */
- const dfield_t* fields, /* in: fields */
- ulint n_fields) /* in: number of fields */
+ dtuple_t* tuple, /*!< in: storage for data tuple */
+ const dfield_t* fields, /*!< in: fields */
+ ulint n_fields) /*!< in: number of fields */
{
tuple->info_bits = 0;
tuple->n_fields = tuple->n_fields_cmp = n_fields;
@@ -400,16 +402,16 @@ dtuple_from_fields(
return(tuple);
}
-/*************************************************************************
+/*********************************************************************//**
Copies a data tuple to another. This is a shallow copy; if a deep copy
-is desired, dfield_dup() will have to be invoked on each field. */
+is desired, dfield_dup() will have to be invoked on each field.
+@return own: copy of tuple */
UNIV_INLINE
dtuple_t*
dtuple_copy(
/*========*/
- /* out, own: copy of tuple */
- const dtuple_t* tuple, /* in: tuple to copy from */
- mem_heap_t* heap) /* in: memory heap
+ const dtuple_t* tuple, /*!< in: tuple to copy from */
+ mem_heap_t* heap) /*!< in: memory heap
where the tuple is created */
{
ulint n_fields = dtuple_get_n_fields(tuple);
@@ -424,16 +426,17 @@ dtuple_copy(
return(new_tuple);
}
-/**************************************************************
+/**********************************************************//**
The following function returns the sum of data lengths of a tuple. The space
occupied by the field structs or the tuple struct is not counted. Neither
-is possible space in externally stored parts of the field. */
+is possible space in externally stored parts of the field.
+@return sum of data lengths */
UNIV_INLINE
ulint
dtuple_get_data_size(
/*=================*/
- /* out: sum of data lengths */
- const dtuple_t* tuple) /* in: typed data tuple */
+ const dtuple_t* tuple, /*!< in: typed data tuple */
+ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
const dfield_t* field;
ulint n_fields;
@@ -452,7 +455,8 @@ dtuple_get_data_size(
len = dfield_get_len(field);
if (len == UNIV_SQL_NULL) {
- len = dtype_get_sql_null_size(dfield_get_type(field));
+ len = dtype_get_sql_null_size(dfield_get_type(field),
+ comp);
}
sum += len;
@@ -461,14 +465,14 @@ dtuple_get_data_size(
return(sum);
}
-/*************************************************************************
-Computes the number of externally stored fields in a data tuple. */
+/*********************************************************************//**
+Computes the number of externally stored fields in a data tuple.
+@return number of externally stored fields */
UNIV_INLINE
ulint
dtuple_get_n_ext(
/*=============*/
- /* out: number of externally stored fields */
- const dtuple_t* tuple) /* in: tuple */
+ const dtuple_t* tuple) /*!< in: tuple */
{
ulint n_ext = 0;
ulint n_fields = tuple->n_fields;
@@ -485,14 +489,14 @@ dtuple_get_n_ext(
return(n_ext);
}
-/***********************************************************************
+/*******************************************************************//**
Sets types of fields binary in a tuple. */
UNIV_INLINE
void
dtuple_set_types_binary(
/*====================*/
- dtuple_t* tuple, /* in: data tuple */
- ulint n) /* in: number of fields to set */
+ dtuple_t* tuple, /*!< in: data tuple */
+ ulint n) /*!< in: number of fields to set */
{
dtype_t* dfield_type;
ulint i;
@@ -503,18 +507,18 @@ dtuple_set_types_binary(
}
}
-/****************************************************************
-Folds a prefix given as the number of fields of a tuple. */
+/************************************************************//**
+Folds a prefix given as the number of fields of a tuple.
+@return the folded value */
UNIV_INLINE
ulint
dtuple_fold(
/*========*/
- /* out: the folded value */
- const dtuple_t* tuple, /* in: the tuple */
- ulint n_fields,/* in: number of complete fields to fold */
- ulint n_bytes,/* in: number of bytes to fold in an
+ const dtuple_t* tuple, /*!< in: the tuple */
+ ulint n_fields,/*!< in: number of complete fields to fold */
+ ulint n_bytes,/*!< in: number of bytes to fold in an
incomplete last field */
- dulint tree_id)/* in: index tree id */
+ dulint tree_id)/*!< in: index tree id */
{
const dfield_t* field;
ulint i;
@@ -559,26 +563,26 @@ dtuple_fold(
return(fold);
}
-/**************************************************************************
+/**********************************************************************//**
Writes an SQL null field full of zeros. */
UNIV_INLINE
void
data_write_sql_null(
/*================*/
- byte* data, /* in: pointer to a buffer of size len */
- ulint len) /* in: SQL null size in bytes */
+ byte* data, /*!< in: pointer to a buffer of size len */
+ ulint len) /*!< in: SQL null size in bytes */
{
memset(data, 0, len);
}
-/**************************************************************************
-Checks if a dtuple contains an SQL null value. */
+/**********************************************************************//**
+Checks if a dtuple contains an SQL null value.
+@return TRUE if some field is SQL null */
UNIV_INLINE
ibool
dtuple_contains_null(
/*=================*/
- /* out: TRUE if some field is SQL null */
- const dtuple_t* tuple) /* in: dtuple */
+ const dtuple_t* tuple) /*!< in: dtuple */
{
ulint n;
ulint i;
@@ -595,13 +599,13 @@ dtuple_contains_null(
return(FALSE);
}
-/******************************************************************
+/**************************************************************//**
Frees the memory in a big rec vector. */
UNIV_INLINE
void
dtuple_big_rec_free(
/*================*/
- big_rec_t* vector) /* in, own: big rec vector; it is
+ big_rec_t* vector) /*!< in, own: big rec vector; it is
freed in this function */
{
mem_heap_free(vector->heap);
diff --git a/storage/xtradb/include/data0type.h b/storage/xtradb/include/data0type.h
index 1f10878984b..a73bed3a9f5 100644
--- a/storage/xtradb/include/data0type.h
+++ b/storage/xtradb/include/data0type.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/data0type.h
Data types
Created 1/16/1996 Heikki Tuuri
@@ -167,228 +168,240 @@ SQL null*/
store the charset-collation number; one byte is left unused, though */
#define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6
-/*************************************************************************
-Gets the MySQL type code from a dtype. */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
+Gets the MySQL type code from a dtype.
+@return MySQL type code; this is NOT an InnoDB type code! */
UNIV_INLINE
ulint
dtype_get_mysql_type(
/*=================*/
- /* out: MySQL type code; this is NOT an InnoDB
- type code! */
- const dtype_t* type); /* in: type struct */
-/*************************************************************************
+ const dtype_t* type); /*!< in: type struct */
+/*********************************************************************//**
Determine how many bytes the first n characters of the given string occupy.
If the string is shorter than n characters, returns the number of bytes
-the characters in the string occupy. */
+the characters in the string occupy.
+@return length of the prefix, in bytes */
UNIV_INTERN
ulint
dtype_get_at_most_n_mbchars(
/*========================*/
- /* out: length of the prefix,
- in bytes */
- ulint prtype, /* in: precise type */
- ulint mbminlen, /* in: minimum length of a
+ ulint prtype, /*!< in: precise type */
+ ulint mbminlen, /*!< in: minimum length of a
multi-byte character */
- ulint mbmaxlen, /* in: maximum length of a
+ ulint mbmaxlen, /*!< in: maximum length of a
multi-byte character */
- ulint prefix_len, /* in: length of the requested
+ ulint prefix_len, /*!< in: length of the requested
prefix, in characters, multiplied by
dtype_get_mbmaxlen(dtype) */
- ulint data_len, /* in: length of str (in bytes) */
- const char* str); /* in: the string whose prefix
+ ulint data_len, /*!< in: length of str (in bytes) */
+ const char* str); /*!< in: the string whose prefix
length is being determined */
-/*************************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************************//**
Checks if a data main type is a string type. Also a BLOB is considered a
-string type. */
+string type.
+@return TRUE if string type */
UNIV_INTERN
ibool
dtype_is_string_type(
/*=================*/
- /* out: TRUE if string type */
- ulint mtype); /* in: InnoDB main data type code: DATA_CHAR, ... */
-/*************************************************************************
+ ulint mtype); /*!< in: InnoDB main data type code: DATA_CHAR, ... */
+/*********************************************************************//**
Checks if a type is a binary string type. Note that for tables created with
< 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For
-those DATA_BLOB columns this function currently returns FALSE. */
+those DATA_BLOB columns this function currently returns FALSE.
+@return TRUE if binary string type */
UNIV_INTERN
ibool
dtype_is_binary_string_type(
/*========================*/
- /* out: TRUE if binary string type */
- ulint mtype, /* in: main data type */
- ulint prtype);/* in: precise type */
-/*************************************************************************
+ ulint mtype, /*!< in: main data type */
+ ulint prtype);/*!< in: precise type */
+/*********************************************************************//**
Checks if a type is a non-binary string type. That is, dtype_is_string_type is
TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created
with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
-For those DATA_BLOB columns this function currently returns TRUE. */
+For those DATA_BLOB columns this function currently returns TRUE.
+@return TRUE if non-binary string type */
UNIV_INTERN
ibool
dtype_is_non_binary_string_type(
/*============================*/
- /* out: TRUE if non-binary string type */
- ulint mtype, /* in: main data type */
- ulint prtype);/* in: precise type */
-/*************************************************************************
+ ulint mtype, /*!< in: main data type */
+ ulint prtype);/*!< in: precise type */
+/*********************************************************************//**
Sets a data type structure. */
UNIV_INLINE
void
dtype_set(
/*======*/
- dtype_t* type, /* in: type struct to init */
- ulint mtype, /* in: main data type */
- ulint prtype, /* in: precise type */
- ulint len); /* in: precision of type */
-/*************************************************************************
+ dtype_t* type, /*!< in: type struct to init */
+ ulint mtype, /*!< in: main data type */
+ ulint prtype, /*!< in: precise type */
+ ulint len); /*!< in: precision of type */
+/*********************************************************************//**
Copies a data type structure. */
UNIV_INLINE
void
dtype_copy(
/*=======*/
- dtype_t* type1, /* in: type struct to copy to */
- const dtype_t* type2); /* in: type struct to copy from */
-/*************************************************************************
-Gets the SQL main data type. */
+ dtype_t* type1, /*!< in: type struct to copy to */
+ const dtype_t* type2); /*!< in: type struct to copy from */
+/*********************************************************************//**
+Gets the SQL main data type.
+@return SQL main data type */
UNIV_INLINE
ulint
dtype_get_mtype(
/*============*/
- const dtype_t* type);
-/*************************************************************************
-Gets the precise data type. */
+ const dtype_t* type); /*!< in: data type */
+/*********************************************************************//**
+Gets the precise data type.
+@return precise data type */
UNIV_INLINE
ulint
dtype_get_prtype(
/*=============*/
- const dtype_t* type);
-/*************************************************************************
+ const dtype_t* type); /*!< in: data type */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
Compute the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
dtype_get_mblen(
/*============*/
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type (and collation) */
- ulint* mbminlen, /* out: minimum length of a
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type (and collation) */
+ ulint* mbminlen, /*!< out: minimum length of a
multi-byte character */
- ulint* mbmaxlen); /* out: maximum length of a
+ ulint* mbmaxlen); /*!< out: maximum length of a
multi-byte character */
-/*************************************************************************
-Gets the MySQL charset-collation code for MySQL string types. */
+/*********************************************************************//**
+Gets the MySQL charset-collation code for MySQL string types.
+@return MySQL charset-collation code */
UNIV_INLINE
ulint
dtype_get_charset_coll(
/*===================*/
- ulint prtype);/* in: precise data type */
-/*************************************************************************
+ ulint prtype);/*!< in: precise data type */
+/*********************************************************************//**
Forms a precise type from the < 4.1.2 format precise type plus the
-charset-collation code. */
+charset-collation code.
+@return precise type, including the charset-collation code */
UNIV_INTERN
ulint
dtype_form_prtype(
/*==============*/
- ulint old_prtype, /* in: the MySQL type code and the flags
+ ulint old_prtype, /*!< in: the MySQL type code and the flags
DATA_BINARY_TYPE etc. */
- ulint charset_coll); /* in: MySQL charset-collation code */
-/*************************************************************************
+ ulint charset_coll); /*!< in: MySQL charset-collation code */
+/*********************************************************************//**
Determines if a MySQL string type is a subset of UTF-8. This function
may return false negatives, in case further character-set collation
-codes are introduced in MySQL later. */
+codes are introduced in MySQL later.
+@return TRUE if a subset of UTF-8 */
UNIV_INLINE
ibool
dtype_is_utf8(
/*==========*/
- /* out: TRUE if a subset of UTF-8 */
- ulint prtype);/* in: precise data type */
-/*************************************************************************
-Gets the type length. */
+ ulint prtype);/*!< in: precise data type */
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************************//**
+Gets the type length.
+@return fixed length of the type, in bytes, or 0 if variable-length */
UNIV_INLINE
ulint
dtype_get_len(
/*==========*/
- const dtype_t* type);
-/*************************************************************************
-Gets the minimum length of a character, in bytes. */
+ const dtype_t* type); /*!< in: data type */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
+Gets the minimum length of a character, in bytes.
+@return minimum length of a char, in bytes, or 0 if this is not a
+character type */
UNIV_INLINE
ulint
dtype_get_mbminlen(
/*===============*/
- /* out: minimum length of a char, in bytes,
- or 0 if this is not a character type */
- const dtype_t* type); /* in: type */
-/*************************************************************************
-Gets the maximum length of a character, in bytes. */
+ const dtype_t* type); /*!< in: type */
+/*********************************************************************//**
+Gets the maximum length of a character, in bytes.
+@return maximum length of a char, in bytes, or 0 if this is not a
+character type */
UNIV_INLINE
ulint
dtype_get_mbmaxlen(
/*===============*/
- /* out: maximum length of a char, in bytes,
- or 0 if this is not a character type */
- const dtype_t* type); /* in: type */
-/*************************************************************************
-Gets the padding character code for the type. */
+ const dtype_t* type); /*!< in: type */
+/*********************************************************************//**
+Gets the padding character code for the type.
+@return padding character code, or ULINT_UNDEFINED if no padding specified */
UNIV_INLINE
ulint
dtype_get_pad_char(
/*===============*/
- /* out: padding character code, or
- ULINT_UNDEFINED if no padding specified */
- ulint mtype, /* in: main type */
- ulint prtype); /* in: precise type */
-/***************************************************************************
-Returns the size of a fixed size data type, 0 if not a fixed size type. */
+ ulint mtype, /*!< in: main type */
+ ulint prtype); /*!< in: precise type */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************************//**
+Returns the size of a fixed size data type, 0 if not a fixed size type.
+@return fixed size, or 0 */
UNIV_INLINE
ulint
dtype_get_fixed_size_low(
/*=====================*/
- /* out: fixed size, or 0 */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- ulint len, /* in: length */
- ulint mbminlen, /* in: minimum length of a multibyte char */
- ulint mbmaxlen); /* in: maximum length of a multibyte char */
-/***************************************************************************
-Returns the minimum size of a data type. */
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ ulint len, /*!< in: length */
+ ulint mbminlen, /*!< in: minimum length of a multibyte char */
+ ulint mbmaxlen, /*!< in: maximum length of a multibyte char */
+ ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
+Returns the minimum size of a data type.
+@return minimum size */
UNIV_INLINE
ulint
dtype_get_min_size_low(
/*===================*/
- /* out: minimum size */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- ulint len, /* in: length */
- ulint mbminlen, /* in: minimum length of a multibyte char */
- ulint mbmaxlen); /* in: maximum length of a multibyte char */
-/***************************************************************************
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ ulint len, /*!< in: length */
+ ulint mbminlen, /*!< in: minimum length of a multibyte char */
+ ulint mbmaxlen); /*!< in: maximum length of a multibyte char */
+/***********************************************************************//**
Returns the maximum size of a data type. Note: types in system tables may be
-incomplete and return incorrect information. */
+incomplete and return incorrect information.
+@return maximum size */
UNIV_INLINE
ulint
dtype_get_max_size_low(
/*===================*/
- /* out: maximum size */
- ulint mtype, /* in: main type */
- ulint len); /* in: length */
-/***************************************************************************
+ ulint mtype, /*!< in: main type */
+ ulint len); /*!< in: length */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************************//**
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a type.
-For fixed length types it is the fixed length of the type, otherwise 0. */
+For fixed length types it is the fixed length of the type, otherwise 0.
+@return SQL null storage size in ROW_FORMAT=REDUNDANT */
UNIV_INLINE
ulint
dtype_get_sql_null_size(
/*====================*/
- /* out: SQL null storage size
- in ROW_FORMAT=REDUNDANT */
- const dtype_t* type); /* in: type */
-/**************************************************************************
+ const dtype_t* type, /*!< in: type */
+ ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. */
UNIV_INLINE
void
dtype_read_for_order_and_null_size(
/*===============================*/
- dtype_t* type, /* in: type struct */
- const byte* buf); /* in: buffer for the stored order info */
-/**************************************************************************
+ dtype_t* type, /*!< in: type struct */
+ const byte* buf); /*!< in: buffer for the stored order info */
+/**********************************************************************//**
Stores for a type the information which determines its alphabetical ordering
and the storage size of an SQL NULL value. This is the >= 4.1.x storage
format. */
@@ -396,13 +409,13 @@ UNIV_INLINE
void
dtype_new_store_for_order_and_null_size(
/*====================================*/
- byte* buf, /* in: buffer for
+ byte* buf, /*!< in: buffer for
DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
bytes where we store the info */
- const dtype_t* type, /* in: type struct */
- ulint prefix_len);/* in: prefix length to
+ const dtype_t* type, /*!< in: type struct */
+ ulint prefix_len);/*!< in: prefix length to
replace type->len, or 0 */
-/**************************************************************************
+/**********************************************************************//**
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. This is the 4.1.x storage
format. */
@@ -410,24 +423,25 @@ UNIV_INLINE
void
dtype_new_read_for_order_and_null_size(
/*===================================*/
- dtype_t* type, /* in: type struct */
- const byte* buf); /* in: buffer for stored type order info */
+ dtype_t* type, /*!< in: type struct */
+ const byte* buf); /*!< in: buffer for stored type order info */
+#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
-Validates a data type structure. */
+/*********************************************************************//**
+Validates a data type structure.
+@return TRUE if ok */
UNIV_INTERN
ibool
dtype_validate(
/*===========*/
- /* out: TRUE if ok */
- const dtype_t* type); /* in: type struct to validate */
-/*************************************************************************
+ const dtype_t* type); /*!< in: type struct to validate */
+/*********************************************************************//**
Prints a data type structure. */
UNIV_INTERN
void
dtype_print(
/*========*/
- const dtype_t* type); /* in: type */
+ const dtype_t* type); /*!< in: type */
/* Structure for an SQL data type.
If you add fields to this structure, be sure to initialize them everywhere.
@@ -438,8 +452,8 @@ dtype_new_read_for_order_and_null_size()
sym_tab_add_null_lit() */
struct dtype_struct{
- unsigned mtype:8; /* main data type */
- unsigned prtype:24; /* precise type; MySQL data
+ unsigned mtype:8; /*!< main data type */
+ unsigned prtype:24; /*!< precise type; MySQL data
type, charset code, flags to
indicate nullability,
signedness, whether this is a
@@ -449,7 +463,7 @@ struct dtype_struct{
/* the remaining fields do not affect alphabetical ordering: */
- unsigned len:16; /* length; for MySQL data this
+ unsigned len:16; /*!< length; for MySQL data this
is field->pack_length(),
except that for a >= 5.0.3
type true VARCHAR this is the
@@ -457,11 +471,12 @@ struct dtype_struct{
string data (in addition to
the string, MySQL uses 1 or 2
bytes to store the string length) */
-
- unsigned mbminlen:2; /* minimum length of a
+#ifndef UNIV_HOTBACKUP
+ unsigned mbminlen:2; /*!< minimum length of a
character, in bytes */
- unsigned mbmaxlen:3; /* maximum length of a
+ unsigned mbmaxlen:3; /*!< maximum length of a
character, in bytes */
+#endif /* !UNIV_HOTBACKUP */
};
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/data0type.ic b/storage/xtradb/include/data0type.ic
index d4c1080bebe..240b4288f39 100644
--- a/storage/xtradb/include/data0type.ic
+++ b/storage/xtradb/include/data0type.ic
@@ -16,36 +16,39 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/data0type.ic
Data types
Created 1/16/1996 Heikki Tuuri
*******************************************************/
#include "mach0data.h"
-#include "ha_prototypes.h"
+#ifndef UNIV_HOTBACKUP
+# include "ha_prototypes.h"
-/*************************************************************************
-Gets the MySQL charset-collation code for MySQL string types. */
+/*********************************************************************//**
+Gets the MySQL charset-collation code for MySQL string types.
+@return MySQL charset-collation code */
UNIV_INLINE
ulint
dtype_get_charset_coll(
/*===================*/
- ulint prtype) /* in: precise data type */
+ ulint prtype) /*!< in: precise data type */
{
return((prtype >> 16) & 0xFFUL);
}
-/*************************************************************************
+/*********************************************************************//**
Determines if a MySQL string type is a subset of UTF-8. This function
may return false negatives, in case further character-set collation
-codes are introduced in MySQL later. */
+codes are introduced in MySQL later.
+@return TRUE if a subset of UTF-8 */
UNIV_INLINE
ibool
dtype_is_utf8(
/*==========*/
- /* out: TRUE if a subset of UTF-8 */
- ulint prtype) /* in: precise data type */
+ ulint prtype) /*!< in: precise data type */
{
/* These codes have been copied from strings/ctype-extra.c
and strings/ctype-utf8.c. */
@@ -61,55 +64,49 @@ dtype_is_utf8(
return(FALSE);
}
-/*************************************************************************
-Gets the MySQL type code from a dtype. */
+/*********************************************************************//**
+Gets the MySQL type code from a dtype.
+@return MySQL type code; this is NOT an InnoDB type code! */
UNIV_INLINE
ulint
dtype_get_mysql_type(
/*=================*/
- /* out: MySQL type code; this is NOT an InnoDB
- type code! */
- const dtype_t* type) /* in: type struct */
+ const dtype_t* type) /*!< in: type struct */
{
return(type->prtype & 0xFFUL);
}
-/*************************************************************************
+/*********************************************************************//**
Compute the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
dtype_get_mblen(
/*============*/
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type (and collation) */
- ulint* mbminlen, /* out: minimum length of a
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type (and collation) */
+ ulint* mbminlen, /*!< out: minimum length of a
multi-byte character */
- ulint* mbmaxlen) /* out: maximum length of a
+ ulint* mbmaxlen) /*!< out: maximum length of a
multi-byte character */
{
if (dtype_is_string_type(mtype)) {
-#ifndef UNIV_HOTBACKUP
innobase_get_cset_width(dtype_get_charset_coll(prtype),
mbminlen, mbmaxlen);
ut_ad(*mbminlen <= *mbmaxlen);
ut_ad(*mbminlen <= 2); /* mbminlen in dtype_t is 0..3 */
ut_ad(*mbmaxlen < 1 << 3); /* mbmaxlen in dtype_t is 0..7 */
-#else /* !UNIV_HOTBACKUP */
- ut_a(mtype <= DATA_BINARY);
- *mbminlen = *mbmaxlen = 1;
-#endif /* !UNIV_HOTBACKUP */
} else {
*mbminlen = *mbmaxlen = 0;
}
}
-/*************************************************************************
+/*********************************************************************//**
Compute the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
dtype_set_mblen(
/*============*/
- dtype_t* type) /* in/out: type */
+ dtype_t* type) /*!< in/out: type */
{
ulint mbminlen;
ulint mbmaxlen;
@@ -120,17 +117,20 @@ dtype_set_mblen(
ut_ad(dtype_validate(type));
}
+#else /* !UNIV_HOTBACKUP */
+# define dtype_set_mblen(type) (void) 0
+#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
+/*********************************************************************//**
Sets a data type structure. */
UNIV_INLINE
void
dtype_set(
/*======*/
- dtype_t* type, /* in: type struct to init */
- ulint mtype, /* in: main data type */
- ulint prtype, /* in: precise type */
- ulint len) /* in: precision of type */
+ dtype_t* type, /*!< in: type struct to init */
+ ulint mtype, /*!< in: main data type */
+ ulint prtype, /*!< in: precise type */
+ ulint len) /*!< in: precision of type */
{
ut_ad(type);
ut_ad(mtype <= DATA_MTYPE_MAX);
@@ -142,96 +142,99 @@ dtype_set(
dtype_set_mblen(type);
}
-/*************************************************************************
+/*********************************************************************//**
Copies a data type structure. */
UNIV_INLINE
void
dtype_copy(
/*=======*/
- dtype_t* type1, /* in: type struct to copy to */
- const dtype_t* type2) /* in: type struct to copy from */
+ dtype_t* type1, /*!< in: type struct to copy to */
+ const dtype_t* type2) /*!< in: type struct to copy from */
{
*type1 = *type2;
ut_ad(dtype_validate(type1));
}
-/*************************************************************************
-Gets the SQL main data type. */
+/*********************************************************************//**
+Gets the SQL main data type.
+@return SQL main data type */
UNIV_INLINE
ulint
dtype_get_mtype(
/*============*/
- const dtype_t* type)
+ const dtype_t* type) /*!< in: data type */
{
ut_ad(type);
return(type->mtype);
}
-/*************************************************************************
-Gets the precise data type. */
+/*********************************************************************//**
+Gets the precise data type.
+@return precise data type */
UNIV_INLINE
ulint
dtype_get_prtype(
/*=============*/
- const dtype_t* type)
+ const dtype_t* type) /*!< in: data type */
{
ut_ad(type);
return(type->prtype);
}
-/*************************************************************************
-Gets the type length. */
+/*********************************************************************//**
+Gets the type length.
+@return fixed length of the type, in bytes, or 0 if variable-length */
UNIV_INLINE
ulint
dtype_get_len(
/*==========*/
- const dtype_t* type)
+ const dtype_t* type) /*!< in: data type */
{
ut_ad(type);
return(type->len);
}
-/*************************************************************************
-Gets the minimum length of a character, in bytes. */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
+Gets the minimum length of a character, in bytes.
+@return minimum length of a char, in bytes, or 0 if this is not a
+character type */
UNIV_INLINE
ulint
dtype_get_mbminlen(
/*===============*/
- /* out: minimum length of a char, in bytes,
- or 0 if this is not a character type */
- const dtype_t* type) /* in: type */
+ const dtype_t* type) /*!< in: type */
{
ut_ad(type);
return(type->mbminlen);
}
-/*************************************************************************
-Gets the maximum length of a character, in bytes. */
+/*********************************************************************//**
+Gets the maximum length of a character, in bytes.
+@return maximum length of a char, in bytes, or 0 if this is not a
+character type */
UNIV_INLINE
ulint
dtype_get_mbmaxlen(
/*===============*/
- /* out: maximum length of a char, in bytes,
- or 0 if this is not a character type */
- const dtype_t* type) /* in: type */
+ const dtype_t* type) /*!< in: type */
{
ut_ad(type);
return(type->mbmaxlen);
}
-/*************************************************************************
-Gets the padding character code for a type. */
+/*********************************************************************//**
+Gets the padding character code for a type.
+@return padding character code, or ULINT_UNDEFINED if no padding specified */
UNIV_INLINE
ulint
dtype_get_pad_char(
/*===============*/
- /* out: padding character code, or
- ULINT_UNDEFINED if no padding specified */
- ulint mtype, /* in: main type */
- ulint prtype) /* in: precise type */
+ ulint mtype, /*!< in: main type */
+ ulint prtype) /*!< in: precise type */
{
switch (mtype) {
case DATA_FIXBINARY:
@@ -262,7 +265,7 @@ dtype_get_pad_char(
}
}
-/**************************************************************************
+/**********************************************************************//**
Stores for a type the information which determines its alphabetical ordering
and the storage size of an SQL NULL value. This is the >= 4.1.x storage
format. */
@@ -270,11 +273,11 @@ UNIV_INLINE
void
dtype_new_store_for_order_and_null_size(
/*====================================*/
- byte* buf, /* in: buffer for
+ byte* buf, /*!< in: buffer for
DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
bytes where we store the info */
- const dtype_t* type, /* in: type struct */
- ulint prefix_len)/* in: prefix length to
+ const dtype_t* type, /*!< in: type struct */
+ ulint prefix_len)/*!< in: prefix length to
replace type->len, or 0 */
{
#if 6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
@@ -307,7 +310,7 @@ dtype_new_store_for_order_and_null_size(
}
}
-/**************************************************************************
+/**********************************************************************//**
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. This is the < 4.1.x
storage format. */
@@ -315,8 +318,8 @@ UNIV_INLINE
void
dtype_read_for_order_and_null_size(
/*===============================*/
- dtype_t* type, /* in: type struct */
- const byte* buf) /* in: buffer for stored type order info */
+ dtype_t* type, /*!< in: type struct */
+ const byte* buf) /*!< in: buffer for stored type order info */
{
#if 4 != DATA_ORDER_NULL_TYPE_BUF_SIZE
# error "4 != DATA_ORDER_NULL_TYPE_BUF_SIZE"
@@ -336,7 +339,7 @@ dtype_read_for_order_and_null_size(
dtype_set_mblen(type);
}
-/**************************************************************************
+/**********************************************************************//**
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. This is the >= 4.1.x
storage format. */
@@ -344,8 +347,8 @@ UNIV_INLINE
void
dtype_new_read_for_order_and_null_size(
/*===================================*/
- dtype_t* type, /* in: type struct */
- const byte* buf) /* in: buffer for stored type order info */
+ dtype_t* type, /*!< in: type struct */
+ const byte* buf) /*!< in: buffer for stored type order info */
{
ulint charset_coll;
@@ -385,19 +388,21 @@ dtype_new_read_for_order_and_null_size(
}
dtype_set_mblen(type);
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************************
-Returns the size of a fixed size data type, 0 if not a fixed size type. */
+/***********************************************************************//**
+Returns the size of a fixed size data type, 0 if not a fixed size type.
+@return fixed size, or 0 */
UNIV_INLINE
ulint
dtype_get_fixed_size_low(
/*=====================*/
- /* out: fixed size, or 0 */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- ulint len, /* in: length */
- ulint mbminlen, /* in: minimum length of a multibyte char */
- ulint mbmaxlen) /* in: maximum length of a multibyte char */
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ ulint len, /*!< in: length */
+ ulint mbminlen, /*!< in: minimum length of a multibyte char */
+ ulint mbmaxlen, /*!< in: maximum length of a multibyte char */
+ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
switch (mtype) {
case DATA_SYS:
@@ -424,14 +429,12 @@ dtype_get_fixed_size_low(
case DATA_DOUBLE:
return(len);
case DATA_MYSQL:
+#ifndef UNIV_HOTBACKUP
if (prtype & DATA_BINARY_TYPE) {
return(len);
+ } else if (!comp) {
+ return(len);
} else {
-#ifdef UNIV_HOTBACKUP
- if (mbminlen == mbmaxlen) {
- return(len);
- }
-#else /* UNIV_HOTBACKUP */
/* We play it safe here and ask MySQL for
mbminlen and mbmaxlen. Although
mbminlen and mbmaxlen are
@@ -463,8 +466,10 @@ dtype_get_fixed_size_low(
if (mbminlen == mbmaxlen) {
return(len);
}
-#endif /* !UNIV_HOTBACKUP */
}
+#else /* !UNIV_HOTBACKUP */
+ return(len);
+#endif /* !UNIV_HOTBACKUP */
/* fall through for variable-length charsets */
case DATA_VARCHAR:
case DATA_BINARY:
@@ -479,18 +484,19 @@ dtype_get_fixed_size_low(
return(0);
}
-/***************************************************************************
-Returns the minimum size of a data type. */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
+Returns the minimum size of a data type.
+@return minimum size */
UNIV_INLINE
ulint
dtype_get_min_size_low(
/*===================*/
- /* out: minimum size */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- ulint len, /* in: length */
- ulint mbminlen, /* in: minimum length of a multibyte char */
- ulint mbmaxlen) /* in: maximum length of a multibyte char */
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ ulint len, /*!< in: length */
+ ulint mbminlen, /*!< in: minimum length of a multibyte char */
+ ulint mbmaxlen) /*!< in: maximum length of a multibyte char */
{
switch (mtype) {
case DATA_SYS:
@@ -538,16 +544,16 @@ dtype_get_min_size_low(
return(0);
}
-/***************************************************************************
+/***********************************************************************//**
Returns the maximum size of a data type. Note: types in system tables may be
-incomplete and return incorrect information. */
+incomplete and return incorrect information.
+@return maximum size */
UNIV_INLINE
ulint
dtype_get_max_size_low(
/*===================*/
- /* out: maximum size */
- ulint mtype, /* in: main type */
- ulint len) /* in: length */
+ ulint mtype, /*!< in: main type */
+ ulint len) /*!< in: length */
{
switch (mtype) {
case DATA_SYS:
@@ -570,18 +576,24 @@ dtype_get_max_size_low(
return(ULINT_MAX);
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************************
+/***********************************************************************//**
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a type.
-For fixed length types it is the fixed length of the type, otherwise 0. */
+For fixed length types it is the fixed length of the type, otherwise 0.
+@return SQL null storage size in ROW_FORMAT=REDUNDANT */
UNIV_INLINE
ulint
dtype_get_sql_null_size(
/*====================*/
- /* out: SQL null storage size
- in ROW_FORMAT=REDUNDANT */
- const dtype_t* type) /* in: type */
+ const dtype_t* type, /*!< in: type */
+ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
+#ifndef UNIV_HOTBACKUP
return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
- type->mbminlen, type->mbmaxlen));
+ type->mbminlen, type->mbmaxlen, comp));
+#else /* !UNIV_HOTBACKUP */
+ return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
+ 0, 0, 0));
+#endif /* !UNIV_HOTBACKUP */
}
diff --git a/storage/xtradb/include/data0types.h b/storage/xtradb/include/data0types.h
index 9e536478d68..04e835bc401 100644
--- a/storage/xtradb/include/data0types.h
+++ b/storage/xtradb/include/data0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/data0types.h
Some type definitions
Created 9/21/2000 Heikki Tuuri
diff --git a/storage/xtradb/include/db0err.h b/storage/xtradb/include/db0err.h
index d6d2a9785a5..23898583b72 100644
--- a/storage/xtradb/include/db0err.h
+++ b/storage/xtradb/include/db0err.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/db0err.h
Global error codes for the database
Created 5/24/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/dict0boot.h b/storage/xtradb/include/dict0boot.h
index e1556bdb16e..51d37ee98d1 100644
--- a/storage/xtradb/include/dict0boot.h
+++ b/storage/xtradb/include/dict0boot.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0boot.h
Data dictionary creation and booting
Created 4/18/1996 Heikki Tuuri
@@ -36,54 +37,53 @@ Created 4/18/1996 Heikki Tuuri
typedef byte dict_hdr_t;
-/**************************************************************************
-Gets a pointer to the dictionary header and x-latches its page. */
+/**********************************************************************//**
+Gets a pointer to the dictionary header and x-latches its page.
+@return pointer to the dictionary header, page x-latched */
UNIV_INTERN
dict_hdr_t*
dict_hdr_get(
/*=========*/
- /* out: pointer to the dictionary header,
- page x-latched */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
-Returns a new row, table, index, or tree id. */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
+Returns a new row, table, index, or tree id.
+@return the new id */
UNIV_INTERN
dulint
dict_hdr_get_new_id(
/*================*/
- /* out: the new id */
- ulint type); /* in: DICT_HDR_ROW_ID, ... */
-/**************************************************************************
-Returns a new row id. */
+ ulint type); /*!< in: DICT_HDR_ROW_ID, ... */
+/**********************************************************************//**
+Returns a new row id.
+@return the new id */
UNIV_INLINE
dulint
dict_sys_get_new_row_id(void);
/*=========================*/
- /* out: the new id */
-/**************************************************************************
-Reads a row id from a record or other 6-byte stored form. */
+/**********************************************************************//**
+Reads a row id from a record or other 6-byte stored form.
+@return row id */
UNIV_INLINE
dulint
dict_sys_read_row_id(
/*=================*/
- /* out: row id */
- byte* field); /* in: record field */
-/**************************************************************************
+ byte* field); /*!< in: record field */
+/**********************************************************************//**
Writes a row id to a record or other 6-byte stored form. */
UNIV_INLINE
void
dict_sys_write_row_id(
/*==================*/
- byte* field, /* in: record field */
- dulint row_id);/* in: row id */
-/*********************************************************************
+ byte* field, /*!< in: record field */
+ dulint row_id);/*!< in: row id */
+/*****************************************************************//**
Initializes the data dictionary memory structures when the database is
started. This function is also called when the data dictionary is created. */
UNIV_INTERN
void
dict_boot(void);
/*===========*/
-/*********************************************************************
+/*****************************************************************//**
Creates and initializes the data dictionary at the database creation. */
UNIV_INTERN
void
diff --git a/storage/xtradb/include/dict0boot.ic b/storage/xtradb/include/dict0boot.ic
index 9b45f9e84be..d5f372e38c4 100644
--- a/storage/xtradb/include/dict0boot.ic
+++ b/storage/xtradb/include/dict0boot.ic
@@ -16,13 +16,14 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0boot.ic
Data dictionary creation and booting
Created 4/18/1996 Heikki Tuuri
*******************************************************/
-/**************************************************************************
+/**********************************************************************//**
Writes the current value of the row id counter to the dictionary header file
page. */
UNIV_INTERN
@@ -31,13 +32,13 @@ dict_hdr_flush_row_id(void);
/*=======================*/
-/**************************************************************************
-Returns a new row id. */
+/**********************************************************************//**
+Returns a new row id.
+@return the new id */
UNIV_INLINE
dulint
dict_sys_get_new_row_id(void)
/*=========================*/
- /* out: the new id */
{
dulint id;
@@ -57,14 +58,14 @@ dict_sys_get_new_row_id(void)
return(id);
}
-/**************************************************************************
-Reads a row id from a record or other 6-byte stored form. */
+/**********************************************************************//**
+Reads a row id from a record or other 6-byte stored form.
+@return row id */
UNIV_INLINE
dulint
dict_sys_read_row_id(
/*=================*/
- /* out: row id */
- byte* field) /* in: record field */
+ byte* field) /*!< in: record field */
{
#if DATA_ROW_ID_LEN != 6
# error "DATA_ROW_ID_LEN != 6"
@@ -73,14 +74,14 @@ dict_sys_read_row_id(
return(mach_read_from_6(field));
}
-/**************************************************************************
+/**********************************************************************//**
Writes a row id to a record or other 6-byte stored form. */
UNIV_INLINE
void
dict_sys_write_row_id(
/*==================*/
- byte* field, /* in: record field */
- dulint row_id) /* in: row id */
+ byte* field, /*!< in: record field */
+ dulint row_id) /*!< in: row id */
{
#if DATA_ROW_ID_LEN != 6
# error "DATA_ROW_ID_LEN != 6"
diff --git a/storage/xtradb/include/dict0crea.h b/storage/xtradb/include/dict0crea.h
index 9ac3e408f1f..3107d771d88 100644
--- a/storage/xtradb/include/dict0crea.h
+++ b/storage/xtradb/include/dict0crea.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0crea.h
Database object creation
Created 1/8/1996 Heikki Tuuri
@@ -32,94 +33,92 @@ Created 1/8/1996 Heikki Tuuri
#include "row0types.h"
#include "mtr0mtr.h"
-/*************************************************************************
-Creates a table create graph. */
+/*********************************************************************//**
+Creates a table create graph.
+@return own: table create node */
UNIV_INTERN
tab_node_t*
tab_create_graph_create(
/*====================*/
- /* out, own: table create node */
- dict_table_t* table, /* in: table to create, built as a memory data
+ dict_table_t* table, /*!< in: table to create, built as a memory data
structure */
- mem_heap_t* heap); /* in: heap where created */
-/*************************************************************************
-Creates an index create graph. */
+ mem_heap_t* heap); /*!< in: heap where created */
+/*********************************************************************//**
+Creates an index create graph.
+@return own: index create node */
UNIV_INTERN
ind_node_t*
ind_create_graph_create(
/*====================*/
- /* out, own: index create node */
- dict_index_t* index, /* in: index to create, built as a memory data
+ dict_index_t* index, /*!< in: index to create, built as a memory data
structure */
- mem_heap_t* heap); /* in: heap where created */
-/***************************************************************
-Creates a table. This is a high-level function used in SQL execution graphs. */
+ mem_heap_t* heap); /*!< in: heap where created */
+/***********************************************************//**
+Creates a table. This is a high-level function used in SQL execution graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
dict_create_table_step(
/*===================*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/***************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/***********************************************************//**
Creates an index. This is a high-level function used in SQL execution
-graphs. */
+graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
dict_create_index_step(
/*===================*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/***********************************************************************
-Truncates the index tree associated with a row in SYS_INDEXES table. */
+ que_thr_t* thr); /*!< in: query thread */
+/*******************************************************************//**
+Truncates the index tree associated with a row in SYS_INDEXES table.
+@return new root page number, or FIL_NULL on failure */
UNIV_INTERN
ulint
dict_truncate_index_tree(
/*=====================*/
- /* out: new root page number, or
- FIL_NULL on failure */
- dict_table_t* table, /* in: the table the index belongs to */
- ulint space, /* in: 0=truncate,
+ dict_table_t* table, /*!< in: the table the index belongs to */
+ ulint space, /*!< in: 0=truncate,
nonzero=create the index tree in the
given tablespace */
- btr_pcur_t* pcur, /* in/out: persistent cursor pointing to
+ btr_pcur_t* pcur, /*!< in/out: persistent cursor pointing to
record in the clustered index of
SYS_INDEXES table. The cursor may be
repositioned in this call. */
- mtr_t* mtr); /* in: mtr having the latch
+ mtr_t* mtr); /*!< in: mtr having the latch
on the record page. The mtr may be
committed and restarted in this call. */
-/***********************************************************************
+/*******************************************************************//**
Drops the index tree associated with a row in SYS_INDEXES table. */
UNIV_INTERN
void
dict_drop_index_tree(
/*=================*/
- rec_t* rec, /* in/out: record in the clustered index
+ rec_t* rec, /*!< in/out: record in the clustered index
of SYS_INDEXES table */
- mtr_t* mtr); /* in: mtr having the latch on the record page */
-#ifndef UNIV_HOTBACKUP
-/********************************************************************
+ mtr_t* mtr); /*!< in: mtr having the latch on the record page */
+/****************************************************************//**
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. */
+not of the right form.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_create_or_check_foreign_constraint_tables(void);
/*================================================*/
- /* out: DB_SUCCESS or error code */
-/************************************************************************
+/********************************************************************//**
Adds foreign key definitions to data dictionary tables in the database. We
look at table->foreign_list, and also generate names to constraints that were
not named by the user. A generated constraint has a name of the format
databasename/tablename_ibfk_<number>, where the numbers start from 1, and are
given locally for this table, that is, the number is not global, as in the
-old format constraints < 4.0.18 it used to be. */
+old format constraints < 4.0.18 it used to be.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
dict_create_add_foreigns_to_dictionary(
/*===================================*/
- /* out: error code or DB_SUCCESS */
- ulint start_id,/* in: if we are actually doing ALTER TABLE
+ ulint start_id,/*!< in: if we are actually doing ALTER TABLE
ADD CONSTRAINT, we want to generate constraint
numbers which are bigger than in the table so
far; we number the constraints from
@@ -127,15 +126,14 @@ dict_create_add_foreigns_to_dictionary(
we are creating a new table, or if the table
so far has no constraints for which the name
was generated here */
- dict_table_t* table, /* in: table */
- trx_t* trx); /* in: transaction */
-#endif /* !UNIV_HOTBACKUP */
+ dict_table_t* table, /*!< in: table */
+ trx_t* trx); /*!< in: transaction */
/* Table create node structure */
struct tab_node_struct{
- que_common_t common; /* node type: QUE_NODE_TABLE_CREATE */
- dict_table_t* table; /* table to create, built as a memory data
+ que_common_t common; /*!< node type: QUE_NODE_TABLE_CREATE */
+ dict_table_t* table; /*!< table to create, built as a memory data
structure with dict_mem_... functions */
ins_node_t* tab_def; /* child node which does the insert of
the table definition; the row to be inserted
@@ -148,9 +146,9 @@ struct tab_node_struct{
a successful table creation */
/*----------------------*/
/* Local storage for this graph node */
- ulint state; /* node execution state */
- ulint col_no; /* next column definition to insert */
- mem_heap_t* heap; /* memory heap used as auxiliary storage */
+ ulint state; /*!< node execution state */
+ ulint col_no; /*!< next column definition to insert */
+ mem_heap_t* heap; /*!< memory heap used as auxiliary storage */
};
/* Table create node states */
@@ -163,8 +161,8 @@ struct tab_node_struct{
/* Index create node struct */
struct ind_node_struct{
- que_common_t common; /* node type: QUE_NODE_INDEX_CREATE */
- dict_index_t* index; /* index to create, built as a memory data
+ que_common_t common; /*!< node type: QUE_NODE_INDEX_CREATE */
+ dict_index_t* index; /*!< index to create, built as a memory data
structure with dict_mem_... functions */
ins_node_t* ind_def; /* child node which does the insert of
the index definition; the row to be inserted
@@ -177,12 +175,12 @@ struct ind_node_struct{
a successful index creation */
/*----------------------*/
/* Local storage for this graph node */
- ulint state; /* node execution state */
+ ulint state; /*!< node execution state */
ulint page_no;/* root page number of the index */
- dict_table_t* table; /* table which owns the index */
+ 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 */
- mem_heap_t* heap; /* memory heap used as auxiliary storage */
+ mem_heap_t* heap; /*!< memory heap used as auxiliary storage */
};
/* Index create node states */
diff --git a/storage/xtradb/include/dict0crea.ic b/storage/xtradb/include/dict0crea.ic
index b05385fa121..c5365ce7489 100644
--- a/storage/xtradb/include/dict0crea.ic
+++ b/storage/xtradb/include/dict0crea.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0crea.ic
Database object creation
Created 1/8/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h
index 7c7b37b7681..0842e307cda 100644
--- a/storage/xtradb/include/dict0dict.h
+++ b/storage/xtradb/include/dict0dict.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0dict.h
Data dictionary system
Created 1/8/1996 Heikki Tuuri
@@ -30,8 +31,6 @@ Created 1/8/1996 Heikki Tuuri
#include "dict0mem.h"
#include "data0type.h"
#include "data0data.h"
-#include "sync0sync.h"
-#include "sync0rw.h"
#include "mem0mem.h"
#include "rem0types.h"
#include "ut0mem.h"
@@ -42,56 +41,57 @@ Created 1/8/1996 Heikki Tuuri
#include "trx0types.h"
#ifndef UNIV_HOTBACKUP
-/**********************************************************************
+# include "sync0sync.h"
+# include "sync0rw.h"
+/******************************************************************//**
Makes all characters in a NUL-terminated UTF-8 string lower case. */
UNIV_INTERN
void
dict_casedn_str(
/*============*/
- char* a); /* in/out: string to put in lower case */
-#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
-Get the database name length in a table name. */
+ char* a); /*!< in/out: string to put in lower case */
+/********************************************************************//**
+Get the database name length in a table name.
+@return database name length */
UNIV_INTERN
ulint
dict_get_db_name_len(
/*=================*/
- /* out: database name length */
- const char* name); /* in: table name in the form
+ const char* name); /*!< in: table name in the form
dbname '/' tablename */
-/************************************************************************
-Return the end of table name where we have removed dbname and '/'. */
+/********************************************************************//**
+Return the end of table name where we have removed dbname and '/'.
+@return table name */
const char*
dict_remove_db_name(
/*================*/
- /* out: table name */
- const char* name); /* in: table name in the form
+ const char* name); /*!< in: table name in the form
dbname '/' tablename */
-/**************************************************************************
-Returns a table object based on table id. */
+/**********************************************************************//**
+Returns a table object based on table id.
+@return table, NULL if does not exist */
UNIV_INTERN
dict_table_t*
dict_table_get_on_id(
/*=================*/
- /* out: table, NULL if does not exist */
- dulint table_id, /* in: table id */
- trx_t* trx); /* in: transaction handle */
-/************************************************************************
+ dulint table_id, /*!< in: table id */
+ trx_t* trx); /*!< in: transaction handle */
+/********************************************************************//**
Decrements the count of open MySQL handles to a table. */
UNIV_INTERN
void
dict_table_decrement_handle_count(
/*==============================*/
- dict_table_t* table, /* in/out: table */
- ibool dict_locked); /* in: TRUE=data dictionary locked */
-/**************************************************************************
+ dict_table_t* table, /*!< in/out: table */
+ ibool dict_locked); /*!< in: TRUE=data dictionary locked */
+/**********************************************************************//**
Inits the data dictionary module. */
UNIV_INTERN
void
dict_init(void);
/*===========*/
-/************************************************************************
+/********************************************************************//**
Gets the space id of every table of the data dictionary and makes a linear
list and a hash table of them to the data dictionary cache. This function
can be called at database startup if we did not need to do a crash recovery.
@@ -101,109 +101,113 @@ UNIV_INTERN
void
dict_load_space_id_list(void);
/*=========================*/
-/*************************************************************************
+/*********************************************************************//**
Gets the column data type. */
UNIV_INLINE
void
dict_col_copy_type(
/*===============*/
- const dict_col_t* col, /* in: column */
- dtype_t* type); /* out: data type */
+ const dict_col_t* col, /*!< in: column */
+ dtype_t* type); /*!< out: data type */
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
-/*************************************************************************
-Assert that a column and a data type match. */
+/*********************************************************************//**
+Assert that a column and a data type match.
+@return TRUE */
UNIV_INLINE
ibool
dict_col_type_assert_equal(
/*=======================*/
- /* out: TRUE */
- const dict_col_t* col, /* in: column */
- const dtype_t* type); /* in: data type */
+ const dict_col_t* col, /*!< in: column */
+ const dtype_t* type); /*!< in: data type */
#endif /* UNIV_DEBUG */
-/***************************************************************************
-Returns the minimum size of the column. */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
+Returns the minimum size of the column.
+@return minimum size */
UNIV_INLINE
ulint
dict_col_get_min_size(
/*==================*/
- /* out: minimum size */
- const dict_col_t* col); /* in: column */
-/***************************************************************************
-Returns the maximum size of the column. */
+ const dict_col_t* col); /*!< in: column */
+/***********************************************************************//**
+Returns the maximum size of the column.
+@return maximum size */
UNIV_INLINE
ulint
dict_col_get_max_size(
/*==================*/
- /* out: maximum size */
- const dict_col_t* col); /* in: column */
-/***************************************************************************
-Returns the size of a fixed size column, 0 if not a fixed size column. */
+ const dict_col_t* col); /*!< in: column */
+/***********************************************************************//**
+Returns the size of a fixed size column, 0 if not a fixed size column.
+@return fixed size, or 0 */
UNIV_INLINE
ulint
dict_col_get_fixed_size(
/*====================*/
- /* out: fixed size, or 0 */
- const dict_col_t* col); /* in: column */
-/***************************************************************************
+ const dict_col_t* col, /*!< in: column */
+ ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
+/***********************************************************************//**
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
-For fixed length types it is the fixed length of the type, otherwise 0. */
+For fixed length types it is the fixed length of the type, otherwise 0.
+@return SQL null storage size in ROW_FORMAT=REDUNDANT */
UNIV_INLINE
ulint
dict_col_get_sql_null_size(
/*=======================*/
- /* out: SQL null storage size
- in ROW_FORMAT=REDUNDANT */
- const dict_col_t* col); /* in: column */
+ const dict_col_t* col, /*!< in: column */
+ ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
-/*************************************************************************
-Gets the column number. */
+/*********************************************************************//**
+Gets the column number.
+@return col->ind, table column position (starting from 0) */
UNIV_INLINE
ulint
dict_col_get_no(
/*============*/
- const dict_col_t* col);
-/*************************************************************************
+ const dict_col_t* col); /*!< in: column */
+/*********************************************************************//**
Gets the column position in the clustered index. */
UNIV_INLINE
ulint
dict_col_get_clust_pos(
/*===================*/
- const dict_col_t* col, /* in: table column */
- const dict_index_t* clust_index); /* in: clustered index */
-/********************************************************************
+ const dict_col_t* col, /*!< in: table column */
+ const dict_index_t* clust_index); /*!< in: clustered index */
+/****************************************************************//**
If the given column name is reserved for InnoDB system columns, return
-TRUE. */
+TRUE.
+@return TRUE if name is reserved */
UNIV_INTERN
ibool
dict_col_name_is_reserved(
/*======================*/
- /* out: TRUE if name is reserved */
- const char* name); /* in: column name */
-/************************************************************************
-Acquire the autoinc lock.*/
+ const char* name); /*!< in: column name */
+/********************************************************************//**
+Acquire the autoinc lock. */
UNIV_INTERN
void
dict_table_autoinc_lock(
/*====================*/
- dict_table_t* table); /* in/out: table */
-/************************************************************************
+ dict_table_t* table); /*!< in/out: table */
+/********************************************************************//**
Unconditionally set the autoinc counter. */
UNIV_INTERN
void
dict_table_autoinc_initialize(
/*==========================*/
- dict_table_t* table, /* in/out: table */
- ib_uint64_t value); /* in: next value to assign to a row */
-/************************************************************************
+ dict_table_t* table, /*!< in/out: table */
+ ib_uint64_t value); /*!< in: next value to assign to a row */
+/********************************************************************//**
Reads the next autoinc value (== autoinc counter value), 0 if not yet
-initialized. */
+initialized.
+@return value for a new row, or 0 */
UNIV_INTERN
ib_uint64_t
dict_table_autoinc_read(
/*====================*/
- /* out: value for a new row, or 0 */
- const dict_table_t* table); /* in: table */
-/************************************************************************
+ const dict_table_t* table); /*!< in: table */
+/********************************************************************//**
Updates the autoinc counter if the value supplied is greater than the
current value. */
UNIV_INTERN
@@ -211,135 +215,136 @@ void
dict_table_autoinc_update_if_greater(
/*=================================*/
- dict_table_t* table, /* in/out: table */
- ib_uint64_t value); /* in: value which was assigned to a row */
-/************************************************************************
-Release the autoinc lock.*/
+ dict_table_t* table, /*!< in/out: table */
+ ib_uint64_t value); /*!< in: value which was assigned to a row */
+/********************************************************************//**
+Release the autoinc lock. */
UNIV_INTERN
void
dict_table_autoinc_unlock(
/*======================*/
- dict_table_t* table); /* in/out: table */
-/**************************************************************************
+ dict_table_t* table); /*!< in/out: table */
+#endif /* !UNIV_HOTBACKUP */
+/**********************************************************************//**
Adds system columns to a table object. */
UNIV_INTERN
void
dict_table_add_system_columns(
/*==========================*/
- dict_table_t* table, /* in/out: table */
- mem_heap_t* heap); /* in: temporary heap */
-/**************************************************************************
+ dict_table_t* table, /*!< in/out: table */
+ mem_heap_t* heap); /*!< in: temporary heap */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Adds a table object to the dictionary cache. */
UNIV_INTERN
void
dict_table_add_to_cache(
/*====================*/
- dict_table_t* table, /* in: table */
- mem_heap_t* heap); /* in: temporary heap */
-/**************************************************************************
+ dict_table_t* table, /*!< in: table */
+ mem_heap_t* heap); /*!< in: temporary heap */
+/**********************************************************************//**
Removes a table object from the dictionary cache. */
UNIV_INTERN
void
dict_table_remove_from_cache(
/*=========================*/
- dict_table_t* table); /* in, own: table */
-/**************************************************************************
-Renames a table object. */
+ dict_table_t* table); /*!< in, own: table */
+/**********************************************************************//**
+Renames a table object.
+@return TRUE if success */
UNIV_INTERN
ibool
dict_table_rename_in_cache(
/*=======================*/
- /* out: TRUE if success */
- dict_table_t* table, /* in/out: table */
- const char* new_name, /* in: new name */
- ibool rename_also_foreigns);/* in: in ALTER TABLE we want
+ dict_table_t* table, /*!< in/out: table */
+ const char* new_name, /*!< in: new name */
+ ibool rename_also_foreigns);/*!< in: in ALTER TABLE we want
to preserve the original table name
in constraints which reference it */
-/**************************************************************************
+/**********************************************************************//**
Removes an index from the dictionary cache. */
UNIV_INTERN
void
dict_index_remove_from_cache(
/*=========================*/
- dict_table_t* table, /* in/out: table */
- dict_index_t* index); /* in, own: index */
-/**************************************************************************
+ dict_table_t* table, /*!< in/out: table */
+ dict_index_t* index); /*!< in, own: index */
+/**********************************************************************//**
Change the id of a table object in the dictionary cache. This is used in
DISCARD TABLESPACE. */
UNIV_INTERN
void
dict_table_change_id_in_cache(
/*==========================*/
- dict_table_t* table, /* in/out: table object already in cache */
- dulint new_id);/* in: new id to set */
-/**************************************************************************
+ dict_table_t* table, /*!< in/out: table object already in cache */
+ dulint new_id);/*!< in: new id to set */
+/**********************************************************************//**
Adds a foreign key constraint object to the dictionary cache. May free
the object if there already is an object with the same identifier in.
At least one of foreign table or referenced table must already be in
-the dictionary cache! */
+the dictionary cache!
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_foreign_add_to_cache(
/*======================*/
- /* out: DB_SUCCESS or error code */
- dict_foreign_t* foreign, /* in, own: foreign key constraint */
- ibool check_charsets);/* in: TRUE=check charset
+ dict_foreign_t* foreign, /*!< in, own: foreign key constraint */
+ ibool check_charsets);/*!< in: TRUE=check charset
compatibility */
-/*************************************************************************
+/*********************************************************************//**
Check if the index is referenced by a foreign key, if TRUE return the
-matching instance NULL otherwise. */
+matching instance NULL otherwise.
+@return pointer to foreign key struct if index is defined for foreign
+key, otherwise NULL */
UNIV_INTERN
dict_foreign_t*
dict_table_get_referenced_constraint(
/*=================================*/
- /* out: pointer to foreign key struct if index
- is defined for foreign key, otherwise NULL */
- dict_table_t* table, /* in: InnoDB table */
- dict_index_t* index); /* in: InnoDB index */
-/*************************************************************************
-Checks if a table is referenced by foreign keys. */
+ dict_table_t* table, /*!< in: InnoDB table */
+ dict_index_t* index); /*!< in: InnoDB index */
+/*********************************************************************//**
+Checks if a table is referenced by foreign keys.
+@return TRUE if table is referenced by a foreign key */
UNIV_INTERN
ibool
dict_table_is_referenced_by_foreign_key(
/*====================================*/
- /* out: TRUE if table is referenced
- by a foreign key */
- const dict_table_t* table); /* in: InnoDB table */
-/**************************************************************************
+ const dict_table_t* table); /*!< in: InnoDB table */
+/**********************************************************************//**
Replace the index in the foreign key list that matches this index's
definition with an equivalent index. */
UNIV_INTERN
void
dict_table_replace_index_in_foreign_list(
/*=====================================*/
- dict_table_t* table, /* in/out: table */
- dict_index_t* index); /* in: index to be replaced */
-/*************************************************************************
+ dict_table_t* table, /*!< in/out: table */
+ dict_index_t* index); /*!< in: index to be replaced */
+/*********************************************************************//**
Checks if a index is defined for a foreign key constraint. Index is a part
of a foreign key constraint if the index is referenced by foreign key
-or index is a foreign key index */
+or index is a foreign key index
+@return pointer to foreign key struct if index is defined for foreign
+key, otherwise NULL */
UNIV_INTERN
dict_foreign_t*
dict_table_get_foreign_constraint(
/*==============================*/
- /* out: pointer to foreign key struct if index
- is defined for foreign key, otherwise NULL */
- dict_table_t* table, /* in: InnoDB table */
- dict_index_t* index); /* in: InnoDB index */
-/*************************************************************************
+ dict_table_t* table, /*!< in: InnoDB table */
+ dict_index_t* index); /*!< in: InnoDB index */
+/*********************************************************************//**
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.
Each foreign key constraint must be accompanied with indexes in
bot participating tables. The indexes are allowed to contain more
-fields than mentioned in the constraint. */
+fields than mentioned in the constraint.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
dict_create_foreign_constraints(
/*============================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in: transaction */
- const char* sql_string, /* in: table create statement where
+ trx_t* trx, /*!< in: transaction */
+ const char* sql_string, /*!< in: table create statement where
foreign keys are declared like:
FOREIGN KEY (a, b) REFERENCES
table2(c, d), table2 can be written
@@ -347,349 +352,345 @@ dict_create_foreign_constraints(
name before it: test.table2; the
default database id the database of
parameter name */
- const char* name, /* in: table full name in the
+ const char* name, /*!< in: table full name in the
normalized form
database_name/table_name */
- ibool reject_fks); /* in: if TRUE, fail with error
+ ibool reject_fks); /*!< in: if TRUE, fail with error
code DB_CANNOT_ADD_CONSTRAINT if
any foreign keys are found. */
-/**************************************************************************
-Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement. */
+/**********************************************************************//**
+Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement.
+@return DB_SUCCESS or DB_CANNOT_DROP_CONSTRAINT if syntax error or the
+constraint id does not match */
UNIV_INTERN
ulint
dict_foreign_parse_drop_constraints(
/*================================*/
- /* out: DB_SUCCESS or
- DB_CANNOT_DROP_CONSTRAINT if
- syntax error or the constraint
- id does not match */
- mem_heap_t* heap, /* in: heap from which we can
+ mem_heap_t* heap, /*!< in: heap from which we can
allocate memory */
- trx_t* trx, /* in: transaction */
- dict_table_t* table, /* in: table */
- ulint* n, /* out: number of constraints
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table, /*!< in: table */
+ ulint* n, /*!< out: number of constraints
to drop */
- const char*** constraints_to_drop); /* out: id's of the
+ const char*** constraints_to_drop); /*!< out: id's of the
constraints to drop */
-/**************************************************************************
+/**********************************************************************//**
Returns a table object and optionally increment its MySQL open handle count.
NOTE! This is a high-level function to be used mainly from outside the
'dict' directory. Inside this directory dict_table_get_low is usually the
-appropriate function. */
+appropriate function.
+@return table, NULL if does not exist */
UNIV_INTERN
dict_table_t*
dict_table_get(
/*===========*/
- /* out: table, NULL if
- does not exist */
- const char* table_name, /* in: table name */
+ const char* table_name, /*!< in: table name */
ibool inc_mysql_count);
- /* in: whether to increment the open
+ /*!< in: whether to increment the open
handle count on the table */
-/**************************************************************************
-Returns a index object, based on table and index id, and memoryfixes it. */
+/**********************************************************************//**
+Returns a index object, based on table and index id, and memoryfixes it.
+@return index, NULL if does not exist */
UNIV_INTERN
dict_index_t*
dict_index_get_on_id_low(
/*=====================*/
- /* out: index, NULL if does not
- exist */
- dict_table_t* table, /* in: table */
- dulint index_id); /* in: index id */
-/**************************************************************************
-Checks if a table is in the dictionary cache. */
+ dict_table_t* table, /*!< in: table */
+ dulint index_id); /*!< in: index id */
+/**********************************************************************//**
+Checks if a table is in the dictionary cache.
+@return table, NULL if not found */
UNIV_INLINE
dict_table_t*
dict_table_check_if_in_cache_low(
/*=============================*/
- /* out: table, NULL if not found */
- const char* table_name); /* in: table name */
-/**************************************************************************
+ const char* table_name); /*!< in: table name */
+/**********************************************************************//**
Gets a table; loads it to the dictionary cache if necessary. A low-level
-function. */
+function.
+@return table, NULL if not found */
UNIV_INLINE
dict_table_t*
dict_table_get_low(
/*===============*/
- /* out: table, NULL if not found */
- const char* table_name); /* in: table name */
-/**************************************************************************
-Returns a table object based on table id. */
+ const char* table_name); /*!< in: table name */
+/**********************************************************************//**
+Returns a table object based on table id.
+@return table, NULL if does not exist */
UNIV_INLINE
dict_table_t*
dict_table_get_on_id_low(
/*=====================*/
- /* out: table, NULL if does not exist */
- dulint table_id); /* in: table id */
-/**************************************************************************
+ dulint table_id); /*!< in: table id */
+/**********************************************************************//**
Find an index that is equivalent to the one passed in and is not marked
-for deletion. */
+for deletion.
+@return index equivalent to foreign->foreign_index, or NULL */
UNIV_INTERN
dict_index_t*
dict_foreign_find_equiv_index(
/*==========================*/
- /* out: index equivalent to
- foreign->foreign_index, or NULL */
- dict_foreign_t* foreign);/* in: foreign key */
-/**************************************************************************
-Returns an index object by matching on the name and column names and if
-more than index is found return the index with the higher id.*/
+ dict_foreign_t* foreign);/*!< in: foreign key */
+/**********************************************************************//**
+Returns an index object by matching on the name and column names and
+if more than one index matches return the index with the max id
+@return matching index, NULL if not found */
UNIV_INTERN
dict_index_t*
dict_table_get_index_by_max_id(
/*===========================*/
- /* out: matching index, NULL if not found */
- dict_table_t* table, /* in: table */
- const char* name, /* in: the index name to find */
- const char** columns,/* in: array of column names */
- ulint n_cols);/* in: number of columns */
-/**************************************************************************
-Returns a column's name. */
-
+ dict_table_t* table, /*!< in: table */
+ const char* name, /*!< in: the index name to find */
+ const char** columns,/*!< in: array of column names */
+ ulint n_cols);/*!< in: number of columns */
+/**********************************************************************//**
+Returns a column's name.
+@return column name. NOTE: not guaranteed to stay valid if table is
+modified in any way (columns added, etc.). */
+UNIV_INTERN
const char*
dict_table_get_col_name(
/*====================*/
- /* out: column name. NOTE: not
- guaranteed to stay valid if table is
- modified in any way (columns added,
- etc.). */
- const dict_table_t* table, /* in: table */
- ulint col_nr);/* in: column number */
+ const dict_table_t* table, /*!< in: table */
+ ulint col_nr);/*!< in: column number */
-/**************************************************************************
+/**********************************************************************//**
Prints a table definition. */
UNIV_INTERN
void
dict_table_print(
/*=============*/
- dict_table_t* table); /* in: table */
-/**************************************************************************
+ dict_table_t* table); /*!< in: table */
+/**********************************************************************//**
Prints a table data. */
UNIV_INTERN
void
dict_table_print_low(
/*=================*/
- dict_table_t* table); /* in: table */
-/**************************************************************************
+ dict_table_t* table); /*!< in: table */
+/**********************************************************************//**
Prints a table data when we know the table name. */
UNIV_INTERN
void
dict_table_print_by_name(
/*=====================*/
- const char* name);
-/**************************************************************************
+ const char* name); /*!< in: table name */
+/**********************************************************************//**
Outputs info on foreign keys of a table. */
UNIV_INTERN
void
dict_print_info_on_foreign_keys(
/*============================*/
- ibool create_table_format, /* in: if TRUE then print in
+ ibool create_table_format, /*!< in: if TRUE then print in
a format suitable to be inserted into
a CREATE TABLE, otherwise in the format
of SHOW TABLE STATUS */
- FILE* file, /* in: file where to print */
- trx_t* trx, /* in: transaction */
- dict_table_t* table); /* in: table */
-/**************************************************************************
+ FILE* file, /*!< in: file where to print */
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table); /*!< in: table */
+/**********************************************************************//**
Outputs info on a foreign key of a table in a format suitable for
CREATE TABLE. */
UNIV_INTERN
void
dict_print_info_on_foreign_key_in_create_format(
/*============================================*/
- FILE* file, /* in: file where to print */
- trx_t* trx, /* in: transaction */
- dict_foreign_t* foreign, /* in: foreign key constraint */
- ibool add_newline); /* in: whether to add a newline */
-/************************************************************************
+ FILE* file, /*!< in: file where to print */
+ trx_t* trx, /*!< in: transaction */
+ dict_foreign_t* foreign, /*!< in: foreign key constraint */
+ ibool add_newline); /*!< in: whether to add a newline */
+/********************************************************************//**
Displays the names of the index and the table. */
UNIV_INTERN
void
dict_index_name_print(
/*==================*/
- FILE* file, /* in: output stream */
- trx_t* trx, /* in: transaction */
- const dict_index_t* index); /* in: index to print */
+ FILE* file, /*!< in: output stream */
+ trx_t* trx, /*!< in: transaction */
+ const dict_index_t* index); /*!< in: index to print */
#ifdef UNIV_DEBUG
-/************************************************************************
-Gets the first index on the table (the clustered index). */
+/********************************************************************//**
+Gets the first index on the table (the clustered index).
+@return index, NULL if none exists */
UNIV_INLINE
dict_index_t*
dict_table_get_first_index(
/*=======================*/
- /* out: index, NULL if none exists */
- const dict_table_t* table); /* in: table */
-/************************************************************************
-Gets the next index on the table. */
+ const dict_table_t* table); /*!< in: table */
+/********************************************************************//**
+Gets the next index on the table.
+@return index, NULL if none left */
UNIV_INLINE
dict_index_t*
dict_table_get_next_index(
/*======================*/
- /* out: index, NULL if none left */
- const dict_index_t* index); /* in: index */
+ const dict_index_t* index); /*!< in: index */
#else /* UNIV_DEBUG */
# define dict_table_get_first_index(table) UT_LIST_GET_FIRST((table)->indexes)
# define dict_table_get_next_index(index) UT_LIST_GET_NEXT(indexes, index)
#endif /* UNIV_DEBUG */
-/************************************************************************
-Check whether the index is the clustered index. */
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
+Check whether the index is the clustered index.
+@return nonzero for clustered index, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_clust(
/*================*/
- /* out: nonzero for clustered index,
- zero for other indexes */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
__attribute__((pure));
-/************************************************************************
-Check whether the index is unique. */
+/********************************************************************//**
+Check whether the index is unique.
+@return nonzero for unique index, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_unique(
/*=================*/
- /* out: nonzero for unique index,
- zero for other indexes */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
__attribute__((pure));
-/************************************************************************
-Check whether the index is the insert buffer tree. */
+/********************************************************************//**
+Check whether the index is the insert buffer tree.
+@return nonzero for insert buffer, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_ibuf(
/*===============*/
- /* out: nonzero for insert buffer,
- zero for other indexes */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
+ __attribute__((pure));
+/********************************************************************//**
+Check whether the index is a secondary index or the insert buffer tree.
+@return nonzero for insert buffer, zero for other indexes */
+UNIV_INLINE
+ulint
+dict_index_is_sec_or_ibuf(
+/*======================*/
+ const dict_index_t* index) /*!< in: index */
__attribute__((pure));
-/************************************************************************
+/********************************************************************//**
Gets the number of user-defined columns in a table in the dictionary
-cache. */
+cache.
+@return number of user-defined (e.g., not ROW_ID) columns of a table */
UNIV_INLINE
ulint
dict_table_get_n_user_cols(
/*=======================*/
- /* out: number of user-defined
- (e.g., not ROW_ID)
- columns of a table */
- const dict_table_t* table); /* in: table */
-/************************************************************************
-Gets the number of system columns in a table in the dictionary cache. */
+ const dict_table_t* table); /*!< in: table */
+/********************************************************************//**
+Gets the number of system columns in a table in the dictionary cache.
+@return number of system (e.g., ROW_ID) columns of a table */
UNIV_INLINE
ulint
dict_table_get_n_sys_cols(
/*======================*/
- /* out: number of system (e.g.,
- ROW_ID) columns of a table */
- const dict_table_t* table); /* in: table */
-/************************************************************************
+ const dict_table_t* table); /*!< in: table */
+/********************************************************************//**
Gets the number of all columns (also system) in a table in the dictionary
-cache. */
+cache.
+@return number of columns of a table */
UNIV_INLINE
ulint
dict_table_get_n_cols(
/*==================*/
- /* out: number of columns of a table */
- const dict_table_t* table); /* in: table */
+ const dict_table_t* table); /*!< in: table */
#ifdef UNIV_DEBUG
-/************************************************************************
-Gets the nth column of a table. */
+/********************************************************************//**
+Gets the nth column of a table.
+@return pointer to column object */
UNIV_INLINE
dict_col_t*
dict_table_get_nth_col(
/*===================*/
- /* out: pointer to column object */
- const dict_table_t* table, /* in: table */
- ulint pos); /* in: position of column */
-/************************************************************************
-Gets the given system column of a table. */
+ const dict_table_t* table, /*!< in: table */
+ ulint pos); /*!< in: position of column */
+/********************************************************************//**
+Gets the given system column of a table.
+@return pointer to column object */
UNIV_INLINE
dict_col_t*
dict_table_get_sys_col(
/*===================*/
- /* out: pointer to column object */
- const dict_table_t* table, /* in: table */
- ulint sys); /* in: DATA_ROW_ID, ... */
+ const dict_table_t* table, /*!< in: table */
+ ulint sys); /*!< in: DATA_ROW_ID, ... */
#else /* UNIV_DEBUG */
#define dict_table_get_nth_col(table, pos) \
((table)->cols + (pos))
#define dict_table_get_sys_col(table, sys) \
((table)->cols + (table)->n_cols + (sys) - DATA_N_SYS_COLS)
#endif /* UNIV_DEBUG */
-/************************************************************************
-Gets the given system column number of a table. */
+/********************************************************************//**
+Gets the given system column number of a table.
+@return column number */
UNIV_INLINE
ulint
dict_table_get_sys_col_no(
/*======================*/
- /* out: column number */
- const dict_table_t* table, /* in: table */
- ulint sys); /* in: DATA_ROW_ID, ... */
-/************************************************************************
-Returns the minimum data size of an index record. */
+ const dict_table_t* table, /*!< in: table */
+ ulint sys); /*!< in: DATA_ROW_ID, ... */
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Returns the minimum data size of an index record.
+@return minimum data size in bytes */
UNIV_INLINE
ulint
dict_index_get_min_size(
/*====================*/
- /* out: minimum data size in bytes */
- const dict_index_t* index); /* in: index */
-/************************************************************************
-Check whether the table uses the compact page format. */
+ const dict_index_t* index); /*!< in: index */
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
+Check whether the table uses the compact page format.
+@return TRUE if table uses the compact page format */
UNIV_INLINE
ibool
dict_table_is_comp(
/*===============*/
- /* out: TRUE if table uses the
- compact page format */
- const dict_table_t* table); /* in: table */
-/************************************************************************
-Determine the file format of a table. */
+ const dict_table_t* table); /*!< in: table */
+/********************************************************************//**
+Determine the file format of a table.
+@return file format version */
UNIV_INLINE
ulint
dict_table_get_format(
/*==================*/
- /* out: file format version */
- const dict_table_t* table); /* in: table */
-/************************************************************************
+ const dict_table_t* table); /*!< in: table */
+/********************************************************************//**
Set the file format of a table. */
UNIV_INLINE
void
dict_table_set_format(
/*==================*/
- dict_table_t* table, /* in/out: table */
- ulint format);/* in: file format version */
-/************************************************************************
-Extract the compressed page size from table flags. */
+ dict_table_t* table, /*!< in/out: table */
+ ulint format);/*!< in: file format version */
+/********************************************************************//**
+Extract the compressed page size from table flags.
+@return compressed page size, or 0 if not compressed */
UNIV_INLINE
ulint
dict_table_flags_to_zip_size(
/*=========================*/
- /* out: compressed page size,
- or 0 if not compressed */
- ulint flags) /* in: flags */
+ ulint flags) /*!< in: flags */
__attribute__((const));
-/************************************************************************
-Check whether the table uses the compressed compact page format. */
+/********************************************************************//**
+Check whether the table uses the compressed compact page format.
+@return compressed page size, or 0 if not compressed */
UNIV_INLINE
ulint
dict_table_zip_size(
/*================*/
- /* out: compressed page size,
- or 0 if not compressed */
- const dict_table_t* table); /* in: table */
-/************************************************************************
+ const dict_table_t* table); /*!< in: table */
+/********************************************************************//**
Checks if a column is in the ordering columns of the clustered index of a
-table. Column prefixes are treated like whole columns. */
+table. Column prefixes are treated like whole columns.
+@return TRUE if the column, or its prefix, is in the clustered key */
UNIV_INTERN
ibool
dict_table_col_in_clustered_key(
/*============================*/
- /* out: TRUE if the column, or its
- prefix, is in the clustered key */
- const dict_table_t* table, /* in: table */
- ulint n); /* in: column number */
-/***********************************************************************
+ const dict_table_t* table, /*!< in: table */
+ ulint n); /*!< in: column number */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Copies types of columns contained in table to tuple and sets all
fields of the tuple to the SQL NULL value. This function should
be called right after dtuple_create(). */
@@ -697,411 +698,406 @@ UNIV_INTERN
void
dict_table_copy_types(
/*==================*/
- dtuple_t* tuple, /* in/out: data tuple */
- const dict_table_t* table); /* in: table */
-/**************************************************************************
+ dtuple_t* tuple, /*!< in/out: data tuple */
+ const dict_table_t* table); /*!< in: table */
+/**********************************************************************//**
Looks for an index with the given id. NOTE that we do not reserve
the dictionary mutex: this function is for emergency purposes like
-printing info of a corrupt database page! */
+printing info of a corrupt database page!
+@return index or NULL if not found from cache */
UNIV_INTERN
dict_index_t*
dict_index_find_on_id_low(
/*======================*/
- /* out: index or NULL if not found from cache */
- dulint id); /* in: index id */
-/**************************************************************************
-Adds an index to the dictionary cache. */
+ dulint id); /*!< in: index id */
+/**********************************************************************//**
+Adds an index to the dictionary cache.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_index_add_to_cache(
/*====================*/
- /* out: DB_SUCCESS or error code */
- dict_table_t* table, /* in: table on which the index is */
- dict_index_t* index, /* in, own: index; NOTE! The index memory
+ dict_table_t* table, /*!< in: table on which the index is */
+ dict_index_t* index, /*!< in, own: index; NOTE! The index memory
object is freed in this function! */
- ulint page_no,/* in: root page number of the index */
- ibool strict);/* in: TRUE=refuse to create the index
+ ulint page_no,/*!< in: root page number of the index */
+ ibool strict);/*!< in: TRUE=refuse to create the index
if records could be too big to fit in
an B-tree page */
-/**************************************************************************
+/**********************************************************************//**
Removes an index from the dictionary cache. */
UNIV_INTERN
void
dict_index_remove_from_cache(
/*=========================*/
- dict_table_t* table, /* in/out: table */
- dict_index_t* index); /* in, own: index */
-/************************************************************************
+ dict_table_t* table, /*!< in/out: table */
+ dict_index_t* index); /*!< in, own: index */
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
Gets the number of fields in the internal representation of an index,
-including fields added by the dictionary system. */
+including fields added by the dictionary system.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_fields(
/*====================*/
- /* out: number of fields */
- const dict_index_t* index); /* in: an internal
+ const dict_index_t* index); /*!< in: an internal
representation of index (in
the dictionary cache) */
-/************************************************************************
+/********************************************************************//**
Gets the number of fields in the internal representation of an index
that uniquely determine the position of an index entry in the index, if
we do not take multiversioning into account: in the B-tree use the value
-returned by dict_index_get_n_unique_in_tree. */
+returned by dict_index_get_n_unique_in_tree.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_unique(
/*====================*/
- /* out: number of fields */
- const dict_index_t* index); /* in: an internal representation
+ const dict_index_t* index); /*!< in: an internal representation
of index (in the dictionary cache) */
-/************************************************************************
+/********************************************************************//**
Gets the number of fields in the internal representation of an index
which uniquely determine the position of an index entry in the index, if
-we also take multiversioning into account. */
+we also take multiversioning into account.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_unique_in_tree(
/*============================*/
- /* out: number of fields */
- const dict_index_t* index); /* in: an internal representation
+ const dict_index_t* index); /*!< in: an internal representation
of index (in the dictionary cache) */
-/************************************************************************
+/********************************************************************//**
Gets the number of user-defined ordering fields in the index. In the internal
representation we add the row id to the ordering fields to make all indexes
unique, but this function returns the number of fields the user defined
-in the index as ordering fields. */
+in the index as ordering fields.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_ordering_defined_by_user(
/*======================================*/
- /* out: number of fields */
- const dict_index_t* index); /* in: an internal representation
+ const dict_index_t* index); /*!< in: an internal representation
of index (in the dictionary cache) */
#ifdef UNIV_DEBUG
-/************************************************************************
-Gets the nth field of an index. */
+/********************************************************************//**
+Gets the nth field of an index.
+@return pointer to field object */
UNIV_INLINE
dict_field_t*
dict_index_get_nth_field(
/*=====================*/
- /* out: pointer to field object */
- const dict_index_t* index, /* in: index */
- ulint pos); /* in: position of field */
+ const dict_index_t* index, /*!< in: index */
+ ulint pos); /*!< in: position of field */
#else /* UNIV_DEBUG */
# define dict_index_get_nth_field(index, pos) ((index)->fields + (pos))
#endif /* UNIV_DEBUG */
-/************************************************************************
-Gets pointer to the nth column in an index. */
+/********************************************************************//**
+Gets pointer to the nth column in an index.
+@return column */
UNIV_INLINE
const dict_col_t*
dict_index_get_nth_col(
/*===================*/
- /* out: column */
- const dict_index_t* index, /* in: index */
- ulint pos); /* in: position of the field */
-/************************************************************************
-Gets the column number of the nth field in an index. */
+ const dict_index_t* index, /*!< in: index */
+ ulint pos); /*!< in: position of the field */
+/********************************************************************//**
+Gets the column number of the nth field in an index.
+@return column number */
UNIV_INLINE
ulint
dict_index_get_nth_col_no(
/*======================*/
- /* out: column number */
- const dict_index_t* index, /* in: index */
- ulint pos); /* in: position of the field */
-/************************************************************************
-Looks for column n in an index. */
+ const dict_index_t* index, /*!< in: index */
+ ulint pos); /*!< in: position of the field */
+/********************************************************************//**
+Looks for column n in an index.
+@return position in internal representation of the index;
+ULINT_UNDEFINED if not contained */
UNIV_INTERN
ulint
dict_index_get_nth_col_pos(
/*=======================*/
- /* out: position in internal
- representation of the index;
- if not contained, returns
- ULINT_UNDEFINED */
- const dict_index_t* index, /* in: index */
- ulint n); /* in: column number */
-/************************************************************************
-Returns TRUE if the index contains a column or a prefix of that column. */
+ const dict_index_t* index, /*!< in: index */
+ ulint n); /*!< in: column number */
+/********************************************************************//**
+Returns TRUE if the index contains a column or a prefix of that column.
+@return TRUE if contains the column or its prefix */
UNIV_INTERN
ibool
dict_index_contains_col_or_prefix(
/*==============================*/
- /* out: TRUE if contains the column
- or its prefix */
- const dict_index_t* index, /* in: index */
- ulint n); /* in: column number */
-/************************************************************************
+ const dict_index_t* index, /*!< in: index */
+ ulint n); /*!< in: column number */
+/********************************************************************//**
Looks for a matching field in an index. The column has to be the same. The
column in index must be complete, or must contain a prefix longer than the
column in index2. That is, we must be able to construct the prefix in index2
-from the prefix in index. */
+from the prefix in index.
+@return position in internal representation of the index;
+ULINT_UNDEFINED if not contained */
UNIV_INTERN
ulint
dict_index_get_nth_field_pos(
/*=========================*/
- /* out: position in internal
- representation of the index;
- if not contained, returns
- ULINT_UNDEFINED */
- const dict_index_t* index, /* in: index from which to search */
- const dict_index_t* index2, /* in: index */
- ulint n); /* in: field number in index2 */
-/************************************************************************
-Looks for column n position in the clustered index. */
+ const dict_index_t* index, /*!< in: index from which to search */
+ const dict_index_t* index2, /*!< in: index */
+ ulint n); /*!< in: field number in index2 */
+/********************************************************************//**
+Looks for column n position in the clustered index.
+@return position in internal representation of the clustered index */
UNIV_INTERN
ulint
dict_table_get_nth_col_pos(
/*=======================*/
- /* out: position in internal
- representation of
- the clustered index */
- const dict_table_t* table, /* in: table */
- ulint n); /* in: column number */
-/************************************************************************
-Returns the position of a system column in an index. */
+ const dict_table_t* table, /*!< in: table */
+ ulint n); /*!< in: column number */
+/********************************************************************//**
+Returns the position of a system column in an index.
+@return position, ULINT_UNDEFINED if not contained */
UNIV_INLINE
ulint
dict_index_get_sys_col_pos(
/*=======================*/
- /* out: position,
- ULINT_UNDEFINED if not contained */
- const dict_index_t* index, /* in: index */
- ulint type); /* in: DATA_ROW_ID, ... */
-/***********************************************************************
+ const dict_index_t* index, /*!< in: index */
+ ulint type); /*!< in: DATA_ROW_ID, ... */
+/*******************************************************************//**
Adds a column to index. */
UNIV_INTERN
void
dict_index_add_col(
/*===============*/
- dict_index_t* index, /* in/out: index */
- const dict_table_t* table, /* in: table */
- dict_col_t* col, /* in: column */
- ulint prefix_len); /* in: column prefix length */
-/***********************************************************************
+ dict_index_t* index, /*!< in/out: index */
+ const dict_table_t* table, /*!< in: table */
+ dict_col_t* col, /*!< in: column */
+ ulint prefix_len); /*!< in: column prefix length */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Copies types of fields contained in index to tuple. */
UNIV_INTERN
void
dict_index_copy_types(
/*==================*/
- dtuple_t* tuple, /* in/out: data tuple */
- const dict_index_t* index, /* in: index */
- ulint n_fields); /* in: number of
+ dtuple_t* tuple, /*!< in/out: data tuple */
+ const dict_index_t* index, /*!< in: index */
+ ulint n_fields); /*!< in: number of
field types to copy */
-/*************************************************************************
-Gets the field column. */
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************************//**
+Gets the field column.
+@return field->col, pointer to the table column */
UNIV_INLINE
const dict_col_t*
dict_field_get_col(
/*===============*/
- const dict_field_t* field);
-
-/**************************************************************************
+ const dict_field_t* field); /*!< in: index field */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Returns an index object if it is found in the dictionary cache.
-Assumes that dict_sys->mutex is already being held. */
+Assumes that dict_sys->mutex is already being held.
+@return index, NULL if not found */
UNIV_INTERN
dict_index_t*
dict_index_get_if_in_cache_low(
/*===========================*/
- /* out: index, NULL if not found */
- dulint index_id); /* in: index id */
+ dulint index_id); /*!< in: index id */
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
-/**************************************************************************
-Returns an index object if it is found in the dictionary cache. */
+/**********************************************************************//**
+Returns an index object if it is found in the dictionary cache.
+@return index, NULL if not found */
UNIV_INTERN
dict_index_t*
dict_index_get_if_in_cache(
/*=======================*/
- /* out: index, NULL if not found */
- dulint index_id); /* in: index id */
+ dulint index_id); /*!< in: index id */
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Checks that a tuple has n_fields_cmp value in a sensible range, so that
-no comparison can occur with the page number field in a node pointer. */
+no comparison can occur with the page number field in a node pointer.
+@return TRUE if ok */
UNIV_INTERN
ibool
dict_index_check_search_tuple(
/*==========================*/
- /* out: TRUE if ok */
- const dict_index_t* index, /* in: index tree */
- const dtuple_t* tuple); /* in: tuple used in a search */
-/**************************************************************************
+ const dict_index_t* index, /*!< in: index tree */
+ const dtuple_t* tuple); /*!< in: tuple used in a search */
+/**********************************************************************//**
Check for duplicate index entries in a table [using the index name] */
UNIV_INTERN
void
dict_table_check_for_dup_indexes(
/*=============================*/
- const dict_table_t* table); /* in: Check for dup indexes
+ const dict_table_t* table); /*!< in: Check for dup indexes
in this table */
#endif /* UNIV_DEBUG */
-/**************************************************************************
-Builds a node pointer out of a physical record and a page number. */
+/**********************************************************************//**
+Builds a node pointer out of a physical record and a page number.
+@return own: node pointer */
UNIV_INTERN
dtuple_t*
dict_index_build_node_ptr(
/*======================*/
- /* out, own: node pointer */
- const dict_index_t* index, /* in: index */
- const rec_t* rec, /* in: record for which to build node
+ const dict_index_t* index, /*!< in: index */
+ const rec_t* rec, /*!< in: record for which to build node
pointer */
- ulint page_no,/* in: page number to put in node
+ ulint page_no,/*!< in: page number to put in node
pointer */
- mem_heap_t* heap, /* in: memory heap where pointer
+ mem_heap_t* heap, /*!< in: memory heap where pointer
created */
- ulint level); /* in: level of rec in tree:
+ ulint level); /*!< in: level of rec in tree:
0 means leaf level */
-/**************************************************************************
+/**********************************************************************//**
Copies an initial segment of a physical record, long enough to specify an
-index entry uniquely. */
+index entry uniquely.
+@return pointer to the prefix record */
UNIV_INTERN
rec_t*
dict_index_copy_rec_order_prefix(
/*=============================*/
- /* out: pointer to the prefix record */
- const dict_index_t* index, /* in: index */
- const rec_t* rec, /* in: record for which to
+ const dict_index_t* index, /*!< in: index */
+ const rec_t* rec, /*!< in: record for which to
copy prefix */
- ulint* n_fields,/* out: number of fields copied */
- byte** buf, /* in/out: memory buffer for the
+ ulint* n_fields,/*!< out: number of fields copied */
+ byte** buf, /*!< in/out: memory buffer for the
copied prefix, or NULL */
- ulint* buf_size);/* in/out: buffer size */
-/**************************************************************************
-Builds a typed data tuple out of a physical record. */
+ ulint* buf_size);/*!< in/out: buffer size */
+/**********************************************************************//**
+Builds a typed data tuple out of a physical record.
+@return own: data tuple */
UNIV_INTERN
dtuple_t*
dict_index_build_data_tuple(
/*========================*/
- /* out, own: data tuple */
- dict_index_t* index, /* in: index */
- rec_t* rec, /* in: record for which to build data tuple */
- ulint n_fields,/* in: number of data fields */
- mem_heap_t* heap); /* in: memory heap where tuple created */
-/*************************************************************************
-Gets the space id of the root of the index tree. */
+ dict_index_t* index, /*!< in: index */
+ rec_t* rec, /*!< in: record for which to build data tuple */
+ ulint n_fields,/*!< in: number of data fields */
+ mem_heap_t* heap); /*!< in: memory heap where tuple created */
+/*********************************************************************//**
+Gets the space id of the root of the index tree.
+@return space id */
UNIV_INLINE
ulint
dict_index_get_space(
/*=================*/
- /* out: space id */
- const dict_index_t* index); /* in: index */
-/*************************************************************************
+ const dict_index_t* index); /*!< in: index */
+/*********************************************************************//**
Sets the space id of the root of the index tree. */
UNIV_INLINE
void
dict_index_set_space(
/*=================*/
- dict_index_t* index, /* in/out: index */
- ulint space); /* in: space id */
-/*************************************************************************
-Gets the page number of the root of the index tree. */
+ dict_index_t* index, /*!< in/out: index */
+ ulint space); /*!< in: space id */
+/*********************************************************************//**
+Gets the page number of the root of the index tree.
+@return page number */
UNIV_INLINE
ulint
dict_index_get_page(
/*================*/
- /* out: page number */
- const dict_index_t* tree); /* in: index */
-/*************************************************************************
+ const dict_index_t* tree); /*!< in: index */
+/*********************************************************************//**
Sets the page number of the root of index tree. */
UNIV_INLINE
void
dict_index_set_page(
/*================*/
- dict_index_t* index, /* in/out: index */
- ulint page); /* in: page number */
-/*************************************************************************
-Gets the read-write lock of the index tree. */
+ dict_index_t* index, /*!< in/out: index */
+ ulint page); /*!< in: page number */
+/*********************************************************************//**
+Gets the read-write lock of the index tree.
+@return read-write lock */
UNIV_INLINE
rw_lock_t*
dict_index_get_lock(
/*================*/
- /* out: read-write lock */
- dict_index_t* index); /* in: index */
-/************************************************************************
+ dict_index_t* index); /*!< in: index */
+/********************************************************************//**
Returns free space reserved for future updates of records. This is
relevant only in the case of many consecutive inserts, as updates
-which make the records bigger might fragment the index. */
+which make the records bigger might fragment the index.
+@return number of free bytes on page, reserved for updates */
UNIV_INLINE
ulint
dict_index_get_space_reserve(void);
/*==============================*/
- /* out: number of free bytes on page,
- reserved for updates */
-/*************************************************************************
+/*********************************************************************//**
Calculates the minimum record length in an index. */
UNIV_INTERN
ulint
dict_index_calc_min_rec_len(
/*========================*/
- const dict_index_t* index); /* in: index */
-/*************************************************************************
+ const dict_index_t* index); /*!< in: index */
+/*********************************************************************//**
Calculates new estimates for table and index statistics. The statistics
are used in query optimization. */
UNIV_INTERN
void
dict_update_statistics_low(
/*=======================*/
- dict_table_t* table, /* in/out: table */
- ibool has_dict_mutex);/* in: TRUE if the caller has the
+ dict_table_t* table, /*!< in/out: table */
+ ibool has_dict_mutex);/*!< in: TRUE if the caller has the
dictionary mutex */
-/*************************************************************************
+/*********************************************************************//**
Calculates new estimates for table and index statistics. The statistics
are used in query optimization. */
UNIV_INTERN
void
dict_update_statistics(
/*===================*/
- dict_table_t* table); /* in/out: table */
-/************************************************************************
+ dict_table_t* table); /*!< in/out: table */
+/********************************************************************//**
Reserves the dictionary system mutex for MySQL. */
UNIV_INTERN
void
dict_mutex_enter_for_mysql(void);
/*============================*/
-/************************************************************************
+/********************************************************************//**
Releases the dictionary system mutex for MySQL. */
UNIV_INTERN
void
dict_mutex_exit_for_mysql(void);
/*===========================*/
-/************************************************************************
-Checks if the database name in two table names is the same. */
+/********************************************************************//**
+Checks if the database name in two table names is the same.
+@return TRUE if same db name */
UNIV_INTERN
ibool
dict_tables_have_same_db(
/*=====================*/
- /* out: TRUE if same db name */
- const char* name1, /* in: table name in the form
+ const char* name1, /*!< in: table name in the form
dbname '/' tablename */
- const char* name2); /* in: table name in the form
+ const char* name2); /*!< in: table name in the form
dbname '/' tablename */
-/*************************************************************************
+/*********************************************************************//**
Removes an index from the cache */
UNIV_INTERN
void
dict_index_remove_from_cache(
/*=========================*/
- dict_table_t* table, /* in/out: table */
- dict_index_t* index); /* in, own: index */
-/**************************************************************************
-Get index by name */
+ dict_table_t* table, /*!< in/out: table */
+ dict_index_t* index); /*!< in, own: index */
+/**********************************************************************//**
+Get index by name
+@return index, NULL if does not exist */
UNIV_INTERN
dict_index_t*
dict_table_get_index_on_name(
/*=========================*/
- /* out: index, NULL if does not exist */
- dict_table_t* table, /* in: table */
- const char* name); /* in: name of the index to find */
-/**************************************************************************
+ dict_table_t* table, /*!< in: table */
+ const char* name); /*!< in: name of the index to find */
+/**********************************************************************//**
In case there is more than one index with the same name return the index
-with the min(id). */
+with the min(id).
+@return index, NULL if does not exist */
UNIV_INTERN
dict_index_t*
dict_table_get_index_on_name_and_min_id(
/*====================================*/
- /* out: index, NULL if does not exist */
- dict_table_t* table, /* in: table */
- const char* name); /* in: name of the index to find */
+ dict_table_t* table, /*!< in: table */
+ const char* name); /*!< in: name of the index to find */
UNIV_INTERN
void
@@ -1113,38 +1109,53 @@ and unique key errors */
extern FILE* dict_foreign_err_file;
extern mutex_t dict_foreign_err_mutex; /* mutex protecting the buffers */
-extern dict_sys_t* dict_sys; /* the dictionary system */
+/** the dictionary system */
+extern dict_sys_t* dict_sys;
+/** the data dictionary rw-latch protecting dict_sys */
extern rw_lock_t dict_operation_lock;
/* Dictionary system struct */
struct dict_sys_struct{
- mutex_t mutex; /* mutex protecting the data
+ mutex_t mutex; /*!< mutex protecting the data
dictionary; protects also the
disk-based dictionary system tables;
this mutex serializes CREATE TABLE
and DROP TABLE, as well as reading
the dictionary data for a table from
system tables */
- dulint row_id; /* the next row id to assign;
+ dulint row_id; /*!< the next row id to assign;
NOTE that at a checkpoint this
must be written to the dict system
header and flushed to a file; in
recovery this must be derived from
the log records */
- hash_table_t* table_hash; /* hash table of the tables, based
+ hash_table_t* table_hash; /*!< hash table of the tables, based
on name */
- hash_table_t* table_id_hash; /* hash table of the tables, based
+ hash_table_t* table_id_hash; /*!< hash table of the tables, based
on id */
UT_LIST_BASE_NODE_T(dict_table_t)
- table_LRU; /* LRU list of tables */
- ulint size; /* varying space in bytes occupied
+ table_LRU; /*!< LRU list of tables */
+ ulint size; /*!< varying space in bytes occupied
by the data dictionary table and
index objects */
- dict_table_t* sys_tables; /* SYS_TABLES table */
- 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_tables; /*!< SYS_TABLES table */
+ dict_table_t* sys_columns; /*!< SYS_COLUMNS table */
+ dict_table_t* sys_indexes; /*!< SYS_INDEXES table */
+ dict_table_t* sys_fields; /*!< SYS_FIELDS table */
};
+#endif /* !UNIV_HOTBACKUP */
+
+/** dummy index for ROW_FORMAT=REDUNDANT supremum and infimum records */
+extern dict_index_t* dict_ind_redundant;
+/** dummy index for ROW_FORMAT=COMPACT supremum and infimum records */
+extern dict_index_t* dict_ind_compact;
+
+/**********************************************************************//**
+Inits dict_ind_redundant and dict_ind_compact. */
+UNIV_INTERN
+void
+dict_ind_init(void);
+/*===============*/
#ifndef UNIV_NONINL
#include "dict0dict.ic"
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic
index 687e5f9fb13..aada3096261 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -16,24 +16,26 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/dict0dict.ic
Data dictionary system
Created 1/8/1996 Heikki Tuuri
***********************************************************************/
+#include "data0type.h"
+#ifndef UNIV_HOTBACKUP
#include "dict0load.h"
#include "rem0types.h"
-#include "data0type.h"
-/*************************************************************************
+/*********************************************************************//**
Gets the column data type. */
UNIV_INLINE
void
dict_col_copy_type(
/*===============*/
- const dict_col_t* col, /* in: column */
- dtype_t* type) /* out: data type */
+ const dict_col_t* col, /*!< in: column */
+ dtype_t* type) /*!< out: data type */
{
ut_ad(col && type);
@@ -43,17 +45,18 @@ dict_col_copy_type(
type->mbminlen = col->mbminlen;
type->mbmaxlen = col->mbmaxlen;
}
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
-/*************************************************************************
-Assert that a column and a data type match. */
+/*********************************************************************//**
+Assert that a column and a data type match.
+@return TRUE */
UNIV_INLINE
ibool
dict_col_type_assert_equal(
/*=======================*/
- /* out: TRUE */
- const dict_col_t* col, /* in: column */
- const dtype_t* type) /* in: data type */
+ const dict_col_t* col, /*!< in: column */
+ const dtype_t* type) /*!< in: data type */
{
ut_ad(col);
ut_ad(type);
@@ -61,83 +64,89 @@ dict_col_type_assert_equal(
ut_ad(col->mtype == type->mtype);
ut_ad(col->prtype == type->prtype);
ut_ad(col->len == type->len);
+# ifndef UNIV_HOTBACKUP
ut_ad(col->mbminlen == type->mbminlen);
ut_ad(col->mbmaxlen == type->mbmaxlen);
+# endif /* !UNIV_HOTBACKUP */
return(TRUE);
}
#endif /* UNIV_DEBUG */
-/***************************************************************************
-Returns the minimum size of the column. */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
+Returns the minimum size of the column.
+@return minimum size */
UNIV_INLINE
ulint
dict_col_get_min_size(
/*==================*/
- /* out: minimum size */
- const dict_col_t* col) /* in: column */
+ const dict_col_t* col) /*!< in: column */
{
return(dtype_get_min_size_low(col->mtype, col->prtype, col->len,
col->mbminlen, col->mbmaxlen));
}
-/***************************************************************************
-Returns the maximum size of the column. */
+/***********************************************************************//**
+Returns the maximum size of the column.
+@return maximum size */
UNIV_INLINE
ulint
dict_col_get_max_size(
/*==================*/
- /* out: maximum size */
- const dict_col_t* col) /* in: column */
+ const dict_col_t* col) /*!< in: column */
{
return(dtype_get_max_size_low(col->mtype, col->len));
}
-/***************************************************************************
-Returns the size of a fixed size column, 0 if not a fixed size column. */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************************//**
+Returns the size of a fixed size column, 0 if not a fixed size column.
+@return fixed size, or 0 */
UNIV_INLINE
ulint
dict_col_get_fixed_size(
/*====================*/
- /* out: fixed size, or 0 */
- const dict_col_t* col) /* in: column */
+ const dict_col_t* col, /*!< in: column */
+ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len,
- col->mbminlen, col->mbmaxlen));
+ col->mbminlen, col->mbmaxlen, comp));
}
-/***************************************************************************
+/***********************************************************************//**
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
-For fixed length types it is the fixed length of the type, otherwise 0. */
+For fixed length types it is the fixed length of the type, otherwise 0.
+@return SQL null storage size in ROW_FORMAT=REDUNDANT */
UNIV_INLINE
ulint
dict_col_get_sql_null_size(
/*=======================*/
- /* out: SQL null storage size
- in ROW_FORMAT=REDUNDANT */
- const dict_col_t* col) /* in: column */
+ const dict_col_t* col, /*!< in: column */
+ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */
{
- return(dict_col_get_fixed_size(col));
+ return(dict_col_get_fixed_size(col, comp));
}
-/*************************************************************************
-Gets the column number. */
+/*********************************************************************//**
+Gets the column number.
+@return col->ind, table column position (starting from 0) */
UNIV_INLINE
ulint
dict_col_get_no(
/*============*/
- const dict_col_t* col)
+ const dict_col_t* col) /*!< in: column */
{
ut_ad(col);
return(col->ind);
}
-/*************************************************************************
+/*********************************************************************//**
Gets the column position in the clustered index. */
UNIV_INLINE
ulint
dict_col_get_clust_pos(
/*===================*/
- const dict_col_t* col, /* in: table column */
- const dict_index_t* clust_index) /* in: clustered index */
+ const dict_col_t* col, /*!< in: table column */
+ const dict_index_t* clust_index) /*!< in: clustered index */
{
ulint i;
@@ -156,15 +165,16 @@ dict_col_get_clust_pos(
return(ULINT_UNDEFINED);
}
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_DEBUG
-/************************************************************************
-Gets the first index on the table (the clustered index). */
+/********************************************************************//**
+Gets the first index on the table (the clustered index).
+@return index, NULL if none exists */
UNIV_INLINE
dict_index_t*
dict_table_get_first_index(
/*=======================*/
- /* out: index, NULL if none exists */
- const dict_table_t* table) /* in: table */
+ const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
@@ -172,14 +182,14 @@ dict_table_get_first_index(
return(UT_LIST_GET_FIRST(((dict_table_t*) table)->indexes));
}
-/************************************************************************
-Gets the next index on the table. */
+/********************************************************************//**
+Gets the next index on the table.
+@return index, NULL if none left */
UNIV_INLINE
dict_index_t*
dict_table_get_next_index(
/*======================*/
- /* out: index, NULL if none left */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -187,31 +197,30 @@ dict_table_get_next_index(
return(UT_LIST_GET_NEXT(indexes, (dict_index_t*) index));
}
#endif /* UNIV_DEBUG */
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
-Check whether the index is the clustered index. */
+/********************************************************************//**
+Check whether the index is the clustered index.
+@return nonzero for clustered index, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_clust(
/*================*/
- /* out: nonzero for clustered index,
- zero for other indexes */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
return(UNIV_UNLIKELY(index->type & DICT_CLUSTERED));
}
-/************************************************************************
-Check whether the index is unique. */
+/********************************************************************//**
+Check whether the index is unique.
+@return nonzero for unique index, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_unique(
/*=================*/
- /* out: nonzero for unique index,
- zero for other indexes */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -219,15 +228,14 @@ dict_index_is_unique(
return(UNIV_UNLIKELY(index->type & DICT_UNIQUE));
}
-/************************************************************************
-Check whether the index is the insert buffer tree. */
+/********************************************************************//**
+Check whether the index is the insert buffer tree.
+@return nonzero for insert buffer, zero for other indexes */
UNIV_INLINE
ulint
dict_index_is_ibuf(
/*===============*/
- /* out: nonzero for insert buffer,
- zero for other indexes */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -235,17 +243,34 @@ dict_index_is_ibuf(
return(UNIV_UNLIKELY(index->type & DICT_IBUF));
}
-/************************************************************************
+/********************************************************************//**
+Check whether the index is a secondary index or the insert buffer tree.
+@return nonzero for insert buffer, zero for other indexes */
+UNIV_INLINE
+ulint
+dict_index_is_sec_or_ibuf(
+/*======================*/
+ const dict_index_t* index) /*!< in: index */
+{
+ ulint type;
+
+ ut_ad(index);
+ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
+
+ type = index->type;
+
+ return(UNIV_LIKELY(!(type & DICT_CLUSTERED) || (type & DICT_IBUF)));
+}
+
+/********************************************************************//**
Gets the number of user-defined columns in a table in the dictionary
-cache. */
+cache.
+@return number of user-defined (e.g., not ROW_ID) columns of a table */
UNIV_INLINE
ulint
dict_table_get_n_user_cols(
/*=======================*/
- /* out: number of user-defined
- (e.g., not ROW_ID)
- columns of a table */
- const dict_table_t* table) /* in: table */
+ const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
@@ -253,15 +278,14 @@ dict_table_get_n_user_cols(
return(table->n_cols - DATA_N_SYS_COLS);
}
-/************************************************************************
-Gets the number of system columns in a table in the dictionary cache. */
+/********************************************************************//**
+Gets the number of system columns in a table in the dictionary cache.
+@return number of system (e.g., ROW_ID) columns of a table */
UNIV_INLINE
ulint
dict_table_get_n_sys_cols(
/*======================*/
- /* out: number of system (e.g.,
- ROW_ID) columns of a table */
- const dict_table_t* table __attribute__((unused))) /* in: table */
+ const dict_table_t* table __attribute__((unused))) /*!< in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
@@ -270,15 +294,15 @@ dict_table_get_n_sys_cols(
return(DATA_N_SYS_COLS);
}
-/************************************************************************
+/********************************************************************//**
Gets the number of all columns (also system) in a table in the dictionary
-cache. */
+cache.
+@return number of columns of a table */
UNIV_INLINE
ulint
dict_table_get_n_cols(
/*==================*/
- /* out: number of columns of a table */
- const dict_table_t* table) /* in: table */
+ const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
@@ -287,15 +311,15 @@ dict_table_get_n_cols(
}
#ifdef UNIV_DEBUG
-/************************************************************************
-Gets the nth column of a table. */
+/********************************************************************//**
+Gets the nth column of a table.
+@return pointer to column object */
UNIV_INLINE
dict_col_t*
dict_table_get_nth_col(
/*===================*/
- /* out: pointer to column object */
- const dict_table_t* table, /* in: table */
- ulint pos) /* in: position of column */
+ const dict_table_t* table, /*!< in: table */
+ ulint pos) /*!< in: position of column */
{
ut_ad(table);
ut_ad(pos < table->n_def);
@@ -304,15 +328,15 @@ dict_table_get_nth_col(
return((dict_col_t*) (table->cols) + pos);
}
-/************************************************************************
-Gets the given system column of a table. */
+/********************************************************************//**
+Gets the given system column of a table.
+@return pointer to column object */
UNIV_INLINE
dict_col_t*
dict_table_get_sys_col(
/*===================*/
- /* out: pointer to column object */
- const dict_table_t* table, /* in: table */
- ulint sys) /* in: DATA_ROW_ID, ... */
+ const dict_table_t* table, /*!< in: table */
+ ulint sys) /*!< in: DATA_ROW_ID, ... */
{
dict_col_t* col;
@@ -329,15 +353,15 @@ dict_table_get_sys_col(
}
#endif /* UNIV_DEBUG */
-/************************************************************************
-Gets the given system column number of a table. */
+/********************************************************************//**
+Gets the given system column number of a table.
+@return column number */
UNIV_INLINE
ulint
dict_table_get_sys_col_no(
/*======================*/
- /* out: column number */
- const dict_table_t* table, /* in: table */
- ulint sys) /* in: DATA_ROW_ID, ... */
+ const dict_table_t* table, /*!< in: table */
+ ulint sys) /*!< in: DATA_ROW_ID, ... */
{
ut_ad(table);
ut_ad(sys < DATA_N_SYS_COLS);
@@ -346,15 +370,14 @@ dict_table_get_sys_col_no(
return(table->n_cols - DATA_N_SYS_COLS + sys);
}
-/************************************************************************
-Check whether the table uses the compact page format. */
+/********************************************************************//**
+Check whether the table uses the compact page format.
+@return TRUE if table uses the compact page format */
UNIV_INLINE
ibool
dict_table_is_comp(
/*===============*/
- /* out: TRUE if table uses the
- compact page format */
- const dict_table_t* table) /* in: table */
+ const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
@@ -365,28 +388,28 @@ dict_table_is_comp(
return(UNIV_LIKELY(table->flags & DICT_TF_COMPACT));
}
-/************************************************************************
-Determine the file format of a table. */
+/********************************************************************//**
+Determine the file format of a table.
+@return file format version */
UNIV_INLINE
ulint
dict_table_get_format(
/*==================*/
- /* out: file format version */
- const dict_table_t* table) /* in: table */
+ const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
return((table->flags & DICT_TF_FORMAT_MASK) >> DICT_TF_FORMAT_SHIFT);
}
-/************************************************************************
+/********************************************************************//**
Determine the file format of a table. */
UNIV_INLINE
void
dict_table_set_format(
/*==================*/
- dict_table_t* table, /* in/out: table */
- ulint format) /* in: file format version */
+ dict_table_t* table, /*!< in/out: table */
+ ulint format) /*!< in: file format version */
{
ut_ad(table);
@@ -394,15 +417,14 @@ dict_table_set_format(
| (format << DICT_TF_FORMAT_SHIFT);
}
-/************************************************************************
-Extract the compressed page size from table flags. */
+/********************************************************************//**
+Extract the compressed page size from table flags.
+@return compressed page size, or 0 if not compressed */
UNIV_INLINE
ulint
dict_table_flags_to_zip_size(
/*=========================*/
- /* out: compressed page size,
- or 0 if not compressed */
- ulint flags) /* in: flags */
+ ulint flags) /*!< in: flags */
{
ulint zip_size = flags & DICT_TF_ZSSIZE_MASK;
@@ -416,30 +438,29 @@ dict_table_flags_to_zip_size(
return(zip_size);
}
-/************************************************************************
-Check whether the table uses the compressed compact page format. */
+/********************************************************************//**
+Check whether the table uses the compressed compact page format.
+@return compressed page size, or 0 if not compressed */
UNIV_INLINE
ulint
dict_table_zip_size(
/*================*/
- /* out: compressed page size,
- or 0 if not compressed */
- const dict_table_t* table) /* in: table */
+ const dict_table_t* table) /*!< in: table */
{
ut_ad(table);
return(dict_table_flags_to_zip_size(table->flags));
}
-/************************************************************************
+/********************************************************************//**
Gets the number of fields in the internal representation of an index,
-including fields added by the dictionary system. */
+including fields added by the dictionary system.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_fields(
/*====================*/
- /* out: number of fields */
- const dict_index_t* index) /* in: an internal
+ const dict_index_t* index) /*!< in: an internal
representation of index (in
the dictionary cache) */
{
@@ -449,17 +470,17 @@ dict_index_get_n_fields(
return(index->n_fields);
}
-/************************************************************************
+/********************************************************************//**
Gets the number of fields in the internal representation of an index
that uniquely determine the position of an index entry in the index, if
we do not take multiversioning into account: in the B-tree use the value
-returned by dict_index_get_n_unique_in_tree. */
+returned by dict_index_get_n_unique_in_tree.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_unique(
/*====================*/
- /* out: number of fields */
- const dict_index_t* index) /* in: an internal representation
+ const dict_index_t* index) /*!< in: an internal representation
of index (in the dictionary cache) */
{
ut_ad(index);
@@ -469,16 +490,16 @@ dict_index_get_n_unique(
return(index->n_uniq);
}
-/************************************************************************
+/********************************************************************//**
Gets the number of fields in the internal representation of an index
which uniquely determine the position of an index entry in the index, if
-we also take multiversioning into account. */
+we also take multiversioning into account.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_unique_in_tree(
/*============================*/
- /* out: number of fields */
- const dict_index_t* index) /* in: an internal representation
+ const dict_index_t* index) /*!< in: an internal representation
of index (in the dictionary cache) */
{
ut_ad(index);
@@ -493,32 +514,32 @@ dict_index_get_n_unique_in_tree(
return(dict_index_get_n_fields(index));
}
-/************************************************************************
+/********************************************************************//**
Gets the number of user-defined ordering fields in the index. In the internal
representation of clustered indexes we add the row id to the ordering fields
to make a clustered index unique, but this function returns the number of
-fields the user defined in the index as ordering fields. */
+fields the user defined in the index as ordering fields.
+@return number of fields */
UNIV_INLINE
ulint
dict_index_get_n_ordering_defined_by_user(
/*======================================*/
- /* out: number of fields */
- const dict_index_t* index) /* in: an internal representation
+ const dict_index_t* index) /*!< in: an internal representation
of index (in the dictionary cache) */
{
return(index->n_user_defined_cols);
}
#ifdef UNIV_DEBUG
-/************************************************************************
-Gets the nth field of an index. */
+/********************************************************************//**
+Gets the nth field of an index.
+@return pointer to field object */
UNIV_INLINE
dict_field_t*
dict_index_get_nth_field(
/*=====================*/
- /* out: pointer to field object */
- const dict_index_t* index, /* in: index */
- ulint pos) /* in: position of field */
+ const dict_index_t* index, /*!< in: index */
+ ulint pos) /*!< in: position of field */
{
ut_ad(index);
ut_ad(pos < index->n_def);
@@ -528,16 +549,15 @@ dict_index_get_nth_field(
}
#endif /* UNIV_DEBUG */
-/************************************************************************
-Returns the position of a system column in an index. */
+/********************************************************************//**
+Returns the position of a system column in an index.
+@return position, ULINT_UNDEFINED if not contained */
UNIV_INLINE
ulint
dict_index_get_sys_col_pos(
/*=======================*/
- /* out: position,
- ULINT_UNDEFINED if not contained */
- const dict_index_t* index, /* in: index */
- ulint type) /* in: DATA_ROW_ID, ... */
+ const dict_index_t* index, /*!< in: index */
+ ulint type) /*!< in: DATA_ROW_ID, ... */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -554,53 +574,55 @@ dict_index_get_sys_col_pos(
index, dict_table_get_sys_col_no(index->table, type)));
}
-/*************************************************************************
-Gets the field column. */
+/*********************************************************************//**
+Gets the field column.
+@return field->col, pointer to the table column */
UNIV_INLINE
const dict_col_t*
dict_field_get_col(
/*===============*/
- const dict_field_t* field)
+ const dict_field_t* field) /*!< in: index field */
{
ut_ad(field);
return(field->col);
}
-/************************************************************************
-Gets pointer to the nth column in an index. */
+/********************************************************************//**
+Gets pointer to the nth column in an index.
+@return column */
UNIV_INLINE
const dict_col_t*
dict_index_get_nth_col(
/*===================*/
- /* out: column */
- const dict_index_t* index, /* in: index */
- ulint pos) /* in: position of the field */
+ const dict_index_t* index, /*!< in: index */
+ ulint pos) /*!< in: position of the field */
{
return(dict_field_get_col(dict_index_get_nth_field(index, pos)));
}
-/************************************************************************
-Gets the column number the nth field in an index. */
+/********************************************************************//**
+Gets the column number the nth field in an index.
+@return column number */
UNIV_INLINE
ulint
dict_index_get_nth_col_no(
/*======================*/
- /* out: column number */
- const dict_index_t* index, /* in: index */
- ulint pos) /* in: position of the field */
+ const dict_index_t* index, /*!< in: index */
+ ulint pos) /*!< in: position of the field */
{
return(dict_col_get_no(dict_index_get_nth_col(index, pos)));
}
-/************************************************************************
-Returns the minimum data size of an index record. */
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Returns the minimum data size of an index record.
+@return minimum data size in bytes */
UNIV_INLINE
ulint
dict_index_get_min_size(
/*====================*/
- /* out: minimum data size in bytes */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ulint n = dict_index_get_n_fields(index);
ulint size = 0;
@@ -613,14 +635,14 @@ dict_index_get_min_size(
return(size);
}
-/*************************************************************************
-Gets the space id of the root of the index tree. */
+/*********************************************************************//**
+Gets the space id of the root of the index tree.
+@return space id */
UNIV_INLINE
ulint
dict_index_get_space(
/*=================*/
- /* out: space id */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -628,14 +650,14 @@ dict_index_get_space(
return(index->space);
}
-/*************************************************************************
+/*********************************************************************//**
Sets the space id of the root of the index tree. */
UNIV_INLINE
void
dict_index_set_space(
/*=================*/
- dict_index_t* index, /* in/out: index */
- ulint space) /* in: space id */
+ dict_index_t* index, /*!< in/out: index */
+ ulint space) /*!< in: space id */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -643,14 +665,14 @@ dict_index_set_space(
index->space = space;
}
-/*************************************************************************
-Gets the page number of the root of the index tree. */
+/*********************************************************************//**
+Gets the page number of the root of the index tree.
+@return page number */
UNIV_INLINE
ulint
dict_index_get_page(
/*================*/
- /* out: page number */
- const dict_index_t* index) /* in: index */
+ const dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -658,14 +680,14 @@ dict_index_get_page(
return(index->page);
}
-/*************************************************************************
+/*********************************************************************//**
Sets the page number of the root of index tree. */
UNIV_INLINE
void
dict_index_set_page(
/*================*/
- dict_index_t* index, /* in/out: index */
- ulint page) /* in: page number */
+ dict_index_t* index, /*!< in/out: index */
+ ulint page) /*!< in: page number */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -673,14 +695,14 @@ dict_index_set_page(
index->page = page;
}
-/*************************************************************************
-Gets the read-write lock of the index tree. */
+/*********************************************************************//**
+Gets the read-write lock of the index tree.
+@return read-write lock */
UNIV_INLINE
rw_lock_t*
dict_index_get_lock(
/*================*/
- /* out: read-write lock */
- dict_index_t* index) /* in: index */
+ dict_index_t* index) /*!< in: index */
{
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
@@ -688,28 +710,27 @@ dict_index_get_lock(
return(&(index->lock));
}
-/************************************************************************
+/********************************************************************//**
Returns free space reserved for future updates of records. This is
relevant only in the case of many consecutive inserts, as updates
-which make the records bigger might fragment the index. */
+which make the records bigger might fragment the index.
+@return number of free bytes on page, reserved for updates */
UNIV_INLINE
ulint
dict_index_get_space_reserve(void)
/*==============================*/
- /* out: number of free bytes on page,
- reserved for updates */
{
return(UNIV_PAGE_SIZE / 16);
}
-/**************************************************************************
-Checks if a table is in the dictionary cache. */
+/**********************************************************************//**
+Checks if a table is in the dictionary cache.
+@return table, NULL if not found */
UNIV_INLINE
dict_table_t*
dict_table_check_if_in_cache_low(
/*=============================*/
- /* out: table, NULL if not found */
- const char* table_name) /* in: table name */
+ const char* table_name) /*!< in: table name */
{
dict_table_t* table;
ulint table_fold;
@@ -733,15 +754,15 @@ dict_table_check_if_in_cache_low(
return(table);
}
-/**************************************************************************
+/**********************************************************************//**
Gets a table; loads it to the dictionary cache if necessary. A low-level
-function. */
+function.
+@return table, NULL if not found */
UNIV_INLINE
dict_table_t*
dict_table_get_low(
/*===============*/
- /* out: table, NULL if not found */
- const char* table_name) /* in: table name */
+ const char* table_name) /*!< in: table name */
{
dict_table_t* table;
@@ -759,14 +780,14 @@ dict_table_get_low(
return(table);
}
-/**************************************************************************
-Returns a table object based on table id. */
+/**********************************************************************//**
+Returns a table object based on table id.
+@return table, NULL if does not exist */
UNIV_INLINE
dict_table_t*
dict_table_get_on_id_low(
/*=====================*/
- /* out: table, NULL if does not exist */
- dulint table_id) /* in: table id */
+ dulint table_id) /*!< in: table id */
{
dict_table_t* table;
ulint fold;
@@ -795,4 +816,4 @@ dict_table_get_on_id_low(
return(table);
}
-
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/dict0load.h b/storage/xtradb/include/dict0load.h
index 759cbcdb14a..60b8c1fb632 100644
--- a/storage/xtradb/include/dict0load.h
+++ b/storage/xtradb/include/dict0load.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0load.h
Loads to the memory cache database object definitions
from dictionary tables
@@ -31,7 +32,7 @@ Created 4/24/1996 Heikki Tuuri
#include "ut0byte.h"
#include "mem0mem.h"
-/************************************************************************
+/********************************************************************//**
In a crash recovery we already have all the tablespace objects created.
This function compares the space id information in the InnoDB data dictionary
to what we already read with fil_load_single_table_tablespaces().
@@ -43,42 +44,39 @@ UNIV_INTERN
void
dict_check_tablespaces_and_store_max_id(
/*====================================*/
- ibool in_crash_recovery); /* in: are we doing a crash recovery */
-/************************************************************************
-Finds the first table name in the given database. */
+ ibool in_crash_recovery); /*!< in: are we doing a crash recovery */
+/********************************************************************//**
+Finds the first table name in the given database.
+@return own: table name, NULL if does not exist; the caller must free
+the memory in the string! */
UNIV_INTERN
char*
dict_get_first_table_name_in_db(
/*============================*/
- /* out, own: table name, NULL if
- does not exist; the caller must free
- the memory in the string! */
- const char* name); /* in: database name which ends to '/' */
-/************************************************************************
+ const char* name); /*!< in: database name which ends to '/' */
+/********************************************************************//**
Loads a table definition and also all its index definitions, and also
the cluster definition if the table is a member in a cluster. Also loads
all foreign key constraints where the foreign key is in the table or where
-a foreign key references columns in this table. */
+a foreign key references columns in this table.
+@return table, NULL if does not exist; if the table is stored in an
+.ibd file, but the file does not exist, then we set the
+ibd_file_missing flag TRUE in the table object we return */
UNIV_INTERN
dict_table_t*
dict_load_table(
/*============*/
- /* out: table, NULL if does not exist;
- if the table is stored in an .ibd file,
- but the file does not exist,
- then we set the ibd_file_missing flag TRUE
- in the table object we return */
- const char* name); /* in: table name in the
+ const char* name); /*!< in: table name in the
databasename/tablename format */
-/***************************************************************************
-Loads a table object based on the table id. */
+/***********************************************************************//**
+Loads a table object based on the table id.
+@return table; NULL if table does not exist */
UNIV_INTERN
dict_table_t*
dict_load_table_on_id(
/*==================*/
- /* out: table; NULL if table does not exist */
- dulint table_id); /* in: table id */
-/************************************************************************
+ dulint table_id); /*!< in: table id */
+/********************************************************************//**
This function is called when the database is booted.
Loads system table index definitions except for the clustered index which
is added to the dictionary cache at booting before calling this function. */
@@ -86,24 +84,22 @@ UNIV_INTERN
void
dict_load_sys_table(
/*================*/
- dict_table_t* table); /* in: system table */
-#ifndef UNIV_HOTBACKUP
-/***************************************************************************
+ dict_table_t* table); /*!< in: system table */
+/***********************************************************************//**
Loads foreign key constraints where the table is either the foreign key
holder or where the table is referenced by a foreign key. Adds these
constraints to the data dictionary. Note that we know that the dictionary
cache already contains all constraints where the other relevant table is
-already in the dictionary cache. */
+already in the dictionary cache.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
dict_load_foreigns(
/*===============*/
- /* out: DB_SUCCESS or error code */
- const char* table_name, /* in: table name */
- ibool check_charsets);/* in: TRUE=check charsets
+ const char* table_name, /*!< in: table name */
+ ibool check_charsets);/*!< in: TRUE=check charsets
compatibility */
-#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
+/********************************************************************//**
Prints to the standard output information on all tables found in the data
dictionary system table. */
UNIV_INTERN
diff --git a/storage/xtradb/include/dict0load.ic b/storage/xtradb/include/dict0load.ic
index 72eac2f621a..ccc16db165b 100644
--- a/storage/xtradb/include/dict0load.ic
+++ b/storage/xtradb/include/dict0load.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0load.ic
Loads to the memory cache database object definitions
from dictionary tables
diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h
index e2b3cfa3679..1ee906fbf57 100644
--- a/storage/xtradb/include/dict0mem.h
+++ b/storage/xtradb/include/dict0mem.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0mem.h
Data dictionary memory object creation
Created 1/8/1996 Heikki Tuuri
@@ -31,107 +32,118 @@ Created 1/8/1996 Heikki Tuuri
#include "mem0mem.h"
#include "rem0types.h"
#include "btr0types.h"
+#ifndef UNIV_HOTBACKUP
+# include "lock0types.h"
+# include "que0types.h"
+# include "sync0rw.h"
+#endif /* !UNIV_HOTBACKUP */
#include "ut0mem.h"
#include "ut0lst.h"
#include "ut0rnd.h"
#include "ut0byte.h"
-#include "sync0rw.h"
-#include "lock0types.h"
#include "hash0hash.h"
-#include "que0types.h"
#include "trx0types.h"
-/* Type flags of an index: OR'ing of the flags is allowed to define a
+/** Type flags of an index: OR'ing of the flags is allowed to define a
combination of types */
-#define DICT_CLUSTERED 1 /* clustered index */
-#define DICT_UNIQUE 2 /* unique index */
-#define DICT_UNIVERSAL 4 /* index which can contain records from any
+/* @{ */
+#define DICT_CLUSTERED 1 /*!< clustered index */
+#define DICT_UNIQUE 2 /*!< unique index */
+#define DICT_UNIVERSAL 4 /*!< index which can contain records from any
other index */
-#define DICT_IBUF 8 /* insert buffer tree */
+#define DICT_IBUF 8 /*!< insert buffer tree */
+/* @} */
-/* Types for a table object */
-#define DICT_TABLE_ORDINARY 1
+/** Types for a table object */
+#define DICT_TABLE_ORDINARY 1 /*!< ordinary table */
#if 0 /* not implemented */
#define DICT_TABLE_CLUSTER_MEMBER 2
#define DICT_TABLE_CLUSTER 3 /* this means that the table is
really a cluster definition */
#endif
-/* Table flags. All unused bits must be 0. */
+/** Table flags. All unused bits must be 0. */
+/* @{ */
#define DICT_TF_COMPACT 1 /* Compact page format.
This must be set for
new file formats
(later than
DICT_TF_FORMAT_51). */
-/* compressed page size (0=uncompressed, up to 15 compressed sizes) */
+/** Compressed page size (0=uncompressed, up to 15 compressed sizes) */
+/* @{ */
#define DICT_TF_ZSSIZE_SHIFT 1
#define DICT_TF_ZSSIZE_MASK (15 << DICT_TF_ZSSIZE_SHIFT)
#define DICT_TF_ZSSIZE_MAX (UNIV_PAGE_SIZE_SHIFT - PAGE_ZIP_MIN_SIZE_SHIFT + 1)
+/* @} */
-
+/** File format */
+/* @{ */
#define DICT_TF_FORMAT_SHIFT 5 /* file format */
#define DICT_TF_FORMAT_MASK (127 << DICT_TF_FORMAT_SHIFT)
-#define DICT_TF_FORMAT_51 0 /* InnoDB/MySQL up to 5.1 */
-#define DICT_TF_FORMAT_ZIP 1 /* InnoDB plugin for 5.1:
+#define DICT_TF_FORMAT_51 0 /*!< InnoDB/MySQL up to 5.1 */
+#define DICT_TF_FORMAT_ZIP 1 /*!< InnoDB plugin for 5.1:
compressed tables,
new BLOB treatment */
+/** Maximum supported file format */
#define DICT_TF_FORMAT_MAX DICT_TF_FORMAT_ZIP
-#define DICT_TF_BITS 6 /* number of flag bits */
+#define DICT_TF_BITS 6 /*!< number of flag bits */
#if (1 << (DICT_TF_BITS - DICT_TF_FORMAT_SHIFT)) <= DICT_TF_FORMAT_MAX
# error "DICT_TF_BITS is insufficient for DICT_TF_FORMAT_MAX"
#endif
+/* @} */
+/* @} */
-/**************************************************************************
-Creates a table memory object. */
+/**********************************************************************//**
+Creates a table memory object.
+@return own: table object */
UNIV_INTERN
dict_table_t*
dict_mem_table_create(
/*==================*/
- /* out, own: table object */
- const char* name, /* in: table name */
- ulint space, /* in: space where the clustered index
+ const char* name, /*!< in: table name */
+ ulint space, /*!< in: space where the clustered index
of the table is placed; this parameter
is ignored if the table is made
a member of a cluster */
- ulint n_cols, /* in: number of columns */
- ulint flags); /* in: table flags */
-/********************************************************************
+ ulint n_cols, /*!< in: number of columns */
+ ulint flags); /*!< in: table flags */
+/****************************************************************//**
Free a table memory object. */
UNIV_INTERN
void
dict_mem_table_free(
/*================*/
- dict_table_t* table); /* in: table */
-/**************************************************************************
+ dict_table_t* table); /*!< in: table */
+/**********************************************************************//**
Adds a column definition to a table. */
UNIV_INTERN
void
dict_mem_table_add_col(
/*===================*/
- dict_table_t* table, /* in: table */
- mem_heap_t* heap, /* in: temporary memory heap, or NULL */
- const char* name, /* in: column name, or NULL */
- ulint mtype, /* in: main datatype */
- ulint prtype, /* in: precise type */
- ulint len); /* in: precision */
-/**************************************************************************
-Creates an index memory object. */
+ dict_table_t* table, /*!< in: table */
+ mem_heap_t* heap, /*!< in: temporary memory heap, or NULL */
+ const char* name, /*!< in: column name, or NULL */
+ ulint mtype, /*!< in: main datatype */
+ ulint prtype, /*!< in: precise type */
+ ulint len); /*!< in: precision */
+/**********************************************************************//**
+Creates an index memory object.
+@return own: index object */
UNIV_INTERN
dict_index_t*
dict_mem_index_create(
/*==================*/
- /* out, own: index object */
- const char* table_name, /* in: table name */
- const char* index_name, /* in: index name */
- ulint space, /* in: space where the index tree is
+ const char* table_name, /*!< in: table name */
+ const char* index_name, /*!< in: index name */
+ ulint space, /*!< in: space where the index tree is
placed, ignored if the index is of
the clustered type */
- ulint type, /* in: DICT_UNIQUE,
+ ulint type, /*!< in: DICT_UNIQUE,
DICT_CLUSTERED, ... ORed */
- ulint n_fields); /* in: number of fields */
-/**************************************************************************
+ ulint n_fields); /*!< in: number of fields */
+/**********************************************************************//**
Adds a field definition to an index. NOTE: does not take a copy
of the column name if the field is a column. The memory occupied
by the column name may be released only after publishing the index. */
@@ -139,33 +151,34 @@ UNIV_INTERN
void
dict_mem_index_add_field(
/*=====================*/
- dict_index_t* index, /* in: index */
- const char* name, /* in: column name */
- ulint prefix_len); /* in: 0 or the column prefix length
+ dict_index_t* index, /*!< in: index */
+ const char* name, /*!< in: column name */
+ ulint prefix_len); /*!< in: 0 or the column prefix length
in a MySQL index like
INDEX (textcol(25)) */
-/**************************************************************************
+/**********************************************************************//**
Frees an index memory object. */
UNIV_INTERN
void
dict_mem_index_free(
/*================*/
- dict_index_t* index); /* in: index */
-/**************************************************************************
-Creates and initializes a foreign constraint memory object. */
+ dict_index_t* index); /*!< in: index */
+/**********************************************************************//**
+Creates and initializes a foreign constraint memory object.
+@return own: foreign constraint struct */
UNIV_INTERN
dict_foreign_t*
dict_mem_foreign_create(void);
/*=========================*/
- /* out, own: foreign constraint struct */
-/* Data structure for a column in a table */
+/** Data structure for a column in a table */
struct dict_col_struct{
/*----------------------*/
- /* The following are copied from dtype_t,
+ /** The following are copied from dtype_t,
so that all bit-fields can be packed tightly. */
- unsigned mtype:8; /* main data type */
- unsigned prtype:24; /* precise type; MySQL data
+ /* @{ */
+ unsigned mtype:8; /*!< main data type */
+ unsigned prtype:24; /*!< precise type; MySQL data
type, charset code, flags to
indicate nullability,
signedness, whether this is a
@@ -175,7 +188,7 @@ struct dict_col_struct{
/* the remaining fields do not affect alphabetical ordering: */
- unsigned len:16; /* length; for MySQL data this
+ unsigned len:16; /*!< length; for MySQL data this
is field->pack_length(),
except that for a >= 5.0.3
type true VARCHAR this is the
@@ -184,258 +197,276 @@ struct dict_col_struct{
the string, MySQL uses 1 or 2
bytes to store the string length) */
- unsigned mbminlen:2; /* minimum length of a
+ unsigned mbminlen:2; /*!< minimum length of a
character, in bytes */
- unsigned mbmaxlen:3; /* maximum length of a
+ unsigned mbmaxlen:3; /*!< maximum length of a
character, in bytes */
/*----------------------*/
/* End of definitions copied from dtype_t */
+ /* @} */
- unsigned ind:10; /* table column position
+ unsigned ind:10; /*!< table column position
(starting from 0) */
- unsigned ord_part:1; /* nonzero if this column
+ unsigned ord_part:1; /*!< nonzero if this column
appears in the ordering fields
of an index */
};
-/* DICT_MAX_INDEX_COL_LEN is measured in bytes and is the maximum
-indexed column length (or indexed prefix length). It is set to 3*256,
-so that one can create a column prefix index on 256 characters of a
-TEXT or VARCHAR column also in the UTF-8 charset. In that charset,
-a character may take at most 3 bytes.
-This constant MUST NOT BE CHANGED, or the compatibility of InnoDB data
-files would be at risk! */
+/** @brief DICT_MAX_INDEX_COL_LEN is measured in bytes and is the maximum
+indexed column length (or indexed prefix length).
+It is set to 3*256, so that one can create a column prefix index on
+256 characters of a TEXT or VARCHAR column also in the UTF-8
+charset. In that charset, a character may take at most 3 bytes. This
+constant MUST NOT BE CHANGED, or the compatibility of InnoDB data
+files would be at risk! */
#define DICT_MAX_INDEX_COL_LEN REC_MAX_INDEX_COL_LEN
-/* Data structure for a field in an index */
+/** Data structure for a field in an index */
struct dict_field_struct{
- dict_col_t* col; /* pointer to the table column */
- const char* name; /* name of the column */
- unsigned prefix_len:10; /* 0 or the length of the column
+ dict_col_t* col; /*!< pointer to the table column */
+ const char* name; /*!< name of the column */
+ unsigned prefix_len:10; /*!< 0 or the length of the column
prefix in bytes in a MySQL index of
type, e.g., INDEX (textcol(25));
must be smaller than
DICT_MAX_INDEX_COL_LEN; NOTE that
in the UTF-8 charset, MySQL sets this
to 3 * the prefix len in UTF-8 chars */
- unsigned fixed_len:10; /* 0 or the fixed length of the
+ unsigned fixed_len:10; /*!< 0 or the fixed length of the
column if smaller than
DICT_MAX_INDEX_COL_LEN */
};
-/* Data structure for an index. Most fields will be
+/** Data structure for an index. Most fields will be
initialized to 0, NULL or FALSE in dict_mem_index_create(). */
struct dict_index_struct{
- dulint id; /* id of the index */
- mem_heap_t* heap; /* memory heap */
- const char* name; /* index name */
- const char* table_name; /* table name */
- dict_table_t* table; /* back pointer to table */
+ dulint id; /*!< id of the index */
+ mem_heap_t* heap; /*!< memory heap */
+ const char* name; /*!< index name */
+ const char* table_name;/*!< table name */
+ dict_table_t* table; /*!< back pointer to table */
+#ifndef UNIV_HOTBACKUP
unsigned space:32;
- /* space where the index tree is placed */
- unsigned page:32;/* index tree root page number */
- unsigned type:4; /* index type (DICT_CLUSTERED, DICT_UNIQUE,
+ /*!< space where the index tree is placed */
+ unsigned page:32;/*!< index tree root page number */
+#endif /* !UNIV_HOTBACKUP */
+ unsigned type:4; /*!< index type (DICT_CLUSTERED, DICT_UNIQUE,
DICT_UNIVERSAL, DICT_IBUF) */
- unsigned trx_id_offset:10;/* position of the trx id column
+ unsigned trx_id_offset:10;/*!< position of the trx id column
in a clustered index record, if the fields
before it are known to be of a fixed size,
0 otherwise */
unsigned n_user_defined_cols:10;
- /* number of columns the user defined to
+ /*!< number of columns the user defined to
be in the index: in the internal
representation we add more columns */
- unsigned n_uniq:10;/* number of fields from the beginning
+ unsigned n_uniq:10;/*!< number of fields from the beginning
which are enough to determine an index
entry uniquely */
- unsigned n_def:10;/* number of fields defined so far */
- unsigned n_fields:10;/* number of fields in the index */
- unsigned n_nullable:10;/* number of nullable fields */
- unsigned cached:1;/* TRUE if the index object is in the
+ unsigned n_def:10;/*!< number of fields defined so far */
+ unsigned n_fields:10;/*!< number of fields in the index */
+ unsigned n_nullable:10;/*!< number of nullable fields */
+ unsigned cached:1;/*!< TRUE if the index object is in the
dictionary cache */
unsigned to_be_dropped:1;
- /* TRUE if this index is marked to be
+ /*!< TRUE if this index is marked to be
dropped in ha_innobase::prepare_drop_index(),
otherwise FALSE */
- dict_field_t* fields; /* array of field descriptions */
+ dict_field_t* fields; /*!< array of field descriptions */
+#ifndef UNIV_HOTBACKUP
UT_LIST_NODE_T(dict_index_t)
- indexes;/* list of indexes of the table */
- btr_search_t* search_info; /* info used in optimistic searches */
+ indexes;/*!< list of indexes of the table */
+ btr_search_t* search_info; /*!< info used in optimistic searches */
/*----------------------*/
+ /** Statistics for query optimization */
+ /* @{ */
ib_int64_t* stat_n_diff_key_vals;
- /* approximate number of different key values
- for this index, for each n-column prefix
- where n <= dict_get_n_unique(index); we
- periodically calculate new estimates */
+ /*!< approximate number of different
+ key values for this index, for each
+ n-column prefix where n <=
+ dict_get_n_unique(index); we
+ periodically calculate new
+ estimates */
ulint stat_index_size;
- /* approximate index size in database pages */
+ /*!< approximate index size in
+ database pages */
ulint stat_n_leaf_pages;
- /* approximate number of leaf pages in the
+ /*!< approximate number of leaf pages in the
index tree */
- rw_lock_t lock; /* read-write lock protecting the upper levels
- of the index tree */
-#ifdef ROW_MERGE_IS_INDEX_USABLE
- dulint trx_id; /* id of the transaction that created this
- index, or ut_dulint_zero if the index existed
+ /* @} */
+ rw_lock_t lock; /*!< read-write lock protecting the
+ upper levels of the index tree */
+ ib_uint64_t trx_id; /*!< id of the transaction that created this
+ index, or 0 if the index existed
when InnoDB was started up */
-#endif /* ROW_MERGE_IS_INDEX_USABLE */
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
- ulint magic_n;/* magic number */
+ ulint magic_n;/*!< magic number */
+/** Value of dict_index_struct::magic_n */
# define DICT_INDEX_MAGIC_N 76789786
#endif
};
-/* Data structure for a foreign key constraint; an example:
+/** Data structure for a foreign key constraint; an example:
FOREIGN KEY (A, B) REFERENCES TABLE2 (C, D). Most fields will be
initialized to 0, NULL or FALSE in dict_mem_foreign_create(). */
-
struct dict_foreign_struct{
- mem_heap_t* heap; /* this object is allocated from
+ mem_heap_t* heap; /*!< this object is allocated from
this memory heap */
- char* id; /* id of the constraint as a
+ char* id; /*!< id of the constraint as a
null-terminated string */
- unsigned n_fields:10; /* number of indexes' first fields
+ unsigned n_fields:10; /*!< number of indexes' first fields
for which the the foreign key
constraint is defined: we allow the
indexes to contain more fields than
mentioned in the constraint, as long
as the first fields are as mentioned */
- unsigned type:6; /* 0 or DICT_FOREIGN_ON_DELETE_CASCADE
+ unsigned type:6; /*!< 0 or DICT_FOREIGN_ON_DELETE_CASCADE
or DICT_FOREIGN_ON_DELETE_SET_NULL */
- char* foreign_table_name;/* foreign table name */
- dict_table_t* foreign_table; /* table where the foreign key is */
- const char** foreign_col_names;/* names of the columns in the
+ char* foreign_table_name;/*!< foreign table name */
+ dict_table_t* foreign_table; /*!< table where the foreign key is */
+ const char** foreign_col_names;/*!< names of the columns in the
foreign key */
- char* referenced_table_name;/* referenced table name */
- dict_table_t* referenced_table;/* table where the referenced key
+ char* referenced_table_name;/*!< referenced table name */
+ dict_table_t* referenced_table;/*!< table where the referenced key
is */
- const char** referenced_col_names;/* names of the referenced
+ const char** referenced_col_names;/*!< names of the referenced
columns in the referenced table */
- dict_index_t* foreign_index; /* foreign index; we require that
+ dict_index_t* foreign_index; /*!< foreign index; we require that
both tables contain explicitly defined
indexes for the constraint: InnoDB
does not generate new indexes
implicitly */
- dict_index_t* referenced_index;/* referenced index */
+ dict_index_t* referenced_index;/*!< referenced index */
UT_LIST_NODE_T(dict_foreign_t)
- foreign_list; /* list node for foreign keys of the
+ foreign_list; /*!< list node for foreign keys of the
table */
UT_LIST_NODE_T(dict_foreign_t)
- referenced_list;/* list node for referenced keys of the
- table */
+ referenced_list;/*!< list node for referenced
+ keys of the table */
};
-/* The flags for ON_UPDATE and ON_DELETE can be ORed; the default is that
+/** The flags for ON_UPDATE and ON_DELETE can be ORed; the default is that
a foreign key constraint is enforced, therefore RESTRICT just means no flag */
-#define DICT_FOREIGN_ON_DELETE_CASCADE 1
-#define DICT_FOREIGN_ON_DELETE_SET_NULL 2
-#define DICT_FOREIGN_ON_UPDATE_CASCADE 4
-#define DICT_FOREIGN_ON_UPDATE_SET_NULL 8
-#define DICT_FOREIGN_ON_DELETE_NO_ACTION 16
-#define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32
+/* @{ */
+#define DICT_FOREIGN_ON_DELETE_CASCADE 1 /*!< ON DELETE CASCADE */
+#define DICT_FOREIGN_ON_DELETE_SET_NULL 2 /*!< ON UPDATE SET NULL */
+#define DICT_FOREIGN_ON_UPDATE_CASCADE 4 /*!< ON DELETE CASCADE */
+#define DICT_FOREIGN_ON_UPDATE_SET_NULL 8 /*!< ON UPDATE SET NULL */
+#define DICT_FOREIGN_ON_DELETE_NO_ACTION 16 /*!< ON DELETE NO ACTION */
+#define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32 /*!< ON UPDATE NO ACTION */
+/* @} */
-/* Data structure for a database table. Most fields will be
+/** Data structure for a database table. Most fields will be
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 */
- const char* dir_path_of_temp_table;/* NULL or the directory path
+ dulint id; /*!< id of the table */
+ mem_heap_t* heap; /*!< memory heap */
+ const 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
innodb_file_per_table is defined in my.cnf;
in Unix this is usually /tmp/..., in Windows
- \temp\... */
+ temp\... */
unsigned space:32;
- /* space where the clustered index of the
+ /*!< space where the clustered index of the
table is placed */
- unsigned flags:DICT_TF_BITS;/* DICT_TF_COMPACT, ... */
+ unsigned flags:DICT_TF_BITS;/*!< DICT_TF_COMPACT, ... */
unsigned ibd_file_missing:1;
- /* TRUE if this is in a single-table
+ /*!< TRUE if this is in a single-table
tablespace and the .ibd file is missing; then
we must return in ha_innodb.cc an error if the
user tries to query such an orphaned table */
unsigned tablespace_discarded:1;
- /* this flag is set TRUE when the user
+ /*!< this flag is set TRUE when the user
calls DISCARD TABLESPACE on this
table, and reset to FALSE in IMPORT
TABLESPACE */
- unsigned cached:1;/* TRUE if the table object has been added
+ unsigned cached:1;/*!< TRUE if the table object has been added
to the dictionary cache */
- unsigned n_def:10;/* number of columns defined so far */
- unsigned n_cols:10;/* number of columns */
- dict_col_t* cols; /* array of column descriptions */
+ unsigned n_def:10;/*!< number of columns defined so far */
+ unsigned n_cols:10;/*!< number of columns */
+ dict_col_t* cols; /*!< array of column descriptions */
const char* col_names;
- /* Column names packed in a character string
+ /*!< Column names packed in a character string
"name1\0name2\0...nameN\0". Until
the string contains n_cols, it will be
allocated from a temporary heap. The final
string will be allocated from table->heap. */
- hash_node_t name_hash; /* hash chain node */
- hash_node_t id_hash; /* hash chain node */
+#ifndef UNIV_HOTBACKUP
+ hash_node_t name_hash; /*!< hash chain node */
+ hash_node_t id_hash; /*!< hash chain node */
UT_LIST_BASE_NODE_T(dict_index_t)
- indexes; /* list of indexes of the table */
+ indexes; /*!< list of indexes of the table */
UT_LIST_BASE_NODE_T(dict_foreign_t)
- foreign_list;/* list of foreign key constraints
+ foreign_list;/*!< list of foreign key constraints
in the table; these refer to columns
in other tables */
UT_LIST_BASE_NODE_T(dict_foreign_t)
- referenced_list;/* list of foreign key constraints
+ referenced_list;/*!< list of foreign key constraints
which refer to this table */
UT_LIST_NODE_T(dict_table_t)
- table_LRU; /* node of the LRU list of tables */
+ table_LRU; /*!< node of the LRU list of tables */
ulint n_mysql_handles_opened;
- /* count of how many handles MySQL has opened
+ /*!< count of how many handles MySQL has opened
to this table; dropping of the table is
NOT allowed until this count gets to zero;
MySQL does NOT itself check the number of
open handles at drop */
ulint n_foreign_key_checks_running;
- /* count of how many foreign key check
+ /*!< count of how many foreign key check
operations are currently being performed
on the table: we cannot drop the table while
there are foreign key checks running on
it! */
- dulint query_cache_inv_trx_id;
- /* transactions whose trx id < than this
- number are not allowed to store to the MySQL
- query cache or retrieve from it; when a trx
- with undo logs commits, it sets this to the
- value of the trx id counter for the tables it
- had an IX lock on */
+ trx_id_t query_cache_inv_trx_id;
+ /*!< transactions whose trx id is
+ smaller than this number are not
+ allowed to store to the MySQL query
+ cache or retrieve from it; when a trx
+ with undo logs commits, it sets this
+ to the value of the trx id counter for
+ the tables it had an IX lock on */
UT_LIST_BASE_NODE_T(lock_t)
- locks; /* list of locks on the table */
+ locks; /*!< list of locks on the table */
#ifdef UNIV_DEBUG
/*----------------------*/
ibool does_not_fit_in_memory;
- /* this field is used to specify in simulations
- tables which are so big that disk should be
- accessed: disk access is simulated by
- putting the thread to sleep for a while;
- NOTE that this flag is not stored to the data
- dictionary on disk, and the database will
- forget about value TRUE if it has to reload
- the table definition from disk */
+ /*!< this field is used to specify in
+ simulations tables which are so big
+ that disk should be accessed: disk
+ access is simulated by putting the
+ thread to sleep for a while; NOTE that
+ this flag is not stored to the data
+ dictionary on disk, and the database
+ will forget about value TRUE if it has
+ to reload the table definition from
+ disk */
#endif /* UNIV_DEBUG */
/*----------------------*/
unsigned big_rows:1;
- /* flag: TRUE if the maximum length of
+ /*!< flag: TRUE if the maximum length of
a single row exceeds BIG_ROW_SIZE;
initialized in dict_table_add_to_cache() */
- unsigned stat_initialized:1; /* TRUE if statistics have
+ /** Statistics for query optimization */
+ /* @{ */
+ unsigned stat_initialized:1; /*!< TRUE if statistics have
been calculated the first time
after database startup or table creation */
ib_int64_t stat_n_rows;
- /* approximate number of rows in the table;
+ /*!< approximate number of rows in the table;
we periodically calculate new estimates */
ulint stat_clustered_index_size;
- /* approximate clustered index size in
+ /*!< approximate clustered index size in
database pages */
ulint stat_sum_of_other_index_sizes;
- /* other indexes in database pages */
+ /*!< other indexes in database pages */
ulint stat_modified_counter;
- /* when a row is inserted, updated, or deleted,
+ /*!< when a row is inserted, updated,
+ or deleted,
we add 1 to this number; we calculate new
estimates for the stat_... values for the
table and the indexes at an interval of 2 GB
@@ -446,8 +477,9 @@ struct dict_table_struct{
calculation; this counter is not protected by
any latch, because this is only used for
heuristics */
+ /* @} */
/*----------------------*/
- /* The following fields are used by the
+ /**!< The following fields are used by the
AUTOINC code. The actual collection of
tables locked during AUTOINC read/write is
kept in trx_t. In order to quickly determine
@@ -461,8 +493,9 @@ struct dict_table_struct{
corresponding lock instance is created on
the trx lock heap rather than use the
pre-allocated instance in autoinc_lock below.*/
+ /* @{ */
lock_t* autoinc_lock;
- /* a buffer for an AUTOINC lock
+ /*!< a buffer for an AUTOINC lock
for this table: we allocate the memory here
so that individual transactions can get it
and release it without a need to allocate
@@ -470,12 +503,12 @@ struct dict_table_struct{
otherwise the lock heap would grow rapidly
if we do a large insert from a select */
mutex_t autoinc_mutex;
- /* mutex protecting the autoincrement
+ /*!< mutex protecting the autoincrement
counter */
- ib_uint64_t autoinc;/* autoinc counter value to give to the
+ ib_uint64_t autoinc;/*!< autoinc counter value to give to the
next inserted row */
ulong n_waiting_or_granted_auto_inc_locks;
- /* This counter is used to track the number
+ /*!< This counter is used to track the number
of granted and pending autoinc locks on this
table. This value is set after acquiring the
kernel mutex but we peek the contents to
@@ -484,12 +517,15 @@ struct dict_table_struct{
only one transaction can be granted the
lock but there can be multiple waiters. */
const trx_t* autoinc_trx;
- /* The transaction that currently holds the
+ /*!< The transaction that currently holds the
the AUTOINC lock on this table. */
+ /* @} */
/*----------------------*/
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
- ulint magic_n;/* magic number */
+ ulint magic_n;/*!< magic number */
+/** Value of dict_table_struct::magic_n */
# define DICT_TABLE_MAGIC_N 76333786
#endif /* UNIV_DEBUG */
};
diff --git a/storage/xtradb/include/dict0mem.ic b/storage/xtradb/include/dict0mem.ic
index 6916393a9cd..c36adb07a18 100644
--- a/storage/xtradb/include/dict0mem.ic
+++ b/storage/xtradb/include/dict0mem.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/dict0mem.ic
Data dictionary memory object creation
Created 1/8/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/dict0types.h b/storage/xtradb/include/dict0types.h
index b93e995e01b..7ad69193cc9 100644
--- a/storage/xtradb/include/dict0types.h
+++ b/storage/xtradb/include/dict0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dict0types.h
Data dictionary global types
Created 1/8/1996 Heikki Tuuri
@@ -25,8 +26,6 @@ Created 1/8/1996 Heikki Tuuri
#ifndef dict0types_h
#define dict0types_h
-#include "ut0list.h"
-
typedef struct dict_sys_struct dict_sys_t;
typedef struct dict_col_struct dict_col_t;
typedef struct dict_field_struct dict_field_t;
@@ -42,4 +41,8 @@ typedef dict_table_t dict_cluster_t;
typedef struct ind_node_struct ind_node_t;
typedef struct tab_node_struct tab_node_t;
+/* Space id and page no where the dictionary header resides */
+#define DICT_HDR_SPACE 0 /* the SYSTEM tablespace */
+#define DICT_HDR_PAGE_NO FSP_DICT_HDR_PAGE_NO
+
#endif
diff --git a/storage/xtradb/include/dyn0dyn.h b/storage/xtradb/include/dyn0dyn.h
index c06d6b88d2f..121a5946ac7 100644
--- a/storage/xtradb/include/dyn0dyn.h
+++ b/storage/xtradb/include/dyn0dyn.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dyn0dyn.h
The dynamically allocated array
Created 2/5/1996 Heikki Tuuri
@@ -29,148 +30,153 @@ Created 2/5/1996 Heikki Tuuri
#include "ut0lst.h"
#include "mem0mem.h"
+/** A block in a dynamically allocated array */
typedef struct dyn_block_struct dyn_block_t;
+/** Dynamically allocated array */
typedef dyn_block_t dyn_array_t;
-/* This is the initial 'payload' size of a dynamic array;
+/** This is the initial 'payload' size of a dynamic array;
this must be > MLOG_BUF_MARGIN + 30! */
#define DYN_ARRAY_DATA_SIZE 512
-/*************************************************************************
-Initializes a dynamic array. */
+/*********************************************************************//**
+Initializes a dynamic array.
+@return initialized dyn array */
UNIV_INLINE
dyn_array_t*
dyn_array_create(
/*=============*/
- /* out: initialized dyn array */
- dyn_array_t* arr); /* in: pointer to a memory buffer of
+ dyn_array_t* arr); /*!< in: pointer to a memory buffer of
size sizeof(dyn_array_t) */
-/****************************************************************
+/************************************************************//**
Frees a dynamic array. */
UNIV_INLINE
void
dyn_array_free(
/*===========*/
- dyn_array_t* arr); /* in: dyn array */
-/*************************************************************************
+ dyn_array_t* arr); /*!< in: dyn array */
+/*********************************************************************//**
Makes room on top of a dyn array and returns a pointer to a buffer in it.
After copying the elements, the caller must close the buffer using
-dyn_array_close. */
+dyn_array_close.
+@return pointer to the buffer */
UNIV_INLINE
byte*
dyn_array_open(
/*===========*/
- /* out: pointer to the buffer */
- dyn_array_t* arr, /* in: dynamic array */
- ulint size); /* in: size in bytes of the buffer; MUST be
+ dyn_array_t* arr, /*!< in: dynamic array */
+ ulint size); /*!< in: size in bytes of the buffer; MUST be
smaller than DYN_ARRAY_DATA_SIZE! */
-/*************************************************************************
+/*********************************************************************//**
Closes the buffer returned by dyn_array_open. */
UNIV_INLINE
void
dyn_array_close(
/*============*/
- dyn_array_t* arr, /* in: dynamic array */
- byte* ptr); /* in: buffer space from ptr up was not used */
-/*************************************************************************
+ dyn_array_t* arr, /*!< in: dynamic array */
+ byte* ptr); /*!< in: buffer space from ptr up was not used */
+/*********************************************************************//**
Makes room on top of a dyn array and returns a pointer to
the added element. The caller must copy the element to
-the pointer returned. */
+the pointer returned.
+@return pointer to the element */
UNIV_INLINE
void*
dyn_array_push(
/*===========*/
- /* out: pointer to the element */
- dyn_array_t* arr, /* in: dynamic array */
- ulint size); /* in: size in bytes of the element */
-/****************************************************************
-Returns pointer to an element in dyn array. */
+ dyn_array_t* arr, /*!< in: dynamic array */
+ ulint size); /*!< in: size in bytes of the element */
+/************************************************************//**
+Returns pointer to an element in dyn array.
+@return pointer to element */
UNIV_INLINE
void*
dyn_array_get_element(
/*==================*/
- /* out: pointer to element */
- dyn_array_t* arr, /* in: dyn array */
- ulint pos); /* in: position of element as bytes
+ dyn_array_t* arr, /*!< in: dyn array */
+ ulint pos); /*!< in: position of element as bytes
from array start */
-/****************************************************************
-Returns the size of stored data in a dyn array. */
+/************************************************************//**
+Returns the size of stored data in a dyn array.
+@return data size in bytes */
UNIV_INLINE
ulint
dyn_array_get_data_size(
/*====================*/
- /* out: data size in bytes */
- dyn_array_t* arr); /* in: dyn array */
-/****************************************************************
+ dyn_array_t* arr); /*!< in: dyn array */
+/************************************************************//**
Gets the first block in a dyn array. */
UNIV_INLINE
dyn_block_t*
dyn_array_get_first_block(
/*======================*/
- dyn_array_t* arr); /* in: dyn array */
-/****************************************************************
+ dyn_array_t* arr); /*!< in: dyn array */
+/************************************************************//**
Gets the last block in a dyn array. */
UNIV_INLINE
dyn_block_t*
dyn_array_get_last_block(
/*=====================*/
- dyn_array_t* arr); /* in: dyn array */
-/************************************************************************
-Gets the next block in a dyn array. */
+ dyn_array_t* arr); /*!< in: dyn array */
+/********************************************************************//**
+Gets the next block in a dyn array.
+@return pointer to next, NULL if end of list */
UNIV_INLINE
dyn_block_t*
dyn_array_get_next_block(
/*=====================*/
- /* out: pointer to next, NULL if end of list */
- dyn_array_t* arr, /* in: dyn array */
- dyn_block_t* block); /* in: dyn array block */
-/************************************************************************
-Gets the number of used bytes in a dyn array block. */
+ dyn_array_t* arr, /*!< in: dyn array */
+ dyn_block_t* block); /*!< in: dyn array block */
+/********************************************************************//**
+Gets the number of used bytes in a dyn array block.
+@return number of bytes used */
UNIV_INLINE
ulint
dyn_block_get_used(
/*===============*/
- /* out: number of bytes used */
- dyn_block_t* block); /* in: dyn array block */
-/************************************************************************
-Gets pointer to the start of data in a dyn array block. */
+ dyn_block_t* block); /*!< in: dyn array block */
+/********************************************************************//**
+Gets pointer to the start of data in a dyn array block.
+@return pointer to data */
UNIV_INLINE
byte*
dyn_block_get_data(
/*===============*/
- /* out: pointer to data */
- dyn_block_t* block); /* in: dyn array block */
-/************************************************************
+ dyn_block_t* block); /*!< in: dyn array block */
+/********************************************************//**
Pushes n bytes to a dyn array. */
UNIV_INLINE
void
dyn_push_string(
/*============*/
- dyn_array_t* arr, /* in: dyn array */
- const byte* str, /* in: string to write */
- ulint len); /* in: string length */
+ dyn_array_t* arr, /*!< in: dyn array */
+ const byte* str, /*!< in: string to write */
+ ulint len); /*!< in: string length */
/*#################################################################*/
-/* NOTE! Do not use the fields of the struct directly: the definition
+/** @brief A block in a dynamically allocated array.
+NOTE! Do not access the fields of the struct directly: the definition
appears here only for the compiler to know its size! */
struct dyn_block_struct{
- mem_heap_t* heap; /* in the first block this is != NULL
+ mem_heap_t* heap; /*!< in the first block this is != NULL
if dynamic allocation has been needed */
- ulint used; /* number of data bytes used in this block */
+ ulint used; /*!< number of data bytes used in this block;
+ DYN_BLOCK_FULL_FLAG is set when the block
+ becomes full */
byte data[DYN_ARRAY_DATA_SIZE];
- /* storage for array elements */
+ /*!< storage for array elements */
UT_LIST_BASE_NODE_T(dyn_block_t) base;
- /* linear list of dyn blocks: this node is
+ /*!< linear list of dyn blocks: this node is
used only in the first block */
UT_LIST_NODE_T(dyn_block_t) list;
- /* linear list node: used in all blocks */
+ /*!< linear list node: used in all blocks */
#ifdef UNIV_DEBUG
- ulint buf_end;/* only in the debug version: if dyn array is
- opened, this is the buffer end offset, else
- this is 0 */
- ulint magic_n;
+ ulint buf_end;/*!< only in the debug version: if dyn
+ array is opened, this is the buffer
+ end offset, else this is 0 */
+ ulint magic_n;/*!< magic number (DYN_BLOCK_MAGIC_N) */
#endif
};
diff --git a/storage/xtradb/include/dyn0dyn.ic b/storage/xtradb/include/dyn0dyn.ic
index 1ef8b284a99..110e674abff 100644
--- a/storage/xtradb/include/dyn0dyn.ic
+++ b/storage/xtradb/include/dyn0dyn.ic
@@ -16,43 +16,46 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/dyn0dyn.ic
The dynamically allocated array
Created 2/5/1996 Heikki Tuuri
*******************************************************/
+/** Value of dyn_block_struct::magic_n */
#define DYN_BLOCK_MAGIC_N 375767
+/** Flag for dyn_block_struct::used that indicates a full block */
#define DYN_BLOCK_FULL_FLAG 0x1000000UL
-/****************************************************************
-Adds a new block to a dyn array. */
+/************************************************************//**
+Adds a new block to a dyn array.
+@return created block */
UNIV_INTERN
dyn_block_t*
dyn_array_add_block(
/*================*/
- /* out: created block */
- dyn_array_t* arr); /* in: dyn array */
+ dyn_array_t* arr); /*!< in: dyn array */
-/****************************************************************
+/************************************************************//**
Gets the first block in a dyn array. */
UNIV_INLINE
dyn_block_t*
dyn_array_get_first_block(
/*======================*/
- dyn_array_t* arr) /* in: dyn array */
+ dyn_array_t* arr) /*!< in: dyn array */
{
return(arr);
}
-/****************************************************************
+/************************************************************//**
Gets the last block in a dyn array. */
UNIV_INLINE
dyn_block_t*
dyn_array_get_last_block(
/*=====================*/
- dyn_array_t* arr) /* in: dyn array */
+ dyn_array_t* arr) /*!< in: dyn array */
{
if (arr->heap == NULL) {
@@ -62,15 +65,15 @@ dyn_array_get_last_block(
return(UT_LIST_GET_LAST(arr->base));
}
-/************************************************************************
-Gets the next block in a dyn array. */
+/********************************************************************//**
+Gets the next block in a dyn array.
+@return pointer to next, NULL if end of list */
UNIV_INLINE
dyn_block_t*
dyn_array_get_next_block(
/*=====================*/
- /* out: pointer to next, NULL if end of list */
- dyn_array_t* arr, /* in: dyn array */
- dyn_block_t* block) /* in: dyn array block */
+ dyn_array_t* arr, /*!< in: dyn array */
+ dyn_block_t* block) /*!< in: dyn array block */
{
ut_ad(arr && block);
@@ -83,42 +86,42 @@ dyn_array_get_next_block(
return(UT_LIST_GET_NEXT(list, block));
}
-/************************************************************************
-Gets the number of used bytes in a dyn array block. */
+/********************************************************************//**
+Gets the number of used bytes in a dyn array block.
+@return number of bytes used */
UNIV_INLINE
ulint
dyn_block_get_used(
/*===============*/
- /* out: number of bytes used */
- dyn_block_t* block) /* in: dyn array block */
+ dyn_block_t* block) /*!< in: dyn array block */
{
ut_ad(block);
return((block->used) & ~DYN_BLOCK_FULL_FLAG);
}
-/************************************************************************
-Gets pointer to the start of data in a dyn array block. */
+/********************************************************************//**
+Gets pointer to the start of data in a dyn array block.
+@return pointer to data */
UNIV_INLINE
byte*
dyn_block_get_data(
/*===============*/
- /* out: pointer to data */
- dyn_block_t* block) /* in: dyn array block */
+ dyn_block_t* block) /*!< in: dyn array block */
{
ut_ad(block);
return(block->data);
}
-/*************************************************************************
-Initializes a dynamic array. */
+/*********************************************************************//**
+Initializes a dynamic array.
+@return initialized dyn array */
UNIV_INLINE
dyn_array_t*
dyn_array_create(
/*=============*/
- /* out: initialized dyn array */
- dyn_array_t* arr) /* in: pointer to a memory buffer of
+ dyn_array_t* arr) /*!< in: pointer to a memory buffer of
size sizeof(dyn_array_t) */
{
ut_ad(arr);
@@ -136,13 +139,13 @@ dyn_array_create(
return(arr);
}
-/****************************************************************
+/************************************************************//**
Frees a dynamic array. */
UNIV_INLINE
void
dyn_array_free(
/*===========*/
- dyn_array_t* arr) /* in: dyn array */
+ dyn_array_t* arr) /*!< in: dyn array */
{
if (arr->heap != NULL) {
mem_heap_free(arr->heap);
@@ -153,16 +156,16 @@ dyn_array_free(
#endif
}
-/*************************************************************************
+/*********************************************************************//**
Makes room on top of a dyn array and returns a pointer to the added element.
-The caller must copy the element to the pointer returned. */
+The caller must copy the element to the pointer returned.
+@return pointer to the element */
UNIV_INLINE
void*
dyn_array_push(
/*===========*/
- /* out: pointer to the element */
- dyn_array_t* arr, /* in: dynamic array */
- ulint size) /* in: size in bytes of the element */
+ dyn_array_t* arr, /*!< in: dynamic array */
+ ulint size) /*!< in: size in bytes of the element */
{
dyn_block_t* block;
ulint used;
@@ -193,17 +196,17 @@ dyn_array_push(
return((block->data) + used);
}
-/*************************************************************************
+/*********************************************************************//**
Makes room on top of a dyn array and returns a pointer to a buffer in it.
After copying the elements, the caller must close the buffer using
-dyn_array_close. */
+dyn_array_close.
+@return pointer to the buffer */
UNIV_INLINE
byte*
dyn_array_open(
/*===========*/
- /* out: pointer to the buffer */
- dyn_array_t* arr, /* in: dynamic array */
- ulint size) /* in: size in bytes of the buffer; MUST be
+ dyn_array_t* arr, /*!< in: dynamic array */
+ ulint size) /*!< in: size in bytes of the buffer; MUST be
smaller than DYN_ARRAY_DATA_SIZE! */
{
dyn_block_t* block;
@@ -239,14 +242,14 @@ dyn_array_open(
return((block->data) + used);
}
-/*************************************************************************
+/*********************************************************************//**
Closes the buffer returned by dyn_array_open. */
UNIV_INLINE
void
dyn_array_close(
/*============*/
- dyn_array_t* arr, /* in: dynamic array */
- byte* ptr) /* in: buffer space from ptr up was not used */
+ dyn_array_t* arr, /*!< in: dynamic array */
+ byte* ptr) /*!< in: buffer space from ptr up was not used */
{
dyn_block_t* block;
@@ -266,15 +269,15 @@ dyn_array_close(
#endif
}
-/****************************************************************
-Returns pointer to an element in dyn array. */
+/************************************************************//**
+Returns pointer to an element in dyn array.
+@return pointer to element */
UNIV_INLINE
void*
dyn_array_get_element(
/*==================*/
- /* out: pointer to element */
- dyn_array_t* arr, /* in: dyn array */
- ulint pos) /* in: position of element as bytes
+ dyn_array_t* arr, /*!< in: dyn array */
+ ulint pos) /*!< in: position of element as bytes
from array start */
{
dyn_block_t* block;
@@ -304,14 +307,14 @@ dyn_array_get_element(
return(block->data + pos);
}
-/****************************************************************
-Returns the size of stored data in a dyn array. */
+/************************************************************//**
+Returns the size of stored data in a dyn array.
+@return data size in bytes */
UNIV_INLINE
ulint
dyn_array_get_data_size(
/*====================*/
- /* out: data size in bytes */
- dyn_array_t* arr) /* in: dyn array */
+ dyn_array_t* arr) /*!< in: dyn array */
{
dyn_block_t* block;
ulint sum = 0;
@@ -335,15 +338,15 @@ dyn_array_get_data_size(
return(sum);
}
-/************************************************************
+/********************************************************//**
Pushes n bytes to a dyn array. */
UNIV_INLINE
void
dyn_push_string(
/*============*/
- dyn_array_t* arr, /* in: dyn array */
- const byte* str, /* in: string to write */
- ulint len) /* in: string length */
+ dyn_array_t* arr, /*!< in: dyn array */
+ const byte* str, /*!< in: string to write */
+ ulint len) /*!< in: string length */
{
ulint n_copied;
diff --git a/storage/xtradb/include/eval0eval.h b/storage/xtradb/include/eval0eval.h
index 75cf9b38c3a..60aefd8d453 100644
--- a/storage/xtradb/include/eval0eval.h
+++ b/storage/xtradb/include/eval0eval.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/eval0eval.h
SQL evaluator: evaluates simple data structures, like expressions, in
a query graph
@@ -31,7 +32,7 @@ Created 12/29/1997 Heikki Tuuri
#include "pars0sym.h"
#include "pars0pars.h"
-/*********************************************************************
+/*****************************************************************//**
Free the buffer from global dynamic memory for a value of a que_node,
if it has been allocated in the above function. The freeing for pushed
column values is done in sel_col_prefetch_buf_free. */
@@ -39,71 +40,71 @@ UNIV_INTERN
void
eval_node_free_val_buf(
/*===================*/
- que_node_t* node); /* in: query graph node */
-/*********************************************************************
+ que_node_t* node); /*!< in: query graph node */
+/*****************************************************************//**
Evaluates a symbol table symbol. */
UNIV_INLINE
void
eval_sym(
/*=====*/
- sym_node_t* sym_node); /* in: symbol table node */
-/*********************************************************************
+ sym_node_t* sym_node); /*!< in: symbol table node */
+/*****************************************************************//**
Evaluates an expression. */
UNIV_INLINE
void
eval_exp(
/*=====*/
- que_node_t* exp_node); /* in: expression */
-/*********************************************************************
+ que_node_t* exp_node); /*!< in: expression */
+/*****************************************************************//**
Sets an integer value as the value of an expression node. */
UNIV_INLINE
void
eval_node_set_int_val(
/*==================*/
- que_node_t* node, /* in: expression node */
- lint val); /* in: value to set */
-/*********************************************************************
-Gets an integer value from an expression node. */
+ que_node_t* node, /*!< in: expression node */
+ lint val); /*!< in: value to set */
+/*****************************************************************//**
+Gets an integer value from an expression node.
+@return integer value */
UNIV_INLINE
lint
eval_node_get_int_val(
/*==================*/
- /* out: integer value */
- que_node_t* node); /* in: expression node */
-/*********************************************************************
+ que_node_t* node); /*!< in: expression node */
+/*****************************************************************//**
Copies a binary string value as the value of a query graph node. Allocates a
new buffer if necessary. */
UNIV_INLINE
void
eval_node_copy_and_alloc_val(
/*=========================*/
- que_node_t* node, /* in: query graph node */
- const byte* str, /* in: binary string */
- ulint len); /* in: string length or UNIV_SQL_NULL */
-/*********************************************************************
+ que_node_t* node, /*!< in: query graph node */
+ const byte* str, /*!< in: binary string */
+ ulint len); /*!< in: string length or UNIV_SQL_NULL */
+/*****************************************************************//**
Copies a query node value to another node. */
UNIV_INLINE
void
eval_node_copy_val(
/*===============*/
- que_node_t* node1, /* in: node to copy to */
- que_node_t* node2); /* in: node to copy from */
-/*********************************************************************
-Gets a iboolean value from a query node. */
+ que_node_t* node1, /*!< in: node to copy to */
+ que_node_t* node2); /*!< in: node to copy from */
+/*****************************************************************//**
+Gets a iboolean value from a query node.
+@return iboolean value */
UNIV_INLINE
ibool
eval_node_get_ibool_val(
/*====================*/
- /* out: iboolean value */
- que_node_t* node); /* in: query graph node */
-/*********************************************************************
-Evaluates a comparison node. */
+ que_node_t* node); /*!< in: query graph node */
+/*****************************************************************//**
+Evaluates a comparison node.
+@return the result of the comparison */
UNIV_INTERN
ibool
eval_cmp(
/*=====*/
- /* out: the result of the comparison */
- func_node_t* cmp_node); /* in: comparison node */
+ func_node_t* cmp_node); /*!< in: comparison node */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/eval0eval.ic b/storage/xtradb/include/eval0eval.ic
index a6330ae441f..fe767f39b00 100644
--- a/storage/xtradb/include/eval0eval.ic
+++ b/storage/xtradb/include/eval0eval.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/eval0eval.ic
SQL evaluator: evaluates simple data structures, like expressions, in
a query graph
@@ -27,41 +28,41 @@ Created 12/29/1997 Heikki Tuuri
#include "rem0cmp.h"
#include "pars0grm.h"
-/*********************************************************************
+/*****************************************************************//**
Evaluates a function node. */
UNIV_INTERN
void
eval_func(
/*======*/
- func_node_t* func_node); /* in: function node */
-/*********************************************************************
+ func_node_t* func_node); /*!< in: function node */
+/*****************************************************************//**
Allocate a buffer from global dynamic memory for a value of a que_node.
NOTE that this memory must be explicitly freed when the query graph is
freed. If the node already has allocated buffer, that buffer is freed
here. NOTE that this is the only function where dynamic memory should be
-allocated for a query node val field. */
+allocated for a query node val field.
+@return pointer to allocated buffer */
UNIV_INTERN
byte*
eval_node_alloc_val_buf(
/*====================*/
- /* out: pointer to allocated buffer */
- que_node_t* node, /* in: query graph node; sets the val field
+ que_node_t* node, /*!< in: query graph node; sets the val field
data field to point to the new buffer, and
len field equal to size */
- ulint size); /* in: buffer size */
+ ulint size); /*!< in: buffer size */
-/*********************************************************************
-Allocates a new buffer if needed. */
+/*****************************************************************//**
+Allocates a new buffer if needed.
+@return pointer to buffer */
UNIV_INLINE
byte*
eval_node_ensure_val_buf(
/*=====================*/
- /* out: pointer to buffer */
- que_node_t* node, /* in: query graph node; sets the val field
+ que_node_t* node, /*!< in: query graph node; sets the val field
data field to point to the new buffer, and
len field equal to size */
- ulint size) /* in: buffer size */
+ ulint size) /*!< in: buffer size */
{
dfield_t* dfield;
byte* data;
@@ -79,13 +80,13 @@ eval_node_ensure_val_buf(
return(data);
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates a symbol table symbol. */
UNIV_INLINE
void
eval_sym(
/*=====*/
- sym_node_t* sym_node) /* in: symbol table node */
+ sym_node_t* sym_node) /*!< in: symbol table node */
{
ut_ad(que_node_get_type(sym_node) == QUE_NODE_SYMBOL);
@@ -99,13 +100,13 @@ eval_sym(
}
}
-/*********************************************************************
+/*****************************************************************//**
Evaluates an expression. */
UNIV_INLINE
void
eval_exp(
/*=====*/
- que_node_t* exp_node) /* in: expression */
+ que_node_t* exp_node) /*!< in: expression */
{
if (que_node_get_type(exp_node) == QUE_NODE_SYMBOL) {
@@ -117,14 +118,14 @@ eval_exp(
eval_func(exp_node);
}
-/*********************************************************************
+/*****************************************************************//**
Sets an integer value as the value of an expression node. */
UNIV_INLINE
void
eval_node_set_int_val(
/*==================*/
- que_node_t* node, /* in: expression node */
- lint val) /* in: value to set */
+ que_node_t* node, /*!< in: expression node */
+ lint val) /*!< in: value to set */
{
dfield_t* dfield;
byte* data;
@@ -142,14 +143,14 @@ eval_node_set_int_val(
mach_write_to_4(data, (ulint)val);
}
-/*********************************************************************
-Gets an integer non-SQL null value from an expression node. */
+/*****************************************************************//**
+Gets an integer non-SQL null value from an expression node.
+@return integer value */
UNIV_INLINE
lint
eval_node_get_int_val(
/*==================*/
- /* out: integer value */
- que_node_t* node) /* in: expression node */
+ que_node_t* node) /*!< in: expression node */
{
dfield_t* dfield;
@@ -160,14 +161,14 @@ eval_node_get_int_val(
return((int)mach_read_from_4(dfield_get_data(dfield)));
}
-/*********************************************************************
-Gets a iboolean value from a query node. */
+/*****************************************************************//**
+Gets a iboolean value from a query node.
+@return iboolean value */
UNIV_INLINE
ibool
eval_node_get_ibool_val(
/*====================*/
- /* out: iboolean value */
- que_node_t* node) /* in: query graph node */
+ que_node_t* node) /*!< in: query graph node */
{
dfield_t* dfield;
byte* data;
@@ -181,14 +182,14 @@ eval_node_get_ibool_val(
return(mach_read_from_1(data));
}
-/*********************************************************************
+/*****************************************************************//**
Sets a iboolean value as the value of a function node. */
UNIV_INLINE
void
eval_node_set_ibool_val(
/*====================*/
- func_node_t* func_node, /* in: function node */
- ibool val) /* in: value to set */
+ func_node_t* func_node, /*!< in: function node */
+ ibool val) /*!< in: value to set */
{
dfield_t* dfield;
byte* data;
@@ -208,16 +209,16 @@ eval_node_set_ibool_val(
mach_write_to_1(data, val);
}
-/*********************************************************************
+/*****************************************************************//**
Copies a binary string value as the value of a query graph node. Allocates a
new buffer if necessary. */
UNIV_INLINE
void
eval_node_copy_and_alloc_val(
/*=========================*/
- que_node_t* node, /* in: query graph node */
- const byte* str, /* in: binary string */
- ulint len) /* in: string length or UNIV_SQL_NULL */
+ que_node_t* node, /*!< in: query graph node */
+ const byte* str, /*!< in: binary string */
+ ulint len) /*!< in: string length or UNIV_SQL_NULL */
{
byte* data;
@@ -232,14 +233,14 @@ eval_node_copy_and_alloc_val(
ut_memcpy(data, str, len);
}
-/*********************************************************************
+/*****************************************************************//**
Copies a query node value to another node. */
UNIV_INLINE
void
eval_node_copy_val(
/*===============*/
- que_node_t* node1, /* in: node to copy to */
- que_node_t* node2) /* in: node to copy from */
+ que_node_t* node1, /*!< in: node to copy to */
+ que_node_t* node2) /*!< in: node to copy from */
{
dfield_t* dfield2;
diff --git a/storage/xtradb/include/eval0proc.h b/storage/xtradb/include/eval0proc.h
index 58937c18124..13e2e365320 100644
--- a/storage/xtradb/include/eval0proc.h
+++ b/storage/xtradb/include/eval0proc.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/eval0proc.h
Executes SQL stored procedures and their control structures
Created 1/20/1998 Heikki Tuuri
@@ -30,70 +31,70 @@ Created 1/20/1998 Heikki Tuuri
#include "pars0sym.h"
#include "pars0pars.h"
-/**************************************************************************
-Performs an execution step of a procedure node. */
+/**********************************************************************//**
+Performs an execution step of a procedure node.
+@return query thread to run next or NULL */
UNIV_INLINE
que_thr_t*
proc_step(
/*======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of an if-statement node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of an if-statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
if_step(
/*====*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of a while-statement node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of a while-statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
while_step(
/*=======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of a for-loop node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of a for-loop node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
for_step(
/*=====*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of an assignment statement node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of an assignment statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
assign_step(
/*========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of a procedure call node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of a procedure call node.
+@return query thread to run next or NULL */
UNIV_INLINE
que_thr_t*
proc_eval_step(
/*===========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of an exit statement node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of an exit statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
exit_step(
/*======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of a return-statement node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of a return-statement node.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
return_step(
/*========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
+ que_thr_t* thr); /*!< in: query thread */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/eval0proc.ic b/storage/xtradb/include/eval0proc.ic
index 6bd978ad3fc..c602af0a694 100644
--- a/storage/xtradb/include/eval0proc.ic
+++ b/storage/xtradb/include/eval0proc.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/eval0proc.ic
Executes SQL stored procedures and their control structures
Created 1/20/1998 Heikki Tuuri
@@ -26,14 +27,14 @@ Created 1/20/1998 Heikki Tuuri
#include "que0que.h"
#include "eval0eval.h"
-/**************************************************************************
-Performs an execution step of a procedure node. */
+/**********************************************************************//**
+Performs an execution step of a procedure node.
+@return query thread to run next or NULL */
UNIV_INLINE
que_thr_t*
proc_step(
/*======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
proc_node_t* node;
@@ -61,14 +62,14 @@ proc_step(
return(thr);
}
-/**************************************************************************
-Performs an execution step of a procedure call node. */
+/**********************************************************************//**
+Performs an execution step of a procedure call node.
+@return query thread to run next or NULL */
UNIV_INLINE
que_thr_t*
proc_eval_step(
/*===========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
func_node_t* node;
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index 587e5ee48a8..0470d533dec 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/fil0fil.h
The low-level file system
Created 10/25/1995 Heikki Tuuri
@@ -26,58 +27,62 @@ Created 10/25/1995 Heikki Tuuri
#define fil0fil_h
#include "univ.i"
+#ifndef UNIV_HOTBACKUP
#include "sync0rw.h"
+#endif /* !UNIV_HOTBACKUP */
#include "dict0types.h"
#include "ut0byte.h"
#include "os0file.h"
-/* When mysqld is run, the default directory "." is the mysqld datadir, but in
-ibbackup we must set it explicitly; the patgh must NOT contain the trailing
-'/' or '\' */
+/** When mysqld is run, the default directory "." is the mysqld datadir,
+but in the MySQL Embedded Server Library and ibbackup it is not the default
+directory, and we must set the base file path explicitly */
extern const char* fil_path_to_mysql_datadir;
-/* Initial size of a single-table tablespace in pages */
+/** Initial size of a single-table tablespace in pages */
#define FIL_IBD_FILE_INITIAL_SIZE 4
-/* 'null' (undefined) page offset in the context of file spaces */
+/** 'null' (undefined) page offset in the context of file spaces */
#define FIL_NULL ULINT32_UNDEFINED
/* Space address data type; this is intended to be used when
addresses accurate to a byte are stored in file pages. If the page part
of the address is FIL_NULL, the address is considered undefined. */
-typedef byte fil_faddr_t; /* 'type' definition in C: an address
+typedef byte fil_faddr_t; /*!< 'type' definition in C: an address
stored in a file page is a string of bytes */
#define FIL_ADDR_PAGE 0 /* first in address is the page offset */
#define FIL_ADDR_BYTE 4 /* then comes 2-byte byte offset within page*/
#define FIL_ADDR_SIZE 6 /* address size is 6 bytes */
-/* A struct for storing a space address FIL_ADDR, when it is used
+/** A struct for storing a space address FIL_ADDR, when it is used
in C program data structures. */
typedef struct fil_addr_struct fil_addr_t;
+/** File space address */
struct fil_addr_struct{
- ulint page; /* page number within a space */
- ulint boffset; /* byte offset within the page */
+ ulint page; /*!< page number within a space */
+ ulint boffset; /*!< byte offset within the page */
};
-/* Null file address */
+/** The null file address */
extern fil_addr_t fil_addr_null;
-/* The byte offsets on a file page for various variables */
-#define FIL_PAGE_SPACE_OR_CHKSUM 0 /* in < MySQL-4.0.14 space id the
+/** The byte offsets on a file page for various variables @{ */
+#define FIL_PAGE_SPACE_OR_CHKSUM 0 /*!< in < MySQL-4.0.14 space id the
page belongs to (== 0) but in later
versions the 'new' checksum of the
page */
-#define FIL_PAGE_OFFSET 4 /* page offset inside space */
-#define FIL_PAGE_PREV 8 /* if there is a 'natural' predecessor
- of the page, its offset.
- Otherwise FIL_NULL.
- This field is not set on BLOB pages,
- which are stored as a singly-linked
- list. See also FIL_PAGE_NEXT. */
-#define FIL_PAGE_NEXT 12 /* if there is a 'natural' successor
+#define FIL_PAGE_OFFSET 4 /*!< page offset inside space */
+#define FIL_PAGE_PREV 8 /*!< if there is a 'natural'
+ predecessor of the page, its
+ offset. Otherwise FIL_NULL.
+ This field is not set on BLOB
+ pages, which are stored as a
+ singly-linked list. See also
+ FIL_PAGE_NEXT. */
+#define FIL_PAGE_NEXT 12 /*!< if there is a 'natural' successor
of the page, its offset.
Otherwise FIL_NULL.
B-tree index pages
@@ -87,9 +92,9 @@ extern fil_addr_t fil_addr_null;
FIL_PAGE_PREV and FIL_PAGE_NEXT
in the collation order of the
smallest user record on each page. */
-#define FIL_PAGE_LSN 16 /* lsn of the end of the newest
+#define FIL_PAGE_LSN 16 /*!< lsn of the end of the newest
modification log record to the page */
-#define FIL_PAGE_TYPE 24 /* file page type: FIL_PAGE_INDEX,...,
+#define FIL_PAGE_TYPE 24 /*!< file page type: FIL_PAGE_INDEX,...,
2 bytes.
The contents of this field can only
@@ -104,167 +109,175 @@ extern fil_addr_t fil_addr_null;
MySQL/InnoDB 5.1.7 or later, the
contents of this field is valid
for all uncompressed pages. */
-#define FIL_PAGE_FILE_FLUSH_LSN 26 /* this is only defined for the
+#define FIL_PAGE_FILE_FLUSH_LSN 26 /*!< this is only defined for the
first page in a data file: the file
has been flushed to disk at least up
to this lsn */
-#define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 34 /* starting from 4.1.x this
+#define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 34 /*!< starting from 4.1.x this
contains the space id of the page */
-#define FIL_PAGE_DATA 38 /* start of the data on the page */
-
-/* File page trailer */
-#define FIL_PAGE_END_LSN_OLD_CHKSUM 8 /* the low 4 bytes of this are used
+#define FIL_PAGE_DATA 38 /*!< start of the data on the page */
+/* @} */
+/** File page trailer @{ */
+#define FIL_PAGE_END_LSN_OLD_CHKSUM 8 /*!< the low 4 bytes of this are used
to store the page checksum, the
last 4 bytes should be identical
to the last 4 bytes of FIL_PAGE_LSN */
-#define FIL_PAGE_DATA_END 8
-
-/* File page types (values of FIL_PAGE_TYPE) */
-#define FIL_PAGE_INDEX 17855 /* B-tree node */
-#define FIL_PAGE_UNDO_LOG 2 /* Undo log page */
-#define FIL_PAGE_INODE 3 /* Index node */
-#define FIL_PAGE_IBUF_FREE_LIST 4 /* Insert buffer free list */
+#define FIL_PAGE_DATA_END 8 /*!< size of the page trailer */
+/* @} */
+
+/** File page types (values of FIL_PAGE_TYPE) @{ */
+#define FIL_PAGE_INDEX 17855 /*!< B-tree node */
+#define FIL_PAGE_UNDO_LOG 2 /*!< Undo log page */
+#define FIL_PAGE_INODE 3 /*!< Index node */
+#define FIL_PAGE_IBUF_FREE_LIST 4 /*!< Insert buffer free list */
/* File page types introduced in MySQL/InnoDB 5.1.7 */
-#define FIL_PAGE_TYPE_ALLOCATED 0 /* Freshly allocated page */
-#define FIL_PAGE_IBUF_BITMAP 5 /* Insert buffer bitmap */
-#define FIL_PAGE_TYPE_SYS 6 /* System page */
-#define FIL_PAGE_TYPE_TRX_SYS 7 /* Transaction system data */
-#define FIL_PAGE_TYPE_FSP_HDR 8 /* File space header */
-#define FIL_PAGE_TYPE_XDES 9 /* Extent descriptor page */
-#define FIL_PAGE_TYPE_BLOB 10 /* Uncompressed BLOB page */
-#define FIL_PAGE_TYPE_ZBLOB 11 /* First compressed BLOB page */
-#define FIL_PAGE_TYPE_ZBLOB2 12 /* Subsequent compressed BLOB page */
-
-/* Space types */
-#define FIL_TABLESPACE 501
-#define FIL_LOG 502
-
+#define FIL_PAGE_TYPE_ALLOCATED 0 /*!< Freshly allocated page */
+#define FIL_PAGE_IBUF_BITMAP 5 /*!< Insert buffer bitmap */
+#define FIL_PAGE_TYPE_SYS 6 /*!< System page */
+#define FIL_PAGE_TYPE_TRX_SYS 7 /*!< Transaction system data */
+#define FIL_PAGE_TYPE_FSP_HDR 8 /*!< File space header */
+#define FIL_PAGE_TYPE_XDES 9 /*!< Extent descriptor page */
+#define FIL_PAGE_TYPE_BLOB 10 /*!< Uncompressed BLOB page */
+#define FIL_PAGE_TYPE_ZBLOB 11 /*!< First compressed BLOB page */
+#define FIL_PAGE_TYPE_ZBLOB2 12 /*!< Subsequent compressed BLOB page */
+/* @} */
+
+/** Space types @{ */
+#define FIL_TABLESPACE 501 /*!< tablespace */
+#define FIL_LOG 502 /*!< redo log */
+/* @} */
+
+/** The number of fsyncs done to the log */
extern ulint fil_n_log_flushes;
+/** Number of pending redo log flushes */
extern ulint fil_n_pending_log_flushes;
+/** Number of pending tablespace flushes */
extern ulint fil_n_pending_tablespace_flushes;
-/***********************************************************************
-Returns the version number of a tablespace, -1 if not found. */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
+Returns the version number of a tablespace, -1 if not found.
+@return version number, -1 if the tablespace does not exist in the
+memory cache */
UNIV_INTERN
ib_int64_t
fil_space_get_version(
/*==================*/
- /* out: version number, -1 if the tablespace does not
- exist in the memory cache */
- ulint id); /* in: space id */
-/***********************************************************************
-Returns the latch of a file space. */
+ ulint id); /*!< in: space id */
+/*******************************************************************//**
+Returns the latch of a file space.
+@return latch protecting storage allocation */
UNIV_INTERN
rw_lock_t*
fil_space_get_latch(
/*================*/
- /* out: latch protecting storage allocation */
- ulint id, /* in: space id */
- ulint* zip_size);/* out: compressed page size, or
+ ulint id, /*!< in: space id */
+ ulint* zip_size);/*!< out: compressed page size, or
0 for uncompressed tablespaces */
-/***********************************************************************
-Returns the type of a file space. */
+/*******************************************************************//**
+Returns the type of a file space.
+@return FIL_TABLESPACE or FIL_LOG */
UNIV_INTERN
ulint
fil_space_get_type(
/*===============*/
- /* out: FIL_TABLESPACE or FIL_LOG */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+#endif /* !UNIV_HOTBACKUP */
+/*******************************************************************//**
Appends a new file to the chain of files of a space. File must be closed. */
UNIV_INTERN
void
fil_node_create(
/*============*/
- const char* name, /* in: file name (file must be closed) */
- ulint size, /* in: file size in database blocks, rounded
+ const char* name, /*!< in: file name (file must be closed) */
+ ulint size, /*!< in: file size in database blocks, rounded
downwards to an integer */
- ulint id, /* in: space id where to append */
- ibool is_raw);/* in: TRUE if a raw device or
+ ulint id, /*!< in: space id where to append */
+ ibool is_raw);/*!< in: TRUE if a raw device or
a raw disk partition */
#ifdef UNIV_LOG_ARCHIVE
-/********************************************************************
+/****************************************************************//**
Drops files from the start of a file space, so that its size is cut by
the amount given. */
UNIV_INTERN
void
fil_space_truncate_start(
/*=====================*/
- ulint id, /* in: space id */
- ulint trunc_len); /* in: truncate by this much; it is an error
+ ulint id, /*!< in: space id */
+ ulint trunc_len); /*!< in: truncate by this much; it is an error
if this does not equal to the combined size of
some initial files in the space */
#endif /* UNIV_LOG_ARCHIVE */
-/***********************************************************************
+/*******************************************************************//**
Creates a space memory object and puts it to the 'fil system' hash table. If
-there is an error, prints an error message to the .err log. */
+there is an error, prints an error message to the .err log.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_space_create(
/*=============*/
- /* out: TRUE if success */
- const char* name, /* in: space name */
- ulint id, /* in: space id */
- ulint zip_size,/* in: compressed page size, or
+ const char* name, /*!< in: space name */
+ ulint id, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size, or
0 for uncompressed tablespaces */
- ulint purpose);/* in: FIL_TABLESPACE, or FIL_LOG if log */
-/***********************************************************************
+ ulint purpose);/*!< in: FIL_TABLESPACE, or FIL_LOG if log */
+/*******************************************************************//**
Frees a space object from a the tablespace memory cache. Closes the files in
-the chain but does not delete them. */
+the chain but does not delete them.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_space_free(
/*===========*/
- /* out: TRUE if success */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+/*******************************************************************//**
Returns the size of the space in pages. The tablespace must be cached in the
-memory cache. */
+memory cache.
+@return space size, 0 if space not found */
UNIV_INTERN
ulint
fil_space_get_size(
/*===============*/
- /* out: space size, 0 if space not found */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+/*******************************************************************//**
Returns the flags of the space. The tablespace must be cached
-in the memory cache. */
+in the memory cache.
+@return flags, ULINT_UNDEFINED if space not found */
UNIV_INTERN
ulint
fil_space_get_flags(
/*================*/
- /* out: flags, ULINT_UNDEFINED if space not found */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+/*******************************************************************//**
Returns the compressed page size of the space, or 0 if the space
-is not compressed. The tablespace must be cached in the memory cache. */
+is not compressed. The tablespace must be cached in the memory cache.
+@return compressed page size, ULINT_UNDEFINED if space not found */
UNIV_INTERN
ulint
fil_space_get_zip_size(
/*===================*/
- /* out: compressed page size, ULINT_UNDEFINED
- if space not found */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+/*******************************************************************//**
Checks if the pair space, page_no refers to an existing page in a tablespace
-file space. The tablespace must be cached in the memory cache. */
+file space. The tablespace must be cached in the memory cache.
+@return TRUE if the address is meaningful */
UNIV_INTERN
ibool
fil_check_adress_in_tablespace(
/*===========================*/
- /* out: TRUE if the address is meaningful */
- ulint id, /* in: space id */
- ulint page_no);/* in: page number */
-/********************************************************************
+ ulint id, /*!< in: space id */
+ ulint page_no);/*!< in: page number */
+/****************************************************************//**
Initializes the tablespace memory cache. */
UNIV_INTERN
void
fil_init(
/*=====*/
- ulint max_n_open); /* in: max number of open files */
-/***********************************************************************
+ ulint hash_size, /*!< in: hash table size */
+ ulint max_n_open); /*!< in: max number of open files */
+/*******************************************************************//**
Opens all log files and system tablespace data files. They stay open until the
database server shutdown. This should be called at a server startup after the
space objects for the log and the system tablespace have been created. The
@@ -274,67 +287,68 @@ UNIV_INTERN
void
fil_open_log_and_system_tablespace_files(void);
/*==========================================*/
-/***********************************************************************
+/*******************************************************************//**
Closes all open files. There must not be any pending i/o's or not flushed
modifications in the files. */
UNIV_INTERN
void
fil_close_all_files(void);
/*=====================*/
-/***********************************************************************
+/*******************************************************************//**
Sets the max tablespace id counter if the given number is bigger than the
previous value. */
UNIV_INTERN
void
fil_set_max_space_id_if_bigger(
/*===========================*/
- ulint max_id);/* in: maximum known id */
-/********************************************************************
+ ulint max_id);/*!< in: maximum known id */
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
Writes the flushed lsn and the latest archived log number to the page
-header of the first page of each data file in the system tablespace. */
+header of the first page of each data file in the system tablespace.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
fil_write_flushed_lsn_to_data_files(
/*================================*/
- /* out: DB_SUCCESS or error number */
- ib_uint64_t lsn, /* in: lsn to write */
- ulint arch_log_no); /* in: latest archived log
+ ib_uint64_t lsn, /*!< in: lsn to write */
+ ulint arch_log_no); /*!< in: latest archived log
file number */
-/***********************************************************************
+/*******************************************************************//**
Reads the flushed lsn and arch no fields from a data file at database
startup. */
UNIV_INTERN
void
fil_read_flushed_lsn_and_arch_log_no(
/*=================================*/
- os_file_t data_file, /* in: open data file */
- ibool one_read_already, /* in: TRUE if min and max
+ os_file_t data_file, /*!< in: open data file */
+ ibool one_read_already, /*!< in: TRUE if min and max
parameters below already
contain sensible data */
#ifdef UNIV_LOG_ARCHIVE
- ulint* min_arch_log_no, /* in/out: */
- ulint* max_arch_log_no, /* in/out: */
+ ulint* min_arch_log_no, /*!< in/out: */
+ ulint* max_arch_log_no, /*!< in/out: */
#endif /* UNIV_LOG_ARCHIVE */
- ib_uint64_t* min_flushed_lsn, /* in/out: */
- ib_uint64_t* max_flushed_lsn); /* in/out: */
-/***********************************************************************
+ ib_uint64_t* min_flushed_lsn, /*!< in/out: */
+ ib_uint64_t* max_flushed_lsn); /*!< in/out: */
+/*******************************************************************//**
Increments the count of pending insert buffer page merges, if space is not
-being deleted. */
+being deleted.
+@return TRUE if being deleted, and ibuf merges should be skipped */
UNIV_INTERN
ibool
fil_inc_pending_ibuf_merges(
/*========================*/
- /* out: TRUE if being deleted, and ibuf merges should
- be skipped */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+/*******************************************************************//**
Decrements the count of pending insert buffer page merges. */
UNIV_INTERN
void
fil_decr_pending_ibuf_merges(
/*=========================*/
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+#endif /* !UNIV_HOTBACKUP */
+/*******************************************************************//**
Parses the body of a log record written about an .ibd file operation. That is,
the log record part after the standard (type, space id, page no) header of the
log record.
@@ -345,87 +359,91 @@ at that path does not exist yet. If the database directory for the file to be
created does not exist, then we create the directory, too.
Note that ibbackup --apply-log sets fil_path_to_mysql_datadir to point to the
-datadir that we should use in replaying the file operations. */
+datadir that we should use in replaying the file operations.
+@return end of log record, or NULL if the record was not completely
+contained between ptr and end_ptr */
UNIV_INTERN
byte*
fil_op_log_parse_or_replay(
/*=======================*/
- /* out: end of log record, or NULL if the
- record was not completely contained between
- ptr and end_ptr */
- byte* ptr, /* in: buffer containing the log record body,
+ byte* ptr, /*!< in: buffer containing the log record body,
or an initial segment of it, if the record does
not fir completely between ptr and end_ptr */
- byte* end_ptr, /* in: buffer end */
- ulint type, /* in: the type of this log record */
- ulint space_id); /* in: the space id of the tablespace in
+ byte* end_ptr, /*!< in: buffer end */
+ ulint type, /*!< in: the type of this log record */
+ ulint space_id, /*!< in: the space id of the tablespace in
question, or 0 if the log record should
only be parsed but not replayed */
-/***********************************************************************
+ ulint log_flags); /*!< in: redo log flags
+ (stored in the page number parameter) */
+/*******************************************************************//**
Deletes a single-table tablespace. The tablespace must be cached in the
-memory cache. */
+memory cache.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_delete_tablespace(
/*==================*/
- /* out: TRUE if success */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Discards a single-table tablespace. The tablespace must be cached in the
memory cache. Discarding is like deleting a tablespace, but
1) we do not drop the table from the data dictionary;
2) we remove all insert buffer entries for the tablespace immediately; in DROP
TABLE they are only removed gradually in the background;
3) when the user does IMPORT TABLESPACE, the tablespace will have the same id
-as it originally had. */
+as it originally had.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_discard_tablespace(
/*===================*/
- /* out: TRUE if success */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+#endif /* !UNIV_HOTBACKUP */
+/*******************************************************************//**
Renames a single-table tablespace. The tablespace must be cached in the
-tablespace memory cache. */
+tablespace memory cache.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_rename_tablespace(
/*==================*/
- /* out: TRUE if success */
- const char* old_name, /* in: old table name in the standard
+ const char* old_name, /*!< in: old table name in the standard
databasename/tablename format of
InnoDB, or NULL if we do the rename
based on the space id only */
- ulint id, /* in: space id */
- const char* new_name); /* in: new table name in the standard
+ ulint id, /*!< in: space id */
+ const char* new_name); /*!< in: new table name in the standard
databasename/tablename format
of InnoDB */
-/***********************************************************************
+/*******************************************************************//**
Creates a new single-table tablespace to a database directory of MySQL.
Database directories are under the 'datadir' of MySQL. The datadir is the
directory of a running mysqld program. We can refer to it by simply the
path '.'. Tables created with CREATE TEMPORARY TABLE we place in the temp
-dir of the mysqld server. */
+dir of the mysqld server.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
fil_create_new_single_table_tablespace(
/*===================================*/
- /* out: DB_SUCCESS or error code */
- ulint* space_id, /* in/out: space id; if this is != 0,
+ ulint* space_id, /*!< in/out: space id; if this is != 0,
then this is an input parameter,
otherwise output */
- const char* tablename, /* in: the table name in the usual
+ const char* tablename, /*!< in: the table name in the usual
databasename/tablename format
of InnoDB, or a dir path to a temp
table */
- ibool is_temp, /* in: TRUE if a table created with
+ ibool is_temp, /*!< in: TRUE if a table created with
CREATE TEMPORARY TABLE */
- ulint flags, /* in: tablespace flags */
- ulint size); /* in: the initial size of the
+ ulint flags, /*!< in: tablespace flags */
+ ulint size); /*!< in: the initial size of the
tablespace file in pages,
must be >= FIL_IBD_FILE_INITIAL_SIZE */
-/************************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Tries to open a single-table tablespace and optionally checks the space id is
right in it. If does not succeed, prints an error message to the .err log. This
function is used to open a tablespace when we start up mysqld, and also in
@@ -433,24 +451,24 @@ IMPORT TABLESPACE.
NOTE that we assume this operation is used either at the database startup
or under the protection of the dictionary mutex, so that two users cannot
race here. This operation does not leave the file associated with the
-tablespace open, but closes it after we have looked at the space id in it. */
+tablespace open, but closes it after we have looked at the space id in it.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_open_single_table_tablespace(
/*=============================*/
- /* out: TRUE if success */
- ibool check_space_id, /* in: should we check that the space
+ ibool check_space_id, /*!< in: should we check that the space
id in the file is right; we assume
that this function runs much faster
if no check is made, since accessing
the file inode probably is much
faster (the OS caches them) than
accessing the first page of the file */
- ulint id, /* in: space id */
- ulint flags, /* in: tablespace flags */
- const char* name); /* in: table name in the
+ ulint id, /*!< in: space id */
+ ulint flags, /*!< in: tablespace flags */
+ const char* name); /*!< in: table name in the
databasename/tablename format */
-/************************************************************************
+/********************************************************************//**
It is possible, though very improbable, that the lsn's in the tablespace to be
imported have risen above the current system lsn, if a lengthy purge, ibuf
merge, or rollback was performed on a backup taken with ibbackup. If that is
@@ -458,30 +476,31 @@ the case, reset page lsn's in the file. We assume that mysqld was shut down
after it performed these cleanup operations on the .ibd file, so that it at
the shutdown stamped the latest lsn to the FIL_PAGE_FILE_FLUSH_LSN in the
first page of the .ibd file, and we can determine whether we need to reset the
-lsn's just by looking at that flush lsn. */
+lsn's just by looking at that flush lsn.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_reset_too_high_lsns(
/*====================*/
- /* out: TRUE if success */
- const char* name, /* in: table name in the
+ const char* name, /*!< in: table name in the
databasename/tablename format */
- ib_uint64_t current_lsn); /* in: reset lsn's if the lsn stamped
+ ib_uint64_t current_lsn); /*!< in: reset lsn's if the lsn stamped
to FIL_PAGE_FILE_FLUSH_LSN in the
first page is too high */
-/************************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
At the server startup, if we need crash recovery, scans the database
directories under the MySQL datadir, looking for .ibd files. Those files are
single-table tablespaces. We need to know the space id in each of them so that
we know into which file we should look to check the contents of a page stored
in the doublewrite buffer, also to know where to apply log records where the
-space id is != 0. */
+space id is != 0.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
fil_load_single_table_tablespaces(void);
/*===================================*/
- /* out: DB_SUCCESS or error number */
-/************************************************************************
+/********************************************************************//**
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
@@ -491,117 +510,115 @@ 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. */
+or is being deleted there.
+@return TRUE if does not exist or is being\ deleted */
UNIV_INTERN
ibool
fil_tablespace_deleted_or_being_deleted_in_mem(
/*===========================================*/
- /* out: TRUE if does not exist or is being\
- deleted */
- ulint id, /* in: space id */
- ib_int64_t version);/* in: tablespace_version should be this; if
+ ulint id, /*!< in: space id */
+ ib_int64_t version);/*!< in: tablespace_version should be this; if
you pass -1 as the value of this, then this
parameter is ignored */
-/***********************************************************************
-Returns TRUE if a single-table tablespace exists in the memory cache. */
+/*******************************************************************//**
+Returns TRUE if a single-table tablespace exists in the memory cache.
+@return TRUE if exists */
UNIV_INTERN
ibool
fil_tablespace_exists_in_mem(
/*=========================*/
- /* out: TRUE if exists */
- ulint id); /* in: space id */
-/***********************************************************************
+ ulint id); /*!< in: space id */
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Returns TRUE if a matching tablespace exists in the InnoDB tablespace memory
cache. Note that if we have not done a crash recovery at the database startup,
-there may be many tablespaces which are not yet in the memory cache. */
+there may be many tablespaces which are not yet in the memory cache.
+@return TRUE if a matching tablespace exists in the memory cache */
UNIV_INTERN
ibool
fil_space_for_table_exists_in_mem(
/*==============================*/
- /* out: TRUE if a matching tablespace
- exists in the memory cache */
- ulint id, /* in: space id */
- const char* name, /* in: table name in the standard
+ ulint id, /*!< in: space id */
+ const char* name, /*!< in: table name in the standard
'databasename/tablename' format or
the dir path to a temp table */
- ibool is_temp, /* in: TRUE if created with CREATE
+ ibool is_temp, /*!< in: TRUE if created with CREATE
TEMPORARY TABLE */
- ibool mark_space, /* in: in crash recovery, at database
+ ibool mark_space, /*!< in: in crash recovery, at database
startup we mark all spaces which have
an associated table in the InnoDB
data dictionary, so that
we can print a warning about orphaned
tablespaces */
ibool print_error_if_does_not_exist);
- /* in: print detailed error
+ /*!< in: print detailed error
information to the .err log if a
matching tablespace is not found from
memory */
-/**************************************************************************
+#else /* !UNIV_HOTBACKUP */
+/********************************************************************//**
+Extends all tablespaces to the size stored in the space header. During the
+ibbackup --apply-log phase we extended the spaces on-demand so that log records
+could be appllied, but that may have left spaces still too small compared to
+the size stored in the space header. */
+UNIV_INTERN
+void
+fil_extend_tablespaces_to_stored_len(void);
+/*======================================*/
+#endif /* !UNIV_HOTBACKUP */
+/**********************************************************************//**
Tries to extend a data file so that it would accommodate the number of pages
given. The tablespace must be cached in the memory cache. If the space is big
-enough already, does nothing. */
+enough already, does nothing.
+@return TRUE if success */
UNIV_INTERN
ibool
fil_extend_space_to_desired_size(
/*=============================*/
- /* out: TRUE if success */
- ulint* actual_size, /* out: size of the space after extension;
+ ulint* actual_size, /*!< out: size of the space after extension;
if we ran out of disk space this may be lower
than the desired size */
- ulint space_id, /* in: space id */
- ulint size_after_extend);/* in: desired size in pages after the
+ ulint space_id, /*!< in: space id */
+ ulint size_after_extend);/*!< in: desired size in pages after the
extension; if the current space size is bigger
than this already, the function does nothing */
-#ifdef UNIV_HOTBACKUP
-/************************************************************************
-Extends all tablespaces to the size stored in the space header. During the
-ibbackup --apply-log phase we extended the spaces on-demand so that log records
-could be appllied, but that may have left spaces still too small compared to
-the size stored in the space header. */
-UNIV_INTERN
-void
-fil_extend_tablespaces_to_stored_len(void);
-/*======================================*/
-#endif
-/***********************************************************************
-Tries to reserve free extents in a file space. */
+/*******************************************************************//**
+Tries to reserve free extents in a file space.
+@return TRUE if succeed */
UNIV_INTERN
ibool
fil_space_reserve_free_extents(
/*===========================*/
- /* out: TRUE if succeed */
- ulint id, /* in: space id */
- ulint n_free_now, /* in: number of free extents now */
- ulint n_to_reserve); /* in: how many one wants to reserve */
-/***********************************************************************
+ ulint id, /*!< in: space id */
+ ulint n_free_now, /*!< in: number of free extents now */
+ ulint n_to_reserve); /*!< in: how many one wants to reserve */
+/*******************************************************************//**
Releases free extents in a file space. */
UNIV_INTERN
void
fil_space_release_free_extents(
/*===========================*/
- ulint id, /* in: space id */
- ulint n_reserved); /* in: how many one reserved */
-/***********************************************************************
+ ulint id, /*!< in: space id */
+ ulint n_reserved); /*!< in: how many one reserved */
+/*******************************************************************//**
Gets the number of reserved extents. If the database is silent, this number
should be zero. */
UNIV_INTERN
ulint
fil_space_get_n_reserved_extents(
/*=============================*/
- ulint id); /* in: space id */
-/************************************************************************
-Reads or writes data. This operation is asynchronous (aio). */
+ ulint id); /*!< in: space id */
+/********************************************************************//**
+Reads or writes data. This operation is asynchronous (aio).
+@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
+i/o on a tablespace which does not exist */
UNIV_INTERN
ulint
fil_io(
/*===*/
- /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
- if we are trying to do i/o on a tablespace
- which does not exist */
- ulint type, /* in: OS_FILE_READ or OS_FILE_WRITE,
+ ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
ORed to OS_FILE_LOG, if a log i/o
and ORed to OS_AIO_SIMULATED_WAKE_LATER
if simulated aio and we want to post a
@@ -610,23 +627,23 @@ fil_io(
because i/os are not actually handled until
all have been posted: use with great
caution! */
- ibool sync, /* in: TRUE if synchronous aio is desired */
- ulint space_id, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes;
+ ibool sync, /*!< in: TRUE if synchronous aio is desired */
+ ulint space_id, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint block_offset, /* in: offset in number of blocks */
- ulint byte_offset, /* in: remainder of offset in bytes; in
+ ulint block_offset, /*!< in: offset in number of blocks */
+ ulint byte_offset, /*!< in: remainder of offset in bytes; in
aio this must be divisible by the OS block
size */
- ulint len, /* in: how many bytes to read or write; this
+ ulint len, /*!< in: how many bytes to read or write; this
must not cross a file boundary; in aio this
must be a block size multiple */
- void* buf, /* in/out: buffer where to store read data
+ void* buf, /*!< in/out: buffer where to store read data
or from where to write; in aio this must be
appropriately aligned */
- void* message); /* in: message for aio handler if non-sync
+ void* message); /*!< in: message for aio handler if non-sync
aio used, else ignored */
-/**************************************************************************
+/**********************************************************************//**
Waits for an aio operation to complete. This function is used to write the
handler for completed requests. The aio array of pending requests is divided
into segments (see os0file.c for more info). The thread specifies which
@@ -635,65 +652,73 @@ UNIV_INTERN
void
fil_aio_wait(
/*=========*/
- ulint segment); /* in: the number of the segment in the aio
+ ulint segment); /*!< in: the number of the segment in the aio
array to wait for */
-/**************************************************************************
+/**********************************************************************//**
Flushes to disk possible writes cached by the OS. If the space does not exist
or is being dropped, does not do anything. */
UNIV_INTERN
void
fil_flush(
/*======*/
- ulint space_id); /* in: file space id (this can be a group of
+ ulint space_id); /*!< in: file space id (this can be a group of
log files or a tablespace of the database) */
-/**************************************************************************
+/**********************************************************************//**
Flushes to disk writes in file spaces of the given type possibly cached by
the OS. */
UNIV_INTERN
void
fil_flush_file_spaces(
/*==================*/
- ulint purpose); /* in: FIL_TABLESPACE, FIL_LOG */
-/**********************************************************************
-Checks the consistency of the tablespace cache. */
+ ulint purpose); /*!< in: FIL_TABLESPACE, FIL_LOG */
+/******************************************************************//**
+Checks the consistency of the tablespace cache.
+@return TRUE if ok */
UNIV_INTERN
ibool
fil_validate(void);
/*==============*/
- /* out: TRUE if ok */
-/************************************************************************
-Returns TRUE if file address is undefined. */
+/********************************************************************//**
+Returns TRUE if file address is undefined.
+@return TRUE if undefined */
UNIV_INTERN
ibool
fil_addr_is_null(
/*=============*/
- /* out: TRUE if undefined */
- fil_addr_t addr); /* in: address */
-/************************************************************************
-Accessor functions for a file page */
+ fil_addr_t addr); /*!< in: address */
+/********************************************************************//**
+Get the predecessor of a file page.
+@return FIL_PAGE_PREV */
UNIV_INTERN
ulint
-fil_page_get_prev(const byte* page);
+fil_page_get_prev(
+/*==============*/
+ const byte* page); /*!< in: file page */
+/********************************************************************//**
+Get the successor of a file page.
+@return FIL_PAGE_NEXT */
+UNIV_INTERN
ulint
-fil_page_get_next(const byte* page);
-/*************************************************************************
+fil_page_get_next(
+/*==============*/
+ const byte* page); /*!< in: file page */
+/*********************************************************************//**
Sets the file page type. */
UNIV_INTERN
void
fil_page_set_type(
/*==============*/
- byte* page, /* in: file page */
- ulint type); /* in: type */
-/*************************************************************************
-Gets the file page type. */
+ byte* page, /*!< in/out: file page */
+ ulint type); /*!< in: type */
+/*********************************************************************//**
+Gets the file page type.
+@return type; NOTE that if the type has not been written to page, the
+return value not defined */
UNIV_INTERN
ulint
fil_page_get_type(
/*==============*/
- /* out: type; NOTE that if the type
- has not been written to page, the
- return value not defined */
- const byte* page); /* in: file page */
+ const byte* page); /*!< in: file page */
/*************************************************************************
Return local hash table informations. */
diff --git a/storage/xtradb/include/fsp0fsp.h b/storage/xtradb/include/fsp0fsp.h
index 1f6ae4b614b..5f7dc58eedc 100644
--- a/storage/xtradb/include/fsp0fsp.h
+++ b/storage/xtradb/include/fsp0fsp.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/fsp0fsp.h
File space management
Created 12/18/1995 Heikki Tuuri
@@ -31,90 +32,67 @@ Created 12/18/1995 Heikki Tuuri
#include "fut0lst.h"
#include "ut0byte.h"
#include "page0types.h"
+#include "fsp0types.h"
-/* If records are inserted in order, there are the following
-flags to tell this (their type is made byte for the compiler
-to warn if direction and hint parameters are switched in
-fseg_alloc_free_page): */
-#define FSP_UP ((byte)111) /* alphabetically upwards */
-#define FSP_DOWN ((byte)112) /* alphabetically downwards */
-#define FSP_NO_DIR ((byte)113) /* no order */
-
-/* File space extent size (one megabyte) in pages */
-#define FSP_EXTENT_SIZE (1 << (20 - UNIV_PAGE_SIZE_SHIFT))
-
-/* On a page of any file segment, data may be put starting from this offset: */
-#define FSEG_PAGE_DATA FIL_PAGE_DATA
-
-/* File segment header which points to the inode describing the file segment */
-typedef byte fseg_header_t;
-
-#define FSEG_HDR_SPACE 0 /* space id of the inode */
-#define FSEG_HDR_PAGE_NO 4 /* page number of the inode */
-#define FSEG_HDR_OFFSET 8 /* byte offset of the inode */
-
-#define FSEG_HEADER_SIZE 10
-
-/**************************************************************************
+/**********************************************************************//**
Initializes the file space system. */
UNIV_INTERN
void
fsp_init(void);
/*==========*/
-/**************************************************************************
+/**********************************************************************//**
Gets the current free limit of the system tablespace. The free limit
means the place of the first page which has never been put to the the
free list for allocation. The space above that address is initialized
-to zero. Sets also the global variable log_fsp_current_free_limit. */
+to zero. Sets also the global variable log_fsp_current_free_limit.
+@return free limit in megabytes */
UNIV_INTERN
ulint
fsp_header_get_free_limit(void);
/*===========================*/
- /* out: free limit in megabytes */
-/**************************************************************************
+/**********************************************************************//**
Gets the size of the system tablespace from the tablespace header. If
we do not have an auto-extending data file, this should be equal to
the size of the data files. If there is an auto-extending data file,
-this can be smaller. */
+this can be smaller.
+@return size in pages */
UNIV_INTERN
ulint
fsp_header_get_tablespace_size(void);
/*================================*/
- /* out: size in pages */
-/**************************************************************************
-Reads the file space size stored in the header page. */
+/**********************************************************************//**
+Reads the file space size stored in the header page.
+@return tablespace size stored in the space header */
UNIV_INTERN
ulint
fsp_get_size_low(
/*=============*/
- /* out: tablespace size stored in the space header */
- page_t* page); /* in: header page (page 0 in the tablespace) */
-/**************************************************************************
-Reads the space id from the first page of a tablespace. */
+ page_t* page); /*!< in: header page (page 0 in the tablespace) */
+/**********************************************************************//**
+Reads the space id from the first page of a tablespace.
+@return space id, ULINT UNDEFINED if error */
UNIV_INTERN
ulint
fsp_header_get_space_id(
/*====================*/
- /* out: space id, ULINT UNDEFINED if error */
- const page_t* page); /* in: first page of a tablespace */
-/**************************************************************************
-Reads the space flags from the first page of a tablespace. */
+ const page_t* page); /*!< in: first page of a tablespace */
+/**********************************************************************//**
+Reads the space flags from the first page of a tablespace.
+@return flags */
UNIV_INTERN
ulint
fsp_header_get_flags(
/*=================*/
- /* out: flags */
- const page_t* page); /* in: first page of a tablespace */
-/**************************************************************************
-Reads the compressed page size from the first page of a tablespace. */
+ const page_t* page); /*!< in: first page of a tablespace */
+/**********************************************************************//**
+Reads the compressed page size from the first page of a tablespace.
+@return compressed page size in bytes, or 0 if uncompressed */
UNIV_INTERN
ulint
fsp_header_get_zip_size(
/*====================*/
- /* out: compressed page size in bytes,
- or 0 if uncompressed */
- const page_t* page); /* in: first page of a tablespace */
-/**************************************************************************
+ const page_t* page); /*!< in: first page of a tablespace */
+/**********************************************************************//**
Writes the space id and compressed page size to a tablespace header.
This function is used past the buffer pool when we in fil0fil.c create
a new single-table tablespace. */
@@ -122,122 +100,118 @@ UNIV_INTERN
void
fsp_header_init_fields(
/*===================*/
- page_t* page, /* in/out: first page in the space */
- ulint space_id, /* in: space id */
- ulint flags); /* in: tablespace flags (FSP_SPACE_FLAGS):
+ page_t* page, /*!< in/out: first page in the space */
+ ulint space_id, /*!< in: space id */
+ ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS):
0, or table->flags if newer than COMPACT */
-/**************************************************************************
+/**********************************************************************//**
Initializes the space header of a new created space and creates also the
insert buffer tree root if space == 0. */
UNIV_INTERN
void
fsp_header_init(
/*============*/
- ulint space, /* in: space id */
- ulint size, /* in: current size in blocks */
- mtr_t* mtr); /* in: mini-transaction handle */
-/**************************************************************************
+ ulint space, /*!< in: space id */
+ ulint size, /*!< in: current size in blocks */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/**********************************************************************//**
Increases the space size field of a space. */
UNIV_INTERN
void
fsp_header_inc_size(
/*================*/
- ulint space, /* in: space id */
- ulint size_inc,/* in: size increment in pages */
- mtr_t* mtr); /* in: mini-transaction handle */
-/**************************************************************************
-Creates a new segment. */
+ ulint space, /*!< in: space id */
+ ulint size_inc,/*!< in: size increment in pages */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/**********************************************************************//**
+Creates a new segment.
+@return the block where the segment header is placed, x-latched, NULL
+if could not create segment because of lack of space */
UNIV_INTERN
buf_block_t*
fseg_create(
/*========*/
- /* out: the block where the segment header is placed,
- x-latched, NULL if could not create segment
- because of lack of space */
- ulint space, /* in: space id */
- ulint page, /* in: page where the segment header is placed: if
+ ulint space, /*!< in: space id */
+ ulint page, /*!< in: page where the segment header is placed: if
this is != 0, the page must belong to another segment,
if this is 0, a new page will be allocated and it
will belong to the created segment */
- ulint byte_offset, /* in: byte offset of the created segment header
+ ulint byte_offset, /*!< in: byte offset of the created segment header
on the page */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
-Creates a new segment. */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
+Creates a new segment.
+@return the block where the segment header is placed, x-latched, NULL
+if could not create segment because of lack of space */
UNIV_INTERN
buf_block_t*
fseg_create_general(
/*================*/
- /* out: the block where the segment header is placed,
- x-latched, NULL if could not create segment
- because of lack of space */
- ulint space, /* in: space id */
- ulint page, /* in: page where the segment header is placed: if
+ ulint space, /*!< in: space id */
+ ulint page, /*!< in: page where the segment header is placed: if
this is != 0, the page must belong to another segment,
if this is 0, a new page will be allocated and it
will belong to the created segment */
- ulint byte_offset, /* in: byte offset of the created segment header
+ ulint byte_offset, /*!< in: byte offset of the created segment header
on the page */
- ibool has_done_reservation, /* in: TRUE if the caller has already
+ ibool has_done_reservation, /*!< in: TRUE if the caller has already
done the reservation for the pages with
fsp_reserve_free_extents (at least 2 extents: one for
the inode and the other for the segment) then there is
no need to do the check for this individual
operation */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Calculates the number of pages reserved by a segment, and how many pages are
-currently used. */
+currently used.
+@return number of reserved pages */
UNIV_INTERN
ulint
fseg_n_reserved_pages(
/*==================*/
- /* out: number of reserved pages */
- fseg_header_t* header, /* in: segment header */
- ulint* used, /* out: number of pages used (<= reserved) */
- mtr_t* mtr); /* in: mtr handle */
-/**************************************************************************
+ fseg_header_t* header, /*!< in: segment header */
+ ulint* used, /*!< out: number of pages used (<= reserved) */
+ mtr_t* mtr); /*!< in: mtr handle */
+/**********************************************************************//**
Allocates a single free page from a segment. This function implements
the intelligent allocation strategy which tries to minimize
-file space fragmentation. */
+file space fragmentation.
+@return the allocated page offset FIL_NULL if no page could be allocated */
UNIV_INTERN
ulint
fseg_alloc_free_page(
/*=================*/
- /* out: the allocated page offset
- FIL_NULL if no page could be allocated */
- fseg_header_t* seg_header, /* in: segment header */
- ulint hint, /* in: hint of which page would be desirable */
- byte direction, /* in: if the new page is needed because
+ fseg_header_t* seg_header, /*!< in: segment header */
+ ulint hint, /*!< in: hint of which page would be desirable */
+ byte direction, /*!< in: if the new page is needed because
of an index page split, and records are
inserted there in order, into which
direction they go alphabetically: FSP_DOWN,
FSP_UP, FSP_NO_DIR */
- mtr_t* mtr); /* in: mtr handle */
-/**************************************************************************
+ mtr_t* mtr); /*!< in: mtr handle */
+/**********************************************************************//**
Allocates a single free page from a segment. This function implements
the intelligent allocation strategy which tries to minimize file space
-fragmentation. */
+fragmentation.
+@return allocated page offset, FIL_NULL if no page could be allocated */
UNIV_INTERN
ulint
fseg_alloc_free_page_general(
/*=========================*/
- /* out: allocated page offset, FIL_NULL if no
- page could be allocated */
- fseg_header_t* seg_header,/* in: segment header */
- ulint hint, /* in: hint of which page would be desirable */
- byte direction,/* in: if the new page is needed because
+ fseg_header_t* seg_header,/*!< in: segment header */
+ ulint hint, /*!< in: hint of which page would be desirable */
+ byte direction,/*!< in: if the new page is needed because
of an index page split, and records are
inserted there in order, into which
direction they go alphabetically: FSP_DOWN,
FSP_UP, FSP_NO_DIR */
- ibool has_done_reservation, /* in: TRUE if the caller has
+ ibool has_done_reservation, /*!< in: TRUE if the caller has
already done the reservation for the page
with fsp_reserve_free_extents, then there
is no need to do the check for this individual
page */
- mtr_t* mtr); /* in: mtr handle */
-/**************************************************************************
+ mtr_t* mtr); /*!< in: mtr handle */
+/**********************************************************************//**
Reserves free pages from a tablespace. All mini-transactions which may
use several pages from the tablespace should call this function beforehand
and reserve enough free extents so that they certainly will be able
@@ -261,171 +235,123 @@ Single-table tablespaces whose size is < 32 pages are a special case. In this
function we would liberally reserve several 64 page extents for every page
split or merge in a B-tree. But we do not want to waste disk space if the table
only occupies < 32 pages. That is why we apply different rules in that special
-case, just ensuring that there are 3 free pages available. */
+case, just ensuring that there are 3 free pages available.
+@return TRUE if we were able to make the reservation */
UNIV_INTERN
ibool
fsp_reserve_free_extents(
/*=====================*/
- /* out: TRUE if we were able to make the reservation */
- ulint* n_reserved,/* out: number of extents actually reserved; if we
+ ulint* n_reserved,/*!< out: number of extents actually reserved; if we
return TRUE and the tablespace size is < 64 pages,
then this can be 0, otherwise it is n_ext */
- ulint space, /* in: space id */
- ulint n_ext, /* in: number of extents to reserve */
- ulint alloc_type,/* in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ ulint space, /*!< in: space id */
+ ulint n_ext, /*!< in: number of extents to reserve */
+ ulint alloc_type,/*!< in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
This function should be used to get information on how much we still
will be able to insert new data to the database without running out the
tablespace. Only free extents are taken into account and we also subtract
-the safety margin required by the above function fsp_reserve_free_extents. */
+the safety margin required by the above function fsp_reserve_free_extents.
+@return available space in kB */
UNIV_INTERN
ullint
fsp_get_available_space_in_free_extents(
/*====================================*/
- /* out: available space in kB */
- ulint space); /* in: space id */
-/**************************************************************************
+ ulint space); /*!< in: space id */
+/**********************************************************************//**
Frees a single page of a segment. */
UNIV_INTERN
void
fseg_free_page(
/*===========*/
- fseg_header_t* seg_header, /* in: segment header */
- ulint space, /* in: space id */
- ulint page, /* in: page offset */
- mtr_t* mtr); /* in: mtr handle */
-/***********************************************************************
-Frees a segment. The freeing is performed in several mini-transactions,
-so that there is no danger of bufferfixing too many buffer pages. */
-UNIV_INTERN
-void
-fseg_free(
-/*======*/
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
- or 0 for uncompressed pages */
- ulint page_no,/* in: page number where the segment header is
- placed */
- ulint offset);/* in: byte offset of the segment header on that
- page */
-/**************************************************************************
+ fseg_header_t* seg_header, /*!< in: segment header */
+ ulint space, /*!< in: space id */
+ ulint page, /*!< in: page offset */
+ mtr_t* mtr); /*!< in: mtr handle */
+/**********************************************************************//**
Frees part of a segment. This function can be used to free a segment
by repeatedly calling this function in different mini-transactions.
Doing the freeing in a single mini-transaction might result in
-too big a mini-transaction. */
+too big a mini-transaction.
+@return TRUE if freeing completed */
UNIV_INTERN
ibool
fseg_free_step(
/*===========*/
- /* out: TRUE if freeing completed */
- fseg_header_t* header, /* in, own: segment header; NOTE: if the header
+ fseg_header_t* header, /*!< in, own: segment header; NOTE: if the header
resides on the first page of the frag list
of the segment, this pointer becomes obsolete
after the last freeing step */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
Frees part of a segment. Differs from fseg_free_step because this function
-leaves the header page unfreed. */
+leaves the header page unfreed.
+@return TRUE if freeing completed, except the header page */
UNIV_INTERN
ibool
fseg_free_step_not_header(
/*======================*/
- /* out: TRUE if freeing completed, except the
- header page */
- fseg_header_t* header, /* in: segment header which must reside on
+ fseg_header_t* header, /*!< in: segment header which must reside on
the first fragment page of the segment */
- mtr_t* mtr); /* in: mtr */
-/***************************************************************************
-Checks if a page address is an extent descriptor page address. */
+ mtr_t* mtr); /*!< in: mtr */
+/***********************************************************************//**
+Checks if a page address is an extent descriptor page address.
+@return TRUE if a descriptor page */
UNIV_INLINE
ibool
fsp_descr_page(
/*===========*/
- /* out: TRUE if a descriptor page */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint page_no);/* in: page number */
-/***************************************************************
-Parses a redo log record of a file page init. */
+ ulint page_no);/*!< in: page number */
+/***********************************************************//**
+Parses a redo log record of a file page init.
+@return end of log record or NULL */
UNIV_INTERN
byte*
fsp_parse_init_file_page(
/*=====================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr, /* in: buffer end */
- buf_block_t* block); /* in: block or NULL */
-/***********************************************************************
-Validates the file space system and its segments. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr, /*!< in: buffer end */
+ buf_block_t* block); /*!< in: block or NULL */
+/*******************************************************************//**
+Validates the file space system and its segments.
+@return TRUE if ok */
UNIV_INTERN
ibool
fsp_validate(
/*=========*/
- /* out: TRUE if ok */
- ulint space); /* in: space id */
-/***********************************************************************
+ ulint space); /*!< in: space id */
+/*******************************************************************//**
Prints info of a file space. */
UNIV_INTERN
void
fsp_print(
/*======*/
- ulint space); /* in: space id */
-/***********************************************************************
-Validates a segment. */
+ ulint space); /*!< in: space id */
+#ifdef UNIV_DEBUG
+/*******************************************************************//**
+Validates a segment.
+@return TRUE if ok */
UNIV_INTERN
ibool
fseg_validate(
/*==========*/
- /* out: TRUE if ok */
- fseg_header_t* header, /* in: segment header */
- mtr_t* mtr2); /* in: mtr */
+ fseg_header_t* header, /*!< in: segment header */
+ mtr_t* mtr); /*!< in: mtr */
+#endif /* UNIV_DEBUG */
#ifdef UNIV_BTR_PRINT
-/***********************************************************************
+/*******************************************************************//**
Writes info of a segment. */
UNIV_INTERN
void
fseg_print(
/*=======*/
- fseg_header_t* header, /* in: segment header */
- mtr_t* mtr); /* in: mtr */
+ fseg_header_t* header, /*!< in: segment header */
+ mtr_t* mtr); /*!< in: mtr */
#endif /* UNIV_BTR_PRINT */
-/* Flags for fsp_reserve_free_extents */
-#define FSP_NORMAL 1000000
-#define FSP_UNDO 2000000
-#define FSP_CLEANING 3000000
-
-/* Number of pages described in a single descriptor page: currently each page
-description takes less than 1 byte; a descriptor page is repeated every
-this many file pages */
-/* #define XDES_DESCRIBED_PER_PAGE UNIV_PAGE_SIZE */
-/* This has been replaced with either UNIV_PAGE_SIZE or page_zip->size. */
-
-/* The space low address page map */
-/*--------------------------------------*/
- /* The following two pages are repeated
- every XDES_DESCRIBED_PER_PAGE pages in
- every tablespace. */
-#define FSP_XDES_OFFSET 0 /* extent descriptor */
-#define FSP_IBUF_BITMAP_OFFSET 1 /* insert buffer bitmap */
- /* The ibuf bitmap pages are the ones whose
- page number is the number above plus a
- multiple of XDES_DESCRIBED_PER_PAGE */
-
-#define FSP_FIRST_INODE_PAGE_NO 2 /* in every tablespace */
- /* The following pages exist
- in the system tablespace (space 0). */
-#define FSP_IBUF_HEADER_PAGE_NO 3 /* in tablespace 0 */
-#define FSP_IBUF_TREE_ROOT_PAGE_NO 4 /* in tablespace 0 */
- /* The ibuf tree root page number in
- tablespace 0; its fseg inode is on the page
- number FSP_FIRST_INODE_PAGE_NO */
-#define FSP_TRX_SYS_PAGE_NO 5 /* in tablespace 0 */
-#define FSP_FIRST_RSEG_PAGE_NO 6 /* in tablespace 0 */
-#define FSP_DICT_HDR_PAGE_NO 7 /* in tablespace 0 */
-/*--------------------------------------*/
-
#ifndef UNIV_NONINL
#include "fsp0fsp.ic"
#endif
diff --git a/storage/xtradb/include/fsp0fsp.ic b/storage/xtradb/include/fsp0fsp.ic
index f0301cc5e18..434c370b527 100644
--- a/storage/xtradb/include/fsp0fsp.ic
+++ b/storage/xtradb/include/fsp0fsp.ic
@@ -16,22 +16,23 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/fsp0fsp.ic
File space management
Created 12/18/1995 Heikki Tuuri
*******************************************************/
-/***************************************************************************
-Checks if a page address is an extent descriptor page address. */
+/***********************************************************************//**
+Checks if a page address is an extent descriptor page address.
+@return TRUE if a descriptor page */
UNIV_INLINE
ibool
fsp_descr_page(
/*===========*/
- /* out: TRUE if a descriptor page */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint page_no)/* in: page number */
+ ulint page_no)/*!< in: page number */
{
ut_ad(ut_is_2pow(zip_size));
diff --git a/storage/xtradb/include/fsp0types.h b/storage/xtradb/include/fsp0types.h
new file mode 100644
index 00000000000..496081c2346
--- /dev/null
+++ b/storage/xtradb/include/fsp0types.h
@@ -0,0 +1,110 @@
+/*****************************************************************************
+
+Copyright (c) 1995, 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
+
+*****************************************************************************/
+
+/******************************************************
+@file include/fsp0types.h
+File space management types
+
+Created May 26, 2009 Vasil Dimov
+*******************************************************/
+
+#ifndef fsp0types_h
+#define fsp0types_h
+
+#include "univ.i"
+
+#include "fil0fil.h" /* for FIL_PAGE_DATA */
+
+/** @name Flags for inserting records in order
+If records are inserted in order, there are the following
+flags to tell this (their type is made byte for the compiler
+to warn if direction and hint parameters are switched in
+fseg_alloc_free_page) */
+/* @{ */
+#define FSP_UP ((byte)111) /*!< alphabetically upwards */
+#define FSP_DOWN ((byte)112) /*!< alphabetically downwards */
+#define FSP_NO_DIR ((byte)113) /*!< no order */
+/* @} */
+
+/** File space extent size (one megabyte) in pages */
+#define FSP_EXTENT_SIZE (1 << (20 - UNIV_PAGE_SIZE_SHIFT))
+
+/** On a page of any file segment, data may be put starting from this
+offset */
+#define FSEG_PAGE_DATA FIL_PAGE_DATA
+
+/** @name File segment header
+The file segment header points to the inode describing the file segment. */
+/* @{ */
+/** Data type for file segment header */
+typedef byte fseg_header_t;
+
+#define FSEG_HDR_SPACE 0 /*!< space id of the inode */
+#define FSEG_HDR_PAGE_NO 4 /*!< page number of the inode */
+#define FSEG_HDR_OFFSET 8 /*!< byte offset of the inode */
+
+#define FSEG_HEADER_SIZE 10 /*!< Length of the file system
+ header, in bytes */
+/* @} */
+
+/** Flags for fsp_reserve_free_extents @{ */
+#define FSP_NORMAL 1000000
+#define FSP_UNDO 2000000
+#define FSP_CLEANING 3000000
+/* @} */
+
+/* Number of pages described in a single descriptor page: currently each page
+description takes less than 1 byte; a descriptor page is repeated every
+this many file pages */
+/* #define XDES_DESCRIBED_PER_PAGE UNIV_PAGE_SIZE */
+/* This has been replaced with either UNIV_PAGE_SIZE or page_zip->size. */
+
+/** @name The space low address page map
+The pages at FSP_XDES_OFFSET and FSP_IBUF_BITMAP_OFFSET are repeated
+every XDES_DESCRIBED_PER_PAGE pages in every tablespace. */
+/* @{ */
+/*--------------------------------------*/
+#define FSP_XDES_OFFSET 0 /* !< extent descriptor */
+#define FSP_IBUF_BITMAP_OFFSET 1 /* !< insert buffer bitmap */
+ /* The ibuf bitmap pages are the ones whose
+ page number is the number above plus a
+ multiple of XDES_DESCRIBED_PER_PAGE */
+
+#define FSP_FIRST_INODE_PAGE_NO 2 /*!< in every tablespace */
+ /* The following pages exist
+ in the system tablespace (space 0). */
+#define FSP_IBUF_HEADER_PAGE_NO 3 /*!< insert buffer
+ header page, in
+ tablespace 0 */
+#define FSP_IBUF_TREE_ROOT_PAGE_NO 4 /*!< insert buffer
+ B-tree root page in
+ tablespace 0 */
+ /* The ibuf tree root page number in
+ tablespace 0; its fseg inode is on the page
+ number FSP_FIRST_INODE_PAGE_NO */
+#define FSP_TRX_SYS_PAGE_NO 5 /*!< transaction
+ system header, in
+ tablespace 0 */
+#define FSP_FIRST_RSEG_PAGE_NO 6 /*!< first rollback segment
+ page, in tablespace 0 */
+#define FSP_DICT_HDR_PAGE_NO 7 /*!< data dictionary header
+ page, in tablespace 0 */
+/*--------------------------------------*/
+/* @} */
+
+#endif /* fsp0types_h */
diff --git a/storage/xtradb/include/fut0fut.h b/storage/xtradb/include/fut0fut.h
index 4de0c97294c..dce20b3bad6 100644
--- a/storage/xtradb/include/fut0fut.h
+++ b/storage/xtradb/include/fut0fut.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/fut0fut.h
File-based utilities
Created 12/13/1995 Heikki Tuuri
@@ -31,20 +32,20 @@ Created 12/13/1995 Heikki Tuuri
#include "fil0fil.h"
#include "mtr0mtr.h"
-/************************************************************************
-Gets a pointer to a file address and latches the page. */
+/********************************************************************//**
+Gets a pointer to a file address and latches the page.
+@return pointer to a byte in a frame; the file page in the frame is
+bufferfixed and latched */
UNIV_INLINE
byte*
fut_get_ptr(
/*========*/
- /* out: pointer to a byte in a frame; the file
- page in the frame is bufferfixed and latched */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- fil_addr_t addr, /* in: file address */
- ulint rw_latch, /* in: RW_S_LATCH, RW_X_LATCH */
- mtr_t* mtr); /* in: mtr handle */
+ fil_addr_t addr, /*!< in: file address */
+ ulint rw_latch, /*!< in: RW_S_LATCH, RW_X_LATCH */
+ mtr_t* mtr); /*!< in: mtr handle */
#ifndef UNIV_NONINL
#include "fut0fut.ic"
diff --git a/storage/xtradb/include/fut0fut.ic b/storage/xtradb/include/fut0fut.ic
index f7e820da008..0b52719a055 100644
--- a/storage/xtradb/include/fut0fut.ic
+++ b/storage/xtradb/include/fut0fut.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/fut0fut.ic
File-based utilities
Created 12/13/1995 Heikki Tuuri
@@ -25,20 +26,20 @@ Created 12/13/1995 Heikki Tuuri
#include "sync0rw.h"
#include "buf0buf.h"
-/************************************************************************
-Gets a pointer to a file address and latches the page. */
+/********************************************************************//**
+Gets a pointer to a file address and latches the page.
+@return pointer to a byte in a frame; the file page in the frame is
+bufferfixed and latched */
UNIV_INLINE
byte*
fut_get_ptr(
/*========*/
- /* out: pointer to a byte in a frame; the file
- page in the frame is bufferfixed and latched */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- fil_addr_t addr, /* in: file address */
- ulint rw_latch, /* in: RW_S_LATCH, RW_X_LATCH */
- mtr_t* mtr) /* in: mtr handle */
+ fil_addr_t addr, /*!< in: file address */
+ ulint rw_latch, /*!< in: RW_S_LATCH, RW_X_LATCH */
+ mtr_t* mtr) /*!< in: mtr handle */
{
buf_block_t* block;
byte* ptr;
diff --git a/storage/xtradb/include/fut0lst.h b/storage/xtradb/include/fut0lst.h
index f812874fe00..fe024c2498f 100644
--- a/storage/xtradb/include/fut0lst.h
+++ b/storage/xtradb/include/fut0lst.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/fut0lst.h
File-based list utilities
Created 11/28/1995 Heikki Tuuri
@@ -44,63 +45,63 @@ typedef byte flst_node_t;
/* The physical size of a list node in bytes */
#define FLST_NODE_SIZE (2 * FIL_ADDR_SIZE)
-
-/************************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Initializes a list base node. */
UNIV_INLINE
void
flst_init(
/*======*/
- flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Adds a node as the last node in a list. */
UNIV_INTERN
void
flst_add_last(
/*==========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node, /* in: node to add */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node, /*!< in: node to add */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Adds a node as the first node in a list. */
UNIV_INTERN
void
flst_add_first(
/*===========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node, /* in: node to add */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node, /*!< in: node to add */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Inserts a node after another in a list. */
UNIV_INTERN
void
flst_insert_after(
/*==============*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node1, /* in: node to insert after */
- flst_node_t* node2, /* in: node to add */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node1, /*!< in: node to insert after */
+ flst_node_t* node2, /*!< in: node to add */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Inserts a node before another in a list. */
UNIV_INTERN
void
flst_insert_before(
/*===============*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: node to insert */
- flst_node_t* node3, /* in: node to insert before */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: node to insert */
+ flst_node_t* node3, /*!< in: node to insert before */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Removes a node. */
UNIV_INTERN
void
flst_remove(
/*========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: node to remove */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: node to remove */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Cuts off the tail of the list, including the node given. The number of
nodes which will be removed must be provided by the caller, as this function
does not measure the length of the tail. */
@@ -108,12 +109,12 @@ UNIV_INTERN
void
flst_cut_end(
/*=========*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: first node to remove */
- ulint n_nodes,/* in: number of nodes to remove,
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: first node to remove */
+ ulint n_nodes,/*!< in: number of nodes to remove,
must be >= 1 */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Cuts off the tail of the list, not including the given node. The number of
nodes which will be removed must be provided by the caller, as this function
does not measure the length of the tail. */
@@ -121,94 +122,96 @@ UNIV_INTERN
void
flst_truncate_end(
/*==============*/
- flst_base_node_t* base, /* in: pointer to base node of list */
- flst_node_t* node2, /* in: first node not to remove */
- ulint n_nodes,/* in: number of nodes to remove */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
-Gets list length. */
+ flst_base_node_t* base, /*!< in: pointer to base node of list */
+ flst_node_t* node2, /*!< in: first node not to remove */
+ ulint n_nodes,/*!< in: number of nodes to remove */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
+Gets list length.
+@return length */
UNIV_INLINE
ulint
flst_get_len(
/*=========*/
- /* out: length */
- const flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
-Gets list first node address. */
+ const flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
+Gets list first node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_first(
/*===========*/
- /* out: file address */
- const flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
-Gets list last node address. */
+ const flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
+Gets list last node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_last(
/*==========*/
- /* out: file address */
- const flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
-Gets list next node address. */
+ const flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
+Gets list next node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_next_addr(
/*===============*/
- /* out: file address */
- const flst_node_t* node, /* in: pointer to node */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
-Gets list prev node address. */
+ const flst_node_t* node, /*!< in: pointer to node */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
+Gets list prev node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_prev_addr(
/*===============*/
- /* out: file address */
- const flst_node_t* node, /* in: pointer to node */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
+ const flst_node_t* node, /*!< in: pointer to node */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
Writes a file address. */
UNIV_INLINE
void
flst_write_addr(
/*============*/
- fil_faddr_t* faddr, /* in: pointer to file faddress */
- fil_addr_t addr, /* in: file address */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
-Reads a file address. */
+ fil_faddr_t* faddr, /*!< in: pointer to file faddress */
+ fil_addr_t addr, /*!< in: file address */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
+Reads a file address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_read_addr(
/*===========*/
- /* out: file address */
- const fil_faddr_t* faddr, /* in: pointer to file faddress */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************************
-Validates a file-based list. */
+ const fil_faddr_t* faddr, /*!< in: pointer to file faddress */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************************//**
+Validates a file-based list.
+@return TRUE if ok */
UNIV_INTERN
ibool
flst_validate(
/*==========*/
- /* out: TRUE if ok */
- const flst_base_node_t* base, /* in: pointer to base node of list */
- mtr_t* mtr1); /* in: mtr */
-/************************************************************************
+ const flst_base_node_t* base, /*!< in: pointer to base node of list */
+ mtr_t* mtr1); /*!< in: mtr */
+/********************************************************************//**
Prints info of a file-based list. */
UNIV_INTERN
void
flst_print(
/*=======*/
- const flst_base_node_t* base, /* in: pointer to base node of list */
- mtr_t* mtr); /* in: mtr */
+ const flst_base_node_t* base, /*!< in: pointer to base node of list */
+ mtr_t* mtr); /*!< in: mtr */
#ifndef UNIV_NONINL
#include "fut0lst.ic"
#endif
+#endif /* !UNIV_HOTBACKUP */
+
#endif
diff --git a/storage/xtradb/include/fut0lst.ic b/storage/xtradb/include/fut0lst.ic
index 5899e996059..dcd13c61871 100644
--- a/storage/xtradb/include/fut0lst.ic
+++ b/storage/xtradb/include/fut0lst.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/fut0lst.ic
File-based list utilities
Created 11/28/1995 Heikki Tuuri
@@ -42,15 +43,15 @@ Created 11/28/1995 Heikki Tuuri
last element of the list; undefined
if empty list */
-/************************************************************************
+/********************************************************************//**
Writes a file address. */
UNIV_INLINE
void
flst_write_addr(
/*============*/
- fil_faddr_t* faddr, /* in: pointer to file faddress */
- fil_addr_t addr, /* in: file address */
- mtr_t* mtr) /* in: mini-transaction handle */
+ fil_faddr_t* faddr, /*!< in: pointer to file faddress */
+ fil_addr_t addr, /*!< in: file address */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ut_ad(faddr && mtr);
ut_ad(mtr_memo_contains_page(mtr, faddr, MTR_MEMO_PAGE_X_FIX));
@@ -62,15 +63,15 @@ flst_write_addr(
MLOG_2BYTES, mtr);
}
-/************************************************************************
-Reads a file address. */
+/********************************************************************//**
+Reads a file address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_read_addr(
/*===========*/
- /* out: file address */
- const fil_faddr_t* faddr, /* in: pointer to file faddress */
- mtr_t* mtr) /* in: mini-transaction handle */
+ const fil_faddr_t* faddr, /*!< in: pointer to file faddress */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
fil_addr_t addr;
@@ -84,14 +85,14 @@ flst_read_addr(
return(addr);
}
-/************************************************************************
+/********************************************************************//**
Initializes a list base node. */
UNIV_INLINE
void
flst_init(
/*======*/
- flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr) /* in: mini-transaction handle */
+ flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ut_ad(mtr_memo_contains_page(mtr, base, MTR_MEMO_PAGE_X_FIX));
@@ -100,67 +101,67 @@ flst_init(
flst_write_addr(base + FLST_LAST, fil_addr_null, mtr);
}
-/************************************************************************
-Gets list length. */
+/********************************************************************//**
+Gets list length.
+@return length */
UNIV_INLINE
ulint
flst_get_len(
/*=========*/
- /* out: length */
- const flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr) /* in: mini-transaction handle */
+ const flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
return(mtr_read_ulint(base + FLST_LEN, MLOG_4BYTES, mtr));
}
-/************************************************************************
-Gets list first node address. */
+/********************************************************************//**
+Gets list first node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_first(
/*===========*/
- /* out: file address */
- const flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr) /* in: mini-transaction handle */
+ const flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
return(flst_read_addr(base + FLST_FIRST, mtr));
}
-/************************************************************************
-Gets list last node address. */
+/********************************************************************//**
+Gets list last node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_last(
/*==========*/
- /* out: file address */
- const flst_base_node_t* base, /* in: pointer to base node */
- mtr_t* mtr) /* in: mini-transaction handle */
+ const flst_base_node_t* base, /*!< in: pointer to base node */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
return(flst_read_addr(base + FLST_LAST, mtr));
}
-/************************************************************************
-Gets list next node address. */
+/********************************************************************//**
+Gets list next node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_next_addr(
/*===============*/
- /* out: file address */
- const flst_node_t* node, /* in: pointer to node */
- mtr_t* mtr) /* in: mini-transaction handle */
+ const flst_node_t* node, /*!< in: pointer to node */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
return(flst_read_addr(node + FLST_NEXT, mtr));
}
-/************************************************************************
-Gets list prev node address. */
+/********************************************************************//**
+Gets list prev node address.
+@return file address */
UNIV_INLINE
fil_addr_t
flst_get_prev_addr(
/*===============*/
- /* out: file address */
- const flst_node_t* node, /* in: pointer to node */
- mtr_t* mtr) /* in: mini-transaction handle */
+ const flst_node_t* node, /*!< in: pointer to node */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
return(flst_read_addr(node + FLST_PREV, mtr));
}
diff --git a/storage/xtradb/include/ha0ha.h b/storage/xtradb/include/ha0ha.h
index 768f3d7aca3..1ffbd3440aa 100644
--- a/storage/xtradb/include/ha0ha.h
+++ b/storage/xtradb/include/ha0ha.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/ha0ha.h
The hash table with external chains
Created 8/18/1994 Heikki Tuuri
@@ -31,156 +32,208 @@ Created 8/18/1994 Heikki Tuuri
#include "page0types.h"
#include "buf0types.h"
-/*****************************************************************
-Looks for an element in a hash table. */
+/*************************************************************//**
+Looks for an element in a hash table.
+@return pointer to the data of the first hash table node in chain
+having the fold number, NULL if not found */
UNIV_INLINE
void*
ha_search_and_get_data(
/*===================*/
- /* out: pointer to the data of the first hash
- table node in chain having the fold number,
- NULL if not found */
- hash_table_t* table, /* in: hash table */
- ulint fold); /* in: folded value of the searched data */
-/*************************************************************
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: folded value of the searched data */
+/*********************************************************//**
Looks for an element when we know the pointer to the data and updates
the pointer to data if found. */
UNIV_INTERN
void
ha_search_and_update_if_found_func(
/*===============================*/
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of the searched data */
- void* data, /* in: pointer to the data */
+ hash_table_t* table, /*!< in/out: hash table */
+ ulint fold, /*!< in: folded value of the searched data */
+ void* data, /*!< in: pointer to the data */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- buf_block_t* new_block,/* in: block containing new_data */
+ buf_block_t* new_block,/*!< in: block containing new_data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- void* new_data);/* in: new pointer to the data */
+ void* new_data);/*!< in: new pointer to the data */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+/** Looks for an element when we know the pointer to the data and
+updates the pointer to data if found.
+@param table in/out: hash table
+@param fold in: folded value of the searched data
+@param data in: pointer to the data
+@param new_block in: block containing new_data
+@param new_data in: new pointer to the data */
# define ha_search_and_update_if_found(table,fold,data,new_block,new_data) \
ha_search_and_update_if_found_func(table,fold,data,new_block,new_data)
#else /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+/** Looks for an element when we know the pointer to the data and
+updates the pointer to data if found.
+@param table in/out: hash table
+@param fold in: folded value of the searched data
+@param data in: pointer to the data
+@param new_block ignored: block containing new_data
+@param new_data in: new pointer to the data */
# define ha_search_and_update_if_found(table,fold,data,new_block,new_data) \
ha_search_and_update_if_found_func(table,fold,data,new_data)
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-/*****************************************************************
-Creates a hash table with >= n array cells. The actual number of cells is
-chosen to be a prime number slightly bigger than n. */
+/*************************************************************//**
+Creates a hash table with at least n array cells. The actual number
+of cells is chosen to be a prime number slightly bigger than n.
+@return own: created table */
UNIV_INTERN
hash_table_t*
ha_create_func(
/*===========*/
- /* out, own: created table */
- ulint n, /* in: number of array cells */
+ ulint n, /*!< in: number of array cells */
#ifdef UNIV_SYNC_DEBUG
- ulint mutex_level, /* in: level of the mutexes in the latching
+ ulint mutex_level, /*!< in: level of the mutexes in the latching
order: this is used in the debug version */
#endif /* UNIV_SYNC_DEBUG */
- ulint n_mutexes); /* in: number of mutexes to protect the
- hash table: must be a power of 2 */
+ ulint n_mutexes); /*!< in: number of mutexes to protect the
+ hash table: must be a power of 2, or 0 */
#ifdef UNIV_SYNC_DEBUG
+/** Creates a hash table.
+@return own: created table
+@param n_c in: number of array cells. The actual number of cells is
+chosen to be a slightly bigger prime number.
+@param level in: level of the mutexes in the latching order
+@param n_m in: number of mutexes to protect the hash table;
+ must be a power of 2, or 0 */
# define ha_create(n_c,n_m,level) ha_create_func(n_c,level,n_m)
#else /* UNIV_SYNC_DEBUG */
+/** Creates a hash table.
+@return own: created table
+@param n_c in: number of array cells. The actual number of cells is
+chosen to be a slightly bigger prime number.
+@param level in: level of the mutexes in the latching order
+@param n_m in: number of mutexes to protect the hash table;
+ must be a power of 2, or 0 */
# define ha_create(n_c,n_m,level) ha_create_func(n_c,n_m)
#endif /* UNIV_SYNC_DEBUG */
-/*****************************************************************
+/*************************************************************//**
Empties a hash table and frees the memory heaps. */
UNIV_INTERN
void
ha_clear(
/*=====*/
- hash_table_t* table); /* in, own: hash table */
+ hash_table_t* table); /*!< in, own: hash table */
-/*****************************************************************
+/*************************************************************//**
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.
+@return TRUE if succeed, FALSE if no more memory could be allocated */
UNIV_INTERN
ibool
ha_insert_for_fold_func(
/*====================*/
- /* out: TRUE if succeed, FALSE if no more
- memory could be allocated */
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of data; if a node with
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold, /*!< in: folded value of data; if a node with
the same fold value already exists, it is
updated to point to the same data, and no new
node is created! */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- buf_block_t* block, /* in: buffer block containing the data */
+ buf_block_t* block, /*!< in: buffer block containing the data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- void* data); /* in: data, must not be NULL */
+ void* data); /*!< in: data, must not be NULL */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+/**
+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.
+@return TRUE if succeed, FALSE if no more memory could be allocated
+@param t in: hash table
+@param f in: folded value of data
+@param b in: buffer block containing the data
+@param d in: data, must not be NULL */
# define ha_insert_for_fold(t,f,b,d) ha_insert_for_fold_func(t,f,b,d)
#else /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+/**
+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.
+@return TRUE if succeed, FALSE if no more memory could be allocated
+@param t in: hash table
+@param f in: folded value of data
+@param b ignored: buffer block containing the data
+@param d in: data, must not be NULL */
# define ha_insert_for_fold(t,f,b,d) ha_insert_for_fold_func(t,f,d)
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-/*****************************************************************
-Deletes an entry from a hash table. */
-UNIV_INTERN
-void
-ha_delete(
-/*======*/
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of data */
- void* data); /* in: data, must not be NULL and must exist
- in the hash table */
-/*************************************************************
+/*********************************************************//**
Looks for an element when we know the pointer to the data and deletes
-it from the hash table if found. */
+it from the hash table if found.
+@return TRUE if found */
UNIV_INLINE
ibool
ha_search_and_delete_if_found(
/*==========================*/
- /* out: TRUE if found */
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of the searched data */
- void* data); /* in: pointer to the data */
-/*********************************************************************
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold, /*!< in: folded value of the searched data */
+ void* data); /*!< in: pointer to the data */
+#ifndef UNIV_HOTBACKUP
+/*****************************************************************//**
Removes from the chain determined by fold all nodes whose data pointer
points to the page given. */
UNIV_INTERN
void
ha_remove_all_nodes_to_page(
/*========================*/
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: fold value */
- const page_t* page); /* in: buffer page */
-/*****************************************************************
-Validates a given range of the cells in hash table. */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold, /*!< in: fold value */
+ const page_t* page); /*!< in: buffer page */
+/*************************************************************//**
+Validates a given range of the cells in hash table.
+@return TRUE if ok */
UNIV_INTERN
ibool
ha_validate(
/*========*/
- /* out: TRUE if ok */
- hash_table_t* table, /* in: hash table */
- ulint start_index, /* in: start index */
- ulint end_index); /* in: end index */
-/*****************************************************************
+ hash_table_t* table, /*!< in: hash table */
+ ulint start_index, /*!< in: start index */
+ ulint end_index); /*!< in: end index */
+/*************************************************************//**
Prints info of a hash table. */
UNIV_INTERN
void
ha_print_info(
/*==========*/
- FILE* file, /* in: file where to print */
- hash_table_t* table); /* in: hash table */
-
-/* The hash table external chain node */
+ FILE* file, /*!< in: file where to print */
+ hash_table_t* table); /*!< in: hash table */
+#endif /* !UNIV_HOTBACKUP */
+/** The hash table external chain node */
typedef struct ha_node_struct ha_node_t;
+
+/** The hash table external chain node */
struct ha_node_struct {
- ha_node_t* next; /* next chain node or NULL if none */
+ ha_node_t* next; /*!< next chain node or NULL if none */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- buf_block_t* block; /* buffer block containing the data, or NULL */
+ buf_block_t* block; /*!< buffer block containing the data, or NULL */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- void* data; /* pointer to the data */
- ulint fold; /* fold value for the data */
+ void* data; /*!< pointer to the data */
+ ulint fold; /*!< fold value for the data */
};
+#ifndef UNIV_HOTBACKUP
+/** Assert that the current thread is holding the mutex protecting a
+hash bucket corresponding to a fold value.
+@param table in: hash table
+@param fold in: fold value */
+# define ASSERT_HASH_MUTEX_OWN(table, fold) \
+ ut_ad(!(table)->mutexes || mutex_own(hash_get_mutex(table, fold)))
+#else /* !UNIV_HOTBACKUP */
+/** Assert that the current thread is holding the mutex protecting a
+hash bucket corresponding to a fold value.
+@param table in: hash table
+@param fold in: fold value */
+# define ASSERT_HASH_MUTEX_OWN(table, fold) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
+
#ifndef UNIV_NONINL
#include "ha0ha.ic"
#endif
diff --git a/storage/xtradb/include/ha0ha.ic b/storage/xtradb/include/ha0ha.ic
index 35fd802eaef..734403c4cd9 100644
--- a/storage/xtradb/include/ha0ha.ic
+++ b/storage/xtradb/include/ha0ha.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/ha0ha.ic
The hash table with external chains
Created 8/18/1994 Heikki Tuuri
@@ -25,38 +26,38 @@ Created 8/18/1994 Heikki Tuuri
#include "ut0rnd.h"
#include "mem0mem.h"
-/***************************************************************
+/***********************************************************//**
Deletes a hash node. */
UNIV_INTERN
void
ha_delete_hash_node(
/*================*/
- hash_table_t* table, /* in: hash table */
- ha_node_t* del_node); /* in: node to be deleted */
+ hash_table_t* table, /*!< in: hash table */
+ ha_node_t* del_node); /*!< in: node to be deleted */
-/**********************************************************************
-Gets a hash node data. */
+/******************************************************************//**
+Gets a hash node data.
+@return pointer to the data */
UNIV_INLINE
void*
ha_node_get_data(
/*=============*/
- /* out: pointer to the data */
- ha_node_t* node) /* in: hash chain node */
+ ha_node_t* node) /*!< in: hash chain node */
{
return(node->data);
}
-/**********************************************************************
+/******************************************************************//**
Sets hash node data. */
UNIV_INLINE
void
ha_node_set_data_func(
/*==================*/
- ha_node_t* node, /* in: hash chain node */
+ ha_node_t* node, /*!< in: hash chain node */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
- buf_block_t* block, /* in: buffer block containing the data */
+ buf_block_t* block, /*!< in: buffer block containing the data */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- void* data) /* in: pointer to the data */
+ void* data) /*!< in: pointer to the data */
{
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
node->block = block;
@@ -65,52 +66,59 @@ ha_node_set_data_func(
}
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+/** Sets hash node data.
+@param n in: hash chain node
+@param b in: buffer block containing the data
+@param d in: pointer to the data */
# define ha_node_set_data(n,b,d) ha_node_set_data_func(n,b,d)
#else /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+/** Sets hash node data.
+@param n in: hash chain node
+@param b in: buffer block containing the data
+@param d in: pointer to the data */
# define ha_node_set_data(n,b,d) ha_node_set_data_func(n,d)
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-/**********************************************************************
-Gets the next node in a hash chain. */
+/******************************************************************//**
+Gets the next node in a hash chain.
+@return next node, NULL if none */
UNIV_INLINE
ha_node_t*
ha_chain_get_next(
/*==============*/
- /* out: next node, NULL if none */
- ha_node_t* node) /* in: hash chain node */
+ ha_node_t* node) /*!< in: hash chain node */
{
return(node->next);
}
-/**********************************************************************
-Gets the first node in a hash chain. */
+/******************************************************************//**
+Gets the first node in a hash chain.
+@return first node, NULL if none */
UNIV_INLINE
ha_node_t*
ha_chain_get_first(
/*===============*/
- /* out: first node, NULL if none */
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: fold value determining the chain */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: fold value determining the chain */
{
return((ha_node_t*)
hash_get_nth_cell(table, hash_calc_hash(fold, table))->node);
}
-/*****************************************************************
-Looks for an element in a hash table. */
+/*************************************************************//**
+Looks for an element in a hash table.
+@return pointer to the first hash table node in chain having the fold
+number, NULL if not found */
UNIV_INLINE
ha_node_t*
ha_search(
/*======*/
- /* out: pointer to the first hash table node
- in chain having the fold number, NULL if not
- found */
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: folded value of the searched data */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: folded value of the searched data */
{
ha_node_t* node;
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
+ ASSERT_HASH_MUTEX_OWN(table, fold);
node = ha_chain_get_first(table, fold);
@@ -126,21 +134,20 @@ ha_search(
return(NULL);
}
-/*****************************************************************
-Looks for an element in a hash table. */
+/*************************************************************//**
+Looks for an element in a hash table.
+@return pointer to the data of the first hash table node in chain
+having the fold number, NULL if not found */
UNIV_INLINE
void*
ha_search_and_get_data(
/*===================*/
- /* out: pointer to the data of the first hash
- table node in chain having the fold number,
- NULL if not found */
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: folded value of the searched data */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: folded value of the searched data */
{
ha_node_t* node;
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
+ ASSERT_HASH_MUTEX_OWN(table, fold);
node = ha_chain_get_first(table, fold);
@@ -156,21 +163,20 @@ ha_search_and_get_data(
return(NULL);
}
-/*************************************************************
-Looks for an element when we know the pointer to the data. */
+/*********************************************************//**
+Looks for an element when we know the pointer to the data.
+@return pointer to the hash table node, NULL if not found in the table */
UNIV_INLINE
ha_node_t*
ha_search_with_data(
/*================*/
- /* out: pointer to the hash table node, NULL
- if not found in the table */
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of the searched data */
- void* data) /* in: pointer to the data */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold, /*!< in: folded value of the searched data */
+ void* data) /*!< in: pointer to the data */
{
ha_node_t* node;
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
+ ASSERT_HASH_MUTEX_OWN(table, fold);
node = ha_chain_get_first(table, fold);
@@ -186,21 +192,21 @@ ha_search_with_data(
return(NULL);
}
-/*************************************************************
+/*********************************************************//**
Looks for an element when we know the pointer to the data, and deletes
-it from the hash table, if found. */
+it from the hash table, if found.
+@return TRUE if found */
UNIV_INLINE
ibool
ha_search_and_delete_if_found(
/*==========================*/
- /* out: TRUE if found */
- hash_table_t* table, /* in: hash table */
- ulint fold, /* in: folded value of the searched data */
- void* data) /* in: pointer to the data */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold, /*!< in: folded value of the searched data */
+ void* data) /*!< in: pointer to the data */
{
ha_node_t* node;
- ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
+ ASSERT_HASH_MUTEX_OWN(table, fold);
node = ha_search_with_data(table, fold, data);
diff --git a/storage/xtradb/include/ha0storage.h b/storage/xtradb/include/ha0storage.h
index f5a3938f434..c30bd840579 100644
--- a/storage/xtradb/include/ha0storage.h
+++ b/storage/xtradb/include/ha0storage.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/ha0storage.h
Hash storage.
Provides a data structure that stores chunks of data in
its own storage, avoiding duplicates.
@@ -29,29 +30,30 @@ Created September 22, 2007 Vasil Dimov
#include "univ.i"
-/* This value is used by default by ha_storage_create(). More memory
+/** This value is used by default by ha_storage_create(). More memory
is allocated later when/if it is needed. */
#define HA_STORAGE_DEFAULT_HEAP_BYTES 1024
-/* This value is used by default by ha_storage_create(). It is a
+/** This value is used by default by ha_storage_create(). It is a
constant per ha_storage's lifetime. */
#define HA_STORAGE_DEFAULT_HASH_CELLS 4096
+/** Hash storage */
typedef struct ha_storage_struct ha_storage_t;
-/***********************************************************************
+/*******************************************************************//**
Creates a hash storage. If any of the parameters is 0, then a default
-value is used. */
+value is used.
+@return own: hash storage */
UNIV_INLINE
ha_storage_t*
ha_storage_create(
/*==============*/
- /* out, own: hash storage */
- ulint initial_heap_bytes, /* in: initial heap's size */
- ulint initial_hash_cells); /* in: initial number of cells
+ ulint initial_heap_bytes, /*!< in: initial heap's size */
+ ulint initial_hash_cells); /*!< in: initial number of cells
in the hash table */
-/***********************************************************************
+/*******************************************************************//**
Copies data into the storage and returns a pointer to the copy. If the
same data chunk is already present, then pointer to it is returned.
Data chunks are considered to be equal if len1 == len2 and
@@ -59,40 +61,50 @@ memcmp(data1, data2, len1) == 0. If "data" is not present (and thus
data_len bytes need to be allocated) and the size of storage is going to
become more than "memlim" then "data" is not added and NULL is returned.
To disable this behavior "memlim" can be set to 0, which stands for
-"no limit". */
-
+"no limit".
+@return pointer to the copy */
+UNIV_INTERN
const void*
ha_storage_put_memlim(
/*==================*/
- /* out: pointer to the copy */
- ha_storage_t* storage, /* in/out: hash storage */
- const void* data, /* in: data to store */
- ulint data_len, /* in: data length */
- ulint memlim); /* in: memory limit to obey */
-
-/***********************************************************************
-Same as ha_storage_put_memlim() but without memory limit. */
-
+ ha_storage_t* storage, /*!< in/out: hash storage */
+ const void* data, /*!< in: data to store */
+ ulint data_len, /*!< in: data length */
+ ulint memlim); /*!< in: memory limit to obey */
+
+/*******************************************************************//**
+Same as ha_storage_put_memlim() but without memory limit.
+@param storage in/out: hash storage
+@param data in: data to store
+@param data_len in: data length
+@return pointer to the copy of the string */
#define ha_storage_put(storage, data, data_len) \
ha_storage_put_memlim((storage), (data), (data_len), 0)
-/***********************************************************************
+/*******************************************************************//**
Copies string into the storage and returns a pointer to the copy. If the
same string is already present, then pointer to it is returned.
-Strings are considered to be equal if strcmp(str1, str2) == 0. */
-
+Strings are considered to be equal if strcmp(str1, str2) == 0.
+@param storage in/out: hash storage
+@param str in: string to put
+@return pointer to the copy of the string */
#define ha_storage_put_str(storage, str) \
((const char*) ha_storage_put((storage), (str), strlen(str) + 1))
-/***********************************************************************
+/*******************************************************************//**
Copies string into the storage and returns a pointer to the copy obeying
-a memory limit. */
-
+a memory limit.
+If the same string is already present, then pointer to it is returned.
+Strings are considered to be equal if strcmp(str1, str2) == 0.
+@param storage in/out: hash storage
+@param str in: string to put
+@param memlim in: memory limit to obey
+@return pointer to the copy of the string */
#define ha_storage_put_str_memlim(storage, str, memlim) \
((const char*) ha_storage_put_memlim((storage), (str), \
strlen(str) + 1, (memlim)))
-/***********************************************************************
+/*******************************************************************//**
Empties a hash storage, freeing memory occupied by data chunks.
This invalidates any pointers previously returned by ha_storage_put().
The hash storage is not invalidated itself and can be used again. */
@@ -100,27 +112,26 @@ UNIV_INLINE
void
ha_storage_empty(
/*=============*/
- ha_storage_t** storage); /* in/out: hash storage */
+ ha_storage_t** storage); /*!< in/out: hash storage */
-/***********************************************************************
+/*******************************************************************//**
Frees a hash storage and everything it contains, it cannot be used after
this call.
-This invalidates any pointers previously returned by ha_storage_put().
-*/
+This invalidates any pointers previously returned by ha_storage_put(). */
UNIV_INLINE
void
ha_storage_free(
/*============*/
- ha_storage_t* storage); /* in/out: hash storage */
+ ha_storage_t* storage); /*!< in, own: hash storage */
-/***********************************************************************
-Gets the size of the memory used by a storage. */
+/*******************************************************************//**
+Gets the size of the memory used by a storage.
+@return bytes used */
UNIV_INLINE
ulint
ha_storage_get_size(
/*================*/
- /* out: bytes used */
- const ha_storage_t* storage); /* in: hash storage */
+ const ha_storage_t* storage); /*!< in: hash storage */
#ifndef UNIV_NONINL
#include "ha0storage.ic"
diff --git a/storage/xtradb/include/ha0storage.ic b/storage/xtradb/include/ha0storage.ic
index 7ab43bc00ba..5acbf82f005 100644
--- a/storage/xtradb/include/ha0storage.ic
+++ b/storage/xtradb/include/ha0storage.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/ha0storage.ic
Hash storage.
Provides a data structure that stores chunks of data in
its own storage, avoiding duplicates.
@@ -29,31 +30,33 @@ Created September 24, 2007 Vasil Dimov
#include "hash0hash.h"
#include "mem0mem.h"
+/** Hash storage for strings */
struct ha_storage_struct {
- mem_heap_t* heap; /* storage from which memory is
+ mem_heap_t* heap; /*!< memory heap from which memory is
allocated */
- hash_table_t* hash; /* hash table used to avoid
+ hash_table_t* hash; /*!< hash table used to avoid
duplicates */
};
-/* Objects of this type are put in the hash */
+/** Objects of this type are stored in ha_storage_t */
typedef struct ha_storage_node_struct ha_storage_node_t;
+/** Objects of this type are stored in ha_storage_struct */
struct ha_storage_node_struct {
- ulint data_len;/* length of the data */
- const void* data; /* pointer to data */
- ha_storage_node_t* next; /* next node in hash chain */
+ ulint data_len;/*!< length of the data */
+ const void* data; /*!< pointer to data */
+ ha_storage_node_t* next; /*!< next node in hash chain */
};
-/***********************************************************************
+/*******************************************************************//**
Creates a hash storage. If any of the parameters is 0, then a default
-value is used. */
+value is used.
+@return own: hash storage */
UNIV_INLINE
ha_storage_t*
ha_storage_create(
/*==============*/
- /* out, own: hash storage */
- ulint initial_heap_bytes, /* in: initial heap's size */
- ulint initial_hash_cells) /* in: initial number of cells
+ ulint initial_heap_bytes, /*!< in: initial heap's size */
+ ulint initial_hash_cells) /*!< in: initial number of cells
in the hash table */
{
ha_storage_t* storage;
@@ -83,7 +86,7 @@ ha_storage_create(
return(storage);
}
-/***********************************************************************
+/*******************************************************************//**
Empties a hash storage, freeing memory occupied by data chunks.
This invalidates any pointers previously returned by ha_storage_put().
The hash storage is not invalidated itself and can be used again. */
@@ -91,7 +94,7 @@ UNIV_INLINE
void
ha_storage_empty(
/*=============*/
- ha_storage_t** storage) /* in/out: hash storage */
+ ha_storage_t** storage) /*!< in/out: hash storage */
{
ha_storage_t temp_storage;
@@ -108,16 +111,15 @@ ha_storage_empty(
(*storage)->hash = temp_storage.hash;
}
-/***********************************************************************
+/*******************************************************************//**
Frees a hash storage and everything it contains, it cannot be used after
this call.
-This invalidates any pointers previously returned by ha_storage_put().
-*/
+This invalidates any pointers previously returned by ha_storage_put(). */
UNIV_INLINE
void
ha_storage_free(
/*============*/
- ha_storage_t* storage) /* in/out: hash storage */
+ ha_storage_t* storage) /*!< in, own: hash storage */
{
/* order is important because the pointer storage->hash is
within the heap */
@@ -125,14 +127,14 @@ ha_storage_free(
mem_heap_free(storage->heap);
}
-/***********************************************************************
-Gets the size of the memory used by a storage. */
+/*******************************************************************//**
+Gets the size of the memory used by a storage.
+@return bytes used */
UNIV_INLINE
ulint
ha_storage_get_size(
/*================*/
- /* out: bytes used */
- const ha_storage_t* storage) /* in: hash storage */
+ const ha_storage_t* storage) /*!< in: hash storage */
{
ulint ret;
diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h
index 116242b32e4..e8789d1638b 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -16,126 +16,144 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/*******************************************************************//**
+@file include/ha_prototypes.h
+Prototypes for global functions in ha_innodb.cc that are called by
+InnoDB C code
+
+Created 5/11/2006 Osku Salerma
+************************************************************************/
+
#ifndef HA_INNODB_PROTOTYPES_H
#define HA_INNODB_PROTOTYPES_H
-#ifndef UNIV_HOTBACKUP
-
-#include "univ.i" /* ulint, uint */
+#include "trx0types.h"
#include "m_ctype.h" /* CHARSET_INFO */
-/* Prototypes for global functions in ha_innodb.cc that are called by
-InnoDB's C-code. */
-
-/*************************************************************************
-Wrapper around MySQL's copy_and_convert function, see it for
-documentation. */
+/*********************************************************************//**
+Wrapper around MySQL's copy_and_convert function.
+@return number of bytes copied to 'to' */
UNIV_INTERN
ulint
innobase_convert_string(
/*====================*/
- void* to,
- ulint to_length,
- CHARSET_INFO* to_cs,
- const void* from,
- ulint from_length,
- CHARSET_INFO* from_cs,
- uint* errors);
-
-/***********************************************************************
+ void* to, /*!< out: converted string */
+ ulint to_length, /*!< in: number of bytes reserved
+ for the converted string */
+ CHARSET_INFO* to_cs, /*!< in: character set to convert to */
+ const void* from, /*!< in: string to convert */
+ ulint from_length, /*!< in: number of bytes to convert */
+ CHARSET_INFO* from_cs, /*!< in: character set to convert from */
+ uint* errors); /*!< out: number of errors encountered
+ during the conversion */
+
+/*******************************************************************//**
Formats the raw data in "data" (in InnoDB on-disk format) that is of
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "charset_coll" and writes
the result to "buf". The result is converted to "system_charset_info".
Not more than "buf_size" bytes are written to "buf".
-The result is always '\0'-terminated (provided buf_size > 0) and the
+The result is always NUL-terminated (provided buf_size > 0) and the
number of bytes that were written to "buf" is returned (including the
-terminating '\0'). */
+terminating NUL).
+@return number of bytes that were written */
UNIV_INTERN
ulint
innobase_raw_format(
/*================*/
- /* out: number of bytes
- that were written */
- const char* data, /* in: raw data */
- ulint data_len, /* in: raw data length
+ const char* data, /*!< in: raw data */
+ ulint data_len, /*!< in: raw data length
in bytes */
- ulint charset_coll, /* in: charset collation */
- char* buf, /* out: output buffer */
- ulint buf_size); /* in: output buffer size
+ ulint charset_coll, /*!< in: charset collation */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size); /*!< in: output buffer size
in bytes */
-
-/*********************************************************************
+
+/*****************************************************************//**
+Invalidates the MySQL query cache for the table. */
+UNIV_INTERN
+void
+innobase_invalidate_query_cache(
+/*============================*/
+ trx_t* trx, /*!< in: transaction which
+ modifies the table */
+ const char* full_name, /*!< in: concatenation of
+ database name, null char NUL,
+ table name, null char NUL;
+ NOTE that in Windows this is
+ always in LOWER CASE! */
+ ulint full_name_len); /*!< in: full name length where
+ also the null chars count */
+
+/*****************************************************************//**
Convert a table or index name to the MySQL system_charset_info (UTF-8)
-and quote it if needed. */
+and quote it if needed.
+@return pointer to the end of buf */
UNIV_INTERN
char*
innobase_convert_name(
/*==================*/
- /* out: pointer to the end of buf */
- char* buf, /* out: buffer for converted identifier */
- ulint buflen, /* in: length of buf, in bytes */
- const char* id, /* in: identifier to convert */
- ulint idlen, /* in: length of id, in bytes */
- void* thd, /* in: MySQL connection thread, or NULL */
- ibool table_id);/* in: TRUE=id is a table or database name;
+ char* buf, /*!< out: buffer for converted identifier */
+ ulint buflen, /*!< in: length of buf, in bytes */
+ const char* id, /*!< in: identifier to convert */
+ ulint idlen, /*!< in: length of id, in bytes */
+ void* thd, /*!< in: MySQL connection thread, or NULL */
+ ibool table_id);/*!< in: TRUE=id is a table or database name;
FALSE=id is an index name */
-/**********************************************************************
+/******************************************************************//**
Returns true if the thread is the replication thread on the slave
server. Used in srv_conc_enter_innodb() to determine if the thread
should be allowed to enter InnoDB - the replication thread is treated
differently than other threads. Also used in
-srv_conc_force_exit_innodb(). */
+srv_conc_force_exit_innodb().
+@return true if thd is the replication thread */
UNIV_INTERN
ibool
thd_is_replication_slave_thread(
/*============================*/
- /* out: true if thd is the replication thread */
- void* thd); /* in: thread handle (THD*) */
+ void* thd); /*!< in: thread handle (THD*) */
-/**********************************************************************
+/******************************************************************//**
Returns true if the transaction this thread is processing has edited
non-transactional tables. Used by the deadlock detector when deciding
which transaction to rollback in case of a deadlock - we try to avoid
-rolling back transactions that have edited non-transactional tables. */
+rolling back transactions that have edited non-transactional tables.
+@return true if non-transactional tables have been edited */
UNIV_INTERN
ibool
thd_has_edited_nontrans_tables(
/*===========================*/
- /* out: true if non-transactional tables have
- been edited */
- void* thd); /* in: thread handle (THD*) */
+ void* thd); /*!< in: thread handle (THD*) */
-/*****************************************************************
+/*************************************************************//**
Prints info of a THD object (== user session thread) to the given file. */
UNIV_INTERN
void
innobase_mysql_print_thd(
/*=====================*/
- FILE* f, /* in: output stream */
- void* thd, /* in: pointer to a MySQL THD object */
- uint max_query_len); /* in: max query length to print, or 0 to
+ FILE* f, /*!< in: output stream */
+ void* thd, /*!< in: pointer to a MySQL THD object */
+ uint max_query_len); /*!< in: max query length to print, or 0 to
use the default max length */
-/******************************************************************
+/**************************************************************//**
Converts a MySQL type to an InnoDB type. Note that this function returns
the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1
-VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'. */
+VARCHAR and the new true VARCHAR in >= 5.0.3 by the 'prtype'.
+@return DATA_BINARY, DATA_VARCHAR, ... */
UNIV_INTERN
ulint
get_innobase_type_from_mysql_type(
/*==============================*/
- /* out: DATA_BINARY,
- DATA_VARCHAR, ... */
- ulint* unsigned_flag, /* out: DATA_UNSIGNED if an
+ ulint* unsigned_flag, /*!< out: DATA_UNSIGNED if an
'unsigned type';
at least ENUM and SET,
and unsigned integer
types are 'unsigned types' */
- const void* field) /* in: MySQL Field */
+ const void* field) /*!< in: MySQL Field */
__attribute__((nonnull));
-/*****************************************************************
+/*************************************************************//**
If you want to print a thd that is not associated with the current thread,
you must call this function before reserving the InnoDB kernel_mutex, to
protect MySQL from setting thd->query NULL. If you print a thd of the current
@@ -147,7 +165,7 @@ void
innobase_mysql_prepare_print_arbitrary_thd(void);
/*============================================*/
-/*****************************************************************
+/*************************************************************//**
Releases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
In the InnoDB latching order, the mutex sits right above the
kernel_mutex. In debug builds, we assert that the kernel_mutex is
@@ -157,93 +175,109 @@ void
innobase_mysql_end_print_arbitrary_thd(void);
/*========================================*/
-/**********************************************************************
+/******************************************************************//**
Get the variable length bounds of the given character set. */
UNIV_INTERN
void
innobase_get_cset_width(
/*====================*/
- ulint cset, /* in: MySQL charset-collation code */
- ulint* mbminlen, /* out: minimum length of a char (in bytes) */
- ulint* mbmaxlen); /* out: maximum length of a char (in bytes) */
+ ulint cset, /*!< in: MySQL charset-collation code */
+ ulint* mbminlen, /*!< out: minimum length of a char (in bytes) */
+ ulint* mbmaxlen); /*!< out: maximum length of a char (in bytes) */
-/**********************************************************************
-Compares NUL-terminated UTF-8 strings case insensitively. */
+/******************************************************************//**
+Compares NUL-terminated UTF-8 strings case insensitively.
+@return 0 if a=b, <0 if a<b, >1 if a>b */
UNIV_INTERN
int
innobase_strcasecmp(
/*================*/
- /* out: 0 if a=b, <0 if a<b, >1 if a>b */
- const char* a, /* in: first string to compare */
- const char* b); /* in: second string to compare */
+ const char* a, /*!< in: first string to compare */
+ const char* b); /*!< in: second string to compare */
-/**********************************************************************
-Returns true if the thread is executing a SELECT statement. */
+/******************************************************************//**
+Returns true if the thread is executing a SELECT statement.
+@return true if thd is executing SELECT */
ibool
thd_is_select(
/*==========*/
- /* out: true if thd is executing SELECT */
- const void* thd); /* in: thread handle (THD*) */
+ const void* thd); /*!< in: thread handle (THD*) */
-/**********************************************************************
+/******************************************************************//**
Converts an identifier to a table name. */
UNIV_INTERN
void
innobase_convert_from_table_id(
/*===========================*/
- struct charset_info_st* cs, /* in: the 'from' character set */
- char* to, /* out: converted identifier */
- const char* from, /* in: identifier to convert */
- ulint len); /* in: length of 'to', in bytes; should
+ struct charset_info_st* cs, /*!< in: the 'from' character set */
+ char* to, /*!< out: converted identifier */
+ const char* from, /*!< in: identifier to convert */
+ ulint len); /*!< in: length of 'to', in bytes; should
be at least 5 * strlen(to) + 1 */
-/**********************************************************************
+/******************************************************************//**
Converts an identifier to UTF-8. */
UNIV_INTERN
void
innobase_convert_from_id(
/*=====================*/
- struct charset_info_st* cs, /* in: the 'from' character set */
- char* to, /* out: converted identifier */
- const char* from, /* in: identifier to convert */
- ulint len); /* in: length of 'to', in bytes; should
+ struct charset_info_st* cs, /*!< in: the 'from' character set */
+ char* to, /*!< out: converted identifier */
+ const char* from, /*!< in: identifier to convert */
+ ulint len); /*!< in: length of 'to', in bytes; should
be at least 3 * strlen(to) + 1 */
-/**********************************************************************
+/******************************************************************//**
Makes all characters in a NUL-terminated UTF-8 string lower case. */
UNIV_INTERN
void
innobase_casedn_str(
/*================*/
- char* a); /* in/out: string to put in lower case */
+ char* a); /*!< in/out: string to put in lower case */
-/**************************************************************************
-Determines the connection character set. */
+/**********************************************************************//**
+Determines the connection character set.
+@return connection character set */
struct charset_info_st*
innobase_get_charset(
/*=================*/
- /* out: connection character set */
- void* mysql_thd); /* in: MySQL thread handle */
+ void* mysql_thd); /*!< in: MySQL thread handle */
-/**********************************************************************
+/******************************************************************//**
+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
+finds charset information and returns length of prefix_len characters in the
+index field in bytes.
+@return number of bytes occupied by the first n characters */
+UNIV_INTERN
+ulint
+innobase_get_at_most_n_mbchars(
+/*===========================*/
+ ulint charset_id, /*!< in: character set id */
+ ulint prefix_len, /*!< in: prefix length in bytes of the index
+ (this has to be divided by mbmaxlen to get the
+ number of CHARACTERS n in the prefix) */
+ ulint data_len, /*!< in: length of the string in bytes */
+ const char* str); /*!< in: character string */
+
+/******************************************************************//**
Returns true if the thread supports XA,
-global value of innodb_supports_xa if thd is NULL. */
+global value of innodb_supports_xa if thd is NULL.
+@return true if thd supports XA */
ibool
thd_supports_xa(
/*============*/
- /* out: true if thd supports XA */
- void* thd); /* in: thread handle (THD*), or NULL to query
+ void* thd); /*!< in: thread handle (THD*), or NULL to query
the global innodb_supports_xa */
-/**********************************************************************
-Returns the lock wait timeout for the current connection. */
+/******************************************************************//**
+Returns the lock wait timeout for the current connection.
+@return the lock wait timeout, in seconds */
ulong
thd_lock_wait_timeout(
/*==================*/
- /* out: the lock wait timeout, in seconds */
- void* thd); /* in: thread handle (THD*), or NULL to query
+ void* thd); /*!< in: thread handle (THD*), or NULL to query
the global innodb_lock_wait_timeout */
#endif
-#endif
diff --git a/storage/xtradb/include/handler0alter.h b/storage/xtradb/include/handler0alter.h
index 69488b67b2b..985b76f4f50 100644
--- a/storage/xtradb/include/handler0alter.h
+++ b/storage/xtradb/include/handler0alter.h
@@ -16,26 +16,27 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/handler0alter.h
Smart ALTER TABLE
*******************************************************/
-/*****************************************************************
+/*************************************************************//**
Copies an InnoDB record to table->record[0]. */
UNIV_INTERN
void
innobase_rec_to_mysql(
/*==================*/
- TABLE* table, /* in/out: MySQL table */
- const rec_t* rec, /* in: record */
- const dict_index_t* index, /* in: index */
- const ulint* offsets); /* in: rec_get_offsets(
+ TABLE* table, /*!< in/out: MySQL table */
+ const rec_t* rec, /*!< in: record */
+ const dict_index_t* index, /*!< in: index */
+ const ulint* offsets); /*!< in: rec_get_offsets(
rec, index, ...) */
-/*****************************************************************
+/*************************************************************//**
Resets table->record[0]. */
UNIV_INTERN
void
innobase_rec_reset(
/*===============*/
- TABLE* table); /* in/out: MySQL table */
+ TABLE* table); /*!< in/out: MySQL table */
diff --git a/storage/xtradb/include/hash0hash.h b/storage/xtradb/include/hash0hash.h
index 2b3eea62754..977cb829f35 100644
--- a/storage/xtradb/include/hash0hash.h
+++ b/storage/xtradb/include/hash0hash.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/hash0hash.h
The simple hash table utility
Created 5/20/1997 Heikki Tuuri
@@ -27,7 +28,9 @@ Created 5/20/1997 Heikki Tuuri
#include "univ.i"
#include "mem0mem.h"
-#include "sync0sync.h"
+#ifndef UNIV_HOTBACKUP
+# include "sync0sync.h"
+#endif /* !UNIV_HOTBACKUP */
typedef struct hash_table_struct hash_table_t;
typedef struct hash_cell_struct hash_cell_t;
@@ -37,55 +40,61 @@ typedef void* hash_node_t;
/* Fix Bug #13859: symbol collision between imap/mysql */
#define hash_create hash0_create
-/*****************************************************************
+/*************************************************************//**
Creates a hash table with >= n array cells. The actual number
-of cells is chosen to be a prime number slightly bigger than n. */
+of cells is chosen to be a prime number slightly bigger than n.
+@return own: created table */
UNIV_INTERN
hash_table_t*
hash_create(
/*========*/
- /* out, own: created table */
- ulint n); /* in: number of array cells */
-/*****************************************************************
+ ulint n); /*!< in: number of array cells */
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Creates a mutex array to protect a hash table. */
UNIV_INTERN
void
hash_create_mutexes_func(
/*=====================*/
- hash_table_t* table, /* in: hash table */
+ hash_table_t* table, /*!< in: hash table */
#ifdef UNIV_SYNC_DEBUG
- ulint sync_level, /* in: latching order level of the
+ ulint sync_level, /*!< in: latching order level of the
mutexes: used in the debug version */
#endif /* UNIV_SYNC_DEBUG */
- ulint n_mutexes); /* in: number of mutexes */
+ ulint n_mutexes); /*!< in: number of mutexes */
#ifdef UNIV_SYNC_DEBUG
# define hash_create_mutexes(t,n,level) hash_create_mutexes_func(t,level,n)
#else /* UNIV_SYNC_DEBUG */
# define hash_create_mutexes(t,n,level) hash_create_mutexes_func(t,n)
#endif /* UNIV_SYNC_DEBUG */
+#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+/*************************************************************//**
Frees a hash table. */
UNIV_INTERN
void
hash_table_free(
/*============*/
- hash_table_t* table); /* in, own: hash table */
-/******************************************************************
-Calculates the hash value from a folded value. */
+ hash_table_t* table); /*!< in, own: hash table */
+/**************************************************************//**
+Calculates the hash value from a folded value.
+@return hashed value */
UNIV_INLINE
ulint
hash_calc_hash(
/*===========*/
- /* out: hashed value */
- ulint fold, /* in: folded value */
- hash_table_t* table); /* in: hash table */
-/************************************************************************
+ ulint fold, /*!< in: folded value */
+ hash_table_t* table); /*!< in: hash table */
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Assert that the mutex for the table in a hash operation is owned. */
-#define HASH_ASSERT_OWNED(TABLE, FOLD) \
+# define HASH_ASSERT_OWNED(TABLE, FOLD) \
ut_ad(!(TABLE)->mutexes || mutex_own(hash_get_mutex(TABLE, FOLD)));
+#else /* !UNIV_HOTBACKUP */
+# define HASH_ASSERT_OWNED(TABLE, FOLD)
+#endif /* !UNIV_HOTBACKUP */
-/***********************************************************************
+/*******************************************************************//**
Inserts a struct to a hash table. */
#define HASH_INSERT(TYPE, NAME, TABLE, FOLD, DATA)\
@@ -121,7 +130,7 @@ do {\
# define HASH_INVALIDATE(DATA, NAME) do {} while (0)
#endif
-/***********************************************************************
+/*******************************************************************//**
Deletes a struct from a hash table. */
#define HASH_DELETE(TYPE, NAME, TABLE, FOLD, DATA)\
@@ -150,18 +159,18 @@ do {\
HASH_INVALIDATE(DATA, NAME);\
} while (0)
-/***********************************************************************
+/*******************************************************************//**
Gets the first struct in a hash chain, NULL if none. */
#define HASH_GET_FIRST(TABLE, HASH_VAL)\
(hash_get_nth_cell(TABLE, HASH_VAL)->node)
-/***********************************************************************
+/*******************************************************************//**
Gets the next struct in a hash chain, NULL if none. */
#define HASH_GET_NEXT(NAME, DATA) ((DATA)->NAME)
-/************************************************************************
+/********************************************************************//**
Looks for a struct in a hash table. */
#define HASH_SEARCH(NAME, TABLE, FOLD, TYPE, DATA, ASSERTION, TEST)\
{\
@@ -182,7 +191,7 @@ Looks for a struct in a hash table. */
}\
}
-/************************************************************************
+/********************************************************************//**
Looks for an item in all hash buckets. */
#define HASH_SEARCH_ALL(NAME, TABLE, TYPE, DATA, ASSERTION, TEST) \
do { \
@@ -208,33 +217,33 @@ do { \
} \
} while (0)
-/****************************************************************
-Gets the nth cell in a hash table. */
+/************************************************************//**
+Gets the nth cell in a hash table.
+@return pointer to cell */
UNIV_INLINE
hash_cell_t*
hash_get_nth_cell(
/*==============*/
- /* out: pointer to cell */
- hash_table_t* table, /* in: hash table */
- ulint n); /* in: cell index */
+ hash_table_t* table, /*!< in: hash table */
+ ulint n); /*!< in: cell index */
-/*****************************************************************
+/*************************************************************//**
Clears a hash table so that all the cells become empty. */
UNIV_INLINE
void
hash_table_clear(
/*=============*/
- hash_table_t* table); /* in/out: hash table */
+ hash_table_t* table); /*!< in/out: hash table */
-/*****************************************************************
-Returns the number of cells in a hash table. */
+/*************************************************************//**
+Returns the number of cells in a hash table.
+@return number of cells */
UNIV_INLINE
ulint
hash_get_n_cells(
/*=============*/
- /* out: number of cells */
- hash_table_t* table); /* in: table */
-/***********************************************************************
+ hash_table_t* table); /*!< in: table */
+/*******************************************************************//**
Deletes a struct which is stored in the heap of the hash table, and compacts
the heap. The fold value must be stored in the struct NODE in a field named
'fold'. */
@@ -293,8 +302,9 @@ do {\
mem_heap_free_top(hash_get_heap(TABLE, fold111), sizeof(TYPE));\
} while (0)
-/********************************************************************
-Move all hash table entries from OLD_TABLE to NEW_TABLE.*/
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
+Move all hash table entries from OLD_TABLE to NEW_TABLE. */
#define HASH_MIGRATE(OLD_TABLE, NEW_TABLE, NODE_TYPE, PTR_NAME, FOLD_FUNC) \
do {\
@@ -318,104 +328,111 @@ do {\
}\
} while (0)
-
-/****************************************************************
-Gets the mutex index for a fold value in a hash table. */
+/************************************************************//**
+Gets the mutex index for a fold value in a hash table.
+@return mutex number */
UNIV_INLINE
ulint
hash_get_mutex_no(
/*==============*/
- /* out: mutex number */
- hash_table_t* table, /* in: hash table */
- ulint fold); /* in: fold */
-/****************************************************************
-Gets the nth heap in a hash table. */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: fold */
+/************************************************************//**
+Gets the nth heap in a hash table.
+@return mem heap */
UNIV_INLINE
mem_heap_t*
hash_get_nth_heap(
/*==============*/
- /* out: mem heap */
- hash_table_t* table, /* in: hash table */
- ulint i); /* in: index of the heap */
-/****************************************************************
-Gets the heap for a fold value in a hash table. */
+ hash_table_t* table, /*!< in: hash table */
+ ulint i); /*!< in: index of the heap */
+/************************************************************//**
+Gets the heap for a fold value in a hash table.
+@return mem heap */
UNIV_INLINE
mem_heap_t*
hash_get_heap(
/*==========*/
- /* out: mem heap */
- hash_table_t* table, /* in: hash table */
- ulint fold); /* in: fold */
-/****************************************************************
-Gets the nth mutex in a hash table. */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: fold */
+/************************************************************//**
+Gets the nth mutex in a hash table.
+@return mutex */
UNIV_INLINE
mutex_t*
hash_get_nth_mutex(
/*===============*/
- /* out: mutex */
- hash_table_t* table, /* in: hash table */
- ulint i); /* in: index of the mutex */
-/****************************************************************
-Gets the mutex for a fold value in a hash table. */
+ hash_table_t* table, /*!< in: hash table */
+ ulint i); /*!< in: index of the mutex */
+/************************************************************//**
+Gets the mutex for a fold value in a hash table.
+@return mutex */
UNIV_INLINE
mutex_t*
hash_get_mutex(
/*===========*/
- /* out: mutex */
- hash_table_t* table, /* in: hash table */
- ulint fold); /* in: fold */
-/****************************************************************
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: fold */
+/************************************************************//**
Reserves the mutex for a fold value in a hash table. */
UNIV_INTERN
void
hash_mutex_enter(
/*=============*/
- hash_table_t* table, /* in: hash table */
- ulint fold); /* in: fold */
-/****************************************************************
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: fold */
+/************************************************************//**
Releases the mutex for a fold value in a hash table. */
UNIV_INTERN
void
hash_mutex_exit(
/*============*/
- hash_table_t* table, /* in: hash table */
- ulint fold); /* in: fold */
-/****************************************************************
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold); /*!< in: fold */
+/************************************************************//**
Reserves all the mutexes of a hash table, in an ascending order. */
UNIV_INTERN
void
hash_mutex_enter_all(
/*=================*/
- hash_table_t* table); /* in: hash table */
-/****************************************************************
+ hash_table_t* table); /*!< in: hash table */
+/************************************************************//**
Releases all the mutexes of a hash table. */
UNIV_INTERN
void
hash_mutex_exit_all(
/*================*/
- hash_table_t* table); /* in: hash table */
-
+ hash_table_t* table); /*!< in: hash table */
+#else /* !UNIV_HOTBACKUP */
+# define hash_get_heap(table, fold) ((table)->heap)
+# define hash_mutex_enter(table, fold) ((void) 0)
+# define hash_mutex_exit(table, fold) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
struct hash_cell_struct{
- void* node; /* hash chain node, NULL if none */
+ void* node; /*!< hash chain node, NULL if none */
};
/* The hash table structure */
struct hash_table_struct {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+# ifndef UNIV_HOTBACKUP
ibool adaptive;/* TRUE if this is the hash table of the
adaptive hash index */
+# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
ulint n_cells;/* number of cells in the hash table */
- hash_cell_t* array; /* pointer to cell array */
+ hash_cell_t* array; /*!< pointer to cell array */
+#ifndef UNIV_HOTBACKUP
ulint n_mutexes;/* if mutexes != NULL, then the number of
mutexes, must be a power of 2 */
mutex_t* mutexes;/* NULL, or an array of mutexes used to
protect segments of the hash table */
- mem_heap_t** heaps; /* if this is non-NULL, hash chain nodes for
+ mem_heap_t** heaps; /*!< if this is non-NULL, hash chain nodes for
external chaining can be allocated from these
memory heaps; there are then n_mutexes many of
these heaps */
+#endif /* !UNIV_HOTBACKUP */
mem_heap_t* heap;
ulint magic_n;
};
diff --git a/storage/xtradb/include/hash0hash.ic b/storage/xtradb/include/hash0hash.ic
index 792fdcbf4f8..19da2d50701 100644
--- a/storage/xtradb/include/hash0hash.ic
+++ b/storage/xtradb/include/hash0hash.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/hash0hash.ic
The simple hash table utility
Created 5/20/1997 Heikki Tuuri
@@ -24,97 +25,98 @@ Created 5/20/1997 Heikki Tuuri
#include "ut0rnd.h"
-/****************************************************************
-Gets the nth cell in a hash table. */
+/************************************************************//**
+Gets the nth cell in a hash table.
+@return pointer to cell */
UNIV_INLINE
hash_cell_t*
hash_get_nth_cell(
/*==============*/
- /* out: pointer to cell */
- hash_table_t* table, /* in: hash table */
- ulint n) /* in: cell index */
+ hash_table_t* table, /*!< in: hash table */
+ ulint n) /*!< in: cell index */
{
ut_ad(n < table->n_cells);
return(table->array + n);
}
-/*****************************************************************
+/*************************************************************//**
Clears a hash table so that all the cells become empty. */
UNIV_INLINE
void
hash_table_clear(
/*=============*/
- hash_table_t* table) /* in/out: hash table */
+ hash_table_t* table) /*!< in/out: hash table */
{
memset(table->array, 0x0,
table->n_cells * sizeof(*table->array));
}
-/*****************************************************************
-Returns the number of cells in a hash table. */
+/*************************************************************//**
+Returns the number of cells in a hash table.
+@return number of cells */
UNIV_INLINE
ulint
hash_get_n_cells(
/*=============*/
- /* out: number of cells */
- hash_table_t* table) /* in: table */
+ hash_table_t* table) /*!< in: table */
{
return(table->n_cells);
}
-/******************************************************************
-Calculates the hash value from a folded value. */
+/**************************************************************//**
+Calculates the hash value from a folded value.
+@return hashed value */
UNIV_INLINE
ulint
hash_calc_hash(
/*===========*/
- /* out: hashed value */
- ulint fold, /* in: folded value */
- hash_table_t* table) /* in: hash table */
+ ulint fold, /*!< in: folded value */
+ hash_table_t* table) /*!< in: hash table */
{
return(ut_hash_ulint(fold, table->n_cells));
}
-/****************************************************************
-Gets the mutex index for a fold value in a hash table. */
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
+Gets the mutex index for a fold value in a hash table.
+@return mutex number */
UNIV_INLINE
ulint
hash_get_mutex_no(
/*==============*/
- /* out: mutex number */
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: fold */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: fold */
{
ut_ad(ut_is_2pow(table->n_mutexes));
return(ut_2pow_remainder(hash_calc_hash(fold, table),
table->n_mutexes));
}
-/****************************************************************
-Gets the nth heap in a hash table. */
+/************************************************************//**
+Gets the nth heap in a hash table.
+@return mem heap */
UNIV_INLINE
mem_heap_t*
hash_get_nth_heap(
/*==============*/
- /* out: mem heap */
- hash_table_t* table, /* in: hash table */
- ulint i) /* in: index of the heap */
+ hash_table_t* table, /*!< in: hash table */
+ ulint i) /*!< in: index of the heap */
{
ut_ad(i < table->n_mutexes);
return(table->heaps[i]);
}
-/****************************************************************
-Gets the heap for a fold value in a hash table. */
+/************************************************************//**
+Gets the heap for a fold value in a hash table.
+@return mem heap */
UNIV_INLINE
mem_heap_t*
hash_get_heap(
/*==========*/
- /* out: mem heap */
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: fold */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: fold */
{
ulint i;
@@ -127,30 +129,30 @@ hash_get_heap(
return(hash_get_nth_heap(table, i));
}
-/****************************************************************
-Gets the nth mutex in a hash table. */
+/************************************************************//**
+Gets the nth mutex in a hash table.
+@return mutex */
UNIV_INLINE
mutex_t*
hash_get_nth_mutex(
/*===============*/
- /* out: mutex */
- hash_table_t* table, /* in: hash table */
- ulint i) /* in: index of the mutex */
+ hash_table_t* table, /*!< in: hash table */
+ ulint i) /*!< in: index of the mutex */
{
ut_ad(i < table->n_mutexes);
return(table->mutexes + i);
}
-/****************************************************************
-Gets the mutex for a fold value in a hash table. */
+/************************************************************//**
+Gets the mutex for a fold value in a hash table.
+@return mutex */
UNIV_INLINE
mutex_t*
hash_get_mutex(
/*===========*/
- /* out: mutex */
- hash_table_t* table, /* in: hash table */
- ulint fold) /* in: fold */
+ hash_table_t* table, /*!< in: hash table */
+ ulint fold) /*!< in: fold */
{
ulint i;
@@ -158,3 +160,4 @@ hash_get_mutex(
return(hash_get_nth_mutex(table, i));
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/ibuf0ibuf.h b/storage/xtradb/include/ibuf0ibuf.h
index 41e2392cc4a..21330997df3 100644
--- a/storage/xtradb/include/ibuf0ibuf.h
+++ b/storage/xtradb/include/ibuf0ibuf.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/ibuf0ibuf.h
Insert buffer
Created 7/19/1997 Heikki Tuuri
@@ -27,12 +28,13 @@ Created 7/19/1997 Heikki Tuuri
#include "univ.i"
-#include "dict0mem.h"
#include "mtr0mtr.h"
-#include "que0types.h"
-#include "ibuf0types.h"
+#include "dict0mem.h"
#include "fsp0fsp.h"
+#ifndef UNIV_HOTBACKUP
+# include "ibuf0types.h"
+
/** Combinations of operations that can be buffered. Because the enum
values are used for indexing innobase_change_buffering_values[], they
should start at 0 and there should not be any gaps. */
@@ -69,29 +71,29 @@ affects the free space. It is unsafe to increment the bits in a
separately committed mini-transaction, because in crash recovery, the
free bits could momentarily be set too high. */
-/**********************************************************************
+/******************************************************************//**
Creates the insert buffer data structure at a database startup and
initializes the data structures for the insert buffer of each tablespace. */
UNIV_INTERN
void
ibuf_init_at_db_start(void);
/*=======================*/
-/*************************************************************************
+/*********************************************************************//**
Reads the biggest tablespace id from the high end of the insert buffer
tree and updates the counter in fil_system. */
UNIV_INTERN
void
ibuf_update_max_tablespace_id(void);
/*===============================*/
-/*************************************************************************
+/*********************************************************************//**
Initializes an ibuf bitmap page. */
UNIV_INTERN
void
ibuf_bitmap_page_init(
/*==================*/
- buf_block_t* block, /* in: bitmap page */
- mtr_t* mtr); /* in: mtr */
-/****************************************************************************
+ buf_block_t* block, /*!< in: bitmap page */
+ mtr_t* mtr); /*!< in: mtr */
+/************************************************************************//**
Resets the free bits of the page in the ibuf bitmap. This is done in a
separate mini-transaction, hence this operation does not restrict
further work to only ibuf bitmap operations, which would result if the
@@ -104,10 +106,10 @@ UNIV_INTERN
void
ibuf_reset_free_bits(
/*=================*/
- buf_block_t* block); /* in: index page; free bits are set to 0
+ buf_block_t* block); /*!< in: index page; free bits are set to 0
if the index is a non-clustered
non-unique, and page level is 0 */
-/****************************************************************************
+/************************************************************************//**
Updates the free bits of an uncompressed page in the ibuf bitmap if
there is not enough free on the page any more. This is done in a
separate mini-transaction, hence this operation does not restrict
@@ -124,18 +126,18 @@ UNIV_INLINE
void
ibuf_update_free_bits_if_full(
/*==========================*/
- buf_block_t* block, /* in: index page to which we have added new
+ buf_block_t* block, /*!< in: index page to which we have added new
records; the free bits are updated if the
index is non-clustered and non-unique and
the page level is 0, and the page becomes
fuller */
- ulint max_ins_size,/* in: value of maximum insert size with
+ ulint max_ins_size,/*!< in: value of maximum insert size with
reorganize before the latest operation
performed to the page */
- ulint increase);/* in: upper limit for the additional space
+ ulint increase);/*!< in: upper limit for the additional space
used in the latest operation, if known, or
ULINT_UNDEFINED */
-/**************************************************************************
+/**********************************************************************//**
Updates the free bits for an uncompressed page to reflect the present
state. Does this in the mtr given, which means that the latching
order rules virtually prevent any further operations for this OS
@@ -147,14 +149,14 @@ UNIV_INTERN
void
ibuf_update_free_bits_low(
/*======================*/
- const buf_block_t* block, /* in: index page */
- ulint max_ins_size, /* in: value of
+ const buf_block_t* block, /*!< in: index page */
+ ulint max_ins_size, /*!< in: value of
maximum insert size
with reorganize before
the latest operation
performed to the page */
- mtr_t* mtr); /* in/out: mtr */
-/**************************************************************************
+ mtr_t* mtr); /*!< in/out: mtr */
+/**********************************************************************//**
Updates the free bits for a compressed page to reflect the present
state. Does this in the mtr given, which means that the latching
order rules virtually prevent any further operations for this OS
@@ -166,9 +168,9 @@ UNIV_INTERN
void
ibuf_update_free_bits_zip(
/*======================*/
- buf_block_t* block, /* in/out: index page */
- mtr_t* mtr); /* in/out: mtr */
-/**************************************************************************
+ buf_block_t* block, /*!< in/out: index page */
+ mtr_t* mtr); /*!< in/out: mtr */
+/**********************************************************************//**
Updates the free bits for the two pages to reflect the present state.
Does this in the mtr given, which means that the latching order rules
virtually prevent any further operations until mtr is committed.
@@ -179,58 +181,60 @@ UNIV_INTERN
void
ibuf_update_free_bits_for_two_pages_low(
/*====================================*/
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- buf_block_t* block1, /* in: index page */
- buf_block_t* block2, /* in: index page */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ buf_block_t* block1, /*!< in: index page */
+ buf_block_t* block2, /*!< in: index page */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
A basic partial test if an insert to the insert buffer could be possible and
recommended. */
UNIV_INLINE
ibool
ibuf_should_try(
/*============*/
- dict_index_t* index, /* in: index where to insert */
- ulint ignore_sec_unique); /* in: if != 0, we should
+ dict_index_t* index, /*!< in: index where to insert */
+ ulint ignore_sec_unique); /*!< in: if != 0, we should
ignore UNIQUE constraint on
a secondary index when we
decide */
-/**********************************************************************
+/******************************************************************//**
Returns TRUE if the current OS thread is performing an insert buffer
-routine. */
+routine.
+
+For instance, a read-ahead of non-ibuf pages is forbidden by threads
+that are executing an insert buffer routine.
+@return TRUE if inside an insert buffer routine */
UNIV_INTERN
ibool
ibuf_inside(void);
/*=============*/
- /* out: TRUE if inside an insert buffer routine: for instance,
- a read-ahead of non-ibuf pages is then forbidden */
-/***************************************************************************
-Checks if a page address is an ibuf bitmap page (level 3 page) address. */
+/***********************************************************************//**
+Checks if a page address is an ibuf bitmap page (level 3 page) address.
+@return TRUE if a bitmap page */
UNIV_INLINE
ibool
ibuf_bitmap_page(
/*=============*/
- /* out: TRUE if a bitmap page */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint page_no);/* in: page number */
-/***************************************************************************
+ ulint page_no);/*!< in: page number */
+/***********************************************************************//**
Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages.
-Must not be called when recv_no_ibuf_operations==TRUE. */
+Must not be called when recv_no_ibuf_operations==TRUE.
+@return TRUE if level 2 or level 3 page */
UNIV_INTERN
ibool
ibuf_page(
/*======*/
- /* out: TRUE if level 2 or level 3 page */
- ulint space, /* in: space id */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint page_no,/* in: page number */
- mtr_t* mtr); /* in: mtr which will contain an x-latch to the
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint page_no,/*!< in: page number */
+ mtr_t* mtr); /*!< in: mtr which will contain an x-latch to the
bitmap page if the page is not one of the fixed
address ibuf pages, or NULL, in which case a new
transaction is created. */
-/***************************************************************************
+/***********************************************************************//**
Frees excess pages from the ibuf free list. This function is called when an OS
thread calls fsp services to allocate a new file segment, or a new page to a
file segment, and the thread did not own the fsp latch before this call. */
@@ -238,22 +242,22 @@ UNIV_INTERN
void
ibuf_free_excess_pages(void);
/*========================*/
-/*************************************************************************
+/*********************************************************************//**
Makes an index insert to the insert buffer, instead of directly to the disk
page, if this is possible. Does not do insert if the index is clustered
-or unique. */
+or unique.
+@return TRUE if success */
UNIV_INTERN
ibool
ibuf_insert(
/*========*/
- /* out: TRUE if success */
- const dtuple_t* entry, /* in: index entry to insert */
- dict_index_t* index, /* in: index where to insert */
- ulint space, /* in: space id where to insert */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint page_no,/* in: page number where to insert */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
+ const dtuple_t* entry, /*!< in: index entry to insert */
+ dict_index_t* index, /*!< in: index where to insert */
+ ulint space, /*!< in: space id where to insert */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint page_no,/*!< in: page number where to insert */
+ que_thr_t* thr); /*!< in: query thread */
+/*********************************************************************//**
When an index page is read from a disk to the buffer pool, this function
inserts to the page the possible index entries buffered in the insert buffer.
The entries are deleted from the insert buffer. If the page is not read, but
@@ -264,19 +268,19 @@ UNIV_INTERN
void
ibuf_merge_or_delete_for_page(
/*==========================*/
- buf_block_t* block, /* in: if page has been read from
+ buf_block_t* block, /*!< in: if page has been read from
disk, pointer to the page x-latched,
else NULL */
- ulint space, /* in: space id of the index page */
- ulint page_no,/* in: page number of the index page */
- ulint zip_size,/* in: compressed page size in bytes,
+ ulint space, /*!< in: space id of the index page */
+ ulint page_no,/*!< in: page number of the index page */
+ ulint zip_size,/*!< in: compressed page size in bytes,
or 0 */
- ibool update_ibuf_bitmap);/* in: normally this is set
+ ibool update_ibuf_bitmap);/*!< in: normally this is set
to TRUE, but if we have deleted or are
deleting the tablespace, then we
naturally do not want to update a
non-existent bitmap page */
-/*************************************************************************
+/*********************************************************************//**
Deletes all entries in the insert buffer for a given space id. This is used
in DISCARD TABLESPACE and IMPORT TABLESPACE.
NOTE: this does not update the page free bitmaps in the space. The space will
@@ -285,75 +289,79 @@ UNIV_INTERN
void
ibuf_delete_for_discarded_space(
/*============================*/
- ulint space); /* in: space id */
-/*************************************************************************
-Contracts insert buffer trees by reading pages to the buffer pool. */
+ ulint space); /*!< in: space id */
+/*********************************************************************//**
+Contracts insert buffer trees by reading pages to the buffer pool.
+@return a lower limit for the combined size in bytes of entries which
+will be merged from ibuf trees to the pages read, 0 if ibuf is
+empty */
UNIV_INTERN
ulint
ibuf_contract(
/*==========*/
- /* out: a lower limit for the combined size in bytes
- of entries which will be merged from ibuf trees to the
- pages read, 0 if ibuf is empty */
- ibool sync); /* in: TRUE if the caller wants to wait for the
+ ibool sync); /*!< in: TRUE if the caller wants to wait for the
issued read with the highest tablespace address
to complete */
-/*************************************************************************
-Contracts insert buffer trees by reading pages to the buffer pool. */
+/*********************************************************************//**
+Contracts insert buffer trees by reading pages to the buffer pool.
+@return a lower limit for the combined size in bytes of entries which
+will be merged from ibuf trees to the pages read, 0 if ibuf is
+empty */
UNIV_INTERN
ulint
ibuf_contract_for_n_pages(
/*======================*/
- /* out: a lower limit for the combined size in bytes
- of entries which will be merged from ibuf trees to the
- pages read, 0 if ibuf is empty */
- ibool sync, /* in: TRUE if the caller wants to wait for the
+ ibool sync, /*!< in: TRUE if the caller wants to wait for the
issued read with the highest tablespace address
to complete */
- ulint n_pages);/* in: try to read at least this many pages to
+ ulint n_pages);/*!< in: try to read at least this many pages to
the buffer pool and merge the ibuf contents to
them */
-/*************************************************************************
-Parses a redo log record of an ibuf bitmap page init. */
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************************//**
+Parses a redo log record of an ibuf bitmap page init.
+@return end of log record or NULL */
UNIV_INTERN
byte*
ibuf_parse_bitmap_init(
/*===================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in: block or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in: block or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_IBUF_COUNT_DEBUG
-/**********************************************************************
-Gets the ibuf count for a given page. */
+/******************************************************************//**
+Gets the ibuf count for a given page.
+@return number of entries in the insert buffer currently buffered for
+this page */
UNIV_INTERN
ulint
ibuf_count_get(
/*===========*/
- /* out: number of entries in the insert buffer
- currently buffered for this page */
- ulint space, /* in: space id */
- ulint page_no);/* in: page number */
+ ulint space, /*!< in: space id */
+ ulint page_no);/*!< in: page number */
#endif
-/**********************************************************************
-Looks if the insert buffer is empty. */
+/******************************************************************//**
+Looks if the insert buffer is empty.
+@return TRUE if empty */
UNIV_INTERN
ibool
ibuf_is_empty(void);
/*===============*/
- /* out: TRUE if empty */
-/**********************************************************************
+/******************************************************************//**
Prints info of ibuf. */
UNIV_INTERN
void
ibuf_print(
/*=======*/
- FILE* file); /* in: file where to print */
+ FILE* file); /*!< in: file where to print */
#define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO
#define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO
+#endif /* !UNIV_HOTBACKUP */
+
/* The ibuf header page currently contains only the file segment header
for the file segment from which the pages for the ibuf tree are allocated */
#define IBUF_HEADER PAGE_DATA
diff --git a/storage/xtradb/include/ibuf0ibuf.ic b/storage/xtradb/include/ibuf0ibuf.ic
index 170e5dba473..15bbe61ab30 100644
--- a/storage/xtradb/include/ibuf0ibuf.ic
+++ b/storage/xtradb/include/ibuf0ibuf.ic
@@ -16,50 +16,52 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/ibuf0ibuf.ic
Insert buffer
Created 7/19/1997 Heikki Tuuri
*******************************************************/
-#include "buf0lru.h"
#include "page0page.h"
#include "page0zip.h"
+#ifndef UNIV_HOTBACKUP
+#include "buf0lru.h"
+/** Counter for ibuf_should_try() */
extern ulint ibuf_flush_count;
-/* If this number is n, an index page must contain at least the page size
-per n bytes of free space for ibuf to try to buffer inserts to this page.
-If there is this much of free space, the corresponding bits are set in the
-ibuf bitmap. */
+/** An index page must contain at least UNIV_PAGE_SIZE /
+IBUF_PAGE_SIZE_PER_FREE_SPACE bytes of free space for ibuf to try to
+buffer inserts to this page. If there is this much of free space, the
+corresponding bits are set in the ibuf bitmap. */
#define IBUF_PAGE_SIZE_PER_FREE_SPACE 32
-/* Insert buffer struct */
-
+/** Insert buffer struct */
struct ibuf_struct{
- ulint size; /* current size of the ibuf index
+ ulint size; /*!< current size of the ibuf index
tree, in pages */
- ulint max_size; /* recommended maximum size of the
+ ulint max_size; /*!< recommended maximum size of the
ibuf index tree, in pages */
- ulint seg_size; /* allocated pages of the file
+ ulint seg_size; /*!< allocated pages of the file
segment containing ibuf header and
tree */
- ibool empty; /* after an insert to the ibuf tree
+ ibool empty; /*!< after an insert to the ibuf tree
is performed, this is set to FALSE,
and if a contract operation finds
the tree empty, this is set to
TRUE */
- ulint free_list_len; /* length of the free list */
- ulint height; /* tree height */
- dict_index_t* index; /* insert buffer index */
+ ulint free_list_len; /*!< length of the free list */
+ ulint height; /*!< tree height */
+ dict_index_t* index; /*!< insert buffer index */
- ulint n_inserts; /* number of inserts made to
+ ulint n_inserts; /*!< number of inserts made to
the insert buffer */
- ulint n_merges; /* number of pages merged */
- ulint n_merged_recs; /* number of records merged */
+ ulint n_merges; /*!< number of pages merged */
+ ulint n_merged_recs; /*!< number of records merged */
};
-/****************************************************************************
+/************************************************************************//**
Sets the free bit of the page in the ibuf bitmap. This is done in a separate
mini-transaction, hence this operation does not restrict further work to only
ibuf bitmap operations, which would result if the latch to the bitmap page
@@ -68,29 +70,29 @@ UNIV_INTERN
void
ibuf_set_free_bits_func(
/*====================*/
- buf_block_t* block, /* in: index page of a non-clustered index;
+ buf_block_t* block, /*!< in: index page of a non-clustered index;
free bit is reset if page level is 0 */
#ifdef UNIV_IBUF_DEBUG
- ulint max_val,/* in: ULINT_UNDEFINED or a maximum
+ ulint max_val,/*!< in: ULINT_UNDEFINED or a maximum
value which the bits must have before
setting; this is for debugging */
#endif /* UNIV_IBUF_DEBUG */
- ulint val); /* in: value to set: < 4 */
+ ulint val); /*!< in: value to set: < 4 */
#ifdef UNIV_IBUF_DEBUG
# define ibuf_set_free_bits(b,v,max) ibuf_set_free_bits_func(b,max,v)
#else /* UNIV_IBUF_DEBUG */
# define ibuf_set_free_bits(b,v,max) ibuf_set_free_bits_func(b,v)
#endif /* UNIV_IBUF_DEBUG */
-/**************************************************************************
+/**********************************************************************//**
A basic partial test if an insert to the insert buffer could be possible and
recommended. */
UNIV_INLINE
ibool
ibuf_should_try(
/*============*/
- dict_index_t* index, /* in: index where to insert */
- ulint ignore_sec_unique) /* in: if != 0, we should
+ dict_index_t* index, /*!< in: index where to insert */
+ ulint ignore_sec_unique) /*!< in: if != 0, we should
ignore UNIQUE constraint on
a secondary index when we
decide */
@@ -112,16 +114,16 @@ ibuf_should_try(
return(FALSE);
}
-/***************************************************************************
-Checks if a page address is an ibuf bitmap page address. */
+/***********************************************************************//**
+Checks if a page address is an ibuf bitmap page address.
+@return TRUE if a bitmap page */
UNIV_INLINE
ibool
ibuf_bitmap_page(
/*=============*/
- /* out: TRUE if a bitmap page */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint page_no)/* in: page number */
+ ulint page_no)/*!< in: page number */
{
ut_ad(ut_is_2pow(zip_size));
@@ -134,16 +136,16 @@ ibuf_bitmap_page(
== FSP_IBUF_BITMAP_OFFSET));
}
-/*************************************************************************
-Translates the free space on a page to a value in the ibuf bitmap.*/
+/*********************************************************************//**
+Translates the free space on a page to a value in the ibuf bitmap.
+@return value for ibuf bitmap bits */
UNIV_INLINE
ulint
ibuf_index_page_calc_free_bits(
/*===========================*/
- /* out: value for ibuf bitmap bits */
- ulint zip_size, /* in: compressed page size in bytes;
+ ulint zip_size, /*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint max_ins_size) /* in: maximum insert size after reorganize
+ ulint max_ins_size) /*!< in: maximum insert size after reorganize
for the page */
{
ulint n;
@@ -170,17 +172,16 @@ ibuf_index_page_calc_free_bits(
return(n);
}
-/*************************************************************************
-Translates the ibuf free bits to the free space on a page in bytes. */
+/*********************************************************************//**
+Translates the ibuf free bits to the free space on a page in bytes.
+@return maximum insert size after reorganize for the page */
UNIV_INLINE
ulint
ibuf_index_page_calc_free_from_bits(
/*================================*/
- /* out: maximum insert size after reorganize for the
- page */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint bits) /* in: value for ibuf bitmap bits */
+ ulint bits) /*!< in: value for ibuf bitmap bits */
{
ut_ad(bits < 4);
ut_ad(ut_is_2pow(zip_size));
@@ -202,16 +203,16 @@ ibuf_index_page_calc_free_from_bits(
return(bits * (UNIV_PAGE_SIZE / IBUF_PAGE_SIZE_PER_FREE_SPACE));
}
-/*************************************************************************
-Translates the free space on a compressed page to a value in the ibuf bitmap.*/
+/*********************************************************************//**
+Translates the free space on a compressed page to a value in the ibuf bitmap.
+@return value for ibuf bitmap bits */
UNIV_INLINE
ulint
ibuf_index_page_calc_free_zip(
/*==========================*/
- /* out: value for ibuf bitmap bits */
ulint zip_size,
- /* in: compressed page size in bytes */
- const buf_block_t* block) /* in: buffer block */
+ /*!< in: compressed page size in bytes */
+ const buf_block_t* block) /*!< in: buffer block */
{
ulint max_ins_size;
const page_zip_des_t* page_zip;
@@ -236,16 +237,16 @@ ibuf_index_page_calc_free_zip(
return(ibuf_index_page_calc_free_bits(zip_size, max_ins_size));
}
-/*************************************************************************
-Translates the free space on a page to a value in the ibuf bitmap.*/
+/*********************************************************************//**
+Translates the free space on a page to a value in the ibuf bitmap.
+@return value for ibuf bitmap bits */
UNIV_INLINE
ulint
ibuf_index_page_calc_free(
/*======================*/
- /* out: value for ibuf bitmap bits */
- ulint zip_size,/* in: compressed page size in bytes;
+ ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- const buf_block_t* block) /* in: buffer block */
+ const buf_block_t* block) /*!< in: buffer block */
{
ut_ad(zip_size == buf_block_get_zip_size(block));
@@ -261,7 +262,7 @@ ibuf_index_page_calc_free(
}
}
-/****************************************************************************
+/************************************************************************//**
Updates the free bits of an uncompressed page in the ibuf bitmap if
there is not enough free on the page any more. This is done in a
separate mini-transaction, hence this operation does not restrict
@@ -278,15 +279,15 @@ UNIV_INLINE
void
ibuf_update_free_bits_if_full(
/*==========================*/
- buf_block_t* block, /* in: index page to which we have added new
+ buf_block_t* block, /*!< in: index page to which we have added new
records; the free bits are updated if the
index is non-clustered and non-unique and
the page level is 0, and the page becomes
fuller */
- ulint max_ins_size,/* in: value of maximum insert size with
+ ulint max_ins_size,/*!< in: value of maximum insert size with
reorganize before the latest operation
performed to the page */
- ulint increase)/* in: upper limit for the additional space
+ ulint increase)/*!< in: upper limit for the additional space
used in the latest operation, if known, or
ULINT_UNDEFINED */
{
@@ -323,3 +324,4 @@ ibuf_update_free_bits_if_full(
ibuf_set_free_bits(block, after, before);
}
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/ibuf0types.h b/storage/xtradb/include/ibuf0types.h
index 264415196a1..55944f879b2 100644
--- a/storage/xtradb/include/ibuf0types.h
+++ b/storage/xtradb/include/ibuf0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/ibuf0types.h
Insert buffer global types
Created 7/29/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/lock0iter.h b/storage/xtradb/include/lock0iter.h
index 3cd47bb95d2..25a57c9740c 100644
--- a/storage/xtradb/include/lock0iter.h
+++ b/storage/xtradb/include/lock0iter.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/lock0iter.h
Lock queue iterator type and function prototypes.
Created July 16, 2007 Vasil Dimov
@@ -36,7 +37,7 @@ typedef struct lock_queue_iterator_struct {
ulint bit_no;
} lock_queue_iterator_t;
-/***********************************************************************
+/*******************************************************************//**
Initialize lock queue iterator so that it starts to iterate from
"lock". bit_no specifies the record number within the heap where the
record is stored. It can be undefined (ULINT_UNDEFINED) in two cases:
@@ -49,20 +50,20 @@ UNIV_INTERN
void
lock_queue_iterator_reset(
/*======================*/
- lock_queue_iterator_t* iter, /* out: iterator */
- const lock_t* lock, /* in: lock to start from */
- ulint bit_no);/* in: record number in the
+ lock_queue_iterator_t* iter, /*!< out: iterator */
+ const lock_t* lock, /*!< in: lock to start from */
+ ulint bit_no);/*!< in: record number in the
heap */
-/***********************************************************************
+/*******************************************************************//**
Gets the previous lock in the lock queue, returns NULL if there are no
more locks (i.e. the current lock is the first one). The iterator is
-receded (if not-NULL is returned). */
+receded (if not-NULL is returned).
+@return previous lock or NULL */
const lock_t*
lock_queue_iterator_get_prev(
/*=========================*/
- /* out: previous lock or NULL */
- lock_queue_iterator_t* iter); /* in/out: iterator */
+ lock_queue_iterator_t* iter); /*!< in/out: iterator */
#endif /* lock0iter_h */
diff --git a/storage/xtradb/include/lock0lock.h b/storage/xtradb/include/lock0lock.h
index 2deeb804737..fa5db831d4f 100644
--- a/storage/xtradb/include/lock0lock.h
+++ b/storage/xtradb/include/lock0lock.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/lock0lock.h
The transaction lock system
Created 5/7/1996 Heikki Tuuri
@@ -28,6 +29,7 @@ Created 5/7/1996 Heikki Tuuri
#include "univ.i"
#include "buf0types.h"
#include "trx0types.h"
+#include "mtr0types.h"
#include "rem0types.h"
#include "dict0types.h"
#include "que0types.h"
@@ -42,43 +44,40 @@ extern ibool lock_print_waits;
/* Buffer for storing information about the most recent deadlock error */
extern FILE* lock_latest_err_file;
-/*************************************************************************
-Gets the size of a lock struct. */
+/*********************************************************************//**
+Gets the size of a lock struct.
+@return size in bytes */
UNIV_INTERN
ulint
lock_get_size(void);
/*===============*/
- /* out: size in bytes */
-/*************************************************************************
+/*********************************************************************//**
Creates the lock system at database start. */
UNIV_INTERN
void
lock_sys_create(
/*============*/
- ulint n_cells); /* in: number of slots in lock hash table */
-/*************************************************************************
+ ulint n_cells); /*!< in: number of slots in lock hash table */
+/*********************************************************************//**
Checks if some transaction has an implicit x-lock on a record in a clustered
-index. */
+index.
+@return transaction which has the x-lock, or NULL */
UNIV_INLINE
trx_t*
lock_clust_rec_some_has_impl(
/*=========================*/
- /* out: transaction which has the x-lock, or
- NULL */
- const rec_t* rec, /* in: user record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets);/* in: rec_get_offsets(rec, index) */
-/*************************************************************************
-Gets the heap_no of the smallest user record on a page. */
+ const rec_t* rec, /*!< in: user record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */
+/*********************************************************************//**
+Gets the heap_no of the smallest user record on a page.
+@return heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */
UNIV_INLINE
ulint
lock_get_min_heap_no(
/*=================*/
- /* out: heap_no of smallest
- user record, or
- PAGE_HEAP_NO_SUPREMUM */
- const buf_block_t* block); /* in: buffer block */
-/*****************************************************************
+ const buf_block_t* block); /*!< in: buffer block */
+/*************************************************************//**
Updates the lock table when we have reorganized a page. NOTE: we copy
also the locks set on the infimum of the page; the infimum may carry
locks if an update of a record is occurring on the page, and its locks
@@ -87,62 +86,62 @@ UNIV_INTERN
void
lock_move_reorganize_page(
/*======================*/
- const buf_block_t* block, /* in: old index page, now
+ const buf_block_t* block, /*!< in: old index page, now
reorganized */
- const buf_block_t* oblock);/* in: copy of the old, not
+ const buf_block_t* oblock);/*!< in: copy of the old, not
reorganized page */
-/*****************************************************************
+/*************************************************************//**
Moves the explicit locks on user records to another page if a record
list end is moved to another page. */
UNIV_INTERN
void
lock_move_rec_list_end(
/*===================*/
- const buf_block_t* new_block, /* in: index page to move to */
- const buf_block_t* block, /* in: index page */
- const rec_t* rec); /* in: record on page: this
+ const buf_block_t* new_block, /*!< in: index page to move to */
+ const buf_block_t* block, /*!< in: index page */
+ const rec_t* rec); /*!< in: record on page: this
is the first record moved */
-/*****************************************************************
+/*************************************************************//**
Moves the explicit locks on user records to another page if a record
list start is moved to another page. */
UNIV_INTERN
void
lock_move_rec_list_start(
/*=====================*/
- const buf_block_t* new_block, /* in: index page to move to */
- const buf_block_t* block, /* in: index page */
- const rec_t* rec, /* in: record on page:
+ const buf_block_t* new_block, /*!< in: index page to move to */
+ const buf_block_t* block, /*!< in: index page */
+ const rec_t* rec, /*!< in: record on page:
this is the first
record NOT copied */
- const rec_t* old_end); /* in: old
+ const rec_t* old_end); /*!< in: old
previous-to-last
record on new_page
before the records
were copied */
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is split to the right. */
UNIV_INTERN
void
lock_update_split_right(
/*====================*/
- const buf_block_t* right_block, /* in: right page */
- const buf_block_t* left_block); /* in: left page */
-/*****************************************************************
+ const buf_block_t* right_block, /*!< in: right page */
+ const buf_block_t* left_block); /*!< in: left page */
+/*************************************************************//**
Updates the lock table when a page is merged to the right. */
UNIV_INTERN
void
lock_update_merge_right(
/*====================*/
- const buf_block_t* right_block, /* in: right page to
+ const buf_block_t* right_block, /*!< in: right page to
which merged */
- const rec_t* orig_succ, /* in: original
+ const rec_t* orig_succ, /*!< in: original
successor of infimum
on the right page
before merge */
- const buf_block_t* left_block); /* in: merged index
+ const buf_block_t* left_block); /*!< in: merged index
page which will be
discarded */
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when the root page is copied to another in
btr_root_raise_and_insert. Note that we leave lock structs on the
root page, even though they do not make sense on other than leaf
@@ -153,86 +152,86 @@ UNIV_INTERN
void
lock_update_root_raise(
/*===================*/
- const buf_block_t* block, /* in: index page to which copied */
- const buf_block_t* root); /* in: root page */
-/*****************************************************************
+ const buf_block_t* block, /*!< in: index page to which copied */
+ const buf_block_t* root); /*!< in: root page */
+/*************************************************************//**
Updates the lock table when a page is copied to another and the original page
is removed from the chain of leaf pages, except if page is the root! */
UNIV_INTERN
void
lock_update_copy_and_discard(
/*=========================*/
- const buf_block_t* new_block, /* in: index page to
+ const buf_block_t* new_block, /*!< in: index page to
which copied */
- const buf_block_t* block); /* in: index page;
+ const buf_block_t* block); /*!< in: index page;
NOT the root! */
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is split to the left. */
UNIV_INTERN
void
lock_update_split_left(
/*===================*/
- const buf_block_t* right_block, /* in: right page */
- const buf_block_t* left_block); /* in: left page */
-/*****************************************************************
+ const buf_block_t* right_block, /*!< in: right page */
+ const buf_block_t* left_block); /*!< in: left page */
+/*************************************************************//**
Updates the lock table when a page is merged to the left. */
UNIV_INTERN
void
lock_update_merge_left(
/*===================*/
- const buf_block_t* left_block, /* in: left page to
+ const buf_block_t* left_block, /*!< in: left page to
which merged */
- const rec_t* orig_pred, /* in: original predecessor
+ const rec_t* orig_pred, /*!< in: original predecessor
of supremum on the left page
before merge */
- const buf_block_t* right_block); /* in: merged index page
+ const buf_block_t* right_block); /*!< in: merged index page
which will be discarded */
-/*****************************************************************
+/*************************************************************//**
Resets the original locks on heir and replaces them with gap type locks
inherited from rec. */
UNIV_INTERN
void
lock_rec_reset_and_inherit_gap_locks(
/*=================================*/
- const buf_block_t* heir_block, /* in: block containing the
+ const buf_block_t* heir_block, /*!< in: block containing the
record which inherits */
- const buf_block_t* block, /* in: block containing the
+ const buf_block_t* block, /*!< in: block containing the
record from which inherited;
does NOT reset the locks on
this record */
- ulint heir_heap_no, /* in: heap_no of the
+ ulint heir_heap_no, /*!< in: heap_no of the
inheriting record */
- ulint heap_no); /* in: heap_no of the
+ ulint heap_no); /*!< in: heap_no of the
donating record */
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is discarded. */
UNIV_INTERN
void
lock_update_discard(
/*================*/
- const buf_block_t* heir_block, /* in: index page
+ const buf_block_t* heir_block, /*!< in: index page
which will inherit the locks */
- ulint heir_heap_no, /* in: heap_no of the record
+ ulint heir_heap_no, /*!< in: heap_no of the record
which will inherit the locks */
- const buf_block_t* block); /* in: index page
+ const buf_block_t* block); /*!< in: index page
which will be discarded */
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a new user record is inserted. */
UNIV_INTERN
void
lock_update_insert(
/*===============*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec); /* in: the inserted record */
-/*****************************************************************
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec); /*!< in: the inserted record */
+/*************************************************************//**
Updates the lock table when a record is removed. */
UNIV_INTERN
void
lock_update_delete(
/*===============*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec); /* in: the record to be removed */
-/*************************************************************************
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec); /*!< in: the record to be removed */
+/*********************************************************************//**
Stores on the page infimum record the explicit locks of another record.
This function is used to store the lock state of a record when it is
updated and the size of the record changes in the update. The record
@@ -243,159 +242,152 @@ UNIV_INTERN
void
lock_rec_store_on_page_infimum(
/*===========================*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec); /* in: record whose lock state
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec); /*!< in: record whose lock state
is stored on the infimum
record of the same page; lock
bits are reset on the
record */
-/*************************************************************************
+/*********************************************************************//**
Restores the state of explicit lock requests on a single record, where the
state was stored on the infimum of the page. */
UNIV_INTERN
void
lock_rec_restore_from_page_infimum(
/*===============================*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec, /* in: record whose lock state
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec, /*!< in: record whose lock state
is restored */
- const buf_block_t* donator);/* in: page (rec is not
+ const buf_block_t* donator);/*!< in: page (rec is not
necessarily on this page)
whose infimum stored the lock
state; lock bits are reset on
the infimum */
-/*************************************************************************
-Returns TRUE if there are explicit record locks on a page. */
+/*********************************************************************//**
+Returns TRUE if there are explicit record locks on a page.
+@return TRUE if there are explicit record locks on the page */
UNIV_INTERN
ibool
lock_rec_expl_exist_on_page(
/*========================*/
- /* out: TRUE if there are explicit record locks on
- the page */
- ulint space, /* in: space id */
- ulint page_no);/* in: page number */
-/*************************************************************************
+ ulint space, /*!< in: space id */
+ ulint page_no);/*!< in: page number */
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate insert of
a record. If they do, first tests 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 gap x-lock to the lock queue. */
+for a gap x-lock to the lock queue.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_rec_insert_check_and_lock(
/*===========================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is
set, does nothing */
- rec_t* rec, /* in: record after which to insert */
- buf_block_t* block, /* in/out: buffer block of rec */
- dict_index_t* index, /* in: index */
- que_thr_t* thr, /* in: query thread */
- ibool* inherit);/* out: set to TRUE if the new
+ const rec_t* rec, /*!< in: record after which to insert */
+ buf_block_t* block, /*!< in/out: buffer block of rec */
+ dict_index_t* index, /*!< in: index */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr, /*!< in/out: mini-transaction */
+ ibool* inherit);/*!< out: set to TRUE if the new
inserted record maybe should inherit
LOCK_GAP type locks from the successor
record */
-/*************************************************************************
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate modify (update,
delete mark, or delete unmark) of a clustered index record. If they do,
first tests 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 x-lock to the
-lock queue. */
+lock queue.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_clust_rec_modify_check_and_lock(
/*=================================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: record which should be
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: record which should be
modified */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ que_thr_t* thr); /*!< in: query thread */
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate modify
-(delete mark or delete unmark) of a secondary index record. */
+(delete mark or delete unmark) of a secondary index record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_sec_rec_modify_check_and_lock(
/*===============================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- buf_block_t* block, /* in/out: buffer block of rec */
- rec_t* rec, /* in: record which should be
+ buf_block_t* block, /*!< in/out: buffer block of rec */
+ const rec_t* rec, /*!< in: record which should be
modified; NOTE: as this is a secondary
index, we always have to modify the
clustered index record first: see the
comment below */
- dict_index_t* index, /* in: secondary index */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
+ dict_index_t* index, /*!< in: secondary index */
+ 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
-secondary index record. */
+secondary index record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_sec_rec_read_check_and_lock(
/*=============================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: user record or page
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: user record or page
supremum record which should
be read or passed over by a
read cursor */
- dict_index_t* index, /* in: secondary index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- enum lock_mode mode, /* in: mode of the lock which
+ dict_index_t* index, /*!< in: secondary index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ enum lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
latter is possible in
SELECT FOR UPDATE */
- ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate read, or passing
over by a read cursor, of a clustered index record. If they do, first tests
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. */
+lock on the record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_clust_rec_read_check_and_lock(
/*===============================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: user record or page
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: user record or page
supremum record which should
be read or passed over by a
read cursor */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- enum lock_mode mode, /* in: mode of the lock which
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ enum lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
latter is possible in
SELECT FOR UPDATE */
- ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate read, or passing
over by a read cursor, of a clustered index record. If they do, first tests
if the query thread should anyway be suspended for some reason; if not, then
@@ -403,89 +395,73 @@ 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. This is an alternative version of
lock_clust_rec_read_check_and_lock() that does not require the parameter
-"offsets". */
+"offsets".
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_clust_rec_read_check_and_lock_alt(
/*===================================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: user record or page
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: user record or page
supremum record which should
be read or passed over by a
read cursor */
- dict_index_t* index, /* in: clustered index */
- enum lock_mode mode, /* in: mode of the lock which
+ dict_index_t* index, /*!< in: clustered index */
+ enum lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
latter is possible in
SELECT FOR UPDATE */
- ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
-Checks that a record is seen in a consistent read. */
+ que_thr_t* thr); /*!< in: query thread */
+/*********************************************************************//**
+Checks that a record is seen in a consistent read.
+@return TRUE if sees, or FALSE if an earlier version of the record
+should be retrieved */
UNIV_INTERN
ibool
lock_clust_rec_cons_read_sees(
/*==========================*/
- /* out: TRUE if sees, or FALSE if an earlier
- version of the record should be retrieved */
- const rec_t* rec, /* in: user record which should be read or
+ const rec_t* rec, /*!< in: user record which should be read or
passed over by a read cursor */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- read_view_t* view); /* in: consistent read view */
-/*************************************************************************
-Checks that a non-clustered index record is seen in a consistent read. */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ read_view_t* view); /*!< in: consistent read view */
+/*********************************************************************//**
+Checks that a non-clustered index record is seen in a consistent read.
+
+NOTE that a non-clustered index page contains so little information on
+its modifications that also in the case FALSE, the present version of
+rec may be the right, but we must check this from the clustered index
+record.
+
+@return TRUE if certainly sees, or FALSE if an earlier version of the
+clustered index record might be needed */
UNIV_INTERN
ulint
lock_sec_rec_cons_read_sees(
/*========================*/
- /* out: TRUE if certainly
- sees, or FALSE if an earlier
- version of the clustered index
- record might be needed: NOTE
- that a non-clustered index
- page contains so little
- information on its
- modifications that also in the
- case FALSE, the present
- version of rec may be the
- right, but we must check this
- from the clustered index
- record */
- const rec_t* rec, /* in: user record which
+ const rec_t* rec, /*!< in: user record which
should be read or passed over
by a read cursor */
- const read_view_t* view); /* in: consistent read view */
-/*************************************************************************
+ const read_view_t* view); /*!< in: consistent read view */
+/*********************************************************************//**
Locks the specified database table in the mode given. If the lock cannot
-be granted immediately, the query thread is put to wait. */
+be granted immediately, the query thread is put to wait.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_table(
/*=======*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is set,
does nothing */
- dict_table_t* table, /* in: database table in dictionary cache */
- enum lock_mode mode, /* in: lock mode */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
-Checks if there are any locks set on the table. */
-UNIV_INTERN
-ibool
-lock_is_on_table(
-/*=============*/
- /* out: TRUE if there are lock(s) */
- dict_table_t* table); /* in: database table in dictionary cache */
-/*****************************************************************
+ dict_table_t* table, /*!< in: database table in dictionary cache */
+ enum lock_mode mode, /*!< in: lock mode */
+ que_thr_t* thr); /*!< in: query thread */
+/*************************************************************//**
Removes a granted record lock of a transaction from the queue and grants
locks to other transactions waiting in the queue if they now are entitled
to a lock. */
@@ -493,37 +469,29 @@ UNIV_INTERN
void
lock_rec_unlock(
/*============*/
- trx_t* trx, /* in: transaction that has
+ trx_t* trx, /*!< in: transaction that has
set a record lock */
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec, /* in: record */
- enum lock_mode lock_mode);/* in: LOCK_S or LOCK_X */
-/*************************************************************************
-Releases a table lock.
-Releases possible other transactions waiting for this lock. */
-UNIV_INTERN
-void
-lock_table_unlock(
-/*==============*/
- lock_t* lock); /* in: lock */
-/*************************************************************************
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec, /*!< in: record */
+ enum lock_mode lock_mode);/*!< in: LOCK_S or LOCK_X */
+/*********************************************************************//**
Releases transaction locks, and releases possible other transactions waiting
because of these locks. */
UNIV_INTERN
void
lock_release_off_kernel(
/*====================*/
- trx_t* trx); /* in: transaction */
-/*************************************************************************
+ trx_t* trx); /*!< in: transaction */
+/*********************************************************************//**
Cancels a waiting lock request and releases possible other transactions
waiting behind it. */
UNIV_INTERN
void
lock_cancel_waiting_and_release(
/*============================*/
- lock_t* lock); /* in: waiting lock request */
+ lock_t* lock); /*!< in: waiting lock request */
-/*************************************************************************
+/*********************************************************************//**
Removes locks on a table to be dropped or truncated.
If remove_also_table_sx_locks is TRUE then table-level S and X locks are
also removed in addition to other table-level and record-level locks.
@@ -532,128 +500,127 @@ UNIV_INTERN
void
lock_remove_all_on_table(
/*=====================*/
- dict_table_t* table, /* in: table to be dropped
+ dict_table_t* table, /*!< in: table to be dropped
or truncated */
- ibool remove_also_table_sx_locks);/* in: also removes
+ ibool remove_also_table_sx_locks);/*!< in: also removes
table S and X locks */
-/*************************************************************************
+/*********************************************************************//**
Calculates the fold value of a page file address: used in inserting or
-searching for a lock in the hash table. */
+searching for a lock in the hash table.
+@return folded value */
UNIV_INLINE
ulint
lock_rec_fold(
/*==========*/
- /* out: folded value */
- ulint space, /* in: space */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no)/*!< in: page number */
__attribute__((const));
-/*************************************************************************
+/*********************************************************************//**
Calculates the hash value of a page file address: used in inserting or
-searching for a lock in the hash table. */
+searching for a lock in the hash table.
+@return hashed value */
UNIV_INLINE
ulint
lock_rec_hash(
/*==========*/
- /* out: hashed value */
- ulint space, /* in: space */
- ulint page_no);/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no);/*!< in: page number */
-/**************************************************************************
+/**********************************************************************//**
Looks for a set bit in a record lock bitmap. Returns ULINT_UNDEFINED,
-if none found. */
+if none found.
+@return bit index == heap number of the record, or ULINT_UNDEFINED if
+none found */
UNIV_INTERN
ulint
lock_rec_find_set_bit(
/*==================*/
- /* out: bit index == heap number of
- the record, or ULINT_UNDEFINED if none found */
- const lock_t* lock); /* in: record lock with at least one bit set */
+ const lock_t* lock); /*!< in: record lock with at least one
+ bit set */
-/*************************************************************************
+/*********************************************************************//**
Gets the source table of an ALTER TABLE transaction. The table must be
-covered by an IX or IS table lock. */
+covered by an IX or IS table lock.
+@return the source table of transaction, if it is covered by an IX or
+IS table lock; dest if there is no source table, and NULL if the
+transaction is locking more than two tables or an inconsistency is
+found */
UNIV_INTERN
dict_table_t*
lock_get_src_table(
/*===============*/
- /* out: the source table of transaction,
- if it is covered by an IX or IS table lock;
- dest if there is no source table, and
- NULL if the transaction is locking more than
- two tables or an inconsistency is found */
- trx_t* trx, /* in: transaction */
- dict_table_t* dest, /* in: destination of ALTER TABLE */
- enum lock_mode* mode); /* out: lock mode of the source table */
-/*************************************************************************
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* dest, /*!< in: destination of ALTER TABLE */
+ enum lock_mode* mode); /*!< out: lock mode of the source table */
+/*********************************************************************//**
Determine if the given table is exclusively "owned" by the given
transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
-on the table. */
+on the table.
+@return TRUE if table is only locked by trx, with LOCK_IX, and
+possibly LOCK_AUTO_INC */
UNIV_INTERN
ibool
lock_is_table_exclusive(
/*====================*/
- /* out: TRUE if table is only locked by trx,
- with LOCK_IX, and possibly LOCK_AUTO_INC */
- dict_table_t* table, /* in: table */
- trx_t* trx); /* in: transaction */
-/*************************************************************************
-Checks if a lock request lock1 has to wait for request lock2. */
+ dict_table_t* table, /*!< in: table */
+ trx_t* trx); /*!< in: transaction */
+/*********************************************************************//**
+Checks if a lock request lock1 has to wait for request lock2.
+@return TRUE if lock1 has to wait for lock2 to be removed */
UNIV_INTERN
ibool
lock_has_to_wait(
/*=============*/
- /* out: TRUE if lock1 has to wait for
- lock2 to be removed */
- const lock_t* lock1, /* in: waiting lock */
- const lock_t* lock2); /* in: another lock; NOTE that it is
+ const lock_t* lock1, /*!< in: waiting lock */
+ const lock_t* lock2); /*!< in: another lock; NOTE that it is
assumed that this has a lock bit set
on the same record as in lock1 if the
locks are record locks */
-/*************************************************************************
-Checks that a transaction id is sensible, i.e., not in the future. */
+/*********************************************************************//**
+Checks that a transaction id is sensible, i.e., not in the future.
+@return TRUE if ok */
UNIV_INTERN
ibool
lock_check_trx_id_sanity(
/*=====================*/
- /* out: TRUE if ok */
- dulint trx_id, /* in: trx id */
- const rec_t* rec, /* in: user record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets, /* in: rec_get_offsets(rec, index) */
- ibool has_kernel_mutex);/* in: TRUE if the caller owns the
+ trx_id_t trx_id, /*!< in: trx id */
+ const rec_t* rec, /*!< in: user record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */
+ ibool has_kernel_mutex);/*!< in: TRUE if the caller owns the
kernel mutex */
-/*************************************************************************
+/*********************************************************************//**
Prints info of a table lock. */
UNIV_INTERN
void
lock_table_print(
/*=============*/
- FILE* file, /* in: file where to print */
- const lock_t* lock); /* in: table type lock */
-/*************************************************************************
+ FILE* file, /*!< in: file where to print */
+ const lock_t* lock); /*!< in: table type lock */
+/*********************************************************************//**
Prints info of a record lock. */
UNIV_INTERN
void
lock_rec_print(
/*===========*/
- FILE* file, /* in: file where to print */
- const lock_t* lock); /* in: record type lock */
-/*************************************************************************
+ FILE* file, /*!< in: file where to print */
+ const lock_t* lock); /*!< in: record type lock */
+/*********************************************************************//**
Prints info of locks for all transactions. */
UNIV_INTERN
void
lock_print_info_summary(
/*====================*/
- FILE* file); /* in: file where to print */
-/*************************************************************************
+ FILE* file); /*!< in: file where to print */
+/*********************************************************************//**
Prints info of locks for each transaction. */
UNIV_INTERN
void
lock_print_info_all_transactions(
/*=============================*/
- FILE* file); /* in: file where to print */
-/*************************************************************************
+ FILE* file); /*!< in: file where to print */
+/*********************************************************************//**
Return approximate number or record locks (bits set in the bitmap) for
this transaction. Since delete-marked records may be removed, the
record count will not be precise. */
@@ -661,137 +628,140 @@ UNIV_INTERN
ulint
lock_number_of_rows_locked(
/*=======================*/
- trx_t* trx); /* in: transaction */
-/***********************************************************************
+ trx_t* trx); /*!< in: transaction */
+/*******************************************************************//**
Release all the transaction's autoinc locks. */
UNIV_INTERN
void
lock_release_autoinc_locks(
/*=======================*/
- trx_t* trx); /* in/out: transaction */
+ trx_t* trx); /*!< in/out: transaction */
-/***********************************************************************
+/*******************************************************************//**
Gets the type of a lock. Non-inline version for using outside of the
-lock module. */
+lock module.
+@return LOCK_TABLE or LOCK_REC */
UNIV_INTERN
ulint
lock_get_type(
/*==========*/
- /* out: LOCK_TABLE or LOCK_REC */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
-Gets the id of the transaction owning a lock. */
+/*******************************************************************//**
+Gets the id of the transaction owning a lock.
+@return transaction id */
UNIV_INTERN
ullint
lock_get_trx_id(
/*============*/
- /* out: transaction id */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
+/*******************************************************************//**
Gets the mode of a lock in a human readable string.
-The string should not be free()'d or modified. */
-
+The string should not be free()'d or modified.
+@return lock mode */
+UNIV_INTERN
const char*
lock_get_mode_str(
/*==============*/
- /* out: lock mode */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
+/*******************************************************************//**
Gets the type of a lock in a human readable string.
-The string should not be free()'d or modified. */
-
+The string should not be free()'d or modified.
+@return lock type */
+UNIV_INTERN
const char*
lock_get_type_str(
/*==============*/
- /* out: lock type */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
-Gets the id of the table on which the lock is. */
+/*******************************************************************//**
+Gets the id of the table on which the lock is.
+@return id of the table */
UNIV_INTERN
ullint
lock_get_table_id(
/*==============*/
- /* out: id of the table */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
+/*******************************************************************//**
Gets the name of the table on which the lock is.
-The string should not be free()'d or modified. */
-
+The string should not be free()'d or modified.
+@return name of the table */
+UNIV_INTERN
const char*
lock_get_table_name(
/*================*/
- /* out: name of the table */
- const lock_t* lock); /* in: lock */
-
-/***********************************************************************
-For a record lock, gets the index on which the lock is. */
+ const lock_t* lock); /*!< in: lock */
+/*******************************************************************//**
+For a record lock, gets the index on which the lock is.
+@return index */
+UNIV_INTERN
const dict_index_t*
lock_rec_get_index(
/*===============*/
- /* out: index */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
+/*******************************************************************//**
For a record lock, gets the name of the index on which the lock is.
-The string should not be free()'d or modified. */
-
+The string should not be free()'d or modified.
+@return name of the index */
+UNIV_INTERN
const char*
lock_rec_get_index_name(
/*====================*/
- /* out: name of the index */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
-For a record lock, gets the tablespace number on which the lock is. */
+/*******************************************************************//**
+For a record lock, gets the tablespace number on which the lock is.
+@return tablespace number */
UNIV_INTERN
ulint
lock_rec_get_space_id(
/*==================*/
- /* out: tablespace number */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/***********************************************************************
-For a record lock, gets the page number on which the lock is. */
+/*******************************************************************//**
+For a record lock, gets the page number on which the lock is.
+@return page number */
UNIV_INTERN
ulint
lock_rec_get_page_no(
/*=================*/
- /* out: page number */
- const lock_t* lock); /* in: lock */
+ const lock_t* lock); /*!< in: lock */
-/* Lock modes and types */
-#define LOCK_MODE_MASK 0xFUL /* mask used to extract mode from the
+/** Lock modes and types */
+/* @{ */
+#define LOCK_MODE_MASK 0xFUL /*!< mask used to extract mode from the
type_mode field in a lock */
-/* Lock types */
-#define LOCK_TABLE 16 /* these type values should be so high that */
-#define LOCK_REC 32 /* they can be ORed to the lock mode */
-#define LOCK_TYPE_MASK 0xF0UL /* mask used to extract lock type from the
+/** Lock types */
+/* @{ */
+#define LOCK_TABLE 16 /*!< table lock */
+#define LOCK_REC 32 /*!< record lock */
+#define LOCK_TYPE_MASK 0xF0UL /*!< mask used to extract lock type from the
type_mode field in a lock */
-/* Waiting lock flag */
-#define LOCK_WAIT 256 /* this wait bit should be so high that
- it can be ORed to the lock mode and type;
- when this bit is set, it means that the
- lock has not yet been granted, it is just
- waiting for its turn in the wait queue */
+#if LOCK_MODE_MASK & LOCK_TYPE_MASK
+# error "LOCK_MODE_MASK & LOCK_TYPE_MASK"
+#endif
+
+#define LOCK_WAIT 256 /*!< Waiting lock flag; when set, it
+ means that the lock has not yet been
+ granted, it is just waiting for its
+ turn in the wait queue */
/* Precise modes */
-#define LOCK_ORDINARY 0 /* this flag denotes an ordinary next-key lock
- in contrast to LOCK_GAP or LOCK_REC_NOT_GAP */
-#define LOCK_GAP 512 /* this gap bit should be so high that
- it can be ORed to the other flags;
- when this bit is set, it means that the
+#define LOCK_ORDINARY 0 /*!< this flag denotes an ordinary
+ next-key lock in contrast to LOCK_GAP
+ or LOCK_REC_NOT_GAP */
+#define LOCK_GAP 512 /*!< when this bit is set, it means that the
lock holds only on the gap before the record;
for instance, an x-lock on the gap does not
give permission to modify the record on which
the bit is set; locks of this type are created
when records are removed from the index chain
of records */
-#define LOCK_REC_NOT_GAP 1024 /* this bit means that the lock is only on
+#define LOCK_REC_NOT_GAP 1024 /*!< this bit means that the lock is only on
the index record and does NOT block inserts
to the gap before the index record; this is
used in the case when we retrieve a record
@@ -799,7 +769,7 @@ lock_rec_get_page_no(
locking plain SELECTs (not part of UPDATE
or DELETE) when the user has set the READ
COMMITTED isolation level */
-#define LOCK_INSERT_INTENTION 2048 /* this bit is set when we place a waiting
+#define LOCK_INSERT_INTENTION 2048 /*!< this bit is set when we place a waiting
gap type record lock request in order to let
an insert of an index record to wait until
there are no conflicting locks by other
@@ -807,27 +777,28 @@ lock_rec_get_page_no(
remains set when the waiting lock is granted,
or if the lock is inherited to a neighboring
record */
+#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_MODE_MASK
+# error
+#endif
+#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_TYPE_MASK
+# error
+#endif
+/* @} */
-/* When lock bits are reset, the following flags are available: */
-#define LOCK_RELEASE_WAIT 1
-#define LOCK_NOT_RELEASE_WAIT 2
-
-/* Lock operation struct */
+/** Lock operation struct */
typedef struct lock_op_struct lock_op_t;
+/** Lock operation struct */
struct lock_op_struct{
- dict_table_t* table; /* table to be locked */
- enum lock_mode mode; /* lock mode */
+ dict_table_t* table; /*!< table to be locked */
+ enum lock_mode mode; /*!< lock mode */
};
-#define LOCK_OP_START 1
-#define LOCK_OP_COMPLETE 2
-
-/* The lock system struct */
+/** The lock system struct */
struct lock_sys_struct{
- hash_table_t* rec_hash; /* hash table of the record locks */
+ hash_table_t* rec_hash; /*!< hash table of the record locks */
};
-/* The lock system */
+/** The lock system */
extern lock_sys_t* lock_sys;
diff --git a/storage/xtradb/include/lock0lock.ic b/storage/xtradb/include/lock0lock.ic
index f978cc70678..014722f51c4 100644
--- a/storage/xtradb/include/lock0lock.ic
+++ b/storage/xtradb/include/lock0lock.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/lock0lock.ic
The transaction lock system
Created 5/7/1996 Heikki Tuuri
@@ -37,49 +38,48 @@ Created 5/7/1996 Heikki Tuuri
#include "read0read.h"
#include "log0recv.h"
-/*************************************************************************
+/*********************************************************************//**
Calculates the fold value of a page file address: used in inserting or
-searching for a lock in the hash table. */
+searching for a lock in the hash table.
+@return folded value */
UNIV_INLINE
ulint
lock_rec_fold(
/*==========*/
- /* out: folded value */
- ulint space, /* in: space */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no)/*!< in: page number */
{
return(ut_fold_ulint_pair(space, page_no));
}
-/*************************************************************************
+/*********************************************************************//**
Calculates the hash value of a page file address: used in inserting or
-searching for a lock in the hash table. */
+searching for a lock in the hash table.
+@return hashed value */
UNIV_INLINE
ulint
lock_rec_hash(
/*==========*/
- /* out: hashed value */
- ulint space, /* in: space */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no)/*!< in: page number */
{
return(hash_calc_hash(lock_rec_fold(space, page_no),
lock_sys->rec_hash));
}
-/*************************************************************************
+/*********************************************************************//**
Checks if some transaction has an implicit x-lock on a record in a clustered
-index. */
+index.
+@return transaction which has the x-lock, or NULL */
UNIV_INLINE
trx_t*
lock_clust_rec_some_has_impl(
/*=========================*/
- /* out: transaction which has the x-lock, or
- NULL */
- const rec_t* rec, /* in: user record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ const rec_t* rec, /*!< in: user record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
- dulint trx_id;
+ trx_id_t trx_id;
ut_ad(mutex_own(&kernel_mutex));
ut_ad(dict_index_is_clust(index));
@@ -96,16 +96,14 @@ lock_clust_rec_some_has_impl(
return(NULL);
}
-/*************************************************************************
-Gets the heap_no of the smallest user record on a page. */
+/*********************************************************************//**
+Gets the heap_no of the smallest user record on a page.
+@return heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM */
UNIV_INLINE
ulint
lock_get_min_heap_no(
/*=================*/
- /* out: heap_no of smallest
- user record, or
- PAGE_HEAP_NO_SUPREMUM */
- const buf_block_t* block) /* in: buffer block */
+ const buf_block_t* block) /*!< in: buffer block */
{
const page_t* page = block->frame;
diff --git a/storage/xtradb/include/lock0priv.h b/storage/xtradb/include/lock0priv.h
index 0a0d41e6aaa..287c151b19f 100644
--- a/storage/xtradb/include/lock0priv.h
+++ b/storage/xtradb/include/lock0priv.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/lock0priv.h
Lock module internal structures and methods.
Created July 12, 2007 Vasil Dimov
@@ -38,66 +39,67 @@ those functions in lock/ */
#include "trx0types.h"
#include "ut0lst.h"
-/* A table lock */
+/** A table lock */
typedef struct lock_table_struct lock_table_t;
+/** A table lock */
struct lock_table_struct {
- dict_table_t* table; /* database table in dictionary
+ dict_table_t* table; /*!< database table in dictionary
cache */
UT_LIST_NODE_T(lock_t)
- locks; /* list of locks on the same
+ locks; /*!< list of locks on the same
table */
};
-/* Record lock for a page */
+/** Record lock for a page */
typedef struct lock_rec_struct lock_rec_t;
+/** Record lock for a page */
struct lock_rec_struct {
- ulint space; /* space id */
- ulint page_no; /* page number */
- ulint n_bits; /* number of bits in the lock
+ ulint space; /*!< space id */
+ ulint page_no; /*!< page number */
+ ulint n_bits; /*!< number of bits in the lock
bitmap; NOTE: the lock bitmap is
placed immediately after the
lock struct */
};
-/* Lock struct */
+/** Lock struct */
struct lock_struct {
- trx_t* trx; /* transaction owning the
+ trx_t* trx; /*!< transaction owning the
lock */
UT_LIST_NODE_T(lock_t)
- trx_locks; /* list of the locks of the
+ trx_locks; /*!< list of the locks of the
transaction */
- ulint type_mode; /* lock type, mode, LOCK_GAP or
+ ulint type_mode; /*!< lock type, mode, LOCK_GAP or
LOCK_REC_NOT_GAP,
LOCK_INSERT_INTENTION,
wait flag, ORed */
- hash_node_t hash; /* hash chain node for a record
+ hash_node_t hash; /*!< hash chain node for a record
lock */
- dict_index_t* index; /* index for a record lock */
+ dict_index_t* index; /*!< index for a record lock */
union {
- lock_table_t tab_lock;/* table lock */
- lock_rec_t rec_lock;/* record lock */
- } un_member;
+ lock_table_t tab_lock;/*!< table lock */
+ lock_rec_t rec_lock;/*!< record lock */
+ } un_member; /*!< lock details */
};
-/*************************************************************************
-Gets the type of a lock. */
+/*********************************************************************//**
+Gets the type of a lock.
+@return LOCK_TABLE or LOCK_REC */
UNIV_INLINE
ulint
lock_get_type_low(
/*==============*/
- /* out: LOCK_TABLE or LOCK_REC */
- const lock_t* lock); /* in: lock */
-
-/*************************************************************************
-Gets the previous record lock set on a record. */
+ const lock_t* lock); /*!< in: lock */
+/*********************************************************************//**
+Gets the previous record lock set on a record.
+@return previous lock on the same record, NULL if none exists */
+UNIV_INTERN
const lock_t*
lock_rec_get_prev(
/*==============*/
- /* out: previous lock on the same
- record, NULL if none exists */
- const lock_t* in_lock,/* in: record lock */
- ulint heap_no);/* in: heap number of the record */
+ const lock_t* in_lock,/*!< in: record lock */
+ ulint heap_no);/*!< in: heap number of the record */
#ifndef UNIV_NONINL
#include "lock0priv.ic"
diff --git a/storage/xtradb/include/lock0priv.ic b/storage/xtradb/include/lock0priv.ic
index ae633a4fc61..30447c99848 100644
--- a/storage/xtradb/include/lock0priv.ic
+++ b/storage/xtradb/include/lock0priv.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/lock0priv.ic
Lock module internal inline methods.
Created July 16, 2007 Vasil Dimov
@@ -31,14 +32,14 @@ methods but they are used only in that file. */
#error Do not include lock0priv.ic outside of the lock/ module
#endif
-/*************************************************************************
-Gets the type of a lock. */
+/*********************************************************************//**
+Gets the type of a lock.
+@return LOCK_TABLE or LOCK_REC */
UNIV_INLINE
ulint
lock_get_type_low(
/*==============*/
- /* out: LOCK_TABLE or LOCK_REC */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ut_ad(lock);
diff --git a/storage/xtradb/include/lock0types.h b/storage/xtradb/include/lock0types.h
index 52631b56532..45f29e90fe9 100644
--- a/storage/xtradb/include/lock0types.h
+++ b/storage/xtradb/include/lock0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/lock0types.h
The transaction lock system global types
Created 5/7/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/log0log.h b/storage/xtradb/include/log0log.h
index 2aaf74b4190..059f548a085 100644
--- a/storage/xtradb/include/log0log.h
+++ b/storage/xtradb/include/log0log.h
@@ -15,8 +15,33 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/*****************************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Google Inc.
-/******************************************************
+Portions of this file contain modifications contributed and copyrighted by
+Google, Inc. Those modifications are gratefully acknowledged and are described
+briefly in the InnoDB documentation. The contributions by Google are
+incorporated with their permission, and subject to the conditions contained in
+the file COPYING.Google.
+
+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
+
+*****************************************************************************/
+
+/**************************************************//**
+@file include/log0log.h
Database log
Created 12/9/1995 Heikki Tuuri
@@ -27,26 +52,37 @@ Created 12/9/1995 Heikki Tuuri
#include "univ.i"
#include "ut0byte.h"
+#include "ut0lst.h"
+#ifndef UNIV_HOTBACKUP
#include "sync0sync.h"
#include "sync0rw.h"
+#endif /* !UNIV_HOTBACKUP */
+/** Redo log buffer */
typedef struct log_struct log_t;
+/** Redo log group */
typedef struct log_group_struct log_group_t;
#ifdef UNIV_DEBUG
+/** Flag: write to log file? */
extern ibool log_do_write;
+/** Flag: enable debug output when writing to the log? */
extern ibool log_debug_writes;
#else /* UNIV_DEBUG */
+/** Write to log */
# define log_do_write TRUE
#endif /* UNIV_DEBUG */
-/* Wait modes for log_write_up_to */
+/** Wait modes for log_write_up_to @{ */
#define LOG_NO_WAIT 91
#define LOG_WAIT_ONE_GROUP 92
#define LOG_WAIT_ALL_GROUPS 93
+/* @} */
+/** Maximum number of log groups in log_group_struct::checkpoint_buf */
#define LOG_MAX_N_GROUPS 32
-/********************************************************************
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
Sets the global variable log_fsp_current_free_limit. Also makes a checkpoint,
so that we know that the limit has been written to a log checkpoint field
on disk. */
@@ -54,44 +90,45 @@ UNIV_INTERN
void
log_fsp_current_free_limit_set_and_checkpoint(
/*==========================================*/
- ulint limit); /* in: limit to set */
-/***********************************************************************
-Calculates where in log files we find a specified lsn. */
+ ulint limit); /*!< in: limit to set */
+#endif /* !UNIV_HOTBACKUP */
+/*******************************************************************//**
+Calculates where in log files we find a specified lsn.
+@return log file number */
UNIV_INTERN
ulint
log_calc_where_lsn_is(
/*==================*/
- /* out: log file number */
- ib_int64_t* log_file_offset, /* out: offset in that file
+ ib_int64_t* log_file_offset, /*!< out: offset in that file
(including the header) */
- ib_uint64_t first_header_lsn, /* in: first log file start
+ ib_uint64_t first_header_lsn, /*!< in: first log file start
lsn */
- ib_uint64_t lsn, /* in: lsn whose position to
+ ib_uint64_t lsn, /*!< in: lsn whose position to
determine */
- ulint n_log_files, /* in: total number of log
+ ulint n_log_files, /*!< in: total number of log
files */
- ib_int64_t log_file_size); /* in: log file size
+ ib_int64_t log_file_size); /*!< in: log file size
(including the header) */
-/****************************************************************
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
Writes to the log the string given. The log must be released with
-log_release. */
+log_release.
+@return end lsn of the log record, zero if did not succeed */
UNIV_INLINE
ib_uint64_t
log_reserve_and_write_fast(
/*=======================*/
- /* out: end lsn of the log record,
- zero if did not succeed */
- byte* str, /* in: string */
- ulint len, /* in: string length */
- ib_uint64_t* start_lsn,/* out: start lsn of the log record */
- ibool* success);/* out: TRUE if success */
-/***************************************************************************
+ byte* str, /*!< in: string */
+ ulint len, /*!< in: string length */
+ ib_uint64_t* start_lsn,/*!< out: start lsn of the log record */
+ ibool* success);/*!< out: TRUE if success */
+/***********************************************************************//**
Releases the log mutex. */
UNIV_INLINE
void
log_release(void);
/*=============*/
-/***************************************************************************
+/***********************************************************************//**
Checks if there is need for a log buffer flush or a new checkpoint, and does
this if yes. Any database operation should call this when it has modified
more than about 4 pages. NOTE that this function may only be called when the
@@ -100,69 +137,77 @@ UNIV_INLINE
void
log_free_check(void);
/*================*/
-/****************************************************************
+/************************************************************//**
Opens the log for log_write_low. The log must be closed with log_close and
-released with log_release. */
+released with log_release.
+@return start lsn of the log record */
UNIV_INTERN
ib_uint64_t
log_reserve_and_open(
/*=================*/
- /* out: start lsn of the log record */
- ulint len); /* in: length of data to be catenated */
-/****************************************************************
+ ulint len); /*!< in: length of data to be catenated */
+/************************************************************//**
Writes to the log the string given. It is assumed that the caller holds the
log mutex. */
UNIV_INTERN
void
log_write_low(
/*==========*/
- byte* str, /* in: string */
- ulint str_len); /* in: string length */
-/****************************************************************
-Closes the log. */
+ byte* str, /*!< in: string */
+ ulint str_len); /*!< in: string length */
+/************************************************************//**
+Closes the log.
+@return lsn */
UNIV_INTERN
ib_uint64_t
log_close(void);
/*===========*/
- /* out: lsn */
-/****************************************************************
-Gets the current lsn. */
+/************************************************************//**
+Gets the current lsn.
+@return current lsn */
UNIV_INLINE
ib_uint64_t
log_get_lsn(void);
/*=============*/
- /* out: current lsn */
-/**********************************************************
+/****************************************************************
+Gets the log group capacity. It is OK to read the value without
+holding log_sys->mutex because it is constant.
+@return log group capacity */
+UNIV_INLINE
+ulint
+log_get_capacity(void);
+/*==================*/
+/******************************************************//**
Initializes the log. */
UNIV_INTERN
void
log_init(void);
/*==========*/
-/**********************************************************************
+/******************************************************************//**
Inits a log group to the log system. */
UNIV_INTERN
void
log_group_init(
/*===========*/
- ulint id, /* in: group id */
- ulint n_files, /* in: number of log files */
- ulint file_size, /* in: log file size in bytes */
- ulint space_id, /* in: space id of the file space
+ ulint id, /*!< in: group id */
+ ulint n_files, /*!< in: number of log files */
+ ulint file_size, /*!< in: log file size in bytes */
+ ulint space_id, /*!< in: space id of the file space
which contains the log files of this
group */
- ulint archive_space_id); /* in: space id of the file space
+ ulint archive_space_id); /*!< in: space id of the file space
which contains some archived log
files for this group; currently, only
for the first log group this is
used */
-/**********************************************************
+/******************************************************//**
Completes an i/o to a log file. */
UNIV_INTERN
void
log_io_complete(
/*============*/
- log_group_t* group); /* in: log group */
-/**********************************************************
+ log_group_t* group); /*!< in: log group */
+/******************************************************//**
This function is called, e.g., when a transaction wants to commit. It checks
that the log has been written to the log file up to the last log entry written
by the transaction. If there is a flush running, it waits and checks if the
@@ -171,81 +216,80 @@ UNIV_INTERN
void
log_write_up_to(
/*============*/
- ib_uint64_t lsn, /* in: log sequence number up to which
+ ib_uint64_t lsn, /*!< in: log sequence number up to which
the log should be written,
IB_ULONGLONG_MAX if not specified */
- ulint wait, /* in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
+ ulint wait, /*!< in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
or LOG_WAIT_ALL_GROUPS */
ibool flush_to_disk);
- /* in: TRUE if we want the written log
+ /*!< in: TRUE if we want the written log
also to be flushed to disk */
-/********************************************************************
+/****************************************************************//**
Does a syncronous flush of the log buffer to disk. */
UNIV_INTERN
void
log_buffer_flush_to_disk(void);
/*==========================*/
-/********************************************************************
-Flushes the log buffer. Forces it to disk depending on the value of
-the configuration parameter innodb_flush_log_at_trx_commit. */
+/****************************************************************//**
+This functions writes the log buffer to the log file and if 'flush'
+is set it forces a flush of the log file as well. This is meant to be
+called from background master thread only as it does not wait for
+the write (+ possible flush) to finish. */
UNIV_INTERN
void
-log_buffer_flush_maybe_sync(void);
-/*=============================*/
-/********************************************************************
+log_buffer_sync_in_background(
+/*==========================*/
+ ibool flush); /*<! in: flush the logs to disk */
+/****************************************************************//**
Advances the smallest lsn for which there are unflushed dirty blocks in the
buffer pool and also may make a new checkpoint. NOTE: this function may only
-be called if the calling thread owns no synchronization objects! */
+be called if the calling thread owns no synchronization objects!
+@return FALSE if there was a flush batch of the same type running,
+which means that we could not start this flush batch */
UNIV_INTERN
ibool
log_preflush_pool_modified_pages(
/*=============================*/
- /* out: FALSE if there was a
- flush batch of the same type
- running, which means that we
- could not start this flush
- batch */
- ib_uint64_t new_oldest, /* in: try to advance
+ ib_uint64_t new_oldest, /*!< in: try to advance
oldest_modified_lsn at least
to this lsn */
- ibool sync); /* in: TRUE if synchronous
+ ibool sync); /*!< in: TRUE if synchronous
operation is desired */
-/**********************************************************
+/******************************************************//**
Makes a checkpoint. Note that this function does not flush dirty
blocks from the buffer pool: it only checks what is lsn of the oldest
modification in the pool, and writes information about the lsn in
-log files. Use log_make_checkpoint_at to flush also the pool. */
+log files. Use log_make_checkpoint_at to flush also the pool.
+@return TRUE if success, FALSE if a checkpoint write was already running */
UNIV_INTERN
ibool
log_checkpoint(
/*===========*/
- /* out: TRUE if success, FALSE if a checkpoint
- write was already running */
- ibool sync, /* in: TRUE if synchronous operation is
+ ibool sync, /*!< in: TRUE if synchronous operation is
desired */
- ibool write_always); /* in: the function normally checks if the
+ ibool write_always); /*!< in: the function normally checks if the
the new checkpoint would have a greater
lsn than the previous one: if not, then no
physical write is done; by setting this
parameter TRUE, a physical write will always be
made to log files */
-/********************************************************************
+/****************************************************************//**
Makes a checkpoint at a given lsn or later. */
UNIV_INTERN
void
log_make_checkpoint_at(
/*===================*/
- ib_uint64_t lsn, /* in: make a checkpoint at this or a
+ ib_uint64_t lsn, /*!< in: make a checkpoint at this or a
later lsn, if IB_ULONGLONG_MAX, makes
a checkpoint at the latest lsn */
- ibool write_always); /* in: the function normally checks if
+ ibool write_always); /*!< in: the function normally checks if
the the new checkpoint would have a
greater lsn than the previous one: if
not, then no physical write is done;
by setting this parameter TRUE, a
physical write will always be made to
log files */
-/********************************************************************
+/****************************************************************//**
Makes a checkpoint at the latest lsn and writes it to first page of each
data file in the database, so that we know that the file spaces contain
all modifications up to that lsn. This can only be called at database
@@ -254,97 +298,96 @@ UNIV_INTERN
void
logs_empty_and_mark_files_at_shutdown(void);
/*=======================================*/
-/**********************************************************
+/******************************************************//**
Reads a checkpoint info from a log group header to log_sys->checkpoint_buf. */
UNIV_INTERN
void
log_group_read_checkpoint_info(
/*===========================*/
- log_group_t* group, /* in: log group */
- ulint field); /* in: LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2 */
-/***********************************************************************
+ log_group_t* group, /*!< in: log group */
+ ulint field); /*!< in: LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2 */
+/*******************************************************************//**
Gets info from a checkpoint about a log group. */
UNIV_INTERN
void
log_checkpoint_get_nth_group_info(
/*==============================*/
- byte* buf, /* in: buffer containing checkpoint info */
- ulint n, /* in: nth slot */
- ulint* file_no,/* out: archived file number */
- ulint* offset);/* out: archived file offset */
-/**********************************************************
+ const byte* buf, /*!< in: buffer containing checkpoint info */
+ ulint n, /*!< in: nth slot */
+ ulint* file_no,/*!< out: archived file number */
+ ulint* offset);/*!< out: archived file offset */
+/******************************************************//**
Writes checkpoint info to groups. */
UNIV_INTERN
void
log_groups_write_checkpoint_info(void);
/*==================================*/
-#ifdef UNIV_HOTBACKUP
-/**********************************************************
-Writes info to a buffer of a log group when log files are created in
-backup restoration. */
-UNIV_INTERN
-void
-log_reset_first_header_and_checkpoint(
-/*==================================*/
- byte* hdr_buf,/* in: buffer which will be written to the
- start of the first log file */
- ib_uint64_t start); /* in: lsn of the start of the first log file;
- we pretend that there is a checkpoint at
- start + LOG_BLOCK_HDR_SIZE */
-#endif /* UNIV_HOTBACKUP */
-/************************************************************************
-Starts an archiving operation. */
+/********************************************************************//**
+Starts an archiving operation.
+@return TRUE if succeed, FALSE if an archiving operation was already running */
UNIV_INTERN
ibool
log_archive_do(
/*===========*/
- /* out: TRUE if succeed, FALSE if an archiving
- operation was already running */
- ibool sync, /* in: TRUE if synchronous operation is desired */
- ulint* n_bytes);/* out: archive log buffer size, 0 if nothing to
+ ibool sync, /*!< in: TRUE if synchronous operation is desired */
+ ulint* n_bytes);/*!< out: archive log buffer size, 0 if nothing to
archive */
-/********************************************************************
+/****************************************************************//**
Writes the log contents to the archive up to the lsn when this function was
called, and stops the archiving. When archiving is started again, the archived
log file numbers start from a number one higher, so that the archiving will
not write again to the archived log files which exist when this function
-returns. */
+returns.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_stop(void);
/*==================*/
- /* out: DB_SUCCESS or DB_ERROR */
-/********************************************************************
-Starts again archiving which has been stopped. */
+/****************************************************************//**
+Starts again archiving which has been stopped.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_start(void);
/*===================*/
- /* out: DB_SUCCESS or DB_ERROR */
-/********************************************************************
-Stop archiving the log so that a gap may occur in the archived log files. */
+/****************************************************************//**
+Stop archiving the log so that a gap may occur in the archived log files.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_noarchivelog(void);
/*==========================*/
- /* out: DB_SUCCESS or DB_ERROR */
-/********************************************************************
-Start archiving the log so that a gap may occur in the archived log files. */
+/****************************************************************//**
+Start archiving the log so that a gap may occur in the archived log files.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_archivelog(void);
/*========================*/
- /* out: DB_SUCCESS or DB_ERROR */
-/**********************************************************
+/******************************************************//**
Generates an archived log file name. */
UNIV_INTERN
void
log_archived_file_name_gen(
/*=======================*/
- char* buf, /* in: buffer where to write */
- ulint id, /* in: group id */
- ulint file_no);/* in: file number */
-/************************************************************************
+ char* buf, /*!< in: buffer where to write */
+ ulint id, /*!< in: group id */
+ ulint file_no);/*!< in: file number */
+#else /* !UNIV_HOTBACKUP */
+/******************************************************//**
+Writes info to a buffer of a log group when log files are created in
+backup restoration. */
+UNIV_INTERN
+void
+log_reset_first_header_and_checkpoint(
+/*==================================*/
+ byte* hdr_buf,/*!< in: buffer which will be written to the
+ start of the first log file */
+ ib_uint64_t start); /*!< in: lsn of the start of the first log file;
+ we pretend that there is a checkpoint at
+ start + LOG_BLOCK_HDR_SIZE */
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************************//**
Checks that there is enough free space in the log to start a new query step.
Flushes the log buffer or makes a new checkpoint if necessary. NOTE: this
function may only be called if the calling thread owns no synchronization
@@ -353,35 +396,36 @@ UNIV_INTERN
void
log_check_margins(void);
/*===================*/
-/**********************************************************
+#ifndef UNIV_HOTBACKUP
+/******************************************************//**
Reads a specified log segment to a buffer. */
UNIV_INTERN
void
log_group_read_log_seg(
/*===================*/
- ulint type, /* in: LOG_ARCHIVE or LOG_RECOVER */
- byte* buf, /* in: buffer where to read */
- log_group_t* group, /* in: log group */
- ib_uint64_t start_lsn, /* in: read area start */
- ib_uint64_t end_lsn); /* in: read area end */
-/**********************************************************
+ ulint type, /*!< in: LOG_ARCHIVE or LOG_RECOVER */
+ byte* buf, /*!< in: buffer where to read */
+ log_group_t* group, /*!< in: log group */
+ ib_uint64_t start_lsn, /*!< in: read area start */
+ ib_uint64_t end_lsn); /*!< in: read area end */
+/******************************************************//**
Writes a buffer to a log file group. */
UNIV_INTERN
void
log_group_write_buf(
/*================*/
- log_group_t* group, /* in: log group */
- byte* buf, /* in: buffer */
- ulint len, /* in: buffer len; must be divisible
+ log_group_t* group, /*!< in: log group */
+ byte* buf, /*!< in: buffer */
+ ulint len, /*!< in: buffer len; must be divisible
by OS_FILE_LOG_BLOCK_SIZE */
- ib_uint64_t start_lsn, /* in: start lsn of the buffer; must
+ ib_uint64_t start_lsn, /*!< in: start lsn of the buffer; must
be divisible by
OS_FILE_LOG_BLOCK_SIZE */
- ulint new_data_offset);/* in: start offset of new data in
+ ulint new_data_offset);/*!< in: start offset of new data in
buf: this parameter is used to decide
if we have to write a new log file
header */
-/************************************************************
+/********************************************************//**
Sets the field values in group to correspond to a given lsn. For this function
to work, the values must already be correctly initialized to correspond to
some lsn, for instance, a checkpoint lsn. */
@@ -389,145 +433,141 @@ UNIV_INTERN
void
log_group_set_fields(
/*=================*/
- log_group_t* group, /* in: group */
- ib_uint64_t lsn); /* in: lsn for which the values should be
+ log_group_t* group, /*!< in/out: group */
+ ib_uint64_t lsn); /*!< in: lsn for which the values should be
set */
-/**********************************************************
+/******************************************************//**
Calculates the data capacity of a log group, when the log file headers are not
-included. */
+included.
+@return capacity in bytes */
UNIV_INTERN
ulint
log_group_get_capacity(
/*===================*/
- /* out: capacity in bytes */
- log_group_t* group); /* in: log group */
-/****************************************************************
-Gets a log block flush bit. */
+ const log_group_t* group); /*!< in: log group */
+#endif /* !UNIV_HOTBACKUP */
+/************************************************************//**
+Gets a log block flush bit.
+@return TRUE if this block was the first to be written in a log flush */
UNIV_INLINE
ibool
log_block_get_flush_bit(
/*====================*/
- /* out: TRUE if this block was the first
- to be written in a log flush */
- byte* log_block); /* in: log block */
-/****************************************************************
-Gets a log block number stored in the header. */
+ const byte* log_block); /*!< in: log block */
+/************************************************************//**
+Gets a log block number stored in the header.
+@return log block number stored in the block header */
UNIV_INLINE
ulint
log_block_get_hdr_no(
/*=================*/
- /* out: log block number stored in the block
- header */
- byte* log_block); /* in: log block */
-/****************************************************************
-Gets a log block data length. */
+ const byte* log_block); /*!< in: log block */
+/************************************************************//**
+Gets a log block data length.
+@return log block data length measured as a byte offset from the block start */
UNIV_INLINE
ulint
log_block_get_data_len(
/*===================*/
- /* out: log block data length measured as a
- byte offset from the block start */
- byte* log_block); /* in: log block */
-/****************************************************************
+ const byte* log_block); /*!< in: log block */
+/************************************************************//**
Sets the log block data length. */
UNIV_INLINE
void
log_block_set_data_len(
/*===================*/
- byte* log_block, /* in: log block */
- ulint len); /* in: data length */
-/****************************************************************
-Calculates the checksum for a log block. */
+ byte* log_block, /*!< in/out: log block */
+ ulint len); /*!< in: data length */
+/************************************************************//**
+Calculates the checksum for a log block.
+@return checksum */
UNIV_INLINE
ulint
log_block_calc_checksum(
/*====================*/
- /* out: checksum */
- const byte* block); /* in: log block */
-/****************************************************************
-Gets a log block checksum field value. */
+ const byte* block); /*!< in: log block */
+/************************************************************//**
+Gets a log block checksum field value.
+@return checksum */
UNIV_INLINE
ulint
log_block_get_checksum(
/*===================*/
- /* out: checksum */
- const byte* log_block); /* in: log block */
-/****************************************************************
+ const byte* log_block); /*!< in: log block */
+/************************************************************//**
Sets a log block checksum field value. */
UNIV_INLINE
void
log_block_set_checksum(
/*===================*/
- byte* log_block, /* in: log block */
- ulint checksum); /* in: checksum */
-/****************************************************************
-Gets a log block first mtr log record group offset. */
+ byte* log_block, /*!< in/out: log block */
+ ulint checksum); /*!< in: checksum */
+/************************************************************//**
+Gets a log block first mtr log record group offset.
+@return first mtr log record group byte offset from the block start, 0
+if none */
UNIV_INLINE
ulint
log_block_get_first_rec_group(
/*==========================*/
- /* out: first mtr log record group byte offset
- from the block start, 0 if none */
- byte* log_block); /* in: log block */
-/****************************************************************
+ const byte* log_block); /*!< in: log block */
+/************************************************************//**
Sets the log block first mtr log record group offset. */
UNIV_INLINE
void
log_block_set_first_rec_group(
/*==========================*/
- byte* log_block, /* in: log block */
- ulint offset); /* in: offset, 0 if none */
-/****************************************************************
-Gets a log block checkpoint number field (4 lowest bytes). */
+ byte* log_block, /*!< in/out: log block */
+ ulint offset); /*!< in: offset, 0 if none */
+/************************************************************//**
+Gets a log block checkpoint number field (4 lowest bytes).
+@return checkpoint no (4 lowest bytes) */
UNIV_INLINE
ulint
log_block_get_checkpoint_no(
/*========================*/
- /* out: checkpoint no (4 lowest bytes) */
- byte* log_block); /* in: log block */
-/****************************************************************
+ const byte* log_block); /*!< in: log block */
+/************************************************************//**
Initializes a log block in the log buffer. */
UNIV_INLINE
void
log_block_init(
/*===========*/
- byte* log_block, /* in: pointer to the log buffer */
- ib_uint64_t lsn); /* in: lsn within the log block */
-/****************************************************************
+ byte* log_block, /*!< in: pointer to the log buffer */
+ ib_uint64_t lsn); /*!< in: lsn within the log block */
+/************************************************************//**
Initializes a log block in the log buffer in the old, < 3.23.52 format, where
there was no checksum yet. */
UNIV_INLINE
void
log_block_init_in_old_format(
/*=========================*/
- byte* log_block, /* in: pointer to the log buffer */
- ib_uint64_t lsn); /* in: lsn within the log block */
-/****************************************************************
-Converts a lsn to a log block number. */
+ byte* log_block, /*!< in: pointer to the log buffer */
+ ib_uint64_t lsn); /*!< in: lsn within the log block */
+/************************************************************//**
+Converts a lsn to a log block number.
+@return log block number, it is > 0 and <= 1G */
UNIV_INLINE
ulint
log_block_convert_lsn_to_no(
/*========================*/
- /* out: log block number,
- it is > 0 and <= 1G */
- ib_uint64_t lsn); /* in: lsn of a byte within the block */
-/**********************************************************
+ ib_uint64_t lsn); /*!< in: lsn of a byte within the block */
+/******************************************************//**
Prints info of the log. */
UNIV_INTERN
void
log_print(
/*======*/
- FILE* file); /* in: file where to print */
-/**********************************************************
-Peeks the current lsn. */
+ FILE* file); /*!< in: file where to print */
+/******************************************************//**
+Peeks the current lsn.
+@return TRUE if success, FALSE if could not get the log system mutex */
UNIV_INTERN
ibool
log_peek_lsn(
/*=========*/
- /* out: TRUE if success, FALSE if
- could not get the log system mutex */
- ib_uint64_t* lsn); /* out: if returns TRUE, current lsn is here */
-/**************************************************************************
+ ib_uint64_t* lsn); /*!< out: if returns TRUE, current lsn is here */
+/**********************************************************************//**
Refreshes the statistics used to print per-second averages. */
UNIV_INTERN
void
@@ -597,7 +637,7 @@ extern log_t* log_sys;
#define LOG_CHECKPOINT_ARCHIVED_LSN 24
#define LOG_CHECKPOINT_GROUP_ARRAY 32
-/* For each value < LOG_MAX_N_GROUPS the following 8 bytes: */
+/* For each value smaller than LOG_MAX_N_GROUPS the following 8 bytes: */
#define LOG_CHECKPOINT_ARCHIVED_FILE_NO 0
#define LOG_CHECKPOINT_ARCHIVED_OFFSET 4
@@ -665,74 +705,78 @@ extern log_t* log_sys;
#define LOG_GROUP_OK 301
#define LOG_GROUP_CORRUPTED 302
-/* Log group consists of a number of log files, each of the same size; a log
+/** Log group consists of a number of log files, each of the same size; a log
group is implemented as a space in the sense of the module fil0fil. */
-
struct log_group_struct{
/* The following fields are protected by log_sys->mutex */
- ulint id; /* log group id */
- ulint n_files; /* number of files in the group */
- ulint file_size; /* individual log file size in bytes,
+ ulint id; /*!< log group id */
+ ulint n_files; /*!< number of files in the group */
+ ulint file_size; /*!< individual log file size in bytes,
including the log file header */
- ulint space_id; /* file space which implements the log
+ ulint space_id; /*!< file space which implements the log
group */
- ulint state; /* LOG_GROUP_OK or
+ ulint state; /*!< LOG_GROUP_OK or
LOG_GROUP_CORRUPTED */
- ib_uint64_t lsn; /* lsn used to fix coordinates within
+ ib_uint64_t lsn; /*!< lsn used to fix coordinates within
the log group */
- ulint lsn_offset; /* the offset of the above lsn */
- ulint n_pending_writes;/* number of currently pending flush
+ ulint lsn_offset; /*!< the offset of the above lsn */
+ ulint n_pending_writes;/*!< number of currently pending flush
writes for this log group */
- byte** file_header_bufs;/* buffers for each file header in the
- group */
+ byte** file_header_bufs;/*!< buffers for each file
+ header in the group */
/*-----------------------------*/
- byte** archive_file_header_bufs;/* buffers for each file
+ byte** archive_file_header_bufs;/*!< buffers for each file
header in the group */
- ulint archive_space_id;/* file space which implements the log
- group archive */
- ulint archived_file_no;/* file number corresponding to
+ ulint archive_space_id;/*!< file space which
+ implements the log group
+ archive */
+ ulint archived_file_no;/*!< file number corresponding to
log_sys->archived_lsn */
- ulint archived_offset;/* file offset corresponding to
+ ulint archived_offset;/*!< file offset corresponding to
log_sys->archived_lsn, 0 if we have
not yet written to the archive file
number archived_file_no */
- ulint next_archived_file_no;/* during an archive write,
+ ulint next_archived_file_no;/*!< during an archive write,
until the write is completed, we
store the next value for
archived_file_no here: the write
completion function then sets the new
value to ..._file_no */
- ulint next_archived_offset; /* like the preceding field */
+ ulint next_archived_offset; /*!< like the preceding field */
/*-----------------------------*/
- ib_uint64_t scanned_lsn; /* used only in recovery: recovery scan
+ ib_uint64_t scanned_lsn; /*!< used only in recovery: recovery scan
succeeded up to this lsn in this log
group */
- byte* checkpoint_buf; /* checkpoint header is written from
+ byte* checkpoint_buf; /*!< checkpoint header is written from
this buffer to the group */
UT_LIST_NODE_T(log_group_t)
- log_groups; /* list of log groups */
+ log_groups; /*!< list of log groups */
};
+/** Redo log buffer */
struct log_struct{
- byte pad[64]; /* padding to prevent other memory
+ byte pad[64]; /*!< padding to prevent other memory
update hotspots from residing on the
same memory cache line */
- ib_uint64_t lsn; /* log sequence number */
- ulint buf_free; /* first free offset within the log
+ ib_uint64_t lsn; /*!< log sequence number */
+ ulint buf_free; /*!< first free offset within the log
buffer */
- mutex_t mutex; /* mutex protecting the log */
- byte* buf; /* log buffer */
- ulint buf_size; /* log buffer size in bytes */
- ulint max_buf_free; /* recommended maximum value of
+#ifndef UNIV_HOTBACKUP
+ mutex_t mutex; /*!< mutex protecting the log */
+#endif /* !UNIV_HOTBACKUP */
+ byte* buf; /*!< log buffer */
+ ulint buf_size; /*!< log buffer size in bytes */
+ ulint max_buf_free; /*!< recommended maximum value of
buf_free, after which the buffer is
flushed */
- ulint old_buf_free; /* value of buf free when log was
+ ulint old_buf_free; /*!< value of buf free when log was
last time opened; only in the debug
version */
- ib_uint64_t old_lsn; /* value of lsn when log was last time
- opened; only in the debug version */
+ ib_uint64_t old_lsn; /*!< value of lsn when log was
+ last time opened; only in the
+ debug version */
ibool check_flush_or_checkpoint;
- /* this is set to TRUE when there may
+ /*!< this is set to TRUE when there may
be need to flush the log buffer, or
preflush buffer pool pages, or make
a checkpoint; this MUST be TRUE when
@@ -741,11 +785,12 @@ struct log_struct{
peeked at by log_free_check(), which
does not reserve the log mutex */
UT_LIST_BASE_NODE_T(log_group_t)
- log_groups; /* log groups */
+ log_groups; /*!< log groups */
- /* The fields involved in the log buffer flush */
+#ifndef UNIV_HOTBACKUP
+ /** The fields involved in the log buffer flush @{ */
- ulint buf_next_to_write;/* first offset in the log buffer
+ ulint buf_next_to_write;/*!< first offset in the log buffer
where the byte content may not exist
written to file, e.g., the start
offset of a log record catenated
@@ -753,44 +798,46 @@ struct log_struct{
operation is completed to all the log
groups */
ib_uint64_t written_to_some_lsn;
- /* first log sequence number not yet
+ /*!< first log sequence number not yet
written to any log group; for this to
be advanced, it is enough that the
write i/o has been completed for any
one log group */
ib_uint64_t written_to_all_lsn;
- /* first log sequence number not yet
+ /*!< first log sequence number not yet
written to some log group; for this to
be advanced, it is enough that the
write i/o has been completed for all
log groups */
- ib_uint64_t write_lsn; /* end lsn for the current running
+ ib_uint64_t write_lsn; /*!< end lsn for the current running
write */
- ulint write_end_offset;/* the data in buffer has been written
- up to this offset when the current
- write ends: this field will then
- be copied to buf_next_to_write */
- ib_uint64_t current_flush_lsn;/* end lsn for the current running
+ ulint write_end_offset;/*!< the data in buffer has
+ been written up to this offset
+ when the current write ends:
+ this field will then be copied
+ to buf_next_to_write */
+ ib_uint64_t current_flush_lsn;/*!< end lsn for the current running
write + flush operation */
ib_uint64_t flushed_to_disk_lsn;
- /* how far we have written the log
+ /*!< how far we have written the log
AND flushed to disk */
- ulint n_pending_writes;/* number of currently pending flushes
- or writes */
+ ulint n_pending_writes;/*!< number of currently
+ pending flushes or writes */
/* NOTE on the 'flush' in names of the fields below: starting from
4.0.14, we separate the write of the log file and the actual fsync()
or other method to flush it to disk. The names below shhould really
be 'flush_or_write'! */
- os_event_t no_flush_event; /* this event is in the reset state
+ os_event_t no_flush_event; /*!< this event is in the reset state
when a flush or a write is running;
a thread should wait for this without
owning the log mutex, but NOTE that
to set or reset this event, the
thread MUST own the log mutex! */
- ibool one_flushed; /* during a flush, this is first FALSE
- and becomes TRUE when one log group
- has been written or flushed */
- os_event_t one_flushed_event;/* this event is reset when the
+ ibool one_flushed; /*!< during a flush, this is
+ first FALSE and becomes TRUE
+ when one log group has been
+ written or flushed */
+ os_event_t one_flushed_event;/*!< this event is reset when the
flush or write has not yet completed
for any log group; e.g., this means
that a transaction has been committed
@@ -799,99 +846,110 @@ struct log_struct{
but NOTE that to set or reset this
event, the thread MUST own the log
mutex! */
- ulint n_log_ios; /* number of log i/os initiated thus
+ ulint n_log_ios; /*!< number of log i/os initiated thus
far */
- ulint n_log_ios_old; /* number of log i/o's at the
+ ulint n_log_ios_old; /*!< number of log i/o's at the
previous printout */
- time_t last_printout_time;/* when log_print was last time
+ time_t last_printout_time;/*!< when log_print was last time
called */
+ /* @} */
- /* Fields involved in checkpoints */
- ulint log_group_capacity; /* capacity of the log group; if
+ /** Fields involved in checkpoints @{ */
+ ulint log_group_capacity; /*!< capacity of the log group; if
the checkpoint age exceeds this, it is
a serious error because it is possible
we will then overwrite log and spoil
crash recovery */
ulint max_modified_age_async;
- /* when this recommended value for lsn
- - buf_pool_get_oldest_modification()
- is exceeded, we start an asynchronous
- preflush of pool pages */
+ /*!< when this recommended
+ value for lsn -
+ buf_pool_get_oldest_modification()
+ is exceeded, we start an
+ asynchronous preflush of pool pages */
ulint max_modified_age_sync;
- /* when this recommended value for lsn
- - buf_pool_get_oldest_modification()
- is exceeded, we start a synchronous
- preflush of pool pages */
+ /*!< when this recommended
+ value for lsn -
+ buf_pool_get_oldest_modification()
+ is exceeded, we start a
+ synchronous preflush of pool pages */
ulint adm_checkpoint_interval;
- /* administrator-specified checkpoint
+ /*!< administrator-specified checkpoint
interval in terms of log growth in
bytes; the interval actually used by
the database can be smaller */
ulint max_checkpoint_age_async;
- /* when this checkpoint age is exceeded
- we start an asynchronous writing of a
- new checkpoint */
+ /*!< when this checkpoint age
+ is exceeded we start an
+ asynchronous writing of a new
+ checkpoint */
ulint max_checkpoint_age;
- /* this is the maximum allowed value
+ /*!< this is the maximum allowed value
for lsn - last_checkpoint_lsn when a
new query step is started */
ib_uint64_t next_checkpoint_no;
- /* next checkpoint number */
+ /*!< next checkpoint number */
ib_uint64_t last_checkpoint_lsn;
- /* latest checkpoint lsn */
+ /*!< latest checkpoint lsn */
ib_uint64_t next_checkpoint_lsn;
- /* next checkpoint lsn */
+ /*!< next checkpoint lsn */
ulint n_pending_checkpoint_writes;
- /* number of currently pending
+ /*!< number of currently pending
checkpoint writes */
- rw_lock_t checkpoint_lock;/* this latch is x-locked when a
+ rw_lock_t checkpoint_lock;/*!< this latch is x-locked when a
checkpoint write is running; a thread
should wait for this without owning
the log mutex */
- byte* checkpoint_buf; /* checkpoint header is read to this
+#endif /* !UNIV_HOTBACKUP */
+ byte* checkpoint_buf; /*!< checkpoint header is read to this
buffer */
+ /* @} */
#ifdef UNIV_LOG_ARCHIVE
- /* Fields involved in archiving */
- ulint archiving_state;/* LOG_ARCH_ON, LOG_ARCH_STOPPING
+ /** Fields involved in archiving @{ */
+ ulint archiving_state;/*!< LOG_ARCH_ON, LOG_ARCH_STOPPING
LOG_ARCH_STOPPED, LOG_ARCH_OFF */
- ib_uint64_t archived_lsn; /* archiving has advanced to this
+ ib_uint64_t archived_lsn; /*!< archiving has advanced to this
lsn */
ulint max_archived_lsn_age_async;
- /* recommended maximum age of
+ /*!< recommended maximum age of
archived_lsn, before we start
asynchronous copying to the archive */
ulint max_archived_lsn_age;
- /* maximum allowed age for
+ /*!< maximum allowed age for
archived_lsn */
- ib_uint64_t next_archived_lsn;/* during an archive write,
+ ib_uint64_t next_archived_lsn;/*!< during an archive write,
until the write is completed, we
store the next value for
archived_lsn here: the write
completion function then sets the new
value to archived_lsn */
- ulint archiving_phase;/* LOG_ARCHIVE_READ or
+ ulint archiving_phase;/*!< LOG_ARCHIVE_READ or
LOG_ARCHIVE_WRITE */
ulint n_pending_archive_ios;
- /* number of currently pending reads
+ /*!< number of currently pending reads
or writes in archiving */
- rw_lock_t archive_lock; /* this latch is x-locked when an
+ rw_lock_t archive_lock; /*!< this latch is x-locked when an
archive write is running; a thread
should wait for this without owning
the log mutex */
- ulint archive_buf_size;/* size of archive_buf */
- byte* archive_buf; /* log segment is written to the
+ ulint archive_buf_size;/*!< size of archive_buf */
+ byte* archive_buf; /*!< log segment is written to the
archive from this buffer */
- os_event_t archiving_on; /* if archiving has been stopped,
+ os_event_t archiving_on; /*!< if archiving has been stopped,
a thread can wait for this event to
become signaled */
+ /* @} */
#endif /* UNIV_LOG_ARCHIVE */
};
+#ifdef UNIV_LOG_ARCHIVE
+/** Archiving state @{ */
#define LOG_ARCH_ON 71
#define LOG_ARCH_STOPPING 72
#define LOG_ARCH_STOPPING2 73
#define LOG_ARCH_STOPPED 74
#define LOG_ARCH_OFF 75
+/* @} */
+#endif /* UNIV_LOG_ARCHIVE */
#ifndef UNIV_NONINL
#include "log0log.ic"
diff --git a/storage/xtradb/include/log0log.ic b/storage/xtradb/include/log0log.ic
index 85eebda4942..d071985982a 100644
--- a/storage/xtradb/include/log0log.ic
+++ b/storage/xtradb/include/log0log.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/log0log.ic
Database log
Created 12/9/1995 Heikki Tuuri
@@ -26,28 +27,27 @@ Created 12/9/1995 Heikki Tuuri
#include "mach0data.h"
#include "mtr0mtr.h"
-/**********************************************************
+/******************************************************//**
Checks by parsing that the catenated log segment for a single mtr is
consistent. */
UNIV_INTERN
ibool
log_check_log_recs(
/*===============*/
- byte* buf, /* in: pointer to the start of
+ byte* buf, /*!< in: pointer to the start of
the log segment in the
log_sys->buf log buffer */
- ulint len, /* in: segment length in bytes */
- ib_uint64_t buf_start_lsn); /* in: buffer start lsn */
+ ulint len, /*!< in: segment length in bytes */
+ ib_uint64_t buf_start_lsn); /*!< in: buffer start lsn */
-/****************************************************************
-Gets a log block flush bit. */
+/************************************************************//**
+Gets a log block flush bit.
+@return TRUE if this block was the first to be written in a log flush */
UNIV_INLINE
ibool
log_block_get_flush_bit(
/*====================*/
- /* out: TRUE if this block was the first
- to be written in a log flush */
- byte* log_block) /* in: log block */
+ const byte* log_block) /*!< in: log block */
{
if (LOG_BLOCK_FLUSH_BIT_MASK
& mach_read_from_4(log_block + LOG_BLOCK_HDR_NO)) {
@@ -58,14 +58,14 @@ log_block_get_flush_bit(
return(FALSE);
}
-/****************************************************************
+/************************************************************//**
Sets the log block flush bit. */
UNIV_INLINE
void
log_block_set_flush_bit(
/*====================*/
- byte* log_block, /* in: log block */
- ibool val) /* in: value to set */
+ byte* log_block, /*!< in/out: log block */
+ ibool val) /*!< in: value to set */
{
ulint field;
@@ -80,29 +80,28 @@ log_block_set_flush_bit(
mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, field);
}
-/****************************************************************
-Gets a log block number stored in the header. */
+/************************************************************//**
+Gets a log block number stored in the header.
+@return log block number stored in the block header */
UNIV_INLINE
ulint
log_block_get_hdr_no(
/*=================*/
- /* out: log block number stored in the block
- header */
- byte* log_block) /* in: log block */
+ const byte* log_block) /*!< in: log block */
{
return(~LOG_BLOCK_FLUSH_BIT_MASK
& mach_read_from_4(log_block + LOG_BLOCK_HDR_NO));
}
-/****************************************************************
+/************************************************************//**
Sets the log block number stored in the header; NOTE that this must be set
before the flush bit! */
UNIV_INLINE
void
log_block_set_hdr_no(
/*=================*/
- byte* log_block, /* in: log block */
- ulint n) /* in: log block number: must be > 0 and
+ byte* log_block, /*!< in/out: log block */
+ ulint n) /*!< in: log block number: must be > 0 and
< LOG_BLOCK_FLUSH_BIT_MASK */
{
ut_ad(n > 0);
@@ -111,101 +110,99 @@ log_block_set_hdr_no(
mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, n);
}
-/****************************************************************
-Gets a log block data length. */
+/************************************************************//**
+Gets a log block data length.
+@return log block data length measured as a byte offset from the block start */
UNIV_INLINE
ulint
log_block_get_data_len(
/*===================*/
- /* out: log block data length measured as a
- byte offset from the block start */
- byte* log_block) /* in: log block */
+ const byte* log_block) /*!< in: log block */
{
return(mach_read_from_2(log_block + LOG_BLOCK_HDR_DATA_LEN));
}
-/****************************************************************
+/************************************************************//**
Sets the log block data length. */
UNIV_INLINE
void
log_block_set_data_len(
/*===================*/
- byte* log_block, /* in: log block */
- ulint len) /* in: data length */
+ byte* log_block, /*!< in/out: log block */
+ ulint len) /*!< in: data length */
{
mach_write_to_2(log_block + LOG_BLOCK_HDR_DATA_LEN, len);
}
-/****************************************************************
-Gets a log block first mtr log record group offset. */
+/************************************************************//**
+Gets a log block first mtr log record group offset.
+@return first mtr log record group byte offset from the block start, 0
+if none */
UNIV_INLINE
ulint
log_block_get_first_rec_group(
/*==========================*/
- /* out: first mtr log record group byte offset
- from the block start, 0 if none */
- byte* log_block) /* in: log block */
+ const byte* log_block) /*!< in: log block */
{
return(mach_read_from_2(log_block + LOG_BLOCK_FIRST_REC_GROUP));
}
-/****************************************************************
+/************************************************************//**
Sets the log block first mtr log record group offset. */
UNIV_INLINE
void
log_block_set_first_rec_group(
/*==========================*/
- byte* log_block, /* in: log block */
- ulint offset) /* in: offset, 0 if none */
+ byte* log_block, /*!< in/out: log block */
+ ulint offset) /*!< in: offset, 0 if none */
{
mach_write_to_2(log_block + LOG_BLOCK_FIRST_REC_GROUP, offset);
}
-/****************************************************************
-Gets a log block checkpoint number field (4 lowest bytes). */
+/************************************************************//**
+Gets a log block checkpoint number field (4 lowest bytes).
+@return checkpoint no (4 lowest bytes) */
UNIV_INLINE
ulint
log_block_get_checkpoint_no(
/*========================*/
- /* out: checkpoint no (4 lowest bytes) */
- byte* log_block) /* in: log block */
+ const byte* log_block) /*!< in: log block */
{
return(mach_read_from_4(log_block + LOG_BLOCK_CHECKPOINT_NO));
}
-/****************************************************************
+/************************************************************//**
Sets a log block checkpoint number field (4 lowest bytes). */
UNIV_INLINE
void
log_block_set_checkpoint_no(
/*========================*/
- byte* log_block, /* in: log block */
- ib_uint64_t no) /* in: checkpoint no */
+ byte* log_block, /*!< in/out: log block */
+ ib_uint64_t no) /*!< in: checkpoint no */
{
mach_write_to_4(log_block + LOG_BLOCK_CHECKPOINT_NO, (ulint) no);
}
-/****************************************************************
-Converts a lsn to a log block number. */
+/************************************************************//**
+Converts a lsn to a log block number.
+@return log block number, it is > 0 and <= 1G */
UNIV_INLINE
ulint
log_block_convert_lsn_to_no(
/*========================*/
- /* out: log block number,
- it is > 0 and <= 1G */
- ib_uint64_t lsn) /* in: lsn of a byte within the block */
+ ib_uint64_t lsn) /*!< in: lsn of a byte within the block */
{
return(((ulint) (lsn / OS_FILE_LOG_BLOCK_SIZE) & 0x3FFFFFFFUL) + 1);
}
-/****************************************************************
-Calculates the checksum for a log block. */
+/************************************************************//**
+Calculates the checksum for a log block.
+@return checksum */
UNIV_INLINE
ulint
log_block_calc_checksum(
/*====================*/
- /* out: checksum */
- const byte* block) /* in: log block */
+ const byte* block) /*!< in: log block */
{
ulint sum;
ulint sh;
@@ -228,41 +225,41 @@ log_block_calc_checksum(
return(sum);
}
-/****************************************************************
-Gets a log block checksum field value. */
+/************************************************************//**
+Gets a log block checksum field value.
+@return checksum */
UNIV_INLINE
ulint
log_block_get_checksum(
/*===================*/
- /* out: checksum */
- const byte* log_block) /* in: log block */
+ const byte* log_block) /*!< in: log block */
{
return(mach_read_from_4(log_block + OS_FILE_LOG_BLOCK_SIZE
- LOG_BLOCK_CHECKSUM));
}
-/****************************************************************
+/************************************************************//**
Sets a log block checksum field value. */
UNIV_INLINE
void
log_block_set_checksum(
/*===================*/
- byte* log_block, /* in: log block */
- ulint checksum) /* in: checksum */
+ byte* log_block, /*!< in/out: log block */
+ ulint checksum) /*!< in: checksum */
{
mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE
- LOG_BLOCK_CHECKSUM,
checksum);
}
-/****************************************************************
+/************************************************************//**
Initializes a log block in the log buffer. */
UNIV_INLINE
void
log_block_init(
/*===========*/
- byte* log_block, /* in: pointer to the log buffer */
- ib_uint64_t lsn) /* in: lsn within the log block */
+ byte* log_block, /*!< in: pointer to the log buffer */
+ ib_uint64_t lsn) /*!< in: lsn within the log block */
{
ulint no;
@@ -276,15 +273,15 @@ log_block_init(
log_block_set_first_rec_group(log_block, 0);
}
-/****************************************************************
+/************************************************************//**
Initializes a log block in the log buffer in the old format, where there
was no checksum yet. */
UNIV_INLINE
void
log_block_init_in_old_format(
/*=========================*/
- byte* log_block, /* in: pointer to the log buffer */
- ib_uint64_t lsn) /* in: lsn within the log block */
+ byte* log_block, /*!< in: pointer to the log buffer */
+ ib_uint64_t lsn) /*!< in: lsn within the log block */
{
ulint no;
@@ -299,19 +296,19 @@ log_block_init_in_old_format(
log_block_set_first_rec_group(log_block, 0);
}
-/****************************************************************
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
Writes to the log the string given. The log must be released with
-log_release. */
+log_release.
+@return end lsn of the log record, zero if did not succeed */
UNIV_INLINE
ib_uint64_t
log_reserve_and_write_fast(
/*=======================*/
- /* out: end lsn of the log record,
- zero if did not succeed */
- byte* str, /* in: string */
- ulint len, /* in: string length */
- ib_uint64_t* start_lsn,/* out: start lsn of the log record */
- ibool* success)/* out: TRUE if success */
+ byte* str, /*!< in: string */
+ ulint len, /*!< in: string length */
+ ib_uint64_t* start_lsn,/*!< out: start lsn of the log record */
+ ibool* success)/*!< out: TRUE if success */
{
log_t* log = log_sys;
ulint data_len;
@@ -359,7 +356,7 @@ log_reserve_and_write_fast(
return(lsn);
}
-/***************************************************************************
+/***********************************************************************//**
Releases the log mutex. */
UNIV_INLINE
void
@@ -369,13 +366,13 @@ log_release(void)
mutex_exit(&(log_sys->mutex));
}
-/****************************************************************
-Gets the current lsn. */
+/************************************************************//**
+Gets the current lsn.
+@return current lsn */
UNIV_INLINE
ib_uint64_t
log_get_lsn(void)
/*=============*/
- /* out: current lsn */
{
ib_uint64_t lsn;
@@ -388,7 +385,19 @@ log_get_lsn(void)
return(lsn);
}
-/***************************************************************************
+/****************************************************************
+Gets the log group capacity. It is OK to read the value without
+holding log_sys->mutex because it is constant.
+@return log group capacity */
+UNIV_INLINE
+ulint
+log_get_capacity(void)
+/*==================*/
+{
+ return(log_sys->log_group_capacity);
+}
+
+/***********************************************************************//**
Checks if there is need for a log buffer flush or a new checkpoint, and does
this if yes. Any database operation should call this when it has modified
more than about 4 pages. NOTE that this function may only be called when the
@@ -405,3 +414,4 @@ log_free_check(void)
log_check_margins();
}
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/log0recv.h b/storage/xtradb/include/log0recv.h
index e3fe9ed330a..8468c213bdb 100644
--- a/storage/xtradb/include/log0recv.h
+++ b/storage/xtradb/include/log0recv.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/log0recv.h
Recovery
Created 9/20/1997 Heikki Tuuri
@@ -34,189 +35,225 @@ Created 9/20/1997 Heikki Tuuri
#ifdef UNIV_HOTBACKUP
extern ibool recv_replay_file_ops;
-/***********************************************************************
-Reads the checkpoint info needed in hot backup. */
+/*******************************************************************//**
+Reads the checkpoint info needed in hot backup.
+@return TRUE if success */
UNIV_INTERN
ibool
recv_read_cp_info_for_backup(
/*=========================*/
- /* out: TRUE if success */
- byte* hdr, /* in: buffer containing the log group
+ const byte* hdr, /*!< in: buffer containing the log group
header */
- ib_uint64_t* lsn, /* out: checkpoint lsn */
- ulint* offset, /* out: checkpoint offset in the log group */
- ulint* fsp_limit,/* out: fsp limit of space 0,
+ ib_uint64_t* lsn, /*!< out: checkpoint lsn */
+ ulint* offset, /*!< out: checkpoint offset in the log group */
+ ulint* fsp_limit,/*!< out: fsp limit of space 0,
1000000000 if the database is running
with < version 3.23.50 of InnoDB */
- ib_uint64_t* cp_no, /* out: checkpoint number */
+ ib_uint64_t* cp_no, /*!< out: checkpoint number */
ib_uint64_t* first_header_lsn);
- /* out: lsn of of the start of the
+ /*!< out: lsn of of the start of the
first log file */
-/***********************************************************************
+/*******************************************************************//**
Scans the log segment and n_bytes_scanned is set to the length of valid
log scanned. */
UNIV_INTERN
void
recv_scan_log_seg_for_backup(
/*=========================*/
- byte* buf, /* in: buffer containing log data */
- ulint buf_len, /* in: data length in that buffer */
- ib_uint64_t* scanned_lsn, /* in/out: lsn of buffer start,
+ byte* buf, /*!< in: buffer containing log data */
+ ulint buf_len, /*!< in: data length in that buffer */
+ ib_uint64_t* scanned_lsn, /*!< in/out: lsn of buffer start,
we return scanned lsn */
ulint* scanned_checkpoint_no,
- /* in/out: 4 lowest bytes of the
+ /*!< in/out: 4 lowest bytes of the
highest scanned checkpoint number so
far */
- ulint* n_bytes_scanned);/* out: how much we were able to
+ ulint* n_bytes_scanned);/*!< out: how much we were able to
scan, smaller than buf_len if log
data ended here */
#endif /* UNIV_HOTBACKUP */
-/***********************************************************************
-Returns TRUE if recovery is currently running. */
+/*******************************************************************//**
+Returns TRUE if recovery is currently running.
+@return recv_recovery_on */
UNIV_INLINE
ibool
recv_recovery_is_on(void);
/*=====================*/
-/***********************************************************************
-Returns TRUE if recovery from backup is currently running. */
+#ifdef UNIV_LOG_ARCHIVE
+/*******************************************************************//**
+Returns TRUE if recovery from backup is currently running.
+@return recv_recovery_from_backup_on */
UNIV_INLINE
ibool
recv_recovery_from_backup_is_on(void);
/*=================================*/
-/****************************************************************************
+#endif /* UNIV_LOG_ARCHIVE */
+/************************************************************************//**
Applies the hashed log records to the page, if the page lsn is less than the
lsn of a log record. This can be called when a buffer page has just been
read in, or also for a page already in the buffer pool. */
UNIV_INTERN
void
-recv_recover_page(
-/*==============*/
- ibool recover_backup,
- /* in: TRUE if we are recovering a backup
- page: then we do not acquire any latches
- since the page was read in outside the
- buffer pool */
+recv_recover_page_func(
+/*===================*/
+#ifndef UNIV_HOTBACKUP
ibool just_read_in,
- /* in: TRUE if the i/o-handler calls this for
- a freshly read page */
- buf_block_t* block); /* in: buffer block */
-/************************************************************
+ /*!< in: TRUE if the i/o handler calls
+ this for a freshly read page */
+#endif /* !UNIV_HOTBACKUP */
+ buf_block_t* block); /*!< in/out: buffer block */
+#ifndef UNIV_HOTBACKUP
+/** Wrapper for recv_recover_page_func().
+Applies the hashed log records to the page, if the page lsn is less than the
+lsn of a log record. This can be called when a buffer page has just been
+read in, or also for a page already in the buffer pool.
+@param jri in: TRUE if just read in (the i/o handler calls this for
+a freshly read page)
+@param block in/out: the buffer block
+*/
+# define recv_recover_page(jri, block) recv_recover_page_func(jri, block)
+#else /* !UNIV_HOTBACKUP */
+/** Wrapper for recv_recover_page_func().
+Applies the hashed log records to the page, if the page lsn is less than the
+lsn of a log record. This can be called when a buffer page has just been
+read in, or also for a page already in the buffer pool.
+@param jri in: TRUE if just read in (the i/o handler calls this for
+a freshly read page)
+@param block in/out: the buffer block
+*/
+# define recv_recover_page(jri, block) recv_recover_page_func(block)
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************//**
Recovers from a checkpoint. When this function returns, the database is able
to start processing of new user transactions, but the function
recv_recovery_from_checkpoint_finish should be called later to complete
-the recovery and free the resources used in it. */
+the recovery and free the resources used in it.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
recv_recovery_from_checkpoint_start_func(
/*=====================================*/
- /* out: error code or DB_SUCCESS */
#ifdef UNIV_LOG_ARCHIVE
- ulint type, /* in: LOG_CHECKPOINT or LOG_ARCHIVE */
- ib_uint64_t limit_lsn, /* in: recover up to this lsn
+ ulint type, /*!< in: LOG_CHECKPOINT or
+ LOG_ARCHIVE */
+ ib_uint64_t limit_lsn, /*!< in: recover up to this lsn
if possible */
#endif /* UNIV_LOG_ARCHIVE */
- ib_uint64_t min_flushed_lsn,/* in: min flushed lsn from
+ ib_uint64_t min_flushed_lsn,/*!< in: min flushed lsn from
data files */
- ib_uint64_t max_flushed_lsn);/* in: max flushed lsn from
+ ib_uint64_t max_flushed_lsn);/*!< in: max flushed lsn from
data files */
#ifdef UNIV_LOG_ARCHIVE
+/** Wrapper for recv_recovery_from_checkpoint_start_func().
+Recovers from a checkpoint. When this function returns, the database is able
+to start processing of new user transactions, but the function
+recv_recovery_from_checkpoint_finish should be called later to complete
+the recovery and free the resources used in it.
+@param type in: LOG_CHECKPOINT or LOG_ARCHIVE
+@param lim in: recover up to this log sequence number if possible
+@param min in: minimum flushed log sequence number from data files
+@param max in: maximum flushed log sequence number from data files
+@return error code or DB_SUCCESS */
# define recv_recovery_from_checkpoint_start(type,lim,min,max) \
recv_recovery_from_checkpoint_start_func(type,lim,min,max)
#else /* UNIV_LOG_ARCHIVE */
+/** Wrapper for recv_recovery_from_checkpoint_start_func().
+Recovers from a checkpoint. When this function returns, the database is able
+to start processing of new user transactions, but the function
+recv_recovery_from_checkpoint_finish should be called later to complete
+the recovery and free the resources used in it.
+@param type ignored: LOG_CHECKPOINT or LOG_ARCHIVE
+@param lim ignored: recover up to this log sequence number if possible
+@param min in: minimum flushed log sequence number from data files
+@param max in: maximum flushed log sequence number from data files
+@return error code or DB_SUCCESS */
# define recv_recovery_from_checkpoint_start(type,lim,min,max) \
recv_recovery_from_checkpoint_start_func(min,max)
#endif /* UNIV_LOG_ARCHIVE */
-/************************************************************
+/********************************************************//**
Completes recovery from a checkpoint. */
UNIV_INTERN
void
recv_recovery_from_checkpoint_finish(void);
/*======================================*/
-/***********************************************************
-Scans log from a buffer and stores new log data to the parsing buffer. Parses
-and hashes the log records if new data found. */
+/*******************************************************//**
+Scans log from a buffer and stores new log data to the parsing buffer.
+Parses and hashes the log records if new data found. Unless
+UNIV_HOTBACKUP is defined, this function will apply log records
+automatically when the hash table becomes full.
+@return TRUE if limit_lsn has been reached, or not able to scan any
+more in this log group */
UNIV_INTERN
ibool
recv_scan_log_recs(
/*===============*/
- /* out: TRUE if limit_lsn has been
- reached, or not able to scan any more
- in this log group */
- ibool apply_automatically,/* in: TRUE if we want this
- function to apply log records
- automatically when the hash table
- becomes full; in the hot backup tool
- the tool does the applying, not this
- function */
- ulint available_memory,/* in: we let the hash table of recs
+ ulint available_memory,/*!< in: we let the hash table of recs
to grow to this size, at the maximum */
- ibool store_to_hash, /* in: TRUE if the records should be
+ ibool store_to_hash, /*!< in: TRUE if the records should be
stored to the hash table; this is set
to FALSE if just debug checking is
needed */
- byte* buf, /* in: buffer containing a log segment
- or garbage */
- ulint len, /* in: buffer length */
- ib_uint64_t start_lsn, /* in: buffer start lsn */
- ib_uint64_t* contiguous_lsn, /* in/out: it is known that all log
+ const byte* buf, /*!< in: buffer containing a log
+ segment or garbage */
+ ulint len, /*!< in: buffer length */
+ ib_uint64_t start_lsn, /*!< in: buffer start lsn */
+ ib_uint64_t* contiguous_lsn, /*!< in/out: it is known that all log
groups contain contiguous log data up
to this lsn */
- ib_uint64_t* group_scanned_lsn);/* out: scanning succeeded up to
+ ib_uint64_t* group_scanned_lsn);/*!< out: scanning succeeded up to
this lsn */
-/**********************************************************
+/******************************************************//**
Resets the logs. The contents of log files will be lost! */
UNIV_INTERN
void
recv_reset_logs(
/*============*/
- ib_uint64_t lsn, /* in: reset to this lsn
+ ib_uint64_t lsn, /*!< in: reset to this lsn
rounded up to be divisible by
OS_FILE_LOG_BLOCK_SIZE, after
which we add
LOG_BLOCK_HDR_SIZE */
#ifdef UNIV_LOG_ARCHIVE
- ulint arch_log_no, /* in: next archived log file number */
+ ulint arch_log_no, /*!< in: next archived log file number */
#endif /* UNIV_LOG_ARCHIVE */
- ibool new_logs_created);/* in: TRUE if resetting logs
+ ibool new_logs_created);/*!< in: TRUE if resetting logs
is done at the log creation;
FALSE if it is done after
archive recovery */
#ifdef UNIV_HOTBACKUP
-/**********************************************************
+/******************************************************//**
Creates new log files after a backup has been restored. */
UNIV_INTERN
void
recv_reset_log_files_for_backup(
/*============================*/
- const char* log_dir, /* in: log file directory path */
- ulint n_log_files, /* in: number of log files */
- ulint log_file_size, /* in: log file size */
- ib_uint64_t lsn); /* in: new start lsn, must be
+ const char* log_dir, /*!< in: log file directory path */
+ ulint n_log_files, /*!< in: number of log files */
+ ulint log_file_size, /*!< in: log file size */
+ ib_uint64_t lsn); /*!< in: new start lsn, must be
divisible by OS_FILE_LOG_BLOCK_SIZE */
#endif /* UNIV_HOTBACKUP */
-/************************************************************
+/********************************************************//**
Creates the recovery system. */
UNIV_INTERN
void
recv_sys_create(void);
/*=================*/
-/************************************************************
+/********************************************************//**
Inits the recovery system for a recovery operation. */
UNIV_INTERN
void
recv_sys_init(
/*==========*/
- ibool recover_from_backup, /* in: TRUE if this is called
- to recover from a hot backup */
- ulint available_memory); /* in: available memory in bytes */
-/***********************************************************************
+ ulint available_memory); /*!< in: available memory in bytes */
+/*******************************************************************//**
Empties the hash table of stored log records, applying them to appropriate
pages. */
UNIV_INTERN
void
recv_apply_hashed_log_recs(
/*=======================*/
- ibool allow_ibuf); /* in: if TRUE, also ibuf operations are
+ ibool allow_ibuf); /*!< in: if TRUE, also ibuf operations are
allowed during the application; if FALSE,
no ibuf operations are allowed, and after
the application all file pages are flushed to
@@ -224,7 +261,7 @@ recv_apply_hashed_log_recs(
alternative means that no new log records
can be generated during the application */
#ifdef UNIV_HOTBACKUP
-/***********************************************************************
+/*******************************************************************//**
Applies log records in the hash table to a backup. */
UNIV_INTERN
void
@@ -232,23 +269,23 @@ recv_apply_log_recs_for_backup(void);
/*================================*/
#endif
#ifdef UNIV_LOG_ARCHIVE
-/************************************************************
-Recovers from archived log files, and also from log files, if they exist. */
+/********************************************************//**
+Recovers from archived log files, and also from log files, if they exist.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
recv_recovery_from_archive_start(
/*=============================*/
- /* out: error code or DB_SUCCESS */
- ib_uint64_t min_flushed_lsn,/* in: min flushed lsn field from the
+ ib_uint64_t min_flushed_lsn,/*!< in: min flushed lsn field from the
data files */
- ib_uint64_t limit_lsn, /* in: recover up to this lsn if
+ ib_uint64_t limit_lsn, /*!< in: recover up to this lsn if
possible */
- ulint first_log_no); /* in: number of the first archived
+ ulint first_log_no); /*!< in: number of the first archived
log file to use in the recovery; the
file will be searched from
INNOBASE_LOG_ARCH_DIR specified in
server config file */
-/************************************************************
+/********************************************************//**
Completes recovery from archive. */
UNIV_INTERN
void
@@ -256,133 +293,170 @@ recv_recovery_from_archive_finish(void);
/*===================================*/
#endif /* UNIV_LOG_ARCHIVE */
-/* Block of log record data */
+/** Block of log record data */
typedef struct recv_data_struct recv_data_t;
+/** Block of log record data */
struct recv_data_struct{
- recv_data_t* next; /* pointer to the next block or NULL */
- /* the log record data is stored physically
+ recv_data_t* next; /*!< pointer to the next block or NULL */
+ /*!< the log record data is stored physically
immediately after this struct, max amount
RECV_DATA_BLOCK_SIZE bytes of it */
};
-/* Stored log record struct */
+/** Stored log record struct */
typedef struct recv_struct recv_t;
+/** Stored log record struct */
struct recv_struct{
- byte type; /* log record type */
- ulint len; /* log record body length in bytes */
- recv_data_t* data; /* chain of blocks containing the log record
+ byte type; /*!< log record type */
+ ulint len; /*!< log record body length in bytes */
+ recv_data_t* data; /*!< chain of blocks containing the log record
body */
- ib_uint64_t start_lsn;/* start lsn of the log segment written by
+ ib_uint64_t start_lsn;/*!< start lsn of the log segment written by
the mtr which generated this log record: NOTE
that this is not necessarily the start lsn of
this log record */
- ib_uint64_t end_lsn;/* end lsn of the log segment written by
+ ib_uint64_t end_lsn;/*!< end lsn of the log segment written by
the mtr which generated this log record: NOTE
that this is not necessarily the end lsn of
this log record */
UT_LIST_NODE_T(recv_t)
- rec_list;/* list of log records for this page */
+ rec_list;/*!< list of log records for this page */
+};
+
+/** States of recv_addr_struct */
+enum recv_addr_state {
+ /** not yet processed */
+ RECV_NOT_PROCESSED,
+ /** page is being read */
+ RECV_BEING_READ,
+ /** log records are being applied on the page */
+ RECV_BEING_PROCESSED,
+ /** log records have been applied on the page, or they have
+ been discarded because the tablespace does not exist */
+ RECV_PROCESSED
};
-/* Hashed page file address struct */
+/** Hashed page file address struct */
typedef struct recv_addr_struct recv_addr_t;
+/** Hashed page file address struct */
struct recv_addr_struct{
- ulint state; /* RECV_NOT_PROCESSED, RECV_BEING_PROCESSED,
- or RECV_PROCESSED */
- ulint space; /* space id */
- ulint page_no;/* page number */
+ enum recv_addr_state state;
+ /*!< recovery state of the page */
+ ulint space; /*!< space id */
+ ulint page_no;/*!< page number */
UT_LIST_BASE_NODE_T(recv_t)
- rec_list;/* list of log records for this page */
- hash_node_t addr_hash;
+ rec_list;/*!< list of log records for this page */
+ hash_node_t addr_hash;/*!< hash node in the hash bucket chain */
};
-/* Recovery system data structure */
+/** Recovery system data structure */
typedef struct recv_sys_struct recv_sys_t;
+/** Recovery system data structure */
struct recv_sys_struct{
- mutex_t mutex; /* mutex protecting the fields apply_log_recs,
+#ifndef UNIV_HOTBACKUP
+ mutex_t mutex; /*!< mutex protecting the fields apply_log_recs,
n_addrs, and the state field in each recv_addr
struct */
+#endif /* !UNIV_HOTBACKUP */
ibool apply_log_recs;
- /* this is TRUE when log rec application to
+ /*!< this is TRUE when log rec application to
pages is allowed; this flag tells the
i/o-handler if it should do log record
application */
ibool apply_batch_on;
- /* this is TRUE when a log rec application
+ /*!< this is TRUE when a log rec application
batch is running */
- ib_uint64_t lsn; /* log sequence number */
+ ib_uint64_t lsn; /*!< log sequence number */
ulint last_log_buf_size;
- /* size of the log buffer when the database
+ /*!< size of the log buffer when the database
last time wrote to the log */
byte* last_block;
- /* possible incomplete last recovered log
+ /*!< possible incomplete last recovered log
block */
byte* last_block_buf_start;
- /* the nonaligned start address of the
+ /*!< the nonaligned start address of the
preceding buffer */
- byte* buf; /* buffer for parsing log records */
- ulint len; /* amount of data in buf */
+ byte* buf; /*!< buffer for parsing log records */
+ ulint len; /*!< amount of data in buf */
ib_uint64_t parse_start_lsn;
- /* this is the lsn from which we were able to
+ /*!< this is the lsn from which we were able to
start parsing log records and adding them to
the hash table; zero if a suitable
start point not found yet */
ib_uint64_t scanned_lsn;
- /* the log data has been scanned up to this
+ /*!< the log data has been scanned up to this
lsn */
ulint scanned_checkpoint_no;
- /* the log data has been scanned up to this
+ /*!< the log data has been scanned up to this
checkpoint number (lowest 4 bytes) */
ulint recovered_offset;
- /* start offset of non-parsed log records in
+ /*!< start offset of non-parsed log records in
buf */
ib_uint64_t recovered_lsn;
- /* the log records have been parsed up to
+ /*!< the log records have been parsed up to
this lsn */
- ib_uint64_t limit_lsn;/* recovery should be made at most up to this
- lsn */
+ ib_uint64_t limit_lsn;/*!< recovery should be made at most
+ up to this lsn */
ibool found_corrupt_log;
- /* this is set to TRUE if we during log
+ /*!< this is set to TRUE if we during log
scan find a corrupt log block, or a corrupt
log record, or there is a log parsing
buffer overflow */
#ifdef UNIV_LOG_ARCHIVE
log_group_t* archive_group;
- /* in archive recovery: the log group whose
+ /*!< in archive recovery: the log group whose
archive is read */
#endif /* !UNIV_LOG_ARCHIVE */
- mem_heap_t* heap; /* memory heap of log records and file
+ mem_heap_t* heap; /*!< memory heap of log records and file
addresses*/
- hash_table_t* addr_hash;/* hash table of file addresses of pages */
- ulint n_addrs;/* number of not processed hashed file
+ hash_table_t* addr_hash;/*!< hash table of file addresses of pages */
+ ulint n_addrs;/*!< number of not processed hashed file
addresses in the hash table */
};
+/** The recovery system */
extern recv_sys_t* recv_sys;
+
+/** TRUE when applying redo log records during crash recovery; FALSE
+otherwise. Note that this is FALSE while a background thread is
+rolling back incomplete transactions. */
extern ibool recv_recovery_on;
+/** If the following is TRUE, the buffer pool file pages must be invalidated
+after recovery and no ibuf operations are allowed; this becomes TRUE if
+the log record hash table becomes too full, and log records must be merged
+to file pages already before the recovery is finished: in this case no
+ibuf operations are allowed, as they could modify the pages read in the
+buffer pool before the pages have been recovered to the up-to-date state.
+
+TRUE means that recovery is running and no operations on the log files
+are allowed yet: the variable name is misleading. */
extern ibool recv_no_ibuf_operations;
+/** TRUE when recv_init_crash_recovery() has been called. */
extern ibool recv_needed_recovery;
+/** TRUE if buf_page_is_corrupted() should check if the log sequence
+number (FIL_PAGE_LSN) is in the future. Initially FALSE, and set by
+recv_recovery_from_checkpoint_start_func(). */
extern ibool recv_lsn_checks_on;
#ifdef UNIV_HOTBACKUP
+/** TRUE when the redo log is being backed up */
extern ibool recv_is_making_a_backup;
#endif /* UNIV_HOTBACKUP */
+/** Maximum page number encountered in the redo log */
extern ulint recv_max_parsed_page_no;
-/* Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many
+/** Size of the parsing buffer; it must accommodate RECV_SCAN_SIZE many
times! */
#define RECV_PARSING_BUF_SIZE (2 * 1024 * 1024)
-/* Size of block reads when the log groups are scanned forward to do a
+/** Size of block reads when the log groups are scanned forward to do a
roll-forward */
#define RECV_SCAN_SIZE (4 * UNIV_PAGE_SIZE)
-/* States of recv_addr_struct */
-#define RECV_NOT_PROCESSED 71
-#define RECV_BEING_READ 72
-#define RECV_BEING_PROCESSED 73
-#define RECV_PROCESSED 74
-
+/** This many frames must be left free in the buffer pool when we scan
+the log and store the scanned log records in the buffer pool: we will
+use these free frames to read in pages when we start applying the
+log records to the database. */
extern ulint recv_n_pool_free_frames;
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/log0recv.ic b/storage/xtradb/include/log0recv.ic
index e114bede38f..0a8e55b96fa 100644
--- a/storage/xtradb/include/log0recv.ic
+++ b/storage/xtradb/include/log0recv.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/log0recv.ic
Recovery
Created 9/20/1997 Heikki Tuuri
@@ -24,10 +25,9 @@ Created 9/20/1997 Heikki Tuuri
#include "univ.i"
-extern ibool recv_recovery_from_backup_on;
-
-/***********************************************************************
-Returns TRUE if recovery is currently running. */
+/*******************************************************************//**
+Returns TRUE if recovery is currently running.
+@return recv_recovery_on */
UNIV_INLINE
ibool
recv_recovery_is_on(void)
@@ -36,8 +36,13 @@ recv_recovery_is_on(void)
return(UNIV_UNLIKELY(recv_recovery_on));
}
-/***********************************************************************
-Returns TRUE if recovery from backup is currently running. */
+#ifdef UNIV_LOG_ARCHIVE
+/** TRUE when applying redo log records from an archived log file */
+extern ibool recv_recovery_from_backup_on;
+
+/*******************************************************************//**
+Returns TRUE if recovery from backup is currently running.
+@return recv_recovery_from_backup_on */
UNIV_INLINE
ibool
recv_recovery_from_backup_is_on(void)
@@ -45,4 +50,4 @@ recv_recovery_from_backup_is_on(void)
{
return(recv_recovery_from_backup_on);
}
-
+#endif /* UNIV_LOG_ARCHIVE */
diff --git a/storage/xtradb/include/mach0data.h b/storage/xtradb/include/mach0data.h
index 78b48af0836..44ee3df22ce 100644
--- a/storage/xtradb/include/mach0data.h
+++ b/storage/xtradb/include/mach0data.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/mach0data.h
Utilities for converting data from the database file
to the machine format.
@@ -34,363 +35,364 @@ in the same format: ascii, big-endian, ... .
All data in the files MUST be accessed using the functions in this
module. */
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in one byte. */
UNIV_INLINE
void
mach_write_to_1(
/*============*/
- byte* b, /* in: pointer to byte where to store */
- ulint n); /* in: ulint integer to be stored, >= 0, < 256 */
-/************************************************************
-The following function is used to fetch data from one byte. */
+ byte* b, /*!< in: pointer to byte where to store */
+ ulint n); /*!< in: ulint integer to be stored, >= 0, < 256 */
+/********************************************************//**
+The following function is used to fetch data from one byte.
+@return ulint integer, >= 0, < 256 */
UNIV_INLINE
ulint
mach_read_from_1(
/*=============*/
- /* out: ulint integer, >= 0, < 256 */
- const byte* b) /* in: pointer to byte */
+ const byte* b) /*!< in: pointer to byte */
__attribute__((nonnull, pure));
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in two consecutive
bytes. We store the most significant byte to the lower address. */
UNIV_INLINE
void
mach_write_to_2(
/*============*/
- byte* b, /* in: pointer to two bytes where to store */
- ulint n); /* in: ulint integer to be stored, >= 0, < 64k */
-/************************************************************
+ byte* b, /*!< in: pointer to two bytes where to store */
+ ulint n); /*!< in: ulint integer to be stored, >= 0, < 64k */
+/********************************************************//**
The following function is used to fetch data from two consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return ulint integer, >= 0, < 64k */
UNIV_INLINE
ulint
mach_read_from_2(
/*=============*/
- /* out: ulint integer, >= 0, < 64k */
- const byte* b) /* in: pointer to two bytes */
+ const byte* b) /*!< in: pointer to two bytes */
__attribute__((nonnull, pure));
-/************************************************************
+/********************************************************//**
The following function is used to convert a 16-bit data item
to the canonical format, for fast bytewise equality test
-against memory. */
+against memory.
+@return 16-bit integer in canonical format */
UNIV_INLINE
uint16
mach_encode_2(
/*==========*/
- /* out: 16-bit integer in canonical format */
- ulint n) /* in: integer in machine-dependent format */
+ ulint n) /*!< in: integer in machine-dependent format */
__attribute__((const));
-/************************************************************
+/********************************************************//**
The following function is used to convert a 16-bit data item
from the canonical format, for fast bytewise equality test
-against memory. */
+against memory.
+@return integer in machine-dependent format */
UNIV_INLINE
ulint
mach_decode_2(
/*==========*/
- /* out: integer in machine-dependent format */
- uint16 n) /* in: 16-bit integer in canonical format */
+ uint16 n) /*!< in: 16-bit integer in canonical format */
__attribute__((const));
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 3 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_3(
/*============*/
- byte* b, /* in: pointer to 3 bytes where to store */
- ulint n); /* in: ulint integer to be stored */
-/************************************************************
+ byte* b, /*!< in: pointer to 3 bytes where to store */
+ ulint n); /*!< in: ulint integer to be stored */
+/********************************************************//**
The following function is used to fetch data from 3 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return ulint integer */
UNIV_INLINE
ulint
mach_read_from_3(
/*=============*/
- /* out: ulint integer */
- const byte* b) /* in: pointer to 3 bytes */
+ const byte* b) /*!< in: pointer to 3 bytes */
__attribute__((nonnull, pure));
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in four consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_4(
/*============*/
- byte* b, /* in: pointer to four bytes where to store */
- ulint n); /* in: ulint integer to be stored */
-/************************************************************
+ byte* b, /*!< in: pointer to four bytes where to store */
+ ulint n); /*!< in: ulint integer to be stored */
+/********************************************************//**
The following function is used to fetch data from 4 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return ulint integer */
UNIV_INLINE
ulint
mach_read_from_4(
/*=============*/
- /* out: ulint integer */
- const byte* b) /* in: pointer to four bytes */
+ const byte* b) /*!< in: pointer to four bytes */
__attribute__((nonnull, pure));
-/*************************************************************
-Writes a ulint in a compressed form (1..5 bytes). */
+/*********************************************************//**
+Writes a ulint in a compressed form (1..5 bytes).
+@return stored size in bytes */
UNIV_INLINE
ulint
mach_write_compressed(
/*==================*/
- /* out: stored size in bytes */
- byte* b, /* in: pointer to memory where to store */
- ulint n); /* in: ulint integer to be stored */
-/*************************************************************
-Returns the size of an ulint when written in the compressed form. */
+ byte* b, /*!< in: pointer to memory where to store */
+ ulint n); /*!< in: ulint integer to be stored */
+/*********************************************************//**
+Returns the size of an ulint when written in the compressed form.
+@return compressed size in bytes */
UNIV_INLINE
ulint
mach_get_compressed_size(
/*=====================*/
- /* out: compressed size in bytes */
- ulint n) /* in: ulint integer to be stored */
+ ulint n) /*!< in: ulint integer to be stored */
__attribute__((const));
-/*************************************************************
-Reads a ulint in a compressed form. */
+/*********************************************************//**
+Reads a ulint in a compressed form.
+@return read integer */
UNIV_INLINE
ulint
mach_read_compressed(
/*=================*/
- /* out: read integer */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
__attribute__((nonnull, pure));
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 6 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_6(
/*============*/
- byte* b, /* in: pointer to 6 bytes where to store */
- dulint n); /* in: dulint integer to be stored */
-/************************************************************
+ byte* b, /*!< in: pointer to 6 bytes where to store */
+ dulint n); /*!< in: dulint integer to be stored */
+/********************************************************//**
The following function is used to fetch data from 6 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return dulint integer */
UNIV_INLINE
dulint
mach_read_from_6(
/*=============*/
- /* out: dulint integer */
- const byte* b) /* in: pointer to 6 bytes */
+ const byte* b) /*!< in: pointer to 6 bytes */
__attribute__((nonnull, pure));
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 7 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_7(
/*============*/
- byte* b, /* in: pointer to 7 bytes where to store */
- dulint n); /* in: dulint integer to be stored */
-/************************************************************
+ byte* b, /*!< in: pointer to 7 bytes where to store */
+ dulint n); /*!< in: dulint integer to be stored */
+/********************************************************//**
The following function is used to fetch data from 7 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return dulint integer */
UNIV_INLINE
dulint
mach_read_from_7(
/*=============*/
- /* out: dulint integer */
- const byte* b) /* in: pointer to 7 bytes */
+ const byte* b) /*!< in: pointer to 7 bytes */
__attribute__((nonnull, pure));
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 8 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_8(
/*============*/
- byte* b, /* in: pointer to 8 bytes where to store */
- dulint n); /* in: dulint integer to be stored */
-/***********************************************************
+ byte* b, /*!< in: pointer to 8 bytes where to store */
+ dulint n); /*!< in: dulint integer to be stored */
+/*******************************************************//**
The following function is used to store data in 8 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_ull(
/*===========*/
- byte* b, /* in: pointer to 8 bytes where to store */
- ib_uint64_t n); /* in: 64-bit integer to be stored */
-/************************************************************
+ byte* b, /*!< in: pointer to 8 bytes where to store */
+ ib_uint64_t n); /*!< in: 64-bit integer to be stored */
+/********************************************************//**
The following function is used to fetch data from 8 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return dulint integer */
UNIV_INLINE
dulint
mach_read_from_8(
/*=============*/
- /* out: dulint integer */
- const byte* b) /* in: pointer to 8 bytes */
+ const byte* b) /*!< in: pointer to 8 bytes */
__attribute__((nonnull, pure));
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 8 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return 64-bit integer */
UNIV_INLINE
ib_uint64_t
mach_read_ull(
/*==========*/
- /* out: 64-bit integer */
- const byte* b) /* in: pointer to 8 bytes */
+ const byte* b) /*!< in: pointer to 8 bytes */
__attribute__((nonnull, pure));
-/*************************************************************
-Writes a dulint in a compressed form (5..9 bytes). */
+/*********************************************************//**
+Writes a dulint in a compressed form (5..9 bytes).
+@return size in bytes */
UNIV_INLINE
ulint
mach_dulint_write_compressed(
/*=========================*/
- /* out: size in bytes */
- byte* b, /* in: pointer to memory where to store */
- dulint n); /* in: dulint integer to be stored */
-/*************************************************************
-Returns the size of a dulint when written in the compressed form. */
+ byte* b, /*!< in: pointer to memory where to store */
+ dulint n); /*!< in: dulint integer to be stored */
+/*********************************************************//**
+Returns the size of a dulint when written in the compressed form.
+@return compressed size in bytes */
UNIV_INLINE
ulint
mach_dulint_get_compressed_size(
/*============================*/
- /* out: compressed size in bytes */
- dulint n); /* in: dulint integer to be stored */
-/*************************************************************
-Reads a dulint in a compressed form. */
+ dulint n); /*!< in: dulint integer to be stored */
+/*********************************************************//**
+Reads a dulint in a compressed form.
+@return read dulint */
UNIV_INLINE
dulint
mach_dulint_read_compressed(
/*========================*/
- /* out: read dulint */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
__attribute__((nonnull, pure));
-/*************************************************************
-Writes a dulint in a compressed form (1..11 bytes). */
+/*********************************************************//**
+Writes a dulint in a compressed form (1..11 bytes).
+@return size in bytes */
UNIV_INLINE
ulint
mach_dulint_write_much_compressed(
/*==============================*/
- /* out: size in bytes */
- byte* b, /* in: pointer to memory where to store */
- dulint n); /* in: dulint integer to be stored */
-/*************************************************************
-Returns the size of a dulint when written in the compressed form. */
+ byte* b, /*!< in: pointer to memory where to store */
+ dulint n); /*!< in: dulint integer to be stored */
+/*********************************************************//**
+Returns the size of a dulint when written in the compressed form.
+@return compressed size in bytes */
UNIV_INLINE
ulint
mach_dulint_get_much_compressed_size(
/*=================================*/
- /* out: compressed size in bytes */
- dulint n) /* in: dulint integer to be stored */
+ dulint n) /*!< in: dulint integer to be stored */
__attribute__((const));
-/*************************************************************
-Reads a dulint in a compressed form. */
+/*********************************************************//**
+Reads a dulint in a compressed form.
+@return read dulint */
UNIV_INLINE
dulint
mach_dulint_read_much_compressed(
/*=============================*/
- /* out: read dulint */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
__attribute__((nonnull, pure));
-/*************************************************************
-Reads a ulint in a compressed form if the log record fully contains it. */
+/*********************************************************//**
+Reads a ulint in a compressed form if the log record fully contains it.
+@return pointer to end of the stored field, NULL if not complete */
UNIV_INTERN
byte*
mach_parse_compressed(
/*==================*/
- /* out: pointer to end of the stored field, NULL if
- not complete */
- byte* ptr, /* in: pointer to buffer from where to read */
- byte* end_ptr,/* in: pointer to end of the buffer */
- ulint* val); /* out: read value */
-/*************************************************************
-Reads a dulint in a compressed form if the log record fully contains it. */
+ byte* ptr, /*!< in: pointer to buffer from where to read */
+ byte* end_ptr,/*!< in: pointer to end of the buffer */
+ ulint* val); /*!< out: read value */
+/*********************************************************//**
+Reads a dulint in a compressed form if the log record fully contains it.
+@return pointer to end of the stored field, NULL if not complete */
UNIV_INTERN
byte*
mach_dulint_parse_compressed(
/*=========================*/
- /* out: pointer to end of the stored field, NULL if
- not complete */
- byte* ptr, /* in: pointer to buffer from where to read */
- byte* end_ptr,/* in: pointer to end of the buffer */
- dulint* val); /* out: read value */
-/*************************************************************
-Reads a double. It is stored in a little-endian format. */
+ byte* ptr, /*!< in: pointer to buffer from where to read */
+ byte* end_ptr,/*!< in: pointer to end of the buffer */
+ dulint* val); /*!< out: read value */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************//**
+Reads a double. It is stored in a little-endian format.
+@return double read */
UNIV_INLINE
double
mach_double_read(
/*=============*/
- /* out: double read */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
__attribute__((nonnull, pure));
-/*************************************************************
+/*********************************************************//**
Writes a double. It is stored in a little-endian format. */
UNIV_INLINE
void
mach_double_write(
/*==============*/
- byte* b, /* in: pointer to memory where to write */
- double d); /* in: double */
-/*************************************************************
-Reads a float. It is stored in a little-endian format. */
+ byte* b, /*!< in: pointer to memory where to write */
+ double d); /*!< in: double */
+/*********************************************************//**
+Reads a float. It is stored in a little-endian format.
+@return float read */
UNIV_INLINE
float
mach_float_read(
/*============*/
- /* out: float read */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
__attribute__((nonnull, pure));
-/*************************************************************
+/*********************************************************//**
Writes a float. It is stored in a little-endian format. */
UNIV_INLINE
void
mach_float_write(
/*=============*/
- byte* b, /* in: pointer to memory where to write */
- float d); /* in: float */
-/*************************************************************
-Reads a ulint stored in the little-endian format. */
+ byte* b, /*!< in: pointer to memory where to write */
+ float d); /*!< in: float */
+/*********************************************************//**
+Reads a ulint stored in the little-endian format.
+@return unsigned long int */
UNIV_INLINE
ulint
mach_read_from_n_little_endian(
/*===========================*/
- /* out: unsigned long int */
- const byte* buf, /* in: from where to read */
- ulint buf_size) /* in: from how many bytes to read */
+ const byte* buf, /*!< in: from where to read */
+ ulint buf_size) /*!< in: from how many bytes to read */
__attribute__((nonnull, pure));
-/*************************************************************
+/*********************************************************//**
Writes a ulint in the little-endian format. */
UNIV_INLINE
void
mach_write_to_n_little_endian(
/*==========================*/
- byte* dest, /* in: where to write */
- ulint dest_size, /* in: into how many bytes to write */
- ulint n); /* in: unsigned long int to write */
-/*************************************************************
-Reads a ulint stored in the little-endian format. */
+ byte* dest, /*!< in: where to write */
+ ulint dest_size, /*!< in: into how many bytes to write */
+ ulint n); /*!< in: unsigned long int to write */
+/*********************************************************//**
+Reads a ulint stored in the little-endian format.
+@return unsigned long int */
UNIV_INLINE
ulint
mach_read_from_2_little_endian(
/*===========================*/
- /* out: unsigned long int */
- const byte* buf) /* in: from where to read */
+ const byte* buf) /*!< in: from where to read */
__attribute__((nonnull, pure));
-/*************************************************************
+/*********************************************************//**
Writes a ulint in the little-endian format. */
UNIV_INLINE
void
mach_write_to_2_little_endian(
/*==========================*/
- byte* dest, /* in: where to write */
- ulint n); /* in: unsigned long int to write */
+ byte* dest, /*!< in: where to write */
+ ulint n); /*!< in: unsigned long int to write */
-/*************************************************************
+/*********************************************************//**
Convert integral type from storage byte order (big endian) to
-host byte order. */
+host byte order.
+@return integer value */
UNIV_INLINE
ullint
mach_read_int_type(
/*===============*/
- /* out: integer value */
- const byte* src, /* in: where to read from */
- ulint len, /* in: length of src */
- ibool unsigned_type); /* in: signed or unsigned flag */
+ const byte* src, /*!< in: where to read from */
+ ulint len, /*!< in: length of src */
+ ibool unsigned_type); /*!< in: signed or unsigned flag */
+#endif /* !UNIV_HOTBACKUP */
+
#ifndef UNIV_NONINL
#include "mach0data.ic"
#endif
diff --git a/storage/xtradb/include/mach0data.ic b/storage/xtradb/include/mach0data.ic
index 5dda9aece2f..ef20356bd31 100644
--- a/storage/xtradb/include/mach0data.ic
+++ b/storage/xtradb/include/mach0data.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/mach0data.ic
Utilities for converting data from the database file
to the machine format.
@@ -25,14 +26,14 @@ Created 11/28/1995 Heikki Tuuri
#include "ut0mem.h"
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in one byte. */
UNIV_INLINE
void
mach_write_to_1(
/*============*/
- byte* b, /* in: pointer to byte where to store */
- ulint n) /* in: ulint integer to be stored, >= 0, < 256 */
+ byte* b, /*!< in: pointer to byte where to store */
+ ulint n) /*!< in: ulint integer to be stored, >= 0, < 256 */
{
ut_ad(b);
ut_ad(n <= 0xFFUL);
@@ -40,28 +41,28 @@ mach_write_to_1(
b[0] = (byte)n;
}
-/************************************************************
-The following function is used to fetch data from one byte. */
+/********************************************************//**
+The following function is used to fetch data from one byte.
+@return ulint integer, >= 0, < 256 */
UNIV_INLINE
ulint
mach_read_from_1(
/*=============*/
- /* out: ulint integer, >= 0, < 256 */
- const byte* b) /* in: pointer to byte */
+ const byte* b) /*!< in: pointer to byte */
{
ut_ad(b);
return((ulint)(b[0]));
}
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in two consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_2(
/*============*/
- byte* b, /* in: pointer to two bytes where to store */
- ulint n) /* in: ulint integer to be stored */
+ byte* b, /*!< in: pointer to two bytes where to store */
+ ulint n) /*!< in: ulint integer to be stored */
{
ut_ad(b);
ut_ad(n <= 0xFFFFUL);
@@ -70,15 +71,15 @@ mach_write_to_2(
b[1] = (byte)(n);
}
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 2 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return ulint integer */
UNIV_INLINE
ulint
mach_read_from_2(
/*=============*/
- /* out: ulint integer */
- const byte* b) /* in: pointer to 2 bytes */
+ const byte* b) /*!< in: pointer to 2 bytes */
{
ut_ad(b);
return( ((ulint)(b[0]) << 8)
@@ -86,46 +87,46 @@ mach_read_from_2(
);
}
-/************************************************************
+/********************************************************//**
The following function is used to convert a 16-bit data item
to the canonical format, for fast bytewise equality test
-against memory. */
+against memory.
+@return 16-bit integer in canonical format */
UNIV_INLINE
uint16
mach_encode_2(
/*==========*/
- /* out: 16-bit integer in canonical format */
- ulint n) /* in: integer in machine-dependent format */
+ ulint n) /*!< in: integer in machine-dependent format */
{
uint16 ret;
ut_ad(2 == sizeof ret);
mach_write_to_2((byte*) &ret, n);
return(ret);
}
-/************************************************************
+/********************************************************//**
The following function is used to convert a 16-bit data item
from the canonical format, for fast bytewise equality test
-against memory. */
+against memory.
+@return integer in machine-dependent format */
UNIV_INLINE
ulint
mach_decode_2(
/*==========*/
- /* out: integer in machine-dependent format */
- uint16 n) /* in: 16-bit integer in canonical format */
+ uint16 n) /*!< in: 16-bit integer in canonical format */
{
ut_ad(2 == sizeof n);
return(mach_read_from_2((const byte*) &n));
}
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 3 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_3(
/*============*/
- byte* b, /* in: pointer to 3 bytes where to store */
- ulint n) /* in: ulint integer to be stored */
+ byte* b, /*!< in: pointer to 3 bytes where to store */
+ ulint n) /*!< in: ulint integer to be stored */
{
ut_ad(b);
ut_ad(n <= 0xFFFFFFUL);
@@ -135,15 +136,15 @@ mach_write_to_3(
b[2] = (byte)(n);
}
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 3 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return ulint integer */
UNIV_INLINE
ulint
mach_read_from_3(
/*=============*/
- /* out: ulint integer */
- const byte* b) /* in: pointer to 3 bytes */
+ const byte* b) /*!< in: pointer to 3 bytes */
{
ut_ad(b);
return( ((ulint)(b[0]) << 16)
@@ -152,15 +153,15 @@ mach_read_from_3(
);
}
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in four consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_4(
/*============*/
- byte* b, /* in: pointer to four bytes where to store */
- ulint n) /* in: ulint integer to be stored */
+ byte* b, /*!< in: pointer to four bytes where to store */
+ ulint n) /*!< in: ulint integer to be stored */
{
ut_ad(b);
@@ -170,15 +171,15 @@ mach_write_to_4(
b[3] = (byte)n;
}
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 4 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return ulint integer */
UNIV_INLINE
ulint
mach_read_from_4(
/*=============*/
- /* out: ulint integer */
- const byte* b) /* in: pointer to four bytes */
+ const byte* b) /*!< in: pointer to four bytes */
{
ut_ad(b);
return( ((ulint)(b[0]) << 24)
@@ -188,20 +189,20 @@ mach_read_from_4(
);
}
-/*************************************************************
+/*********************************************************//**
Writes a ulint in a compressed form where the first byte codes the
length of the stored ulint. We look at the most significant bits of
the byte. If the most significant bit is zero, it means 1-byte storage,
else if the 2nd bit is 0, it means 2-byte storage, else if 3rd is 0,
it means 3-byte storage, else if 4th is 0, it means 4-byte storage,
-else the storage is 5-byte. */
+else the storage is 5-byte.
+@return compressed size in bytes */
UNIV_INLINE
ulint
mach_write_compressed(
/*==================*/
- /* out: compressed size in bytes */
- byte* b, /* in: pointer to memory where to store */
- ulint n) /* in: ulint integer (< 2^32) to be stored */
+ byte* b, /*!< in: pointer to memory where to store */
+ ulint n) /*!< in: ulint integer (< 2^32) to be stored */
{
ut_ad(b);
@@ -224,14 +225,14 @@ mach_write_compressed(
}
}
-/*************************************************************
-Returns the size of a ulint when written in the compressed form. */
+/*********************************************************//**
+Returns the size of a ulint when written in the compressed form.
+@return compressed size in bytes */
UNIV_INLINE
ulint
mach_get_compressed_size(
/*=====================*/
- /* out: compressed size in bytes */
- ulint n) /* in: ulint integer (< 2^32) to be stored */
+ ulint n) /*!< in: ulint integer (< 2^32) to be stored */
{
if (n < 0x80UL) {
return(1);
@@ -246,14 +247,14 @@ mach_get_compressed_size(
}
}
-/*************************************************************
-Reads a ulint in a compressed form. */
+/*********************************************************//**
+Reads a ulint in a compressed form.
+@return read integer (< 2^32) */
UNIV_INLINE
ulint
mach_read_compressed(
/*=================*/
- /* out: read integer (< 2^32) */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
{
ulint flag;
@@ -275,15 +276,15 @@ mach_read_compressed(
}
}
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 8 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_8(
/*============*/
- byte* b, /* in: pointer to 8 bytes where to store */
- dulint n) /* in: dulint integer to be stored */
+ byte* b, /*!< in: pointer to 8 bytes where to store */
+ dulint n) /*!< in: dulint integer to be stored */
{
ut_ad(b);
@@ -291,15 +292,15 @@ mach_write_to_8(
mach_write_to_4(b + 4, ut_dulint_get_low(n));
}
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 8 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_ull(
/*===========*/
- byte* b, /* in: pointer to 8 bytes where to store */
- ib_uint64_t n) /* in: 64-bit integer to be stored */
+ byte* b, /*!< in: pointer to 8 bytes where to store */
+ ib_uint64_t n) /*!< in: 64-bit integer to be stored */
{
ut_ad(b);
@@ -307,15 +308,15 @@ mach_write_ull(
mach_write_to_4(b + 4, (ulint) n);
}
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 8 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return dulint integer */
UNIV_INLINE
dulint
mach_read_from_8(
/*=============*/
- /* out: dulint integer */
- const byte* b) /* in: pointer to 8 bytes */
+ const byte* b) /*!< in: pointer to 8 bytes */
{
ulint high;
ulint low;
@@ -328,15 +329,15 @@ mach_read_from_8(
return(ut_dulint_create(high, low));
}
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 8 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return 64-bit integer */
UNIV_INLINE
ib_uint64_t
mach_read_ull(
/*==========*/
- /* out: 64-bit integer */
- const byte* b) /* in: pointer to 8 bytes */
+ const byte* b) /*!< in: pointer to 8 bytes */
{
ib_uint64_t ull;
@@ -346,15 +347,15 @@ mach_read_ull(
return(ull);
}
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 7 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_7(
/*============*/
- byte* b, /* in: pointer to 7 bytes where to store */
- dulint n) /* in: dulint integer to be stored */
+ byte* b, /*!< in: pointer to 7 bytes where to store */
+ dulint n) /*!< in: dulint integer to be stored */
{
ut_ad(b);
@@ -362,15 +363,15 @@ mach_write_to_7(
mach_write_to_4(b + 3, ut_dulint_get_low(n));
}
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 7 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return dulint integer */
UNIV_INLINE
dulint
mach_read_from_7(
/*=============*/
- /* out: dulint integer */
- const byte* b) /* in: pointer to 7 bytes */
+ const byte* b) /*!< in: pointer to 7 bytes */
{
ulint high;
ulint low;
@@ -383,15 +384,15 @@ mach_read_from_7(
return(ut_dulint_create(high, low));
}
-/***********************************************************
+/*******************************************************//**
The following function is used to store data in 6 consecutive
bytes. We store the most significant byte to the lowest address. */
UNIV_INLINE
void
mach_write_to_6(
/*============*/
- byte* b, /* in: pointer to 6 bytes where to store */
- dulint n) /* in: dulint integer to be stored */
+ byte* b, /*!< in: pointer to 6 bytes where to store */
+ dulint n) /*!< in: dulint integer to be stored */
{
ut_ad(b);
@@ -399,15 +400,15 @@ mach_write_to_6(
mach_write_to_4(b + 2, ut_dulint_get_low(n));
}
-/************************************************************
+/********************************************************//**
The following function is used to fetch data from 6 consecutive
-bytes. The most significant byte is at the lowest address. */
+bytes. The most significant byte is at the lowest address.
+@return dulint integer */
UNIV_INLINE
dulint
mach_read_from_6(
/*=============*/
- /* out: dulint integer */
- const byte* b) /* in: pointer to 6 bytes */
+ const byte* b) /*!< in: pointer to 6 bytes */
{
ulint high;
ulint low;
@@ -420,15 +421,15 @@ mach_read_from_6(
return(ut_dulint_create(high, low));
}
-/*************************************************************
-Writes a dulint in a compressed form (5..9 bytes). */
+/*********************************************************//**
+Writes a dulint in a compressed form (5..9 bytes).
+@return size in bytes */
UNIV_INLINE
ulint
mach_dulint_write_compressed(
/*=========================*/
- /* out: size in bytes */
- byte* b, /* in: pointer to memory where to store */
- dulint n) /* in: dulint integer to be stored */
+ byte* b, /*!< in: pointer to memory where to store */
+ dulint n) /*!< in: dulint integer to be stored */
{
ulint size;
@@ -440,26 +441,26 @@ mach_dulint_write_compressed(
return(size + 4);
}
-/*************************************************************
-Returns the size of a dulint when written in the compressed form. */
+/*********************************************************//**
+Returns the size of a dulint when written in the compressed form.
+@return compressed size in bytes */
UNIV_INLINE
ulint
mach_dulint_get_compressed_size(
/*============================*/
- /* out: compressed size in bytes */
- dulint n) /* in: dulint integer to be stored */
+ dulint n) /*!< in: dulint integer to be stored */
{
return(4 + mach_get_compressed_size(ut_dulint_get_high(n)));
}
-/*************************************************************
-Reads a dulint in a compressed form. */
+/*********************************************************//**
+Reads a dulint in a compressed form.
+@return read dulint */
UNIV_INLINE
dulint
mach_dulint_read_compressed(
/*========================*/
- /* out: read dulint */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
{
ulint high;
ulint low;
@@ -476,15 +477,15 @@ mach_dulint_read_compressed(
return(ut_dulint_create(high, low));
}
-/*************************************************************
-Writes a dulint in a compressed form (1..11 bytes). */
+/*********************************************************//**
+Writes a dulint in a compressed form (1..11 bytes).
+@return size in bytes */
UNIV_INLINE
ulint
mach_dulint_write_much_compressed(
/*==============================*/
- /* out: size in bytes */
- byte* b, /* in: pointer to memory where to store */
- dulint n) /* in: dulint integer to be stored */
+ byte* b, /*!< in: pointer to memory where to store */
+ dulint n) /*!< in: dulint integer to be stored */
{
ulint size;
@@ -502,14 +503,14 @@ mach_dulint_write_much_compressed(
return(size);
}
-/*************************************************************
-Returns the size of a dulint when written in the compressed form. */
+/*********************************************************//**
+Returns the size of a dulint when written in the compressed form.
+@return compressed size in bytes */
UNIV_INLINE
ulint
mach_dulint_get_much_compressed_size(
/*=================================*/
- /* out: compressed size in bytes */
- dulint n) /* in: dulint integer to be stored */
+ dulint n) /*!< in: dulint integer to be stored */
{
if (0 == ut_dulint_get_high(n)) {
return(mach_get_compressed_size(ut_dulint_get_low(n)));
@@ -519,14 +520,14 @@ mach_dulint_get_much_compressed_size(
+ mach_get_compressed_size(ut_dulint_get_low(n)));
}
-/*************************************************************
-Reads a dulint in a compressed form. */
+/*********************************************************//**
+Reads a dulint in a compressed form.
+@return read dulint */
UNIV_INLINE
dulint
mach_dulint_read_much_compressed(
/*=============================*/
- /* out: read dulint */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
{
ulint high;
ulint low;
@@ -547,15 +548,15 @@ mach_dulint_read_much_compressed(
return(ut_dulint_create(high, low));
}
-
-/*************************************************************
-Reads a double. It is stored in a little-endian format. */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************//**
+Reads a double. It is stored in a little-endian format.
+@return double read */
UNIV_INLINE
double
mach_double_read(
/*=============*/
- /* out: double read */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
{
double d;
ulint i;
@@ -574,14 +575,14 @@ mach_double_read(
return(d);
}
-/*************************************************************
+/*********************************************************//**
Writes a double. It is stored in a little-endian format. */
UNIV_INLINE
void
mach_double_write(
/*==============*/
- byte* b, /* in: pointer to memory where to write */
- double d) /* in: double */
+ byte* b, /*!< in: pointer to memory where to write */
+ double d) /*!< in: double */
{
ulint i;
byte* ptr;
@@ -597,14 +598,14 @@ mach_double_write(
}
}
-/*************************************************************
-Reads a float. It is stored in a little-endian format. */
+/*********************************************************//**
+Reads a float. It is stored in a little-endian format.
+@return float read */
UNIV_INLINE
float
mach_float_read(
/*============*/
- /* out: float read */
- const byte* b) /* in: pointer to memory from where to read */
+ const byte* b) /*!< in: pointer to memory from where to read */
{
float d;
ulint i;
@@ -623,14 +624,14 @@ mach_float_read(
return(d);
}
-/*************************************************************
+/*********************************************************//**
Writes a float. It is stored in a little-endian format. */
UNIV_INLINE
void
mach_float_write(
/*=============*/
- byte* b, /* in: pointer to memory where to write */
- float d) /* in: float */
+ byte* b, /*!< in: pointer to memory where to write */
+ float d) /*!< in: float */
{
ulint i;
byte* ptr;
@@ -646,15 +647,15 @@ mach_float_write(
}
}
-/*************************************************************
-Reads a ulint stored in the little-endian format. */
+/*********************************************************//**
+Reads a ulint stored in the little-endian format.
+@return unsigned long int */
UNIV_INLINE
ulint
mach_read_from_n_little_endian(
/*===========================*/
- /* out: unsigned long int */
- const byte* buf, /* in: from where to read */
- ulint buf_size) /* in: from how many bytes to read */
+ const byte* buf, /*!< in: from where to read */
+ ulint buf_size) /*!< in: from how many bytes to read */
{
ulint n = 0;
const byte* ptr;
@@ -679,15 +680,15 @@ mach_read_from_n_little_endian(
return(n);
}
-/*************************************************************
+/*********************************************************//**
Writes a ulint in the little-endian format. */
UNIV_INLINE
void
mach_write_to_n_little_endian(
/*==========================*/
- byte* dest, /* in: where to write */
- ulint dest_size, /* in: into how many bytes to write */
- ulint n) /* in: unsigned long int to write */
+ byte* dest, /*!< in: where to write */
+ ulint dest_size, /*!< in: into how many bytes to write */
+ ulint n) /*!< in: unsigned long int to write */
{
byte* end;
@@ -711,26 +712,26 @@ mach_write_to_n_little_endian(
ut_ad(n == 0);
}
-/*************************************************************
-Reads a ulint stored in the little-endian format. */
+/*********************************************************//**
+Reads a ulint stored in the little-endian format.
+@return unsigned long int */
UNIV_INLINE
ulint
mach_read_from_2_little_endian(
/*===========================*/
- /* out: unsigned long int */
- const byte* buf) /* in: from where to read */
+ const byte* buf) /*!< in: from where to read */
{
return((ulint)(*buf) + ((ulint)(*(buf + 1))) * 256);
}
-/*************************************************************
+/*********************************************************//**
Writes a ulint in the little-endian format. */
UNIV_INLINE
void
mach_write_to_2_little_endian(
/*==========================*/
- byte* dest, /* in: where to write */
- ulint n) /* in: unsigned long int to write */
+ byte* dest, /*!< in: where to write */
+ ulint n) /*!< in: unsigned long int to write */
{
ut_ad(n < 256 * 256);
@@ -742,17 +743,17 @@ mach_write_to_2_little_endian(
*dest = (byte)(n & 0xFFUL);
}
-/*************************************************************
+/*********************************************************//**
Convert integral type from storage byte order (big endian) to
-host byte order. */
+host byte order.
+@return integer value */
UNIV_INLINE
ullint
mach_read_int_type(
/*===============*/
- /* out: integer value */
- const byte* src, /* in: where to read from */
- ulint len, /* in: length of src */
- ibool unsigned_type) /* in: signed or unsigned flag */
+ const byte* src, /*!< in: where to read from */
+ ulint len, /*!< in: length of src */
+ ibool unsigned_type) /*!< in: signed or unsigned flag */
{
/* XXX this can be optimized on big-endian machines */
@@ -782,3 +783,4 @@ mach_read_int_type(
return(ret);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/mem0dbg.h b/storage/xtradb/include/mem0dbg.h
index 0568a595d06..a064af5c678 100644
--- a/storage/xtradb/include/mem0dbg.h
+++ b/storage/xtradb/include/mem0dbg.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mem0dbg.h
The memory management: the debug code. This is not a compilation module,
but is included in mem0mem.* !
@@ -47,7 +48,7 @@ check fields at the both ends of the field. */
#endif
#if defined UNIV_MEM_DEBUG || defined UNIV_DEBUG
-/*******************************************************************
+/***************************************************************//**
Checks a memory heap for consistency and prints the contents if requested.
Outputs the sum of sizes of buffers given to the user (only in
the debug version), the physical size of the heap and the number of
@@ -57,83 +58,83 @@ UNIV_INTERN
void
mem_heap_validate_or_print(
/*=======================*/
- mem_heap_t* heap, /* in: memory heap */
- byte* top, /* in: calculate and validate only until
+ mem_heap_t* heap, /*!< in: memory heap */
+ byte* top, /*!< in: calculate and validate only until
this top pointer in the heap is reached,
if this pointer is NULL, ignored */
- ibool print, /* in: if TRUE, prints the contents
+ ibool print, /*!< in: if TRUE, prints the contents
of the heap; works only in
the debug version */
- ibool* error, /* out: TRUE if error */
- ulint* us_size,/* out: allocated memory
+ ibool* error, /*!< out: TRUE if error */
+ ulint* us_size,/*!< out: allocated memory
(for the user) in the heap,
if a NULL pointer is passed as this
argument, it is ignored; in the
non-debug version this is always -1 */
- ulint* ph_size,/* out: physical size of the heap,
+ ulint* ph_size,/*!< out: physical size of the heap,
if a NULL pointer is passed as this
argument, it is ignored */
- ulint* n_blocks); /* out: number of blocks in the heap,
+ ulint* n_blocks); /*!< out: number of blocks in the heap,
if a NULL pointer is passed as this
argument, it is ignored */
-/******************************************************************
-Validates the contents of a memory heap. */
+/**************************************************************//**
+Validates the contents of a memory heap.
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_heap_validate(
/*==============*/
- /* out: TRUE if ok */
- mem_heap_t* heap); /* in: memory heap */
+ mem_heap_t* heap); /*!< in: memory heap */
#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
#ifdef UNIV_DEBUG
-/******************************************************************
-Checks that an object is a memory heap (or a block of it) */
+/**************************************************************//**
+Checks that an object is a memory heap (or a block of it)
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_heap_check(
/*===========*/
- /* out: TRUE if ok */
- mem_heap_t* heap); /* in: memory heap */
+ mem_heap_t* heap); /*!< in: memory heap */
#endif /* UNIV_DEBUG */
#ifdef UNIV_MEM_DEBUG
-/*********************************************************************
-TRUE if no memory is currently allocated. */
+/*****************************************************************//**
+TRUE if no memory is currently allocated.
+@return TRUE if no heaps exist */
UNIV_INTERN
ibool
mem_all_freed(void);
/*===============*/
- /* out: TRUE if no heaps exist */
-/*********************************************************************
-Validates the dynamic memory */
+/*****************************************************************//**
+Validates the dynamic memory
+@return TRUE if error */
UNIV_INTERN
ibool
mem_validate_no_assert(void);
/*=========================*/
- /* out: TRUE if error */
-/****************************************************************
-Validates the dynamic memory */
+/************************************************************//**
+Validates the dynamic memory
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_validate(void);
/*===============*/
- /* out: TRUE if ok */
#endif /* UNIV_MEM_DEBUG */
-/****************************************************************
+/************************************************************//**
Tries to find neigboring memory allocation blocks and dumps to stderr
the neighborhood of a given pointer. */
UNIV_INTERN
void
mem_analyze_corruption(
/*===================*/
- void* ptr); /* in: pointer to place of possible corruption */
-/*********************************************************************
+ void* ptr); /*!< in: pointer to place of possible corruption */
+/*****************************************************************//**
Prints information of dynamic memory usage and currently allocated memory
heaps or buffers. Can only be used in the debug version. */
UNIV_INTERN
void
mem_print_info(void);
/*================*/
-/*********************************************************************
+/*****************************************************************//**
Prints information of dynamic memory usage and currently allocated memory
heaps or buffers since the last ..._print_info or..._print_new_info. */
UNIV_INTERN
diff --git a/storage/xtradb/include/mem0dbg.ic b/storage/xtradb/include/mem0dbg.ic
index bf695fee785..cb9245411dc 100644
--- a/storage/xtradb/include/mem0dbg.ic
+++ b/storage/xtradb/include/mem0dbg.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/mem0dbg.ic
The memory management: the debug code. This is not an independent
compilation module but is included in mem0mem.*.
@@ -24,44 +25,46 @@ Created 6/8/1994 Heikki Tuuri
*************************************************************************/
#ifdef UNIV_MEM_DEBUG
+# ifndef UNIV_HOTBACKUP
extern mutex_t mem_hash_mutex;
+# endif /* !UNIV_HOTBACKUP */
extern ulint mem_current_allocated_memory;
-/**********************************************************************
+/******************************************************************//**
Initializes an allocated memory field in the debug version. */
UNIV_INTERN
void
mem_field_init(
/*===========*/
- byte* buf, /* in: memory field */
- ulint n); /* in: how many bytes the user requested */
-/**********************************************************************
+ byte* buf, /*!< in: memory field */
+ ulint n); /*!< in: how many bytes the user requested */
+/******************************************************************//**
Erases an allocated memory field in the debug version. */
UNIV_INTERN
void
mem_field_erase(
/*============*/
- byte* buf, /* in: memory field */
- ulint n); /* in: how many bytes the user requested */
-/*******************************************************************
+ byte* buf, /*!< in: memory field */
+ ulint n); /*!< in: how many bytes the user requested */
+/***************************************************************//**
Initializes a buffer to a random combination of hex BA and BE.
Used to initialize allocated memory. */
UNIV_INTERN
void
mem_init_buf(
/*=========*/
- byte* buf, /* in: pointer to buffer */
- ulint n); /* in: length of buffer */
-/*******************************************************************
+ byte* buf, /*!< in: pointer to buffer */
+ ulint n); /*!< in: length of buffer */
+/***************************************************************//**
Initializes a buffer to a random combination of hex DE and AD.
-Used to erase freed memory.*/
+Used to erase freed memory. */
UNIV_INTERN
void
mem_erase_buf(
/*==========*/
- byte* buf, /* in: pointer to buffer */
- ulint n); /* in: length of buffer */
-/*******************************************************************
+ byte* buf, /*!< in: pointer to buffer */
+ ulint n); /*!< in: length of buffer */
+/***************************************************************//**
Inserts a created memory heap to the hash table of
current allocated memory heaps.
Initializes the hash table when first called. */
@@ -69,10 +72,10 @@ UNIV_INTERN
void
mem_hash_insert(
/*============*/
- mem_heap_t* heap, /* in: the created heap */
- const char* file_name, /* in: file name of creation */
- ulint line); /* in: line where created */
-/*******************************************************************
+ mem_heap_t* heap, /*!< in: the created heap */
+ const char* file_name, /*!< in: file name of creation */
+ ulint line); /*!< in: line where created */
+/***************************************************************//**
Removes a memory heap (which is going to be freed by the caller)
from the list of live memory heaps. Returns the size of the heap
in terms of how much memory in bytes was allocated for the user of
@@ -84,9 +87,9 @@ UNIV_INTERN
void
mem_hash_remove(
/*============*/
- mem_heap_t* heap, /* in: the heap to be freed */
- const char* file_name, /* in: file name of freeing */
- ulint line); /* in: line where freed */
+ mem_heap_t* heap, /*!< in: the heap to be freed */
+ const char* file_name, /*!< in: file name of freeing */
+ ulint line); /*!< in: line where freed */
void
diff --git a/storage/xtradb/include/mem0mem.h b/storage/xtradb/include/mem0mem.h
index c20e7815001..a092b024219 100644
--- a/storage/xtradb/include/mem0mem.h
+++ b/storage/xtradb/include/mem0mem.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mem0mem.h
The memory management
Created 6/9/1994 Heikki Tuuri
@@ -28,9 +29,10 @@ Created 6/9/1994 Heikki Tuuri
#include "univ.i"
#include "ut0mem.h"
#include "ut0byte.h"
-#include "ut0ut.h"
#include "ut0rnd.h"
-#include "sync0sync.h"
+#ifndef UNIV_HOTBACKUP
+# include "sync0sync.h"
+#endif /* UNIV_HOTBACKUP */
#include "ut0lst.h"
#include "mach0data.h"
@@ -73,26 +75,26 @@ allocations of small buffers. */
is the maximum size for a single allocated buffer: */
#define MEM_MAX_ALLOC_IN_BUF (UNIV_PAGE_SIZE - 200)
-/**********************************************************************
+/******************************************************************//**
Initializes the memory system. */
UNIV_INTERN
void
mem_init(
/*=====*/
- ulint size); /* in: common pool size in bytes */
-/******************************************************************
+ ulint size); /*!< in: common pool size in bytes */
+/**************************************************************//**
Use this macro instead of the corresponding function! Macro for memory
heap creation. */
#define mem_heap_create(N) mem_heap_create_func(\
(N), MEM_HEAP_DYNAMIC, __FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
Use this macro instead of the corresponding function! Macro for memory
heap creation. */
#define mem_heap_create_in_buffer(N) mem_heap_create_func(\
(N), MEM_HEAP_BUFFER, __FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
Use this macro instead of the corresponding function! Macro for memory
heap creation. */
@@ -100,31 +102,30 @@ heap creation. */
(N), MEM_HEAP_BTR_SEARCH | MEM_HEAP_BUFFER,\
__FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
Use this macro instead of the corresponding function! Macro for memory
heap freeing. */
#define mem_heap_free(heap) mem_heap_free_func(\
(heap), __FILE__, __LINE__)
-/*********************************************************************
+/*****************************************************************//**
NOTE: Use the corresponding macros instead of this function. Creates a
memory heap. For debugging purposes, takes also the file name and line as
-arguments. */
+arguments.
+@return own: memory heap, NULL if did not succeed (only possible for
+MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INLINE
mem_heap_t*
mem_heap_create_func(
/*=================*/
- /* out, own: memory heap, NULL if
- did not succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps)*/
- ulint n, /* in: desired start block size,
+ ulint n, /*!< in: desired start block size,
this means that a single user buffer
of size n will fit in the block,
0 creates a default size block */
- ulint type, /* in: heap type */
- const char* file_name, /* in: file name where created */
- ulint line); /* in: line where created */
-/*********************************************************************
+ ulint type, /*!< in: heap type */
+ const char* file_name, /*!< in: file name where created */
+ ulint line); /*!< in: line where created */
+/*****************************************************************//**
NOTE: Use the corresponding macro instead of this function. Frees the space
occupied by a memory heap. In the debug version erases the heap memory
blocks. */
@@ -132,42 +133,41 @@ UNIV_INLINE
void
mem_heap_free_func(
/*===============*/
- mem_heap_t* heap, /* in, own: heap to be freed */
- const char* file_name, /* in: file name where freed */
- ulint line); /* in: line where freed */
-/*******************************************************************
-Allocates and zero-fills n bytes of memory from a memory heap. */
+ mem_heap_t* heap, /*!< in, own: heap to be freed */
+ const char* file_name, /*!< in: file name where freed */
+ ulint line); /*!< in: line where freed */
+/***************************************************************//**
+Allocates and zero-fills n bytes of memory from a memory heap.
+@return allocated, zero-filled storage */
UNIV_INLINE
void*
mem_heap_zalloc(
/*============*/
- /* out: allocated, zero-filled storage */
- mem_heap_t* heap, /* in: memory heap */
- ulint n); /* in: number of bytes; if the heap is allowed
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n); /*!< in: number of bytes; if the heap is allowed
to grow into the buffer pool, this must be
<= MEM_MAX_ALLOC_IN_BUF */
-/*******************************************************************
-Allocates n bytes of memory from a memory heap. */
+/***************************************************************//**
+Allocates n bytes of memory from a memory heap.
+@return allocated storage, NULL if did not succeed (only possible for
+MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INLINE
void*
mem_heap_alloc(
/*===========*/
- /* out: allocated storage, NULL if did not
- succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps) */
- mem_heap_t* heap, /* in: memory heap */
- ulint n); /* in: number of bytes; if the heap is allowed
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n); /*!< in: number of bytes; if the heap is allowed
to grow into the buffer pool, this must be
<= MEM_MAX_ALLOC_IN_BUF */
-/*********************************************************************
-Returns a pointer to the heap top. */
+/*****************************************************************//**
+Returns a pointer to the heap top.
+@return pointer to the heap top */
UNIV_INLINE
byte*
mem_heap_get_heap_top(
/*==================*/
- /* out: pointer to the heap top */
- mem_heap_t* heap); /* in: memory heap */
-/*********************************************************************
+ mem_heap_t* heap); /*!< in: memory heap */
+/*****************************************************************//**
Frees the space in a memory heap exceeding the pointer given. The
pointer must have been acquired from mem_heap_get_heap_top. The first
memory block of the heap is not freed. */
@@ -175,42 +175,42 @@ UNIV_INLINE
void
mem_heap_free_heap_top(
/*===================*/
- mem_heap_t* heap, /* in: heap from which to free */
- byte* old_top);/* in: pointer to old top of heap */
-/*********************************************************************
+ mem_heap_t* heap, /*!< in: heap from which to free */
+ byte* old_top);/*!< in: pointer to old top of heap */
+/*****************************************************************//**
Empties a memory heap. The first memory block of the heap is not freed. */
UNIV_INLINE
void
mem_heap_empty(
/*===========*/
- mem_heap_t* heap); /* in: heap to empty */
-/*********************************************************************
+ mem_heap_t* heap); /*!< in: heap to empty */
+/*****************************************************************//**
Returns a pointer to the topmost element in a memory heap.
-The size of the element must be given. */
+The size of the element must be given.
+@return pointer to the topmost element */
UNIV_INLINE
void*
mem_heap_get_top(
/*=============*/
- /* out: pointer to the topmost element */
- mem_heap_t* heap, /* in: memory heap */
- ulint n); /* in: size of the topmost element */
-/*********************************************************************
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n); /*!< in: size of the topmost element */
+/*****************************************************************//**
Frees the topmost element in a memory heap.
The size of the element must be given. */
UNIV_INLINE
void
mem_heap_free_top(
/*==============*/
- mem_heap_t* heap, /* in: memory heap */
- ulint n); /* in: size of the topmost element */
-/*********************************************************************
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n); /*!< in: size of the topmost element */
+/*****************************************************************//**
Returns the space in bytes occupied by a memory heap. */
UNIV_INLINE
ulint
mem_heap_get_size(
/*==============*/
- mem_heap_t* heap); /* in: heap */
-/******************************************************************
+ mem_heap_t* heap); /*!< in: heap */
+/**************************************************************//**
Use this macro instead of the corresponding function!
Macro for memory buffer allocation */
@@ -218,28 +218,28 @@ Macro for memory buffer allocation */
#define mem_alloc(N) mem_alloc_func((N), NULL, __FILE__, __LINE__)
#define mem_alloc2(N,S) mem_alloc_func((N), (S), __FILE__, __LINE__)
-/*******************************************************************
+/***************************************************************//**
NOTE: Use the corresponding macro instead of this function.
Allocates a single buffer of memory from the dynamic memory of
the C compiler. Is like malloc of C. The buffer must be freed
-with mem_free. */
+with mem_free.
+@return own: free storage */
UNIV_INLINE
void*
mem_alloc_func(
/*===========*/
- /* out, own: free storage */
- ulint n, /* in: requested size in bytes */
- ulint* size, /* out: allocated size in bytes,
+ ulint n, /*!< in: requested size in bytes */
+ ulint* size, /*!< out: allocated size in bytes,
or NULL */
- const char* file_name, /* in: file name where created */
- ulint line); /* in: line where created */
+ const char* file_name, /*!< in: file name where created */
+ ulint line); /*!< in: line where created */
-/******************************************************************
+/**************************************************************//**
Use this macro instead of the corresponding function!
Macro for memory buffer freeing */
#define mem_free(PTR) mem_free_func((PTR), __FILE__, __LINE__)
-/*******************************************************************
+/***************************************************************//**
NOTE: Use the corresponding macro instead of this function.
Frees a single buffer of storage from
the dynamic memory of C compiler. Similar to free of C. */
@@ -247,103 +247,87 @@ UNIV_INLINE
void
mem_free_func(
/*==========*/
- void* ptr, /* in, own: buffer to be freed */
- const char* file_name, /* in: file name where created */
- ulint line /* in: line where created */
-);
+ void* ptr, /*!< in, own: buffer to be freed */
+ const char* file_name, /*!< in: file name where created */
+ ulint line); /*!< in: line where created */
-/**************************************************************************
-Duplicates a NUL-terminated string. */
+/**********************************************************************//**
+Duplicates a NUL-terminated string.
+@return own: a copy of the string, must be deallocated with mem_free */
UNIV_INLINE
char*
mem_strdup(
/*=======*/
- /* out, own: a copy of the string,
- must be deallocated with mem_free */
- const char* str); /* in: string to be copied */
-/**************************************************************************
-Makes a NUL-terminated copy of a nonterminated string. */
+ const char* str); /*!< in: string to be copied */
+/**********************************************************************//**
+Makes a NUL-terminated copy of a nonterminated string.
+@return own: a copy of the string, must be deallocated with mem_free */
UNIV_INLINE
char*
mem_strdupl(
/*========*/
- /* out, own: a copy of the string,
- must be deallocated with mem_free */
- const char* str, /* in: string to be copied */
- ulint len); /* in: length of str, in bytes */
+ const char* str, /*!< in: string to be copied */
+ ulint len); /*!< in: length of str, in bytes */
-/**************************************************************************
-Duplicates a NUL-terminated string, allocated from a memory heap. */
+/**********************************************************************//**
+Duplicates a NUL-terminated string, allocated from a memory heap.
+@return own: a copy of the string */
UNIV_INTERN
char*
mem_heap_strdup(
/*============*/
- /* out, own: a copy of the string */
- mem_heap_t* heap, /* in: memory heap where string is allocated */
- const char* str); /* in: string to be copied */
-/**************************************************************************
+ mem_heap_t* heap, /*!< in: memory heap where string is allocated */
+ const char* str); /*!< in: string to be copied */
+/**********************************************************************//**
Makes a NUL-terminated copy of a nonterminated string,
-allocated from a memory heap. */
+allocated from a memory heap.
+@return own: a copy of the string */
UNIV_INLINE
char*
mem_heap_strdupl(
/*=============*/
- /* out, own: a copy of the string */
- mem_heap_t* heap, /* in: memory heap where string is allocated */
- const char* str, /* in: string to be copied */
- ulint len); /* in: length of str, in bytes */
+ mem_heap_t* heap, /*!< in: memory heap where string is allocated */
+ const char* str, /*!< in: string to be copied */
+ ulint len); /*!< in: length of str, in bytes */
-/**************************************************************************
-Concatenate two strings and return the result, using a memory heap. */
+/**********************************************************************//**
+Concatenate two strings and return the result, using a memory heap.
+@return own: the result */
UNIV_INTERN
char*
mem_heap_strcat(
/*============*/
- /* out, own: the result */
- mem_heap_t* heap, /* in: memory heap where string is allocated */
- const char* s1, /* in: string 1 */
- const char* s2); /* in: string 2 */
+ mem_heap_t* heap, /*!< in: memory heap where string is allocated */
+ const char* s1, /*!< in: string 1 */
+ const char* s2); /*!< in: string 2 */
-/**************************************************************************
-Duplicate a block of data, allocated from a memory heap. */
+/**********************************************************************//**
+Duplicate a block of data, allocated from a memory heap.
+@return own: a copy of the data */
UNIV_INTERN
void*
mem_heap_dup(
/*=========*/
- /* out, own: a copy of the data */
- mem_heap_t* heap, /* in: memory heap where copy is allocated */
- const void* data, /* in: data to be copied */
- ulint len); /* in: length of data, in bytes */
+ mem_heap_t* heap, /*!< in: memory heap where copy is allocated */
+ const void* data, /*!< in: data to be copied */
+ ulint len); /*!< in: length of data, in bytes */
-/**************************************************************************
-Concatenate two memory blocks and return the result, using a memory heap. */
-UNIV_INTERN
-void*
-mem_heap_cat(
-/*=========*/
- /* out, own: the result */
- mem_heap_t* heap, /* in: memory heap where result is allocated */
- const void* b1, /* in: block 1 */
- ulint len1, /* in: length of b1, in bytes */
- const void* b2, /* in: block 2 */
- ulint len2); /* in: length of b2, in bytes */
-
-/********************************************************************
+/****************************************************************//**
A simple (s)printf replacement that dynamically allocates the space for the
formatted string from the given heap. This supports a very limited set of
the printf syntax: types 's' and 'u' and length modifier 'l' (which is
-required for the 'u' type). */
+required for the 'u' type).
+@return heap-allocated formatted string */
UNIV_INTERN
char*
mem_heap_printf(
/*============*/
- /* out: heap-allocated formatted string */
- mem_heap_t* heap, /* in: memory heap */
- const char* format, /* in: format string */
+ mem_heap_t* heap, /*!< in: memory heap */
+ const char* format, /*!< in: format string */
...) __attribute__ ((format (printf, 2, 3)));
#ifdef MEM_PERIODIC_CHECK
-/**********************************************************************
+/******************************************************************//**
Goes through the list of all allocated mem blocks, checks their magic
numbers, and reports possible corruption. */
UNIV_INTERN
@@ -359,7 +343,7 @@ mem_validate_all_blocks(void);
struct mem_block_info_struct {
ulint magic_n;/* magic number for debugging */
char file_name[8];/* file name where the mem heap was created */
- ulint line; /* line number where the mem heap was created */
+ ulint line; /*!< line number where the mem heap was created */
UT_LIST_BASE_NODE_T(mem_block_t) base; /* In the first block in the
the list this is the base node of the list of blocks;
in subsequent blocks this is undefined */
@@ -367,13 +351,14 @@ struct mem_block_info_struct {
and prev in the list. The first block allocated
to the heap is also the first block in this list,
though it also contains the base node of the list. */
- ulint len; /* physical length of this block in bytes */
- ulint type; /* type of heap: MEM_HEAP_DYNAMIC, or
+ ulint len; /*!< physical length of this block in bytes */
+ ulint type; /*!< type of heap: MEM_HEAP_DYNAMIC, or
MEM_HEAP_BUF possibly ORed to MEM_HEAP_BTR_SEARCH */
- ulint free; /* offset in bytes of the first free position for
+ ulint free; /*!< offset in bytes of the first free position for
user data in the block */
- ulint start; /* the value of the struct field 'free' at the
+ ulint start; /*!< the value of the struct field 'free' at the
creation of the block */
+#ifndef UNIV_HOTBACKUP
void* free_block;
/* if the MEM_HEAP_BTR_SEARCH bit is set in type,
and this is the heap root, this can contain an
@@ -384,6 +369,7 @@ struct mem_block_info_struct {
/* if this block has been allocated from the buffer
pool, this contains the buf_block_t handle;
otherwise, this is NULL */
+#endif /* !UNIV_HOTBACKUP */
#ifdef MEM_PERIODIC_CHECK
UT_LIST_NODE_T(mem_block_t) mem_block_list;
/* List of all mem blocks allocated; protected
diff --git a/storage/xtradb/include/mem0mem.ic b/storage/xtradb/include/mem0mem.ic
index 04b4234904a..e7080d8c508 100644
--- a/storage/xtradb/include/mem0mem.ic
+++ b/storage/xtradb/include/mem0mem.ic
@@ -16,58 +16,60 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/mem0mem.ic
The memory management
Created 6/8/1994 Heikki Tuuri
*************************************************************************/
#include "mem0dbg.ic"
-
-#include "mem0pool.h"
-
-/*******************************************************************
-Creates a memory heap block where data can be allocated. */
+#ifndef UNIV_HOTBACKUP
+# include "mem0pool.h"
+#endif /* !UNIV_HOTBACKUP */
+
+/***************************************************************//**
+Creates a memory heap block where data can be allocated.
+@return own: memory heap block, NULL if did not succeed (only possible
+for MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INTERN
mem_block_t*
mem_heap_create_block(
/*==================*/
- /* out, own: memory heap block, NULL if
- did not succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps) */
- mem_heap_t* heap, /* in: memory heap or NULL if first block
+ mem_heap_t* heap, /*!< in: memory heap or NULL if first block
should be created */
- ulint n, /* in: number of bytes needed for user data */
- ulint type, /* in: type of heap: MEM_HEAP_DYNAMIC or
+ ulint n, /*!< in: number of bytes needed for user data */
+ ulint type, /*!< in: type of heap: MEM_HEAP_DYNAMIC or
MEM_HEAP_BUFFER */
- const char* file_name,/* in: file name where created */
- ulint line); /* in: line where created */
-/**********************************************************************
+ const char* file_name,/*!< in: file name where created */
+ ulint line); /*!< in: line where created */
+/******************************************************************//**
Frees a block from a memory heap. */
UNIV_INTERN
void
mem_heap_block_free(
/*================*/
- mem_heap_t* heap, /* in: heap */
- mem_block_t* block); /* in: block to free */
-/**********************************************************************
+ mem_heap_t* heap, /*!< in: heap */
+ mem_block_t* block); /*!< in: block to free */
+#ifndef UNIV_HOTBACKUP
+/******************************************************************//**
Frees the free_block field from a memory heap. */
UNIV_INTERN
void
mem_heap_free_block_free(
/*=====================*/
- mem_heap_t* heap); /* in: heap */
-/*******************************************************************
-Adds a new block to a memory heap. */
+ mem_heap_t* heap); /*!< in: heap */
+#endif /* !UNIV_HOTBACKUP */
+/***************************************************************//**
+Adds a new block to a memory heap.
+@return created block, NULL if did not succeed (only possible for
+MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INTERN
mem_block_t*
mem_heap_add_block(
/*===============*/
- /* out: created block, NULL if did not
- succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps)*/
- mem_heap_t* heap, /* in: memory heap */
- ulint n); /* in: number of bytes user needs */
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n); /*!< in: number of bytes user needs */
UNIV_INLINE
void
@@ -135,15 +137,15 @@ mem_block_get_start(mem_block_t* block)
return(block->start);
}
-/*******************************************************************
-Allocates and zero-fills n bytes of memory from a memory heap. */
+/***************************************************************//**
+Allocates and zero-fills n bytes of memory from a memory heap.
+@return allocated, zero-filled storage */
UNIV_INLINE
void*
mem_heap_zalloc(
/*============*/
- /* out: allocated, zero-filled storage */
- mem_heap_t* heap, /* in: memory heap */
- ulint n) /* in: number of bytes; if the heap is allowed
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n) /*!< in: number of bytes; if the heap is allowed
to grow into the buffer pool, this must be
<= MEM_MAX_ALLOC_IN_BUF */
{
@@ -152,17 +154,16 @@ mem_heap_zalloc(
return(memset(mem_heap_alloc(heap, n), 0, n));
}
-/*******************************************************************
-Allocates n bytes of memory from a memory heap. */
+/***************************************************************//**
+Allocates n bytes of memory from a memory heap.
+@return allocated storage, NULL if did not succeed (only possible for
+MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INLINE
void*
mem_heap_alloc(
/*===========*/
- /* out: allocated storage, NULL if did not
- succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps) */
- mem_heap_t* heap, /* in: memory heap */
- ulint n) /* in: number of bytes; if the heap is allowed
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n) /*!< in: number of bytes; if the heap is allowed
to grow into the buffer pool, this must be
<= MEM_MAX_ALLOC_IN_BUF */
{
@@ -216,14 +217,14 @@ mem_heap_alloc(
return(buf);
}
-/*********************************************************************
-Returns a pointer to the heap top. */
+/*****************************************************************//**
+Returns a pointer to the heap top.
+@return pointer to the heap top */
UNIV_INLINE
byte*
mem_heap_get_heap_top(
/*==================*/
- /* out: pointer to the heap top */
- mem_heap_t* heap) /* in: memory heap */
+ mem_heap_t* heap) /*!< in: memory heap */
{
mem_block_t* block;
byte* buf;
@@ -237,7 +238,7 @@ mem_heap_get_heap_top(
return(buf);
}
-/*********************************************************************
+/*****************************************************************//**
Frees the space in a memory heap exceeding the pointer given. The
pointer must have been acquired from mem_heap_get_heap_top. The first
memory block of the heap is not freed. */
@@ -245,8 +246,8 @@ UNIV_INLINE
void
mem_heap_free_heap_top(
/*===================*/
- mem_heap_t* heap, /* in: heap from which to free */
- byte* old_top)/* in: pointer to old top of heap */
+ mem_heap_t* heap, /*!< in: heap from which to free */
+ byte* old_top)/*!< in: pointer to old top of heap */
{
mem_block_t* block;
mem_block_t* prev_block;
@@ -321,31 +322,32 @@ mem_heap_free_heap_top(
}
}
-/*********************************************************************
+/*****************************************************************//**
Empties a memory heap. The first memory block of the heap is not freed. */
UNIV_INLINE
void
mem_heap_empty(
/*===========*/
- mem_heap_t* heap) /* in: heap to empty */
+ mem_heap_t* heap) /*!< in: heap to empty */
{
mem_heap_free_heap_top(heap, (byte*)heap + mem_block_get_start(heap));
-
+#ifndef UNIV_HOTBACKUP
if (heap->free_block) {
mem_heap_free_block_free(heap);
}
+#endif /* !UNIV_HOTBACKUP */
}
-/*********************************************************************
+/*****************************************************************//**
Returns a pointer to the topmost element in a memory heap. The size of the
-element must be given. */
+element must be given.
+@return pointer to the topmost element */
UNIV_INLINE
void*
mem_heap_get_top(
/*=============*/
- /* out: pointer to the topmost element */
- mem_heap_t* heap, /* in: memory heap */
- ulint n) /* in: size of the topmost element */
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n) /*!< in: size of the topmost element */
{
mem_block_t* block;
void* buf;
@@ -371,15 +373,15 @@ mem_heap_get_top(
return(buf);
}
-/*********************************************************************
+/*****************************************************************//**
Frees the topmost element in a memory heap. The size of the element must be
given. */
UNIV_INLINE
void
mem_heap_free_top(
/*==============*/
- mem_heap_t* heap, /* in: memory heap */
- ulint n) /* in: size of the topmost element */
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n) /*!< in: size of the topmost element */
{
mem_block_t* block;
@@ -414,24 +416,23 @@ mem_heap_free_top(
}
}
-/*********************************************************************
+/*****************************************************************//**
NOTE: Use the corresponding macros instead of this function. Creates a
memory heap. For debugging purposes, takes also the file name and line as
-argument. */
+argument.
+@return own: memory heap, NULL if did not succeed (only possible for
+MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INLINE
mem_heap_t*
mem_heap_create_func(
/*=================*/
- /* out, own: memory heap, NULL if
- did not succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps)*/
- ulint n, /* in: desired start block size,
+ ulint n, /*!< in: desired start block size,
this means that a single user buffer
of size n will fit in the block,
0 creates a default size block */
- ulint type, /* in: heap type */
- const char* file_name, /* in: file name where created */
- ulint line) /* in: line where created */
+ ulint type, /*!< in: heap type */
+ const char* file_name, /*!< in: file name where created */
+ ulint line) /*!< in: line where created */
{
mem_block_t* block;
@@ -460,7 +461,7 @@ mem_heap_create_func(
return(block);
}
-/*********************************************************************
+/*****************************************************************//**
NOTE: Use the corresponding macro instead of this function. Frees the space
occupied by a memory heap. In the debug version erases the heap memory
blocks. */
@@ -468,9 +469,9 @@ UNIV_INLINE
void
mem_heap_free_func(
/*===============*/
- mem_heap_t* heap, /* in, own: heap to be freed */
+ mem_heap_t* heap, /*!< in, own: heap to be freed */
const char* file_name __attribute__((unused)),
- /* in: file name where freed */
+ /*!< in: file name where freed */
ulint line __attribute__((unused)))
{
mem_block_t* block;
@@ -488,10 +489,11 @@ mem_heap_free_func(
mem_hash_remove(heap, file_name, line);
#endif
-
+#ifndef UNIV_HOTBACKUP
if (heap->free_block) {
mem_heap_free_block_free(heap);
}
+#endif /* !UNIV_HOTBACKUP */
while (block != NULL) {
/* Store the contents of info before freeing current block
@@ -505,21 +507,21 @@ mem_heap_free_func(
}
}
-/*******************************************************************
+/***************************************************************//**
NOTE: Use the corresponding macro instead of this function.
Allocates a single buffer of memory from the dynamic memory of
the C compiler. Is like malloc of C. The buffer must be freed
-with mem_free. */
+with mem_free.
+@return own: free storage */
UNIV_INLINE
void*
mem_alloc_func(
/*===========*/
- /* out, own: free storage */
- ulint n, /* in: desired number of bytes */
- ulint* size, /* out: allocated size in bytes,
+ ulint n, /*!< in: desired number of bytes */
+ ulint* size, /*!< out: allocated size in bytes,
or NULL */
- const char* file_name, /* in: file name where created */
- ulint line) /* in: line where created */
+ const char* file_name, /*!< in: file name where created */
+ ulint line) /*!< in: line where created */
{
mem_heap_t* heap;
void* buf;
@@ -550,7 +552,7 @@ mem_alloc_func(
return(buf);
}
-/*******************************************************************
+/***************************************************************//**
NOTE: Use the corresponding macro instead of this function. Frees a single
buffer of storage from the dynamic memory of the C compiler. Similar to the
free of C. */
@@ -558,10 +560,9 @@ UNIV_INLINE
void
mem_free_func(
/*==========*/
- void* ptr, /* in, own: buffer to be freed */
- const char* file_name, /* in: file name where created */
- ulint line /* in: line where created */
- )
+ void* ptr, /*!< in, own: buffer to be freed */
+ const char* file_name, /*!< in: file name where created */
+ ulint line) /*!< in: line where created */
{
mem_heap_t* heap;
@@ -570,13 +571,13 @@ mem_free_func(
mem_heap_free_func(heap, file_name, line);
}
-/*********************************************************************
+/*****************************************************************//**
Returns the space in bytes occupied by a memory heap. */
UNIV_INLINE
ulint
mem_heap_get_size(
/*==============*/
- mem_heap_t* heap) /* in: heap */
+ mem_heap_t* heap) /*!< in: heap */
{
mem_block_t* block;
ulint size = 0;
@@ -590,55 +591,54 @@ mem_heap_get_size(
size += mem_block_get_len(block);
block = UT_LIST_GET_NEXT(list, block);
}
-
+#ifndef UNIV_HOTBACKUP
if (heap->free_block) {
size += UNIV_PAGE_SIZE;
}
+#endif /* !UNIV_HOTBACKUP */
return(size);
}
-/**************************************************************************
-Duplicates a NUL-terminated string. */
+/**********************************************************************//**
+Duplicates a NUL-terminated string.
+@return own: a copy of the string, must be deallocated with mem_free */
UNIV_INLINE
char*
mem_strdup(
/*=======*/
- /* out, own: a copy of the string,
- must be deallocated with mem_free */
- const char* str) /* in: string to be copied */
+ const char* str) /*!< in: string to be copied */
{
ulint len = strlen(str) + 1;
return((char*) memcpy(mem_alloc(len), str, len));
}
-/**************************************************************************
-Makes a NUL-terminated copy of a nonterminated string. */
+/**********************************************************************//**
+Makes a NUL-terminated copy of a nonterminated string.
+@return own: a copy of the string, must be deallocated with mem_free */
UNIV_INLINE
char*
mem_strdupl(
/*========*/
- /* out, own: a copy of the string,
- must be deallocated with mem_free */
- const char* str, /* in: string to be copied */
- ulint len) /* in: length of str, in bytes */
+ const char* str, /*!< in: string to be copied */
+ ulint len) /*!< in: length of str, in bytes */
{
char* s = (char*) mem_alloc(len + 1);
s[len] = 0;
return((char*) memcpy(s, str, len));
}
-/**************************************************************************
+/**********************************************************************//**
Makes a NUL-terminated copy of a nonterminated string,
-allocated from a memory heap. */
+allocated from a memory heap.
+@return own: a copy of the string */
UNIV_INLINE
char*
mem_heap_strdupl(
/*=============*/
- /* out, own: a copy of the string */
- mem_heap_t* heap, /* in: memory heap where string is allocated */
- const char* str, /* in: string to be copied */
- ulint len) /* in: length of str, in bytes */
+ mem_heap_t* heap, /*!< in: memory heap where string is allocated */
+ const char* str, /*!< in: string to be copied */
+ ulint len) /*!< in: length of str, in bytes */
{
char* s = (char*) mem_heap_alloc(heap, len + 1);
s[len] = 0;
diff --git a/storage/xtradb/include/mem0pool.h b/storage/xtradb/include/mem0pool.h
index 7e51b07bfe0..18f988241d6 100644
--- a/storage/xtradb/include/mem0pool.h
+++ b/storage/xtradb/include/mem0pool.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mem0pool.h
The lowest-level memory management
Created 6/9/1994 Heikki Tuuri
@@ -29,94 +30,96 @@ Created 6/9/1994 Heikki Tuuri
#include "os0file.h"
#include "ut0lst.h"
+/** Memory area header */
typedef struct mem_area_struct mem_area_t;
+/** Memory pool */
typedef struct mem_pool_struct mem_pool_t;
-/* The common memory pool */
+/** The common memory pool */
extern mem_pool_t* mem_comm_pool;
-/* Memory area header */
+/** Memory area header */
struct mem_area_struct{
- ulint size_and_free; /* memory area size is obtained by
+ ulint size_and_free; /*!< memory area size is obtained by
anding with ~MEM_AREA_FREE; area in
a free list if ANDing with
MEM_AREA_FREE results in nonzero */
UT_LIST_NODE_T(mem_area_t)
- free_list; /* free list node */
+ free_list; /*!< free list node */
};
-/* Each memory area takes this many extra bytes for control information */
+/** Each memory area takes this many extra bytes for control information */
#define MEM_AREA_EXTRA_SIZE (ut_calc_align(sizeof(struct mem_area_struct),\
UNIV_MEM_ALIGNMENT))
-/************************************************************************
-Creates a memory pool. */
+/********************************************************************//**
+Creates a memory pool.
+@return memory pool */
UNIV_INTERN
mem_pool_t*
mem_pool_create(
/*============*/
- /* out: memory pool */
- ulint size); /* in: pool size in bytes */
-/************************************************************************
+ ulint size); /*!< in: pool size in bytes */
+/********************************************************************//**
Allocates memory from a pool. NOTE: This low-level function should only be
-used in mem0mem.*! */
+used in mem0mem.*!
+@return own: allocated memory buffer */
UNIV_INTERN
void*
mem_area_alloc(
/*===========*/
- /* out, own: allocated memory buffer */
- ulint* psize, /* in: requested size in bytes; for optimum
+ ulint* psize, /*!< in: requested size in bytes; for optimum
space usage, the size should be a power of 2
minus MEM_AREA_EXTRA_SIZE;
out: allocated size in bytes (greater than
or equal to the requested size) */
- mem_pool_t* pool); /* in: memory pool */
-/************************************************************************
+ mem_pool_t* pool); /*!< in: memory pool */
+/********************************************************************//**
Frees memory to a pool. */
UNIV_INTERN
void
mem_area_free(
/*==========*/
- void* ptr, /* in, own: pointer to allocated memory
+ void* ptr, /*!< in, own: pointer to allocated memory
buffer */
- mem_pool_t* pool); /* in: memory pool */
-/************************************************************************
-Returns the amount of reserved memory. */
+ mem_pool_t* pool); /*!< in: memory pool */
+/********************************************************************//**
+Returns the amount of reserved memory.
+@return reserved mmeory in bytes */
UNIV_INTERN
ulint
mem_pool_get_reserved(
/*==================*/
- /* out: reserved mmeory in bytes */
- mem_pool_t* pool); /* in: memory pool */
-/************************************************************************
+ 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. */
+/********************************************************************//**
+Validates a memory pool.
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_pool_validate(
/*==============*/
- /* out: TRUE if ok */
- mem_pool_t* pool); /* in: memory pool */
-/************************************************************************
+ mem_pool_t* pool); /*!< in: memory pool */
+/********************************************************************//**
Prints info of a memory pool. */
UNIV_INTERN
void
mem_pool_print_info(
/*================*/
- FILE* outfile,/* in: output file to write to */
- mem_pool_t* pool); /* in: memory pool */
+ FILE* outfile,/*!< in: output file to write to */
+ mem_pool_t* pool); /*!< in: memory pool */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/mem0pool.ic b/storage/xtradb/include/mem0pool.ic
index 4cc65e754ce..b891dd6dea0 100644
--- a/storage/xtradb/include/mem0pool.ic
+++ b/storage/xtradb/include/mem0pool.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/mem0pool.ic
The lowest-level memory management
Created 6/8/1994 Heikki Tuuri
diff --git a/storage/xtradb/include/mtr0log.h b/storage/xtradb/include/mtr0log.h
index 44374cdf1a4..6322af2a569 100644
--- a/storage/xtradb/include/mtr0log.h
+++ b/storage/xtradb/include/mtr0log.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mtr0log.h
Mini-transaction logging routines
Created 12/7/1995 Heikki Tuuri
@@ -29,216 +30,218 @@ Created 12/7/1995 Heikki Tuuri
#include "mtr0mtr.h"
#include "dict0types.h"
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
Writes 1 - 4 bytes to a file page buffered in the buffer pool.
Writes the corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_write_ulint(
/*=============*/
- byte* ptr, /* in: pointer where to write */
- ulint val, /* in: value to write */
- byte type, /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
+ byte* ptr, /*!< in: pointer where to write */
+ ulint val, /*!< in: value to write */
+ byte type, /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
Writes 8 bytes to a file page buffered in the buffer pool.
Writes the corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_write_dulint(
/*==============*/
- byte* ptr, /* in: pointer where to write */
- dulint val, /* in: value to write */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
+ byte* ptr, /*!< in: pointer where to write */
+ dulint val, /*!< in: value to write */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
Writes a string to a file page buffered in the buffer pool. Writes the
corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_write_string(
/*==============*/
- byte* ptr, /* in: pointer where to write */
- const byte* str, /* in: string to write */
- ulint len, /* in: string length */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
+ byte* ptr, /*!< in: pointer where to write */
+ const byte* str, /*!< in: string to write */
+ ulint len, /*!< in: string length */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
Logs a write of a string to a file page buffered in the buffer pool.
Writes the corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_log_string(
/*============*/
- byte* ptr, /* in: pointer written to */
- ulint len, /* in: string length */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
+ byte* ptr, /*!< in: pointer written to */
+ ulint len, /*!< in: string length */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
Writes initial part of a log record consisting of one-byte item
type and four-byte space and page numbers. */
UNIV_INTERN
void
mlog_write_initial_log_record(
/*==========================*/
- const byte* ptr, /* in: pointer to (inside) a buffer
+ const byte* ptr, /*!< in: pointer to (inside) a buffer
frame holding the file page where
modification is made */
- byte type, /* in: log item type: MLOG_1BYTE, ... */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
-Writes a log record about an .ibd file create/delete/rename. */
+ byte type, /*!< in: log item type: MLOG_1BYTE, ... */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
+Writes a log record about an .ibd file create/delete/rename.
+@return new value of log_ptr */
UNIV_INLINE
byte*
mlog_write_initial_log_record_for_file_op(
/*======================================*/
- /* out: new value of log_ptr */
- ulint type, /* in: MLOG_FILE_CREATE, MLOG_FILE_DELETE, or
+ ulint type, /*!< in: MLOG_FILE_CREATE, MLOG_FILE_DELETE, or
MLOG_FILE_RENAME */
- ulint space_id,/* in: space id, if applicable */
- ulint page_no,/* in: page number (not relevant currently) */
- byte* log_ptr,/* in: pointer to mtr log which has been opened */
- mtr_t* mtr); /* in: mtr */
-/************************************************************
+ ulint space_id,/*!< in: space id, if applicable */
+ ulint page_no,/*!< in: page number (not relevant currently) */
+ byte* log_ptr,/*!< in: pointer to mtr log which has been opened */
+ mtr_t* mtr); /*!< in: mtr */
+/********************************************************//**
Catenates 1 - 4 bytes to the mtr log. */
UNIV_INLINE
void
mlog_catenate_ulint(
/*================*/
- mtr_t* mtr, /* in: mtr */
- ulint val, /* in: value to write */
- ulint type); /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
-/************************************************************
+ mtr_t* mtr, /*!< in: mtr */
+ ulint val, /*!< in: value to write */
+ ulint type); /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
+/********************************************************//**
Catenates n bytes to the mtr log. */
UNIV_INTERN
void
mlog_catenate_string(
/*=================*/
- mtr_t* mtr, /* in: mtr */
- const byte* str, /* in: string to write */
- ulint len); /* in: string length */
-/************************************************************
+ mtr_t* mtr, /*!< in: mtr */
+ const byte* str, /*!< in: string to write */
+ ulint len); /*!< in: string length */
+/********************************************************//**
Catenates a compressed ulint to mlog. */
UNIV_INLINE
void
mlog_catenate_ulint_compressed(
/*===========================*/
- mtr_t* mtr, /* in: mtr */
- ulint val); /* in: value to write */
-/************************************************************
+ mtr_t* mtr, /*!< in: mtr */
+ ulint val); /*!< in: value to write */
+/********************************************************//**
Catenates a compressed dulint to mlog. */
UNIV_INLINE
void
mlog_catenate_dulint_compressed(
/*============================*/
- mtr_t* mtr, /* in: mtr */
- dulint val); /* in: value to write */
-/************************************************************
-Opens a buffer to mlog. It must be closed with mlog_close. */
+ mtr_t* mtr, /*!< in: mtr */
+ dulint val); /*!< in: value to write */
+/********************************************************//**
+Opens a buffer to mlog. It must be closed with mlog_close.
+@return buffer, NULL if log mode MTR_LOG_NONE */
UNIV_INLINE
byte*
mlog_open(
/*======*/
- /* out: buffer, NULL if log mode MTR_LOG_NONE */
- mtr_t* mtr, /* in: mtr */
- ulint size); /* in: buffer size in bytes; MUST be
+ mtr_t* mtr, /*!< in: mtr */
+ ulint size); /*!< in: buffer size in bytes; MUST be
smaller than DYN_ARRAY_DATA_SIZE! */
-/************************************************************
+/********************************************************//**
Closes a buffer opened to mlog. */
UNIV_INLINE
void
mlog_close(
/*=======*/
- mtr_t* mtr, /* in: mtr */
- byte* ptr); /* in: buffer space from ptr up was not used */
-/************************************************************
+ mtr_t* mtr, /*!< in: mtr */
+ byte* ptr); /*!< in: buffer space from ptr up was not used */
+/********************************************************//**
Writes the initial part of a log record (3..11 bytes).
If the implementation of this function is changed, all
-size parameters to mlog_open() should be adjusted accordingly! */
+size parameters to mlog_open() should be adjusted accordingly!
+@return new value of log_ptr */
UNIV_INLINE
byte*
mlog_write_initial_log_record_fast(
/*===============================*/
- /* out: new value of log_ptr */
- const byte* ptr, /* in: pointer to (inside) a buffer
+ const byte* ptr, /*!< in: pointer to (inside) a buffer
frame holding the file page where
modification is made */
- byte type, /* in: log item type: MLOG_1BYTE, ... */
- byte* log_ptr,/* in: pointer to mtr log which has
+ byte type, /*!< in: log item type: MLOG_1BYTE, ... */
+ byte* log_ptr,/*!< in: pointer to mtr log which has
been opened */
- mtr_t* mtr); /* in: mtr */
-/************************************************************
-Parses an initial log record written by mlog_write_initial_log_record. */
+ mtr_t* mtr); /*!< in: mtr */
+#else /* !UNIV_HOTBACKUP */
+# define mlog_write_initial_log_record(ptr,type,mtr) ((void) 0)
+# define mlog_write_initial_log_record_fast(ptr,type,log_ptr,mtr) ((byte *) 0)
+#endif /* !UNIV_HOTBACKUP */
+/********************************************************//**
+Parses an initial log record written by mlog_write_initial_log_record.
+@return parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_initial_log_record(
/*==========================*/
- /* out: parsed record end, NULL if not a complete
- record */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- byte* type, /* out: log record type: MLOG_1BYTE, ... */
- ulint* space, /* out: space id */
- ulint* page_no);/* out: page number */
-/************************************************************
-Parses a log record written by mlog_write_ulint or mlog_write_dulint. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ byte* type, /*!< out: log record type: MLOG_1BYTE, ... */
+ ulint* space, /*!< out: space id */
+ ulint* page_no);/*!< out: page number */
+/********************************************************//**
+Parses a log record written by mlog_write_ulint or mlog_write_dulint.
+@return parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_nbytes(
/*==============*/
- /* out: parsed record end, NULL if not a complete
- record */
- ulint type, /* in: log record type: MLOG_1BYTE, ... */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- byte* page, /* in: page where to apply the log record, or NULL */
- void* page_zip);/* in/out: compressed page, or NULL */
-/************************************************************
-Parses a log record written by mlog_write_string. */
+ ulint type, /*!< in: log record type: MLOG_1BYTE, ... */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ byte* page, /*!< in: page where to apply the log record, or NULL */
+ void* page_zip);/*!< in/out: compressed page, or NULL */
+/********************************************************//**
+Parses a log record written by mlog_write_string.
+@return parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_string(
/*==============*/
- /* out: parsed record end, NULL if not a complete
- record */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- byte* page, /* in: page where to apply the log record, or NULL */
- void* page_zip);/* in/out: compressed page, or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ byte* page, /*!< in: page where to apply the log record, or NULL */
+ void* page_zip);/*!< in/out: compressed page, or NULL */
-
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
Opens a buffer for mlog, writes the initial log record and,
if needed, the field lengths of an index. Reserves space
for further log entries. The log entry must be closed with
-mtr_close(). */
+mtr_close().
+@return buffer, NULL if log mode MTR_LOG_NONE */
UNIV_INTERN
byte*
mlog_open_and_write_index(
/*======================*/
- /* out: buffer, NULL if log mode
- MTR_LOG_NONE */
- mtr_t* mtr, /* in: mtr */
- byte* rec, /* in: index record or page */
- dict_index_t* index, /* in: record descriptor */
- byte type, /* in: log item type */
- ulint size); /* in: requested buffer size in bytes
+ mtr_t* mtr, /*!< in: mtr */
+ const byte* rec, /*!< in: index record or page */
+ dict_index_t* index, /*!< in: record descriptor */
+ byte type, /*!< in: log item type */
+ ulint size); /*!< in: requested buffer size in bytes
(if 0, calls mlog_close() and returns NULL) */
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************
-Parses a log record written by mlog_open_and_write_index. */
+/********************************************************//**
+Parses a log record written by mlog_open_and_write_index.
+@return parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_index(
/*=============*/
- /* out: parsed record end,
- NULL if not a complete record */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- /* out: new value of log_ptr */
- ibool comp, /* in: TRUE=compact record format */
- dict_index_t** index); /* out, own: dummy index */
+ byte* ptr, /*!< in: buffer */
+ const byte* end_ptr,/*!< in: buffer end */
+ ibool comp, /*!< in: TRUE=compact record format */
+ dict_index_t** index); /*!< out, own: dummy index */
+#ifndef UNIV_HOTBACKUP
/* Insert, update, and maybe other functions may use this value to define an
extra mlog buffer size for variable size data */
#define MLOG_BUF_MARGIN 256
+#endif /* !UNIV_HOTBACKUP */
#ifndef UNIV_NONINL
#include "mtr0log.ic"
diff --git a/storage/xtradb/include/mtr0log.ic b/storage/xtradb/include/mtr0log.ic
index 5f05befb9cc..5c24c38b337 100644
--- a/storage/xtradb/include/mtr0log.ic
+++ b/storage/xtradb/include/mtr0log.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mtr0log.ic
Mini-transaction logging routines
Created 12/7/1995 Heikki Tuuri
@@ -25,16 +26,18 @@ Created 12/7/1995 Heikki Tuuri
#include "mach0data.h"
#include "ut0lst.h"
#include "buf0buf.h"
+#include "fsp0types.h"
+#include "trx0sys.h"
-/************************************************************
-Opens a buffer to mlog. It must be closed with mlog_close. */
+/********************************************************//**
+Opens a buffer to mlog. It must be closed with mlog_close.
+@return buffer, NULL if log mode MTR_LOG_NONE */
UNIV_INLINE
byte*
mlog_open(
/*======*/
- /* out: buffer, NULL if log mode MTR_LOG_NONE */
- mtr_t* mtr, /* in: mtr */
- ulint size) /* in: buffer size in bytes; MUST be
+ mtr_t* mtr, /*!< in: mtr */
+ ulint size) /*!< in: buffer size in bytes; MUST be
smaller than DYN_ARRAY_DATA_SIZE! */
{
dyn_array_t* mlog;
@@ -51,14 +54,14 @@ mlog_open(
return(dyn_array_open(mlog, size));
}
-/************************************************************
+/********************************************************//**
Closes a buffer opened to mlog. */
UNIV_INLINE
void
mlog_close(
/*=======*/
- mtr_t* mtr, /* in: mtr */
- byte* ptr) /* in: buffer space from ptr up was not used */
+ mtr_t* mtr, /*!< in: mtr */
+ byte* ptr) /*!< in: buffer space from ptr up was not used */
{
dyn_array_t* mlog;
@@ -69,15 +72,16 @@ mlog_close(
dyn_array_close(mlog, ptr);
}
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
Catenates 1 - 4 bytes to the mtr log. The value is not compressed. */
UNIV_INLINE
void
mlog_catenate_ulint(
/*================*/
- mtr_t* mtr, /* in: mtr */
- ulint val, /* in: value to write */
- ulint type) /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint val, /*!< in: value to write */
+ ulint type) /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
{
dyn_array_t* mlog;
byte* ptr;
@@ -113,14 +117,14 @@ mlog_catenate_ulint(
}
}
-/************************************************************
+/********************************************************//**
Catenates a compressed ulint to mlog. */
UNIV_INLINE
void
mlog_catenate_ulint_compressed(
/*===========================*/
- mtr_t* mtr, /* in: mtr */
- ulint val) /* in: value to write */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint val) /*!< in: value to write */
{
byte* log_ptr;
@@ -137,14 +141,14 @@ mlog_catenate_ulint_compressed(
mlog_close(mtr, log_ptr);
}
-/************************************************************
+/********************************************************//**
Catenates a compressed dulint to mlog. */
UNIV_INLINE
void
mlog_catenate_dulint_compressed(
/*============================*/
- mtr_t* mtr, /* in: mtr */
- dulint val) /* in: value to write */
+ mtr_t* mtr, /*!< in: mtr */
+ dulint val) /*!< in: value to write */
{
byte* log_ptr;
@@ -161,22 +165,22 @@ mlog_catenate_dulint_compressed(
mlog_close(mtr, log_ptr);
}
-/************************************************************
+/********************************************************//**
Writes the initial part of a log record (3..11 bytes).
If the implementation of this function is changed, all
-size parameters to mlog_open() should be adjusted accordingly! */
+size parameters to mlog_open() should be adjusted accordingly!
+@return new value of log_ptr */
UNIV_INLINE
byte*
mlog_write_initial_log_record_fast(
/*===============================*/
- /* out: new value of log_ptr */
- const byte* ptr, /* in: pointer to (inside) a buffer
+ const byte* ptr, /*!< in: pointer to (inside) a buffer
frame holding the file page where
modification is made */
- byte type, /* in: log item type: MLOG_1BYTE, ... */
- byte* log_ptr,/* in: pointer to mtr log which has
+ byte type, /*!< in: log item type: MLOG_1BYTE, ... */
+ byte* log_ptr,/*!< in: pointer to mtr log which has
been opened */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
#ifdef UNIV_DEBUG
buf_block_t* block;
@@ -193,6 +197,28 @@ mlog_write_initial_log_record_fast(
space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
offset = mach_read_from_4(page + FIL_PAGE_OFFSET);
+ /* check whether the page is in the doublewrite buffer;
+ the doublewrite buffer is located in pages
+ FSP_EXTENT_SIZE, ..., 3 * FSP_EXTENT_SIZE - 1 in the
+ system tablespace */
+ if (space == TRX_SYS_SPACE
+ && offset >= FSP_EXTENT_SIZE && offset < 3 * 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
+ anything for the doublewrite buffer pages. */
+ return(log_ptr);
+ } else {
+ fprintf(stderr,
+ "Error: trying to redo log a record of type "
+ "%d on page %lu of space %lu in the "
+ "doublewrite buffer, continuing anyway.\n"
+ "Please post a bug report to "
+ "bugs.mysql.com.\n",
+ type, offset, space);
+ }
+ }
+
mach_write_to_1(log_ptr, type);
log_ptr++;
log_ptr += mach_write_compressed(log_ptr, space);
@@ -218,19 +244,19 @@ mlog_write_initial_log_record_fast(
return(log_ptr);
}
-/************************************************************
-Writes a log record about an .ibd file create/delete/rename. */
+/********************************************************//**
+Writes a log record about an .ibd file create/delete/rename.
+@return new value of log_ptr */
UNIV_INLINE
byte*
mlog_write_initial_log_record_for_file_op(
/*======================================*/
- /* out: new value of log_ptr */
- ulint type, /* in: MLOG_FILE_CREATE, MLOG_FILE_DELETE, or
+ ulint type, /*!< in: MLOG_FILE_CREATE, MLOG_FILE_DELETE, or
MLOG_FILE_RENAME */
- ulint space_id,/* in: space id, if applicable */
- ulint page_no,/* in: page number (not relevant currently) */
- byte* log_ptr,/* in: pointer to mtr log which has been opened */
- mtr_t* mtr) /* in: mtr */
+ ulint space_id,/*!< in: space id, if applicable */
+ ulint page_no,/*!< in: page number (not relevant currently) */
+ byte* log_ptr,/*!< in: pointer to mtr log which has been opened */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(log_ptr);
@@ -245,3 +271,4 @@ mlog_write_initial_log_record_for_file_op(
return(log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/mtr0mtr.h b/storage/xtradb/include/mtr0mtr.h
index a29f6c73141..69a2c03f4cb 100644
--- a/storage/xtradb/include/mtr0mtr.h
+++ b/storage/xtradb/include/mtr0mtr.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mtr0mtr.h
Mini-transaction buffer
Created 11/26/1995 Heikki Tuuri
@@ -53,139 +54,163 @@ first 3 values must be RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
#define MTR_MEMO_S_LOCK 55
#define MTR_MEMO_X_LOCK 56
-/* Log item types: we have made them to be of the type 'byte'
-for the compiler to warn if val and type parameters are switched
-in a call to mlog_write_ulint. NOTE! For 1 - 8 bytes, the
-flag value must give the length also! */
-#define MLOG_SINGLE_REC_FLAG 128 /* if the mtr contains only
+/** @name Log item types
+The log items are declared 'byte' so that the compiler can warn if val
+and type parameters are switched in a call to mlog_write_ulint. NOTE!
+For 1 - 8 bytes, the flag value must give the length also! @{ */
+#define MLOG_SINGLE_REC_FLAG 128 /*!< if the mtr contains only
one log record for one page,
i.e., write_initial_log_record
has been called only once,
this flag is ORed to the type
of that first log record */
-#define MLOG_1BYTE (1) /* one byte is written */
-#define MLOG_2BYTES (2) /* 2 bytes ... */
-#define MLOG_4BYTES (4) /* 4 bytes ... */
-#define MLOG_8BYTES (8) /* 8 bytes ... */
-#define MLOG_REC_INSERT ((byte)9) /* record insert */
-#define MLOG_REC_CLUST_DELETE_MARK ((byte)10) /* mark clustered index record
+#define MLOG_1BYTE (1) /*!< one byte is written */
+#define MLOG_2BYTES (2) /*!< 2 bytes ... */
+#define MLOG_4BYTES (4) /*!< 4 bytes ... */
+#define MLOG_8BYTES (8) /*!< 8 bytes ... */
+#define MLOG_REC_INSERT ((byte)9) /*!< record insert */
+#define MLOG_REC_CLUST_DELETE_MARK ((byte)10) /*!< mark clustered index record
deleted */
-#define MLOG_REC_SEC_DELETE_MARK ((byte)11) /* mark secondary index record
+#define MLOG_REC_SEC_DELETE_MARK ((byte)11) /*!< mark secondary index record
deleted */
-#define MLOG_REC_UPDATE_IN_PLACE ((byte)13) /* update of a record,
+#define MLOG_REC_UPDATE_IN_PLACE ((byte)13) /*!< update of a record,
preserves record field sizes */
-#define MLOG_REC_DELETE ((byte)14) /* delete a record from a
+#define MLOG_REC_DELETE ((byte)14) /*!< delete a record from a
page */
-#define MLOG_LIST_END_DELETE ((byte)15) /* delete record list end on
+#define MLOG_LIST_END_DELETE ((byte)15) /*!< delete record list end on
index page */
-#define MLOG_LIST_START_DELETE ((byte)16) /* delete record list start on
+#define MLOG_LIST_START_DELETE ((byte)16) /*!< delete record list start on
index page */
-#define MLOG_LIST_END_COPY_CREATED ((byte)17) /* copy record list end to a
+#define MLOG_LIST_END_COPY_CREATED ((byte)17) /*!< copy record list end to a
new created index page */
-#define MLOG_PAGE_REORGANIZE ((byte)18) /* reorganize an index page */
-#define MLOG_PAGE_CREATE ((byte)19) /* create an index page */
-#define MLOG_UNDO_INSERT ((byte)20) /* insert entry in an undo
+#define MLOG_PAGE_REORGANIZE ((byte)18) /*!< reorganize an
+ index page in
+ ROW_FORMAT=REDUNDANT */
+#define MLOG_PAGE_CREATE ((byte)19) /*!< create an index page */
+#define MLOG_UNDO_INSERT ((byte)20) /*!< insert entry in an undo
log */
-#define MLOG_UNDO_ERASE_END ((byte)21) /* erase an undo log
+#define MLOG_UNDO_ERASE_END ((byte)21) /*!< erase an undo log
page end */
-#define MLOG_UNDO_INIT ((byte)22) /* initialize a page in an
+#define MLOG_UNDO_INIT ((byte)22) /*!< initialize a page in an
undo log */
-#define MLOG_UNDO_HDR_DISCARD ((byte)23) /* discard an update undo log
+#define MLOG_UNDO_HDR_DISCARD ((byte)23) /*!< discard an update undo log
header */
-#define MLOG_UNDO_HDR_REUSE ((byte)24) /* reuse an insert undo log
+#define MLOG_UNDO_HDR_REUSE ((byte)24) /*!< reuse an insert undo log
header */
-#define MLOG_UNDO_HDR_CREATE ((byte)25) /* create an undo log header */
-#define MLOG_REC_MIN_MARK ((byte)26) /* mark an index record as the
- predefined minimum record */
-#define MLOG_IBUF_BITMAP_INIT ((byte)27) /* initialize an ibuf bitmap
- page */
+#define MLOG_UNDO_HDR_CREATE ((byte)25) /*!< create an undo
+ log header */
+#define MLOG_REC_MIN_MARK ((byte)26) /*!< mark an index
+ record as the
+ predefined minimum
+ record */
+#define MLOG_IBUF_BITMAP_INIT ((byte)27) /*!< initialize an
+ ibuf bitmap page */
/*#define MLOG_FULL_PAGE ((byte)28) full contents of a page */
-#define MLOG_INIT_FILE_PAGE ((byte)29) /* this means that a file page
- is taken into use and the prior
- contents of the page should be
- ignored: in recovery we must
- not trust the lsn values stored
- to the file page */
-#define MLOG_WRITE_STRING ((byte)30) /* write a string to a page */
-#define MLOG_MULTI_REC_END ((byte)31) /* if a single mtr writes
+#define MLOG_INIT_FILE_PAGE ((byte)29) /*!< this means that a
+ file page is taken
+ into use and the prior
+ contents of the page
+ should be ignored: in
+ recovery we must not
+ trust the lsn values
+ stored to the file
+ page */
+#define MLOG_WRITE_STRING ((byte)30) /*!< write a string to
+ a page */
+#define MLOG_MULTI_REC_END ((byte)31) /*!< if a single mtr writes
log records for several pages,
this log record ends the
sequence of these records */
-#define MLOG_DUMMY_RECORD ((byte)32) /* dummy log record used to
+#define MLOG_DUMMY_RECORD ((byte)32) /*!< dummy log record used to
pad a log block full */
-#define MLOG_FILE_CREATE ((byte)33) /* log record about an .ibd
+#define MLOG_FILE_CREATE ((byte)33) /*!< log record about an .ibd
file creation */
-#define MLOG_FILE_RENAME ((byte)34) /* log record about an .ibd
+#define MLOG_FILE_RENAME ((byte)34) /*!< log record about an .ibd
file rename */
-#define MLOG_FILE_DELETE ((byte)35) /* log record about an .ibd
+#define MLOG_FILE_DELETE ((byte)35) /*!< log record about an .ibd
file deletion */
-#define MLOG_COMP_REC_MIN_MARK ((byte)36) /* mark a compact index record
- as the predefined minimum
+#define MLOG_COMP_REC_MIN_MARK ((byte)36) /*!< mark a compact
+ index record as the
+ predefined minimum
record */
-#define MLOG_COMP_PAGE_CREATE ((byte)37) /* create a compact
+#define MLOG_COMP_PAGE_CREATE ((byte)37) /*!< create a compact
index page */
-#define MLOG_COMP_REC_INSERT ((byte)38) /* compact record insert */
+#define MLOG_COMP_REC_INSERT ((byte)38) /*!< compact record insert */
#define MLOG_COMP_REC_CLUST_DELETE_MARK ((byte)39)
- /* mark compact clustered index
- record deleted */
-#define MLOG_COMP_REC_SEC_DELETE_MARK ((byte)40)/* mark compact secondary index
- record deleted; this log
- record type is redundant, as
- MLOG_REC_SEC_DELETE_MARK is
- independent of the record
- format. */
-#define MLOG_COMP_REC_UPDATE_IN_PLACE ((byte)41)/* update of a compact record,
- preserves record field sizes */
-#define MLOG_COMP_REC_DELETE ((byte)42) /* delete a compact record
+ /*!< mark compact
+ clustered index record
+ deleted */
+#define MLOG_COMP_REC_SEC_DELETE_MARK ((byte)40)/*!< mark compact
+ secondary index record
+ deleted; this log
+ record type is
+ redundant, as
+ MLOG_REC_SEC_DELETE_MARK
+ is independent of the
+ record format. */
+#define MLOG_COMP_REC_UPDATE_IN_PLACE ((byte)41)/*!< update of a
+ compact record,
+ preserves record field
+ sizes */
+#define MLOG_COMP_REC_DELETE ((byte)42) /*!< delete a compact record
from a page */
-#define MLOG_COMP_LIST_END_DELETE ((byte)43) /* delete compact record list
+#define MLOG_COMP_LIST_END_DELETE ((byte)43) /*!< delete compact record list
end on index page */
-#define MLOG_COMP_LIST_START_DELETE ((byte)44) /* delete compact record list
+#define MLOG_COMP_LIST_START_DELETE ((byte)44) /*!< delete compact record list
start on index page */
#define MLOG_COMP_LIST_END_COPY_CREATED ((byte)45)
- /* copy compact record list end
- to a new created index page */
-#define MLOG_COMP_PAGE_REORGANIZE ((byte)46) /* reorganize an index page */
-#define MLOG_FILE_CREATE2 ((byte)47) /* log record about creating
+ /*!< copy compact
+ record list end to a
+ new created index
+ page */
+#define MLOG_COMP_PAGE_REORGANIZE ((byte)46) /*!< reorganize an index page */
+#define MLOG_FILE_CREATE2 ((byte)47) /*!< log record about creating
an .ibd file, with format */
-#define MLOG_ZIP_WRITE_NODE_PTR ((byte)48) /* write the node pointer of
+#define MLOG_ZIP_WRITE_NODE_PTR ((byte)48) /*!< write the node pointer of
a record on a compressed
non-leaf B-tree page */
-#define MLOG_ZIP_WRITE_BLOB_PTR ((byte)49) /* write the BLOB pointer
+#define MLOG_ZIP_WRITE_BLOB_PTR ((byte)49) /*!< write the BLOB pointer
of an externally stored column
on a compressed page */
-#define MLOG_ZIP_WRITE_HEADER ((byte)50) /* write to compressed page
+#define MLOG_ZIP_WRITE_HEADER ((byte)50) /*!< write to compressed page
header */
-#define MLOG_ZIP_PAGE_COMPRESS ((byte)51) /* compress an index page */
-#define MLOG_BIGGEST_TYPE ((byte)51) /* biggest value (used in
- asserts) */
+#define MLOG_ZIP_PAGE_COMPRESS ((byte)51) /*!< compress an index page */
+#define MLOG_BIGGEST_TYPE ((byte)51) /*!< biggest value (used in
+ assertions) */
+/* @} */
+
+/** @name Flags for MLOG_FILE operations
+(stored in the page number parameter, called log_flags in the
+functions). The page number parameter was originally written as 0. @{ */
+#define MLOG_FILE_FLAG_TEMP 1 /*!< identifies TEMPORARY TABLE in
+ MLOG_FILE_CREATE, MLOG_FILE_CREATE2 */
+/* @} */
-/*******************************************************************
+/***************************************************************//**
Starts a mini-transaction and creates a mini-transaction handle
-and buffer in the memory buffer given by the caller. */
+and buffer in the memory buffer given by the caller.
+@return mtr buffer which also acts as the mtr handle */
UNIV_INLINE
mtr_t*
mtr_start(
/*======*/
- /* out: mtr buffer which also acts as
- the mtr handle */
- mtr_t* mtr); /* in: memory buffer for the mtr buffer */
-/*******************************************************************
+ mtr_t* mtr); /*!< in: memory buffer for the mtr buffer */
+/***************************************************************//**
Commits a mini-transaction. */
UNIV_INTERN
void
mtr_commit(
/*=======*/
- mtr_t* mtr); /* in: mini-transaction */
-/**************************************************************
-Sets and returns a savepoint in mtr. */
+ mtr_t* mtr); /*!< in: mini-transaction */
+/**********************************************************//**
+Sets and returns a savepoint in mtr.
+@return savepoint */
UNIV_INLINE
ulint
mtr_set_savepoint(
/*==============*/
- /* out: savepoint */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************//**
Releases the latches stored in an mtr memo down to a savepoint.
NOTE! The mtr must not have made changes to buffer pages after the
savepoint, as these can be handled only by mtr_commit. */
@@ -193,161 +218,172 @@ UNIV_INTERN
void
mtr_rollback_to_savepoint(
/*======================*/
- mtr_t* mtr, /* in: mtr */
- ulint savepoint); /* in: savepoint */
-/**************************************************************
+ mtr_t* mtr, /*!< in: mtr */
+ ulint savepoint); /*!< in: savepoint */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
Releases the (index tree) s-latch stored in an mtr memo after a
savepoint. */
UNIV_INLINE
void
mtr_release_s_latch_at_savepoint(
/*=============================*/
- mtr_t* mtr, /* in: mtr */
- ulint savepoint, /* in: savepoint */
- rw_lock_t* lock); /* in: latch to release */
-/*******************************************************************
-Gets the logging mode of a mini-transaction. */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint savepoint, /*!< in: savepoint */
+ rw_lock_t* lock); /*!< in: latch to release */
+#else /* !UNIV_HOTBACKUP */
+# define mtr_release_s_latch_at_savepoint(mtr,savepoint,lock) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
+/***************************************************************//**
+Gets the logging mode of a mini-transaction.
+@return logging mode: MTR_LOG_NONE, ... */
UNIV_INLINE
ulint
mtr_get_log_mode(
/*=============*/
- /* out: logging mode: MTR_LOG_NONE, ... */
- mtr_t* mtr); /* in: mtr */
-/*******************************************************************
-Changes the logging mode of a mini-transaction. */
+ mtr_t* mtr); /*!< in: mtr */
+/***************************************************************//**
+Changes the logging mode of a mini-transaction.
+@return old mode */
UNIV_INLINE
ulint
mtr_set_log_mode(
/*=============*/
- /* out: old mode */
- mtr_t* mtr, /* in: mtr */
- ulint mode); /* in: logging mode: MTR_LOG_NONE, ... */
-/************************************************************
-Reads 1 - 4 bytes from a file page buffered in the buffer pool. */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint mode); /*!< in: logging mode: MTR_LOG_NONE, ... */
+/********************************************************//**
+Reads 1 - 4 bytes from a file page buffered in the buffer pool.
+@return value read */
UNIV_INTERN
ulint
mtr_read_ulint(
/*===========*/
- /* out: value read */
- const byte* ptr, /* in: pointer from where to read */
- ulint type, /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
- mtr_t* mtr); /* in: mini-transaction handle */
-/************************************************************
-Reads 8 bytes from a file page buffered in the buffer pool. */
+ const byte* ptr, /*!< in: pointer from where to read */
+ ulint type, /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+/********************************************************//**
+Reads 8 bytes from a file page buffered in the buffer pool.
+@return value read */
UNIV_INTERN
dulint
mtr_read_dulint(
/*============*/
- /* out: value read */
- const byte* ptr, /* in: pointer from where to read */
- mtr_t* mtr); /* in: mini-transaction handle */
-/*************************************************************************
+ const byte* ptr, /*!< in: pointer from where to read */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
This macro locks an rw-lock in s-mode. */
#define mtr_s_lock(B, MTR) mtr_s_lock_func((B), __FILE__, __LINE__,\
(MTR))
-/*************************************************************************
+/*********************************************************************//**
This macro locks an rw-lock in x-mode. */
#define mtr_x_lock(B, MTR) mtr_x_lock_func((B), __FILE__, __LINE__,\
(MTR))
-/*************************************************************************
+/*********************************************************************//**
NOTE! Use the macro above!
Locks a lock in s-mode. */
UNIV_INLINE
void
mtr_s_lock_func(
/*============*/
- rw_lock_t* lock, /* in: rw-lock */
- const char* file, /* in: file name */
- ulint line, /* in: line number */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************************
+ rw_lock_t* lock, /*!< in: rw-lock */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line number */
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************************//**
NOTE! Use the macro above!
Locks a lock in x-mode. */
UNIV_INLINE
void
mtr_x_lock_func(
/*============*/
- rw_lock_t* lock, /* in: rw-lock */
- const char* file, /* in: file name */
- ulint line, /* in: line number */
- mtr_t* mtr); /* in: mtr */
+ rw_lock_t* lock, /*!< in: rw-lock */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line number */
+ mtr_t* mtr); /*!< in: mtr */
+#endif /* !UNIV_HOTBACKUP */
-/*******************************************************
+/***************************************************//**
Releases an object in the memo stack. */
UNIV_INTERN
void
mtr_memo_release(
/*=============*/
- mtr_t* mtr, /* in: mtr */
- void* object, /* in: object */
- ulint type); /* in: object type: MTR_MEMO_S_LOCK, ... */
+ mtr_t* mtr, /*!< in: mtr */
+ void* object, /*!< in: object */
+ ulint type); /*!< in: object type: MTR_MEMO_S_LOCK, ... */
#ifdef UNIV_DEBUG
-/**************************************************************
-Checks if memo contains the given item. */
+# ifndef UNIV_HOTBACKUP
+/**********************************************************//**
+Checks if memo contains the given item.
+@return TRUE if contains */
UNIV_INLINE
ibool
mtr_memo_contains(
/*==============*/
- /* out: TRUE if contains */
- mtr_t* mtr, /* in: mtr */
- const void* object, /* in: object to search */
- ulint type); /* in: type of object */
+ mtr_t* mtr, /*!< in: mtr */
+ const void* object, /*!< in: object to search */
+ ulint type); /*!< in: type of object */
-/**************************************************************
-Checks if memo contains the given page. */
+/**********************************************************//**
+Checks if memo contains the given page.
+@return TRUE if contains */
UNIV_INTERN
ibool
mtr_memo_contains_page(
/*===================*/
- /* out: TRUE if contains */
- mtr_t* mtr, /* in: mtr */
- const byte* ptr, /* in: pointer to buffer frame */
- ulint type); /* in: type of object */
-/*************************************************************
+ mtr_t* mtr, /*!< in: mtr */
+ const byte* ptr, /*!< in: pointer to buffer frame */
+ ulint type); /*!< in: type of object */
+/*********************************************************//**
Prints info of an mtr handle. */
UNIV_INTERN
void
mtr_print(
/*======*/
- mtr_t* mtr); /* in: mtr */
+ mtr_t* mtr); /*!< in: mtr */
+# else /* !UNIV_HOTBACKUP */
+# define mtr_memo_contains(mtr, object, type) TRUE
+# define mtr_memo_contains_page(mtr, ptr, type) TRUE
+# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG */
/*######################################################################*/
#define MTR_BUF_MEMO_SIZE 200 /* number of slots in memo */
-/*******************************************************************
-Returns the log object of a mini-transaction buffer. */
+/***************************************************************//**
+Returns the log object of a mini-transaction buffer.
+@return log */
UNIV_INLINE
dyn_array_t*
mtr_get_log(
/*========*/
- /* out: log */
- mtr_t* mtr); /* in: mini-transaction */
-/*******************************************************
+ mtr_t* mtr); /*!< in: mini-transaction */
+/***************************************************//**
Pushes an object to an mtr memo stack. */
UNIV_INLINE
void
mtr_memo_push(
/*==========*/
- mtr_t* mtr, /* in: mtr */
- void* object, /* in: object */
- ulint type); /* in: object type: MTR_MEMO_S_LOCK, ... */
+ mtr_t* mtr, /*!< in: mtr */
+ void* object, /*!< in: object */
+ ulint type); /*!< in: object type: MTR_MEMO_S_LOCK, ... */
/* Type definition of a mini-transaction memo stack slot. */
typedef struct mtr_memo_slot_struct mtr_memo_slot_t;
struct mtr_memo_slot_struct{
- ulint type; /* type of the stored object (MTR_MEMO_S_LOCK, ...) */
- void* object; /* pointer to the object */
+ ulint type; /*!< type of the stored object (MTR_MEMO_S_LOCK, ...) */
+ void* object; /*!< pointer to the object */
};
/* Mini-transaction handle and buffer */
struct mtr_struct{
#ifdef UNIV_DEBUG
- ulint state; /* MTR_ACTIVE, MTR_COMMITTING, MTR_COMMITTED */
+ ulint state; /*!< MTR_ACTIVE, MTR_COMMITTING, MTR_COMMITTED */
#endif
- dyn_array_t memo; /* memo stack for locks etc. */
- dyn_array_t log; /* mini-transaction log */
+ dyn_array_t memo; /*!< memo stack for locks etc. */
+ dyn_array_t log; /*!< mini-transaction log */
ibool modifications;
/* TRUE if the mtr made modifications to
buffer pool pages */
diff --git a/storage/xtradb/include/mtr0mtr.ic b/storage/xtradb/include/mtr0mtr.ic
index 7d6d99917b7..310c7c4117f 100644
--- a/storage/xtradb/include/mtr0mtr.ic
+++ b/storage/xtradb/include/mtr0mtr.ic
@@ -16,26 +16,28 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mtr0mtr.ic
Mini-transaction buffer
Created 11/26/1995 Heikki Tuuri
*******************************************************/
-#include "sync0sync.h"
-#include "sync0rw.h"
+#ifndef UNIV_HOTBACKUP
+# include "sync0sync.h"
+# include "sync0rw.h"
+#endif /* !UNIV_HOTBACKUP */
#include "mach0data.h"
-/*******************************************************************
+/***************************************************************//**
Starts a mini-transaction and creates a mini-transaction handle
-and a buffer in the memory buffer given by the caller. */
+and a buffer in the memory buffer given by the caller.
+@return mtr buffer which also acts as the mtr handle */
UNIV_INLINE
mtr_t*
mtr_start(
/*======*/
- /* out: mtr buffer which also acts as
- the mtr handle */
- mtr_t* mtr) /* in: memory buffer for the mtr buffer */
+ mtr_t* mtr) /*!< in: memory buffer for the mtr buffer */
{
dyn_array_create(&(mtr->memo));
dyn_array_create(&(mtr->log));
@@ -50,15 +52,15 @@ mtr_start(
return(mtr);
}
-/*******************************************************
+/***************************************************//**
Pushes an object to an mtr memo stack. */
UNIV_INLINE
void
mtr_memo_push(
/*==========*/
- mtr_t* mtr, /* in: mtr */
- void* object, /* in: object */
- ulint type) /* in: object type: MTR_MEMO_S_LOCK, ... */
+ mtr_t* mtr, /*!< in: mtr */
+ void* object, /*!< in: object */
+ ulint type) /*!< in: object type: MTR_MEMO_S_LOCK, ... */
{
dyn_array_t* memo;
mtr_memo_slot_t* slot;
@@ -77,14 +79,14 @@ mtr_memo_push(
slot->type = type;
}
-/**************************************************************
-Sets and returns a savepoint in mtr. */
+/**********************************************************//**
+Sets and returns a savepoint in mtr.
+@return savepoint */
UNIV_INLINE
ulint
mtr_set_savepoint(
/*==============*/
- /* out: savepoint */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dyn_array_t* memo;
@@ -96,16 +98,17 @@ mtr_set_savepoint(
return(dyn_array_get_data_size(memo));
}
-/**************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
Releases the (index tree) s-latch stored in an mtr memo after a
savepoint. */
UNIV_INLINE
void
mtr_release_s_latch_at_savepoint(
/*=============================*/
- mtr_t* mtr, /* in: mtr */
- ulint savepoint, /* in: savepoint */
- rw_lock_t* lock) /* in: latch to release */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint savepoint, /*!< in: savepoint */
+ rw_lock_t* lock) /*!< in: latch to release */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
@@ -128,17 +131,17 @@ mtr_release_s_latch_at_savepoint(
slot->object = NULL;
}
-#ifdef UNIV_DEBUG
-/**************************************************************
-Checks if memo contains the given item. */
+# ifdef UNIV_DEBUG
+/**********************************************************//**
+Checks if memo contains the given item.
+@return TRUE if contains */
UNIV_INLINE
ibool
mtr_memo_contains(
/*==============*/
- /* out: TRUE if contains */
- mtr_t* mtr, /* in: mtr */
- const void* object, /* in: object to search */
- ulint type) /* in: type of object */
+ mtr_t* mtr, /*!< in: mtr */
+ const void* object, /*!< in: object to search */
+ ulint type) /*!< in: type of object */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
@@ -164,16 +167,17 @@ mtr_memo_contains(
return(FALSE);
}
-#endif /* UNIV_DEBUG */
+# endif /* UNIV_DEBUG */
+#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
-Returns the log object of a mini-transaction buffer. */
+/***************************************************************//**
+Returns the log object of a mini-transaction buffer.
+@return log */
UNIV_INLINE
dyn_array_t*
mtr_get_log(
/*========*/
- /* out: log */
- mtr_t* mtr) /* in: mini-transaction */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
@@ -181,14 +185,14 @@ mtr_get_log(
return(&(mtr->log));
}
-/*******************************************************************
-Gets the logging mode of a mini-transaction. */
+/***************************************************************//**
+Gets the logging mode of a mini-transaction.
+@return logging mode: MTR_LOG_NONE, ... */
UNIV_INLINE
ulint
mtr_get_log_mode(
/*=============*/
- /* out: logging mode: MTR_LOG_NONE, ... */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mtr);
ut_ad(mtr->log_mode >= MTR_LOG_ALL);
@@ -197,15 +201,15 @@ mtr_get_log_mode(
return(mtr->log_mode);
}
-/*******************************************************************
-Changes the logging mode of a mini-transaction. */
+/***************************************************************//**
+Changes the logging mode of a mini-transaction.
+@return old mode */
UNIV_INLINE
ulint
mtr_set_log_mode(
/*=============*/
- /* out: old mode */
- mtr_t* mtr, /* in: mtr */
- ulint mode) /* in: logging mode: MTR_LOG_NONE, ... */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint mode) /*!< in: logging mode: MTR_LOG_NONE, ... */
{
ulint old_mode;
@@ -227,16 +231,17 @@ mtr_set_log_mode(
return(old_mode);
}
-/*************************************************************************
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
Locks a lock in s-mode. */
UNIV_INLINE
void
mtr_s_lock_func(
/*============*/
- rw_lock_t* lock, /* in: rw-lock */
- const char* file, /* in: file name */
- ulint line, /* in: line number */
- mtr_t* mtr) /* in: mtr */
+ rw_lock_t* lock, /*!< in: rw-lock */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line number */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mtr);
ut_ad(lock);
@@ -246,16 +251,16 @@ mtr_s_lock_func(
mtr_memo_push(mtr, lock, MTR_MEMO_S_LOCK);
}
-/*************************************************************************
+/*********************************************************************//**
Locks a lock in x-mode. */
UNIV_INLINE
void
mtr_x_lock_func(
/*============*/
- rw_lock_t* lock, /* in: rw-lock */
- const char* file, /* in: file name */
- ulint line, /* in: line number */
- mtr_t* mtr) /* in: mtr */
+ rw_lock_t* lock, /*!< in: rw-lock */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line number */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mtr);
ut_ad(lock);
@@ -264,3 +269,4 @@ mtr_x_lock_func(
mtr_memo_push(mtr, lock, MTR_MEMO_X_LOCK);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/mtr0types.h b/storage/xtradb/include/mtr0types.h
index 23634c98827..83a7aaf3839 100644
--- a/storage/xtradb/include/mtr0types.h
+++ b/storage/xtradb/include/mtr0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mtr0types.h
Mini-transaction buffer global types
Created 11/26/1995 Heikki Tuuri
diff --git a/storage/xtradb/include/mysql_addons.h b/storage/xtradb/include/mysql_addons.h
index 2e8c87f5962..17660c18710 100644
--- a/storage/xtradb/include/mysql_addons.h
+++ b/storage/xtradb/include/mysql_addons.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/mysql_addons.h
This file contains functions that need to be added to
MySQL code but have not been added yet.
diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h
index 26897226ff4..d8d2f0e5d9e 100644
--- a/storage/xtradb/include/os0file.h
+++ b/storage/xtradb/include/os0file.h
@@ -15,8 +15,35 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+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
+
+***********************************************************************/
+
+/**************************************************//**
+@file include/os0file.h
The interface to the operating system file io
Created 10/21/1995 Heikki Tuuri
@@ -33,49 +60,63 @@ Created 10/21/1995 Heikki Tuuri
#include <time.h>
#endif
+/** File node of a tablespace or the log data space */
typedef struct fil_node_struct fil_node_t;
#ifdef UNIV_DO_FLUSH
extern ibool os_do_not_call_flush_at_each_write;
#endif /* UNIV_DO_FLUSH */
extern ibool os_has_said_disk_full;
+/** Flag: enable debug printout for asynchronous i/o */
extern ibool os_aio_print_debug;
+/** Number of pending os_file_pread() operations */
extern ulint os_file_n_pending_preads;
+/** Number of pending os_file_pwrite() operations */
extern ulint os_file_n_pending_pwrites;
+/** Number of pending read operations */
extern ulint os_n_pending_reads;
+/** Number of pending write operations */
extern ulint os_n_pending_writes;
#ifdef __WIN__
-/* We define always WIN_ASYNC_IO, and check at run-time whether
+/** We define always WIN_ASYNC_IO, and check at run-time whether
the OS actually supports it: Win 95 does not, NT does. */
#define WIN_ASYNC_IO
+/** Use unbuffered I/O */
#define UNIV_NON_BUFFERED_IO
#endif
#ifdef __WIN__
+/** File handle */
#define os_file_t HANDLE
+/** Convert a C file descriptor to a native file handle
+@param fd file descriptor
+@return native file handle */
#define OS_FILE_FROM_FD(fd) (HANDLE) _get_osfhandle(fd)
#else
+/** File handle */
typedef int os_file_t;
+/** Convert a C file descriptor to a native file handle
+@param fd file descriptor
+@return native file handle */
#define OS_FILE_FROM_FD(fd) fd
#endif
+/** Umask for creating files */
extern ulint os_innodb_umask;
-/* If this flag is TRUE, then we will use the native aio of the
+/** If this flag is TRUE, then we will use the native aio of the
OS (provided we compiled Innobase with it in), otherwise we will
use simulated aio we build below with threads */
extern ibool os_aio_use_native_aio;
-#define OS_FILE_SECTOR_SIZE 512
-
-/* The next value should be smaller or equal to the smallest sector size used
+/** The next value should be smaller or equal to the smallest sector size used
on any disk. A log block is required to be a portion of disk which is written
so that if the start and the end of a block get written to disk, then the
whole block gets written. This should be true even in most cases of a crash:
@@ -84,7 +125,7 @@ log. */
#define OS_FILE_LOG_BLOCK_SIZE 512
-/* Options for file_create */
+/** Options for file_create @{ */
#define OS_FILE_OPEN 51
#define OS_FILE_CREATE 52
#define OS_FILE_OVERWRITE 53
@@ -100,12 +141,14 @@ log. */
/* Options for file_create */
#define OS_FILE_AIO 61
#define OS_FILE_NORMAL 62
+/* @} */
-/* Types for file create */
+/** Types for file create @{ */
#define OS_DATA_FILE 100
#define OS_LOG_FILE 101
+/* @} */
-/* Error codes from os_file_get_last_error */
+/** Error codes from os_file_get_last_error @{ */
#define OS_FILE_NOT_FOUND 71
#define OS_FILE_DISK_FULL 72
#define OS_FILE_ALREADY_EXISTS 73
@@ -114,23 +157,25 @@ log. */
to become available again */
#define OS_FILE_SHARING_VIOLATION 76
#define OS_FILE_ERROR_NOT_SPECIFIED 77
+/* @} */
-/* Types for aio operations */
+/** Types for aio operations @{ */
#define OS_FILE_READ 10
#define OS_FILE_WRITE 11
#define OS_FILE_LOG 256 /* This can be ORed to type */
+/* @} */
-#define OS_AIO_N_PENDING_IOS_PER_THREAD 32 /* Win NT does not allow more
+#define OS_AIO_N_PENDING_IOS_PER_THREAD 32 /*!< Win NT does not allow more
than 64 */
-/* Modes for aio operations */
-#define OS_AIO_NORMAL 21 /* Normal asynchronous i/o not for ibuf
+/** Modes for aio operations @{ */
+#define OS_AIO_NORMAL 21 /*!< Normal asynchronous i/o not for ibuf
pages or ibuf bitmap pages */
-#define OS_AIO_IBUF 22 /* Asynchronous i/o for ibuf pages or ibuf
+#define OS_AIO_IBUF 22 /*!< Asynchronous i/o for ibuf pages or ibuf
bitmap pages */
-#define OS_AIO_LOG 23 /* Asynchronous i/o for the log */
-#define OS_AIO_SYNC 24 /* Asynchronous i/o where the calling thread
+#define OS_AIO_LOG 23 /*!< Asynchronous i/o for the log */
+#define OS_AIO_SYNC 24 /*!< Asynchronous i/o where the calling thread
will itself wait for the i/o to complete,
doing also the job of the i/o-handler thread;
can be used for any pages, ibuf or non-ibuf.
@@ -140,16 +185,18 @@ log. */
the file seek and read or write, causing a
bottleneck for parallelism. */
-#define OS_AIO_SIMULATED_WAKE_LATER 512 /* This can be ORed to mode
+#define OS_AIO_SIMULATED_WAKE_LATER 512 /*!< This can be ORed to mode
in the call of os_aio(...),
if the caller wants to post several i/o
requests in a batch, and only after that
wake the i/o-handler thread; this has
effect only in simulated aio */
-#define OS_WIN31 1
-#define OS_WIN95 2
-#define OS_WINNT 3
-#define OS_WIN2000 4
+/* @} */
+
+#define OS_WIN31 1 /*!< Microsoft Windows 3.x */
+#define OS_WIN95 2 /*!< Microsoft Windows 95 */
+#define OS_WINNT 3 /*!< Microsoft Windows NT 3.x */
+#define OS_WIN2000 4 /*!< Microsoft Windows 2000 */
extern ulint os_n_file_reads;
extern ulint os_n_file_writes;
@@ -173,161 +220,157 @@ bigger than 4000 bytes */
/* Struct used in fetching information of a file in a directory */
struct os_file_stat_struct{
- char name[OS_FILE_MAX_PATH]; /* path to a file */
- os_file_type_t type; /* file type */
- ib_int64_t size; /* file size */
- time_t ctime; /* creation time */
- time_t mtime; /* modification time */
- time_t atime; /* access time */
+ char name[OS_FILE_MAX_PATH]; /*!< path to a file */
+ os_file_type_t type; /*!< file type */
+ ib_int64_t size; /*!< file size */
+ time_t ctime; /*!< creation time */
+ time_t mtime; /*!< modification time */
+ time_t atime; /*!< access time */
};
typedef struct os_file_stat_struct os_file_stat_t;
#ifdef __WIN__
-typedef HANDLE os_file_dir_t; /* directory stream */
+typedef HANDLE os_file_dir_t; /*!< directory stream */
#else
-typedef DIR* os_file_dir_t; /* directory stream */
+typedef DIR* os_file_dir_t; /*!< directory stream */
#endif
-/***************************************************************************
-Gets the operating system version. Currently works only on Windows. */
+/***********************************************************************//**
+Gets the operating system version. Currently works only on Windows.
+@return OS_WIN95, OS_WIN31, OS_WINNT, or OS_WIN2000 */
UNIV_INTERN
ulint
os_get_os_version(void);
/*===================*/
- /* out: OS_WIN95, OS_WIN31, OS_WINNT, or OS_WIN2000 */
-/********************************************************************
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
Creates the seek mutexes used in positioned reads and writes. */
UNIV_INTERN
void
os_io_init_simple(void);
/*===================*/
-/***************************************************************************
+/***********************************************************************//**
Creates a temporary file. This function is like tmpfile(3), but
the temporary file is created in the MySQL temporary directory.
On Netware, this function is like tmpfile(3), because the C run-time
-library of Netware does not expose the delete-on-close flag. */
+library of Netware does not expose the delete-on-close flag.
+@return temporary file handle, or NULL on error */
FILE*
os_file_create_tmpfile(void);
/*========================*/
- /* out: temporary file handle, or NULL on error */
-/***************************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************************//**
The os_file_opendir() function opens a directory stream corresponding to the
directory named by the dirname argument. The directory stream is positioned
at the first entry. In both Unix and Windows we automatically skip the '.'
-and '..' items at the start of the directory listing. */
+and '..' items at the start of the directory listing.
+@return directory stream, NULL if error */
UNIV_INTERN
os_file_dir_t
os_file_opendir(
/*============*/
- /* out: directory stream, NULL if
- error */
- const char* dirname, /* in: directory name; it must not
+ const char* dirname, /*!< in: directory name; it must not
contain a trailing '\' or '/' */
- ibool error_is_fatal);/* in: TRUE if we should treat an
+ ibool error_is_fatal);/*!< in: TRUE if we should treat an
error as a fatal error; if we try to
open symlinks then we do not wish a
fatal error if it happens not to be
a directory */
-/***************************************************************************
-Closes a directory stream. */
+/***********************************************************************//**
+Closes a directory stream.
+@return 0 if success, -1 if failure */
UNIV_INTERN
int
os_file_closedir(
/*=============*/
- /* out: 0 if success, -1 if failure */
- os_file_dir_t dir); /* in: directory stream */
-/***************************************************************************
+ os_file_dir_t dir); /*!< in: directory stream */
+/***********************************************************************//**
This function returns information of the next file in the directory. We jump
-over the '.' and '..' entries in the directory. */
+over the '.' and '..' entries in the directory.
+@return 0 if ok, -1 if error, 1 if at the end of the directory */
UNIV_INTERN
int
os_file_readdir_next_file(
/*======================*/
- /* out: 0 if ok, -1 if error, 1 if at the end
- of the directory */
- const char* dirname,/* in: directory name or path */
- os_file_dir_t dir, /* in: directory stream */
- os_file_stat_t* info); /* in/out: buffer where the info is returned */
-/*********************************************************************
+ const char* dirname,/*!< in: directory name or path */
+ os_file_dir_t dir, /*!< in: directory stream */
+ os_file_stat_t* info); /*!< in/out: buffer where the info is returned */
+/*****************************************************************//**
This function attempts to create a directory named pathname. The new directory
gets default permissions. On Unix, the permissions are (0770 & ~umask). If the
directory exists already, nothing is done and the call succeeds, unless the
-fail_if_exists arguments is true. */
+fail_if_exists arguments is true.
+@return TRUE if call succeeds, FALSE on error */
UNIV_INTERN
ibool
os_file_create_directory(
/*=====================*/
- /* out: TRUE if call succeeds,
- FALSE on error */
- const char* pathname, /* in: directory name as
+ const char* pathname, /*!< in: directory name as
null-terminated string */
- ibool fail_if_exists);/* in: if TRUE, pre-existing directory
+ ibool fail_if_exists);/*!< in: if TRUE, pre-existing directory
is treated as an error. */
-/********************************************************************
-A simple function to open or create a file. */
+/****************************************************************//**
+A simple function to open or create a file.
+@return own: handle to the file, not defined if error, error number
+can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
os_file_create_simple(
/*==================*/
- /* out, own: handle to the file, not defined
- if error, error number can be retrieved with
- os_file_get_last_error */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- ulint create_mode,/* in: OS_FILE_OPEN if an existing file is
+ ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file is
opened (if does not exist, error), or
OS_FILE_CREATE if a new file is created
(if exists, error), or
OS_FILE_CREATE_PATH if new file
(if exists, error) and subdirectories along
its path are created (if needed)*/
- ulint access_type,/* in: OS_FILE_READ_ONLY or
+ ulint access_type,/*!< in: OS_FILE_READ_ONLY or
OS_FILE_READ_WRITE */
- ibool* success);/* out: TRUE if succeed, FALSE if error */
-/********************************************************************
-A simple function to open or create a file. */
+ ibool* success);/*!< out: TRUE if succeed, FALSE if error */
+/****************************************************************//**
+A simple function to open or create a file.
+@return own: handle to the file, not defined if error, error number
+can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
os_file_create_simple_no_error_handling(
/*====================================*/
- /* out, own: handle to the file, not defined
- if error, error number can be retrieved with
- os_file_get_last_error */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- ulint create_mode,/* in: OS_FILE_OPEN if an existing file
+ ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file
is opened (if does not exist, error), or
OS_FILE_CREATE if a new file is created
(if exists, error) */
- ulint access_type,/* in: OS_FILE_READ_ONLY,
+ ulint access_type,/*!< in: OS_FILE_READ_ONLY,
OS_FILE_READ_WRITE, or
OS_FILE_READ_ALLOW_DELETE; the last option is
used by a backup program reading the file */
- ibool* success);/* out: TRUE if succeed, FALSE if error */
-/********************************************************************
+ ibool* success);/*!< out: TRUE if succeed, FALSE if error */
+/****************************************************************//**
Tries to disable OS caching on an opened file descriptor. */
UNIV_INTERN
void
os_file_set_nocache(
/*================*/
- int fd, /* in: file descriptor to alter */
- const char* file_name, /* in: file name, used in the
+ int fd, /*!< in: file descriptor to alter */
+ const char* file_name, /*!< in: file name, used in the
diagnostic message */
- const char* operation_name);/* in: "open" or "create"; used in the
+ const char* operation_name);/*!< in: "open" or "create"; used in the
diagnostic message */
-/********************************************************************
-Opens an existing file or creates a new. */
+/****************************************************************//**
+Opens an existing file or creates a new.
+@return own: handle to the file, not defined if error, error number
+can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
os_file_create(
/*===========*/
- /* out, own: handle to the file, not defined
- if error, error number can be retrieved with
- os_file_get_last_error */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- ulint create_mode,/* in: OS_FILE_OPEN if an existing file
+ ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file
is opened (if does not exist, error), or
OS_FILE_CREATE if a new file is created
(if exists, error),
@@ -335,137 +378,137 @@ os_file_create(
or an old overwritten;
OS_FILE_OPEN_RAW, if a raw device or disk
partition should be opened */
- ulint purpose,/* in: OS_FILE_AIO, if asynchronous,
+ ulint purpose,/*!< in: OS_FILE_AIO, if asynchronous,
non-buffered i/o is desired,
OS_FILE_NORMAL, if any normal file;
NOTE that it also depends on type, os_aio_..
and srv_.. variables whether we really use
async i/o or unbuffered i/o: look in the
function source code for the exact rules */
- ulint type, /* in: OS_DATA_FILE or OS_LOG_FILE */
- ibool* success);/* out: TRUE if succeed, FALSE if error */
-/***************************************************************************
-Deletes a file. The file has to be closed before calling this. */
+ ulint type, /*!< in: OS_DATA_FILE or OS_LOG_FILE */
+ ibool* success);/*!< out: TRUE if succeed, FALSE if error */
+/***********************************************************************//**
+Deletes a file. The file has to be closed before calling this.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_delete(
/*===========*/
- /* out: TRUE if success */
- const char* name); /* in: file path as a null-terminated string */
+ const char* name); /*!< in: file path as a null-terminated string */
-/***************************************************************************
-Deletes a file if it exists. The file has to be closed before calling this. */
+/***********************************************************************//**
+Deletes a file if it exists. The file has to be closed before calling this.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_delete_if_exists(
/*=====================*/
- /* out: TRUE if success */
- const char* name); /* in: file path as a null-terminated string */
-/***************************************************************************
+ const char* name); /*!< in: file path as a null-terminated string */
+/***********************************************************************//**
Renames a file (can also move it to another directory). It is safest that the
-file is closed before calling this function. */
+file is closed before calling this function.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_rename(
/*===========*/
- /* out: TRUE if success */
- const char* oldpath, /* in: old file path as a
+ const char* oldpath, /*!< in: old file path as a
null-terminated string */
- const char* newpath); /* in: new file path */
-/***************************************************************************
+ const char* newpath); /*!< in: new file path */
+/***********************************************************************//**
Closes a file handle. In case of error, error number can be retrieved with
-os_file_get_last_error. */
+os_file_get_last_error.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_close(
/*==========*/
- /* out: TRUE if success */
- os_file_t file); /* in, own: handle to a file */
-/***************************************************************************
-Closes a file handle. */
+ os_file_t file); /*!< in, own: handle to a file */
+#ifdef UNIV_HOTBACKUP
+/***********************************************************************//**
+Closes a file handle.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_close_no_error_handling(
/*============================*/
- /* out: TRUE if success */
- os_file_t file); /* in, own: handle to a file */
-/***************************************************************************
-Gets a file size. */
+ os_file_t file); /*!< in, own: handle to a file */
+#endif /* UNIV_HOTBACKUP */
+/***********************************************************************//**
+Gets a file size.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_get_size(
/*=============*/
- /* out: TRUE if success */
- os_file_t file, /* in: handle to a file */
- ulint* size, /* out: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ ulint* size, /*!< out: least significant 32 bits of file
size */
- ulint* size_high);/* out: most significant 32 bits of size */
-/***************************************************************************
-Gets file size as a 64-bit integer ib_int64_t. */
+ ulint* size_high);/*!< out: most significant 32 bits of size */
+/***********************************************************************//**
+Gets file size as a 64-bit integer ib_int64_t.
+@return size in bytes, -1 if error */
UNIV_INTERN
ib_int64_t
os_file_get_size_as_iblonglong(
/*===========================*/
- /* out: size in bytes, -1 if error */
- os_file_t file); /* in: handle to a file */
-/***************************************************************************
-Write the specified number of zeros to a newly created file. */
+ os_file_t file); /*!< in: handle to a file */
+/***********************************************************************//**
+Write the specified number of zeros to a newly created file.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_set_size(
/*=============*/
- /* out: TRUE if success */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /* in: handle to a file */
- ulint size, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ ulint size, /*!< in: least significant 32 bits of file
size */
- ulint size_high);/* in: most significant 32 bits of size */
-/***************************************************************************
-Truncates a file at its current position. */
+ ulint size_high);/*!< in: most significant 32 bits of size */
+/***********************************************************************//**
+Truncates a file at its current position.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_set_eof(
/*============*/
- /* out: TRUE if success */
- FILE* file); /* in: file to be truncated */
-/***************************************************************************
-Flushes the write buffers of a given file to the disk. */
+ FILE* file); /*!< in: file to be truncated */
+/***********************************************************************//**
+Flushes the write buffers of a given file to the disk.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_flush(
/*==========*/
- /* out: TRUE if success */
- os_file_t file); /* in, own: handle to a file */
-/***************************************************************************
+ os_file_t file); /*!< in, own: handle to a file */
+/***********************************************************************//**
Retrieves the last error number if an error occurs in a file io function.
The number should be retrieved before any other OS calls (because they may
overwrite the error number). If the number is not known to this program,
-the OS error number + 100 is returned. */
+the OS error number + 100 is returned.
+@return error number, or OS error number + 100 */
UNIV_INTERN
ulint
os_file_get_last_error(
/*===================*/
- /* out: error number, or OS error
- number + 100 */
- ibool report_all_errors); /* in: TRUE if we want an error message
+ ibool report_all_errors); /*!< in: TRUE if we want an error message
printed of all errors */
-/***********************************************************************
-Requests a synchronous read operation. */
+/*******************************************************************//**
+Requests a synchronous read operation.
+@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
ibool
os_file_read(
/*=========*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- os_file_t file, /* in: handle to a file */
- void* buf, /* in: buffer where to read */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ void* buf, /*!< in: buffer where to read */
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to read */
- ulint offset_high,/* in: most significant 32 bits of
+ ulint offset_high,/*!< in: most significant 32 bits of
offset */
- ulint n); /* in: number of bytes to read */
-/***********************************************************************
+ ulint n); /*!< in: number of bytes to read */
+/*******************************************************************//**
Rewind file to its start, read at most size - 1 bytes from it to str, and
NUL-terminate str. All errors are silently ignored. This function is
mostly meant to be used with temporary files. */
@@ -473,54 +516,52 @@ UNIV_INTERN
void
os_file_read_string(
/*================*/
- FILE* file, /* in: file to read from */
- char* str, /* in: buffer where to read */
- ulint size); /* in: size of buffer */
-/***********************************************************************
+ FILE* file, /*!< in: file to read from */
+ char* str, /*!< in: buffer where to read */
+ ulint size); /*!< in: size of buffer */
+/*******************************************************************//**
Requests a synchronous positioned read operation. This function does not do
-any error handling. In case of error it returns FALSE. */
+any error handling. In case of error it returns FALSE.
+@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
ibool
os_file_read_no_error_handling(
/*===========================*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- os_file_t file, /* in: handle to a file */
- void* buf, /* in: buffer where to read */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ void* buf, /*!< in: buffer where to read */
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to read */
- ulint offset_high,/* in: most significant 32 bits of
+ ulint offset_high,/*!< in: most significant 32 bits of
offset */
- ulint n); /* in: number of bytes to read */
+ ulint n); /*!< in: number of bytes to read */
-/***********************************************************************
-Requests a synchronous write operation. */
+/*******************************************************************//**
+Requests a synchronous write operation.
+@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
ibool
os_file_write(
/*==========*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /* in: handle to a file */
- const void* buf, /* in: buffer from which to write */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ const void* buf, /*!< in: buffer from which to write */
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to write */
- ulint offset_high,/* in: most significant 32 bits of
+ ulint offset_high,/*!< in: most significant 32 bits of
offset */
- ulint n); /* in: number of bytes to write */
-/***********************************************************************
-Check the existence and type of the given file. */
+ ulint n); /*!< in: number of bytes to write */
+/*******************************************************************//**
+Check the existence and type of the given file.
+@return TRUE if call succeeded */
UNIV_INTERN
ibool
os_file_status(
/*===========*/
- /* out: TRUE if call succeeded */
- const char* path, /* in: pathname of the file */
- ibool* exists, /* out: TRUE if file exists */
- os_file_type_t* type); /* out: type of the file (if it exists) */
-/********************************************************************
+ const char* path, /*!< in: pathname of the file */
+ ibool* exists, /*!< out: TRUE if file exists */
+ os_file_type_t* type); /*!< out: type of the file (if it exists) */
+/****************************************************************//**
The function os_file_dirname returns a directory component of a
null-terminated pathname string. In the usual case, dirname returns
the string up to, but not including, the final '/', and basename
@@ -546,52 +587,47 @@ returned by dirname and basename for different paths:
"/" "/" "/"
"." "." "."
".." "." ".."
-*/
+
+@return own: directory component of the pathname */
UNIV_INTERN
char*
os_file_dirname(
/*============*/
- /* out, own: directory component of the
- pathname */
- const char* path); /* in: pathname */
-/********************************************************************
-Creates all missing subdirectories along the given path. */
+ const char* path); /*!< in: pathname */
+/****************************************************************//**
+Creates all missing subdirectories along the given path.
+@return TRUE if call succeeded FALSE otherwise */
UNIV_INTERN
ibool
os_file_create_subdirs_if_needed(
/*=============================*/
- /* out: TRUE if call succeeded
- FALSE otherwise */
- const char* path); /* in: path name */
-/****************************************************************************
-Initializes the asynchronous io system. Creates separate aio array for
-non-ibuf read and write, a third aio array for the ibuf i/o, with just one
-segment, two aio arrays for log reads and writes with one segment, and a
-synchronous aio array of the specified size. The combined number of segments
-in the three first aio arrays is the parameter n_segments given to the
-function. The caller must create an i/o handler thread for each segment in
-the four first arrays, but not for the sync aio array. */
+ const char* path); /*!< in: path name */
+/***********************************************************************
+Initializes the asynchronous io system. Creates one array each for ibuf
+and log i/o. Also creates one array each for read and write where each
+array is divided logically into n_read_segs and n_write_segs
+respectively. The caller must create an i/o handler thread for each
+segment in these arrays. This function also creates the sync array.
+No i/o handler thread needs to be created for that */
UNIV_INTERN
void
os_aio_init(
/*========*/
- ulint n, /* in: maximum number of pending aio operations
- allowed; n must be divisible by n_segments */
-// ulint n_segments, /* in: combined number of segments in the four
-// first aio arrays; must be >= 4 */
- ulint n_read_threads, /* n_segments == 2 + n_read_threads + n_write_threads */
- ulint n_write_threads, /**/
- ulint n_slots_sync); /* in: number of slots in the sync aio array */
-/***********************************************************************
-Requests an asynchronous i/o operation. */
+ ulint n_per_seg, /*<! in: maximum number of pending aio
+ operations allowed per segment */
+ ulint n_read_segs, /*<! in: number of reader threads */
+ ulint n_write_segs, /*<! in: number of writer threads */
+ ulint n_slots_sync); /*<! in: number of slots in the sync aio
+ array */
+/*******************************************************************//**
+Requests an asynchronous i/o operation.
+@return TRUE if request was queued successfully, FALSE if fail */
UNIV_INTERN
ibool
os_aio(
/*===*/
- /* out: TRUE if request was queued
- successfully, FALSE if fail */
- ulint type, /* in: OS_FILE_READ or OS_FILE_WRITE */
- ulint mode, /* in: OS_AIO_NORMAL, ..., possibly ORed
+ ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE */
+ ulint mode, /*!< in: OS_AIO_NORMAL, ..., possibly ORed
to OS_AIO_SIMULATED_WAKE_LATER: the
last flag advises this function not to wake
i/o-handler threads, but the caller will
@@ -604,42 +640,45 @@ os_aio(
because i/os are not actually handled until
all have been posted: use with great
caution! */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /* in: handle to a file */
- void* buf, /* in: buffer where to read or from which
+ os_file_t file, /*!< in: handle to a file */
+ void* buf, /*!< in: buffer where to read or from which
to write */
- ulint offset, /* in: least significant 32 bits of file
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to read or write */
- ulint offset_high, /* in: most significant 32 bits of
+ ulint offset_high, /*!< in: most significant 32 bits of
offset */
- ulint n, /* in: number of bytes to read or write */
- fil_node_t* message1,/* in: messages for the aio handler (these
- can be used to identify a completed aio
- operation); if mode is OS_AIO_SYNC, these
- are ignored */
- void* message2);
-/****************************************************************************
+ ulint n, /*!< in: number of bytes to read or write */
+ fil_node_t* message1,/*!< in: message for the aio handler
+ (can be used to identify a completed
+ aio operation); ignored if mode is
+ OS_AIO_SYNC */
+ void* message2);/*!< in: message for the aio handler
+ (can be used to identify a completed
+ aio operation); ignored if mode is
+ OS_AIO_SYNC */
+/************************************************************************//**
Wakes up all async i/o threads so that they know to exit themselves in
shutdown. */
UNIV_INTERN
void
os_aio_wake_all_threads_at_shutdown(void);
/*=====================================*/
-/****************************************************************************
+/************************************************************************//**
Waits until there are no pending writes in os_aio_write_array. There can
be other, synchronous, pending writes. */
UNIV_INTERN
void
os_aio_wait_until_no_pending_writes(void);
/*=====================================*/
-/**************************************************************************
+/**********************************************************************//**
Wakes up simulated aio i/o-handler threads if they have something to do. */
UNIV_INTERN
void
os_aio_simulated_wake_handler_threads(void);
/*=======================================*/
-/**************************************************************************
+/**********************************************************************//**
This function can be called if one wants to post a batch of reads and
prefers an i/o-handler thread to handle them all at once later. You must
call os_aio_simulated_wake_handler_threads later to ensure the threads
@@ -650,19 +689,19 @@ os_aio_simulated_put_read_threads_to_sleep(void);
/*============================================*/
#ifdef WIN_ASYNC_IO
-/**************************************************************************
+/**********************************************************************//**
This function is only used in Windows asynchronous i/o.
Waits for an aio operation to complete. This function is used to wait the
for completed requests. The aio array of pending requests is divided
into segments. The thread specifies which segment or slot it wants to wait
for. NOTE: this function will also take care of freeing the aio slot,
-therefore no other thread is allowed to do the freeing! */
+therefore no other thread is allowed to do the freeing!
+@return TRUE if the aio operation succeeded */
UNIV_INTERN
ibool
os_aio_windows_handle(
/*==================*/
- /* out: TRUE if the aio operation succeeded */
- ulint segment, /* in: the number of the segment in the aio
+ ulint segment, /*!< in: the number of the segment in the aio
arrays to wait for; segment 0 is the ibuf
i/o thread, segment 1 the log i/o thread,
then follow the non-ibuf read threads, and as
@@ -670,52 +709,52 @@ os_aio_windows_handle(
this is ULINT_UNDEFINED, then it means that
sync aio is used, and this parameter is
ignored */
- ulint pos, /* this parameter is used only in sync aio:
+ ulint pos, /*!< this parameter is used only in sync aio:
wait for the aio slot at this position */
- fil_node_t**message1, /* out: the messages passed with the aio
+ fil_node_t**message1, /*!< out: the messages passed with the aio
request; note that also in the case where
the aio operation failed, these output
parameters are valid and can be used to
restart the operation, for example */
void** message2,
- ulint* type); /* out: OS_FILE_WRITE or ..._READ */
+ ulint* type); /*!< out: OS_FILE_WRITE or ..._READ */
#endif
-/**************************************************************************
+/**********************************************************************//**
Does simulated aio. This function should be called by an i/o-handler
-thread. */
+thread.
+@return TRUE if the aio operation succeeded */
UNIV_INTERN
ibool
os_aio_simulated_handle(
/*====================*/
- /* out: TRUE if the aio operation succeeded */
- ulint segment, /* in: the number of the segment in the aio
+ ulint segment, /*!< in: the number of the segment in the aio
arrays to wait for; segment 0 is the ibuf
i/o thread, segment 1 the log i/o thread,
then follow the non-ibuf read threads, and as
the last are the non-ibuf write threads */
- fil_node_t**message1, /* out: the messages passed with the aio
+ fil_node_t**message1, /*!< out: the messages passed with the aio
request; note that also in the case where
the aio operation failed, these output
parameters are valid and can be used to
restart the operation, for example */
void** message2,
- ulint* type); /* out: OS_FILE_WRITE or ..._READ */
-/**************************************************************************
-Validates the consistency of the aio system. */
+ ulint* type); /*!< out: OS_FILE_WRITE or ..._READ */
+/**********************************************************************//**
+Validates the consistency of the aio system.
+@return TRUE if ok */
UNIV_INTERN
ibool
os_aio_validate(void);
/*=================*/
- /* out: TRUE if ok */
-/**************************************************************************
+/**********************************************************************//**
Prints info of the aio arrays. */
UNIV_INTERN
void
os_aio_print(
/*=========*/
- FILE* file); /* in: file where to print */
-/**************************************************************************
+ FILE* file); /*!< in: file where to print */
+/**********************************************************************//**
Refreshes the statistics used to print per-second averages. */
UNIV_INTERN
void
@@ -723,7 +762,7 @@ os_aio_refresh_stats(void);
/*======================*/
#ifdef UNIV_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Checks that all slots in the system have been freed, that is, there are
no pending io operations. */
UNIV_INTERN
@@ -732,27 +771,26 @@ os_aio_all_slots_free(void);
/*=======================*/
#endif /* UNIV_DEBUG */
-/***********************************************************************
-This function returns information about the specified file */
+/*******************************************************************//**
+This function returns information about the specified file
+@return TRUE if stat information found */
UNIV_INTERN
ibool
os_file_get_status(
/*===============*/
- /* out: TRUE if stat
- information found */
- const char* path, /* in: pathname of the file */
- os_file_stat_t* stat_info); /* information of a file in a
+ const char* path, /*!< in: pathname of the file */
+ os_file_stat_t* stat_info); /*!< information of a file in a
directory */
#if !defined(UNIV_HOTBACKUP) && !defined(__NETWARE__)
-/*************************************************************************
+/*********************************************************************//**
Creates a temporary file that will be deleted on close.
-This function is defined in ha_innodb.cc. */
+This function is defined in ha_innodb.cc.
+@return temporary file descriptor, or < 0 on error */
UNIV_INTERN
int
innobase_mysql_tmpfile(void);
/*========================*/
- /* out: temporary file descriptor, or < 0 on error */
#endif /* !UNIV_HOTBACKUP && !__NETWARE__ */
#endif
diff --git a/storage/xtradb/include/os0proc.h b/storage/xtradb/include/os0proc.h
index 19b0b112638..fd46bd7db87 100644
--- a/storage/xtradb/include/os0proc.h
+++ b/storage/xtradb/include/os0proc.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/os0proc.h
The interface to the operating system
process control primitives
@@ -40,42 +41,34 @@ extern ibool os_use_large_pages;
/* Large page size. This may be a boot-time option on some platforms */
extern ulint os_large_page_size;
-/********************************************************************
+/****************************************************************//**
Converts the current process id to a number. It is not guaranteed that the
number is unique. In Linux returns the 'process number' of the current
thread. That number is the same as one sees in 'top', for example. In Linux
-the thread id is not the same as one sees in 'top'. */
+the thread id is not the same as one sees in 'top'.
+@return process id as a number */
UNIV_INTERN
ulint
os_proc_get_number(void);
/*====================*/
-/********************************************************************
-Allocates large pages memory. */
+/****************************************************************//**
+Allocates large pages memory.
+@return allocated memory */
UNIV_INTERN
void*
os_mem_alloc_large(
/*===============*/
- /* out: allocated memory */
- ulint* n); /* in/out: number of bytes */
-/********************************************************************
+ ulint* n); /*!< in/out: number of bytes */
+/****************************************************************//**
Frees large pages memory. */
UNIV_INTERN
void
os_mem_free_large(
/*==============*/
- void *ptr, /* in: pointer returned by
+ void *ptr, /*!< in: pointer returned by
os_mem_alloc_large() */
- ulint size); /* in: size returned by
+ ulint size); /*!< in: size returned by
os_mem_alloc_large() */
-/********************************************************************
-Sets the priority boost for threads released from waiting within the current
-process. */
-UNIV_INTERN
-void
-os_process_set_priority_boost(
-/*==========================*/
- ibool do_boost); /* in: TRUE if priority boost should be done,
- FALSE if not */
#ifndef UNIV_NONINL
#include "os0proc.ic"
diff --git a/storage/xtradb/include/os0proc.ic b/storage/xtradb/include/os0proc.ic
index 9f1fb01866d..c9641644525 100644
--- a/storage/xtradb/include/os0proc.ic
+++ b/storage/xtradb/include/os0proc.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/os0proc.ic
The interface to the operating system
process control primitives
diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h
index 7e058266762..0e0b32e7036 100644
--- a/storage/xtradb/include/os0sync.h
+++ b/storage/xtradb/include/os0sync.h
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/os0sync.h
The interface to the operating system
synchronization primitives.
@@ -38,52 +39,65 @@ Created 9/6/1995 Heikki Tuuri
#ifdef __WIN__
+/** Native mutex */
#define os_fast_mutex_t CRITICAL_SECTION
+/** Native event */
typedef HANDLE os_native_event_t;
+/** Operating system event */
typedef struct os_event_struct os_event_struct_t;
+/** Operating system event handle */
typedef os_event_struct_t* os_event_t;
+/** An asynchronous signal sent between threads */
struct os_event_struct {
os_native_event_t handle;
- /* Windows event */
+ /*!< Windows event */
UT_LIST_NODE_T(os_event_struct_t) os_event_list;
- /* list of all created events */
+ /*!< list of all created events */
};
#else
+/** Native mutex */
typedef pthread_mutex_t os_fast_mutex_t;
+/** Operating system event */
typedef struct os_event_struct os_event_struct_t;
+/** Operating system event handle */
typedef os_event_struct_t* os_event_t;
+/** An asynchronous signal sent between threads */
struct os_event_struct {
- os_fast_mutex_t os_mutex; /* this mutex protects the next
+ os_fast_mutex_t os_mutex; /*!< this mutex protects the next
fields */
- ibool is_set; /* this is TRUE when the event is
+ ibool is_set; /*!< this is TRUE when the event is
in the signaled state, i.e., a thread
does not stop if it tries to wait for
this event */
- ib_int64_t signal_count; /* this is incremented each time
+ ib_int64_t signal_count; /*!< this is incremented each time
the event becomes signaled */
- pthread_cond_t cond_var; /* condition variable is used in
+ pthread_cond_t cond_var; /*!< condition variable is used in
waiting for the event */
UT_LIST_NODE_T(os_event_struct_t) os_event_list;
- /* list of all created events */
+ /*!< list of all created events */
};
#endif
+/** Operating system mutex */
typedef struct os_mutex_struct os_mutex_str_t;
+/** Operating system mutex handle */
typedef os_mutex_str_t* os_mutex_t;
+/** Denotes an infinite delay for os_event_wait_time() */
#define OS_SYNC_INFINITE_TIME ((ulint)(-1))
+/** Return value of os_event_wait_time() when the time is exceeded */
#define OS_SYNC_TIME_EXCEEDED 1
-/* Mutex protecting counts and the event and OS 'slow' mutex lists */
+/** Mutex protecting counts and the event and OS 'slow' mutex lists */
extern os_mutex_t os_sync_mutex;
-/* This is incremented by 1 in os_thread_create and decremented by 1 in
+/** This is incremented by 1 in os_thread_create and decremented by 1 in
os_thread_exit */
extern ulint os_thread_count;
@@ -91,50 +105,38 @@ extern ulint os_event_count;
extern ulint os_mutex_count;
extern ulint os_fast_mutex_count;
-/*************************************************************
+/*********************************************************//**
Initializes global event and OS 'slow' mutex lists. */
UNIV_INTERN
void
os_sync_init(void);
/*==============*/
-/*************************************************************
+/*********************************************************//**
Frees created events and OS 'slow' mutexes. */
UNIV_INTERN
void
os_sync_free(void);
/*==============*/
-/*************************************************************
+/*********************************************************//**
Creates an event semaphore, i.e., a semaphore which may just have two states:
signaled and nonsignaled. The created event is manual reset: it must be reset
-explicitly by calling sync_os_reset_event. */
+explicitly by calling sync_os_reset_event.
+@return the event handle */
UNIV_INTERN
os_event_t
os_event_create(
/*============*/
- /* out: the event handle */
- const char* name); /* in: the name of the event, if NULL
+ const char* name); /*!< in: the name of the event, if NULL
the event is created without a name */
-#ifdef __WIN__
-/*************************************************************
-Creates an auto-reset event semaphore, i.e., an event which is automatically
-reset when a single thread is released. Works only in Windows. */
-UNIV_INTERN
-os_event_t
-os_event_create_auto(
-/*=================*/
- /* out: the event handle */
- const char* name); /* in: the name of the event, if NULL
- the event is created without a name */
-#endif
-/**************************************************************
+/**********************************************************//**
Sets an event semaphore to the signaled state: lets waiting threads
proceed. */
UNIV_INTERN
void
os_event_set(
/*=========*/
- os_event_t event); /* in: event to set */
-/**************************************************************
+ os_event_t event); /*!< in: event to set */
+/**********************************************************//**
Resets an event semaphore to the nonsignaled state. Waiting threads will
stop to wait for the event.
The return value should be passed to os_even_wait_low() if it is desired
@@ -145,16 +147,16 @@ UNIV_INTERN
ib_int64_t
os_event_reset(
/*===========*/
- os_event_t event); /* in: event to reset */
-/**************************************************************
+ os_event_t event); /*!< in: event to reset */
+/**********************************************************//**
Frees an event object. */
UNIV_INTERN
void
os_event_free(
/*==========*/
- os_event_t event); /* in: event to free */
+ os_event_t event); /*!< in: event to free */
-/**************************************************************
+/**********************************************************//**
Waits for an event object until it is in the signaled state. If
srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
waiting thread when the event becomes signaled (or immediately if the
@@ -178,128 +180,203 @@ UNIV_INTERN
void
os_event_wait_low(
/*==============*/
- os_event_t event, /* in: event to wait */
- ib_int64_t reset_sig_count);/* in: zero or the value
+ os_event_t event, /*!< in: event to wait */
+ ib_int64_t reset_sig_count);/*!< in: zero or the value
returned by previous call of
os_event_reset(). */
#define os_event_wait(event) os_event_wait_low(event, 0)
-/**************************************************************
+/**********************************************************//**
Waits for an event object until it is in the signaled state or
-a timeout is exceeded. In Unix the timeout is always infinite. */
+a timeout is exceeded. In Unix the timeout is always infinite.
+@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
UNIV_INTERN
ulint
os_event_wait_time(
/*===============*/
- /* out: 0 if success,
- OS_SYNC_TIME_EXCEEDED if timeout
- was exceeded */
- os_event_t event, /* in: event to wait */
- ulint time); /* in: timeout in microseconds, or
+ os_event_t event, /*!< in: event to wait */
+ ulint time); /*!< in: timeout in microseconds, or
OS_SYNC_INFINITE_TIME */
#ifdef __WIN__
-/**************************************************************
+/**********************************************************//**
Waits for any event in an OS native event array. Returns if even a single
-one is signaled or becomes signaled. */
+one is signaled or becomes signaled.
+@return index of the event which was signaled */
UNIV_INTERN
ulint
os_event_wait_multiple(
/*===================*/
- /* out: index of the event
- which was signaled */
- ulint n, /* in: number of events in the
+ ulint n, /*!< in: number of events in the
array */
os_native_event_t* native_event_array);
- /* in: pointer to an array of event
+ /*!< in: pointer to an array of event
handles */
#endif
-/*************************************************************
+/*********************************************************//**
Creates an operating system mutex semaphore. Because these are slow, the
-mutex semaphore of InnoDB itself (mutex_t) should be used where possible. */
+mutex semaphore of InnoDB itself (mutex_t) should be used where possible.
+@return the mutex handle */
UNIV_INTERN
os_mutex_t
os_mutex_create(
/*============*/
- /* out: the mutex handle */
- const char* name); /* in: the name of the mutex, if NULL
+ const char* name); /*!< in: the name of the mutex, if NULL
the mutex is created without a name */
-/**************************************************************
+/**********************************************************//**
Acquires ownership of a mutex semaphore. */
UNIV_INTERN
void
os_mutex_enter(
/*===========*/
- os_mutex_t mutex); /* in: mutex to acquire */
-/**************************************************************
+ os_mutex_t mutex); /*!< in: mutex to acquire */
+/**********************************************************//**
Releases ownership of a mutex. */
UNIV_INTERN
void
os_mutex_exit(
/*==========*/
- os_mutex_t mutex); /* in: mutex to release */
-/**************************************************************
+ os_mutex_t mutex); /*!< in: mutex to release */
+/**********************************************************//**
Frees an mutex object. */
UNIV_INTERN
void
os_mutex_free(
/*==========*/
- os_mutex_t mutex); /* in: mutex to free */
-/**************************************************************
+ os_mutex_t mutex); /*!< in: mutex to free */
+/**********************************************************//**
Acquires ownership of a fast mutex. Currently in Windows this is the same
-as os_fast_mutex_lock! */
+as os_fast_mutex_lock!
+@return 0 if success, != 0 if was reserved by another thread */
UNIV_INLINE
ulint
os_fast_mutex_trylock(
/*==================*/
- /* out: 0 if success, != 0 if
- was reserved by another
- thread */
- os_fast_mutex_t* fast_mutex); /* in: mutex to acquire */
-/**************************************************************
+ os_fast_mutex_t* fast_mutex); /*!< in: mutex to acquire */
+/**********************************************************//**
Releases ownership of a fast mutex. */
UNIV_INTERN
void
os_fast_mutex_unlock(
/*=================*/
- os_fast_mutex_t* fast_mutex); /* in: mutex to release */
-/*************************************************************
+ os_fast_mutex_t* fast_mutex); /*!< in: mutex to release */
+/*********************************************************//**
Initializes an operating system fast mutex semaphore. */
UNIV_INTERN
void
os_fast_mutex_init(
/*===============*/
- os_fast_mutex_t* fast_mutex); /* in: fast mutex */
-/**************************************************************
+ os_fast_mutex_t* fast_mutex); /*!< in: fast mutex */
+/**********************************************************//**
Acquires ownership of a fast mutex. */
UNIV_INTERN
void
os_fast_mutex_lock(
/*===============*/
- os_fast_mutex_t* fast_mutex); /* in: mutex to acquire */
-/**************************************************************
+ os_fast_mutex_t* fast_mutex); /*!< in: mutex to acquire */
+/**********************************************************//**
Frees an mutex object. */
UNIV_INTERN
void
os_fast_mutex_free(
/*===============*/
- os_fast_mutex_t* fast_mutex); /* in: mutex to free */
+ os_fast_mutex_t* fast_mutex); /*!< in: mutex to free */
+
+/**********************************************************//**
+Atomic compare-and-swap and increment for InnoDB. */
#ifdef HAVE_GCC_ATOMIC_BUILTINS
-/**************************************************************
-Atomic compare-and-swap for InnoDB. Currently requires GCC atomic builtins.
+/**********************************************************//**
Returns true if swapped, ptr is pointer to target, old_val is value to
compare to, new_val is the value to swap in. */
-#define os_compare_and_swap(ptr, old_val, new_val) \
+# define os_compare_and_swap(ptr, old_val, new_val) \
__sync_bool_compare_and_swap(ptr, old_val, new_val)
-
-/**************************************************************
-Atomic increment for InnoDB. Currently requires GCC atomic builtins.
+# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
+ os_compare_and_swap(ptr, old_val, new_val)
+# define os_compare_and_swap_lint(ptr, old_val, new_val) \
+ os_compare_and_swap(ptr, old_val, new_val)
+# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
+ os_compare_and_swap(ptr, old_val, new_val)
+/**********************************************************//**
Returns the resulting value, ptr is pointer to target, amount is the
amount of increment. */
-#define os_atomic_increment(ptr, amount) \
+# define os_atomic_increment(ptr, amount) \
__sync_add_and_fetch(ptr, amount)
-
+# define os_atomic_increment_lint(ptr, amount) \
+ os_atomic_increment(ptr, amount)
+# define os_atomic_increment_ulint(ptr, amount) \
+ os_atomic_increment(ptr, amount)
+/**********************************************************//**
+Returns the old value of *ptr, atomically sets *ptr to new_val */
+# define os_atomic_test_and_set_byte(ptr, new_val) \
+ __sync_lock_test_and_set(ptr, new_val)
+/* If not compiling with GCC or GCC doesn't support the atomic
+intrinsics and running on Solaris >= 10 use Solaris atomics */
+#elif defined(HAVE_SOLARIS_ATOMICS)
+#include <atomic.h>
+/**********************************************************//**
+Returns true if swapped, ptr is pointer to target, old_val is value to
+compare to, new_val is the value to swap in. */
+# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
+ (atomic_cas_ulong(ptr, old_val, new_val) == old_val)
+# define os_compare_and_swap_lint(ptr, old_val, new_val) \
+ ((lint)atomic_cas_ulong((ulong_t*) ptr, old_val, new_val) == old_val)
+# ifdef INNODB_RW_LOCKS_USE_ATOMICS
+# if SIZEOF_PTHREAD_T == 4
+# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
+ ((pthread_t)atomic_cas_32(ptr, old_val, new_val) == old_val)
+# elif SIZEOF_PTHREAD_T == 8
+# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
+ ((pthread_t)atomic_cas_64(ptr, old_val, new_val) == old_val)
+# else
+# error "SIZEOF_PTHREAD_T != 4 or 8"
+# endif /* SIZEOF_PTHREAD_T CHECK */
+# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
+
+/**********************************************************//**
+Returns the resulting value, ptr is pointer to target, amount is the
+amount of increment. */
+# define os_atomic_increment_lint(ptr, amount) \
+ atomic_add_long_nv((ulong_t*) ptr, amount)
+# define os_atomic_increment_ulint(ptr, amount) \
+ atomic_add_long_nv(ptr, amount)
+/**********************************************************//**
+Returns the old value of *ptr, atomically sets *ptr to new_val */
+# define os_atomic_test_and_set_byte(ptr, new_val) \
+ atomic_swap_uchar(ptr, new_val)
+/* On Windows, use Windows atomics / interlocked */
+#elif defined(HAVE_WINDOWS_ATOMICS)
+# ifdef _WIN64
+# define win_cmp_and_xchg InterlockedCompareExchange64
+# define win_xchg_and_add InterlockedExchangeAdd64
+# else /* _WIN64 */
+# define win_cmp_and_xchg InterlockedCompareExchange
+# define win_xchg_and_add InterlockedExchangeAdd
+# endif
+/**********************************************************//**
+Returns true if swapped, ptr is pointer to target, old_val is value to
+compare to, new_val is the value to swap in. */
+# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
+ (win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
+# define os_compare_and_swap_lint(ptr, old_val, new_val) \
+ (win_cmp_and_xchg(ptr, new_val, old_val) == old_val)
+# ifdef INNODB_RW_LOCKS_USE_ATOMICS
+# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
+ (InterlockedCompareExchange(ptr, new_val, old_val) == old_val)
+# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
+/**********************************************************//**
+Returns the resulting value, ptr is pointer to target, amount is the
+amount of increment. */
+# define os_atomic_increment_lint(ptr, amount) \
+ (win_xchg_and_add(ptr, amount) + amount)
+# define os_atomic_increment_ulint(ptr, amount) \
+ ((ulint) (win_xchg_and_add(ptr, amount) + amount))
+/**********************************************************//**
+Returns the old value of *ptr, atomically sets *ptr to new_val.
+InterlockedExchange() operates on LONG, and the LONG will be
+clobbered */
+# define os_atomic_test_and_set_byte(ptr, new_val) \
+ ((byte) InterlockedExchange(ptr, new_val))
#endif /* HAVE_GCC_ATOMIC_BUILTINS */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/os0sync.ic b/storage/xtradb/include/os0sync.ic
index 5c03d184c7c..1f3ce38fa65 100644
--- a/storage/xtradb/include/os0sync.ic
+++ b/storage/xtradb/include/os0sync.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/os0sync.ic
The interface to the operating system synchronization primitives.
Created 9/6/1995 Heikki Tuuri
@@ -26,30 +27,21 @@ Created 9/6/1995 Heikki Tuuri
#include <winbase.h>
#endif
-/**************************************************************
+/**********************************************************//**
Acquires ownership of a fast mutex. Currently in Windows this is the same
-as os_fast_mutex_lock! */
+as os_fast_mutex_lock!
+@return 0 if success, != 0 if was reserved by another thread */
UNIV_INLINE
ulint
os_fast_mutex_trylock(
/*==================*/
- /* out: 0 if success, != 0 if
- was reserved by another
- thread */
- os_fast_mutex_t* fast_mutex) /* in: mutex to acquire */
+ os_fast_mutex_t* fast_mutex) /*!< in: mutex to acquire */
{
#ifdef __WIN__
EnterCriticalSection(fast_mutex);
return(0);
#else
-#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
- /* Since the hot backup version is standalone, MySQL does not redefine
- pthread_mutex_trylock for HP-UX-10.20, and consequently we must invert
- the return value here */
-
- return((ulint) (1 - pthread_mutex_trylock(fast_mutex)));
-#else
/* NOTE that the MySQL my_pthread.h redefines pthread_mutex_trylock
so that it returns 0 on success. In the operating system
libraries, HP-UX-10.20 follows the old Posix 1003.4a Draft 4 and
@@ -58,5 +50,4 @@ os_fast_mutex_trylock(
return((ulint) pthread_mutex_trylock(fast_mutex));
#endif
-#endif
}
diff --git a/storage/xtradb/include/os0thread.h b/storage/xtradb/include/os0thread.h
index 863596bfa84..6583de0005f 100644
--- a/storage/xtradb/include/os0thread.h
+++ b/storage/xtradb/include/os0thread.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/os0thread.h
The interface to the operating system
process and thread control primitives
@@ -43,11 +44,11 @@ can wait inside InnoDB */
#ifdef __WIN__
typedef void* os_thread_t;
-typedef ulint os_thread_id_t; /* In Windows the thread id
+typedef unsigned long os_thread_id_t; /*!< In Windows the thread id
is an unsigned long int */
#else
typedef pthread_t os_thread_t;
-typedef os_thread_t os_thread_id_t; /* In Unix we use the thread
+typedef os_thread_t os_thread_id_t; /*!< In Unix we use the thread
handle itself as the id of
the thread */
#endif
@@ -55,97 +56,100 @@ typedef os_thread_t os_thread_id_t; /* In Unix we use the thread
/* Define a function pointer type to use in a typecast */
typedef void* (*os_posix_f_t) (void*);
-/*******************************************************************
-Compares two thread ids for equality. */
+/***************************************************************//**
+Compares two thread ids for equality.
+@return TRUE if equal */
UNIV_INTERN
ibool
os_thread_eq(
/*=========*/
- /* out: TRUE if equal */
- os_thread_id_t a, /* in: OS thread or thread id */
- os_thread_id_t b); /* in: OS thread or thread id */
-/********************************************************************
+ os_thread_id_t a, /*!< in: OS thread or thread id */
+ os_thread_id_t b); /*!< in: OS thread or thread id */
+/****************************************************************//**
Converts an OS thread id to a ulint. It is NOT guaranteed that the ulint is
-unique for the thread though! */
+unique for the thread though!
+@return thread identifier as a number */
UNIV_INTERN
ulint
os_thread_pf(
/*=========*/
- /* out: unsigned long int */
- os_thread_id_t a); /* in: thread or thread id */
-/********************************************************************
+ os_thread_id_t a); /*!< in: OS thread identifier */
+/****************************************************************//**
Creates a new thread of execution. The execution starts from
the function given. The start function takes a void* parameter
and returns a ulint.
NOTE: We count the number of threads in os_thread_exit(). A created
-thread should always use that to exit and not use return() to exit. */
+thread should always use that to exit and not use return() to exit.
+@return handle to the thread */
UNIV_INTERN
os_thread_t
os_thread_create(
/*=============*/
- /* out: handle to the thread */
#ifndef __WIN__
os_posix_f_t start_f,
#else
- ulint (*start_f)(void*), /* in: pointer to function
+ ulint (*start_f)(void*), /*!< in: pointer to function
from which to start */
#endif
- void* arg, /* in: argument to start
+ void* arg, /*!< in: argument to start
function */
- os_thread_id_t* thread_id); /* out: id of the created
+ os_thread_id_t* thread_id); /*!< out: id of the created
thread, or NULL */
-/*********************************************************************
+/*****************************************************************//**
Exits the current thread. */
UNIV_INTERN
void
os_thread_exit(
/*===========*/
- void* exit_value); /* in: exit value; in Windows this void*
+ void* exit_value); /*!< in: exit value; in Windows this void*
is cast as a DWORD */
-/*********************************************************************
-Returns the thread identifier of current thread. */
+/*****************************************************************//**
+Returns the thread identifier of current thread.
+@return current thread identifier */
UNIV_INTERN
os_thread_id_t
os_thread_get_curr_id(void);
/*========================*/
-/*********************************************************************
-Returns handle to the current thread. */
+/*****************************************************************//**
+Returns handle to the current thread.
+@return current thread handle */
UNIV_INTERN
os_thread_t
os_thread_get_curr(void);
/*====================*/
-/*********************************************************************
+/*****************************************************************//**
Advises the os to give up remainder of the thread's time slice. */
UNIV_INTERN
void
os_thread_yield(void);
/*=================*/
-/*********************************************************************
+/*****************************************************************//**
The thread sleeps at least the time given in microseconds. */
UNIV_INTERN
void
os_thread_sleep(
/*============*/
- ulint tm); /* in: time in microseconds */
-/**********************************************************************
-Gets a thread priority. */
+ ulint tm); /*!< in: time in microseconds */
+/******************************************************************//**
+Gets a thread priority.
+@return priority */
UNIV_INTERN
ulint
os_thread_get_priority(
/*===================*/
- /* out: priority */
- os_thread_t handle);/* in: OS handle to the thread */
-/**********************************************************************
+ os_thread_t handle);/*!< in: OS handle to the thread */
+/******************************************************************//**
Sets a thread priority. */
UNIV_INTERN
void
os_thread_set_priority(
/*===================*/
- os_thread_t handle, /* in: OS handle to the thread */
- ulint pri); /* in: priority: one of OS_PRIORITY_... */
-/**********************************************************************
-Gets the last operating system error code for the calling thread. */
+ os_thread_t handle, /*!< in: OS handle to the thread */
+ ulint pri); /*!< in: priority: one of OS_PRIORITY_... */
+/******************************************************************//**
+Gets the last operating system error code for the calling thread.
+@return last error on Windows, 0 otherwise */
UNIV_INTERN
ulint
os_thread_get_last_error(void);
diff --git a/storage/xtradb/include/os0thread.ic b/storage/xtradb/include/os0thread.ic
index a86b203809c..f89bc40b4fa 100644
--- a/storage/xtradb/include/os0thread.ic
+++ b/storage/xtradb/include/os0thread.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/os0thread.ic
The interface to the operating system
process and thread control primitives
diff --git a/storage/xtradb/include/page0cur.h b/storage/xtradb/include/page0cur.h
index 960ecdddf4e..1544b0abe1c 100644
--- a/storage/xtradb/include/page0cur.h
+++ b/storage/xtradb/include/page0cur.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/page0cur.h
The page cursor
Created 10/4/1994 Heikki Tuuri
@@ -52,291 +53,290 @@ Created 10/4/1994 Heikki Tuuri
#endif /* UNIV_SEARCH_DEBUG */
#ifdef UNIV_DEBUG
-/*************************************************************
-Gets pointer to the page frame where the cursor is positioned. */
+/*********************************************************//**
+Gets pointer to the page frame where the cursor is positioned.
+@return page */
UNIV_INLINE
page_t*
page_cur_get_page(
/*==============*/
- /* out: page */
- page_cur_t* cur); /* in: page cursor */
-/*************************************************************
-Gets pointer to the buffer block where the cursor is positioned. */
+ page_cur_t* cur); /*!< in: page cursor */
+/*********************************************************//**
+Gets pointer to the buffer block where the cursor is positioned.
+@return page */
UNIV_INLINE
buf_block_t*
page_cur_get_block(
/*===============*/
- /* out: page */
- page_cur_t* cur); /* in: page cursor */
-/*************************************************************
-Gets pointer to the page frame where the cursor is positioned. */
+ page_cur_t* cur); /*!< in: page cursor */
+/*********************************************************//**
+Gets pointer to the page frame where the cursor is positioned.
+@return page */
UNIV_INLINE
page_zip_des_t*
page_cur_get_page_zip(
/*==================*/
- /* out: page */
- page_cur_t* cur); /* in: page cursor */
-/*************************************************************
-Gets the record where the cursor is positioned. */
+ page_cur_t* cur); /*!< in: page cursor */
+/*********************************************************//**
+Gets the record where the cursor is positioned.
+@return record */
UNIV_INLINE
rec_t*
page_cur_get_rec(
/*=============*/
- /* out: record */
- page_cur_t* cur); /* in: page cursor */
+ page_cur_t* cur); /*!< in: page cursor */
#else /* UNIV_DEBUG */
# define page_cur_get_page(cur) page_align((cur)->rec)
# define page_cur_get_block(cur) (cur)->block
# define page_cur_get_page_zip(cur) buf_block_get_page_zip((cur)->block)
# define page_cur_get_rec(cur) (cur)->rec
#endif /* UNIV_DEBUG */
-/*************************************************************
+/*********************************************************//**
Sets the cursor object to point before the first user record
on the page. */
UNIV_INLINE
void
page_cur_set_before_first(
/*======================*/
- const buf_block_t* block, /* in: index page */
- page_cur_t* cur); /* in: cursor */
-/*************************************************************
+ const buf_block_t* block, /*!< in: index page */
+ page_cur_t* cur); /*!< in: cursor */
+/*********************************************************//**
Sets the cursor object to point after the last user record on
the page. */
UNIV_INLINE
void
page_cur_set_after_last(
/*====================*/
- const buf_block_t* block, /* in: index page */
- page_cur_t* cur); /* in: cursor */
-/*************************************************************
-Returns TRUE if the cursor is before first user record on page. */
+ const buf_block_t* block, /*!< in: index page */
+ page_cur_t* cur); /*!< in: cursor */
+/*********************************************************//**
+Returns TRUE if the cursor is before first user record on page.
+@return TRUE if at start */
UNIV_INLINE
ibool
page_cur_is_before_first(
/*=====================*/
- /* out: TRUE if at start */
- const page_cur_t* cur); /* in: cursor */
-/*************************************************************
-Returns TRUE if the cursor is after last user record. */
+ const page_cur_t* cur); /*!< in: cursor */
+/*********************************************************//**
+Returns TRUE if the cursor is after last user record.
+@return TRUE if at end */
UNIV_INLINE
ibool
page_cur_is_after_last(
/*===================*/
- /* out: TRUE if at end */
- const page_cur_t* cur); /* in: cursor */
-/**************************************************************
+ const page_cur_t* cur); /*!< in: cursor */
+/**********************************************************//**
Positions the cursor on the given record. */
UNIV_INLINE
void
page_cur_position(
/*==============*/
- const rec_t* rec, /* in: record on a page */
- const buf_block_t* block, /* in: buffer block containing
+ const rec_t* rec, /*!< in: record on a page */
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- page_cur_t* cur); /* out: page cursor */
-/**************************************************************
+ page_cur_t* cur); /*!< out: page cursor */
+/**********************************************************//**
Invalidates a page cursor by setting the record pointer NULL. */
UNIV_INLINE
void
page_cur_invalidate(
/*================*/
- page_cur_t* cur); /* out: page cursor */
-/**************************************************************
+ page_cur_t* cur); /*!< out: page cursor */
+/**********************************************************//**
Moves the cursor to the next record on page. */
UNIV_INLINE
void
page_cur_move_to_next(
/*==================*/
- page_cur_t* cur); /* in/out: cursor; must not be after last */
-/**************************************************************
+ page_cur_t* cur); /*!< in/out: cursor; must not be after last */
+/**********************************************************//**
Moves the cursor to the previous record on page. */
UNIV_INLINE
void
page_cur_move_to_prev(
/*==================*/
- page_cur_t* cur); /* in/out: cursor; not before first */
-/***************************************************************
+ page_cur_t* cur); /*!< in/out: cursor; not before first */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************//**
Inserts a record next to page cursor. Returns pointer to inserted record if
succeed, i.e., enough space available, NULL otherwise. The cursor stays at
the same logical position, but the physical position may change if it is
-pointing to a compressed page that was reorganized. */
+pointing to a compressed page that was reorganized.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INLINE
rec_t*
page_cur_tuple_insert(
/*==================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- page_cur_t* cursor, /* in/out: a page cursor */
- const dtuple_t* tuple, /* in: pointer to a data tuple */
- dict_index_t* index, /* in: record descriptor */
- ulint n_ext, /* in: number of externally stored columns */
- mtr_t* mtr); /* in: mini-transaction handle, or NULL */
-/***************************************************************
+ page_cur_t* cursor, /*!< in/out: a page cursor */
+ const dtuple_t* tuple, /*!< in: pointer to a data tuple */
+ dict_index_t* index, /*!< in: record descriptor */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ mtr_t* mtr); /*!< in: mini-transaction handle, or NULL */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************//**
Inserts a record next to page cursor. Returns pointer to inserted record if
succeed, i.e., enough space available, NULL otherwise. The cursor stays at
the same logical position, but the physical position may change if it is
-pointing to a compressed page that was reorganized. */
+pointing to a compressed page that was reorganized.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INLINE
rec_t*
page_cur_rec_insert(
/*================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- page_cur_t* cursor, /* in/out: a page cursor */
- const rec_t* rec, /* in: record to insert */
- dict_index_t* index, /* in: record descriptor */
- ulint* offsets,/* in/out: rec_get_offsets(rec, index) */
- mtr_t* mtr); /* in: mini-transaction handle, or NULL */
-/***************************************************************
+ page_cur_t* cursor, /*!< in/out: a page cursor */
+ const rec_t* rec, /*!< in: record to insert */
+ dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
+ mtr_t* mtr); /*!< in: mini-transaction handle, or NULL */
+/***********************************************************//**
Inserts a record next to page cursor on an uncompressed page.
Returns pointer to inserted record if succeed, i.e., enough
-space available, NULL otherwise. The cursor stays at the same position. */
+space available, NULL otherwise. The cursor stays at the same position.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INTERN
rec_t*
page_cur_insert_rec_low(
/*====================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- rec_t* current_rec,/* in: pointer to current record after
+ rec_t* current_rec,/*!< in: pointer to current record after
which the new record is inserted */
- dict_index_t* index, /* in: record descriptor */
- const rec_t* rec, /* in: pointer to a physical record */
- ulint* offsets,/* in/out: rec_get_offsets(rec, index) */
- mtr_t* mtr); /* in: mini-transaction handle, or NULL */
-/***************************************************************
+ dict_index_t* index, /*!< in: record descriptor */
+ const rec_t* rec, /*!< in: pointer to a physical record */
+ ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
+ mtr_t* mtr); /*!< in: mini-transaction handle, or NULL */
+/***********************************************************//**
Inserts a record next to page cursor on a compressed and uncompressed
page. Returns pointer to inserted record if succeed, i.e.,
enough space available, NULL otherwise.
-The cursor stays at the same position. */
+The cursor stays at the same position.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INTERN
rec_t*
page_cur_insert_rec_zip(
/*====================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- rec_t** current_rec,/* in/out: pointer to current record after
+ rec_t** current_rec,/*!< in/out: pointer to current record after
which the new record is inserted */
- buf_block_t* block, /* in: buffer block of *current_rec */
- dict_index_t* index, /* in: record descriptor */
- const rec_t* rec, /* in: pointer to a physical record */
- ulint* offsets,/* in/out: rec_get_offsets(rec, index) */
- mtr_t* mtr); /* in: mini-transaction handle, or NULL */
-/*****************************************************************
+ buf_block_t* block, /*!< in: buffer block of *current_rec */
+ dict_index_t* index, /*!< in: record descriptor */
+ const rec_t* rec, /*!< in: pointer to a physical record */
+ ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
+ mtr_t* mtr); /*!< in: mini-transaction handle, or NULL */
+/*************************************************************//**
Copies records from page to a newly created page, from a given record onward,
including that record. Infimum and supremum records are not copied. */
UNIV_INTERN
void
page_copy_rec_list_end_to_created_page(
/*===================================*/
- page_t* new_page, /* in/out: index page to copy to */
- rec_t* rec, /* in: first record to copy */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr); /* in: mtr */
-/***************************************************************
+ page_t* new_page, /*!< in/out: index page to copy to */
+ rec_t* rec, /*!< in: first record to copy */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr); /*!< in: mtr */
+/***********************************************************//**
Deletes a record at the page cursor. The cursor is moved to the
next record after the deleted one. */
UNIV_INTERN
void
page_cur_delete_rec(
/*================*/
- page_cur_t* cursor, /* in/out: a page cursor */
- dict_index_t* index, /* in: record descriptor */
- const ulint* offsets,/* in: rec_get_offsets(cursor->rec, index) */
- mtr_t* mtr); /* in: mini-transaction handle */
-/********************************************************************
-Searches the right position for a page cursor. */
+ page_cur_t* cursor, /*!< in/out: a page cursor */
+ dict_index_t* index, /*!< in: record descriptor */
+ const ulint* offsets,/*!< in: rec_get_offsets(cursor->rec, index) */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
+Searches the right position for a page cursor.
+@return number of matched fields on the left */
UNIV_INLINE
ulint
page_cur_search(
/*============*/
- /* out: number of matched
- fields on the left */
- const buf_block_t* block, /* in: buffer block */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* tuple, /* in: data tuple */
- ulint mode, /* in: PAGE_CUR_L,
+ const buf_block_t* block, /*!< in: buffer block */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* tuple, /*!< in: data tuple */
+ ulint mode, /*!< in: PAGE_CUR_L,
PAGE_CUR_LE, PAGE_CUR_G, or
PAGE_CUR_GE */
- page_cur_t* cursor);/* out: page cursor */
-/********************************************************************
+ page_cur_t* cursor);/*!< out: page cursor */
+/****************************************************************//**
Searches the right position for a page cursor. */
UNIV_INTERN
void
page_cur_search_with_match(
/*=======================*/
- const buf_block_t* block, /* in: buffer block */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* tuple, /* in: data tuple */
- ulint mode, /* in: PAGE_CUR_L,
+ const buf_block_t* block, /*!< in: buffer block */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* tuple, /*!< in: data tuple */
+ ulint mode, /*!< in: PAGE_CUR_L,
PAGE_CUR_LE, PAGE_CUR_G, or
PAGE_CUR_GE */
ulint* iup_matched_fields,
- /* in/out: already matched
+ /*!< in/out: already matched
fields in upper limit record */
ulint* iup_matched_bytes,
- /* in/out: already matched
+ /*!< in/out: already matched
bytes in a field not yet
completely matched */
ulint* ilow_matched_fields,
- /* in/out: already matched
+ /*!< in/out: already matched
fields in lower limit record */
ulint* ilow_matched_bytes,
- /* in/out: already matched
+ /*!< in/out: already matched
bytes in a field not yet
completely matched */
- page_cur_t* cursor);/* out: page cursor */
-/***************************************************************
+ page_cur_t* cursor);/*!< out: page cursor */
+/***********************************************************//**
Positions a page cursor on a randomly chosen user record on a page. If there
are no user records, sets the cursor on the infimum record. */
UNIV_INTERN
void
page_cur_open_on_rnd_user_rec(
/*==========================*/
- buf_block_t* block, /* in: page */
- page_cur_t* cursor);/* out: page cursor */
-/***************************************************************
-Parses a log record of a record insert on a page. */
+ buf_block_t* block, /*!< in: page */
+ page_cur_t* cursor);/*!< out: page cursor */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************//**
+Parses a log record of a record insert on a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_cur_parse_insert_rec(
/*======================*/
- /* out: end of log record or NULL */
- ibool is_short,/* in: TRUE if short inserts */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in: page or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr); /* in: mtr or NULL */
-/**************************************************************
-Parses a log record of copying a record list end to a new created page. */
+ ibool is_short,/*!< in: TRUE if short inserts */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in: page or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+/**********************************************************//**
+Parses a log record of copying a record list end to a new created page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_parse_copy_rec_list_to_created_page(
/*=====================================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in: page or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr); /* in: mtr or NULL */
-/***************************************************************
-Parses log record of a record delete on a page. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in: page or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+/***********************************************************//**
+Parses log record of a record delete on a page.
+@return pointer to record end or NULL */
UNIV_INTERN
byte*
page_cur_parse_delete_rec(
/*======================*/
- /* out: pointer to record end or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in: page or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr); /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in: page or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr); /*!< in: mtr or NULL */
-/* Index page cursor */
+/** Index page cursor */
struct page_cur_struct{
- byte* rec; /* pointer to a record on page */
- buf_block_t* block; /* pointer to the block containing rec */
+ byte* rec; /*!< pointer to a record on page */
+ buf_block_t* block; /*!< pointer to the block containing rec */
};
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/page0cur.ic b/storage/xtradb/include/page0cur.ic
index 9cf10ea5e3f..3520677dfb3 100644
--- a/storage/xtradb/include/page0cur.ic
+++ b/storage/xtradb/include/page0cur.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/page0cur.ic
The page cursor
Created 10/4/1994 Heikki Tuuri
@@ -26,14 +27,14 @@ Created 10/4/1994 Heikki Tuuri
#include "buf0types.h"
#ifdef UNIV_DEBUG
-/*************************************************************
-Gets pointer to the page frame where the cursor is positioned. */
+/*********************************************************//**
+Gets pointer to the page frame where the cursor is positioned.
+@return page */
UNIV_INLINE
page_t*
page_cur_get_page(
/*==============*/
- /* out: page */
- page_cur_t* cur) /* in: page cursor */
+ page_cur_t* cur) /*!< in: page cursor */
{
ut_ad(cur);
ut_ad(page_align(cur->rec) == cur->block->frame);
@@ -41,40 +42,40 @@ page_cur_get_page(
return(page_align(cur->rec));
}
-/*************************************************************
-Gets pointer to the buffer block where the cursor is positioned. */
+/*********************************************************//**
+Gets pointer to the buffer block where the cursor is positioned.
+@return page */
UNIV_INLINE
buf_block_t*
page_cur_get_block(
/*===============*/
- /* out: page */
- page_cur_t* cur) /* in: page cursor */
+ page_cur_t* cur) /*!< in: page cursor */
{
ut_ad(cur);
ut_ad(page_align(cur->rec) == cur->block->frame);
return(cur->block);
}
-/*************************************************************
-Gets pointer to the page frame where the cursor is positioned. */
+/*********************************************************//**
+Gets pointer to the page frame where the cursor is positioned.
+@return page */
UNIV_INLINE
page_zip_des_t*
page_cur_get_page_zip(
/*==================*/
- /* out: page */
- page_cur_t* cur) /* in: page cursor */
+ page_cur_t* cur) /*!< in: page cursor */
{
return(buf_block_get_page_zip(page_cur_get_block(cur)));
}
-/*************************************************************
-Gets the record where the cursor is positioned. */
+/*********************************************************//**
+Gets the record where the cursor is positioned.
+@return record */
UNIV_INLINE
rec_t*
page_cur_get_rec(
/*=============*/
- /* out: record */
- page_cur_t* cur) /* in: page cursor */
+ page_cur_t* cur) /*!< in: page cursor */
{
ut_ad(cur);
ut_ad(page_align(cur->rec) == cur->block->frame);
@@ -83,72 +84,72 @@ page_cur_get_rec(
}
#endif /* UNIV_DEBUG */
-/*************************************************************
+/*********************************************************//**
Sets the cursor object to point before the first user record
on the page. */
UNIV_INLINE
void
page_cur_set_before_first(
/*======================*/
- const buf_block_t* block, /* in: index page */
- page_cur_t* cur) /* in: cursor */
+ const buf_block_t* block, /*!< in: index page */
+ page_cur_t* cur) /*!< in: cursor */
{
cur->block = (buf_block_t*) block;
cur->rec = page_get_infimum_rec(buf_block_get_frame(cur->block));
}
-/*************************************************************
+/*********************************************************//**
Sets the cursor object to point after the last user record on
the page. */
UNIV_INLINE
void
page_cur_set_after_last(
/*====================*/
- const buf_block_t* block, /* in: index page */
- page_cur_t* cur) /* in: cursor */
+ const buf_block_t* block, /*!< in: index page */
+ page_cur_t* cur) /*!< in: cursor */
{
cur->block = (buf_block_t*) block;
cur->rec = page_get_supremum_rec(buf_block_get_frame(cur->block));
}
-/*************************************************************
-Returns TRUE if the cursor is before first user record on page. */
+/*********************************************************//**
+Returns TRUE if the cursor is before first user record on page.
+@return TRUE if at start */
UNIV_INLINE
ibool
page_cur_is_before_first(
/*=====================*/
- /* out: TRUE if at start */
- const page_cur_t* cur) /* in: cursor */
+ const page_cur_t* cur) /*!< in: cursor */
{
ut_ad(cur);
ut_ad(page_align(cur->rec) == cur->block->frame);
return(page_rec_is_infimum(cur->rec));
}
-/*************************************************************
-Returns TRUE if the cursor is after last user record. */
+/*********************************************************//**
+Returns TRUE if the cursor is after last user record.
+@return TRUE if at end */
UNIV_INLINE
ibool
page_cur_is_after_last(
/*===================*/
- /* out: TRUE if at end */
- const page_cur_t* cur) /* in: cursor */
+ const page_cur_t* cur) /*!< in: cursor */
{
ut_ad(cur);
ut_ad(page_align(cur->rec) == cur->block->frame);
return(page_rec_is_supremum(cur->rec));
}
-/**************************************************************
+/**********************************************************//**
Positions the cursor on the given record. */
UNIV_INLINE
void
page_cur_position(
/*==============*/
- const rec_t* rec, /* in: record on a page */
- const buf_block_t* block, /* in: buffer block containing
+ const rec_t* rec, /*!< in: record on a page */
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- page_cur_t* cur) /* out: page cursor */
+ page_cur_t* cur) /*!< out: page cursor */
{
ut_ad(rec && block && cur);
ut_ad(page_align(rec) == block->frame);
@@ -157,13 +158,13 @@ page_cur_position(
cur->block = (buf_block_t*) block;
}
-/**************************************************************
+/**********************************************************//**
Invalidates a page cursor by setting the record pointer NULL. */
UNIV_INLINE
void
page_cur_invalidate(
/*================*/
- page_cur_t* cur) /* out: page cursor */
+ page_cur_t* cur) /*!< out: page cursor */
{
ut_ad(cur);
@@ -171,47 +172,47 @@ page_cur_invalidate(
cur->block = NULL;
}
-/**************************************************************
+/**********************************************************//**
Moves the cursor to the next record on page. */
UNIV_INLINE
void
page_cur_move_to_next(
/*==================*/
- page_cur_t* cur) /* in/out: cursor; must not be after last */
+ page_cur_t* cur) /*!< in/out: cursor; must not be after last */
{
ut_ad(!page_cur_is_after_last(cur));
cur->rec = page_rec_get_next(cur->rec);
}
-/**************************************************************
+/**********************************************************//**
Moves the cursor to the previous record on page. */
UNIV_INLINE
void
page_cur_move_to_prev(
/*==================*/
- page_cur_t* cur) /* in/out: page cursor, not before first */
+ page_cur_t* cur) /*!< in/out: page cursor, not before first */
{
ut_ad(!page_cur_is_before_first(cur));
cur->rec = page_rec_get_prev(cur->rec);
}
-/********************************************************************
-Searches the right position for a page cursor. */
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
+Searches the right position for a page cursor.
+@return number of matched fields on the left */
UNIV_INLINE
ulint
page_cur_search(
/*============*/
- /* out: number of matched
- fields on the left */
- const buf_block_t* block, /* in: buffer block */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* tuple, /* in: data tuple */
- ulint mode, /* in: PAGE_CUR_L,
+ const buf_block_t* block, /*!< in: buffer block */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* tuple, /*!< in: data tuple */
+ ulint mode, /*!< in: PAGE_CUR_L,
PAGE_CUR_LE, PAGE_CUR_G, or
PAGE_CUR_GE */
- page_cur_t* cursor) /* out: page cursor */
+ page_cur_t* cursor) /*!< out: page cursor */
{
ulint low_matched_fields = 0;
ulint low_matched_bytes = 0;
@@ -229,22 +230,21 @@ page_cur_search(
return(low_matched_fields);
}
-/***************************************************************
+/***********************************************************//**
Inserts a record next to page cursor. Returns pointer to inserted record if
succeed, i.e., enough space available, NULL otherwise. The cursor stays at
the same logical position, but the physical position may change if it is
-pointing to a compressed page that was reorganized. */
+pointing to a compressed page that was reorganized.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INLINE
rec_t*
page_cur_tuple_insert(
/*==================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- page_cur_t* cursor, /* in/out: a page cursor */
- const dtuple_t* tuple, /* in: pointer to a data tuple */
- dict_index_t* index, /* in: record descriptor */
- ulint n_ext, /* in: number of externally stored columns */
- mtr_t* mtr) /* in: mini-transaction handle, or NULL */
+ page_cur_t* cursor, /*!< in/out: a page cursor */
+ const dtuple_t* tuple, /*!< in: pointer to a data tuple */
+ dict_index_t* index, /*!< in: record descriptor */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
{
mem_heap_t* heap;
ulint* offsets;
@@ -271,23 +271,23 @@ page_cur_tuple_insert(
mem_heap_free(heap);
return(rec);
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
+/***********************************************************//**
Inserts a record next to page cursor. Returns pointer to inserted record if
succeed, i.e., enough space available, NULL otherwise. The cursor stays at
the same logical position, but the physical position may change if it is
-pointing to a compressed page that was reorganized. */
+pointing to a compressed page that was reorganized.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INLINE
rec_t*
page_cur_rec_insert(
/*================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- page_cur_t* cursor, /* in/out: a page cursor */
- const rec_t* rec, /* in: record to insert */
- dict_index_t* index, /* in: record descriptor */
- ulint* offsets,/* in/out: rec_get_offsets(rec, index) */
- mtr_t* mtr) /* in: mini-transaction handle, or NULL */
+ page_cur_t* cursor, /*!< in/out: a page cursor */
+ const rec_t* rec, /*!< in: record to insert */
+ dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
+ mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
{
if (buf_block_get_page_zip(cursor->block)) {
return(page_cur_insert_rec_zip(&cursor->rec, cursor->block,
@@ -297,4 +297,3 @@ page_cur_rec_insert(
index, rec, offsets, mtr));
}
}
-
diff --git a/storage/xtradb/include/page0page.h b/storage/xtradb/include/page0page.h
index e3de6901ee1..a4fe069d022 100644
--- a/storage/xtradb/include/page0page.h
+++ b/storage/xtradb/include/page0page.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/page0page.h
Index page routines
Created 2/2/1994 Heikki Tuuri
@@ -66,8 +67,8 @@ typedef byte page_header_t;
#define PAGE_N_RECS 16 /* number of user records on the page */
#define PAGE_MAX_TRX_ID 18 /* highest id of a trx which may have modified
a record on the page; a dulint; defined only
- in secondary indexes; specifically, not in an
- ibuf tree; NOTE: this may be modified only
+ in secondary indexes and in the insert buffer
+ tree; NOTE: this may be modified only
when the thread has an x-latch to the page,
and ALSO an x-latch to btr_search_latch
if there is a hash index to the page! */
@@ -156,294 +157,296 @@ directory. */
#define PAGE_DIR_SLOT_MAX_N_OWNED 8
#define PAGE_DIR_SLOT_MIN_N_OWNED 4
-/****************************************************************
-Gets the start of a page. */
+/************************************************************//**
+Gets the start of a page.
+@return start of the page */
UNIV_INLINE
page_t*
page_align(
/*=======*/
- /* out: start of the page */
- const void* ptr) /* in: pointer to page frame */
+ const void* ptr) /*!< in: pointer to page frame */
__attribute__((const));
-/****************************************************************
-Gets the offset within a page. */
+/************************************************************//**
+Gets the offset within a page.
+@return offset from the start of the page */
UNIV_INLINE
ulint
page_offset(
/*========*/
- /* out: offset from the start of the page */
- const void* ptr) /* in: pointer to page frame */
+ const void* ptr) /*!< in: pointer to page frame */
__attribute__((const));
-/*****************************************************************
+/*************************************************************//**
Returns the max trx id field value. */
UNIV_INLINE
-dulint
+trx_id_t
page_get_max_trx_id(
/*================*/
- const page_t* page); /* in: page */
-/*****************************************************************
+ const page_t* page); /*!< in: page */
+/*************************************************************//**
Sets the max trx id field value. */
UNIV_INTERN
void
page_set_max_trx_id(
/*================*/
- buf_block_t* block, /* in/out: page */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- dulint trx_id);/* in: transaction id */
-/*****************************************************************
+ buf_block_t* block, /*!< in/out: page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr); /*!< in/out: mini-transaction, or NULL */
+/*************************************************************//**
Sets the max trx id field value if trx_id is bigger than the previous
value. */
UNIV_INLINE
void
page_update_max_trx_id(
/*===================*/
- buf_block_t* block, /* in/out: page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ buf_block_t* block, /*!< in/out: page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
- dulint trx_id);/* in: transaction id */
-/*****************************************************************
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr); /*!< in/out: mini-transaction */
+/*************************************************************//**
Reads the given header field. */
UNIV_INLINE
ulint
page_header_get_field(
/*==================*/
- const page_t* page, /* in: page */
- ulint field); /* in: PAGE_N_DIR_SLOTS, ... */
-/*****************************************************************
+ const page_t* page, /*!< in: page */
+ ulint field); /*!< in: PAGE_N_DIR_SLOTS, ... */
+/*************************************************************//**
Sets the given header field. */
UNIV_INLINE
void
page_header_set_field(
/*==================*/
- page_t* page, /* in/out: page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ page_t* page, /*!< in/out: page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
- ulint field, /* in: PAGE_N_DIR_SLOTS, ... */
- ulint val); /* in: value */
-/*****************************************************************
-Returns the offset stored in the given header field. */
+ ulint field, /*!< in: PAGE_N_DIR_SLOTS, ... */
+ ulint val); /*!< in: value */
+/*************************************************************//**
+Returns the offset stored in the given header field.
+@return offset from the start of the page, or 0 */
UNIV_INLINE
ulint
page_header_get_offs(
/*=================*/
- /* out: offset from the start of the page,
- or 0 */
- const page_t* page, /* in: page */
- ulint field) /* in: PAGE_FREE, ... */
+ const page_t* page, /*!< in: page */
+ ulint field) /*!< in: PAGE_FREE, ... */
__attribute__((nonnull, pure));
-/*****************************************************************
+/*************************************************************//**
Returns the pointer stored in the given header field, or NULL. */
#define page_header_get_ptr(page, field) \
(page_header_get_offs(page, field) \
? page + page_header_get_offs(page, field) : NULL)
-/*****************************************************************
+/*************************************************************//**
Sets the pointer stored in the given header field. */
UNIV_INLINE
void
page_header_set_ptr(
/*================*/
- page_t* page, /* in/out: page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ page_t* page, /*!< in/out: page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
- ulint field, /* in/out: PAGE_FREE, ... */
- const byte* ptr); /* in: pointer or NULL*/
-/*****************************************************************
+ ulint field, /*!< in/out: PAGE_FREE, ... */
+ const byte* ptr); /*!< in: pointer or NULL*/
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Resets the last insert info field in the page header. Writes to mlog
about this operation. */
UNIV_INLINE
void
page_header_reset_last_insert(
/*==========================*/
- page_t* page, /* in: page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ page_t* page, /*!< in: page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
- mtr_t* mtr); /* in: mtr */
-/****************************************************************
-Gets the offset of the first record on the page. */
+ mtr_t* mtr); /*!< in: mtr */
+#endif /* !UNIV_HOTBACKUP */
+/************************************************************//**
+Gets the offset of the first record on the page.
+@return offset of the first record in record list, relative from page */
UNIV_INLINE
ulint
page_get_infimum_offset(
/*====================*/
- /* out: offset of the first record
- in record list, relative from page */
- const page_t* page); /* in: page which must have record(s) */
-/****************************************************************
-Gets the offset of the last record on the page. */
+ const page_t* page); /*!< in: page which must have record(s) */
+/************************************************************//**
+Gets the offset of the last record on the page.
+@return offset of the last record in record list, relative from page */
UNIV_INLINE
ulint
page_get_supremum_offset(
/*=====================*/
- /* out: offset of the last record in
- record list, relative from page */
- const page_t* page); /* in: page which must have record(s) */
+ const page_t* page); /*!< in: page which must have record(s) */
#define page_get_infimum_rec(page) ((page) + page_get_infimum_offset(page))
#define page_get_supremum_rec(page) ((page) + page_get_supremum_offset(page))
-/****************************************************************
+/************************************************************//**
Returns the middle record of record list. If there are an even number
-of records in the list, returns the first record of upper half-list. */
+of records in the list, returns the first record of upper half-list.
+@return middle record */
UNIV_INTERN
rec_t*
page_get_middle_rec(
/*================*/
- /* out: middle record */
- page_t* page); /* in: page */
-/*****************************************************************
+ page_t* page); /*!< in: page */
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Compares a data tuple to a physical record. Differs from the function
cmp_dtuple_rec_with_match in the way that the record must reside on an
index page, and also page infimum and supremum records can be given in
the parameter rec. These are considered as the negative infinity and
-the positive infinity in the alphabetical order. */
+the positive infinity in the alphabetical order.
+@return 1, 0, -1, if dtuple is greater, equal, less than rec,
+respectively, when only the common first fields are compared */
UNIV_INLINE
int
page_cmp_dtuple_rec_with_match(
/*===========================*/
- /* out: 1, 0, -1, if dtuple is greater, equal,
- less than rec, respectively, when only the
- common first fields are compared */
- const dtuple_t* dtuple, /* in: data tuple */
- const rec_t* rec, /* in: physical record on a page; may also
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record on a page; may also
be page infimum or supremum, in which case
matched-parameter values below are not
affected */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint* matched_fields, /* in/out: number of already completely
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint* matched_fields, /*!< in/out: number of already completely
matched fields; when function returns
contains the value for current comparison */
- ulint* matched_bytes); /* in/out: number of already matched
+ ulint* matched_bytes); /*!< in/out: number of already matched
bytes within the first field not completely
matched; when function returns contains the
value for current comparison */
-/*****************************************************************
-Gets the page number. */
+#endif /* !UNIV_HOTBACKUP */
+/*************************************************************//**
+Gets the page number.
+@return page number */
UNIV_INLINE
ulint
page_get_page_no(
/*=============*/
- /* out: page number */
- const page_t* page); /* in: page */
-/*****************************************************************
-Gets the tablespace identifier. */
+ const page_t* page); /*!< in: page */
+/*************************************************************//**
+Gets the tablespace identifier.
+@return space id */
UNIV_INLINE
ulint
page_get_space_id(
/*==============*/
- /* out: space id */
- const page_t* page); /* in: page */
-/*****************************************************************
+ const page_t* page); /*!< in: page */
+/*************************************************************//**
Gets the number of user records on page (the infimum and supremum records
-are not user records). */
+are not user records).
+@return number of user records */
UNIV_INLINE
ulint
page_get_n_recs(
/*============*/
- /* out: number of user records */
- const page_t* page); /* in: index page */
-/*******************************************************************
+ const page_t* page); /*!< in: index page */
+/***************************************************************//**
Returns the number of records before the given record in chain.
-The number includes infimum and supremum records. */
+The number includes infimum and supremum records.
+@return number of records */
UNIV_INTERN
ulint
page_rec_get_n_recs_before(
/*=======================*/
- /* out: number of records */
- const rec_t* rec); /* in: the physical record */
-/*****************************************************************
-Gets the number of records in the heap. */
+ const rec_t* rec); /*!< in: the physical record */
+/*************************************************************//**
+Gets the number of records in the heap.
+@return number of user records */
UNIV_INLINE
ulint
page_dir_get_n_heap(
/*================*/
- /* out: number of user records */
- const page_t* page); /* in: index page */
-/*****************************************************************
+ const page_t* page); /*!< in: index page */
+/*************************************************************//**
Sets the number of records in the heap. */
UNIV_INLINE
void
page_dir_set_n_heap(
/*================*/
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL.
Note that the size of the dense page directory
in the compressed page trailer is
n_heap * PAGE_ZIP_DIR_SLOT_SIZE. */
- ulint n_heap);/* in: number of records */
-/*****************************************************************
-Gets the number of dir slots in directory. */
+ ulint n_heap);/*!< in: number of records */
+/*************************************************************//**
+Gets the number of dir slots in directory.
+@return number of slots */
UNIV_INLINE
ulint
page_dir_get_n_slots(
/*=================*/
- /* out: number of slots */
- const page_t* page); /* in: index page */
-/*****************************************************************
+ const page_t* page); /*!< in: index page */
+/*************************************************************//**
Sets the number of dir slots in directory. */
UNIV_INLINE
void
page_dir_set_n_slots(
/*=================*/
- page_t* page, /* in/out: page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ page_t* page, /*!< in/out: page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
- ulint n_slots);/* in: number of slots */
+ ulint n_slots);/*!< in: number of slots */
#ifdef UNIV_DEBUG
-/*****************************************************************
-Gets pointer to nth directory slot. */
+/*************************************************************//**
+Gets pointer to nth directory slot.
+@return pointer to dir slot */
UNIV_INLINE
page_dir_slot_t*
page_dir_get_nth_slot(
/*==================*/
- /* out: pointer to dir slot */
- const page_t* page, /* in: index page */
- ulint n); /* in: position */
+ const page_t* page, /*!< in: index page */
+ ulint n); /*!< in: position */
#else /* UNIV_DEBUG */
# define page_dir_get_nth_slot(page, n) \
((page) + UNIV_PAGE_SIZE - PAGE_DIR \
- (n + 1) * PAGE_DIR_SLOT_SIZE)
#endif /* UNIV_DEBUG */
-/******************************************************************
-Used to check the consistency of a record on a page. */
+/**************************************************************//**
+Used to check the consistency of a record on a page.
+@return TRUE if succeed */
UNIV_INLINE
ibool
page_rec_check(
/*===========*/
- /* out: TRUE if succeed */
- const rec_t* rec); /* in: record */
-/*******************************************************************
-Gets the record pointed to by a directory slot. */
+ const rec_t* rec); /*!< in: record */
+/***************************************************************//**
+Gets the record pointed to by a directory slot.
+@return pointer to record */
UNIV_INLINE
const rec_t*
page_dir_slot_get_rec(
/*==================*/
- /* out: pointer to record */
- const page_dir_slot_t* slot); /* in: directory slot */
-/*******************************************************************
+ const page_dir_slot_t* slot); /*!< in: directory slot */
+/***************************************************************//**
This is used to set the record offset in a directory slot. */
UNIV_INLINE
void
page_dir_slot_set_rec(
/*==================*/
- page_dir_slot_t* slot, /* in: directory slot */
- rec_t* rec); /* in: record on the page */
-/*******************************************************************
-Gets the number of records owned by a directory slot. */
+ page_dir_slot_t* slot, /*!< in: directory slot */
+ rec_t* rec); /*!< in: record on the page */
+/***************************************************************//**
+Gets the number of records owned by a directory slot.
+@return number of records */
UNIV_INLINE
ulint
page_dir_slot_get_n_owned(
/*======================*/
- /* out: number of records */
- const page_dir_slot_t* slot); /* in: page directory slot */
-/*******************************************************************
+ const page_dir_slot_t* slot); /*!< in: page directory slot */
+/***************************************************************//**
This is used to set the owned records field of a directory slot. */
UNIV_INLINE
void
page_dir_slot_set_n_owned(
/*======================*/
- page_dir_slot_t*slot, /* in/out: directory slot */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint n); /* in: number of records owned by the slot */
-/****************************************************************
+ page_dir_slot_t*slot, /*!< in/out: directory slot */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint n); /*!< in: number of records owned by the slot */
+/************************************************************//**
Calculates the space reserved for directory slots of a given
number of records. The exact value is a fraction number
n * PAGE_DIR_SLOT_SIZE / PAGE_DIR_SLOT_MIN_N_OWNED, and it is
@@ -452,167 +455,167 @@ UNIV_INLINE
ulint
page_dir_calc_reserved_space(
/*=========================*/
- ulint n_recs); /* in: number of records */
-/*******************************************************************
-Looks for the directory slot which owns the given record. */
+ ulint n_recs); /*!< in: number of records */
+/***************************************************************//**
+Looks for the directory slot which owns the given record.
+@return the directory slot number */
UNIV_INTERN
ulint
page_dir_find_owner_slot(
/*=====================*/
- /* out: the directory slot number */
- const rec_t* rec); /* in: the physical record */
-/****************************************************************
-Determine whether the page is in new-style compact format. */
+ const rec_t* rec); /*!< in: the physical record */
+/************************************************************//**
+Determine whether the page is in new-style compact format.
+@return nonzero if the page is in compact format, zero if it is in
+old-style format */
UNIV_INLINE
ulint
page_is_comp(
/*=========*/
- /* out: nonzero if the page is in compact
- format, zero if it is in old-style format */
- const page_t* page); /* in: index page */
-/****************************************************************
-TRUE if the record is on a page in compact format. */
+ const page_t* page); /*!< in: index page */
+/************************************************************//**
+TRUE if the record is on a page in compact format.
+@return nonzero if in compact format */
UNIV_INLINE
ulint
page_rec_is_comp(
/*=============*/
- /* out: nonzero if in compact format */
- const rec_t* rec); /* in: record */
-/*******************************************************************
-Returns the heap number of a record. */
+ const rec_t* rec); /*!< in: record */
+/***************************************************************//**
+Returns the heap number of a record.
+@return heap number */
UNIV_INLINE
ulint
page_rec_get_heap_no(
/*=================*/
- /* out: heap number */
- const rec_t* rec); /* in: the physical record */
-/****************************************************************
-Determine whether the page is a B-tree leaf. */
+ const rec_t* rec); /*!< in: the physical record */
+/************************************************************//**
+Determine whether the page is a B-tree leaf.
+@return TRUE if the page is a B-tree leaf */
UNIV_INLINE
ibool
page_is_leaf(
/*=========*/
- /* out: TRUE if the page is a B-tree leaf */
- const page_t* page) /* in: page */
+ const page_t* page) /*!< in: page */
__attribute__((nonnull, pure));
-/****************************************************************
-Gets the pointer to the next record on the page. */
+/************************************************************//**
+Gets the pointer to the next record on the page.
+@return pointer to next record */
UNIV_INLINE
const rec_t*
page_rec_get_next_low(
/*==================*/
- /* out: pointer to next record */
- const rec_t* rec, /* in: pointer to record */
- ulint comp); /* in: nonzero=compact page layout */
-/****************************************************************
-Gets the pointer to the next record on the page. */
+ const rec_t* rec, /*!< in: pointer to record */
+ ulint comp); /*!< in: nonzero=compact page layout */
+/************************************************************//**
+Gets the pointer to the next record on the page.
+@return pointer to next record */
UNIV_INLINE
rec_t*
page_rec_get_next(
/*==============*/
- /* out: pointer to next record */
- rec_t* rec); /* in: pointer to record */
-/****************************************************************
-Gets the pointer to the next record on the page. */
+ rec_t* rec); /*!< in: pointer to record */
+/************************************************************//**
+Gets the pointer to the next record on the page.
+@return pointer to next record */
UNIV_INLINE
const rec_t*
page_rec_get_next_const(
/*====================*/
- /* out: pointer to next record */
- const rec_t* rec); /* in: pointer to record */
-/****************************************************************
+ const rec_t* rec); /*!< in: pointer to record */
+/************************************************************//**
Sets the pointer to the next record on the page. */
UNIV_INLINE
void
page_rec_set_next(
/*==============*/
- rec_t* rec, /* in: pointer to record,
+ rec_t* rec, /*!< in: pointer to record,
must not be page supremum */
- rec_t* next); /* in: pointer to next record,
+ rec_t* next); /*!< in: pointer to next record,
must not be page infimum */
-/****************************************************************
-Gets the pointer to the previous record. */
+/************************************************************//**
+Gets the pointer to the previous record.
+@return pointer to previous record */
UNIV_INLINE
const rec_t*
page_rec_get_prev_const(
/*====================*/
- /* out: pointer to previous record */
- const rec_t* rec); /* in: pointer to record, must not be page
+ const rec_t* rec); /*!< in: pointer to record, must not be page
infimum */
-/****************************************************************
-Gets the pointer to the previous record. */
+/************************************************************//**
+Gets the pointer to the previous record.
+@return pointer to previous record */
UNIV_INLINE
rec_t*
page_rec_get_prev(
/*==============*/
- /* out: pointer to previous record */
- rec_t* rec); /* in: pointer to record,
+ rec_t* rec); /*!< in: pointer to record,
must not be page infimum */
-/****************************************************************
-TRUE if the record is a user record on the page. */
+/************************************************************//**
+TRUE if the record is a user record on the page.
+@return TRUE if a user record */
UNIV_INLINE
ibool
page_rec_is_user_rec_low(
/*=====================*/
- /* out: TRUE if a user record */
- ulint offset) /* in: record offset on page */
+ ulint offset) /*!< in: record offset on page */
__attribute__((const));
-/****************************************************************
-TRUE if the record is the supremum record on a page. */
+/************************************************************//**
+TRUE if the record is the supremum record on a page.
+@return TRUE if the supremum record */
UNIV_INLINE
ibool
page_rec_is_supremum_low(
/*=====================*/
- /* out: TRUE if the supremum record */
- ulint offset) /* in: record offset on page */
+ ulint offset) /*!< in: record offset on page */
__attribute__((const));
-/****************************************************************
-TRUE if the record is the infimum record on a page. */
+/************************************************************//**
+TRUE if the record is the infimum record on a page.
+@return TRUE if the infimum record */
UNIV_INLINE
ibool
page_rec_is_infimum_low(
/*====================*/
- /* out: TRUE if the infimum record */
- ulint offset) /* in: record offset on page */
+ ulint offset) /*!< in: record offset on page */
__attribute__((const));
-/****************************************************************
-TRUE if the record is a user record on the page. */
+/************************************************************//**
+TRUE if the record is a user record on the page.
+@return TRUE if a user record */
UNIV_INLINE
ibool
page_rec_is_user_rec(
/*=================*/
- /* out: TRUE if a user record */
- const rec_t* rec) /* in: record */
+ const rec_t* rec) /*!< in: record */
__attribute__((const));
-/****************************************************************
-TRUE if the record is the supremum record on a page. */
+/************************************************************//**
+TRUE if the record is the supremum record on a page.
+@return TRUE if the supremum record */
UNIV_INLINE
ibool
page_rec_is_supremum(
/*=================*/
- /* out: TRUE if the supremum record */
- const rec_t* rec) /* in: record */
+ const rec_t* rec) /*!< in: record */
__attribute__((const));
-/****************************************************************
-TRUE if the record is the infimum record on a page. */
+/************************************************************//**
+TRUE if the record is the infimum record on a page.
+@return TRUE if the infimum record */
UNIV_INLINE
ibool
page_rec_is_infimum(
/*================*/
- /* out: TRUE if the infimum record */
- const rec_t* rec) /* in: record */
+ const rec_t* rec) /*!< in: record */
__attribute__((const));
-/*******************************************************************
-Looks for the record which owns the given record. */
+/***************************************************************//**
+Looks for the record which owns the given record.
+@return the owner record */
UNIV_INLINE
rec_t*
page_rec_find_owner_rec(
/*====================*/
- /* out: the owner record */
- rec_t* rec); /* in: the physical record */
-/***************************************************************************
+ rec_t* rec); /*!< in: the physical record */
+/***********************************************************************//**
This is a low-level operation which is used in a database index creation
to update the page number of a created B-tree to a data dictionary
record. */
@@ -620,245 +623,235 @@ UNIV_INTERN
void
page_rec_write_index_page_no(
/*=========================*/
- rec_t* rec, /* in: record to update */
- ulint i, /* in: index of the field to update */
- ulint page_no,/* in: value to write */
- mtr_t* mtr); /* in: mtr */
-/****************************************************************
+ rec_t* rec, /*!< in: record to update */
+ ulint i, /*!< in: index of the field to update */
+ ulint page_no,/*!< in: value to write */
+ mtr_t* mtr); /*!< in: mtr */
+/************************************************************//**
Returns the maximum combined size of records which can be inserted on top
-of record heap. */
+of record heap.
+@return maximum combined size for inserted records */
UNIV_INLINE
ulint
page_get_max_insert_size(
/*=====================*/
- /* out: maximum combined size for
- inserted records */
- const page_t* page, /* in: index page */
- ulint n_recs);/* in: number of records */
-/****************************************************************
+ const page_t* page, /*!< in: index page */
+ ulint n_recs);/*!< in: number of records */
+/************************************************************//**
Returns the maximum combined size of records which can be inserted on top
-of record heap if page is first reorganized. */
+of record heap if page is first reorganized.
+@return maximum combined size for inserted records */
UNIV_INLINE
ulint
page_get_max_insert_size_after_reorganize(
/*======================================*/
- /* out: maximum combined size for
- inserted records */
- const page_t* page, /* in: index page */
- ulint n_recs);/* in: number of records */
-/*****************************************************************
-Calculates free space if a page is emptied. */
+ const page_t* page, /*!< in: index page */
+ ulint n_recs);/*!< in: number of records */
+/*************************************************************//**
+Calculates free space if a page is emptied.
+@return free space */
UNIV_INLINE
ulint
page_get_free_space_of_empty(
/*=========================*/
- /* out: free space */
- ulint comp) /* in: nonzero=compact page format */
+ ulint comp) /*!< in: nonzero=compact page format */
__attribute__((const));
-/**************************************************************
+/**********************************************************//**
Returns the base extra size of a physical record. This is the
-size of the fixed header, independent of the record size. */
+size of the fixed header, independent of the record size.
+@return REC_N_NEW_EXTRA_BYTES or REC_N_OLD_EXTRA_BYTES */
UNIV_INLINE
ulint
page_rec_get_base_extra_size(
/*=========================*/
- /* out: REC_N_NEW_EXTRA_BYTES
- or REC_N_OLD_EXTRA_BYTES */
- const rec_t* rec); /* in: physical record */
-/****************************************************************
+ const rec_t* rec); /*!< in: physical record */
+/************************************************************//**
Returns the sum of the sizes of the records in the record list
-excluding the infimum and supremum records. */
+excluding the infimum and supremum records.
+@return data in bytes */
UNIV_INLINE
ulint
page_get_data_size(
/*===============*/
- /* out: data in bytes */
- const page_t* page); /* in: index page */
-/****************************************************************
+ const page_t* page); /*!< in: index page */
+/************************************************************//**
Allocates a block of memory from the head of the free list
of an index page. */
UNIV_INLINE
void
page_mem_alloc_free(
/*================*/
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page with enough
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
space available for inserting the record,
or NULL */
- rec_t* next_rec,/* in: pointer to the new head of the
+ rec_t* next_rec,/*!< in: pointer to the new head of the
free record list */
- ulint need); /* in: number of bytes allocated */
-/****************************************************************
-Allocates a block of memory from the heap of an index page. */
+ ulint need); /*!< in: number of bytes allocated */
+/************************************************************//**
+Allocates a block of memory from the heap of an index page.
+@return pointer to start of allocated buffer, or NULL if allocation fails */
UNIV_INTERN
byte*
page_mem_alloc_heap(
/*================*/
- /* out: pointer to start of allocated
- buffer, or NULL if allocation fails */
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page with enough
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
space available for inserting the record,
or NULL */
- ulint need, /* in: total number of bytes needed */
- ulint* heap_no);/* out: this contains the heap number
+ ulint need, /*!< in: total number of bytes needed */
+ ulint* heap_no);/*!< out: this contains the heap number
of the allocated record
if allocation succeeds */
-/****************************************************************
+/************************************************************//**
Puts a record to free list. */
UNIV_INLINE
void
page_mem_free(
/*==========*/
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- rec_t* rec, /* in: pointer to the (origin of) record */
- dict_index_t* index, /* in: index of rec */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/**************************************************************
-Create an uncompressed B-tree index page. */
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ rec_t* rec, /*!< in: pointer to the (origin of) record */
+ dict_index_t* index, /*!< in: index of rec */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/**********************************************************//**
+Create an uncompressed B-tree index page.
+@return pointer to the page */
UNIV_INTERN
page_t*
page_create(
/*========*/
- /* out: pointer to the page */
- buf_block_t* block, /* in: a buffer block where the
+ buf_block_t* block, /*!< in: a buffer block where the
page is created */
- mtr_t* mtr, /* in: mini-transaction handle */
- ulint comp); /* in: nonzero=compact page format */
-/**************************************************************
-Create a compressed B-tree index page. */
+ mtr_t* mtr, /*!< in: mini-transaction handle */
+ ulint comp); /*!< in: nonzero=compact page format */
+/**********************************************************//**
+Create a compressed B-tree index page.
+@return pointer to the page */
UNIV_INTERN
page_t*
page_create_zip(
/*============*/
- /* out: pointer to the page */
- buf_block_t* block, /* in/out: a buffer frame where the
+ buf_block_t* block, /*!< in/out: a buffer frame where the
page is created */
- dict_index_t* index, /* in: the index of the page */
- ulint level, /* in: the B-tree level of the page */
- mtr_t* mtr); /* in: mini-transaction handle */
+ dict_index_t* index, /*!< in: the index of the page */
+ ulint level, /*!< in: the B-tree level of the page */
+ mtr_t* mtr); /*!< in: mini-transaction handle */
-/*****************************************************************
+/*************************************************************//**
Differs from page_copy_rec_list_end, because this function does not
touch the lock table and max trx id on page or compress the page. */
UNIV_INTERN
void
page_copy_rec_list_end_no_locks(
/*============================*/
- buf_block_t* new_block, /* in: index page to copy to */
- buf_block_t* block, /* in: index page of rec */
- rec_t* rec, /* in: record on page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr); /* in: mtr */
-/*****************************************************************
+ buf_block_t* new_block, /*!< in: index page to copy to */
+ buf_block_t* block, /*!< in: index page of rec */
+ rec_t* rec, /*!< in: record on page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr); /*!< in: mtr */
+/*************************************************************//**
Copies records from page to new_page, from the given record onward,
including that record. Infimum and supremum records are not copied.
-The records are copied to the start of the record list on new_page. */
+The records are copied to the start of the record list on new_page.
+@return pointer to the original successor of the infimum record on
+new_page, or NULL on zip overflow (new_block will be decompressed) */
UNIV_INTERN
rec_t*
page_copy_rec_list_end(
/*===================*/
- /* out: pointer to the original
- successor of the infimum record
- on new_page, or NULL on zip overflow
- (new_block will be decompressed) */
- buf_block_t* new_block, /* in/out: index page to copy to */
- buf_block_t* block, /* in: index page containing rec */
- rec_t* rec, /* in: record on page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page to copy to */
+ buf_block_t* block, /*!< in: index page containing rec */
+ rec_t* rec, /*!< in: record on page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
__attribute__((nonnull));
-/*****************************************************************
+/*************************************************************//**
Copies records from page to new_page, up to the given record, NOT
including that record. Infimum and supremum records are not copied.
-The records are copied to the end of the record list on new_page. */
+The records are copied to the end of the record list on new_page.
+@return pointer to the original predecessor of the supremum record on
+new_page, or NULL on zip overflow (new_block will be decompressed) */
UNIV_INTERN
rec_t*
page_copy_rec_list_start(
/*=====================*/
- /* out: pointer to the original
- predecessor of the supremum record
- on new_page, or NULL on zip overflow
- (new_block will be decompressed) */
- buf_block_t* new_block, /* in/out: index page to copy to */
- buf_block_t* block, /* in: index page containing rec */
- rec_t* rec, /* in: record on page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page to copy to */
+ buf_block_t* block, /*!< in: index page containing rec */
+ rec_t* rec, /*!< in: record on page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
__attribute__((nonnull));
-/*****************************************************************
+/*************************************************************//**
Deletes records from a page from a given record onward, including that record.
The infimum and supremum records are not deleted. */
UNIV_INTERN
void
page_delete_rec_list_end(
/*=====================*/
- rec_t* rec, /* in: pointer to record on page */
- buf_block_t* block, /* in: buffer block of the page */
- dict_index_t* index, /* in: record descriptor */
- ulint n_recs, /* in: number of records to delete,
+ rec_t* rec, /*!< in: pointer to record on page */
+ buf_block_t* block, /*!< in: buffer block of the page */
+ dict_index_t* index, /*!< in: record descriptor */
+ ulint n_recs, /*!< in: number of records to delete,
or ULINT_UNDEFINED if not known */
- ulint size, /* in: the sum of the sizes of the
+ ulint size, /*!< in: the sum of the sizes of the
records in the end of the chain to
delete, or ULINT_UNDEFINED if not known */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
__attribute__((nonnull));
-/*****************************************************************
+/*************************************************************//**
Deletes records from page, up to the given record, NOT including
that record. Infimum and supremum records are not deleted. */
UNIV_INTERN
void
page_delete_rec_list_start(
/*=======================*/
- rec_t* rec, /* in: record on page */
- buf_block_t* block, /* in: buffer block of the page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ rec_t* rec, /*!< in: record on page */
+ buf_block_t* block, /*!< in: buffer block of the page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
__attribute__((nonnull));
-/*****************************************************************
+/*************************************************************//**
Moves record list end to another page. Moved records include
-split_rec. */
+split_rec.
+@return TRUE on success; FALSE on compression failure (new_block will
+be decompressed) */
UNIV_INTERN
ibool
page_move_rec_list_end(
/*===================*/
- /* out: TRUE on success; FALSE on
- compression failure
- (new_block will be decompressed) */
- buf_block_t* new_block, /* in/out: index page where to move */
- buf_block_t* block, /* in: index page from where to move */
- rec_t* split_rec, /* in: first record to move */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page where to move */
+ buf_block_t* block, /*!< in: index page from where to move */
+ rec_t* split_rec, /*!< in: first record to move */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
__attribute__((nonnull(1, 2, 4, 5)));
-/*****************************************************************
+/*************************************************************//**
Moves record list start to another page. Moved records do not include
-split_rec. */
+split_rec.
+@return TRUE on success; FALSE on compression failure */
UNIV_INTERN
ibool
page_move_rec_list_start(
/*=====================*/
- /* out: TRUE on success; FALSE on
- compression failure */
- buf_block_t* new_block, /* in/out: index page where to move */
- buf_block_t* block, /* in/out: page containing split_rec */
- rec_t* split_rec, /* in: first record not to move */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page where to move */
+ buf_block_t* block, /*!< in/out: page containing split_rec */
+ rec_t* split_rec, /*!< in: first record not to move */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
__attribute__((nonnull(1, 2, 4, 5)));
-/********************************************************************
+/****************************************************************//**
Splits a directory slot which owns too many records. */
UNIV_INTERN
void
page_dir_split_slot(
/*================*/
- page_t* page, /* in: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ page_t* page, /*!< in: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be written, or NULL */
- ulint slot_no)/* in: the directory slot */
+ ulint slot_no)/*!< in: the directory slot */
__attribute__((nonnull(1)));
-/*****************************************************************
+/*************************************************************//**
Tries to balance the given directory slot with too few records
with the upper neighbor, so that there are at least the minimum number
of records owned by the slot; this may result in the merging of
@@ -867,98 +860,98 @@ UNIV_INTERN
void
page_dir_balance_slot(
/*==================*/
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint slot_no)/* in: the directory slot */
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint slot_no)/*!< in: the directory slot */
__attribute__((nonnull(1)));
-/**************************************************************
-Parses a log record of a record list end or start deletion. */
+/**********************************************************//**
+Parses a log record of a record list end or start deletion.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_parse_delete_rec_list(
/*=======================*/
- /* out: end of log record or NULL */
- byte type, /* in: MLOG_LIST_END_DELETE,
+ byte type, /*!< in: MLOG_LIST_END_DELETE,
MLOG_LIST_START_DELETE,
MLOG_COMP_LIST_END_DELETE or
MLOG_COMP_LIST_START_DELETE */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in/out: buffer block or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr); /* in: mtr or NULL */
-/***************************************************************
-Parses a redo log record of creating a page. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in/out: buffer block or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+/***********************************************************//**
+Parses a redo log record of creating a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_parse_create(
/*==============*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- ulint comp, /* in: nonzero=compact page format */
- buf_block_t* block, /* in: block or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
-/****************************************************************
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ ulint comp, /*!< in: nonzero=compact page format */
+ buf_block_t* block, /*!< in: block or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+/************************************************************//**
Prints record contents including the data relevant only in
the index page context. */
UNIV_INTERN
void
page_rec_print(
/*===========*/
- const rec_t* rec, /* in: physical record */
- const ulint* offsets);/* in: record descriptor */
-/*******************************************************************
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets);/*!< in: record descriptor */
+/***************************************************************//**
This is used to print the contents of the directory for
debugging purposes. */
UNIV_INTERN
void
page_dir_print(
/*===========*/
- page_t* page, /* in: index page */
- ulint pr_n); /* in: print n first and n last entries */
-/*******************************************************************
+ page_t* page, /*!< in: index page */
+ ulint pr_n); /*!< in: print n first and n last entries */
+/***************************************************************//**
This is used to print the contents of the page record list for
debugging purposes. */
UNIV_INTERN
void
page_print_list(
/*============*/
- buf_block_t* block, /* in: index page */
- dict_index_t* index, /* in: dictionary index of the page */
- ulint pr_n); /* in: print n first and n last entries */
-/*******************************************************************
+ buf_block_t* block, /*!< in: index page */
+ dict_index_t* index, /*!< in: dictionary index of the page */
+ ulint pr_n); /*!< in: print n first and n last entries */
+/***************************************************************//**
Prints the info in a page header. */
UNIV_INTERN
void
page_header_print(
/*==============*/
- const page_t* page);
-/*******************************************************************
+ const page_t* page); /*!< in: index page */
+/***************************************************************//**
This is used to print the contents of the page for
debugging purposes. */
UNIV_INTERN
void
page_print(
/*=======*/
- buf_block_t* block, /* in: index page */
- dict_index_t* index, /* in: dictionary index of the page */
- ulint dn, /* in: print dn first and last entries
+ buf_block_t* block, /*!< in: index page */
+ dict_index_t* index, /*!< in: dictionary index of the page */
+ ulint dn, /*!< in: print dn first and last entries
in directory */
- ulint rn); /* in: print rn first and last records
+ ulint rn); /*!< in: print rn first and last records
in directory */
-/*******************************************************************
+/***************************************************************//**
The following is used to validate a record on a page. This function
differs from rec_validate as it can also check the n_owned field and
-the heap_no field. */
+the heap_no field.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_rec_validate(
/*==============*/
- /* out: TRUE if ok */
- rec_t* rec, /* in: physical record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/*******************************************************************
+ rec_t* rec, /*!< in: physical record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/***************************************************************//**
Checks that the first directory slot points to the infimum record and
the last to the supremum. This function is intended to track if the
bug fixed in 4.0.14 has caused corruption to users' databases. */
@@ -966,46 +959,46 @@ UNIV_INTERN
void
page_check_dir(
/*===========*/
- const page_t* page); /* in: index page */
-/*******************************************************************
+ const page_t* page); /*!< in: index page */
+/***************************************************************//**
This function checks the consistency of an index page when we do not
know the index. This is also resilient so that this should never crash
-even if the page is total garbage. */
+even if the page is total garbage.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_simple_validate_old(
/*=====================*/
- /* out: TRUE if ok */
- page_t* page); /* in: old-style index page */
-/*******************************************************************
+ page_t* page); /*!< in: old-style index page */
+/***************************************************************//**
This function checks the consistency of an index page when we do not
know the index. This is also resilient so that this should never crash
-even if the page is total garbage. */
+even if the page is total garbage.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_simple_validate_new(
/*=====================*/
- /* out: TRUE if ok */
- page_t* block); /* in: new-style index page */
-/*******************************************************************
-This function checks the consistency of an index page. */
+ page_t* block); /*!< in: new-style index page */
+/***************************************************************//**
+This function checks the consistency of an index page.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_validate(
/*==========*/
- /* out: TRUE if ok */
- page_t* page, /* in: index page */
- dict_index_t* index); /* in: data dictionary index containing
+ page_t* page, /*!< in: index page */
+ dict_index_t* index); /*!< in: data dictionary index containing
the page record type definition */
-/*******************************************************************
-Looks in the page record list for a record with the given heap number. */
+/***************************************************************//**
+Looks in the page record list for a record with the given heap number.
+@return record, NULL if not found */
const rec_t*
page_find_rec_with_heap_no(
/*=======================*/
- /* out: record, NULL if not found */
- const page_t* page, /* in: index page */
- ulint heap_no);/* in: heap number */
+ const page_t* page, /*!< in: index page */
+ ulint heap_no);/*!< in: heap number */
#ifdef UNIV_MATERIALIZE
#undef UNIV_INLINE
diff --git a/storage/xtradb/include/page0page.ic b/storage/xtradb/include/page0page.ic
index df0f6f8b360..318ec1cc1f2 100644
--- a/storage/xtradb/include/page0page.ic
+++ b/storage/xtradb/include/page0page.ic
@@ -16,14 +16,20 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/page0page.ic
Index page routines
Created 2/2/1994 Heikki Tuuri
*******************************************************/
#include "mach0data.h"
-#include "rem0cmp.h"
+#ifdef UNIV_DEBUG
+# include "log0recv.h"
+#endif /* !UNIV_DEBUG */
+#ifndef UNIV_HOTBACKUP
+# include "rem0cmp.h"
+#endif /* !UNIV_HOTBACKUP */
#include "mtr0log.h"
#include "page0zip.h"
@@ -32,70 +38,80 @@ Created 2/2/1994 Heikki Tuuri
#define UNIV_INLINE
#endif
-/****************************************************************
-Gets the start of a page. */
+/************************************************************//**
+Gets the start of a page.
+@return start of the page */
UNIV_INLINE
page_t*
page_align(
/*=======*/
- /* out: start of the page */
- const void* ptr) /* in: pointer to page frame */
+ const void* ptr) /*!< in: pointer to page frame */
{
return((page_t*) ut_align_down(ptr, UNIV_PAGE_SIZE));
}
-/****************************************************************
-Gets the offset within a page. */
+/************************************************************//**
+Gets the offset within a page.
+@return offset from the start of the page */
UNIV_INLINE
ulint
page_offset(
/*========*/
- /* out: offset from the start of the page */
- const void* ptr) /* in: pointer to page frame */
+ const void* ptr) /*!< in: pointer to page frame */
{
return(ut_align_offset(ptr, UNIV_PAGE_SIZE));
}
-/*****************************************************************
+/*************************************************************//**
Returns the max trx id field value. */
UNIV_INLINE
-dulint
+trx_id_t
page_get_max_trx_id(
/*================*/
- const page_t* page) /* in: page */
+ const page_t* page) /*!< in: page */
{
ut_ad(page);
return(mach_read_from_8(page + PAGE_HEADER + PAGE_MAX_TRX_ID));
}
-/*****************************************************************
+/*************************************************************//**
Sets the max trx id field value if trx_id is bigger than the previous
value. */
UNIV_INLINE
void
page_update_max_trx_id(
/*===================*/
- buf_block_t* block, /* in/out: page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ buf_block_t* block, /*!< in/out: page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
- dulint trx_id) /* in: transaction id */
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
{
ut_ad(block);
+ ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
+ /* During crash recovery, this function may be called on
+ something else than a leaf page of a secondary index or the
+ insert buffer index tree (dict_index_is_sec_or_ibuf() returns
+ TRUE for the dummy indexes constructed during redo log
+ application). In that case, PAGE_MAX_TRX_ID is unused,
+ and trx_id is usually zero. */
+ ut_ad(!ut_dulint_is_zero(trx_id) || recv_recovery_is_on());
+ ut_ad(page_is_leaf(buf_block_get_frame(block)));
if (ut_dulint_cmp(page_get_max_trx_id(buf_block_get_frame(block)),
trx_id) < 0) {
- page_set_max_trx_id(block, page_zip, trx_id);
+ page_set_max_trx_id(block, page_zip, trx_id, mtr);
}
}
-/*****************************************************************
+/*************************************************************//**
Reads the given header field. */
UNIV_INLINE
ulint
page_header_get_field(
/*==================*/
- const page_t* page, /* in: page */
- ulint field) /* in: PAGE_LEVEL, ... */
+ const page_t* page, /*!< in: page */
+ ulint field) /*!< in: PAGE_LEVEL, ... */
{
ut_ad(page);
ut_ad(field <= PAGE_INDEX_ID);
@@ -103,17 +119,17 @@ page_header_get_field(
return(mach_read_from_2(page + PAGE_HEADER + field));
}
-/*****************************************************************
+/*************************************************************//**
Sets the given header field. */
UNIV_INLINE
void
page_header_set_field(
/*==================*/
- page_t* page, /* in/out: page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ page_t* page, /*!< in/out: page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
- ulint field, /* in: PAGE_N_DIR_SLOTS, ... */
- ulint val) /* in: value */
+ ulint field, /*!< in: PAGE_N_DIR_SLOTS, ... */
+ ulint val) /*!< in: value */
{
ut_ad(page);
ut_ad(field <= PAGE_N_RECS);
@@ -127,16 +143,15 @@ page_header_set_field(
}
}
-/*****************************************************************
-Returns the offset stored in the given header field. */
+/*************************************************************//**
+Returns the offset stored in the given header field.
+@return offset from the start of the page, or 0 */
UNIV_INLINE
ulint
page_header_get_offs(
/*=================*/
- /* out: offset from the start of the page,
- or 0 */
- const page_t* page, /* in: page */
- ulint field) /* in: PAGE_FREE, ... */
+ const page_t* page, /*!< in: page */
+ ulint field) /*!< in: PAGE_FREE, ... */
{
ulint offs;
@@ -152,17 +167,17 @@ page_header_get_offs(
return(offs);
}
-/*****************************************************************
+/*************************************************************//**
Sets the pointer stored in the given header field. */
UNIV_INLINE
void
page_header_set_ptr(
/*================*/
- page_t* page, /* in: page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ page_t* page, /*!< in: page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
- ulint field, /* in: PAGE_FREE, ... */
- const byte* ptr) /* in: pointer or NULL*/
+ ulint field, /*!< in: PAGE_FREE, ... */
+ const byte* ptr) /*!< in: pointer or NULL*/
{
ulint offs;
@@ -182,17 +197,18 @@ page_header_set_ptr(
page_header_set_field(page, page_zip, field, offs);
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Resets the last insert info field in the page header. Writes to mlog
about this operation. */
UNIV_INLINE
void
page_header_reset_last_insert(
/*==========================*/
- page_t* page, /* in/out: page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ page_t* page, /*!< in/out: page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(page && mtr);
@@ -206,41 +222,42 @@ page_header_reset_last_insert(
MLOG_2BYTES, mtr);
}
}
+#endif /* !UNIV_HOTBACKUP */
-/****************************************************************
-Determine whether the page is in new-style compact format. */
+/************************************************************//**
+Determine whether the page is in new-style compact format.
+@return nonzero if the page is in compact format, zero if it is in
+old-style format */
UNIV_INLINE
ulint
page_is_comp(
/*=========*/
- /* out: nonzero if the page is in compact
- format, zero if it is in old-style format */
- const page_t* page) /* in: index page */
+ const page_t* page) /*!< in: index page */
{
return(UNIV_EXPECT(page_header_get_field(page, PAGE_N_HEAP) & 0x8000,
0x8000));
}
-/****************************************************************
-TRUE if the record is on a page in compact format. */
+/************************************************************//**
+TRUE if the record is on a page in compact format.
+@return nonzero if in compact format */
UNIV_INLINE
ulint
page_rec_is_comp(
/*=============*/
- /* out: nonzero if in compact format */
- const rec_t* rec) /* in: record */
+ const rec_t* rec) /*!< in: record */
{
return(page_is_comp(page_align(rec)));
}
-/*******************************************************************
-Returns the heap number of a record. */
+/***************************************************************//**
+Returns the heap number of a record.
+@return heap number */
UNIV_INLINE
ulint
page_rec_get_heap_no(
/*=================*/
- /* out: heap number */
- const rec_t* rec) /* in: the physical record */
+ const rec_t* rec) /*!< in: the physical record */
{
if (page_rec_is_comp(rec)) {
return(rec_get_heap_no_new(rec));
@@ -249,27 +266,26 @@ page_rec_get_heap_no(
}
}
-/****************************************************************
-Determine whether the page is a B-tree leaf. */
+/************************************************************//**
+Determine whether the page is a B-tree leaf.
+@return TRUE if the page is a B-tree leaf */
UNIV_INLINE
ibool
page_is_leaf(
/*=========*/
- /* out: TRUE if the page is a B-tree leaf */
- const page_t* page) /* in: page */
+ const page_t* page) /*!< in: page */
{
return(!*(const uint16*) (page + (PAGE_HEADER + PAGE_LEVEL)));
}
-/****************************************************************
-Gets the offset of the first record on the page. */
+/************************************************************//**
+Gets the offset of the first record on the page.
+@return offset of the first record in record list, relative from page */
UNIV_INLINE
ulint
page_get_infimum_offset(
/*====================*/
- /* out: offset of the first record
- in record list, relative from page */
- const page_t* page) /* in: page which must have record(s) */
+ const page_t* page) /*!< in: page which must have record(s) */
{
ut_ad(page);
ut_ad(!page_offset(page));
@@ -281,15 +297,14 @@ page_get_infimum_offset(
}
}
-/****************************************************************
-Gets the offset of the last record on the page. */
+/************************************************************//**
+Gets the offset of the last record on the page.
+@return offset of the last record in record list, relative from page */
UNIV_INLINE
ulint
page_get_supremum_offset(
/*=====================*/
- /* out: offset of the last record in
- record list, relative from page */
- const page_t* page) /* in: page which must have record(s) */
+ const page_t* page) /*!< in: page which must have record(s) */
{
ut_ad(page);
ut_ad(!page_offset(page));
@@ -301,14 +316,14 @@ page_get_supremum_offset(
}
}
-/****************************************************************
-TRUE if the record is a user record on the page. */
+/************************************************************//**
+TRUE if the record is a user record on the page.
+@return TRUE if a user record */
UNIV_INLINE
ibool
page_rec_is_user_rec_low(
/*=====================*/
- /* out: TRUE if a user record */
- ulint offset) /* in: record offset on page */
+ ulint offset) /*!< in: record offset on page */
{
ut_ad(offset >= PAGE_NEW_INFIMUM);
#if PAGE_OLD_INFIMUM < PAGE_NEW_INFIMUM
@@ -337,14 +352,14 @@ page_rec_is_user_rec_low(
&& UNIV_LIKELY(offset != PAGE_OLD_SUPREMUM));
}
-/****************************************************************
-TRUE if the record is the supremum record on a page. */
+/************************************************************//**
+TRUE if the record is the supremum record on a page.
+@return TRUE if the supremum record */
UNIV_INLINE
ibool
page_rec_is_supremum_low(
/*=====================*/
- /* out: TRUE if the supremum record */
- ulint offset) /* in: record offset on page */
+ ulint offset) /*!< in: record offset on page */
{
ut_ad(offset >= PAGE_NEW_INFIMUM);
ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
@@ -353,14 +368,14 @@ page_rec_is_supremum_low(
|| UNIV_UNLIKELY(offset == PAGE_OLD_SUPREMUM));
}
-/****************************************************************
-TRUE if the record is the infimum record on a page. */
+/************************************************************//**
+TRUE if the record is the infimum record on a page.
+@return TRUE if the infimum record */
UNIV_INLINE
ibool
page_rec_is_infimum_low(
/*====================*/
- /* out: TRUE if the infimum record */
- ulint offset) /* in: record offset on page */
+ ulint offset) /*!< in: record offset on page */
{
ut_ad(offset >= PAGE_NEW_INFIMUM);
ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
@@ -369,65 +384,65 @@ page_rec_is_infimum_low(
|| UNIV_UNLIKELY(offset == PAGE_OLD_INFIMUM));
}
-/****************************************************************
-TRUE if the record is a user record on the page. */
+/************************************************************//**
+TRUE if the record is a user record on the page.
+@return TRUE if a user record */
UNIV_INLINE
ibool
page_rec_is_user_rec(
/*=================*/
- /* out: TRUE if a user record */
- const rec_t* rec) /* in: record */
+ const rec_t* rec) /*!< in: record */
{
return(page_rec_is_user_rec_low(page_offset(rec)));
}
-/****************************************************************
-TRUE if the record is the supremum record on a page. */
+/************************************************************//**
+TRUE if the record is the supremum record on a page.
+@return TRUE if the supremum record */
UNIV_INLINE
ibool
page_rec_is_supremum(
/*=================*/
- /* out: TRUE if the supremum record */
- const rec_t* rec) /* in: record */
+ const rec_t* rec) /*!< in: record */
{
return(page_rec_is_supremum_low(page_offset(rec)));
}
-/****************************************************************
-TRUE if the record is the infimum record on a page. */
+/************************************************************//**
+TRUE if the record is the infimum record on a page.
+@return TRUE if the infimum record */
UNIV_INLINE
ibool
page_rec_is_infimum(
/*================*/
- /* out: TRUE if the infimum record */
- const rec_t* rec) /* in: record */
+ const rec_t* rec) /*!< in: record */
{
return(page_rec_is_infimum_low(page_offset(rec)));
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Compares a data tuple to a physical record. Differs from the function
cmp_dtuple_rec_with_match in the way that the record must reside on an
index page, and also page infimum and supremum records can be given in
the parameter rec. These are considered as the negative infinity and
-the positive infinity in the alphabetical order. */
+the positive infinity in the alphabetical order.
+@return 1, 0, -1, if dtuple is greater, equal, less than rec,
+respectively, when only the common first fields are compared */
UNIV_INLINE
int
page_cmp_dtuple_rec_with_match(
/*===========================*/
- /* out: 1, 0, -1, if dtuple is greater, equal,
- less than rec, respectively, when only the
- common first fields are compared */
- const dtuple_t* dtuple, /* in: data tuple */
- const rec_t* rec, /* in: physical record on a page; may also
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record on a page; may also
be page infimum or supremum, in which case
matched-parameter values below are not
affected */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint* matched_fields, /* in/out: number of already completely
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint* matched_fields, /*!< in/out: number of already completely
matched fields; when function returns
contains the value for current comparison */
- ulint* matched_bytes) /* in/out: number of already matched
+ ulint* matched_bytes) /*!< in/out: number of already matched
bytes within the first field not completely
matched; when function returns contains the
value for current comparison */
@@ -453,96 +468,97 @@ page_cmp_dtuple_rec_with_match(
matched_fields,
matched_bytes));
}
+#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
-Gets the page number. */
+/*************************************************************//**
+Gets the page number.
+@return page number */
UNIV_INLINE
ulint
page_get_page_no(
/*=============*/
- /* out: page number */
- const page_t* page) /* in: page */
+ const page_t* page) /*!< in: page */
{
ut_ad(page == page_align((page_t*) page));
return(mach_read_from_4(page + FIL_PAGE_OFFSET));
}
-/*****************************************************************
-Gets the tablespace identifier. */
+/*************************************************************//**
+Gets the tablespace identifier.
+@return space id */
UNIV_INLINE
ulint
page_get_space_id(
/*==============*/
- /* out: space id */
- const page_t* page) /* in: page */
+ const page_t* page) /*!< in: page */
{
ut_ad(page == page_align((page_t*) page));
return(mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID));
}
-/*****************************************************************
+/*************************************************************//**
Gets the number of user records on page (infimum and supremum records
-are not user records). */
+are not user records).
+@return number of user records */
UNIV_INLINE
ulint
page_get_n_recs(
/*============*/
- /* out: number of user records */
- const page_t* page) /* in: index page */
+ const page_t* page) /*!< in: index page */
{
return(page_header_get_field(page, PAGE_N_RECS));
}
-/*****************************************************************
-Gets the number of dir slots in directory. */
+/*************************************************************//**
+Gets the number of dir slots in directory.
+@return number of slots */
UNIV_INLINE
ulint
page_dir_get_n_slots(
/*=================*/
- /* out: number of slots */
- const page_t* page) /* in: index page */
+ const page_t* page) /*!< in: index page */
{
return(page_header_get_field(page, PAGE_N_DIR_SLOTS));
}
-/*****************************************************************
+/*************************************************************//**
Sets the number of dir slots in directory. */
UNIV_INLINE
void
page_dir_set_n_slots(
/*=================*/
- page_t* page, /* in/out: page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ page_t* page, /*!< in/out: page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
- ulint n_slots)/* in: number of slots */
+ ulint n_slots)/*!< in: number of slots */
{
page_header_set_field(page, page_zip, PAGE_N_DIR_SLOTS, n_slots);
}
-/*****************************************************************
-Gets the number of records in the heap. */
+/*************************************************************//**
+Gets the number of records in the heap.
+@return number of user records */
UNIV_INLINE
ulint
page_dir_get_n_heap(
/*================*/
- /* out: number of user records */
- const page_t* page) /* in: index page */
+ const page_t* page) /*!< in: index page */
{
return(page_header_get_field(page, PAGE_N_HEAP) & 0x7fff);
}
-/*****************************************************************
+/*************************************************************//**
Sets the number of records in the heap. */
UNIV_INLINE
void
page_dir_set_n_heap(
/*================*/
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL.
Note that the size of the dense page directory
in the compressed page trailer is
n_heap * PAGE_ZIP_DIR_SLOT_SIZE. */
- ulint n_heap) /* in: number of records */
+ ulint n_heap) /*!< in: number of records */
{
ut_ad(n_heap < 0x8000);
ut_ad(!page_zip || n_heap
@@ -554,15 +570,15 @@ page_dir_set_n_heap(
}
#ifdef UNIV_DEBUG
-/*****************************************************************
-Gets pointer to nth directory slot. */
+/*************************************************************//**
+Gets pointer to nth directory slot.
+@return pointer to dir slot */
UNIV_INLINE
page_dir_slot_t*
page_dir_get_nth_slot(
/*==================*/
- /* out: pointer to dir slot */
- const page_t* page, /* in: index page */
- ulint n) /* in: position */
+ const page_t* page, /*!< in: index page */
+ ulint n) /*!< in: position */
{
ut_ad(page_dir_get_n_slots(page) > n);
@@ -572,14 +588,14 @@ page_dir_get_nth_slot(
}
#endif /* UNIV_DEBUG */
-/******************************************************************
-Used to check the consistency of a record on a page. */
+/**************************************************************//**
+Used to check the consistency of a record on a page.
+@return TRUE if succeed */
UNIV_INLINE
ibool
page_rec_check(
/*===========*/
- /* out: TRUE if succeed */
- const rec_t* rec) /* in: record */
+ const rec_t* rec) /*!< in: record */
{
const page_t* page = page_align(rec);
@@ -591,40 +607,40 @@ page_rec_check(
return(TRUE);
}
-/*******************************************************************
-Gets the record pointed to by a directory slot. */
+/***************************************************************//**
+Gets the record pointed to by a directory slot.
+@return pointer to record */
UNIV_INLINE
const rec_t*
page_dir_slot_get_rec(
/*==================*/
- /* out: pointer to record */
- const page_dir_slot_t* slot) /* in: directory slot */
+ const page_dir_slot_t* slot) /*!< in: directory slot */
{
return(page_align(slot) + mach_read_from_2(slot));
}
-/*******************************************************************
+/***************************************************************//**
This is used to set the record offset in a directory slot. */
UNIV_INLINE
void
page_dir_slot_set_rec(
/*==================*/
- page_dir_slot_t* slot, /* in: directory slot */
- rec_t* rec) /* in: record on the page */
+ page_dir_slot_t* slot, /*!< in: directory slot */
+ rec_t* rec) /*!< in: record on the page */
{
ut_ad(page_rec_check(rec));
mach_write_to_2(slot, page_offset(rec));
}
-/*******************************************************************
-Gets the number of records owned by a directory slot. */
+/***************************************************************//**
+Gets the number of records owned by a directory slot.
+@return number of records */
UNIV_INLINE
ulint
page_dir_slot_get_n_owned(
/*======================*/
- /* out: number of records */
- const page_dir_slot_t* slot) /* in: page directory slot */
+ const page_dir_slot_t* slot) /*!< in: page directory slot */
{
const rec_t* rec = page_dir_slot_get_rec(slot);
if (page_rec_is_comp(slot)) {
@@ -634,15 +650,15 @@ page_dir_slot_get_n_owned(
}
}
-/*******************************************************************
+/***************************************************************//**
This is used to set the owned records field of a directory slot. */
UNIV_INLINE
void
page_dir_slot_set_n_owned(
/*======================*/
- page_dir_slot_t*slot, /* in/out: directory slot */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint n) /* in: number of records owned by the slot */
+ page_dir_slot_t*slot, /*!< in/out: directory slot */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint n) /*!< in: number of records owned by the slot */
{
rec_t* rec = (rec_t*) page_dir_slot_get_rec(slot);
if (page_rec_is_comp(slot)) {
@@ -653,7 +669,7 @@ page_dir_slot_set_n_owned(
}
}
-/****************************************************************
+/************************************************************//**
Calculates the space reserved for directory slots of a given number of
records. The exact value is a fraction number n * PAGE_DIR_SLOT_SIZE /
PAGE_DIR_SLOT_MIN_N_OWNED, and it is rounded upwards to an integer. */
@@ -661,21 +677,21 @@ UNIV_INLINE
ulint
page_dir_calc_reserved_space(
/*=========================*/
- ulint n_recs) /* in: number of records */
+ ulint n_recs) /*!< in: number of records */
{
return((PAGE_DIR_SLOT_SIZE * n_recs + PAGE_DIR_SLOT_MIN_N_OWNED - 1)
/ PAGE_DIR_SLOT_MIN_N_OWNED);
}
-/****************************************************************
-Gets the pointer to the next record on the page. */
+/************************************************************//**
+Gets the pointer to the next record on the page.
+@return pointer to next record */
UNIV_INLINE
const rec_t*
page_rec_get_next_low(
/*==================*/
- /* out: pointer to next record */
- const rec_t* rec, /* in: pointer to record */
- ulint comp) /* in: nonzero=compact page layout */
+ const rec_t* rec, /*!< in: pointer to record */
+ ulint comp) /*!< in: nonzero=compact page layout */
{
ulint offs;
const page_t* page;
@@ -708,39 +724,39 @@ page_rec_get_next_low(
return(page + offs);
}
-/****************************************************************
-Gets the pointer to the next record on the page. */
+/************************************************************//**
+Gets the pointer to the next record on the page.
+@return pointer to next record */
UNIV_INLINE
rec_t*
page_rec_get_next(
/*==============*/
- /* out: pointer to next record */
- rec_t* rec) /* in: pointer to record */
+ rec_t* rec) /*!< in: pointer to record */
{
return((rec_t*) page_rec_get_next_low(rec, page_rec_is_comp(rec)));
}
-/****************************************************************
-Gets the pointer to the next record on the page. */
+/************************************************************//**
+Gets the pointer to the next record on the page.
+@return pointer to next record */
UNIV_INLINE
const rec_t*
page_rec_get_next_const(
/*====================*/
- /* out: pointer to next record */
- const rec_t* rec) /* in: pointer to record */
+ const rec_t* rec) /*!< in: pointer to record */
{
return(page_rec_get_next_low(rec, page_rec_is_comp(rec)));
}
-/****************************************************************
+/************************************************************//**
Sets the pointer to the next record on the page. */
UNIV_INLINE
void
page_rec_set_next(
/*==============*/
- rec_t* rec, /* in: pointer to record,
+ rec_t* rec, /*!< in: pointer to record,
must not be page supremum */
- rec_t* next) /* in: pointer to next record,
+ rec_t* next) /*!< in: pointer to next record,
must not be page infimum */
{
ulint offs;
@@ -765,14 +781,14 @@ page_rec_set_next(
}
}
-/****************************************************************
-Gets the pointer to the previous record. */
+/************************************************************//**
+Gets the pointer to the previous record.
+@return pointer to previous record */
UNIV_INLINE
const rec_t*
page_rec_get_prev_const(
/*====================*/
- /* out: pointer to previous record */
- const rec_t* rec) /* in: pointer to record, must not be page
+ const rec_t* rec) /*!< in: pointer to record, must not be page
infimum */
{
const page_dir_slot_t* slot;
@@ -812,27 +828,27 @@ page_rec_get_prev_const(
return(prev_rec);
}
-/****************************************************************
-Gets the pointer to the previous record. */
+/************************************************************//**
+Gets the pointer to the previous record.
+@return pointer to previous record */
UNIV_INLINE
rec_t*
page_rec_get_prev(
/*==============*/
- /* out: pointer to previous record */
- rec_t* rec) /* in: pointer to record, must not be page
+ rec_t* rec) /*!< in: pointer to record, must not be page
infimum */
{
return((rec_t*) page_rec_get_prev_const(rec));
}
-/*******************************************************************
-Looks for the record which owns the given record. */
+/***************************************************************//**
+Looks for the record which owns the given record.
+@return the owner record */
UNIV_INLINE
rec_t*
page_rec_find_owner_rec(
/*====================*/
- /* out: the owner record */
- rec_t* rec) /* in: the physical record */
+ rec_t* rec) /*!< in: the physical record */
{
ut_ad(page_rec_check(rec));
@@ -849,16 +865,15 @@ page_rec_find_owner_rec(
return(rec);
}
-/**************************************************************
+/**********************************************************//**
Returns the base extra size of a physical record. This is the
-size of the fixed header, independent of the record size. */
+size of the fixed header, independent of the record size.
+@return REC_N_NEW_EXTRA_BYTES or REC_N_OLD_EXTRA_BYTES */
UNIV_INLINE
ulint
page_rec_get_base_extra_size(
/*=========================*/
- /* out: REC_N_NEW_EXTRA_BYTES
- or REC_N_OLD_EXTRA_BYTES */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
#if REC_N_NEW_EXTRA_BYTES + 1 != REC_N_OLD_EXTRA_BYTES
# error "REC_N_NEW_EXTRA_BYTES + 1 != REC_N_OLD_EXTRA_BYTES"
@@ -866,15 +881,15 @@ page_rec_get_base_extra_size(
return(REC_N_NEW_EXTRA_BYTES + (ulint) !page_rec_is_comp(rec));
}
-/****************************************************************
+/************************************************************//**
Returns the sum of the sizes of the records in the record list, excluding
-the infimum and supremum records. */
+the infimum and supremum records.
+@return data in bytes */
UNIV_INLINE
ulint
page_get_data_size(
/*===============*/
- /* out: data in bytes */
- const page_t* page) /* in: index page */
+ const page_t* page) /*!< in: index page */
{
ulint ret;
@@ -890,19 +905,19 @@ page_get_data_size(
}
-/****************************************************************
+/************************************************************//**
Allocates a block of memory from the free list of an index page. */
UNIV_INTERN
void
page_mem_alloc_free(
/*================*/
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page with enough
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
space available for inserting the record,
or NULL */
- rec_t* next_rec,/* in: pointer to the new head of the
+ rec_t* next_rec,/*!< in: pointer to the new head of the
free record list */
- ulint need) /* in: number of bytes allocated */
+ ulint need) /*!< in: number of bytes allocated */
{
ulint garbage;
@@ -923,14 +938,14 @@ page_mem_alloc_free(
page_header_set_field(page, page_zip, PAGE_GARBAGE, garbage - need);
}
-/*****************************************************************
-Calculates free space if a page is emptied. */
+/*************************************************************//**
+Calculates free space if a page is emptied.
+@return free space */
UNIV_INLINE
ulint
page_get_free_space_of_empty(
/*=========================*/
- /* out: free space */
- ulint comp) /* in: nonzero=compact page layout */
+ ulint comp) /*!< in: nonzero=compact page layout */
{
if (UNIV_LIKELY(comp)) {
return((ulint)(UNIV_PAGE_SIZE
@@ -945,21 +960,20 @@ page_get_free_space_of_empty(
- 2 * PAGE_DIR_SLOT_SIZE));
}
-/****************************************************************
+/************************************************************//**
Each user record on a page, and also the deleted user records in the heap
takes its size plus the fraction of the dir cell size /
PAGE_DIR_SLOT_MIN_N_OWNED bytes for it. If the sum of these exceeds the
value of page_get_free_space_of_empty, the insert is impossible, otherwise
it is allowed. This function returns the maximum combined size of records
-which can be inserted on top of the record heap. */
+which can be inserted on top of the record heap.
+@return maximum combined size for inserted records */
UNIV_INLINE
ulint
page_get_max_insert_size(
/*=====================*/
- /* out: maximum combined size for
- inserted records */
- const page_t* page, /* in: index page */
- ulint n_recs) /* in: number of records */
+ const page_t* page, /*!< in: index page */
+ ulint n_recs) /*!< in: number of records */
{
ulint occupied;
ulint free_space;
@@ -992,17 +1006,16 @@ page_get_max_insert_size(
return(free_space - occupied);
}
-/****************************************************************
+/************************************************************//**
Returns the maximum combined size of records which can be inserted on top
-of the record heap if a page is first reorganized. */
+of the record heap if a page is first reorganized.
+@return maximum combined size for inserted records */
UNIV_INLINE
ulint
page_get_max_insert_size_after_reorganize(
/*======================================*/
- /* out: maximum combined size for
- inserted records */
- const page_t* page, /* in: index page */
- ulint n_recs) /* in: number of records */
+ const page_t* page, /*!< in: index page */
+ ulint n_recs) /*!< in: number of records */
{
ulint occupied;
ulint free_space;
@@ -1020,17 +1033,17 @@ page_get_max_insert_size_after_reorganize(
return(free_space - occupied);
}
-/****************************************************************
+/************************************************************//**
Puts a record to free list. */
UNIV_INLINE
void
page_mem_free(
/*==========*/
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- rec_t* rec, /* in: pointer to the (origin of) record */
- dict_index_t* index, /* in: index of rec */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ rec_t* rec, /*!< in: pointer to the (origin of) record */
+ dict_index_t* index, /*!< in: index of rec */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
rec_t* free;
ulint garbage;
diff --git a/storage/xtradb/include/page0types.h b/storage/xtradb/include/page0types.h
index 06af7a63d58..d9a277bf208 100644
--- a/storage/xtradb/include/page0types.h
+++ b/storage/xtradb/include/page0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/page0types.h
Index page routines
Created 2/2/1994 Heikki Tuuri
@@ -29,46 +30,52 @@ Created 2/2/1994 Heikki Tuuri
#include "dict0types.h"
#include "mtr0types.h"
-/* Type of the index page */
-/* The following define eliminates a name collision on HP-UX */
+/** Eliminates a name collision on HP-UX */
#define page_t ib_page_t
+/** Type of the index page */
typedef byte page_t;
-typedef struct page_search_struct page_search_t;
+/** Index page cursor */
typedef struct page_cur_struct page_cur_t;
+/** Compressed index page */
typedef byte page_zip_t;
+/** Compressed page descriptor */
typedef struct page_zip_des_struct page_zip_des_t;
/* The following definitions would better belong to page0zip.h,
but we cannot include page0zip.h from rem0rec.ic, because
page0*.h includes rem0rec.h and may include rem0rec.ic. */
+/** Number of bits needed for representing different compressed page sizes */
#define PAGE_ZIP_SSIZE_BITS 3
-#define PAGE_ZIP_MIN_SIZE_SHIFT 10 /* log2 of smallest compressed size */
+/** log2 of smallest compressed page size */
+#define PAGE_ZIP_MIN_SIZE_SHIFT 10
+/** Smallest compressed page size */
#define PAGE_ZIP_MIN_SIZE (1 << PAGE_ZIP_MIN_SIZE_SHIFT)
+/** Number of supported compressed page sizes */
#define PAGE_ZIP_NUM_SSIZE (UNIV_PAGE_SIZE_SHIFT - PAGE_ZIP_MIN_SIZE_SHIFT + 2)
#if PAGE_ZIP_NUM_SSIZE > (1 << PAGE_ZIP_SSIZE_BITS)
# error "PAGE_ZIP_NUM_SSIZE > (1 << PAGE_ZIP_SSIZE_BITS)"
#endif
-/* Compressed page descriptor */
+/** Compressed page descriptor */
struct page_zip_des_struct
{
- page_zip_t* data; /* compressed page data */
+ page_zip_t* data; /*!< compressed page data */
#ifdef UNIV_DEBUG
- unsigned m_start:16; /* start offset of modification log */
+ unsigned m_start:16; /*!< start offset of modification log */
#endif /* UNIV_DEBUG */
- unsigned m_end:16; /* end offset of modification log */
- unsigned m_nonempty:1; /* TRUE if the modification log
+ unsigned m_end:16; /*!< end offset of modification log */
+ unsigned m_nonempty:1; /*!< TRUE if the modification log
is not empty */
- unsigned n_blobs:12; /* number of externally stored
+ unsigned n_blobs:12; /*!< number of externally stored
columns on the page; the maximum
is 744 on a 16 KiB page */
unsigned ssize:PAGE_ZIP_SSIZE_BITS;
- /* 0 or compressed page size;
+ /*!< 0 or compressed page size;
the size in bytes is
PAGE_ZIP_MIN_SIZE << (ssize - 1). */
};
@@ -87,56 +94,57 @@ struct page_zip_stat_struct {
ib_uint64_t decompressed_usec;
};
+/** Compression statistics */
typedef struct page_zip_stat_struct page_zip_stat_t;
-/** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */
+/** Statistics on compression, indexed by page_zip_des_struct::ssize - 1 */
extern page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
-/**************************************************************************
+/**********************************************************************//**
Write the "deleted" flag of a record on a compressed page. The flag must
already have been written on the uncompressed page. */
UNIV_INTERN
void
page_zip_rec_set_deleted(
/*=====================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in: record on the uncompressed page */
- ulint flag) /* in: the deleted flag (nonzero=TRUE) */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in: record on the uncompressed page */
+ ulint flag) /*!< in: the deleted flag (nonzero=TRUE) */
__attribute__((nonnull));
-/**************************************************************************
+/**********************************************************************//**
Write the "owned" flag of a record on a compressed page. The n_owned field
must already have been written on the uncompressed page. */
UNIV_INTERN
void
page_zip_rec_set_owned(
/*===================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in: record on the uncompressed page */
- ulint flag) /* in: the owned flag (nonzero=TRUE) */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in: record on the uncompressed page */
+ ulint flag) /*!< in: the owned flag (nonzero=TRUE) */
__attribute__((nonnull));
-/**************************************************************************
+/**********************************************************************//**
Shift the dense page directory when a record is deleted. */
UNIV_INTERN
void
page_zip_dir_delete(
/*================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- byte* rec, /* in: deleted record */
- dict_index_t* index, /* in: index of rec */
- const ulint* offsets,/* in: rec_get_offsets(rec) */
- const byte* free) /* in: previous start of the free list */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ byte* rec, /*!< in: deleted record */
+ dict_index_t* index, /*!< in: index of rec */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec) */
+ const byte* free) /*!< in: previous start of the free list */
__attribute__((nonnull(1,2,3,4)));
-/**************************************************************************
+/**********************************************************************//**
Add a slot to the dense page directory. */
UNIV_INTERN
void
page_zip_dir_add_slot(
/*==================*/
- page_zip_des_t* page_zip, /* in/out: compressed page */
- ulint is_clustered) /* in: nonzero for clustered index,
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ ulint is_clustered) /*!< in: nonzero for clustered index,
zero for others */
__attribute__((nonnull));
#endif
diff --git a/storage/xtradb/include/page0zip.h b/storage/xtradb/include/page0zip.h
index 0183e013d05..9aaa066306b 100644
--- a/storage/xtradb/include/page0zip.h
+++ b/storage/xtradb/include/page0zip.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/page0zip.h
Compressed page interface
Created June 2005 by Marko Makela
@@ -34,334 +35,332 @@ Created June 2005 by Marko Makela
#include "page0types.h"
#include "buf0types.h"
#include "dict0types.h"
+#include "trx0types.h"
#include "mem0mem.h"
-/**************************************************************************
-Determine the size of a compressed page in bytes. */
+/**********************************************************************//**
+Determine the size of a compressed page in bytes.
+@return size in bytes */
UNIV_INLINE
ulint
page_zip_get_size(
/*==============*/
- /* out: size in bytes */
- const page_zip_des_t* page_zip) /* in: compressed page */
+ const page_zip_des_t* page_zip) /*!< in: compressed page */
__attribute__((nonnull, pure));
-/**************************************************************************
+/**********************************************************************//**
Set the size of a compressed page in bytes. */
UNIV_INLINE
void
page_zip_set_size(
/*==============*/
- page_zip_des_t* page_zip, /* in/out: compressed page */
- ulint size); /* in: size in bytes */
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ ulint size); /*!< in: size in bytes */
-/**************************************************************************
-Determine if a record is so big that it needs to be stored externally. */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
+Determine if a record is so big that it needs to be stored externally.
+@return FALSE if the entire record can be stored locally on the page */
UNIV_INLINE
ibool
page_zip_rec_needs_ext(
/*===================*/
- /* out: FALSE if the entire record
- can be stored locally on the page */
- ulint rec_size, /* in: length of the record in bytes */
- ulint comp, /* in: nonzero=compact format */
- ulint n_fields, /* in: number of fields in the record;
+ ulint rec_size, /*!< in: length of the record in bytes */
+ ulint comp, /*!< in: nonzero=compact format */
+ ulint n_fields, /*!< in: number of fields in the record;
ignored if zip_size == 0 */
- ulint zip_size) /* in: compressed page size in bytes, or 0 */
+ ulint zip_size) /*!< in: compressed page size in bytes, or 0 */
__attribute__((const));
-/**************************************************************************
-Determine the guaranteed free space on an empty page. */
+/**********************************************************************//**
+Determine the guaranteed free space on an empty page.
+@return minimum payload size on the page */
UNIV_INTERN
ulint
page_zip_empty_size(
/*================*/
- /* out: minimum payload size on the page */
- ulint n_fields, /* in: number of columns in the index */
- ulint zip_size) /* in: compressed page size in bytes */
+ ulint n_fields, /*!< in: number of columns in the index */
+ ulint zip_size) /*!< in: compressed page size in bytes */
__attribute__((const));
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Initialize a compressed page descriptor. */
UNIV_INLINE
void
page_zip_des_init(
/*==============*/
- page_zip_des_t* page_zip); /* in/out: compressed page
+ page_zip_des_t* page_zip); /*!< in/out: compressed page
descriptor */
-/**************************************************************************
+/**********************************************************************//**
Configure the zlib allocator to use the given memory heap. */
UNIV_INTERN
void
page_zip_set_alloc(
/*===============*/
- void* stream, /* in/out: zlib stream */
- mem_heap_t* heap); /* in: memory heap to use */
+ void* stream, /*!< in/out: zlib stream */
+ mem_heap_t* heap); /*!< in: memory heap to use */
-/**************************************************************************
-Compress a page. */
+/**********************************************************************//**
+Compress a page.
+@return TRUE on success, FALSE on failure; page_zip will be left
+intact on failure. */
UNIV_INTERN
ibool
page_zip_compress(
/*==============*/
- /* out: TRUE on success, FALSE on failure;
- page_zip will be left intact on failure. */
- page_zip_des_t* page_zip,/* in: size; out: data, n_blobs,
+ page_zip_des_t* page_zip,/*!< in: size; out: data, n_blobs,
m_start, m_end, m_nonempty */
- 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 */
+ 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)));
-/**************************************************************************
+/**********************************************************************//**
Decompress a page. This function should tolerate errors on the compressed
page. Instead of letting assertions fail, it will return FALSE if an
-inconsistency is detected. */
+inconsistency is detected.
+@return TRUE on success, FALSE on failure */
UNIV_INTERN
ibool
page_zip_decompress(
/*================*/
- /* out: TRUE on success, FALSE on failure */
- page_zip_des_t* page_zip,/* in: data, ssize;
+ page_zip_des_t* page_zip,/*!< in: data, ssize;
out: m_start, m_end, m_nonempty, n_blobs */
- page_t* page) /* out: uncompressed page, may be trashed */
+ page_t* page) /*!< out: uncompressed page, may be trashed */
__attribute__((nonnull));
#ifdef UNIV_DEBUG
-/**************************************************************************
-Validate a compressed page descriptor. */
+/**********************************************************************//**
+Validate a compressed page descriptor.
+@return TRUE if ok */
UNIV_INLINE
ibool
page_zip_simple_validate(
/*=====================*/
- /* out: TRUE if ok */
- const page_zip_des_t* page_zip); /* in: compressed page
+ const page_zip_des_t* page_zip); /*!< in: compressed page
descriptor */
#endif /* UNIV_DEBUG */
#ifdef UNIV_ZIP_DEBUG
-/**************************************************************************
-Check that the compressed and decompressed pages match. */
+/**********************************************************************//**
+Check that the compressed and decompressed pages match.
+@return TRUE if valid, FALSE if not */
UNIV_INTERN
ibool
page_zip_validate_low(
/*==================*/
- /* out: TRUE if valid, FALSE if not */
- const page_zip_des_t* page_zip,/* in: compressed page */
- const page_t* page, /* in: uncompressed page */
- ibool sloppy) /* in: FALSE=strict,
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ const page_t* page, /*!< in: uncompressed page */
+ ibool sloppy) /*!< in: FALSE=strict,
TRUE=ignore the MIN_REC_FLAG */
__attribute__((nonnull));
-/**************************************************************************
+/**********************************************************************//**
Check that the compressed and decompressed pages match. */
UNIV_INTERN
ibool
page_zip_validate(
/*==============*/
- const page_zip_des_t* page_zip,/* in: compressed page */
- const page_t* page) /* in: uncompressed page */
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ const page_t* page) /*!< in: uncompressed page */
__attribute__((nonnull));
#endif /* UNIV_ZIP_DEBUG */
-/**************************************************************************
-Determine how big record can be inserted without recompressing the page. */
+/**********************************************************************//**
+Determine how big record can be inserted without recompressing the page.
+@return a positive number indicating the maximum size of a record
+whose insertion is guaranteed to succeed, or zero or negative */
UNIV_INLINE
lint
page_zip_max_ins_size(
/*==================*/
- /* out: a positive number
- indicating the maximum size of
- a record whose insertion is
- guaranteed to succeed, or
- zero or negative */
- const page_zip_des_t* page_zip,/* in: compressed page */
- ibool is_clust)/* in: TRUE if clustered index */
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ ibool is_clust)/*!< in: TRUE if clustered index */
__attribute__((nonnull, pure));
-/**************************************************************************
-Determine if enough space is available in the modification log. */
+/**********************************************************************//**
+Determine if enough space is available in the modification log.
+@return TRUE if page_zip_write_rec() will succeed */
UNIV_INLINE
ibool
page_zip_available(
/*===============*/
- /* out: TRUE if page_zip_write_rec()
- will succeed */
- const page_zip_des_t* page_zip,/* in: compressed page */
- ibool is_clust,/* in: TRUE if clustered index */
- ulint length, /* in: combined size of the record */
- ulint create) /* in: nonzero=add the record to
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ ibool is_clust,/*!< in: TRUE if clustered index */
+ ulint length, /*!< in: combined size of the record */
+ ulint create) /*!< in: nonzero=add the record to
the heap */
__attribute__((nonnull, pure));
-/**************************************************************************
+/**********************************************************************//**
Write data to the uncompressed header portion of a page. The data must
already have been written to the uncompressed page. */
UNIV_INLINE
void
page_zip_write_header(
/*==================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* str, /* in: address on the uncompressed page */
- ulint length, /* in: length of the data */
- mtr_t* mtr) /* in: mini-transaction, or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* str, /*!< in: address on the uncompressed page */
+ ulint length, /*!< in: length of the data */
+ mtr_t* mtr) /*!< in: mini-transaction, or NULL */
__attribute__((nonnull(1,2)));
-/**************************************************************************
+/**********************************************************************//**
Write an entire record on the compressed page. The data must already
have been written to the uncompressed page. */
UNIV_INTERN
void
page_zip_write_rec(
/*===============*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in: record being written */
- dict_index_t* index, /* in: the index the record belongs to */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- ulint create) /* in: nonzero=insert, zero=update */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in: record being written */
+ dict_index_t* index, /*!< in: the index the record belongs to */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ ulint create) /*!< in: nonzero=insert, zero=update */
__attribute__((nonnull));
-/***************************************************************
-Parses a log record of writing a BLOB pointer of a record. */
+/***********************************************************//**
+Parses a log record of writing a BLOB pointer of a record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_write_blob_ptr(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: redo log buffer */
- byte* end_ptr,/* in: redo log buffer end */
- page_t* page, /* in/out: uncompressed page */
- page_zip_des_t* page_zip);/* in/out: compressed page */
+ byte* ptr, /*!< in: redo log buffer */
+ byte* end_ptr,/*!< in: redo log buffer end */
+ page_t* page, /*!< in/out: uncompressed page */
+ page_zip_des_t* page_zip);/*!< in/out: compressed page */
-/**************************************************************************
+/**********************************************************************//**
Write a BLOB pointer of a record on the leaf page of a clustered index.
The information must already have been updated on the uncompressed page. */
UNIV_INTERN
void
page_zip_write_blob_ptr(
/*====================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in/out: record whose data is being
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in/out: record whose data is being
written */
- dict_index_t* index, /* in: index of the page */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- ulint n, /* in: column index */
- mtr_t* mtr) /* in: mini-transaction handle,
+ dict_index_t* index, /*!< in: index of the page */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ ulint n, /*!< in: column index */
+ mtr_t* mtr) /*!< in: mini-transaction handle,
or NULL if no logging is needed */
__attribute__((nonnull(1,2,3,4)));
-/***************************************************************
-Parses a log record of writing the node pointer of a record. */
+/***********************************************************//**
+Parses a log record of writing the node pointer of a record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_write_node_ptr(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: redo log buffer */
- byte* end_ptr,/* in: redo log buffer end */
- page_t* page, /* in/out: uncompressed page */
- page_zip_des_t* page_zip);/* in/out: compressed page */
+ byte* ptr, /*!< in: redo log buffer */
+ byte* end_ptr,/*!< in: redo log buffer end */
+ page_t* page, /*!< in/out: uncompressed page */
+ page_zip_des_t* page_zip);/*!< in/out: compressed page */
-/**************************************************************************
+/**********************************************************************//**
Write the node pointer of a record on a non-leaf compressed page. */
UNIV_INTERN
void
page_zip_write_node_ptr(
/*====================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- byte* rec, /* in/out: record */
- ulint size, /* in: data size of rec */
- ulint ptr, /* in: node pointer */
- mtr_t* mtr) /* in: mini-transaction, or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ byte* rec, /*!< in/out: record */
+ ulint size, /*!< in: data size of rec */
+ ulint ptr, /*!< in: node pointer */
+ mtr_t* mtr) /*!< in: mini-transaction, or NULL */
__attribute__((nonnull(1,2)));
-/**************************************************************************
+/**********************************************************************//**
Write the trx_id and roll_ptr of a record on a B-tree leaf node page. */
UNIV_INTERN
void
page_zip_write_trx_id_and_roll_ptr(
/*===============================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- byte* rec, /* in/out: record */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- ulint trx_id_col,/* in: column number of TRX_ID in rec */
- dulint trx_id, /* in: transaction identifier */
- dulint roll_ptr)/* in: roll_ptr */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ byte* rec, /*!< in/out: record */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ ulint trx_id_col,/*!< in: column number of TRX_ID in rec */
+ trx_id_t trx_id, /*!< in: transaction identifier */
+ roll_ptr_t roll_ptr)/*!< in: roll_ptr */
__attribute__((nonnull));
-/**************************************************************************
+/**********************************************************************//**
Write the "deleted" flag of a record on a compressed page. The flag must
already have been written on the uncompressed page. */
UNIV_INTERN
void
page_zip_rec_set_deleted(
/*=====================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in: record on the uncompressed page */
- ulint flag) /* in: the deleted flag (nonzero=TRUE) */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in: record on the uncompressed page */
+ ulint flag) /*!< in: the deleted flag (nonzero=TRUE) */
__attribute__((nonnull));
-/**************************************************************************
+/**********************************************************************//**
Write the "owned" flag of a record on a compressed page. The n_owned field
must already have been written on the uncompressed page. */
UNIV_INTERN
void
page_zip_rec_set_owned(
/*===================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in: record on the uncompressed page */
- ulint flag) /* in: the owned flag (nonzero=TRUE) */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in: record on the uncompressed page */
+ ulint flag) /*!< in: the owned flag (nonzero=TRUE) */
__attribute__((nonnull));
-/**************************************************************************
+/**********************************************************************//**
Insert a record to the dense page directory. */
UNIV_INTERN
void
page_zip_dir_insert(
/*================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* prev_rec,/* in: record after which to insert */
- const byte* free_rec,/* in: record from which rec was
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* prev_rec,/*!< in: record after which to insert */
+ const byte* free_rec,/*!< in: record from which rec was
allocated, or NULL */
- byte* rec); /* in: record to insert */
+ byte* rec); /*!< in: record to insert */
-/**************************************************************************
+/**********************************************************************//**
Shift the dense page directory and the array of BLOB pointers
when a record is deleted. */
UNIV_INTERN
void
page_zip_dir_delete(
/*================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- byte* rec, /* in: deleted record */
- dict_index_t* index, /* in: index of rec */
- const ulint* offsets,/* in: rec_get_offsets(rec) */
- const byte* free) /* in: previous start of the free list */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ byte* rec, /*!< in: deleted record */
+ dict_index_t* index, /*!< in: index of rec */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec) */
+ const byte* free) /*!< in: previous start of the free list */
__attribute__((nonnull(1,2,3,4)));
-/**************************************************************************
+/**********************************************************************//**
Add a slot to the dense page directory. */
UNIV_INTERN
void
page_zip_dir_add_slot(
/*==================*/
- page_zip_des_t* page_zip, /* in/out: compressed page */
- ulint is_clustered) /* in: nonzero for clustered index,
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ ulint is_clustered) /*!< in: nonzero for clustered index,
zero for others */
__attribute__((nonnull));
-/***************************************************************
-Parses a log record of writing to the header of a page. */
+/***********************************************************//**
+Parses a log record of writing to the header of a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_write_header(
/*========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: redo log buffer */
- byte* end_ptr,/* in: redo log buffer end */
- page_t* page, /* in/out: uncompressed page */
- page_zip_des_t* page_zip);/* in/out: compressed page */
+ byte* ptr, /*!< in: redo log buffer */
+ byte* end_ptr,/*!< in: redo log buffer end */
+ page_t* page, /*!< in/out: uncompressed page */
+ page_zip_des_t* page_zip);/*!< in/out: compressed page */
-/**************************************************************************
+/**********************************************************************//**
Write data to the uncompressed header portion of a page. The data must
already have been written to the uncompressed page.
However, the data portion of the uncompressed page may differ from
@@ -371,13 +370,13 @@ UNIV_INLINE
void
page_zip_write_header(
/*==================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* str, /* in: address on the uncompressed page */
- ulint length, /* in: length of the data */
- mtr_t* mtr) /* in: mini-transaction, or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* str, /*!< in: address on the uncompressed page */
+ ulint length, /*!< in: length of the data */
+ mtr_t* mtr) /*!< in: mini-transaction, or NULL */
__attribute__((nonnull(1,2)));
-/**************************************************************************
+/**********************************************************************//**
Reorganize and compress a page. This is a low-level operation for
compressed pages, to be used when page_zip_compress() fails.
On success, a redo log entry MLOG_ZIP_PAGE_COMPRESS will be written.
@@ -385,22 +384,22 @@ The function btr_page_reorganize() should be preferred whenever possible.
IMPORTANT: if page_zip_reorganize() is invoked on a leaf page of a
non-clustered index, the caller must update the insert buffer free
bits in the same mini-transaction in such a way that the modification
-will be redo-logged. */
+will be redo-logged.
+@return TRUE on success, FALSE on failure; page and page_zip will be
+left intact on failure. */
UNIV_INTERN
ibool
page_zip_reorganize(
/*================*/
- /* out: TRUE on success, FALSE on failure;
- page and page_zip will be left intact
- on failure. */
- buf_block_t* block, /* in/out: page with compressed page;
+ buf_block_t* block, /*!< in/out: page with compressed page;
on the compressed page, in: size;
out: data, n_blobs,
m_start, m_end, m_nonempty */
- dict_index_t* index, /* in: index of the B-tree node */
- mtr_t* mtr) /* in: mini-transaction */
+ dict_index_t* index, /*!< in: index of the B-tree node */
+ mtr_t* mtr) /*!< in: mini-transaction */
__attribute__((nonnull));
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Copy the records of a page byte for byte. Do not copy the page header
or trailer, except those B-tree header fields that are directly
related to the storage of records. Also copy PAGE_MAX_TRX_ID.
@@ -409,40 +408,57 @@ UNIV_INTERN
void
page_zip_copy_recs(
/*===============*/
- page_zip_des_t* page_zip, /* out: copy of src_zip
+ page_zip_des_t* page_zip, /*!< out: copy of src_zip
(n_blobs, m_start, m_end,
m_nonempty, data[0..size-1]) */
- page_t* page, /* out: copy of src */
- const page_zip_des_t* src_zip, /* in: compressed page */
- const page_t* src, /* in: page */
- dict_index_t* index, /* in: index of the B-tree */
- mtr_t* mtr) /* in: mini-transaction */
+ page_t* page, /*!< out: copy of src */
+ const page_zip_des_t* src_zip, /*!< in: compressed page */
+ const page_t* src, /*!< in: page */
+ dict_index_t* index, /*!< in: index of the B-tree */
+ mtr_t* mtr) /*!< in: mini-transaction */
__attribute__((nonnull(1,2,3,4)));
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
-Parses a log record of compressing an index page. */
+/**********************************************************************//**
+Parses a log record of compressing an index page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_compress(
/*====================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* out: uncompressed page */
- page_zip_des_t* page_zip)/* out: compressed page */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< out: uncompressed page */
+ page_zip_des_t* page_zip)/*!< out: compressed page */
__attribute__((nonnull(1,2)));
-/**************************************************************************
-Calculate the compressed page checksum. */
+/**********************************************************************//**
+Calculate the compressed page checksum.
+@return page checksum */
UNIV_INTERN
ulint
page_zip_calc_checksum(
/*===================*/
- /* out: page checksum */
- const void* data, /* in: compressed page */
- ulint size) /* in: size of compressed page */
+ const void* data, /*!< in: compressed page */
+ ulint size) /*!< in: size of compressed page */
__attribute__((nonnull));
+#ifndef UNIV_HOTBACKUP
+/** Check if a pointer to an uncompressed page matches a compressed page.
+@param ptr pointer to an uncompressed page frame
+@param page_zip compressed page descriptor
+@return TRUE if ptr and page_zip refer to the same block */
+# define PAGE_ZIP_MATCH(ptr, page_zip) \
+ (buf_frame_get_page_zip(ptr) == (page_zip))
+#else /* !UNIV_HOTBACKUP */
+/** Check if a pointer to an uncompressed page matches a compressed page.
+@param ptr pointer to an uncompressed page frame
+@param page_zip compressed page descriptor
+@return TRUE if ptr and page_zip refer to the same block */
+# define PAGE_ZIP_MATCH(ptr, page_zip) \
+ (page_align(ptr) + UNIV_PAGE_SIZE == (page_zip)->data)
+#endif /* !UNIV_HOTBACKUP */
+
#ifdef UNIV_MATERIALIZE
# undef UNIV_INLINE
# define UNIV_INLINE UNIV_INLINE_ORIGINAL
diff --git a/storage/xtradb/include/page0zip.ic b/storage/xtradb/include/page0zip.ic
index 3db5f025c31..75cc7a9fcc4 100644
--- a/storage/xtradb/include/page0zip.ic
+++ b/storage/xtradb/include/page0zip.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/page0zip.ic
Compressed page interface
Created June 2005 by Marko Makela
@@ -97,25 +98,25 @@ In summary, the compressed page looks like this:
- deleted records (free list) in link order
*/
-/* Start offset of the area that will be compressed */
+/** Start offset of the area that will be compressed */
#define PAGE_ZIP_START PAGE_NEW_SUPREMUM_END
-/* Size of an compressed page directory entry */
+/** Size of an compressed page directory entry */
#define PAGE_ZIP_DIR_SLOT_SIZE 2
-/* Mask of record offsets */
+/** Mask of record offsets */
#define PAGE_ZIP_DIR_SLOT_MASK 0x3fff
-/* 'owned' flag */
+/** 'owned' flag */
#define PAGE_ZIP_DIR_SLOT_OWNED 0x4000
-/* 'deleted' flag */
+/** 'deleted' flag */
#define PAGE_ZIP_DIR_SLOT_DEL 0x8000
-/**************************************************************************
-Determine the size of a compressed page in bytes. */
+/**********************************************************************//**
+Determine the size of a compressed page in bytes.
+@return size in bytes */
UNIV_INLINE
ulint
page_zip_get_size(
/*==============*/
- /* out: size in bytes */
- const page_zip_des_t* page_zip) /* in: compressed page */
+ const page_zip_des_t* page_zip) /*!< in: compressed page */
{
ulint size;
@@ -130,14 +131,14 @@ page_zip_get_size(
return(size);
}
-/**************************************************************************
+/**********************************************************************//**
Set the size of a compressed page in bytes. */
UNIV_INLINE
void
page_zip_set_size(
/*==============*/
- page_zip_des_t* page_zip, /* in/out: compressed page */
- ulint size) /* in: size in bytes */
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ ulint size) /*!< in: size in bytes */
{
if (size) {
int ssize;
@@ -155,19 +156,19 @@ page_zip_set_size(
ut_ad(page_zip_get_size(page_zip) == size);
}
-/**************************************************************************
-Determine if a record is so big that it needs to be stored externally. */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
+Determine if a record is so big that it needs to be stored externally.
+@return FALSE if the entire record can be stored locally on the page */
UNIV_INLINE
ibool
page_zip_rec_needs_ext(
/*===================*/
- /* out: FALSE if the entire record
- can be stored locally on the page */
- ulint rec_size, /* in: length of the record in bytes */
- ulint comp, /* in: nonzero=compact format */
- ulint n_fields, /* in: number of fields in the record;
+ ulint rec_size, /*!< in: length of the record in bytes */
+ ulint comp, /*!< in: nonzero=compact format */
+ ulint n_fields, /*!< in: number of fields in the record;
ignored if zip_size == 0 */
- ulint zip_size) /* in: compressed page size in bytes, or 0 */
+ ulint zip_size) /*!< in: compressed page size in bytes, or 0 */
{
ut_ad(rec_size > comp ? REC_N_NEW_EXTRA_BYTES : REC_N_OLD_EXTRA_BYTES);
ut_ad(ut_is_2pow(zip_size));
@@ -194,16 +195,17 @@ page_zip_rec_needs_ext(
return(rec_size >= page_get_free_space_of_empty(comp) / 2);
}
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
-/**************************************************************************
-Validate a compressed page descriptor. */
+/**********************************************************************//**
+Validate a compressed page descriptor.
+@return TRUE if ok */
UNIV_INLINE
ibool
page_zip_simple_validate(
/*=====================*/
- /* out: TRUE if ok */
- const page_zip_des_t* page_zip)/* in: compressed page descriptor */
+ const page_zip_des_t* page_zip)/*!< in: compressed page descriptor */
{
ut_ad(page_zip);
ut_ad(page_zip->data);
@@ -218,18 +220,17 @@ page_zip_simple_validate(
}
#endif /* UNIV_DEBUG */
-/**************************************************************************
-Determine if the length of the page trailer. */
+/**********************************************************************//**
+Determine if the length of the page trailer.
+@return length of the page trailer, in bytes, not including the
+terminating zero byte of the modification log */
UNIV_INLINE
ibool
page_zip_get_trailer_len(
/*=====================*/
- /* out: length of the page trailer,
- in bytes, not including the terminating
- zero byte of the modification log */
- const page_zip_des_t* page_zip,/* in: compressed page */
- ibool is_clust,/* in: TRUE if clustered index */
- ulint* entry_size)/* out: size of the uncompressed
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ ibool is_clust,/*!< in: TRUE if clustered index */
+ ulint* entry_size)/*!< out: size of the uncompressed
portion of a user record */
{
ulint uncompressed_size;
@@ -258,19 +259,16 @@ page_zip_get_trailer_len(
+ page_zip->n_blobs * BTR_EXTERN_FIELD_REF_SIZE);
}
-/**************************************************************************
-Determine how big record can be inserted without recompressing the page. */
+/**********************************************************************//**
+Determine how big record can be inserted without recompressing the page.
+@return a positive number indicating the maximum size of a record
+whose insertion is guaranteed to succeed, or zero or negative */
UNIV_INLINE
lint
page_zip_max_ins_size(
/*==================*/
- /* out: a positive number
- indicating the maximum size of
- a record whose insertion is
- guaranteed to succeed, or
- zero or negative */
- const page_zip_des_t* page_zip,/* in: compressed page */
- ibool is_clust)/* in: TRUE if clustered index */
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ ibool is_clust)/*!< in: TRUE if clustered index */
{
ulint uncompressed_size;
ulint trailer_len;
@@ -292,18 +290,17 @@ page_zip_max_ins_size(
- (REC_N_NEW_EXTRA_BYTES - 2));
}
-/**************************************************************************
-Determine if enough space is available in the modification log. */
+/**********************************************************************//**
+Determine if enough space is available in the modification log.
+@return TRUE if enough space is available */
UNIV_INLINE
ibool
page_zip_available(
/*===============*/
- /* out: TRUE if enough space
- is available */
- const page_zip_des_t* page_zip,/* in: compressed page */
- ibool is_clust,/* in: TRUE if clustered index */
- ulint length, /* in: combined size of the record */
- ulint create) /* in: nonzero=add the record to
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ ibool is_clust,/*!< in: TRUE if clustered index */
+ ulint length, /*!< in: combined size of the record */
+ ulint create) /*!< in: nonzero=add the record to
the heap */
{
ulint uncompressed_size;
@@ -335,29 +332,29 @@ page_zip_available(
< page_zip_get_size(page_zip)));
}
-/**************************************************************************
+/**********************************************************************//**
Initialize a compressed page descriptor. */
UNIV_INLINE
void
page_zip_des_init(
/*==============*/
- page_zip_des_t* page_zip) /* in/out: compressed page
+ page_zip_des_t* page_zip) /*!< in/out: compressed page
descriptor */
{
memset(page_zip, 0, sizeof *page_zip);
}
-/**************************************************************************
+/**********************************************************************//**
Write a log record of writing to the uncompressed header portion of a page. */
UNIV_INTERN
void
page_zip_write_header_log(
/*======================*/
- const byte* data,/* in: data on the uncompressed page */
- ulint length, /* in: length of the data */
- mtr_t* mtr); /* in: mini-transaction */
+ const byte* data,/*!< in: data on the uncompressed page */
+ ulint length, /*!< in: length of the data */
+ mtr_t* mtr); /*!< in: mini-transaction */
-/**************************************************************************
+/**********************************************************************//**
Write data to the uncompressed header portion of a page. The data must
already have been written to the uncompressed page.
However, the data portion of the uncompressed page may differ from
@@ -367,14 +364,14 @@ UNIV_INLINE
void
page_zip_write_header(
/*==================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* str, /* in: address on the uncompressed page */
- ulint length, /* in: length of the data */
- mtr_t* mtr) /* in: mini-transaction, or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* str, /*!< in: address on the uncompressed page */
+ ulint length, /*!< in: length of the data */
+ mtr_t* mtr) /*!< in: mini-transaction, or NULL */
{
ulint pos;
- ut_ad(buf_frame_get_page_zip(str) == page_zip);
+ ut_ad(PAGE_ZIP_MATCH(str, page_zip));
ut_ad(page_zip_simple_validate(page_zip));
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
@@ -388,7 +385,9 @@ page_zip_write_header(
/* ut_ad(page_zip_validate(page_zip, str - pos)); */
if (UNIV_LIKELY_NULL(mtr)) {
+#ifndef UNIV_HOTBACKUP
page_zip_write_header_log(str, length, mtr);
+#endif /* !UNIV_HOTBACKUP */
}
}
diff --git a/storage/xtradb/include/pars0opt.h b/storage/xtradb/include/pars0opt.h
index 02524e9d893..42d956068f8 100644
--- a/storage/xtradb/include/pars0opt.h
+++ b/storage/xtradb/include/pars0opt.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/pars0opt.h
Simple SQL optimizer
Created 12/21/1997 Heikki Tuuri
@@ -32,7 +33,7 @@ Created 12/21/1997 Heikki Tuuri
#include "dict0types.h"
#include "row0sel.h"
-/***********************************************************************
+/*******************************************************************//**
Optimizes a select. Decides which indexes to tables to use. The tables
are accessed in the order that they were written to the FROM part in the
select statement. */
@@ -40,8 +41,8 @@ UNIV_INTERN
void
opt_search_plan(
/*============*/
- sel_node_t* sel_node); /* in: parsed select node */
-/***********************************************************************
+ sel_node_t* sel_node); /*!< in: parsed select node */
+/*******************************************************************//**
Looks for occurrences of the columns of the table in the query subgraph and
adds them to the list of columns if an occurrence of the same column does not
already exist in the list. If the column is already in the list, puts a value
@@ -52,20 +53,20 @@ UNIV_INTERN
void
opt_find_all_cols(
/*==============*/
- ibool copy_val, /* in: if TRUE, new found columns are
+ ibool copy_val, /*!< in: if TRUE, new found columns are
added as columns to copy */
- dict_index_t* index, /* in: index to use */
- sym_node_list_t* col_list, /* in: base node of a list where
+ dict_index_t* index, /*!< in: index to use */
+ sym_node_list_t* col_list, /*!< in: base node of a list where
to add new found columns */
- plan_t* plan, /* in: plan or NULL */
- que_node_t* exp); /* in: expression or condition */
-/************************************************************************
+ plan_t* plan, /*!< in: plan or NULL */
+ que_node_t* exp); /*!< in: expression or condition */
+/********************************************************************//**
Prints info of a query plan. */
UNIV_INTERN
void
opt_print_query_plan(
/*=================*/
- sel_node_t* sel_node); /* in: select node */
+ sel_node_t* sel_node); /*!< in: select node */
#ifndef UNIV_NONINL
#include "pars0opt.ic"
diff --git a/storage/xtradb/include/pars0opt.ic b/storage/xtradb/include/pars0opt.ic
index 35653453b30..e0bb6bf1af2 100644
--- a/storage/xtradb/include/pars0opt.ic
+++ b/storage/xtradb/include/pars0opt.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/pars0opt.ic
Simple SQL optimizer
Created 12/21/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/pars0pars.h b/storage/xtradb/include/pars0pars.h
index 865f24f7bf4..a7de7f2292e 100644
--- a/storage/xtradb/include/pars0pars.h
+++ b/storage/xtradb/include/pars0pars.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/pars0pars.h
SQL parser
Created 11/19/1996 Heikki Tuuri
@@ -33,18 +34,19 @@ Created 11/19/1996 Heikki Tuuri
#include "trx0types.h"
#include "ut0vec.h"
-/* Type of the user functions. The first argument is always InnoDB-supplied
+/** Type of the user functions. The first argument is always InnoDB-supplied
and varies in type, while 'user_arg' is a user-supplied argument. The
meaning of the return type also varies. See the individual use cases, e.g.
the FETCH statement, for details on them. */
typedef void* (*pars_user_func_cb_t)(void* arg, void* user_arg);
+/** If the following is set TRUE, the parser will emit debugging
+information */
extern int yydebug;
-/* If the following is set TRUE, the lexer will print the SQL string
-as it tokenizes it */
-
#ifdef UNIV_SQL_DEBUG
+/** If the following is set TRUE, the lexer will print the SQL string
+as it tokenizes it */
extern ibool pars_print_lexed;
#endif /* UNIV_SQL_DEBUG */
@@ -93,315 +95,309 @@ extern ulint pars_star_denoter;
int
yyparse(void);
-/*****************************************************************
-Parses an SQL string returning the query graph. */
+/*************************************************************//**
+Parses an SQL string returning the query graph.
+@return own: the query graph */
UNIV_INTERN
que_t*
pars_sql(
/*=====*/
- /* out, own: the query graph */
- pars_info_t* info, /* in: extra information, or NULL */
- const char* str); /* in: SQL string */
-/*****************************************************************
+ pars_info_t* info, /*!< in: extra information, or NULL */
+ const char* str); /*!< in: SQL string */
+/*************************************************************//**
Retrieves characters to the lexical analyzer. */
UNIV_INTERN
void
pars_get_lex_chars(
/*===============*/
- char* buf, /* in/out: buffer where to copy */
- int* result, /* out: number of characters copied or EOF */
- int max_size); /* in: maximum number of characters which fit
+ char* buf, /*!< in/out: buffer where to copy */
+ int* result, /*!< out: number of characters copied or EOF */
+ int max_size); /*!< in: maximum number of characters which fit
in the buffer */
-/*****************************************************************
+/*************************************************************//**
Called by yyparse on error. */
UNIV_INTERN
void
yyerror(
/*====*/
- const char* s); /* in: error message string */
-/*************************************************************************
-Parses a variable declaration. */
+ const char* s); /*!< in: error message string */
+/*********************************************************************//**
+Parses a variable declaration.
+@return own: symbol table node of type SYM_VAR */
UNIV_INTERN
sym_node_t*
pars_variable_declaration(
/*======================*/
- /* out, own: symbol table node of type
- SYM_VAR */
- sym_node_t* node, /* in: symbol table node allocated for the
+ sym_node_t* node, /*!< in: symbol table node allocated for the
id of the variable */
- pars_res_word_t* type); /* in: pointer to a type token */
-/*************************************************************************
-Parses a function expression. */
+ pars_res_word_t* type); /*!< in: pointer to a type token */
+/*********************************************************************//**
+Parses a function expression.
+@return own: function node in a query tree */
UNIV_INTERN
func_node_t*
pars_func(
/*======*/
- /* out, own: function node in a query tree */
- que_node_t* res_word,/* in: function name reserved word */
- que_node_t* arg); /* in: first argument in the argument list */
-/*************************************************************************
-Parses an operator expression. */
+ que_node_t* res_word,/*!< in: function name reserved word */
+ que_node_t* arg); /*!< in: first argument in the argument list */
+/*********************************************************************//**
+Parses an operator expression.
+@return own: function node in a query tree */
UNIV_INTERN
func_node_t*
pars_op(
/*====*/
- /* out, own: function node in a query tree */
- int func, /* in: operator token code */
- que_node_t* arg1, /* in: first argument */
- que_node_t* arg2); /* in: second argument or NULL for an unary
+ int func, /*!< in: operator token code */
+ que_node_t* arg1, /*!< in: first argument */
+ que_node_t* arg2); /*!< in: second argument or NULL for an unary
operator */
-/*************************************************************************
-Parses an ORDER BY clause. Order by a single column only is supported. */
+/*********************************************************************//**
+Parses an ORDER BY clause. Order by a single column only is supported.
+@return own: order-by node in a query tree */
UNIV_INTERN
order_node_t*
pars_order_by(
/*==========*/
- /* out, own: order-by node in a query tree */
- sym_node_t* column, /* in: column name */
- pars_res_word_t* asc); /* in: &pars_asc_token or pars_desc_token */
-/*************************************************************************
+ sym_node_t* column, /*!< in: column name */
+ pars_res_word_t* asc); /*!< in: &pars_asc_token or pars_desc_token */
+/*********************************************************************//**
Parses a select list; creates a query graph node for the whole SELECT
-statement. */
+statement.
+@return own: select node in a query tree */
UNIV_INTERN
sel_node_t*
pars_select_list(
/*=============*/
- /* out, own: select node in a query
- tree */
- que_node_t* select_list, /* in: select list */
- sym_node_t* into_list); /* in: variables list or NULL */
-/*************************************************************************
-Parses a cursor declaration. */
+ que_node_t* select_list, /*!< in: select list */
+ sym_node_t* into_list); /*!< in: variables list or NULL */
+/*********************************************************************//**
+Parses a cursor declaration.
+@return sym_node */
UNIV_INTERN
que_node_t*
pars_cursor_declaration(
/*====================*/
- /* out: sym_node */
- sym_node_t* sym_node, /* in: cursor id node in the symbol
+ sym_node_t* sym_node, /*!< in: cursor id node in the symbol
table */
- sel_node_t* select_node); /* in: select node */
-/*************************************************************************
-Parses a function declaration. */
+ sel_node_t* select_node); /*!< in: select node */
+/*********************************************************************//**
+Parses a function declaration.
+@return sym_node */
UNIV_INTERN
que_node_t*
pars_function_declaration(
/*======================*/
- /* out: sym_node */
- sym_node_t* sym_node); /* in: function id node in the symbol
+ sym_node_t* sym_node); /*!< in: function id node in the symbol
table */
-/*************************************************************************
-Parses a select statement. */
+/*********************************************************************//**
+Parses a select statement.
+@return own: select node in a query tree */
UNIV_INTERN
sel_node_t*
pars_select_statement(
/*==================*/
- /* out, own: select node in a query
- tree */
- sel_node_t* select_node, /* in: select node already containing
+ sel_node_t* select_node, /*!< in: select node already containing
the select list */
- sym_node_t* table_list, /* in: table list */
- que_node_t* search_cond, /* in: search condition or NULL */
- pars_res_word_t* for_update, /* in: NULL or &pars_update_token */
- pars_res_word_t* consistent_read,/* in: NULL or
+ sym_node_t* table_list, /*!< in: table list */
+ que_node_t* search_cond, /*!< in: search condition or NULL */
+ pars_res_word_t* for_update, /*!< in: NULL or &pars_update_token */
+ pars_res_word_t* consistent_read,/*!< in: NULL or
&pars_consistent_token */
- order_node_t* order_by); /* in: NULL or an order-by node */
-/*************************************************************************
-Parses a column assignment in an update. */
+ order_node_t* order_by); /*!< in: NULL or an order-by node */
+/*********************************************************************//**
+Parses a column assignment in an update.
+@return column assignment node */
UNIV_INTERN
col_assign_node_t*
pars_column_assignment(
/*===================*/
- /* out: column assignment node */
- sym_node_t* column, /* in: column to assign */
- que_node_t* exp); /* in: value to assign */
-/*************************************************************************
-Parses a delete or update statement start. */
+ sym_node_t* column, /*!< in: column to assign */
+ que_node_t* exp); /*!< in: value to assign */
+/*********************************************************************//**
+Parses a delete or update statement start.
+@return own: update node in a query tree */
UNIV_INTERN
upd_node_t*
pars_update_statement_start(
/*========================*/
- /* out, own: update node in a query
- tree */
- ibool is_delete, /* in: TRUE if delete */
- sym_node_t* table_sym, /* in: table name node */
- col_assign_node_t* col_assign_list);/* in: column assignment list, NULL
+ ibool is_delete, /*!< in: TRUE if delete */
+ sym_node_t* table_sym, /*!< in: table name node */
+ col_assign_node_t* col_assign_list);/*!< in: column assignment list, NULL
if delete */
-/*************************************************************************
-Parses an update or delete statement. */
+/*********************************************************************//**
+Parses an update or delete statement.
+@return own: update node in a query tree */
UNIV_INTERN
upd_node_t*
pars_update_statement(
/*==================*/
- /* out, own: update node in a query
- tree */
- upd_node_t* node, /* in: update node */
- sym_node_t* cursor_sym, /* in: pointer to a cursor entry in
+ upd_node_t* node, /*!< in: update node */
+ sym_node_t* cursor_sym, /*!< in: pointer to a cursor entry in
the symbol table or NULL */
- que_node_t* search_cond); /* in: search condition or NULL */
-/*************************************************************************
-Parses an insert statement. */
+ que_node_t* search_cond); /*!< in: search condition or NULL */
+/*********************************************************************//**
+Parses an insert statement.
+@return own: update node in a query tree */
UNIV_INTERN
ins_node_t*
pars_insert_statement(
/*==================*/
- /* out, own: update node in a query
- tree */
- sym_node_t* table_sym, /* in: table name node */
- que_node_t* values_list, /* in: value expression list or NULL */
- sel_node_t* select); /* in: select condition or NULL */
-/*************************************************************************
-Parses a procedure parameter declaration. */
+ sym_node_t* table_sym, /*!< in: table name node */
+ que_node_t* values_list, /*!< in: value expression list or NULL */
+ sel_node_t* select); /*!< in: select condition or NULL */
+/*********************************************************************//**
+Parses a procedure parameter declaration.
+@return own: symbol table node of type SYM_VAR */
UNIV_INTERN
sym_node_t*
pars_parameter_declaration(
/*=======================*/
- /* out, own: symbol table node of type
- SYM_VAR */
- sym_node_t* node, /* in: symbol table node allocated for the
+ sym_node_t* node, /*!< in: symbol table node allocated for the
id of the parameter */
ulint param_type,
- /* in: PARS_INPUT or PARS_OUTPUT */
- pars_res_word_t* type); /* in: pointer to a type token */
-/*************************************************************************
-Parses an elsif element. */
+ /*!< in: PARS_INPUT or PARS_OUTPUT */
+ pars_res_word_t* type); /*!< in: pointer to a type token */
+/*********************************************************************//**
+Parses an elsif element.
+@return elsif node */
UNIV_INTERN
elsif_node_t*
pars_elsif_element(
/*===============*/
- /* out: elsif node */
- que_node_t* cond, /* in: if-condition */
- que_node_t* stat_list); /* in: statement list */
-/*************************************************************************
-Parses an if-statement. */
+ que_node_t* cond, /*!< in: if-condition */
+ que_node_t* stat_list); /*!< in: statement list */
+/*********************************************************************//**
+Parses an if-statement.
+@return if-statement node */
UNIV_INTERN
if_node_t*
pars_if_statement(
/*==============*/
- /* out: if-statement node */
- que_node_t* cond, /* in: if-condition */
- que_node_t* stat_list, /* in: statement list */
- que_node_t* else_part); /* in: else-part statement list */
-/*************************************************************************
-Parses a for-loop-statement. */
+ que_node_t* cond, /*!< in: if-condition */
+ que_node_t* stat_list, /*!< in: statement list */
+ que_node_t* else_part); /*!< in: else-part statement list */
+/*********************************************************************//**
+Parses a for-loop-statement.
+@return for-statement node */
UNIV_INTERN
for_node_t*
pars_for_statement(
/*===============*/
- /* out: for-statement node */
- sym_node_t* loop_var, /* in: loop variable */
- que_node_t* loop_start_limit,/* in: loop start expression */
- que_node_t* loop_end_limit, /* in: loop end expression */
- que_node_t* stat_list); /* in: statement list */
-/*************************************************************************
-Parses a while-statement. */
+ sym_node_t* loop_var, /*!< in: loop variable */
+ que_node_t* loop_start_limit,/*!< in: loop start expression */
+ que_node_t* loop_end_limit, /*!< in: loop end expression */
+ que_node_t* stat_list); /*!< in: statement list */
+/*********************************************************************//**
+Parses a while-statement.
+@return while-statement node */
UNIV_INTERN
while_node_t*
pars_while_statement(
/*=================*/
- /* out: while-statement node */
- que_node_t* cond, /* in: while-condition */
- que_node_t* stat_list); /* in: statement list */
-/*************************************************************************
-Parses an exit statement. */
+ que_node_t* cond, /*!< in: while-condition */
+ que_node_t* stat_list); /*!< in: statement list */
+/*********************************************************************//**
+Parses an exit statement.
+@return exit statement node */
UNIV_INTERN
exit_node_t*
pars_exit_statement(void);
/*=====================*/
- /* out: exit statement node */
-/*************************************************************************
-Parses a return-statement. */
+/*********************************************************************//**
+Parses a return-statement.
+@return return-statement node */
UNIV_INTERN
return_node_t*
pars_return_statement(void);
/*=======================*/
- /* out: return-statement node */
-/*************************************************************************
-Parses a procedure call. */
+/*********************************************************************//**
+Parses a procedure call.
+@return function node */
UNIV_INTERN
func_node_t*
pars_procedure_call(
/*================*/
- /* out: function node */
- que_node_t* res_word,/* in: procedure name reserved word */
- que_node_t* args); /* in: argument list */
-/*************************************************************************
-Parses an assignment statement. */
+ que_node_t* res_word,/*!< in: procedure name reserved word */
+ que_node_t* args); /*!< in: argument list */
+/*********************************************************************//**
+Parses an assignment statement.
+@return assignment statement node */
UNIV_INTERN
assign_node_t*
pars_assignment_statement(
/*======================*/
- /* out: assignment statement node */
- sym_node_t* var, /* in: variable to assign */
- que_node_t* val); /* in: value to assign */
-/*************************************************************************
+ sym_node_t* var, /*!< in: variable to assign */
+ que_node_t* val); /*!< in: value to assign */
+/*********************************************************************//**
Parses a fetch statement. into_list or user_func (but not both) must be
-non-NULL. */
+non-NULL.
+@return fetch statement node */
UNIV_INTERN
fetch_node_t*
pars_fetch_statement(
/*=================*/
- /* out: fetch statement node */
- sym_node_t* cursor, /* in: cursor node */
- sym_node_t* into_list, /* in: variables to set, or NULL */
- sym_node_t* user_func); /* in: user function name, or NULL */
-/*************************************************************************
-Parses an open or close cursor statement. */
+ sym_node_t* cursor, /*!< in: cursor node */
+ sym_node_t* into_list, /*!< in: variables to set, or NULL */
+ sym_node_t* user_func); /*!< in: user function name, or NULL */
+/*********************************************************************//**
+Parses an open or close cursor statement.
+@return fetch statement node */
UNIV_INTERN
open_node_t*
pars_open_statement(
/*================*/
- /* out: fetch statement node */
- ulint type, /* in: ROW_SEL_OPEN_CURSOR
+ ulint type, /*!< in: ROW_SEL_OPEN_CURSOR
or ROW_SEL_CLOSE_CURSOR */
- sym_node_t* cursor); /* in: cursor node */
-/*************************************************************************
-Parses a row_printf-statement. */
+ sym_node_t* cursor); /*!< in: cursor node */
+/*********************************************************************//**
+Parses a row_printf-statement.
+@return row_printf-statement node */
UNIV_INTERN
row_printf_node_t*
pars_row_printf_statement(
/*======================*/
- /* out: row_printf-statement node */
- sel_node_t* sel_node); /* in: select node */
-/*************************************************************************
-Parses a commit statement. */
+ sel_node_t* sel_node); /*!< in: select node */
+/*********************************************************************//**
+Parses a commit statement.
+@return own: commit node struct */
UNIV_INTERN
commit_node_t*
pars_commit_statement(void);
/*=======================*/
-/*************************************************************************
-Parses a rollback statement. */
+/*********************************************************************//**
+Parses a rollback statement.
+@return own: rollback node struct */
UNIV_INTERN
roll_node_t*
pars_rollback_statement(void);
/*=========================*/
-/*************************************************************************
-Parses a column definition at a table creation. */
+/*********************************************************************//**
+Parses a column definition at a table creation.
+@return column sym table node */
UNIV_INTERN
sym_node_t*
pars_column_def(
/*============*/
- /* out: column sym table
- node */
- sym_node_t* sym_node, /* in: column node in the
+ sym_node_t* sym_node, /*!< in: column node in the
symbol table */
- pars_res_word_t* type, /* in: data type */
- sym_node_t* len, /* in: length of column, or
+ pars_res_word_t* type, /*!< in: data type */
+ sym_node_t* len, /*!< in: length of column, or
NULL */
- void* is_unsigned, /* in: if not NULL, column
+ void* is_unsigned, /*!< in: if not NULL, column
is of type UNSIGNED. */
- void* is_not_null); /* in: if not NULL, column
+ void* is_not_null); /*!< in: if not NULL, column
is of type NOT NULL. */
-/*************************************************************************
-Parses a table creation operation. */
+/*********************************************************************//**
+Parses a table creation operation.
+@return table create subgraph */
UNIV_INTERN
tab_node_t*
pars_create_table(
/*==============*/
- /* out: table create subgraph */
- sym_node_t* table_sym, /* in: table name node in the symbol
+ sym_node_t* table_sym, /*!< in: table name node in the symbol
table */
- sym_node_t* column_defs, /* in: list of column names */
- void* not_fit_in_memory);/* in: a non-NULL pointer means that
+ sym_node_t* column_defs, /*!< in: list of column names */
+ void* not_fit_in_memory);/*!< in: a non-NULL pointer means that
this is a table which in simulations
should be simulated as not fitting
in memory; thread is put to sleep
@@ -411,99 +407,99 @@ pars_create_table(
will forget about non-NULL value if
it has to reload the table definition
from disk */
-/*************************************************************************
-Parses an index creation operation. */
+/*********************************************************************//**
+Parses an index creation operation.
+@return index create subgraph */
UNIV_INTERN
ind_node_t*
pars_create_index(
/*==============*/
- /* out: index create subgraph */
- pars_res_word_t* unique_def, /* in: not NULL if a unique index */
- pars_res_word_t* clustered_def, /* in: not NULL if a clustered index */
- sym_node_t* index_sym, /* in: index name node in the symbol
+ pars_res_word_t* unique_def, /*!< in: not NULL if a unique index */
+ pars_res_word_t* clustered_def, /*!< in: not NULL if a clustered index */
+ sym_node_t* index_sym, /*!< in: index name node in the symbol
table */
- sym_node_t* table_sym, /* in: table name node in the symbol
+ sym_node_t* table_sym, /*!< in: table name node in the symbol
table */
- sym_node_t* column_list); /* in: list of column names */
-/*************************************************************************
-Parses a procedure definition. */
+ sym_node_t* column_list); /*!< in: list of column names */
+/*********************************************************************//**
+Parses a procedure definition.
+@return query fork node */
UNIV_INTERN
que_fork_t*
pars_procedure_definition(
/*======================*/
- /* out: query fork node */
- sym_node_t* sym_node, /* in: procedure id node in the symbol
+ sym_node_t* sym_node, /*!< in: procedure id node in the symbol
table */
- sym_node_t* param_list, /* in: parameter declaration list */
- que_node_t* stat_list); /* in: statement list */
+ sym_node_t* param_list, /*!< in: parameter declaration list */
+ que_node_t* stat_list); /*!< in: statement list */
-/*****************************************************************
+/*************************************************************//**
Parses a stored procedure call, when this is not within another stored
procedure, that is, the client issues a procedure call directly.
In MySQL/InnoDB, stored InnoDB procedures are invoked via the
-parsed procedure tree, not via InnoDB SQL, so this function is not used. */
+parsed procedure tree, not via InnoDB SQL, so this function is not used.
+@return query graph */
UNIV_INTERN
que_fork_t*
pars_stored_procedure_call(
/*=======================*/
- /* out: query graph */
- sym_node_t* sym_node); /* in: stored procedure name */
-/**********************************************************************
+ sym_node_t* sym_node); /*!< in: stored procedure name */
+/******************************************************************//**
Completes a query graph by adding query thread and fork nodes
above it and prepares the graph for running. The fork created is of
-type QUE_FORK_MYSQL_INTERFACE. */
+type QUE_FORK_MYSQL_INTERFACE.
+@return query thread node to run */
UNIV_INTERN
que_thr_t*
pars_complete_graph_for_exec(
/*=========================*/
- /* out: query thread node to run */
- que_node_t* node, /* in: root node for an incomplete
+ que_node_t* node, /*!< in: root node for an incomplete
query graph */
- trx_t* trx, /* in: transaction handle */
- mem_heap_t* heap); /* in: memory heap from which allocated */
+ trx_t* trx, /*!< in: transaction handle */
+ mem_heap_t* heap); /*!< in: memory heap from which allocated */
-/********************************************************************
-Create parser info struct.*/
+/****************************************************************//**
+Create parser info struct.
+@return own: info struct */
UNIV_INTERN
pars_info_t*
pars_info_create(void);
/*==================*/
- /* out, own: info struct */
-/********************************************************************
-Free info struct and everything it contains.*/
+/****************************************************************//**
+Free info struct and everything it contains. */
UNIV_INTERN
void
pars_info_free(
/*===========*/
- pars_info_t* info); /* in: info struct */
+ pars_info_t* info); /*!< in, own: info struct */
-/********************************************************************
+/****************************************************************//**
Add bound literal. */
UNIV_INTERN
void
pars_info_add_literal(
/*==================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- const void* address, /* in: address */
- ulint length, /* in: length of data */
- ulint type, /* in: type, e.g. DATA_FIXBINARY */
- ulint prtype); /* in: precise type, e.g.
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ const void* address, /*!< in: address */
+ ulint length, /*!< in: length of data */
+ ulint type, /*!< in: type, e.g. DATA_FIXBINARY */
+ ulint prtype); /*!< in: precise type, e.g.
DATA_UNSIGNED */
-/********************************************************************
+/****************************************************************//**
Equivalent to pars_info_add_literal(info, name, str, strlen(str),
DATA_VARCHAR, DATA_ENGLISH). */
UNIV_INTERN
void
pars_info_add_str_literal(
/*======================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- const char* str); /* in: string */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ const char* str); /*!< in: string */
-/********************************************************************
+/****************************************************************//**
Equivalent to:
char buf[4];
@@ -516,11 +512,11 @@ UNIV_INTERN
void
pars_info_add_int4_literal(
/*=======================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- lint val); /* in: value */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ lint val); /*!< in: value */
-/********************************************************************
+/****************************************************************//**
Equivalent to:
char buf[8];
@@ -533,212 +529,211 @@ UNIV_INTERN
void
pars_info_add_dulint_literal(
/*=========================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- dulint val); /* in: value */
-/********************************************************************
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ dulint val); /*!< in: value */
+/****************************************************************//**
Add user function. */
UNIV_INTERN
void
pars_info_add_function(
/*===================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: function name */
- pars_user_func_cb_t func, /* in: function address */
- void* arg); /* in: user-supplied argument */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: function name */
+ pars_user_func_cb_t func, /*!< in: function address */
+ void* arg); /*!< in: user-supplied argument */
-/********************************************************************
+/****************************************************************//**
Add bound id. */
UNIV_INTERN
void
pars_info_add_id(
/*=============*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- const char* id); /* in: id */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ const char* id); /*!< in: id */
-/********************************************************************
-Get user function with the given name.*/
+/****************************************************************//**
+Get user function with the given name.
+@return user func, or NULL if not found */
UNIV_INTERN
pars_user_func_t*
pars_info_get_user_func(
/*====================*/
- /* out: user func, or NULL if not
- found */
- pars_info_t* info, /* in: info struct */
- const char* name); /* in: function name to find*/
+ pars_info_t* info, /*!< in: info struct */
+ const char* name); /*!< in: function name to find*/
-/********************************************************************
-Get bound literal with the given name.*/
+/****************************************************************//**
+Get bound literal with the given name.
+@return bound literal, or NULL if not found */
UNIV_INTERN
pars_bound_lit_t*
pars_info_get_bound_lit(
/*====================*/
- /* out: bound literal, or NULL if
- not found */
- pars_info_t* info, /* in: info struct */
- const char* name); /* in: bound literal name to find */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name); /*!< in: bound literal name to find */
-/********************************************************************
-Get bound id with the given name.*/
+/****************************************************************//**
+Get bound id with the given name.
+@return bound id, or NULL if not found */
UNIV_INTERN
pars_bound_id_t*
pars_info_get_bound_id(
/*===================*/
- /* out: bound id, or NULL if not
- found */
- pars_info_t* info, /* in: info struct */
- const char* name); /* in: bound id name to find */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name); /*!< in: bound id name to find */
-/* Extra information supplied for pars_sql(). */
+/** Extra information supplied for pars_sql(). */
struct pars_info_struct {
- mem_heap_t* heap; /* our own memory heap */
+ mem_heap_t* heap; /*!< our own memory heap */
- ib_vector_t* funcs; /* user functions, or NUll
+ ib_vector_t* funcs; /*!< user functions, or NUll
(pars_user_func_t*) */
- ib_vector_t* bound_lits; /* bound literals, or NULL
+ ib_vector_t* bound_lits; /*!< bound literals, or NULL
(pars_bound_lit_t*) */
- ib_vector_t* bound_ids; /* bound ids, or NULL
+ ib_vector_t* bound_ids; /*!< bound ids, or NULL
(pars_bound_id_t*) */
- ibool graph_owns_us; /* if TRUE (which is the default),
+ ibool graph_owns_us; /*!< if TRUE (which is the default),
que_graph_free() will free us */
};
-/* User-supplied function and argument. */
+/** User-supplied function and argument. */
struct pars_user_func_struct {
- const char* name; /* function name */
- pars_user_func_cb_t func; /* function address */
- void* arg; /* user-supplied argument */
+ const char* name; /*!< function name */
+ pars_user_func_cb_t func; /*!< function address */
+ void* arg; /*!< user-supplied argument */
};
-/* Bound literal. */
+/** Bound literal. */
struct pars_bound_lit_struct {
- const char* name; /* name */
- const void* address; /* address */
- ulint length; /* length of data */
- ulint type; /* type, e.g. DATA_FIXBINARY */
- ulint prtype; /* precise type, e.g. DATA_UNSIGNED */
+ const char* name; /*!< name */
+ const void* address; /*!< address */
+ ulint length; /*!< length of data */
+ ulint type; /*!< type, e.g. DATA_FIXBINARY */
+ ulint prtype; /*!< precise type, e.g. DATA_UNSIGNED */
};
-/* Bound id. */
+/** Bound identifier. */
struct pars_bound_id_struct {
- const char* name; /* name */
- const char* id; /* id */
+ const char* name; /*!< name */
+ const char* id; /*!< identifier */
};
-/* Struct used to denote a reserved word in a parsing tree */
+/** Struct used to denote a reserved word in a parsing tree */
struct pars_res_word_struct{
- int code; /* the token code for the reserved word from
+ int code; /*!< the token code for the reserved word from
pars0grm.h */
};
-/* A predefined function or operator node in a parsing tree; this construct
+/** A predefined function or operator node in a parsing tree; this construct
is also used for some non-functions like the assignment ':=' */
struct func_node_struct{
- que_common_t common; /* type: QUE_NODE_FUNC */
- int func; /* token code of the function name */
- ulint class; /* class of the function */
- que_node_t* args; /* argument(s) of the function */
+ que_common_t common; /*!< type: QUE_NODE_FUNC */
+ int func; /*!< token code of the function name */
+ ulint class; /*!< class of the function */
+ que_node_t* args; /*!< argument(s) of the function */
UT_LIST_NODE_T(func_node_t) cond_list;
- /* list of comparison conditions; defined
+ /*!< list of comparison conditions; defined
only for comparison operator nodes except,
presently, for OPT_SCROLL_TYPE ones */
UT_LIST_NODE_T(func_node_t) func_node_list;
- /* list of function nodes in a parsed
+ /*!< list of function nodes in a parsed
query graph */
};
-/* An order-by node in a select */
+/** An order-by node in a select */
struct order_node_struct{
- que_common_t common; /* type: QUE_NODE_ORDER */
- sym_node_t* column; /* order-by column */
- ibool asc; /* TRUE if ascending, FALSE if descending */
+ que_common_t common; /*!< type: QUE_NODE_ORDER */
+ sym_node_t* column; /*!< order-by column */
+ ibool asc; /*!< TRUE if ascending, FALSE if descending */
};
-/* Procedure definition node */
+/** Procedure definition node */
struct proc_node_struct{
- que_common_t common; /* type: QUE_NODE_PROC */
- sym_node_t* proc_id; /* procedure name symbol in the symbol
+ que_common_t common; /*!< type: QUE_NODE_PROC */
+ sym_node_t* proc_id; /*!< procedure name symbol in the symbol
table of this same procedure */
- sym_node_t* param_list; /* input and output parameters */
- que_node_t* stat_list; /* statement list */
- sym_tab_t* sym_tab; /* symbol table of this procedure */
+ sym_node_t* param_list; /*!< input and output parameters */
+ que_node_t* stat_list; /*!< statement list */
+ sym_tab_t* sym_tab; /*!< symbol table of this procedure */
};
-/* elsif-element node */
+/** elsif-element node */
struct elsif_node_struct{
- que_common_t common; /* type: QUE_NODE_ELSIF */
- que_node_t* cond; /* if condition */
- que_node_t* stat_list; /* statement list */
+ que_common_t common; /*!< type: QUE_NODE_ELSIF */
+ que_node_t* cond; /*!< if condition */
+ que_node_t* stat_list; /*!< statement list */
};
-/* if-statement node */
+/** if-statement node */
struct if_node_struct{
- que_common_t common; /* type: QUE_NODE_IF */
- que_node_t* cond; /* if condition */
- que_node_t* stat_list; /* statement list */
- que_node_t* else_part; /* else-part statement list */
- elsif_node_t* elsif_list; /* elsif element list */
+ que_common_t common; /*!< type: QUE_NODE_IF */
+ que_node_t* cond; /*!< if condition */
+ que_node_t* stat_list; /*!< statement list */
+ que_node_t* else_part; /*!< else-part statement list */
+ elsif_node_t* elsif_list; /*!< elsif element list */
};
-/* while-statement node */
+/** while-statement node */
struct while_node_struct{
- que_common_t common; /* type: QUE_NODE_WHILE */
- que_node_t* cond; /* while condition */
- que_node_t* stat_list; /* statement list */
+ que_common_t common; /*!< type: QUE_NODE_WHILE */
+ que_node_t* cond; /*!< while condition */
+ que_node_t* stat_list; /*!< statement list */
};
-/* for-loop-statement node */
+/** for-loop-statement node */
struct for_node_struct{
- que_common_t common; /* type: QUE_NODE_FOR */
- sym_node_t* loop_var; /* loop variable: this is the
+ que_common_t common; /*!< type: QUE_NODE_FOR */
+ sym_node_t* loop_var; /*!< loop variable: this is the
dereferenced symbol from the
variable declarations, not the
symbol occurrence in the for loop
definition */
- que_node_t* loop_start_limit;/* initial value of loop variable */
- que_node_t* loop_end_limit; /* end value of loop variable */
- lint loop_end_value; /* evaluated value for the end value:
+ que_node_t* loop_start_limit;/*!< initial value of loop variable */
+ que_node_t* loop_end_limit; /*!< end value of loop variable */
+ lint loop_end_value; /*!< evaluated value for the end value:
it is calculated only when the loop
is entered, and will not change within
the loop */
- que_node_t* stat_list; /* statement list */
+ que_node_t* stat_list; /*!< statement list */
};
-/* exit statement node */
+/** exit statement node */
struct exit_node_struct{
- que_common_t common; /* type: QUE_NODE_EXIT */
+ que_common_t common; /*!< type: QUE_NODE_EXIT */
};
-/* return-statement node */
+/** return-statement node */
struct return_node_struct{
- que_common_t common; /* type: QUE_NODE_RETURN */
+ que_common_t common; /*!< type: QUE_NODE_RETURN */
};
-/* Assignment statement node */
+/** Assignment statement node */
struct assign_node_struct{
- que_common_t common; /* type: QUE_NODE_ASSIGNMENT */
- sym_node_t* var; /* variable to set */
- que_node_t* val; /* value to assign */
+ que_common_t common; /*!< type: QUE_NODE_ASSIGNMENT */
+ sym_node_t* var; /*!< variable to set */
+ que_node_t* val; /*!< value to assign */
};
-/* Column assignment node */
+/** Column assignment node */
struct col_assign_node_struct{
- que_common_t common; /* type: QUE_NODE_COL_ASSIGN */
- sym_node_t* col; /* column to set */
- que_node_t* val; /* value to assign */
+ que_common_t common; /*!< type: QUE_NODE_COL_ASSIGN */
+ sym_node_t* col; /*!< column to set */
+ que_node_t* val; /*!< value to assign */
};
-/* Classes of functions */
-#define PARS_FUNC_ARITH 1 /* +, -, *, / */
-#define PARS_FUNC_LOGICAL 2
-#define PARS_FUNC_CMP 3
-#define PARS_FUNC_PREDEFINED 4 /* TO_NUMBER, SUBSTR, ... */
-#define PARS_FUNC_AGGREGATE 5 /* COUNT, DISTINCT, SUM */
-#define PARS_FUNC_OTHER 6 /* these are not real functions,
+/** Classes of functions */
+/* @{ */
+#define PARS_FUNC_ARITH 1 /*!< +, -, *, / */
+#define PARS_FUNC_LOGICAL 2 /*!< AND, OR, NOT */
+#define PARS_FUNC_CMP 3 /*!< comparison operators */
+#define PARS_FUNC_PREDEFINED 4 /*!< TO_NUMBER, SUBSTR, ... */
+#define PARS_FUNC_AGGREGATE 5 /*!< COUNT, DISTINCT, SUM */
+#define PARS_FUNC_OTHER 6 /*!< these are not real functions,
e.g., := */
+/* @} */
#ifndef UNIV_NONINL
#include "pars0pars.ic"
diff --git a/storage/xtradb/include/pars0pars.ic b/storage/xtradb/include/pars0pars.ic
index 3a55ad86f48..ae6c13cd671 100644
--- a/storage/xtradb/include/pars0pars.ic
+++ b/storage/xtradb/include/pars0pars.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/pars0pars.ic
SQL parser
Created 11/19/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/pars0sym.h b/storage/xtradb/include/pars0sym.h
index 69227a2917e..6d1a4b82414 100644
--- a/storage/xtradb/include/pars0sym.h
+++ b/storage/xtradb/include/pars0sym.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/pars0sym.h
SQL parser symbol table
Created 12/15/1997 Heikki Tuuri
@@ -32,15 +33,15 @@ Created 12/15/1997 Heikki Tuuri
#include "pars0types.h"
#include "row0types.h"
-/**********************************************************************
-Creates a symbol table for a single stored procedure or query. */
+/******************************************************************//**
+Creates a symbol table for a single stored procedure or query.
+@return own: symbol table */
UNIV_INTERN
sym_tab_t*
sym_tab_create(
/*===========*/
- /* out, own: symbol table */
- mem_heap_t* heap); /* in: memory heap where to create */
-/**********************************************************************
+ mem_heap_t* heap); /*!< in: memory heap where to create */
+/******************************************************************//**
Frees the memory allocated dynamically AFTER parsing phase for variables
etc. in the symbol table. Does not free the mem heap where the table was
originally created. Frees also SQL explicit cursor definitions. */
@@ -48,71 +49,89 @@ UNIV_INTERN
void
sym_tab_free_private(
/*=================*/
- sym_tab_t* sym_tab); /* in, own: symbol table */
-/**********************************************************************
-Adds an integer literal to a symbol table. */
+ sym_tab_t* sym_tab); /*!< in, own: symbol table */
+/******************************************************************//**
+Adds an integer literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_int_lit(
/*================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- ulint val); /* in: integer value */
-/**********************************************************************
-Adds an string literal to a symbol table. */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ ulint val); /*!< in: integer value */
+/******************************************************************//**
+Adds an string literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_str_lit(
/*================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- byte* str, /* in: string with no quotes around
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ byte* str, /*!< in: string with no quotes around
it */
- ulint len); /* in: string length */
-/**********************************************************************
-Add a bound literal to a symbol table. */
+ ulint len); /*!< in: string length */
+/******************************************************************//**
+Add a bound literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_bound_lit(
/*==================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- const char* name, /* in: name of bound literal */
- ulint* lit_type); /* out: type of literal (PARS_*_LIT) */
-/**********************************************************************
-Adds an SQL null literal to a symbol table. */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ const char* name, /*!< in: name of bound literal */
+ ulint* lit_type); /*!< out: type of literal (PARS_*_LIT) */
+/******************************************************************//**
+Adds an SQL null literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_null_lit(
/*=================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab); /* in: symbol table */
-/**********************************************************************
-Adds an identifier to a symbol table. */
+ sym_tab_t* sym_tab); /*!< in: symbol table */
+/******************************************************************//**
+Adds an identifier to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_id(
/*===========*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- byte* name, /* in: identifier name */
- ulint len); /* in: identifier length */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ byte* name, /*!< in: identifier name */
+ ulint len); /*!< in: identifier length */
-/**********************************************************************
-Add a bound identifier to a symbol table. */
+/******************************************************************//**
+Add a bound identifier to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_bound_id(
/*===========*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- const char* name); /* in: name of bound id */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ const char* name); /*!< in: name of bound id */
+/** Index of sym_node_struct::field_nos corresponding to the clustered index */
#define SYM_CLUST_FIELD_NO 0
+/** Index of sym_node_struct::field_nos corresponding to a secondary index */
#define SYM_SEC_FIELD_NO 1
+/** Types of a symbol table node */
+enum sym_tab_entry {
+ SYM_VAR = 91, /*!< declared parameter or local
+ variable of a procedure */
+ SYM_IMPLICIT_VAR, /*!< storage for a intermediate result
+ of a calculation */
+ SYM_LIT, /*!< literal */
+ SYM_TABLE, /*!< database table name */
+ SYM_COLUMN, /*!< database table name */
+ SYM_CURSOR, /*!< named cursor */
+ SYM_PROCEDURE_NAME, /*!< stored procedure name */
+ SYM_INDEX, /*!< database index name */
+ SYM_FUNCTION /*!< user function name */
+};
+
+/** Symbol table node */
struct sym_node_struct{
- que_common_t common; /* node type:
+ que_common_t common; /*!< node type:
QUE_NODE_SYMBOL */
/* NOTE: if the data field in 'common.val' is not NULL and the symbol
table node is not for a temporary column, the memory for the value has
@@ -132,25 +151,25 @@ struct sym_node_struct{
TODO: It would be cleaner to make 'indirection' a boolean field and
always use 'alias' to refer to the primary node. */
- sym_node_t* indirection; /* pointer to
+ sym_node_t* indirection; /*!< pointer to
another symbol table
node which contains
the value for this
node, NULL otherwise */
- sym_node_t* alias; /* pointer to
+ sym_node_t* alias; /*!< pointer to
another symbol table
node for which this
node is an alias,
NULL otherwise */
- UT_LIST_NODE_T(sym_node_t) col_var_list; /* list of table
+ UT_LIST_NODE_T(sym_node_t) col_var_list; /*!< list of table
columns or a list of
input variables for an
explicit cursor */
- ibool copy_val; /* TRUE if a column
+ ibool copy_val; /*!< TRUE if a column
and its value should
be copied to dynamic
memory when fetched */
- ulint field_nos[2]; /* if a column, in
+ ulint field_nos[2]; /*!< if a column, in
the position
SYM_CLUST_FIELD_NO is
the field number in the
@@ -162,76 +181,62 @@ struct sym_node_struct{
use first; if not found
from the index, then
ULINT_UNDEFINED */
- ibool resolved; /* TRUE if the
+ ibool resolved; /*!< TRUE if the
meaning of a variable
or a column has been
resolved; for literals
this is always TRUE */
- ulint token_type; /* SYM_VAR, SYM_COLUMN,
- SYM_IMPLICIT_VAR,
- SYM_LIT, SYM_TABLE,
- SYM_CURSOR, ... */
- const char* name; /* name of an id */
- ulint name_len; /* id name length */
- dict_table_t* table; /* table definition
+ enum sym_tab_entry token_type; /*!< type of the
+ parsed token */
+ const char* name; /*!< name of an id */
+ ulint name_len; /*!< id name length */
+ dict_table_t* table; /*!< table definition
if a table id or a
column id */
- ulint col_no; /* column number if a
+ ulint col_no; /*!< column number if a
column */
- sel_buf_t* prefetch_buf; /* NULL, or a buffer
+ sel_buf_t* prefetch_buf; /*!< NULL, or a buffer
for cached column
values for prefetched
rows */
- sel_node_t* cursor_def; /* cursor definition
+ sel_node_t* cursor_def; /*!< cursor definition
select node if a
named cursor */
- ulint param_type; /* PARS_INPUT,
+ ulint param_type; /*!< PARS_INPUT,
PARS_OUTPUT, or
PARS_NOT_PARAM if not a
procedure parameter */
- sym_tab_t* sym_table; /* back pointer to
+ sym_tab_t* sym_table; /*!< back pointer to
the symbol table */
- UT_LIST_NODE_T(sym_node_t) sym_list; /* list of symbol
+ UT_LIST_NODE_T(sym_node_t) sym_list; /*!< list of symbol
nodes */
};
+/** Symbol table */
struct sym_tab_struct{
que_t* query_graph;
- /* query graph generated by the
+ /*!< query graph generated by the
parser */
const char* sql_string;
- /* SQL string to parse */
+ /*!< SQL string to parse */
size_t string_len;
- /* SQL string length */
+ /*!< SQL string length */
int next_char_pos;
- /* position of the next character in
+ /*!< position of the next character in
sql_string to give to the lexical
analyzer */
- pars_info_t* info; /* extra information, or NULL */
+ pars_info_t* info; /*!< extra information, or NULL */
sym_node_list_t sym_list;
- /* list of symbol nodes in the symbol
+ /*!< list of symbol nodes in the symbol
table */
UT_LIST_BASE_NODE_T(func_node_t)
func_node_list;
- /* list of function nodes in the
+ /*!< list of function nodes in the
parsed query graph */
- mem_heap_t* heap; /* memory heap from which we can
+ mem_heap_t* heap; /*!< memory heap from which we can
allocate space */
};
-/* Types of a symbol table entry */
-#define SYM_VAR 91 /* declared parameter or local
- variable of a procedure */
-#define SYM_IMPLICIT_VAR 92 /* storage for a intermediate result
- of a calculation */
-#define SYM_LIT 93 /* literal */
-#define SYM_TABLE 94 /* database table name */
-#define SYM_COLUMN 95 /* database table name */
-#define SYM_CURSOR 96 /* named cursor */
-#define SYM_PROCEDURE_NAME 97 /* stored procedure name */
-#define SYM_INDEX 98 /* database index name */
-#define SYM_FUNCTION 99 /* user function name */
-
#ifndef UNIV_NONINL
#include "pars0sym.ic"
#endif
diff --git a/storage/xtradb/include/pars0sym.ic b/storage/xtradb/include/pars0sym.ic
index 235d6819ae9..9eb09db3a47 100644
--- a/storage/xtradb/include/pars0sym.ic
+++ b/storage/xtradb/include/pars0sym.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/pars0sym.ic
SQL parser symbol table
Created 12/15/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/pars0types.h b/storage/xtradb/include/pars0types.h
index e0902d0611a..e0a8a86bf07 100644
--- a/storage/xtradb/include/pars0types.h
+++ b/storage/xtradb/include/pars0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/pars0types.h
SQL parser global types
Created 1/11/1998 Heikki Tuuri
diff --git a/storage/xtradb/include/que0que.h b/storage/xtradb/include/que0que.h
index a534cb7e464..420f34550e2 100644
--- a/storage/xtradb/include/que0que.h
+++ b/storage/xtradb/include/que0que.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/que0que.h
Query graph
Created 5/27/1996 Heikki Tuuri
@@ -39,116 +40,106 @@ Created 5/27/1996 Heikki Tuuri
of SQL execution in the UNIV_SQL_DEBUG version */
extern ibool que_trace_on;
-/***************************************************************************
+/***********************************************************************//**
Adds a query graph to the session's list of graphs. */
UNIV_INTERN
void
que_graph_publish(
/*==============*/
- que_t* graph, /* in: graph */
- sess_t* sess); /* in: session */
-/***************************************************************************
-Creates a query graph fork node. */
+ que_t* graph, /*!< in: graph */
+ sess_t* sess); /*!< in: session */
+/***********************************************************************//**
+Creates a query graph fork node.
+@return own: fork node */
UNIV_INTERN
que_fork_t*
que_fork_create(
/*============*/
- /* out, own: fork node */
- que_t* graph, /* in: graph, if NULL then this
+ que_t* graph, /*!< in: graph, if NULL then this
fork node is assumed to be the
graph root */
- que_node_t* parent, /* in: parent node */
- ulint fork_type, /* in: fork type */
- mem_heap_t* heap); /* in: memory heap where created */
-/***************************************************************************
+ que_node_t* parent, /*!< in: parent node */
+ ulint fork_type, /*!< in: fork type */
+ mem_heap_t* heap); /*!< in: memory heap where created */
+/***********************************************************************//**
Gets the first thr in a fork. */
UNIV_INLINE
que_thr_t*
que_fork_get_first_thr(
/*===================*/
- que_fork_t* fork); /* in: query fork */
-/***************************************************************************
+ que_fork_t* fork); /*!< in: query fork */
+/***********************************************************************//**
Gets the child node of the first thr in a fork. */
UNIV_INLINE
que_node_t*
que_fork_get_child(
/*===============*/
- que_fork_t* fork); /* in: query fork */
-/***************************************************************************
+ que_fork_t* fork); /*!< in: query fork */
+/***********************************************************************//**
Sets the parent of a graph node. */
UNIV_INLINE
void
que_node_set_parent(
/*================*/
- que_node_t* node, /* in: graph node */
- que_node_t* parent);/* in: parent */
-/***************************************************************************
-Creates a query graph thread node. */
+ que_node_t* node, /*!< in: graph node */
+ que_node_t* parent);/*!< in: parent */
+/***********************************************************************//**
+Creates a query graph thread node.
+@return own: query thread node */
UNIV_INTERN
que_thr_t*
que_thr_create(
/*===========*/
- /* out, own: query thread node */
- que_fork_t* parent, /* in: parent node, i.e., a fork node */
- mem_heap_t* heap); /* in: memory heap where created */
-/**************************************************************************
-Checks if the query graph is in a state where it should be freed, and
-frees it in that case. If the session is in a state where it should be
-closed, also this is done. */
-UNIV_INTERN
-ibool
-que_graph_try_free(
-/*===============*/
- /* out: TRUE if freed */
- que_t* graph); /* in: query graph */
-/**************************************************************************
+ que_fork_t* parent, /*!< in: parent node, i.e., a fork node */
+ mem_heap_t* heap); /*!< in: memory heap where created */
+/**********************************************************************//**
Frees a query graph, but not the heap where it was created. Does not free
explicit cursor declarations, they are freed in que_graph_free. */
UNIV_INTERN
void
que_graph_free_recursive(
/*=====================*/
- que_node_t* node); /* in: query graph node */
-/**************************************************************************
+ que_node_t* node); /*!< in: query graph node */
+/**********************************************************************//**
Frees a query graph. */
UNIV_INTERN
void
que_graph_free(
/*===========*/
- que_t* graph); /* in: query graph; we assume that the memory
+ que_t* graph); /*!< in: query graph; we assume that the memory
heap where this graph was created is private
to this graph: if not, then use
que_graph_free_recursive and free the heap
afterwards! */
-/**************************************************************************
+/**********************************************************************//**
Stops a query thread if graph or trx is in a state requiring it. The
conditions are tested in the order (1) graph, (2) trx. The kernel mutex has
-to be reserved. */
+to be reserved.
+@return TRUE if stopped */
UNIV_INTERN
ibool
que_thr_stop(
/*=========*/
- /* out: TRUE if stopped */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
Moves a thread from another state to the QUE_THR_RUNNING state. Increments
the n_active_thrs counters of the query graph and transaction. */
UNIV_INTERN
void
que_thr_move_to_run_state_for_mysql(
/*================================*/
- que_thr_t* thr, /* in: an query thread */
- trx_t* trx); /* in: transaction */
-/**************************************************************************
+ que_thr_t* thr, /*!< in: an query thread */
+ trx_t* trx); /*!< in: transaction */
+/**********************************************************************//**
A patch for MySQL used to 'stop' a dummy query thread used in MySQL
select, when there is no error or lock wait. */
UNIV_INTERN
void
que_thr_stop_for_mysql_no_error(
/*============================*/
- que_thr_t* thr, /* in: query thread */
- trx_t* trx); /* in: transaction */
-/**************************************************************************
+ que_thr_t* thr, /*!< in: query thread */
+ trx_t* trx); /*!< in: transaction */
+/**********************************************************************//**
A patch for MySQL used to 'stop' a dummy query thread used in MySQL. The
query thread is stopped and made inactive, except in the case where
it was put to the lock wait state in lock0lock.c, but the lock has already
@@ -157,15 +148,15 @@ UNIV_INTERN
void
que_thr_stop_for_mysql(
/*===================*/
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
Run a query thread. Handles lock waits. */
UNIV_INTERN
void
que_run_threads(
/*============*/
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
After signal handling is finished, returns control to a query graph error
handling routine. (Currently, just returns the control to the root of the
graph so that the graph can communicate an error message to the client.) */
@@ -173,10 +164,10 @@ UNIV_INTERN
void
que_fork_error_handle(
/*==================*/
- trx_t* trx, /* in: trx */
- que_t* fork); /* in: query graph which was run before signal
+ trx_t* trx, /*!< in: trx */
+ que_t* fork); /*!< in: query graph which was run before signal
handling started, NULL not allowed */
-/**************************************************************************
+/**********************************************************************//**
Moves a suspended query thread to the QUE_THR_RUNNING state and releases
a single worker thread to execute it. This function should be used to end
the wait state of a query thread waiting for a lock or a stored procedure
@@ -185,203 +176,199 @@ UNIV_INTERN
void
que_thr_end_wait(
/*=============*/
- que_thr_t* thr, /* in: query thread in the
+ que_thr_t* thr, /*!< in: query thread in the
QUE_THR_LOCK_WAIT,
or QUE_THR_PROCEDURE_WAIT, or
QUE_THR_SIG_REPLY_WAIT state */
- que_thr_t** next_thr); /* in/out: next query thread to run;
+ que_thr_t** next_thr); /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
a new query thread */
-/**************************************************************************
+/**********************************************************************//**
Same as que_thr_end_wait, but no parameter next_thr available. */
UNIV_INTERN
void
que_thr_end_wait_no_next_thr(
/*=========================*/
- que_thr_t* thr); /* in: query thread in the
+ que_thr_t* thr); /*!< in: query thread in the
QUE_THR_LOCK_WAIT,
or QUE_THR_PROCEDURE_WAIT, or
QUE_THR_SIG_REPLY_WAIT state */
-/**************************************************************************
+/**********************************************************************//**
Starts execution of a command in a query fork. Picks a query thread which
is not in the QUE_THR_RUNNING state and moves it to that state. If none
can be chosen, a situation which may arise in parallelized fetches, NULL
-is returned. */
+is returned.
+@return a query thread of the graph moved to QUE_THR_RUNNING state, or
+NULL; the query thread should be executed by que_run_threads by the
+caller */
UNIV_INTERN
que_thr_t*
que_fork_start_command(
/*===================*/
- /* out: a query thread of the graph moved to
- QUE_THR_RUNNING state, or NULL; the query
- thread should be executed by que_run_threads
- by the caller */
- que_fork_t* fork); /* in: a query fork */
-/***************************************************************************
+ que_fork_t* fork); /*!< in: a query fork */
+/***********************************************************************//**
Gets the trx of a query thread. */
UNIV_INLINE
trx_t*
thr_get_trx(
/*========*/
- que_thr_t* thr); /* in: query thread */
-/***************************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/***********************************************************************//**
Gets the type of a graph node. */
UNIV_INLINE
ulint
que_node_get_type(
/*==============*/
- que_node_t* node); /* in: graph node */
-/***************************************************************************
+ que_node_t* node); /*!< in: graph node */
+/***********************************************************************//**
Gets pointer to the value data type field of a graph node. */
UNIV_INLINE
dtype_t*
que_node_get_data_type(
/*===================*/
- que_node_t* node); /* in: graph node */
-/***************************************************************************
+ que_node_t* node); /*!< in: graph node */
+/***********************************************************************//**
Gets pointer to the value dfield of a graph node. */
UNIV_INLINE
dfield_t*
que_node_get_val(
/*=============*/
- que_node_t* node); /* in: graph node */
-/***************************************************************************
-Gets the value buffer size of a graph node. */
+ que_node_t* node); /*!< in: graph node */
+/***********************************************************************//**
+Gets the value buffer size of a graph node.
+@return val buffer size, not defined if val.data == NULL in node */
UNIV_INLINE
ulint
que_node_get_val_buf_size(
/*======================*/
- /* out: val buffer size, not defined if
- val.data == NULL in node */
- que_node_t* node); /* in: graph node */
-/***************************************************************************
+ que_node_t* node); /*!< in: graph node */
+/***********************************************************************//**
Sets the value buffer size of a graph node. */
UNIV_INLINE
void
que_node_set_val_buf_size(
/*======================*/
- que_node_t* node, /* in: graph node */
- ulint size); /* in: size */
-/*************************************************************************
+ que_node_t* node, /*!< in: graph node */
+ ulint size); /*!< in: size */
+/*********************************************************************//**
Gets the next list node in a list of query graph nodes. */
UNIV_INLINE
que_node_t*
que_node_get_next(
/*==============*/
- que_node_t* node); /* in: node in a list */
-/*************************************************************************
-Gets the parent node of a query graph node. */
+ que_node_t* node); /*!< in: node in a list */
+/*********************************************************************//**
+Gets the parent node of a query graph node.
+@return parent node or NULL */
UNIV_INLINE
que_node_t*
que_node_get_parent(
/*================*/
- /* out: parent node or NULL */
- que_node_t* node); /* in: node */
-/********************************************************************
+ que_node_t* node); /*!< in: node */
+/****************************************************************//**
Get the first containing loop node (e.g. while_node_t or for_node_t) for the
-given node, or NULL if the node is not within a loop. */
+given node, or NULL if the node is not within a loop.
+@return containing loop node, or NULL. */
UNIV_INTERN
que_node_t*
que_node_get_containing_loop_node(
/*==============================*/
- /* out: containing loop node, or NULL. */
- que_node_t* node); /* in: node */
-/*************************************************************************
-Catenates a query graph node to a list of them, possible empty list. */
+ que_node_t* node); /*!< in: node */
+/*********************************************************************//**
+Catenates a query graph node to a list of them, possible empty list.
+@return one-way list of nodes */
UNIV_INLINE
que_node_t*
que_node_list_add_last(
/*===================*/
- /* out: one-way list of nodes */
- que_node_t* node_list, /* in: node list, or NULL */
- que_node_t* node); /* in: node */
-/*************************************************************************
-Gets a query graph node list length. */
+ que_node_t* node_list, /*!< in: node list, or NULL */
+ que_node_t* node); /*!< in: node */
+/*********************************************************************//**
+Gets a query graph node list length.
+@return length, for NULL list 0 */
UNIV_INLINE
ulint
que_node_list_get_len(
/*==================*/
- /* out: length, for NULL list 0 */
- que_node_t* node_list); /* in: node list, or NULL */
-/**************************************************************************
+ que_node_t* node_list); /*!< in: node list, or NULL */
+/**********************************************************************//**
Checks if graph, trx, or session is in a state where the query thread should
-be stopped. */
+be stopped.
+@return TRUE if should be stopped; NOTE that if the peek is made
+without reserving the kernel mutex, then another peek with the mutex
+reserved is necessary before deciding the actual stopping */
UNIV_INLINE
ibool
que_thr_peek_stop(
/*==============*/
- /* out: TRUE if should be stopped; NOTE that
- if the peek is made without reserving the
- kernel mutex, then another peek with the
- mutex reserved is necessary before deciding
- the actual stopping */
- que_thr_t* thr); /* in: query thread */
-/***************************************************************************
-Returns TRUE if the query graph is for a SELECT statement. */
+ que_thr_t* thr); /*!< in: query thread */
+/***********************************************************************//**
+Returns TRUE if the query graph is for a SELECT statement.
+@return TRUE if a select */
UNIV_INLINE
ibool
que_graph_is_select(
/*================*/
- /* out: TRUE if a select */
- que_t* graph); /* in: graph */
-/**************************************************************************
+ que_t* graph); /*!< in: graph */
+/**********************************************************************//**
Prints info of an SQL query graph node. */
UNIV_INTERN
void
que_node_print_info(
/*================*/
- que_node_t* node); /* in: query graph node */
-/*************************************************************************
-Evaluate the given SQL */
+ que_node_t* node); /*!< in: query graph node */
+/*********************************************************************//**
+Evaluate the given SQL
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
que_eval_sql(
/*=========*/
- /* out: error code or DB_SUCCESS */
- pars_info_t* info, /* in: info struct, or NULL */
- const char* sql, /* in: SQL string */
+ pars_info_t* info, /*!< in: info struct, or NULL */
+ const char* sql, /*!< in: SQL string */
ibool reserve_dict_mutex,
- /* in: if TRUE, acquire/release
+ /*!< in: if TRUE, acquire/release
dict_sys->mutex around call to pars_sql. */
- trx_t* trx); /* in: trx */
+ trx_t* trx); /*!< in: trx */
/* Query graph query thread node: the fields are protected by the kernel
mutex with the exceptions named below */
struct que_thr_struct{
- que_common_t common; /* type: QUE_NODE_THR */
- ulint magic_n; /* magic number to catch memory
+ que_common_t common; /*!< type: QUE_NODE_THR */
+ ulint magic_n; /*!< magic number to catch memory
corruption */
- que_node_t* child; /* graph child node */
- que_t* graph; /* graph where this node belongs */
- ibool is_active; /* TRUE if the thread has been set
+ que_node_t* child; /*!< graph child node */
+ que_t* graph; /*!< graph where this node belongs */
+ ibool is_active; /*!< TRUE if the thread has been set
to the run state in
que_thr_move_to_run_state, but not
deactivated in
que_thr_dec_reference_count */
- ulint state; /* state of the query thread */
+ ulint state; /*!< state of the query thread */
UT_LIST_NODE_T(que_thr_t)
- thrs; /* list of thread nodes of the fork
+ thrs; /*!< list of thread nodes of the fork
node */
UT_LIST_NODE_T(que_thr_t)
- trx_thrs; /* lists of threads in wait list of
+ trx_thrs; /*!< lists of threads in wait list of
the trx */
UT_LIST_NODE_T(que_thr_t)
- queue; /* list of runnable thread nodes in
+ queue; /*!< list of runnable thread nodes in
the server task queue */
/*------------------------------*/
/* The following fields are private to the OS thread executing the
query thread, and are not protected by the kernel mutex: */
- que_node_t* run_node; /* pointer to the node where the
+ que_node_t* run_node; /*!< pointer to the node where the
subgraph down from this node is
currently executed */
- que_node_t* prev_node; /* pointer to the node from which
+ que_node_t* prev_node; /*!< pointer to the node from which
the control came */
- ulint resource; /* resource usage of the query thread
+ ulint resource; /*!< resource usage of the query thread
thus far */
- ulint lock_state; /* lock state of thread (table or
+ ulint lock_state; /*!< lock state of thread (table or
row) */
};
@@ -390,49 +377,49 @@ struct que_thr_struct{
/* Query graph fork node: its fields are protected by the kernel mutex */
struct que_fork_struct{
- que_common_t common; /* type: QUE_NODE_FORK */
- que_t* graph; /* query graph of this node */
- ulint fork_type; /* fork type */
- ulint n_active_thrs; /* if this is the root of a graph, the
+ que_common_t common; /*!< type: QUE_NODE_FORK */
+ que_t* graph; /*!< query graph of this node */
+ ulint fork_type; /*!< fork type */
+ ulint n_active_thrs; /*!< if this is the root of a graph, the
number query threads that have been
started in que_thr_move_to_run_state
but for which que_thr_dec_refer_count
has not yet been called */
- trx_t* trx; /* transaction: this is set only in
+ trx_t* trx; /*!< transaction: this is set only in
the root node */
- ulint state; /* state of the fork node */
- que_thr_t* caller; /* pointer to a possible calling query
+ ulint state; /*!< state of the fork node */
+ que_thr_t* caller; /*!< pointer to a possible calling query
thread */
UT_LIST_BASE_NODE_T(que_thr_t)
- thrs; /* list of query threads */
+ thrs; /*!< list of query threads */
/*------------------------------*/
/* The fields in this section are defined only in the root node */
- sym_tab_t* sym_tab; /* symbol table of the query,
+ sym_tab_t* sym_tab; /*!< symbol table of the query,
generated by the parser, or NULL
if the graph was created 'by hand' */
- pars_info_t* info; /* in: info struct, or NULL */
+ pars_info_t* info; /*!< info struct, or NULL */
/* The following cur_... fields are relevant only in a select graph */
- ulint cur_end; /* QUE_CUR_NOT_DEFINED, QUE_CUR_START,
+ ulint cur_end; /*!< QUE_CUR_NOT_DEFINED, QUE_CUR_START,
QUE_CUR_END */
- ulint cur_pos; /* if there are n rows in the result
+ ulint cur_pos; /*!< if there are n rows in the result
set, values 0 and n + 1 mean before
first row, or after last row, depending
on cur_end; values 1...n mean a row
index */
- ibool cur_on_row; /* TRUE if cursor is on a row, i.e.,
+ ibool cur_on_row; /*!< TRUE if cursor is on a row, i.e.,
it is not before the first row or
after the last row */
- dulint n_inserts; /* number of rows inserted */
- dulint n_updates; /* number of rows updated */
- dulint n_deletes; /* number of rows deleted */
- sel_node_t* last_sel_node; /* last executed select node, or NULL
+ dulint n_inserts; /*!< number of rows inserted */
+ dulint n_updates; /*!< number of rows updated */
+ dulint n_deletes; /*!< number of rows deleted */
+ sel_node_t* last_sel_node; /*!< last executed select node, or NULL
if none */
UT_LIST_NODE_T(que_fork_t)
- graphs; /* list of query graphs of a session
+ graphs; /*!< list of query graphs of a session
or a stored procedure */
/*------------------------------*/
- mem_heap_t* heap; /* memory heap where the fork was
+ mem_heap_t* heap; /*!< memory heap where the fork was
created */
};
diff --git a/storage/xtradb/include/que0que.ic b/storage/xtradb/include/que0que.ic
index e9a6b00b9ab..a1c0dc1e77a 100644
--- a/storage/xtradb/include/que0que.ic
+++ b/storage/xtradb/include/que0que.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/que0que.ic
Query graph
Created 5/27/1996 Heikki Tuuri
@@ -24,37 +25,37 @@ Created 5/27/1996 Heikki Tuuri
#include "usr0sess.h"
-/***************************************************************************
+/***********************************************************************//**
Gets the trx of a query thread. */
UNIV_INLINE
trx_t*
thr_get_trx(
/*========*/
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ut_ad(thr);
return(thr->graph->trx);
}
-/***************************************************************************
+/***********************************************************************//**
Gets the first thr in a fork. */
UNIV_INLINE
que_thr_t*
que_fork_get_first_thr(
/*===================*/
- que_fork_t* fork) /* in: query fork */
+ que_fork_t* fork) /*!< in: query fork */
{
return(UT_LIST_GET_FIRST(fork->thrs));
}
-/***************************************************************************
+/***********************************************************************//**
Gets the child node of the first thr in a fork. */
UNIV_INLINE
que_node_t*
que_fork_get_child(
/*===============*/
- que_fork_t* fork) /* in: query fork */
+ que_fork_t* fork) /*!< in: query fork */
{
que_thr_t* thr;
@@ -63,97 +64,96 @@ que_fork_get_child(
return(thr->child);
}
-/***************************************************************************
+/***********************************************************************//**
Gets the type of a graph node. */
UNIV_INLINE
ulint
que_node_get_type(
/*==============*/
- que_node_t* node) /* in: graph node */
+ que_node_t* node) /*!< in: graph node */
{
ut_ad(node);
return(((que_common_t*)node)->type);
}
-/***************************************************************************
+/***********************************************************************//**
Gets pointer to the value dfield of a graph node. */
UNIV_INLINE
dfield_t*
que_node_get_val(
/*=============*/
- que_node_t* node) /* in: graph node */
+ que_node_t* node) /*!< in: graph node */
{
ut_ad(node);
return(&(((que_common_t*)node)->val));
}
-/***************************************************************************
-Gets the value buffer size of a graph node. */
+/***********************************************************************//**
+Gets the value buffer size of a graph node.
+@return val buffer size, not defined if val.data == NULL in node */
UNIV_INLINE
ulint
que_node_get_val_buf_size(
/*======================*/
- /* out: val buffer size, not defined if
- val.data == NULL in node */
- que_node_t* node) /* in: graph node */
+ que_node_t* node) /*!< in: graph node */
{
ut_ad(node);
return(((que_common_t*)node)->val_buf_size);
}
-/***************************************************************************
+/***********************************************************************//**
Sets the value buffer size of a graph node. */
UNIV_INLINE
void
que_node_set_val_buf_size(
/*======================*/
- que_node_t* node, /* in: graph node */
- ulint size) /* in: size */
+ que_node_t* node, /*!< in: graph node */
+ ulint size) /*!< in: size */
{
ut_ad(node);
((que_common_t*)node)->val_buf_size = size;
}
-/***************************************************************************
+/***********************************************************************//**
Sets the parent of a graph node. */
UNIV_INLINE
void
que_node_set_parent(
/*================*/
- que_node_t* node, /* in: graph node */
- que_node_t* parent) /* in: parent */
+ que_node_t* node, /*!< in: graph node */
+ que_node_t* parent) /*!< in: parent */
{
ut_ad(node);
((que_common_t*)node)->parent = parent;
}
-/***************************************************************************
+/***********************************************************************//**
Gets pointer to the value data type field of a graph node. */
UNIV_INLINE
dtype_t*
que_node_get_data_type(
/*===================*/
- que_node_t* node) /* in: graph node */
+ que_node_t* node) /*!< in: graph node */
{
ut_ad(node);
return(dfield_get_type(&((que_common_t*) node)->val));
}
-/*************************************************************************
-Catenates a query graph node to a list of them, possible empty list. */
+/*********************************************************************//**
+Catenates a query graph node to a list of them, possible empty list.
+@return one-way list of nodes */
UNIV_INLINE
que_node_t*
que_node_list_add_last(
/*===================*/
- /* out: one-way list of nodes */
- que_node_t* node_list, /* in: node list, or NULL */
- que_node_t* node) /* in: node */
+ que_node_t* node_list, /*!< in: node list, or NULL */
+ que_node_t* node) /*!< in: node */
{
que_common_t* cnode;
que_common_t* cnode2;
@@ -178,26 +178,26 @@ que_node_list_add_last(
return(node_list);
}
-/*************************************************************************
-Gets the next list node in a list of query graph nodes. */
+/*********************************************************************//**
+Gets the next list node in a list of query graph nodes.
+@return next node in a list of nodes */
UNIV_INLINE
que_node_t*
que_node_get_next(
/*==============*/
- /* out: next node in a list of nodes */
- que_node_t* node) /* in: node in a list */
+ que_node_t* node) /*!< in: node in a list */
{
return(((que_common_t*)node)->brother);
}
-/*************************************************************************
-Gets a query graph node list length. */
+/*********************************************************************//**
+Gets a query graph node list length.
+@return length, for NULL list 0 */
UNIV_INLINE
ulint
que_node_list_get_len(
/*==================*/
- /* out: length, for NULL list 0 */
- que_node_t* node_list) /* in: node list, or NULL */
+ que_node_t* node_list) /*!< in: node list, or NULL */
{
const que_common_t* cnode;
ulint len;
@@ -213,31 +213,29 @@ que_node_list_get_len(
return(len);
}
-/*************************************************************************
-Gets the parent node of a query graph node. */
+/*********************************************************************//**
+Gets the parent node of a query graph node.
+@return parent node or NULL */
UNIV_INLINE
que_node_t*
que_node_get_parent(
/*================*/
- /* out: parent node or NULL */
- que_node_t* node) /* in: node */
+ que_node_t* node) /*!< in: node */
{
return(((que_common_t*)node)->parent);
}
-/**************************************************************************
+/**********************************************************************//**
Checks if graph, trx, or session is in a state where the query thread should
-be stopped. */
+be stopped.
+@return TRUE if should be stopped; NOTE that if the peek is made
+without reserving the kernel mutex, then another peek with the mutex
+reserved is necessary before deciding the actual stopping */
UNIV_INLINE
ibool
que_thr_peek_stop(
/*==============*/
- /* out: TRUE if should be stopped; NOTE that
- if the peek is made without reserving the
- kernel mutex, then another peek with the
- mutex reserved is necessary before deciding
- the actual stopping */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
trx_t* trx;
que_t* graph;
@@ -256,14 +254,14 @@ que_thr_peek_stop(
return(FALSE);
}
-/***************************************************************************
-Returns TRUE if the query graph is for a SELECT statement. */
+/***********************************************************************//**
+Returns TRUE if the query graph is for a SELECT statement.
+@return TRUE if a select */
UNIV_INLINE
ibool
que_graph_is_select(
/*================*/
- /* out: TRUE if a select */
- que_t* graph) /* in: graph */
+ que_t* graph) /*!< in: graph */
{
if (graph->fork_type == QUE_FORK_SELECT_SCROLL
|| graph->fork_type == QUE_FORK_SELECT_NON_SCROLL) {
diff --git a/storage/xtradb/include/que0types.h b/storage/xtradb/include/que0types.h
index 1d3217fb491..ea976074768 100644
--- a/storage/xtradb/include/que0types.h
+++ b/storage/xtradb/include/que0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/que0types.h
Query graph global types
Created 5/27/1996 Heikki Tuuri
@@ -43,10 +44,10 @@ typedef struct que_common_struct que_common_t;
substruct must be 'common' */
struct que_common_struct{
- ulint type; /* query node type */
- que_node_t* parent; /* back pointer to parent node, or NULL */
+ ulint type; /*!< query node type */
+ que_node_t* parent; /*!< back pointer to parent node, or NULL */
que_node_t* brother;/* pointer to a possible brother node */
- dfield_t val; /* evaluated value for an expression */
+ dfield_t val; /*!< evaluated value for an expression */
ulint val_buf_size;
/* buffer size for the evaluated value data,
if the buffer has been allocated dynamically:
diff --git a/storage/xtradb/include/read0read.h b/storage/xtradb/include/read0read.h
index 7ea8bdaf8dd..4d9a9fade36 100644
--- a/storage/xtradb/include/read0read.h
+++ b/storage/xtradb/include/read0read.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/read0read.h
Cursor read
Created 2/16/1997 Heikki Tuuri
@@ -33,64 +34,64 @@ Created 2/16/1997 Heikki Tuuri
#include "trx0trx.h"
#include "read0types.h"
-/*************************************************************************
+/*********************************************************************//**
Opens a read view where exactly the transactions serialized before this
-point in time are seen in the view. */
+point in time are seen in the view.
+@return own: read view struct */
UNIV_INTERN
read_view_t*
read_view_open_now(
/*===============*/
- /* out, own: read view struct */
- dulint cr_trx_id, /* in: trx_id of creating
- transaction, or (0, 0) used in
- purge */
- mem_heap_t* heap); /* in: memory heap from which
+ trx_id_t cr_trx_id, /*!< in: trx_id of creating
+ transaction, or ut_dulint_zero
+ used in purge */
+ mem_heap_t* heap); /*!< in: memory heap from which
allocated */
-/*************************************************************************
+/*********************************************************************//**
Makes a copy of the oldest existing read view, or opens a new. The view
-must be closed with ..._close. */
+must be closed with ..._close.
+@return own: read view struct */
UNIV_INTERN
read_view_t*
read_view_oldest_copy_or_open_new(
/*==============================*/
- /* out, own: read view struct */
- dulint cr_trx_id, /* in: trx_id of creating
- transaction, or (0, 0) used in
- purge */
- mem_heap_t* heap); /* in: memory heap from which
+ trx_id_t cr_trx_id, /*!< in: trx_id of creating
+ transaction, or ut_dulint_zero
+ used in purge */
+ mem_heap_t* heap); /*!< in: memory heap from which
allocated */
-/*************************************************************************
+/*********************************************************************//**
Closes a read view. */
UNIV_INTERN
void
read_view_close(
/*============*/
- read_view_t* view); /* in: read view */
-/*************************************************************************
+ read_view_t* view); /*!< in: read view */
+/*********************************************************************//**
Closes a consistent read view for MySQL. This function is called at an SQL
statement end if the trx isolation level is <= TRX_ISO_READ_COMMITTED. */
UNIV_INTERN
void
read_view_close_for_mysql(
/*======================*/
- trx_t* trx); /* in: trx which has a read view */
-/*************************************************************************
-Checks if a read view sees the specified transaction. */
+ trx_t* trx); /*!< in: trx which has a read view */
+/*********************************************************************//**
+Checks if a read view sees the specified transaction.
+@return TRUE if sees */
UNIV_INLINE
ibool
read_view_sees_trx_id(
/*==================*/
- /* out: TRUE if sees */
- read_view_t* view, /* in: read view */
- dulint trx_id);/* in: trx id */
-/*************************************************************************
+ const read_view_t* view, /*!< in: read view */
+ trx_id_t trx_id);/*!< in: trx id */
+/*********************************************************************//**
Prints a read view to stderr. */
UNIV_INTERN
void
read_view_print(
/*============*/
- read_view_t* view); /* in: read view */
-/*************************************************************************
+ const read_view_t* view); /*!< in: read view */
+/*********************************************************************//**
Create a consistent cursor view for mysql to be used in cursors. In this
consistent read view modifications done by the creating transaction or future
transactions are not visible. */
@@ -98,17 +99,17 @@ UNIV_INTERN
cursor_view_t*
read_cursor_view_create_for_mysql(
/*==============================*/
- trx_t* cr_trx);/* in: trx where cursor view is created */
-/*************************************************************************
+ trx_t* cr_trx);/*!< in: trx where cursor view is created */
+/*********************************************************************//**
Close a given consistent cursor view for mysql and restore global read view
back to a transaction read view. */
UNIV_INTERN
void
read_cursor_view_close_for_mysql(
/*=============================*/
- trx_t* trx, /* in: trx */
- cursor_view_t* curview); /* in: cursor view to be closed */
-/*************************************************************************
+ trx_t* trx, /*!< in: trx */
+ cursor_view_t* curview); /*!< in: cursor view to be closed */
+/*********************************************************************//**
This function sets a given consistent cursor view to a transaction
read view if given consistent cursor view is not NULL. Otherwise, function
restores a global read view to a transaction read view. */
@@ -116,61 +117,73 @@ UNIV_INTERN
void
read_cursor_set_for_mysql(
/*======================*/
- trx_t* trx, /* in: transaction where cursor is set */
- cursor_view_t* curview);/* in: consistent cursor view to be set */
+ trx_t* trx, /*!< in: transaction where cursor is set */
+ cursor_view_t* curview);/*!< in: consistent cursor view to be set */
-/* Read view lists the trx ids of those transactions for which a consistent
+/** Read view lists the trx ids of those transactions for which a consistent
read should not see the modifications to the database. */
struct read_view_struct{
- ulint type; /* VIEW_NORMAL, VIEW_HIGH_GRANULARITY */
- dulint undo_no; /* (0, 0) or if type is VIEW_HIGH_GRANULARITY
+ ulint type; /*!< VIEW_NORMAL, VIEW_HIGH_GRANULARITY */
+ undo_no_t undo_no;/*!< ut_dulint_zero or if type is
+ VIEW_HIGH_GRANULARITY
transaction undo_no when this high-granularity
consistent read view was created */
- dulint low_limit_no; /* The view does not need to see the undo
+ trx_id_t low_limit_no;
+ /*!< The view does not need to see the undo
logs for transactions whose transaction number
is strictly smaller (<) than this value: they
can be removed in purge if not needed by other
views */
- dulint low_limit_id; /* The read should not see any transaction
- with trx id >= this value */
- dulint up_limit_id; /* The read should see all trx ids which
- are strictly smaller (<) than this value */
- ulint n_trx_ids; /* Number of cells in the trx_ids array */
- dulint* trx_ids; /* Additional trx ids which the read should
+ trx_id_t low_limit_id;
+ /*!< The read should not see any transaction
+ with trx id >= this value. In other words,
+ this is the "high water mark". */
+ trx_id_t up_limit_id;
+ /*!< The read should see all trx ids which
+ are strictly smaller (<) than this value.
+ In other words,
+ this is the "low water mark". */
+ ulint n_trx_ids;
+ /*!< Number of cells in the trx_ids array */
+ trx_id_t* trx_ids;/*!< Additional trx ids which the read should
not see: typically, these are the active
transactions at the time when the read is
serialized, except the reading transaction
itself; the trx ids in this array are in a
- descending order */
- dulint creator_trx_id; /* trx id of creating transaction, or
- (0, 0) used in purge */
+ descending order. These trx_ids should be
+ between the "low" and "high" water marks,
+ that is, up_limit_id and low_limit_id. */
+ trx_id_t creator_trx_id;
+ /*!< trx id of creating transaction, or
+ ut_dulint_zero used in purge */
UT_LIST_NODE_T(read_view_t) view_list;
- /* List of read views in trx_sys */
+ /*!< List of read views in trx_sys */
};
-/* Read view types */
-#define VIEW_NORMAL 1 /* Normal consistent read view
+/** Read view types @{ */
+#define VIEW_NORMAL 1 /*!< Normal consistent read view
where transaction does not see changes
made by active transactions except
creating transaction. */
-#define VIEW_HIGH_GRANULARITY 2 /* High-granularity read view where
+#define VIEW_HIGH_GRANULARITY 2 /*!< High-granularity read view where
transaction does not see changes
made by active transactions and own
changes after a point in time when this
read view was created. */
+/* @} */
-/* Implement InnoDB framework to support consistent read views in
+/** Implement InnoDB framework to support consistent read views in
cursors. This struct holds both heap where consistent read view
is allocated and pointer to a read view. */
struct cursor_view_struct{
mem_heap_t* heap;
- /* Memory heap for the cursor view */
+ /*!< Memory heap for the cursor view */
read_view_t* read_view;
- /* Consistent read view of the cursor*/
+ /*!< Consistent read view of the cursor*/
ulint n_mysql_tables_in_use;
- /* number of Innobase tables used in the
+ /*!< number of Innobase tables used in the
processing of this cursor */
};
diff --git a/storage/xtradb/include/read0read.ic b/storage/xtradb/include/read0read.ic
index 9fc6af04e88..9924967cc2d 100644
--- a/storage/xtradb/include/read0read.ic
+++ b/storage/xtradb/include/read0read.ic
@@ -16,51 +16,52 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/read0read.ic
Cursor read
Created 2/16/1997 Heikki Tuuri
*******************************************************/
-/*************************************************************************
-Gets the nth trx id in a read view. */
+/*********************************************************************//**
+Gets the nth trx id in a read view.
+@return trx id */
UNIV_INLINE
-dulint
+trx_id_t
read_view_get_nth_trx_id(
/*=====================*/
- /* out: trx id */
- read_view_t* view, /* in: read view */
- ulint n) /* in: position */
+ const read_view_t* view, /*!< in: read view */
+ ulint n) /*!< in: position */
{
ut_ad(n < view->n_trx_ids);
return(*(view->trx_ids + n));
}
-/*************************************************************************
+/*********************************************************************//**
Sets the nth trx id in a read view. */
UNIV_INLINE
void
read_view_set_nth_trx_id(
/*=====================*/
- read_view_t* view, /* in: read view */
- ulint n, /* in: position */
- dulint trx_id) /* in: trx id to set */
+ read_view_t* view, /*!< in: read view */
+ ulint n, /*!< in: position */
+ trx_id_t trx_id) /*!< in: trx id to set */
{
ut_ad(n < view->n_trx_ids);
*(view->trx_ids + n) = trx_id;
}
-/*************************************************************************
-Checks if a read view sees the specified transaction. */
+/*********************************************************************//**
+Checks if a read view sees the specified transaction.
+@return TRUE if sees */
UNIV_INLINE
ibool
read_view_sees_trx_id(
/*==================*/
- /* out: TRUE if sees */
- read_view_t* view, /* in: read view */
- dulint trx_id) /* in: trx id */
+ const read_view_t* view, /*!< in: read view */
+ trx_id_t trx_id) /*!< in: trx id */
{
ulint n_ids;
int cmp;
diff --git a/storage/xtradb/include/read0types.h b/storage/xtradb/include/read0types.h
index 44849cbb498..caf69e3fb51 100644
--- a/storage/xtradb/include/read0types.h
+++ b/storage/xtradb/include/read0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/read0types.h
Cursor read
Created 2/16/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/rem0cmp.h b/storage/xtradb/include/rem0cmp.h
index 4687e0ee45e..9d2950bbb01 100644
--- a/storage/xtradb/include/rem0cmp.h
+++ b/storage/xtradb/include/rem0cmp.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file include/rem0cmp.h
Comparison services for records
Created 7/1/1994 Heikki Tuuri
@@ -31,172 +32,160 @@ Created 7/1/1994 Heikki Tuuri
#include "dict0dict.h"
#include "rem0rec.h"
-/*****************************************************************
-Returns TRUE if two columns are equal for comparison purposes. */
+/*************************************************************//**
+Returns TRUE if two columns are equal for comparison purposes.
+@return TRUE if the columns are considered equal in comparisons */
UNIV_INTERN
ibool
cmp_cols_are_equal(
/*===============*/
- /* out: TRUE if the columns are
- considered equal in comparisons */
- const dict_col_t* col1, /* in: column 1 */
- const dict_col_t* col2, /* in: column 2 */
+ const dict_col_t* col1, /*!< in: column 1 */
+ const dict_col_t* col2, /*!< in: column 2 */
ibool check_charsets);
- /* in: whether to check charsets */
-/*****************************************************************
+ /*!< in: whether to check charsets */
+/*************************************************************//**
This function is used to compare two data fields for which we know the
-data type. */
+data type.
+@return 1, 0, -1, if data1 is greater, equal, less than data2, respectively */
UNIV_INLINE
int
cmp_data_data(
/*==========*/
- /* out: 1, 0, -1, if data1 is greater, equal,
- less than data2, respectively */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- const byte* data1, /* in: data field (== a pointer to a memory
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ const byte* data1, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len1, /* in: data field length or UNIV_SQL_NULL */
- const byte* data2, /* in: data field (== a pointer to a memory
+ ulint len1, /*!< in: data field length or UNIV_SQL_NULL */
+ const byte* data2, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len2); /* in: data field length or UNIV_SQL_NULL */
-/*****************************************************************
+ ulint len2); /*!< in: data field length or UNIV_SQL_NULL */
+/*************************************************************//**
This function is used to compare two data fields for which we know the
-data type. */
+data type.
+@return 1, 0, -1, if data1 is greater, equal, less than data2, respectively */
UNIV_INTERN
int
cmp_data_data_slow(
/*===============*/
- /* out: 1, 0, -1, if data1 is greater, equal,
- less than data2, respectively */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- const byte* data1, /* in: data field (== a pointer to a memory
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ const byte* data1, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len1, /* in: data field length or UNIV_SQL_NULL */
- const byte* data2, /* in: data field (== a pointer to a memory
+ ulint len1, /*!< in: data field length or UNIV_SQL_NULL */
+ const byte* data2, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len2); /* in: data field length or UNIV_SQL_NULL */
-/*****************************************************************
+ ulint len2); /*!< in: data field length or UNIV_SQL_NULL */
+/*************************************************************//**
This function is used to compare two dfields where at least the first
-has its data type field set. */
+has its data type field set.
+@return 1, 0, -1, if dfield1 is greater, equal, less than dfield2,
+respectively */
UNIV_INLINE
int
cmp_dfield_dfield(
/*==============*/
- /* out: 1, 0, -1, if dfield1 is greater, equal,
- less than dfield2, respectively */
- const dfield_t* dfield1,/* in: data field; must have type field set */
- const dfield_t* dfield2);/* in: data field */
-/*****************************************************************
+ const dfield_t* dfield1,/*!< in: data field; must have type field set */
+ const dfield_t* dfield2);/*!< in: data field */
+/*************************************************************//**
This function is used to compare a data tuple to a physical record.
Only dtuple->n_fields_cmp first fields are taken into account for
the the data tuple! If we denote by n = n_fields_cmp, then rec must
have either m >= n fields, or it must differ from dtuple in some of
the m fields rec has. If rec has an externally stored field we do not
compare it but return with value 0 if such a comparison should be
-made. */
+made.
+@return 1, 0, -1, if dtuple is greater, equal, less than rec,
+respectively, when only the common first fields are compared, or until
+the first externally stored field in rec */
UNIV_INTERN
int
cmp_dtuple_rec_with_match(
/*======================*/
- /* out: 1, 0, -1, if dtuple is greater, equal,
- less than rec, respectively, when only the
- common first fields are compared, or
- until the first externally stored field in
- rec */
- const dtuple_t* dtuple, /* in: data tuple */
- const rec_t* rec, /* in: physical record which differs from
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record which differs from
dtuple in some of the common fields, or which
has an equal number or more fields than
dtuple */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint* matched_fields, /* in/out: number of already completely
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint* matched_fields, /*!< in/out: number of already completely
matched fields; when function returns,
contains the value for current comparison */
- ulint* matched_bytes); /* in/out: number of already matched
+ ulint* matched_bytes); /*!< in/out: number of already matched
bytes within the first field not completely
matched; when function returns, contains the
value for current comparison */
-/******************************************************************
-Compares a data tuple to a physical record. */
+/**************************************************************//**
+Compares a data tuple to a physical record.
+@see cmp_dtuple_rec_with_match
+@return 1, 0, -1, if dtuple is greater, equal, less than rec, respectively */
UNIV_INTERN
int
cmp_dtuple_rec(
/*===========*/
- /* out: 1, 0, -1, if dtuple is greater, equal,
- less than rec, respectively; see the comments
- for cmp_dtuple_rec_with_match */
- const dtuple_t* dtuple, /* in: data tuple */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/******************************************************************
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/**************************************************************//**
Checks if a dtuple is a prefix of a record. The last field in dtuple
-is allowed to be a prefix of the corresponding field in the record. */
+is allowed to be a prefix of the corresponding field in the record.
+@return TRUE if prefix */
UNIV_INTERN
ibool
cmp_dtuple_is_prefix_of_rec(
/*========================*/
- /* out: TRUE if prefix */
- const dtuple_t* dtuple, /* in: data tuple */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-#ifndef UNIV_HOTBACKUP
-/*****************************************************************
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/*************************************************************//**
Compare two physical records that contain the same number of columns,
-none of which are stored externally. */
+none of which are stored externally.
+@return 1, 0, -1 if rec1 is greater, equal, less, respectively, than rec2 */
UNIV_INTERN
int
cmp_rec_rec_simple(
/*===============*/
- /* out: 1, 0 , -1 if rec1 is greater,
- equal, less, respectively, than rec2 */
- const rec_t* rec1, /* in: physical record */
- const rec_t* rec2, /* in: physical record */
- const ulint* offsets1,/* in: rec_get_offsets(rec1, index) */
- const ulint* offsets2,/* in: rec_get_offsets(rec2, index) */
- const dict_index_t* index); /* in: data dictionary index */
-#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+ const rec_t* rec1, /*!< in: physical record */
+ 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 */
+/*************************************************************//**
This function is used to compare two physical records. Only the common
first fields are compared, and if an externally stored field is
-encountered, then 0 is returned. */
+encountered, then 0 is returned.
+@return 1, 0, -1 if rec1 is greater, equal, less, respectively */
UNIV_INTERN
int
cmp_rec_rec_with_match(
/*===================*/
- /* out: 1, 0 , -1 if rec1 is greater, equal,
- less, respectively, than rec2; only the common
- first fields are compared */
- const rec_t* rec1, /* in: physical record */
- const rec_t* rec2, /* in: physical record */
- const ulint* offsets1,/* in: rec_get_offsets(rec1, index) */
- const ulint* offsets2,/* in: rec_get_offsets(rec2, index) */
- dict_index_t* index, /* in: data dictionary index */
- ulint* matched_fields, /* in/out: number of already completely
+ const rec_t* rec1, /*!< in: physical record */
+ const rec_t* rec2, /*!< in: physical record */
+ const ulint* offsets1,/*!< in: rec_get_offsets(rec1, index) */
+ const ulint* offsets2,/*!< in: rec_get_offsets(rec2, index) */
+ dict_index_t* index, /*!< in: data dictionary index */
+ ulint* matched_fields, /*!< in/out: number of already completely
matched fields; when the function returns,
contains the value the for current
comparison */
- ulint* matched_bytes, /* in/out: number of already matched
+ ulint* matched_bytes, /*!< in/out: number of already matched
bytes within the first field not completely
matched; when the function returns, contains
the value for the current comparison */
ulint stats_method);
-/*****************************************************************
+/*************************************************************//**
This function is used to compare two physical records. Only the common
-first fields are compared. */
+first fields are compared.
+@return 1, 0 , -1 if rec1 is greater, equal, less, respectively, than
+rec2; only the common first fields are compared */
UNIV_INLINE
int
cmp_rec_rec(
/*========*/
- /* out: 1, 0 , -1 if rec1 is greater, equal,
- less, respectively, than rec2; only the common
- first fields are compared */
- const rec_t* rec1, /* in: physical record */
- const rec_t* rec2, /* in: physical record */
- const ulint* offsets1,/* in: rec_get_offsets(rec1, index) */
- const ulint* offsets2,/* in: rec_get_offsets(rec2, index) */
- dict_index_t* index); /* in: data dictionary index */
+ const rec_t* rec1, /*!< in: physical record */
+ const rec_t* rec2, /*!< in: physical record */
+ const ulint* offsets1,/*!< in: rec_get_offsets(rec1, index) */
+ const ulint* offsets2,/*!< in: rec_get_offsets(rec2, index) */
+ dict_index_t* index); /*!< in: data dictionary index */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/rem0cmp.ic b/storage/xtradb/include/rem0cmp.ic
index 1abf4142531..d5185ec94af 100644
--- a/storage/xtradb/include/rem0cmp.ic
+++ b/storage/xtradb/include/rem0cmp.ic
@@ -16,44 +16,44 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file include/rem0cmp.ic
Comparison services for records
Created 7/1/1994 Heikki Tuuri
************************************************************************/
-/*****************************************************************
+/*************************************************************//**
This function is used to compare two data fields for which we know the
-data type. */
+data type.
+@return 1, 0, -1, if data1 is greater, equal, less than data2, respectively */
UNIV_INLINE
int
cmp_data_data(
/*==========*/
- /* out: 1, 0, -1, if data1 is greater, equal,
- less than data2, respectively */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- const byte* data1, /* in: data field (== a pointer to a memory
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ const byte* data1, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len1, /* in: data field length or UNIV_SQL_NULL */
- const byte* data2, /* in: data field (== a pointer to a memory
+ ulint len1, /*!< in: data field length or UNIV_SQL_NULL */
+ const byte* data2, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len2) /* in: data field length or UNIV_SQL_NULL */
+ ulint len2) /*!< in: data field length or UNIV_SQL_NULL */
{
return(cmp_data_data_slow(mtype, prtype, data1, len1, data2, len2));
}
-/*****************************************************************
+/*************************************************************//**
This function is used to compare two dfields where at least the first
-has its data type field set. */
+has its data type field set.
+@return 1, 0, -1, if dfield1 is greater, equal, less than dfield2,
+respectively */
UNIV_INLINE
int
cmp_dfield_dfield(
/*==============*/
- /* out: 1, 0, -1, if dfield1 is greater, equal,
- less than dfield2, respectively */
- const dfield_t* dfield1,/* in: data field; must have type field set */
- const dfield_t* dfield2)/* in: data field */
+ const dfield_t* dfield1,/*!< in: data field; must have type field set */
+ const dfield_t* dfield2)/*!< in: data field */
{
const dtype_t* type;
@@ -68,21 +68,20 @@ cmp_dfield_dfield(
dfield_get_len(dfield2)));
}
-/*****************************************************************
+/*************************************************************//**
This function is used to compare two physical records. Only the common
-first fields are compared. */
+first fields are compared.
+@return 1, 0 , -1 if rec1 is greater, equal, less, respectively, than
+rec2; only the common first fields are compared */
UNIV_INLINE
int
cmp_rec_rec(
/*========*/
- /* out: 1, 0 , -1 if rec1 is greater, equal,
- less, respectively, than rec2; only the common
- first fields are compared */
- const rec_t* rec1, /* in: physical record */
- const rec_t* rec2, /* in: physical record */
- const ulint* offsets1,/* in: rec_get_offsets(rec1, index) */
- const ulint* offsets2,/* in: rec_get_offsets(rec2, index) */
- dict_index_t* index) /* in: data dictionary index */
+ const rec_t* rec1, /*!< in: physical record */
+ const rec_t* rec2, /*!< in: physical record */
+ const ulint* offsets1,/*!< in: rec_get_offsets(rec1, index) */
+ const ulint* offsets2,/*!< in: rec_get_offsets(rec2, index) */
+ dict_index_t* index) /*!< in: data dictionary index */
{
ulint match_f = 0;
ulint match_b = 0;
diff --git a/storage/xtradb/include/rem0rec.h b/storage/xtradb/include/rem0rec.h
index cb72a5fa25b..17d08afabb9 100644
--- a/storage/xtradb/include/rem0rec.h
+++ b/storage/xtradb/include/rem0rec.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/rem0rec.h
Record manager
Created 5/30/1994 Heikki Tuuri
@@ -78,293 +79,289 @@ offsets[] array, first passed to rec_get_offsets() */
#define REC_OFFS_NORMAL_SIZE 100
#define REC_OFFS_SMALL_SIZE 10
-/**********************************************************
+/******************************************************//**
The following function is used to get the pointer of the next chained record
-on the same page. */
+on the same page.
+@return pointer to the next chained record, or NULL if none */
UNIV_INLINE
const rec_t*
rec_get_next_ptr_const(
/*===================*/
- /* out: pointer to the next chained record, or
- NULL if none */
- const rec_t* rec, /* in: physical record */
- ulint comp); /* in: nonzero=compact page format */
-/**********************************************************
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp); /*!< in: nonzero=compact page format */
+/******************************************************//**
The following function is used to get the pointer of the next chained record
-on the same page. */
+on the same page.
+@return pointer to the next chained record, or NULL if none */
UNIV_INLINE
rec_t*
rec_get_next_ptr(
/*=============*/
- /* out: pointer to the next chained record, or
- NULL if none */
- rec_t* rec, /* in: physical record */
- ulint comp); /* in: nonzero=compact page format */
-/**********************************************************
+ rec_t* rec, /*!< in: physical record */
+ ulint comp); /*!< in: nonzero=compact page format */
+/******************************************************//**
The following function is used to get the offset of the
-next chained record on the same page. */
+next chained record on the same page.
+@return the page offset of the next chained record, or 0 if none */
UNIV_INLINE
ulint
rec_get_next_offs(
/*==============*/
- /* out: the page offset of the next
- chained record, or 0 if none */
- const rec_t* rec, /* in: physical record */
- ulint comp); /* in: nonzero=compact page format */
-/**********************************************************
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp); /*!< in: nonzero=compact page format */
+/******************************************************//**
The following function is used to set the next record offset field
of an old-style record. */
UNIV_INLINE
void
rec_set_next_offs_old(
/*==================*/
- rec_t* rec, /* in: old-style physical record */
- ulint next); /* in: offset of the next record */
-/**********************************************************
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint next); /*!< in: offset of the next record */
+/******************************************************//**
The following function is used to set the next record offset field
of a new-style record. */
UNIV_INLINE
void
rec_set_next_offs_new(
/*==================*/
- rec_t* rec, /* in/out: new-style physical record */
- ulint next); /* in: offset of the next record */
-/**********************************************************
+ rec_t* rec, /*!< in/out: new-style physical record */
+ ulint next); /*!< in: offset of the next record */
+/******************************************************//**
The following function is used to get the number of fields
-in an old-style record. */
+in an old-style record.
+@return number of data fields */
UNIV_INLINE
ulint
rec_get_n_fields_old(
/*=================*/
- /* out: number of data fields */
- const rec_t* rec); /* in: physical record */
-/**********************************************************
+ const rec_t* rec); /*!< in: physical record */
+/******************************************************//**
The following function is used to get the number of fields
-in a record. */
+in a record.
+@return number of data fields */
UNIV_INLINE
ulint
rec_get_n_fields(
/*=============*/
- /* out: number of data fields */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index); /* in: record descriptor */
-/**********************************************************
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index); /*!< in: record descriptor */
+/******************************************************//**
The following function is used to get the number of records owned by the
-previous directory record. */
+previous directory record.
+@return number of owned records */
UNIV_INLINE
ulint
rec_get_n_owned_old(
/*================*/
- /* out: number of owned records */
- const rec_t* rec); /* in: old-style physical record */
-/**********************************************************
+ const rec_t* rec); /*!< in: old-style physical record */
+/******************************************************//**
The following function is used to set the number of owned records. */
UNIV_INLINE
void
rec_set_n_owned_old(
/*================*/
- /* out: TRUE on success */
- rec_t* rec, /* in: old-style physical record */
- ulint n_owned); /* in: the number of owned */
-/**********************************************************
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint n_owned); /*!< in: the number of owned */
+/******************************************************//**
The following function is used to get the number of records owned by the
-previous directory record. */
+previous directory record.
+@return number of owned records */
UNIV_INLINE
ulint
rec_get_n_owned_new(
/*================*/
- /* out: number of owned records */
- const rec_t* rec); /* in: new-style physical record */
-/**********************************************************
+ const rec_t* rec); /*!< in: new-style physical record */
+/******************************************************//**
The following function is used to set the number of owned records. */
UNIV_INLINE
void
rec_set_n_owned_new(
/*================*/
- rec_t* rec, /* in/out: new-style physical record */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint n_owned);/* in: the number of owned */
-/**********************************************************
+ rec_t* rec, /*!< in/out: new-style physical record */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint n_owned);/*!< in: the number of owned */
+/******************************************************//**
The following function is used to retrieve the info bits of
-a record. */
+a record.
+@return info bits */
UNIV_INLINE
ulint
rec_get_info_bits(
/*==============*/
- /* out: info bits */
- const rec_t* rec, /* in: physical record */
- ulint comp); /* in: nonzero=compact page format */
-/**********************************************************
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp); /*!< in: nonzero=compact page format */
+/******************************************************//**
The following function is used to set the info bits of a record. */
UNIV_INLINE
void
rec_set_info_bits_old(
/*==================*/
- rec_t* rec, /* in: old-style physical record */
- ulint bits); /* in: info bits */
-/**********************************************************
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint bits); /*!< in: info bits */
+/******************************************************//**
The following function is used to set the info bits of a record. */
UNIV_INLINE
void
rec_set_info_bits_new(
/*==================*/
- rec_t* rec, /* in/out: new-style physical record */
- ulint bits); /* in: info bits */
-/**********************************************************
-The following function retrieves the status bits of a new-style record. */
+ rec_t* rec, /*!< in/out: new-style physical record */
+ ulint bits); /*!< in: info bits */
+/******************************************************//**
+The following function retrieves the status bits of a new-style record.
+@return status bits */
UNIV_INLINE
ulint
rec_get_status(
/*===========*/
- /* out: status bits */
- const rec_t* rec); /* in: physical record */
+ const rec_t* rec); /*!< in: physical record */
-/**********************************************************
+/******************************************************//**
The following function is used to set the status bits of a new-style record. */
UNIV_INLINE
void
rec_set_status(
/*===========*/
- rec_t* rec, /* in/out: physical record */
- ulint bits); /* in: info bits */
+ rec_t* rec, /*!< in/out: physical record */
+ ulint bits); /*!< in: info bits */
-/**********************************************************
+/******************************************************//**
The following function is used to retrieve the info and status
-bits of a record. (Only compact records have status bits.) */
+bits of a record. (Only compact records have status bits.)
+@return info bits */
UNIV_INLINE
ulint
rec_get_info_and_status_bits(
/*=========================*/
- /* out: info bits */
- const rec_t* rec, /* in: physical record */
- ulint comp); /* in: nonzero=compact page format */
-/**********************************************************
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp); /*!< in: nonzero=compact page format */
+/******************************************************//**
The following function is used to set the info and status
bits of a record. (Only compact records have status bits.) */
UNIV_INLINE
void
rec_set_info_and_status_bits(
/*=========================*/
- rec_t* rec, /* in/out: compact physical record */
- ulint bits); /* in: info bits */
+ rec_t* rec, /*!< in/out: compact physical record */
+ ulint bits); /*!< in: info bits */
-/**********************************************************
-The following function tells if record is delete marked. */
+/******************************************************//**
+The following function tells if record is delete marked.
+@return nonzero if delete marked */
UNIV_INLINE
ulint
rec_get_deleted_flag(
/*=================*/
- /* out: nonzero if delete marked */
- const rec_t* rec, /* in: physical record */
- ulint comp); /* in: nonzero=compact page format */
-/**********************************************************
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp); /*!< in: nonzero=compact page format */
+/******************************************************//**
The following function is used to set the deleted bit. */
UNIV_INLINE
void
rec_set_deleted_flag_old(
/*=====================*/
- rec_t* rec, /* in: old-style physical record */
- ulint flag); /* in: nonzero if delete marked */
-/**********************************************************
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint flag); /*!< in: nonzero if delete marked */
+/******************************************************//**
The following function is used to set the deleted bit. */
UNIV_INLINE
void
rec_set_deleted_flag_new(
/*=====================*/
- rec_t* rec, /* in/out: new-style physical record */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint flag); /* in: nonzero if delete marked */
-/**********************************************************
-The following function tells if a new-style record is a node pointer. */
+ rec_t* rec, /*!< in/out: new-style physical record */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint flag); /*!< in: nonzero if delete marked */
+/******************************************************//**
+The following function tells if a new-style record is a node pointer.
+@return TRUE if node pointer */
UNIV_INLINE
ibool
rec_get_node_ptr_flag(
/*==================*/
- /* out: TRUE if node pointer */
- const rec_t* rec); /* in: physical record */
-/**********************************************************
+ const rec_t* rec); /*!< in: physical record */
+/******************************************************//**
The following function is used to get the order number
-of an old-style record in the heap of the index page. */
+of an old-style record in the heap of the index page.
+@return heap order number */
UNIV_INLINE
ulint
rec_get_heap_no_old(
/*================*/
- /* out: heap order number */
- const rec_t* rec); /* in: physical record */
-/**********************************************************
+ const rec_t* rec); /*!< in: physical record */
+/******************************************************//**
The following function is used to set the heap number
field in an old-style record. */
UNIV_INLINE
void
rec_set_heap_no_old(
/*================*/
- rec_t* rec, /* in: physical record */
- ulint heap_no);/* in: the heap number */
-/**********************************************************
+ rec_t* rec, /*!< in: physical record */
+ ulint heap_no);/*!< in: the heap number */
+/******************************************************//**
The following function is used to get the order number
-of a new-style record in the heap of the index page. */
+of a new-style record in the heap of the index page.
+@return heap order number */
UNIV_INLINE
ulint
rec_get_heap_no_new(
/*================*/
- /* out: heap order number */
- const rec_t* rec); /* in: physical record */
-/**********************************************************
+ const rec_t* rec); /*!< in: physical record */
+/******************************************************//**
The following function is used to set the heap number
field in a new-style record. */
UNIV_INLINE
void
rec_set_heap_no_new(
/*================*/
- rec_t* rec, /* in/out: physical record */
- ulint heap_no);/* in: the heap number */
-/**********************************************************
+ rec_t* rec, /*!< in/out: physical record */
+ ulint heap_no);/*!< in: the heap number */
+/******************************************************//**
The following function is used to test whether the data offsets
-in the record are stored in one-byte or two-byte format. */
+in the record are stored in one-byte or two-byte format.
+@return TRUE if 1-byte form */
UNIV_INLINE
ibool
rec_get_1byte_offs_flag(
/*====================*/
- /* out: TRUE if 1-byte form */
- const rec_t* rec); /* in: physical record */
+ const rec_t* rec); /*!< in: physical record */
-/**********************************************************
+/******************************************************//**
Determine how many of the first n columns in a compact
-physical record are stored externally. */
+physical record are stored externally.
+@return number of externally stored columns */
UNIV_INTERN
ulint
rec_get_n_extern_new(
/*=================*/
- /* out: number of externally stored columns */
- const rec_t* rec, /* in: compact physical record */
- dict_index_t* index, /* in: record descriptor */
- ulint n); /* in: number of columns to scan */
+ const rec_t* rec, /*!< in: compact physical record */
+ dict_index_t* index, /*!< in: record descriptor */
+ ulint n); /*!< in: number of columns to scan */
-/**********************************************************
+/******************************************************//**
The following function determines the offsets to each field
-in the record. It can reuse a previously allocated array. */
+in the record. It can reuse a previously allocated array.
+@return the new offsets */
UNIV_INTERN
ulint*
rec_get_offsets_func(
/*=================*/
- /* out: the new offsets */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index, /* in: record descriptor */
- ulint* offsets,/* in/out: array consisting of
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets,/*!< in/out: array consisting of
offsets[0] allocated elements,
or an array from rec_get_offsets(),
or NULL */
- ulint n_fields,/* in: maximum number of
+ ulint n_fields,/*!< in: maximum number of
initialized fields
(ULINT_UNDEFINED if all fields) */
- mem_heap_t** heap, /* in/out: memory heap */
- const char* file, /* in: file name where called */
- ulint line); /* in: line number where called */
+ mem_heap_t** heap, /*!< in/out: memory heap */
+ const char* file, /*!< in: file name where called */
+ ulint line); /*!< in: line number where called */
#define rec_get_offsets(rec,index,offsets,n,heap) \
rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__)
-/**********************************************************
+/******************************************************//**
Determine the offset to each field in a leaf-page record
in ROW_FORMAT=COMPACT. This is a special case of
rec_init_offsets() and rec_get_offsets_func(). */
@@ -372,154 +369,154 @@ UNIV_INTERN
void
rec_init_offsets_comp_ordinary(
/*===========================*/
- const rec_t* rec, /* in: physical record in
+ const rec_t* rec, /*!< in: physical record in
ROW_FORMAT=COMPACT */
- ulint extra, /* in: number of bytes to reserve
+ ulint extra, /*!< in: number of bytes to reserve
between the record header and
the data payload
(usually REC_N_NEW_EXTRA_BYTES) */
- const dict_index_t* index, /* in: record descriptor */
- ulint* offsets);/* in/out: array of offsets;
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets);/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
-/**********************************************************
+/******************************************************//**
The following function determines the offsets to each field
in the record. It can reuse a previously allocated array. */
UNIV_INTERN
void
rec_get_offsets_reverse(
/*====================*/
- const byte* extra, /* in: the extra bytes of a
+ const byte* extra, /*!< in: the extra bytes of a
compact record in reverse order,
excluding the fixed-size
REC_N_NEW_EXTRA_BYTES */
- const dict_index_t* index, /* in: record descriptor */
- ulint node_ptr,/* in: nonzero=node pointer,
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint node_ptr,/*!< in: nonzero=node pointer,
0=leaf node */
- ulint* offsets);/* in/out: array consisting of
+ ulint* offsets);/*!< in/out: array consisting of
offsets[0] allocated elements */
-/****************************************************************
-Validates offsets returned by rec_get_offsets(). */
+/************************************************************//**
+Validates offsets returned by rec_get_offsets().
+@return TRUE if valid */
UNIV_INLINE
ibool
rec_offs_validate(
/*==============*/
- /* out: TRUE if valid */
- const rec_t* rec, /* in: record or NULL */
- const dict_index_t* index, /* in: record descriptor or NULL */
- const ulint* offsets);/* in: array returned by
+ const rec_t* rec, /*!< in: record or NULL */
+ const dict_index_t* index, /*!< in: record descriptor or NULL */
+ const ulint* offsets);/*!< in: array returned by
rec_get_offsets() */
#ifdef UNIV_DEBUG
-/****************************************************************
+/************************************************************//**
Updates debug data in offsets, in order to avoid bogus
rec_offs_validate() failures. */
UNIV_INLINE
void
rec_offs_make_valid(
/*================*/
- const rec_t* rec, /* in: record */
- const dict_index_t* index, /* in: record descriptor */
- ulint* offsets);/* in: array returned by
+ const rec_t* rec, /*!< in: record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets);/*!< in: array returned by
rec_get_offsets() */
#else
# define rec_offs_make_valid(rec, index, offsets) ((void) 0)
#endif /* UNIV_DEBUG */
-/****************************************************************
+/************************************************************//**
The following function is used to get the offset to the nth
-data field in an old-style record. */
+data field in an old-style record.
+@return offset to the field */
UNIV_INTERN
ulint
rec_get_nth_field_offs_old(
/*=======================*/
- /* out: offset to the field */
- const rec_t* rec, /* in: record */
- ulint n, /* in: index of the field */
- ulint* len); /* out: length of the field; UNIV_SQL_NULL
+ const rec_t* rec, /*!< in: record */
+ ulint n, /*!< in: index of the field */
+ ulint* len); /*!< out: length of the field; UNIV_SQL_NULL
if SQL null */
#define rec_get_nth_field_old(rec, n, len) \
((rec) + rec_get_nth_field_offs_old(rec, n, len))
-/****************************************************************
+/************************************************************//**
Gets the physical size of an old-style field.
Also an SQL null may have a field of size > 0,
-if the data type is of a fixed size. */
+if the data type is of a fixed size.
+@return field size in bytes */
UNIV_INLINE
ulint
rec_get_nth_field_size(
/*===================*/
- /* out: field size in bytes */
- const rec_t* rec, /* in: record */
- ulint n); /* in: index of the field */
-/****************************************************************
+ const rec_t* rec, /*!< in: record */
+ ulint n); /*!< in: index of the field */
+/************************************************************//**
The following function is used to get an offset to the nth
-data field in a record. */
+data field in a record.
+@return offset from the origin of rec */
UNIV_INLINE
ulint
rec_get_nth_field_offs(
/*===================*/
- /* out: offset from the origin of rec */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n, /* in: index of the field */
- ulint* len); /* out: length of the field; UNIV_SQL_NULL
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n, /*!< in: index of the field */
+ ulint* len); /*!< out: length of the field; UNIV_SQL_NULL
if SQL null */
#define rec_get_nth_field(rec, offsets, n, len) \
((rec) + rec_get_nth_field_offs(offsets, n, len))
-/**********************************************************
+/******************************************************//**
Determine if the offsets are for a record in the new
-compact format. */
+compact format.
+@return nonzero if compact format */
UNIV_INLINE
ulint
rec_offs_comp(
/*==========*/
- /* out: nonzero if compact format */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/**********************************************************
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/******************************************************//**
Determine if the offsets are for a record containing
-externally stored columns. */
+externally stored columns.
+@return nonzero if externally stored */
UNIV_INLINE
ulint
rec_offs_any_extern(
/*================*/
- /* out: nonzero if externally stored */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/**********************************************************
-Returns nonzero if the extern bit is set in nth field of rec. */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/******************************************************//**
+Returns nonzero if the extern bit is set in nth field of rec.
+@return nonzero if externally stored */
UNIV_INLINE
ulint
rec_offs_nth_extern(
/*================*/
- /* out: nonzero if externally stored */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n); /* in: nth field */
-/**********************************************************
-Returns nonzero if the SQL NULL bit is set in nth field of rec. */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n); /*!< in: nth field */
+/******************************************************//**
+Returns nonzero if the SQL NULL bit is set in nth field of rec.
+@return nonzero if SQL NULL */
UNIV_INLINE
ulint
rec_offs_nth_sql_null(
/*==================*/
- /* out: nonzero if SQL NULL */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n); /* in: nth field */
-/**********************************************************
-Gets the physical size of a field. */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n); /*!< in: nth field */
+/******************************************************//**
+Gets the physical size of a field.
+@return length of field */
UNIV_INLINE
ulint
rec_offs_nth_size(
/*==============*/
- /* out: length of field */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n); /* in: nth field */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n); /*!< in: nth field */
-/**********************************************************
-Returns the number of extern bits set in a record. */
+/******************************************************//**
+Returns the number of extern bits set in a record.
+@return number of externally stored fields */
UNIV_INLINE
ulint
rec_offs_n_extern(
/*==============*/
- /* out: number of externally stored fields */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/***************************************************************
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/***********************************************************//**
This is used to modify the value of an already existing field in a record.
The previous value must have exactly the same size as the new value. If len
is UNIV_SQL_NULL then the field is treated as an SQL null.
@@ -529,280 +526,285 @@ UNIV_INLINE
void
rec_set_nth_field(
/*==============*/
- rec_t* rec, /* in: record */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n, /* in: index number of the field */
- const void* data, /* in: pointer to the data if not SQL null */
- ulint len); /* in: length of the data or UNIV_SQL_NULL */
-/**************************************************************
+ rec_t* rec, /*!< in: record */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n, /*!< in: index number of the field */
+ const void* data, /*!< in: pointer to the data if not SQL null */
+ ulint len); /*!< in: length of the data or UNIV_SQL_NULL */
+/**********************************************************//**
The following function returns the data size of an old-style physical
record, that is the sum of field lengths. SQL null fields
are counted as length 0 fields. The value returned by the function
-is the distance from record origin to record end in bytes. */
+is the distance from record origin to record end in bytes.
+@return size */
UNIV_INLINE
ulint
rec_get_data_size_old(
/*==================*/
- /* out: size */
- const rec_t* rec); /* in: physical record */
-/**************************************************************
+ const rec_t* rec); /*!< in: physical record */
+/**********************************************************//**
The following function returns the number of allocated elements
-for an array of offsets. */
+for an array of offsets.
+@return number of elements */
UNIV_INLINE
ulint
rec_offs_get_n_alloc(
/*=================*/
- /* out: number of elements */
- const ulint* offsets);/* in: array for rec_get_offsets() */
-/**************************************************************
+ const ulint* offsets);/*!< in: array for rec_get_offsets() */
+/**********************************************************//**
The following function sets the number of allocated elements
for an array of offsets. */
UNIV_INLINE
void
rec_offs_set_n_alloc(
/*=================*/
- ulint* offsets, /* out: array for rec_get_offsets(),
+ ulint* offsets, /*!< out: array for rec_get_offsets(),
must be allocated */
- ulint n_alloc); /* in: number of elements */
+ ulint n_alloc); /*!< in: number of elements */
#define rec_offs_init(offsets) \
rec_offs_set_n_alloc(offsets, (sizeof offsets) / sizeof *offsets)
-/**************************************************************
-The following function returns the number of fields in a record. */
+/**********************************************************//**
+The following function returns the number of fields in a record.
+@return number of fields */
UNIV_INLINE
ulint
rec_offs_n_fields(
/*==============*/
- /* out: number of fields */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/**************************************************************
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/**********************************************************//**
The following function returns the data size of a physical
record, that is the sum of field lengths. SQL null fields
are counted as length 0 fields. The value returned by the function
-is the distance from record origin to record end in bytes. */
+is the distance from record origin to record end in bytes.
+@return size */
UNIV_INLINE
ulint
rec_offs_data_size(
/*===============*/
- /* out: size */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/**************************************************************
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/**********************************************************//**
Returns the total size of record minus data size of record.
The value returned by the function is the distance from record
-start to record origin in bytes. */
+start to record origin in bytes.
+@return size */
UNIV_INLINE
ulint
rec_offs_extra_size(
/*================*/
- /* out: size */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/**************************************************************
-Returns the total size of a physical record. */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/**********************************************************//**
+Returns the total size of a physical record.
+@return size */
UNIV_INLINE
ulint
rec_offs_size(
/*==========*/
- /* out: size */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/**************************************************************
-Returns a pointer to the start of the record. */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/**********************************************************//**
+Returns a pointer to the start of the record.
+@return pointer to start */
UNIV_INLINE
byte*
rec_get_start(
/*==========*/
- /* out: pointer to start */
- rec_t* rec, /* in: pointer to record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/**************************************************************
-Returns a pointer to the end of the record. */
+ rec_t* rec, /*!< in: pointer to record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/**********************************************************//**
+Returns a pointer to the end of the record.
+@return pointer to end */
UNIV_INLINE
byte*
rec_get_end(
/*========*/
- /* out: pointer to end */
- rec_t* rec, /* in: pointer to record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/*******************************************************************
-Copies a physical record to a buffer. */
+ rec_t* rec, /*!< in: pointer to record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/***************************************************************//**
+Copies a physical record to a buffer.
+@return pointer to the origin of the copy */
UNIV_INLINE
rec_t*
rec_copy(
/*=====*/
- /* out: pointer to the origin of the copy */
- void* buf, /* in: buffer */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/******************************************************************
+ void* buf, /*!< in: buffer */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+#ifndef UNIV_HOTBACKUP
+/**************************************************************//**
Copies the first n fields of a physical record to a new physical record in
-a buffer. */
+a buffer.
+@return own: copied record */
UNIV_INTERN
rec_t*
rec_copy_prefix_to_buf(
/*===================*/
- /* out, own: copied record */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index, /* in: record descriptor */
- ulint n_fields, /* in: number of fields
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint n_fields, /*!< in: number of fields
to copy */
- byte** buf, /* in/out: memory buffer
+ byte** buf, /*!< in/out: memory buffer
for the copied prefix,
or NULL */
- ulint* buf_size); /* in/out: buffer size */
-/****************************************************************
-Folds a prefix of a physical record to a ulint. */
+ ulint* buf_size); /*!< in/out: buffer size */
+/************************************************************//**
+Folds a prefix of a physical record to a ulint.
+@return the folded value */
UNIV_INLINE
ulint
rec_fold(
/*=====*/
- /* out: the folded value */
- const rec_t* rec, /* in: the physical record */
- const ulint* offsets, /* in: array returned by
+ const rec_t* rec, /*!< in: the physical record */
+ const ulint* offsets, /*!< in: array returned by
rec_get_offsets() */
- ulint n_fields, /* in: number of complete
+ ulint n_fields, /*!< in: number of complete
fields to fold */
- ulint n_bytes, /* in: number of bytes to fold
+ ulint n_bytes, /*!< in: number of bytes to fold
in an incomplete last field */
- dulint tree_id) /* in: index tree id */
+ dulint tree_id) /*!< in: index tree id */
__attribute__((pure));
-/*************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************//**
Builds a ROW_FORMAT=COMPACT record out of a data tuple. */
UNIV_INTERN
void
rec_convert_dtuple_to_rec_comp(
/*===========================*/
- rec_t* rec, /* in: origin of record */
- ulint extra, /* in: number of bytes to
+ rec_t* rec, /*!< in: origin of record */
+ ulint extra, /*!< in: number of bytes to
reserve between the record
header and the data payload
(normally REC_N_NEW_EXTRA_BYTES) */
- const dict_index_t* index, /* in: record descriptor */
- ulint status, /* in: status bits of the record */
- const dfield_t* fields, /* in: array of data fields */
- ulint n_fields);/* in: number of data fields */
-/*************************************************************
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint status, /*!< in: status bits of the record */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields);/*!< in: number of data fields */
+/*********************************************************//**
Builds a physical record out of a data tuple and
-stores it into the given buffer. */
+stores it into the given buffer.
+@return pointer to the origin of physical record */
UNIV_INTERN
rec_t*
rec_convert_dtuple_to_rec(
/*======================*/
- /* out: pointer to the origin
- of physical record */
- byte* buf, /* in: start address of the
+ byte* buf, /*!< in: start address of the
physical record */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* dtuple, /* in: data tuple */
- ulint n_ext); /* in: number of
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ ulint n_ext); /*!< in: number of
externally stored columns */
-/**************************************************************
+/**********************************************************//**
Returns the extra size of an old-style physical record if we know its
-data size and number of fields. */
+data size and number of fields.
+@return extra size */
UNIV_INLINE
ulint
rec_get_converted_extra_size(
/*=========================*/
- /* out: extra size */
- ulint data_size, /* in: data size */
- ulint n_fields, /* in: number of fields */
- ulint n_ext) /* in: number of externally stored columns */
+ ulint data_size, /*!< in: data size */
+ ulint n_fields, /*!< in: number of fields */
+ ulint n_ext) /*!< in: number of externally stored columns */
__attribute__((const));
-/**************************************************************
-Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT. */
+/**********************************************************//**
+Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
+@return total size */
UNIV_INTERN
ulint
rec_get_converted_size_comp_prefix(
/*===============================*/
- /* out: total size */
- const dict_index_t* index, /* in: record descriptor;
+ const dict_index_t* index, /*!< in: record descriptor;
dict_table_is_comp() is
assumed to hold, even if
it does not */
- const dfield_t* fields, /* in: array of data fields */
- ulint n_fields,/* in: number of data fields */
- ulint* extra); /* out: extra size */
-/**************************************************************
-Determines the size of a data tuple in ROW_FORMAT=COMPACT. */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint* extra); /*!< out: extra size */
+/**********************************************************//**
+Determines the size of a data tuple in ROW_FORMAT=COMPACT.
+@return total size */
UNIV_INTERN
ulint
rec_get_converted_size_comp(
/*========================*/
- /* out: total size */
- const dict_index_t* index, /* in: record descriptor;
+ const dict_index_t* index, /*!< in: record descriptor;
dict_table_is_comp() is
assumed to hold, even if
it does not */
- ulint status, /* in: status bits of the record */
- const dfield_t* fields, /* in: array of data fields */
- ulint n_fields,/* in: number of data fields */
- ulint* extra); /* out: extra size */
-/**************************************************************
+ ulint status, /*!< in: status bits of the record */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint* extra); /*!< out: extra size */
+/**********************************************************//**
The following function returns the size of a data tuple when converted to
-a physical record. */
+a physical record.
+@return size */
UNIV_INLINE
ulint
rec_get_converted_size(
/*===================*/
- /* out: size */
- dict_index_t* index, /* in: record descriptor */
- const dtuple_t* dtuple, /* in: data tuple */
- ulint n_ext); /* in: number of externally stored columns */
-/******************************************************************
+ dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ ulint n_ext); /*!< in: number of externally stored columns */
+#ifndef UNIV_HOTBACKUP
+/**************************************************************//**
Copies the first n fields of a physical record to a data tuple.
The fields are copied to the memory heap. */
UNIV_INTERN
void
rec_copy_prefix_to_dtuple(
/*======================*/
- dtuple_t* tuple, /* out: data tuple */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index, /* in: record descriptor */
- ulint n_fields, /* in: number of fields
+ dtuple_t* tuple, /*!< out: data tuple */
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint n_fields, /*!< in: number of fields
to copy */
- mem_heap_t* heap); /* in: memory heap */
-/*******************************************************************
-Validates the consistency of a physical record. */
+ mem_heap_t* heap); /*!< in: memory heap */
+#endif /* !UNIV_HOTBACKUP */
+/***************************************************************//**
+Validates the consistency of a physical record.
+@return TRUE if ok */
UNIV_INTERN
ibool
rec_validate(
/*=========*/
- /* out: TRUE if ok */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/*******************************************************************
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/***************************************************************//**
Prints an old-style physical record. */
UNIV_INTERN
void
rec_print_old(
/*==========*/
- FILE* file, /* in: file where to print */
- const rec_t* rec); /* in: physical record */
-/*******************************************************************
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec); /*!< in: physical record */
+#ifndef UNIV_HOTBACKUP
+/***************************************************************//**
Prints a physical record in ROW_FORMAT=COMPACT. Ignores the
record header. */
UNIV_INTERN
void
rec_print_comp(
/*===========*/
- FILE* file, /* in: file where to print */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/*******************************************************************
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/***************************************************************//**
Prints a physical record. */
UNIV_INTERN
void
rec_print_new(
/*==========*/
- FILE* file, /* in: file where to print */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/*******************************************************************
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/***************************************************************//**
Prints a physical record. */
UNIV_INTERN
void
rec_print(
/*======*/
- FILE* file, /* in: file where to print */
- const rec_t* rec, /* in: physical record */
- dict_index_t* index); /* in: record descriptor */
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec, /*!< in: physical record */
+ dict_index_t* index); /*!< in: record descriptor */
+#endif /* UNIV_HOTBACKUP */
#define REC_INFO_BITS 6 /* This is single byte bit-field */
diff --git a/storage/xtradb/include/rem0rec.ic b/storage/xtradb/include/rem0rec.ic
index 0b2b9f4a685..9fe736f9b0b 100644
--- a/storage/xtradb/include/rem0rec.ic
+++ b/storage/xtradb/include/rem0rec.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/rem0rec.ic
Record manager
Created 5/30/1994 Heikki Tuuri
@@ -143,52 +144,52 @@ a field stored to another page: */
# error "sum of new-style masks != 0xFFFFFFUL"
#endif
-/***************************************************************
+/***********************************************************//**
Sets the value of the ith field SQL null bit of an old-style record. */
UNIV_INTERN
void
rec_set_nth_field_null_bit(
/*=======================*/
- rec_t* rec, /* in: record */
- ulint i, /* in: ith field */
- ibool val); /* in: value to set */
-/***************************************************************
+ rec_t* rec, /*!< in: record */
+ ulint i, /*!< in: ith field */
+ ibool val); /*!< in: value to set */
+/***********************************************************//**
Sets an old-style record field to SQL null.
The physical size of the field is not changed. */
UNIV_INTERN
void
rec_set_nth_field_sql_null(
/*=======================*/
- rec_t* rec, /* in: record */
- ulint n); /* in: index of the field */
+ rec_t* rec, /*!< in: record */
+ ulint n); /*!< in: index of the field */
-/**********************************************************
+/******************************************************//**
Gets a bit field from within 1 byte. */
UNIV_INLINE
ulint
rec_get_bit_field_1(
/*================*/
- const rec_t* rec, /* in: pointer to record origin */
- ulint offs, /* in: offset from the origin down */
- ulint mask, /* in: mask used to filter bits */
- ulint shift) /* in: shift right applied after masking */
+ const rec_t* rec, /*!< in: pointer to record origin */
+ ulint offs, /*!< in: offset from the origin down */
+ ulint mask, /*!< in: mask used to filter bits */
+ ulint shift) /*!< in: shift right applied after masking */
{
ut_ad(rec);
return((mach_read_from_1(rec - offs) & mask) >> shift);
}
-/**********************************************************
+/******************************************************//**
Sets a bit field within 1 byte. */
UNIV_INLINE
void
rec_set_bit_field_1(
/*================*/
- rec_t* rec, /* in: pointer to record origin */
- ulint val, /* in: value to set */
- ulint offs, /* in: offset from the origin down */
- ulint mask, /* in: mask used to filter bits */
- ulint shift) /* in: shift right applied after masking */
+ rec_t* rec, /*!< in: pointer to record origin */
+ ulint val, /*!< in: value to set */
+ ulint offs, /*!< in: offset from the origin down */
+ ulint mask, /*!< in: mask used to filter bits */
+ ulint shift) /*!< in: shift right applied after masking */
{
ut_ad(rec);
ut_ad(offs <= REC_N_OLD_EXTRA_BYTES);
@@ -202,33 +203,33 @@ rec_set_bit_field_1(
| (val << shift));
}
-/**********************************************************
+/******************************************************//**
Gets a bit field from within 2 bytes. */
UNIV_INLINE
ulint
rec_get_bit_field_2(
/*================*/
- const rec_t* rec, /* in: pointer to record origin */
- ulint offs, /* in: offset from the origin down */
- ulint mask, /* in: mask used to filter bits */
- ulint shift) /* in: shift right applied after masking */
+ const rec_t* rec, /*!< in: pointer to record origin */
+ ulint offs, /*!< in: offset from the origin down */
+ ulint mask, /*!< in: mask used to filter bits */
+ ulint shift) /*!< in: shift right applied after masking */
{
ut_ad(rec);
return((mach_read_from_2(rec - offs) & mask) >> shift);
}
-/**********************************************************
+/******************************************************//**
Sets a bit field within 2 bytes. */
UNIV_INLINE
void
rec_set_bit_field_2(
/*================*/
- rec_t* rec, /* in: pointer to record origin */
- ulint val, /* in: value to set */
- ulint offs, /* in: offset from the origin down */
- ulint mask, /* in: mask used to filter bits */
- ulint shift) /* in: shift right applied after masking */
+ rec_t* rec, /*!< in: pointer to record origin */
+ ulint val, /*!< in: value to set */
+ ulint offs, /*!< in: offset from the origin down */
+ ulint mask, /*!< in: mask used to filter bits */
+ ulint shift) /*!< in: shift right applied after masking */
{
ut_ad(rec);
ut_ad(offs <= REC_N_OLD_EXTRA_BYTES);
@@ -244,17 +245,16 @@ rec_set_bit_field_2(
| (val << shift));
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the pointer of the next chained record
-on the same page. */
+on the same page.
+@return pointer to the next chained record, or NULL if none */
UNIV_INLINE
const rec_t*
rec_get_next_ptr_const(
/*===================*/
- /* out: pointer to the next chained record, or
- NULL if none */
- const rec_t* rec, /* in: physical record */
- ulint comp) /* in: nonzero=compact page format */
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp) /*!< in: nonzero=compact page format */
{
ulint field_value;
@@ -301,32 +301,30 @@ rec_get_next_ptr_const(
}
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the pointer of the next chained record
-on the same page. */
+on the same page.
+@return pointer to the next chained record, or NULL if none */
UNIV_INLINE
rec_t*
rec_get_next_ptr(
/*=============*/
- /* out: pointer to the next chained record, or
- NULL if none */
- rec_t* rec, /* in: physical record */
- ulint comp) /* in: nonzero=compact page format */
+ rec_t* rec, /*!< in: physical record */
+ ulint comp) /*!< in: nonzero=compact page format */
{
return((rec_t*) rec_get_next_ptr_const(rec, comp));
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the offset of the next chained record
-on the same page. */
+on the same page.
+@return the page offset of the next chained record, or 0 if none */
UNIV_INLINE
ulint
rec_get_next_offs(
/*==============*/
- /* out: the page offset of the next
- chained record, or 0 if none */
- const rec_t* rec, /* in: physical record */
- ulint comp) /* in: nonzero=compact page format */
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp) /*!< in: nonzero=compact page format */
{
ulint field_value;
#if REC_NEXT_MASK != 0xFFFFUL
@@ -374,15 +372,15 @@ rec_get_next_offs(
}
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the next record offset field
of an old-style record. */
UNIV_INLINE
void
rec_set_next_offs_old(
/*==================*/
- rec_t* rec, /* in: old-style physical record */
- ulint next) /* in: offset of the next record */
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint next) /*!< in: offset of the next record */
{
ut_ad(rec);
ut_ad(UNIV_PAGE_SIZE > next);
@@ -396,15 +394,15 @@ rec_set_next_offs_old(
mach_write_to_2(rec - REC_NEXT, next);
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the next record offset field
of a new-style record. */
UNIV_INLINE
void
rec_set_next_offs_new(
/*==================*/
- rec_t* rec, /* in/out: new-style physical record */
- ulint next) /* in: offset of the next record */
+ rec_t* rec, /*!< in/out: new-style physical record */
+ ulint next) /*!< in: offset of the next record */
{
ulint field_value;
@@ -427,15 +425,15 @@ rec_set_next_offs_new(
mach_write_to_2(rec - REC_NEXT, field_value);
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the number of fields
-in an old-style record. */
+in an old-style record.
+@return number of data fields */
UNIV_INLINE
ulint
rec_get_n_fields_old(
/*=================*/
- /* out: number of data fields */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
ulint ret;
@@ -450,15 +448,15 @@ rec_get_n_fields_old(
return(ret);
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the number of fields
in an old-style record. */
UNIV_INLINE
void
rec_set_n_fields_old(
/*=================*/
- rec_t* rec, /* in: physical record */
- ulint n_fields) /* in: the number of fields */
+ rec_t* rec, /*!< in: physical record */
+ ulint n_fields) /*!< in: the number of fields */
{
ut_ad(rec);
ut_ad(n_fields <= REC_MAX_N_FIELDS);
@@ -468,14 +466,14 @@ rec_set_n_fields_old(
REC_OLD_N_FIELDS_MASK, REC_OLD_N_FIELDS_SHIFT);
}
-/**********************************************************
-The following function retrieves the status bits of a new-style record. */
+/******************************************************//**
+The following function retrieves the status bits of a new-style record.
+@return status bits */
UNIV_INLINE
ulint
rec_get_status(
/*===========*/
- /* out: status bits */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
ulint ret;
@@ -488,16 +486,16 @@ rec_get_status(
return(ret);
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the number of fields
-in a record. */
+in a record.
+@return number of data fields */
UNIV_INLINE
ulint
rec_get_n_fields(
/*=============*/
- /* out: number of data fields */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index) /* in: record descriptor */
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index) /*!< in: record descriptor */
{
ut_ad(rec);
ut_ad(index);
@@ -520,57 +518,56 @@ rec_get_n_fields(
}
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the number of records owned by the
-previous directory record. */
+previous directory record.
+@return number of owned records */
UNIV_INLINE
ulint
rec_get_n_owned_old(
/*================*/
- /* out: number of owned records */
- const rec_t* rec) /* in: old-style physical record */
+ const rec_t* rec) /*!< in: old-style physical record */
{
return(rec_get_bit_field_1(rec, REC_OLD_N_OWNED,
REC_N_OWNED_MASK, REC_N_OWNED_SHIFT));
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the number of owned records. */
UNIV_INLINE
void
rec_set_n_owned_old(
/*================*/
- /* out: TRUE on success */
- rec_t* rec, /* in: old-style physical record */
- ulint n_owned) /* in: the number of owned */
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint n_owned) /*!< in: the number of owned */
{
rec_set_bit_field_1(rec, n_owned, REC_OLD_N_OWNED,
REC_N_OWNED_MASK, REC_N_OWNED_SHIFT);
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the number of records owned by the
-previous directory record. */
+previous directory record.
+@return number of owned records */
UNIV_INLINE
ulint
rec_get_n_owned_new(
/*================*/
- /* out: number of owned records */
- const rec_t* rec) /* in: new-style physical record */
+ const rec_t* rec) /*!< in: new-style physical record */
{
return(rec_get_bit_field_1(rec, REC_NEW_N_OWNED,
REC_N_OWNED_MASK, REC_N_OWNED_SHIFT));
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the number of owned records. */
UNIV_INLINE
void
rec_set_n_owned_new(
/*================*/
- rec_t* rec, /* in/out: new-style physical record */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint n_owned)/* in: the number of owned */
+ rec_t* rec, /*!< in/out: new-style physical record */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint n_owned)/*!< in: the number of owned */
{
rec_set_bit_field_1(rec, n_owned, REC_NEW_N_OWNED,
REC_N_OWNED_MASK, REC_N_OWNED_SHIFT);
@@ -581,69 +578,69 @@ rec_set_n_owned_new(
}
}
-/**********************************************************
-The following function is used to retrieve the info bits of a record. */
+/******************************************************//**
+The following function is used to retrieve the info bits of a record.
+@return info bits */
UNIV_INLINE
ulint
rec_get_info_bits(
/*==============*/
- /* out: info bits */
- const rec_t* rec, /* in: physical record */
- ulint comp) /* in: nonzero=compact page format */
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp) /*!< in: nonzero=compact page format */
{
return(rec_get_bit_field_1(
rec, comp ? REC_NEW_INFO_BITS : REC_OLD_INFO_BITS,
REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT));
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the info bits of a record. */
UNIV_INLINE
void
rec_set_info_bits_old(
/*==================*/
- rec_t* rec, /* in: old-style physical record */
- ulint bits) /* in: info bits */
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint bits) /*!< in: info bits */
{
rec_set_bit_field_1(rec, bits, REC_OLD_INFO_BITS,
REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT);
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the info bits of a record. */
UNIV_INLINE
void
rec_set_info_bits_new(
/*==================*/
- rec_t* rec, /* in/out: new-style physical record */
- ulint bits) /* in: info bits */
+ rec_t* rec, /*!< in/out: new-style physical record */
+ ulint bits) /*!< in: info bits */
{
rec_set_bit_field_1(rec, bits, REC_NEW_INFO_BITS,
REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT);
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the status bits of a new-style record. */
UNIV_INLINE
void
rec_set_status(
/*===========*/
- rec_t* rec, /* in/out: physical record */
- ulint bits) /* in: info bits */
+ rec_t* rec, /*!< in/out: physical record */
+ ulint bits) /*!< in: info bits */
{
rec_set_bit_field_1(rec, bits, REC_NEW_STATUS,
REC_NEW_STATUS_MASK, REC_NEW_STATUS_SHIFT);
}
-/**********************************************************
+/******************************************************//**
The following function is used to retrieve the info and status
-bits of a record. (Only compact records have status bits.) */
+bits of a record. (Only compact records have status bits.)
+@return info bits */
UNIV_INLINE
ulint
rec_get_info_and_status_bits(
/*=========================*/
- /* out: info bits */
- const rec_t* rec, /* in: physical record */
- ulint comp) /* in: nonzero=compact page format */
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp) /*!< in: nonzero=compact page format */
{
ulint bits;
#if (REC_NEW_STATUS_MASK >> REC_NEW_STATUS_SHIFT) \
@@ -658,15 +655,15 @@ rec_get_info_and_status_bits(
}
return(bits);
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the info and status
bits of a record. (Only compact records have status bits.) */
UNIV_INLINE
void
rec_set_info_and_status_bits(
/*=========================*/
- rec_t* rec, /* in/out: physical record */
- ulint bits) /* in: info bits */
+ rec_t* rec, /*!< in/out: physical record */
+ ulint bits) /*!< in: info bits */
{
#if (REC_NEW_STATUS_MASK >> REC_NEW_STATUS_SHIFT) \
& (REC_INFO_BITS_MASK >> REC_INFO_BITS_SHIFT)
@@ -676,15 +673,15 @@ rec_set_info_and_status_bits(
rec_set_info_bits_new(rec, bits & ~REC_NEW_STATUS_MASK);
}
-/**********************************************************
-The following function tells if record is delete marked. */
+/******************************************************//**
+The following function tells if record is delete marked.
+@return nonzero if delete marked */
UNIV_INLINE
ulint
rec_get_deleted_flag(
/*=================*/
- /* out: nonzero if delete marked */
- const rec_t* rec, /* in: physical record */
- ulint comp) /* in: nonzero=compact page format */
+ const rec_t* rec, /*!< in: physical record */
+ ulint comp) /*!< in: nonzero=compact page format */
{
if (UNIV_EXPECT(comp, REC_OFFS_COMPACT)) {
return(UNIV_UNLIKELY(
@@ -699,14 +696,14 @@ rec_get_deleted_flag(
}
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the deleted bit. */
UNIV_INLINE
void
rec_set_deleted_flag_old(
/*=====================*/
- rec_t* rec, /* in: old-style physical record */
- ulint flag) /* in: nonzero if delete marked */
+ rec_t* rec, /*!< in: old-style physical record */
+ ulint flag) /*!< in: nonzero if delete marked */
{
ulint val;
@@ -721,15 +718,15 @@ rec_set_deleted_flag_old(
rec_set_info_bits_old(rec, val);
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the deleted bit. */
UNIV_INLINE
void
rec_set_deleted_flag_new(
/*=====================*/
- rec_t* rec, /* in/out: new-style physical record */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint flag) /* in: nonzero if delete marked */
+ rec_t* rec, /*!< in/out: new-style physical record */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint flag) /*!< in: nonzero if delete marked */
{
ulint val;
@@ -748,83 +745,83 @@ rec_set_deleted_flag_new(
}
}
-/**********************************************************
-The following function tells if a new-style record is a node pointer. */
+/******************************************************//**
+The following function tells if a new-style record is a node pointer.
+@return TRUE if node pointer */
UNIV_INLINE
ibool
rec_get_node_ptr_flag(
/*==================*/
- /* out: TRUE if node pointer */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
return(REC_STATUS_NODE_PTR == rec_get_status(rec));
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the order number
-of an old-style record in the heap of the index page. */
+of an old-style record in the heap of the index page.
+@return heap order number */
UNIV_INLINE
ulint
rec_get_heap_no_old(
/*================*/
- /* out: heap order number */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
return(rec_get_bit_field_2(rec, REC_OLD_HEAP_NO,
REC_HEAP_NO_MASK, REC_HEAP_NO_SHIFT));
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the heap number
field in an old-style record. */
UNIV_INLINE
void
rec_set_heap_no_old(
/*================*/
- rec_t* rec, /* in: physical record */
- ulint heap_no)/* in: the heap number */
+ rec_t* rec, /*!< in: physical record */
+ ulint heap_no)/*!< in: the heap number */
{
rec_set_bit_field_2(rec, heap_no, REC_OLD_HEAP_NO,
REC_HEAP_NO_MASK, REC_HEAP_NO_SHIFT);
}
-/**********************************************************
+/******************************************************//**
The following function is used to get the order number
-of a new-style record in the heap of the index page. */
+of a new-style record in the heap of the index page.
+@return heap order number */
UNIV_INLINE
ulint
rec_get_heap_no_new(
/*================*/
- /* out: heap order number */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
return(rec_get_bit_field_2(rec, REC_NEW_HEAP_NO,
REC_HEAP_NO_MASK, REC_HEAP_NO_SHIFT));
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the heap number
field in a new-style record. */
UNIV_INLINE
void
rec_set_heap_no_new(
/*================*/
- rec_t* rec, /* in/out: physical record */
- ulint heap_no)/* in: the heap number */
+ rec_t* rec, /*!< in/out: physical record */
+ ulint heap_no)/*!< in: the heap number */
{
rec_set_bit_field_2(rec, heap_no, REC_NEW_HEAP_NO,
REC_HEAP_NO_MASK, REC_HEAP_NO_SHIFT);
}
-/**********************************************************
+/******************************************************//**
The following function is used to test whether the data offsets in the record
-are stored in one-byte or two-byte format. */
+are stored in one-byte or two-byte format.
+@return TRUE if 1-byte form */
UNIV_INLINE
ibool
rec_get_1byte_offs_flag(
/*====================*/
- /* out: TRUE if 1-byte form */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
#if TRUE != 1
#error "TRUE != 1"
@@ -834,14 +831,14 @@ rec_get_1byte_offs_flag(
REC_OLD_SHORT_SHIFT));
}
-/**********************************************************
+/******************************************************//**
The following function is used to set the 1-byte offsets flag. */
UNIV_INLINE
void
rec_set_1byte_offs_flag(
/*====================*/
- rec_t* rec, /* in: physical record */
- ibool flag) /* in: TRUE if 1byte form */
+ rec_t* rec, /*!< in: physical record */
+ ibool flag) /*!< in: TRUE if 1byte form */
{
#if TRUE != 1
#error "TRUE != 1"
@@ -852,18 +849,17 @@ rec_set_1byte_offs_flag(
REC_OLD_SHORT_SHIFT);
}
-/**********************************************************
+/******************************************************//**
Returns the offset of nth field end if the record is stored in the 1-byte
offsets form. If the field is SQL null, the flag is ORed in the returned
-value. */
+value.
+@return offset of the start of the field, SQL null flag ORed */
UNIV_INLINE
ulint
rec_1_get_field_end_info(
/*=====================*/
- /* out: offset of the start of the
- field, SQL null flag ORed */
- const rec_t* rec, /* in: record */
- ulint n) /* in: field index */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: field index */
{
ut_ad(rec_get_1byte_offs_flag(rec));
ut_ad(n < rec_get_n_fields_old(rec));
@@ -871,19 +867,18 @@ rec_1_get_field_end_info(
return(mach_read_from_1(rec - (REC_N_OLD_EXTRA_BYTES + n + 1)));
}
-/**********************************************************
+/******************************************************//**
Returns the offset of nth field end if the record is stored in the 2-byte
offsets form. If the field is SQL null, the flag is ORed in the returned
-value. */
+value.
+@return offset of the start of the field, SQL null flag and extern
+storage flag ORed */
UNIV_INLINE
ulint
rec_2_get_field_end_info(
/*=====================*/
- /* out: offset of the start of the
- field, SQL null flag and extern
- storage flag ORed */
- const rec_t* rec, /* in: record */
- ulint n) /* in: field index */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: field index */
{
ut_ad(!rec_get_1byte_offs_flag(rec));
ut_ad(n < rec_get_n_fields_old(rec));
@@ -896,15 +891,15 @@ this position, and following positions hold the end offsets of
the fields. */
#define rec_offs_base(offsets) (offsets + REC_OFFS_HEADER_SIZE)
-/**************************************************************
+/**********************************************************//**
The following function returns the number of allocated elements
-for an array of offsets. */
+for an array of offsets.
+@return number of elements */
UNIV_INLINE
ulint
rec_offs_get_n_alloc(
/*=================*/
- /* out: number of elements */
- const ulint* offsets)/* in: array for rec_get_offsets() */
+ const ulint* offsets)/*!< in: array for rec_get_offsets() */
{
ulint n_alloc;
ut_ad(offsets);
@@ -914,16 +909,16 @@ rec_offs_get_n_alloc(
return(n_alloc);
}
-/**************************************************************
+/**********************************************************//**
The following function sets the number of allocated elements
for an array of offsets. */
UNIV_INLINE
void
rec_offs_set_n_alloc(
/*=================*/
- ulint* offsets, /* out: array for rec_get_offsets(),
+ ulint* offsets, /*!< out: array for rec_get_offsets(),
must be allocated */
- ulint n_alloc) /* in: number of elements */
+ ulint n_alloc) /*!< in: number of elements */
{
ut_ad(offsets);
ut_ad(n_alloc > REC_OFFS_HEADER_SIZE);
@@ -931,14 +926,14 @@ rec_offs_set_n_alloc(
offsets[0] = n_alloc;
}
-/**************************************************************
-The following function returns the number of fields in a record. */
+/**********************************************************//**
+The following function returns the number of fields in a record.
+@return number of fields */
UNIV_INLINE
ulint
rec_offs_n_fields(
/*==============*/
- /* out: number of fields */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n_fields;
ut_ad(offsets);
@@ -950,16 +945,16 @@ rec_offs_n_fields(
return(n_fields);
}
-/****************************************************************
-Validates offsets returned by rec_get_offsets(). */
+/************************************************************//**
+Validates offsets returned by rec_get_offsets().
+@return TRUE if valid */
UNIV_INLINE
ibool
rec_offs_validate(
/*==============*/
- /* out: TRUE if valid */
- const rec_t* rec, /* in: record or NULL */
- const dict_index_t* index, /* in: record descriptor or NULL */
- const ulint* offsets)/* in: array returned by
+ const rec_t* rec, /*!< in: record or NULL */
+ const dict_index_t* index, /*!< in: record descriptor or NULL */
+ const ulint* offsets)/*!< in: array returned by
rec_get_offsets() */
{
ulint i = rec_offs_n_fields(offsets);
@@ -1006,16 +1001,16 @@ rec_offs_validate(
return(TRUE);
}
#ifdef UNIV_DEBUG
-/****************************************************************
+/************************************************************//**
Updates debug data in offsets, in order to avoid bogus
rec_offs_validate() failures. */
UNIV_INLINE
void
rec_offs_make_valid(
/*================*/
- const rec_t* rec, /* in: record */
- const dict_index_t* index, /* in: record descriptor */
- ulint* offsets)/* in: array returned by
+ const rec_t* rec, /*!< in: record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets)/*!< in: array returned by
rec_get_offsets() */
{
ut_ad(rec);
@@ -1027,17 +1022,17 @@ rec_offs_make_valid(
}
#endif /* UNIV_DEBUG */
-/****************************************************************
+/************************************************************//**
The following function is used to get an offset to the nth
-data field in a record. */
+data field in a record.
+@return offset from the origin of rec */
UNIV_INLINE
ulint
rec_get_nth_field_offs(
/*===================*/
- /* out: offset from the origin of rec */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n, /* in: index of the field */
- ulint* len) /* out: length of the field; UNIV_SQL_NULL
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n, /*!< in: index of the field */
+ ulint* len) /*!< out: length of the field; UNIV_SQL_NULL
if SQL null */
{
ulint offs;
@@ -1064,43 +1059,43 @@ rec_get_nth_field_offs(
return(offs);
}
-/**********************************************************
+/******************************************************//**
Determine if the offsets are for a record in the new
-compact format. */
+compact format.
+@return nonzero if compact format */
UNIV_INLINE
ulint
rec_offs_comp(
/*==========*/
- /* out: nonzero if compact format */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
return(*rec_offs_base(offsets) & REC_OFFS_COMPACT);
}
-/**********************************************************
+/******************************************************//**
Determine if the offsets are for a record containing
-externally stored columns. */
+externally stored columns.
+@return nonzero if externally stored */
UNIV_INLINE
ulint
rec_offs_any_extern(
/*================*/
- /* out: nonzero if externally stored */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
return(UNIV_UNLIKELY(*rec_offs_base(offsets) & REC_OFFS_EXTERNAL));
}
-/**********************************************************
-Returns nonzero if the extern bit is set in nth field of rec. */
+/******************************************************//**
+Returns nonzero if the extern bit is set in nth field of rec.
+@return nonzero if externally stored */
UNIV_INLINE
ulint
rec_offs_nth_extern(
/*================*/
- /* out: nonzero if externally stored */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n) /* in: nth field */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n) /*!< in: nth field */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
ut_ad(n < rec_offs_n_fields(offsets));
@@ -1108,15 +1103,15 @@ rec_offs_nth_extern(
& REC_OFFS_EXTERNAL));
}
-/**********************************************************
-Returns nonzero if the SQL NULL bit is set in nth field of rec. */
+/******************************************************//**
+Returns nonzero if the SQL NULL bit is set in nth field of rec.
+@return nonzero if SQL NULL */
UNIV_INLINE
ulint
rec_offs_nth_sql_null(
/*==================*/
- /* out: nonzero if SQL NULL */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n) /* in: nth field */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n) /*!< in: nth field */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
ut_ad(n < rec_offs_n_fields(offsets));
@@ -1124,15 +1119,15 @@ rec_offs_nth_sql_null(
& REC_OFFS_SQL_NULL));
}
-/**********************************************************
-Gets the physical size of a field. */
+/******************************************************//**
+Gets the physical size of a field.
+@return length of field */
UNIV_INLINE
ulint
rec_offs_nth_size(
/*==============*/
- /* out: length of field */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n) /* in: nth field */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n) /*!< in: nth field */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
ut_ad(n < rec_offs_n_fields(offsets));
@@ -1143,14 +1138,14 @@ rec_offs_nth_size(
& REC_OFFS_MASK);
}
-/**********************************************************
-Returns the number of extern bits set in a record. */
+/******************************************************//**
+Returns the number of extern bits set in a record.
+@return number of externally stored fields */
UNIV_INLINE
ulint
rec_offs_n_extern(
/*==============*/
- /* out: number of externally stored fields */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n = 0;
@@ -1167,20 +1162,19 @@ rec_offs_n_extern(
return(n);
}
-/**********************************************************
+/******************************************************//**
Returns the offset of n - 1th field end if the record is stored in the 1-byte
offsets form. If the field is SQL null, the flag is ORed in the returned
value. This function and the 2-byte counterpart are defined here because the
C-compiler was not able to sum negative and positive constant offsets, and
-warned of constant arithmetic overflow within the compiler. */
+warned of constant arithmetic overflow within the compiler.
+@return offset of the start of the PREVIOUS field, SQL null flag ORed */
UNIV_INLINE
ulint
rec_1_get_prev_field_end_info(
/*==========================*/
- /* out: offset of the start of the
- PREVIOUS field, SQL null flag ORed */
- const rec_t* rec, /* in: record */
- ulint n) /* in: field index */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: field index */
{
ut_ad(rec_get_1byte_offs_flag(rec));
ut_ad(n <= rec_get_n_fields_old(rec));
@@ -1188,18 +1182,17 @@ rec_1_get_prev_field_end_info(
return(mach_read_from_1(rec - (REC_N_OLD_EXTRA_BYTES + n)));
}
-/**********************************************************
+/******************************************************//**
Returns the offset of n - 1th field end if the record is stored in the 2-byte
offsets form. If the field is SQL null, the flag is ORed in the returned
-value. */
+value.
+@return offset of the start of the PREVIOUS field, SQL null flag ORed */
UNIV_INLINE
ulint
rec_2_get_prev_field_end_info(
/*==========================*/
- /* out: offset of the start of the
- PREVIOUS field, SQL null flag ORed */
- const rec_t* rec, /* in: record */
- ulint n) /* in: field index */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: field index */
{
ut_ad(!rec_get_1byte_offs_flag(rec));
ut_ad(n <= rec_get_n_fields_old(rec));
@@ -1207,16 +1200,16 @@ rec_2_get_prev_field_end_info(
return(mach_read_from_2(rec - (REC_N_OLD_EXTRA_BYTES + 2 * n)));
}
-/**********************************************************
+/******************************************************//**
Sets the field end info for the nth field if the record is stored in the
1-byte format. */
UNIV_INLINE
void
rec_1_set_field_end_info(
/*=====================*/
- rec_t* rec, /* in: record */
- ulint n, /* in: field index */
- ulint info) /* in: value to set */
+ rec_t* rec, /*!< in: record */
+ ulint n, /*!< in: field index */
+ ulint info) /*!< in: value to set */
{
ut_ad(rec_get_1byte_offs_flag(rec));
ut_ad(n < rec_get_n_fields_old(rec));
@@ -1224,16 +1217,16 @@ rec_1_set_field_end_info(
mach_write_to_1(rec - (REC_N_OLD_EXTRA_BYTES + n + 1), info);
}
-/**********************************************************
+/******************************************************//**
Sets the field end info for the nth field if the record is stored in the
2-byte format. */
UNIV_INLINE
void
rec_2_set_field_end_info(
/*=====================*/
- rec_t* rec, /* in: record */
- ulint n, /* in: field index */
- ulint info) /* in: value to set */
+ rec_t* rec, /*!< in: record */
+ ulint n, /*!< in: field index */
+ ulint info) /*!< in: value to set */
{
ut_ad(!rec_get_1byte_offs_flag(rec));
ut_ad(n < rec_get_n_fields_old(rec));
@@ -1241,16 +1234,16 @@ rec_2_set_field_end_info(
mach_write_to_2(rec - (REC_N_OLD_EXTRA_BYTES + 2 * n + 2), info);
}
-/**********************************************************
+/******************************************************//**
Returns the offset of nth field start if the record is stored in the 1-byte
-offsets form. */
+offsets form.
+@return offset of the start of the field */
UNIV_INLINE
ulint
rec_1_get_field_start_offs(
/*=======================*/
- /* out: offset of the start of the field */
- const rec_t* rec, /* in: record */
- ulint n) /* in: field index */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: field index */
{
ut_ad(rec_get_1byte_offs_flag(rec));
ut_ad(n <= rec_get_n_fields_old(rec));
@@ -1264,16 +1257,16 @@ rec_1_get_field_start_offs(
& ~REC_1BYTE_SQL_NULL_MASK);
}
-/**********************************************************
+/******************************************************//**
Returns the offset of nth field start if the record is stored in the 2-byte
-offsets form. */
+offsets form.
+@return offset of the start of the field */
UNIV_INLINE
ulint
rec_2_get_field_start_offs(
/*=======================*/
- /* out: offset of the start of the field */
- const rec_t* rec, /* in: record */
- ulint n) /* in: field index */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: field index */
{
ut_ad(!rec_get_1byte_offs_flag(rec));
ut_ad(n <= rec_get_n_fields_old(rec));
@@ -1287,18 +1280,18 @@ rec_2_get_field_start_offs(
& ~(REC_2BYTE_SQL_NULL_MASK | REC_2BYTE_EXTERN_MASK));
}
-/**********************************************************
+/******************************************************//**
The following function is used to read the offset of the start of a data field
in the record. The start of an SQL null field is the end offset of the
previous non-null field, or 0, if none exists. If n is the number of the last
-field + 1, then the end offset of the last field is returned. */
+field + 1, then the end offset of the last field is returned.
+@return offset of the start of the field */
UNIV_INLINE
ulint
rec_get_field_start_offs(
/*=====================*/
- /* out: offset of the start of the field */
- const rec_t* rec, /* in: record */
- ulint n) /* in: field index */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: field index */
{
ut_ad(rec);
ut_ad(n <= rec_get_n_fields_old(rec));
@@ -1316,17 +1309,17 @@ rec_get_field_start_offs(
return(rec_2_get_field_start_offs(rec, n));
}
-/****************************************************************
+/************************************************************//**
Gets the physical size of an old-style field.
Also an SQL null may have a field of size > 0,
-if the data type is of a fixed size. */
+if the data type is of a fixed size.
+@return field size in bytes */
UNIV_INLINE
ulint
rec_get_nth_field_size(
/*===================*/
- /* out: field size in bytes */
- const rec_t* rec, /* in: record */
- ulint n) /* in: index of the field */
+ const rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: index of the field */
{
ulint os;
ulint next_os;
@@ -1339,7 +1332,7 @@ rec_get_nth_field_size(
return(next_os - os);
}
-/***************************************************************
+/***********************************************************//**
This is used to modify the value of an already existing field in a record.
The previous value must have exactly the same size as the new value. If len
is UNIV_SQL_NULL then the field is treated as an SQL null.
@@ -1349,12 +1342,12 @@ UNIV_INLINE
void
rec_set_nth_field(
/*==============*/
- rec_t* rec, /* in: record */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n, /* in: index number of the field */
- const void* data, /* in: pointer to the data
+ rec_t* rec, /*!< in: record */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n, /*!< in: index number of the field */
+ const void* data, /*!< in: pointer to the data
if not SQL null */
- ulint len) /* in: length of the data or UNIV_SQL_NULL */
+ ulint len) /*!< in: length of the data or UNIV_SQL_NULL */
{
byte* data2;
ulint len2;
@@ -1383,32 +1376,32 @@ rec_set_nth_field(
ut_memcpy(data2, data, len);
}
-/**************************************************************
+/**********************************************************//**
The following function returns the data size of an old-style physical
record, that is the sum of field lengths. SQL null fields
are counted as length 0 fields. The value returned by the function
-is the distance from record origin to record end in bytes. */
+is the distance from record origin to record end in bytes.
+@return size */
UNIV_INLINE
ulint
rec_get_data_size_old(
/*==================*/
- /* out: size */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
ut_ad(rec);
return(rec_get_field_start_offs(rec, rec_get_n_fields_old(rec)));
}
-/**************************************************************
+/**********************************************************//**
The following function sets the number of fields in offsets. */
UNIV_INLINE
void
rec_offs_set_n_fields(
/*==================*/
- ulint* offsets, /* in/out: array returned by
+ ulint* offsets, /*!< in/out: array returned by
rec_get_offsets() */
- ulint n_fields) /* in: number of fields */
+ ulint n_fields) /*!< in: number of fields */
{
ut_ad(offsets);
ut_ad(n_fields > 0);
@@ -1418,17 +1411,17 @@ rec_offs_set_n_fields(
offsets[1] = n_fields;
}
-/**************************************************************
+/**********************************************************//**
The following function returns the data size of a physical
record, that is the sum of field lengths. SQL null fields
are counted as length 0 fields. The value returned by the function
-is the distance from record origin to record end in bytes. */
+is the distance from record origin to record end in bytes.
+@return size */
UNIV_INLINE
ulint
rec_offs_data_size(
/*===============*/
- /* out: size */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint size;
@@ -1439,16 +1432,16 @@ rec_offs_data_size(
return(size);
}
-/**************************************************************
+/**********************************************************//**
Returns the total size of record minus data size of record. The value
returned by the function is the distance from record start to record origin
-in bytes. */
+in bytes.
+@return size */
UNIV_INLINE
ulint
rec_offs_extra_size(
/*================*/
- /* out: size */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint size;
ut_ad(rec_offs_validate(NULL, NULL, offsets));
@@ -1457,56 +1450,56 @@ rec_offs_extra_size(
return(size);
}
-/**************************************************************
-Returns the total size of a physical record. */
+/**********************************************************//**
+Returns the total size of a physical record.
+@return size */
UNIV_INLINE
ulint
rec_offs_size(
/*==========*/
- /* out: size */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
return(rec_offs_data_size(offsets) + rec_offs_extra_size(offsets));
}
-/**************************************************************
-Returns a pointer to the end of the record. */
+/**********************************************************//**
+Returns a pointer to the end of the record.
+@return pointer to end */
UNIV_INLINE
byte*
rec_get_end(
/*========*/
- /* out: pointer to end */
- rec_t* rec, /* in: pointer to record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ rec_t* rec, /*!< in: pointer to record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(rec, NULL, offsets));
return(rec + rec_offs_data_size(offsets));
}
-/**************************************************************
-Returns a pointer to the start of the record. */
+/**********************************************************//**
+Returns a pointer to the start of the record.
+@return pointer to start */
UNIV_INLINE
byte*
rec_get_start(
/*==========*/
- /* out: pointer to start */
- rec_t* rec, /* in: pointer to record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ rec_t* rec, /*!< in: pointer to record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(rec, NULL, offsets));
return(rec - rec_offs_extra_size(offsets));
}
-/*******************************************************************
-Copies a physical record to a buffer. */
+/***************************************************************//**
+Copies a physical record to a buffer.
+@return pointer to the origin of the copy */
UNIV_INLINE
rec_t*
rec_copy(
/*=====*/
- /* out: pointer to the origin of the copy */
- void* buf, /* in: buffer */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ void* buf, /*!< in: buffer */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint extra_len;
ulint data_len;
@@ -1523,17 +1516,17 @@ rec_copy(
return((byte*)buf + extra_len);
}
-/**************************************************************
+/**********************************************************//**
Returns the extra size of an old-style physical record if we know its
-data size and number of fields. */
+data size and number of fields.
+@return extra size */
UNIV_INLINE
ulint
rec_get_converted_extra_size(
/*=========================*/
- /* out: extra size */
- ulint data_size, /* in: data size */
- ulint n_fields, /* in: number of fields */
- ulint n_ext) /* in: number of externally stored columns */
+ ulint data_size, /*!< in: data size */
+ ulint n_fields, /*!< in: number of fields */
+ ulint n_ext) /*!< in: number of externally stored columns */
{
if (!n_ext && data_size <= REC_1BYTE_OFFS_LIMIT) {
@@ -1543,17 +1536,17 @@ rec_get_converted_extra_size(
return(REC_N_OLD_EXTRA_BYTES + 2 * n_fields);
}
-/**************************************************************
+/**********************************************************//**
The following function returns the size of a data tuple when converted to
-a physical record. */
+a physical record.
+@return size */
UNIV_INLINE
ulint
rec_get_converted_size(
/*===================*/
- /* out: size */
- dict_index_t* index, /* in: record descriptor */
- const dtuple_t* dtuple, /* in: data tuple */
- ulint n_ext) /* in: number of externally stored columns */
+ dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ ulint n_ext) /*!< in: number of externally stored columns */
{
ulint data_size;
ulint extra_size;
@@ -1577,7 +1570,7 @@ rec_get_converted_size(
dtuple->n_fields, NULL));
}
- data_size = dtuple_get_data_size(dtuple);
+ data_size = dtuple_get_data_size(dtuple, 0);
extra_size = rec_get_converted_extra_size(
data_size, dtuple_get_n_fields(dtuple), n_ext);
@@ -1585,22 +1578,23 @@ rec_get_converted_size(
return(data_size + extra_size);
}
-/****************************************************************
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
Folds a prefix of a physical record to a ulint. Folds only existing fields,
-that is, checks that we do not run out of the record. */
+that is, checks that we do not run out of the record.
+@return the folded value */
UNIV_INLINE
ulint
rec_fold(
/*=====*/
- /* out: the folded value */
- const rec_t* rec, /* in: the physical record */
- const ulint* offsets, /* in: array returned by
+ const rec_t* rec, /*!< in: the physical record */
+ const ulint* offsets, /*!< in: array returned by
rec_get_offsets() */
- ulint n_fields, /* in: number of complete
+ ulint n_fields, /*!< in: number of complete
fields to fold */
- ulint n_bytes, /* in: number of bytes to fold
+ ulint n_bytes, /*!< in: number of bytes to fold
in an incomplete last field */
- dulint tree_id) /* in: index tree id */
+ dulint tree_id) /*!< in: index tree id */
{
ulint i;
const byte* data;
@@ -1650,3 +1644,4 @@ rec_fold(
return(fold);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/rem0types.h b/storage/xtradb/include/rem0types.h
index d0b11b92495..8b84d4af233 100644
--- a/storage/xtradb/include/rem0types.h
+++ b/storage/xtradb/include/rem0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file include/rem0types.h
Record manager global types
Created 5/30/1994 Heikki Tuuri
diff --git a/storage/xtradb/include/row0ext.h b/storage/xtradb/include/row0ext.h
index 08ebafa4d98..43d82d644e6 100644
--- a/storage/xtradb/include/row0ext.h
+++ b/storage/xtradb/include/row0ext.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0ext.h
Caching of externally stored column prefixes
Created September 2006 Marko Makela
@@ -30,65 +31,61 @@ Created September 2006 Marko Makela
#include "data0types.h"
#include "mem0mem.h"
-/************************************************************************
-Creates a cache of column prefixes of externally stored columns. */
+/********************************************************************//**
+Creates a cache of column prefixes of externally stored columns.
+@return own: column prefix cache */
UNIV_INTERN
row_ext_t*
row_ext_create(
/*===========*/
- /* out,own: column prefix cache */
- ulint n_ext, /* in: number of externally stored columns */
- const ulint* ext, /* in: col_no's of externally stored columns
+ ulint n_ext, /*!< in: number of externally stored columns */
+ const ulint* ext, /*!< in: col_no's of externally stored columns
in the InnoDB table object, as reported by
dict_col_get_no(); NOT relative to the records
in the clustered index */
- const dtuple_t* tuple, /* in: data tuple containing the field
+ const dtuple_t* tuple, /*!< in: data tuple containing the field
references of the externally stored
columns; must be indexed by col_no;
the clustered index record must be
covered by a lock or a page latch
to prevent deletion (rollback or purge). */
- ulint zip_size,/* compressed page size in bytes, or 0 */
- mem_heap_t* heap); /* in: heap where created */
+ ulint zip_size,/*!< compressed page size in bytes, or 0 */
+ mem_heap_t* heap); /*!< in: heap where created */
-/************************************************************************
-Looks up a column prefix of an externally stored column. */
+/********************************************************************//**
+Looks up a column prefix of an externally stored column.
+@return column prefix, or NULL if the column is not stored externally,
+or pointer to field_ref_zero if the BLOB pointer is unset */
UNIV_INLINE
const byte*
row_ext_lookup_ith(
/*===============*/
- /* out: column prefix, or NULL if
- the column is not stored externally,
- or pointer to field_ref_zero
- if the BLOB pointer is unset */
- const row_ext_t* ext, /* in/out: column prefix cache */
- ulint i, /* in: index of ext->ext[] */
- ulint* len); /* out: length of prefix, in bytes,
+ const row_ext_t* ext, /*!< in/out: column prefix cache */
+ ulint i, /*!< in: index of ext->ext[] */
+ ulint* len); /*!< out: length of prefix, in bytes,
at most REC_MAX_INDEX_COL_LEN */
-/************************************************************************
-Looks up a column prefix of an externally stored column. */
+/********************************************************************//**
+Looks up a column prefix of an externally stored column.
+@return column prefix, or NULL if the column is not stored externally,
+or pointer to field_ref_zero if the BLOB pointer is unset */
UNIV_INLINE
const byte*
row_ext_lookup(
/*===========*/
- /* out: column prefix, or NULL if
- the column is not stored externally,
- or pointer to field_ref_zero
- if the BLOB pointer is unset */
- const row_ext_t* ext, /* in: column prefix cache */
- ulint col, /* in: column number in the InnoDB
+ const row_ext_t* ext, /*!< in: column prefix cache */
+ ulint col, /*!< in: column number in the InnoDB
table object, as reported by
dict_col_get_no(); NOT relative to the
records in the clustered index */
- ulint* len); /* out: length of prefix, in bytes,
+ ulint* len); /*!< out: length of prefix, in bytes,
at most REC_MAX_INDEX_COL_LEN */
-/* Prefixes of externally stored columns */
+/** Prefixes of externally stored columns */
struct row_ext_struct{
- ulint n_ext; /* number of externally stored columns */
- const ulint* ext; /* col_no's of externally stored columns */
- byte* buf; /* backing store of the column prefix cache */
- ulint len[1]; /* prefix lengths; 0 if not cached */
+ ulint n_ext; /*!< number of externally stored columns */
+ const ulint* ext; /*!< col_no's of externally stored columns */
+ byte* buf; /*!< backing store of the column prefix cache */
+ ulint len[1]; /*!< prefix lengths; 0 if not cached */
};
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/row0ext.ic b/storage/xtradb/include/row0ext.ic
index e56fc175764..82771a9312a 100644
--- a/storage/xtradb/include/row0ext.ic
+++ b/storage/xtradb/include/row0ext.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0ext.ic
Caching of externally stored column prefixes
Created September 2006 Marko Makela
@@ -25,19 +26,17 @@ Created September 2006 Marko Makela
#include "rem0types.h"
#include "btr0types.h"
-/************************************************************************
-Looks up a column prefix of an externally stored column. */
+/********************************************************************//**
+Looks up a column prefix of an externally stored column.
+@return column prefix, or NULL if the column is not stored externally,
+or pointer to field_ref_zero if the BLOB pointer is unset */
UNIV_INLINE
const byte*
row_ext_lookup_ith(
/*===============*/
- /* out: column prefix, or NULL if
- the column is not stored externally,
- or pointer to field_ref_zero
- if the BLOB pointer is unset */
- const row_ext_t* ext, /* in/out: column prefix cache */
- ulint i, /* in: index of ext->ext[] */
- ulint* len) /* out: length of prefix, in bytes,
+ const row_ext_t* ext, /*!< in/out: column prefix cache */
+ ulint i, /*!< in: index of ext->ext[] */
+ ulint* len) /*!< out: length of prefix, in bytes,
at most REC_MAX_INDEX_COL_LEN */
{
ut_ad(ext);
@@ -54,22 +53,20 @@ row_ext_lookup_ith(
}
}
-/************************************************************************
-Looks up a column prefix of an externally stored column. */
+/********************************************************************//**
+Looks up a column prefix of an externally stored column.
+@return column prefix, or NULL if the column is not stored externally,
+or pointer to field_ref_zero if the BLOB pointer is unset */
UNIV_INLINE
const byte*
row_ext_lookup(
/*===========*/
- /* out: column prefix, or NULL if
- the column is not stored externally,
- or pointer to field_ref_zero
- if the BLOB pointer is unset */
- const row_ext_t* ext, /* in: column prefix cache */
- ulint col, /* in: column number in the InnoDB
+ const row_ext_t* ext, /*!< in: column prefix cache */
+ ulint col, /*!< in: column number in the InnoDB
table object, as reported by
dict_col_get_no(); NOT relative to the
records in the clustered index */
- ulint* len) /* out: length of prefix, in bytes,
+ ulint* len) /*!< out: length of prefix, in bytes,
at most REC_MAX_INDEX_COL_LEN */
{
ulint i;
diff --git a/storage/xtradb/include/row0ins.h b/storage/xtradb/include/row0ins.h
index 6aa83bed0f6..530622e6225 100644
--- a/storage/xtradb/include/row0ins.h
+++ b/storage/xtradb/include/row0ins.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0ins.h
Insert into a table
Created 4/20/1996 Heikki Tuuri
@@ -32,38 +33,37 @@ Created 4/20/1996 Heikki Tuuri
#include "trx0types.h"
#include "row0types.h"
-/*******************************************************************
+/***************************************************************//**
Checks if foreign key constraint fails for an index entry. Sets shared locks
which lock either the success or the failure of the constraint. NOTE that
-the caller must have a shared latch on dict_foreign_key_check_lock. */
+the caller must have a shared latch on dict_foreign_key_check_lock.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_NO_REFERENCED_ROW, or
+DB_ROW_IS_REFERENCED */
UNIV_INTERN
ulint
row_ins_check_foreign_constraint(
/*=============================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_NO_REFERENCED_ROW,
- or DB_ROW_IS_REFERENCED */
- ibool check_ref,/* in: TRUE If we want to check that
+ ibool check_ref,/*!< in: TRUE If we want to check that
the referenced table is ok, FALSE if we
want to to check the foreign key table */
- dict_foreign_t* foreign,/* in: foreign constraint; NOTE that the
+ dict_foreign_t* foreign,/*!< in: foreign constraint; NOTE that the
tables mentioned in it must be in the
dictionary cache if they exist at all */
- dict_table_t* table, /* in: if check_ref is TRUE, then the foreign
+ dict_table_t* table, /*!< in: if check_ref is TRUE, then the foreign
table, else the referenced table */
- dtuple_t* entry, /* in: index entry for index */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
-Creates an insert node struct. */
+ dtuple_t* entry, /*!< in: index entry for index */
+ que_thr_t* thr); /*!< in: query thread */
+/*********************************************************************//**
+Creates an insert node struct.
+@return own: insert node struct */
UNIV_INTERN
ins_node_t*
ins_node_create(
/*============*/
- /* out, own: insert node struct */
- ulint ins_type, /* in: INS_VALUES, ... */
- dict_table_t* table, /* in: table where to insert */
- mem_heap_t* heap); /* in: mem heap where created */
-/*************************************************************************
+ ulint ins_type, /*!< in: INS_VALUES, ... */
+ dict_table_t* table, /*!< in: table where to insert */
+ mem_heap_t* heap); /*!< in: mem heap where created */
+/*********************************************************************//**
Sets a new row to insert for an INS_DIRECT node. This function is only used
if we have constructed the row separately, which is a rare case; this
function is quite slow. */
@@ -71,61 +71,60 @@ UNIV_INTERN
void
ins_node_set_new_row(
/*=================*/
- ins_node_t* node, /* in: insert node */
- dtuple_t* row); /* in: new row (or first row) for the node */
-/*******************************************************************
+ ins_node_t* node, /*!< in: insert node */
+ dtuple_t* row); /*!< in: new row (or first row) for the node */
+/***************************************************************//**
Inserts an index entry to index. Tries first optimistic, then pessimistic
descent down the tree. If the entry matches enough to a delete marked record,
performs the insert by updating or delete unmarking the delete marked
-record. */
+record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DUPLICATE_KEY, or some other error code */
UNIV_INTERN
ulint
row_ins_index_entry(
/*================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DUPLICATE_KEY, or some other error code */
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in: index entry to insert */
- ulint n_ext, /* in: number of externally stored columns */
- ibool foreign,/* in: TRUE=check foreign key constraints */
- que_thr_t* thr); /* in: query thread */
-/***************************************************************
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in: index entry to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ ibool foreign,/*!< in: TRUE=check foreign key constraints */
+ que_thr_t* thr); /*!< in: query thread */
+/***********************************************************//**
Inserts a row to a table. This is a high-level function used in
-SQL execution graphs. */
+SQL execution graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_ins_step(
/*=========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/***************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/***********************************************************//**
Creates an entry template for each index of a table. */
UNIV_INTERN
void
ins_node_create_entry_list(
/*=======================*/
- ins_node_t* node); /* in: row insert node */
+ ins_node_t* node); /*!< in: row insert node */
/* Insert node structure */
struct ins_node_struct{
- que_common_t common; /* node type: QUE_NODE_INSERT */
+ que_common_t common; /*!< node type: QUE_NODE_INSERT */
ulint ins_type;/* INS_VALUES, INS_SEARCHED, or INS_DIRECT */
- dtuple_t* row; /* row to insert */
- dict_table_t* table; /* table where to insert */
- sel_node_t* select; /* select in searched insert */
+ dtuple_t* row; /*!< row to insert */
+ dict_table_t* table; /*!< table where to insert */
+ sel_node_t* select; /*!< select in searched insert */
que_node_t* values_list;/* list of expressions to evaluate and
insert in an INS_VALUES insert */
- ulint state; /* node execution state */
- dict_index_t* index; /* NULL, or the next index where the index
+ ulint state; /*!< node execution state */
+ dict_index_t* index; /*!< NULL, or the next index where the index
entry should be inserted */
- dtuple_t* entry; /* NULL, or entry to insert in the index;
+ dtuple_t* entry; /*!< NULL, or entry to insert in the index;
after a successful insert of the entry,
this should be reset to NULL */
UT_LIST_BASE_NODE_T(dtuple_t)
entry_list;/* list of entries, one for each index */
byte* row_id_buf;/* buffer for the row id sys field in row */
- dulint trx_id; /* trx id or the last trx which executed the
+ trx_id_t trx_id; /*!< trx id or the last trx which executed the
node */
byte* trx_id_buf;/* buffer for the trx id sys field in row */
mem_heap_t* entry_sys_heap;
diff --git a/storage/xtradb/include/row0ins.ic b/storage/xtradb/include/row0ins.ic
index b7aeaf97834..84f6da255bf 100644
--- a/storage/xtradb/include/row0ins.ic
+++ b/storage/xtradb/include/row0ins.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0ins.ic
Insert into a table
Created 4/20/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/row0merge.h b/storage/xtradb/include/row0merge.h
index 9975497cbeb..62a5efd11f7 100644
--- a/storage/xtradb/include/row0merge.h
+++ b/storage/xtradb/include/row0merge.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0merge.h
Index build routines using a merge sort
Created 13/06/2005 Jan Lindstrom
@@ -38,38 +39,40 @@ Created 13/06/2005 Jan Lindstrom
#include "row0mysql.h"
#include "lock0types.h"
-/* This structure holds index field definitions */
-
+/** Index field definition */
struct merge_index_field_struct {
- ulint prefix_len; /* Prefix len */
- const char* field_name; /* Field name */
+ ulint prefix_len; /*!< column prefix length, or 0
+ if indexing the whole column */
+ const char* field_name; /*!< field name */
};
+/** Index field definition */
typedef struct merge_index_field_struct merge_index_field_t;
-/* This structure holds index definitions */
-
+/** Definition of an index being created */
struct merge_index_def_struct {
- const char* name; /* Index name */
- ulint ind_type; /* 0, DICT_UNIQUE,
+ const char* name; /*!< index name */
+ ulint ind_type; /*!< 0, DICT_UNIQUE,
or DICT_CLUSTERED */
- ulint n_fields; /* Number of fields in index */
- merge_index_field_t* fields; /* Field definitions */
+ ulint n_fields; /*!< number of fields
+ in index */
+ merge_index_field_t* fields; /*!< field definitions */
};
+/** Definition of an index being created */
typedef struct merge_index_def_struct merge_index_def_t;
-/*************************************************************************
-Sets an exclusive lock on a table, for the duration of creating indexes. */
+/*********************************************************************//**
+Sets an exclusive lock on a table, for the duration of creating indexes.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_merge_lock_table(
/*=================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in/out: transaction */
- dict_table_t* table, /* in: table to lock */
- enum lock_mode mode); /* in: LOCK_X or LOCK_S */
-/*************************************************************************
+ trx_t* trx, /*!< in/out: transaction */
+ dict_table_t* table, /*!< in: table to lock */
+ enum lock_mode mode); /*!< in: LOCK_X or LOCK_S */
+/*********************************************************************//**
Drop an index from the InnoDB system tables. The data dictionary must
have been locked exclusively by the caller, because the transaction
will not be committed. */
@@ -77,10 +80,10 @@ UNIV_INTERN
void
row_merge_drop_index(
/*=================*/
- dict_index_t* index, /* in: index to be removed */
- dict_table_t* table, /* in: table */
- trx_t* trx); /* in: transaction handle */
-/*************************************************************************
+ dict_index_t* index, /*!< in: index to be removed */
+ dict_table_t* table, /*!< in: table */
+ trx_t* trx); /*!< in: transaction handle */
+/*********************************************************************//**
Drop those indexes which were created before an error occurred when
building an index. The data dictionary must have been locked
exclusively by the caller, because the transaction will not be
@@ -89,110 +92,106 @@ UNIV_INTERN
void
row_merge_drop_indexes(
/*===================*/
- trx_t* trx, /* in: transaction */
- dict_table_t* table, /* in: table containing the indexes */
- dict_index_t** index, /* in: indexes to drop */
- ulint num_created); /* in: number of elements in index[] */
-/*************************************************************************
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table, /*!< in: table containing the indexes */
+ dict_index_t** index, /*!< in: indexes to drop */
+ ulint num_created); /*!< in: number of elements in index[] */
+/*********************************************************************//**
Drop all partially created indexes during crash recovery. */
UNIV_INTERN
void
row_merge_drop_temp_indexes(void);
/*=============================*/
-/*************************************************************************
+/*********************************************************************//**
Rename the tables in the data dictionary. The data dictionary must
have been locked exclusively by the caller, because the transaction
-will not be committed. */
+will not be committed.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_merge_rename_tables(
/*====================*/
- /* out: error code or DB_SUCCESS */
- dict_table_t* old_table, /* in/out: old table, renamed to
+ dict_table_t* old_table, /*!< in/out: old table, renamed to
tmp_name */
- dict_table_t* new_table, /* in/out: new table, renamed to
+ dict_table_t* new_table, /*!< in/out: new table, renamed to
old_table->name */
- const char* tmp_name, /* in: new name for old_table */
- trx_t* trx); /* in: transaction handle */
+ const char* tmp_name, /*!< in: new name for old_table */
+ trx_t* trx); /*!< in: transaction handle */
-/*************************************************************************
+/*********************************************************************//**
Create a temporary table for creating a primary key, using the definition
-of an existing table. */
+of an existing table.
+@return table, or NULL on error */
UNIV_INTERN
dict_table_t*
row_merge_create_temporary_table(
/*=============================*/
- /* out: table,
- or NULL on error */
- const char* table_name, /* in: new table name */
- const merge_index_def_t*index_def, /* in: the index definition
+ const char* table_name, /*!< in: new table name */
+ const merge_index_def_t*index_def, /*!< in: the index definition
of the primary key */
- const dict_table_t* table, /* in: old table definition */
- trx_t* trx); /* in/out: transaction
+ const dict_table_t* table, /*!< in: old table definition */
+ trx_t* trx); /*!< in/out: transaction
(sets error_state) */
-/*************************************************************************
+/*********************************************************************//**
Rename the temporary indexes in the dictionary to permanent ones. The
data dictionary must have been locked exclusively by the caller,
-because the transaction will not be committed. */
+because the transaction will not be committed.
+@return DB_SUCCESS if all OK */
UNIV_INTERN
ulint
row_merge_rename_indexes(
/*=====================*/
- /* out: DB_SUCCESS if all OK */
- trx_t* trx, /* in/out: transaction */
- dict_table_t* table); /* in/out: table with new indexes */
-/*************************************************************************
-Create the index and load in to the dictionary. */
+ trx_t* trx, /*!< in/out: transaction */
+ dict_table_t* table); /*!< in/out: table with new indexes */
+/*********************************************************************//**
+Create the index and load in to the dictionary.
+@return index, or NULL on error */
UNIV_INTERN
dict_index_t*
row_merge_create_index(
/*===================*/
- /* out: index, or NULL on error */
- trx_t* trx, /* in/out: trx (sets error_state) */
- dict_table_t* table, /* in: the index is on this table */
- const merge_index_def_t* /* in: the index definition */
- index_def);
-#ifdef ROW_MERGE_IS_INDEX_USABLE
-/*************************************************************************
-Check if a transaction can use an index. */
+ trx_t* trx, /*!< in/out: trx (sets error_state) */
+ dict_table_t* table, /*!< in: the index is on this table */
+ const merge_index_def_t*index_def);
+ /*!< in: the index definition */
+/*********************************************************************//**
+Check if a transaction can use an index.
+@return TRUE if index can be used by the transaction else FALSE */
UNIV_INTERN
ibool
row_merge_is_index_usable(
/*======================*/
- /* out: TRUE if index can be used by
- the transaction else FALSE*/
- const trx_t* trx, /* in: transaction */
- const dict_index_t* index); /* in: index to check */
-#endif /* ROW_MERGE_IS_INDEX_USABLE */
-/*************************************************************************
+ const trx_t* trx, /*!< in: transaction */
+ const dict_index_t* index); /*!< in: index to check */
+/*********************************************************************//**
If there are views that refer to the old table name then we "attach" to
-the new instance of the table else we drop it immediately. */
+the new instance of the table else we drop it immediately.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
row_merge_drop_table(
/*=================*/
- /* out: DB_SUCCESS or error code */
- trx_t* trx, /* in: transaction */
- dict_table_t* table); /* in: table instance to drop */
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table); /*!< in: table instance to drop */
-/*************************************************************************
+/*********************************************************************//**
Build indexes on a table by reading a clustered index,
creating a temporary file containing index entries, merge sorting
-these index entries and inserting sorted index entries to indexes. */
+these index entries and inserting sorted index entries to indexes.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
row_merge_build_indexes(
/*====================*/
- /* out: DB_SUCCESS or error code */
- trx_t* trx, /* in: transaction */
- dict_table_t* old_table, /* in: table where rows are
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* old_table, /*!< in: table where rows are
read from */
- dict_table_t* new_table, /* in: table where indexes are
+ dict_table_t* new_table, /*!< in: table where indexes are
created; identical to old_table
unless creating a PRIMARY KEY */
- dict_index_t** indexes, /* in: indexes to be created */
- ulint n_indexes, /* in: size of indexes[] */
- TABLE* table); /* in/out: MySQL table, for
+ dict_index_t** indexes, /*!< in: indexes to be created */
+ ulint n_indexes, /*!< in: size of indexes[] */
+ TABLE* table); /*!< in/out: MySQL table, for
reporting erroneous key value
if applicable */
#endif /* row0merge.h */
diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h
index 8e42c316209..97028622505 100644
--- a/storage/xtradb/include/row0mysql.h
+++ b/storage/xtradb/include/row0mysql.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0mysql.h
Interface between Innobase row operations and MySQL.
Contains also create table and other data dictionary operations.
@@ -39,238 +40,237 @@ extern ibool row_rollback_on_timeout;
typedef struct row_prebuilt_struct row_prebuilt_t;
-/***********************************************************************
+/*******************************************************************//**
Frees the blob heap in prebuilt when no longer needed. */
UNIV_INTERN
void
row_mysql_prebuilt_free_blob_heap(
/*==============================*/
- row_prebuilt_t* prebuilt); /* in: prebuilt struct of a
+ row_prebuilt_t* prebuilt); /*!< in: prebuilt struct of a
ha_innobase:: table handle */
-/***********************************************************************
+/*******************************************************************//**
Stores a >= 5.0.3 format true VARCHAR length to dest, in the MySQL row
-format. */
+format.
+@return pointer to the data, we skip the 1 or 2 bytes at the start
+that are used to store the len */
UNIV_INTERN
byte*
row_mysql_store_true_var_len(
/*=========================*/
- /* out: pointer to the data, we skip the 1 or 2 bytes
- at the start that are used to store the len */
- byte* dest, /* in: where to store */
- ulint len, /* in: length, must fit in two bytes */
- ulint lenlen);/* in: storage length of len: either 1 or 2 bytes */
-/***********************************************************************
+ byte* dest, /*!< in: where to store */
+ ulint len, /*!< in: length, must fit in two bytes */
+ ulint lenlen);/*!< in: storage length of len: either 1 or 2 bytes */
+/*******************************************************************//**
Reads a >= 5.0.3 format true VARCHAR length, in the MySQL row format, and
-returns a pointer to the data. */
-
+returns a pointer to the data.
+@return pointer to the data, we skip the 1 or 2 bytes at the start
+that are used to store the len */
+UNIV_INTERN
const byte*
row_mysql_read_true_varchar(
/*========================*/
- /* out: pointer to the data, we skip
- the 1 or 2 bytes at the start that are
- used to store the len */
- ulint* len, /* out: variable-length field length */
- const byte* field, /* in: field in the MySQL format */
- ulint lenlen);/* in: storage length of len: either 1
+ ulint* len, /*!< out: variable-length field length */
+ const byte* field, /*!< in: field in the MySQL format */
+ ulint lenlen);/*!< in: storage length of len: either 1
or 2 bytes */
-/***********************************************************************
+/*******************************************************************//**
Stores a reference to a BLOB in the MySQL format. */
UNIV_INTERN
void
row_mysql_store_blob_ref(
/*=====================*/
- byte* dest, /* in: where to store */
- ulint col_len,/* in: dest buffer size: determines into
+ byte* dest, /*!< in: where to store */
+ ulint col_len,/*!< in: dest buffer size: determines into
how many bytes the BLOB length is stored,
the space for the length may vary from 1
to 4 bytes */
- const void* data, /* in: BLOB data; if the value to store
+ const void* data, /*!< in: BLOB data; if the value to store
is SQL NULL this should be NULL pointer */
- ulint len); /* in: BLOB length; if the value to store
+ ulint len); /*!< in: BLOB length; if the value to store
is SQL NULL this should be 0; remember
also to set the NULL bit in the MySQL record
header! */
-/***********************************************************************
-Reads a reference to a BLOB in the MySQL format. */
-
+/*******************************************************************//**
+Reads a reference to a BLOB in the MySQL format.
+@return pointer to BLOB data */
+UNIV_INTERN
const byte*
row_mysql_read_blob_ref(
/*====================*/
- /* out: pointer to BLOB data */
- ulint* len, /* out: BLOB length */
- const byte* ref, /* in: BLOB reference in the
+ ulint* len, /*!< out: BLOB length */
+ const byte* ref, /*!< in: BLOB reference in the
MySQL format */
- ulint col_len); /* in: BLOB reference length
+ ulint col_len); /*!< in: BLOB reference length
(not BLOB length) */
-/******************************************************************
+/**************************************************************//**
Stores a non-SQL-NULL field given in the MySQL format in the InnoDB format.
The counterpart of this function is row_sel_field_store_in_mysql_format() in
-row0sel.c. */
+row0sel.c.
+@return up to which byte we used buf in the conversion */
UNIV_INTERN
byte*
row_mysql_store_col_in_innobase_format(
/*===================================*/
- /* out: up to which byte we used
- buf in the conversion */
- dfield_t* dfield, /* in/out: dfield where dtype
+ dfield_t* dfield, /*!< in/out: dfield where dtype
information must be already set when
this function is called! */
- byte* buf, /* in/out: buffer for a converted
+ byte* buf, /*!< in/out: buffer for a converted
integer value; this must be at least
col_len long then! */
- ibool row_format_col, /* TRUE if the mysql_data is from
+ ibool row_format_col, /*!< TRUE if the mysql_data is from
a MySQL row, FALSE if from a MySQL
key value;
in MySQL, a true VARCHAR storage
format differs in a row and in a
key value: in a key value the length
is always stored in 2 bytes! */
- const byte* mysql_data, /* in: MySQL column value, not
+ const byte* mysql_data, /*!< in: MySQL column value, not
SQL NULL; NOTE that dfield may also
get a pointer to mysql_data,
therefore do not discard this as long
as dfield is used! */
- ulint col_len, /* in: MySQL column length; NOTE that
+ ulint col_len, /*!< in: MySQL column length; NOTE that
this is the storage length of the
column in the MySQL format row, not
necessarily the length of the actual
payload data; if the column is a true
VARCHAR then this is irrelevant */
- ulint comp); /* in: nonzero=compact format */
-/********************************************************************
-Handles user errors and lock waits detected by the database engine. */
+ ulint comp); /*!< in: nonzero=compact format */
+/****************************************************************//**
+Handles user errors and lock waits detected by the database engine.
+@return TRUE if it was a lock wait and we should continue running the
+query thread */
UNIV_INTERN
ibool
row_mysql_handle_errors(
/*====================*/
- /* out: TRUE if it was a lock wait and
- we should continue running the query thread */
- ulint* new_err,/* out: possible new error encountered in
+ ulint* new_err,/*!< out: possible new error encountered in
rollback, or the old error which was
during the function entry */
- trx_t* trx, /* in: transaction */
- que_thr_t* thr, /* in: query thread */
- trx_savept_t* savept);/* in: savepoint */
-/************************************************************************
-Create a prebuilt struct for a MySQL table handle. */
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t* thr, /*!< in: query thread */
+ trx_savept_t* savept);/*!< in: savepoint */
+/********************************************************************//**
+Create a prebuilt struct for a MySQL table handle.
+@return own: a prebuilt struct */
UNIV_INTERN
row_prebuilt_t*
row_create_prebuilt(
/*================*/
- /* out, own: a prebuilt struct */
- dict_table_t* table); /* in: Innobase table handle */
-/************************************************************************
+ dict_table_t* table); /*!< in: Innobase table handle */
+/********************************************************************//**
Free a prebuilt struct for a MySQL table handle. */
UNIV_INTERN
void
row_prebuilt_free(
/*==============*/
- row_prebuilt_t* prebuilt, /* in, own: prebuilt struct */
- ibool dict_locked); /* in: TRUE=data dictionary locked */
-/*************************************************************************
+ row_prebuilt_t* prebuilt, /*!< in, own: prebuilt struct */
+ ibool dict_locked); /*!< in: TRUE=data dictionary locked */
+/*********************************************************************//**
Updates the transaction pointers in query graphs stored in the prebuilt
struct. */
UNIV_INTERN
void
row_update_prebuilt_trx(
/*====================*/
- /* out: prebuilt dtuple */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL
- handle */
- trx_t* trx); /* in: transaction handle */
-/*************************************************************************
+ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct
+ in MySQL handle */
+ trx_t* trx); /*!< in: transaction handle */
+/*********************************************************************//**
Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
UNIV_INTERN
void
row_unlock_table_autoinc_for_mysql(
/*===============================*/
- trx_t* trx); /* in/out: transaction */
-/*************************************************************************
+ trx_t* trx); /*!< in/out: transaction */
+/*********************************************************************//**
Sets an AUTO_INC type lock on the table mentioned in prebuilt. The
AUTO_INC lock gives exclusive access to the auto-inc counter of the
table. The lock is reserved only for the duration of an SQL statement.
It is not compatible with another AUTO_INC or exclusive lock on the
-table. */
+table.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_lock_table_autoinc_for_mysql(
/*=============================*/
- /* out: error code or DB_SUCCESS */
- row_prebuilt_t* prebuilt); /* in: prebuilt struct in the MySQL
+ row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in the MySQL
table handle */
-/*************************************************************************
-Sets a table lock on the table mentioned in prebuilt. */
+/*********************************************************************//**
+Sets a table lock on the table mentioned in prebuilt.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_lock_table_for_mysql(
/*=====================*/
- /* out: error code or DB_SUCCESS */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct in the MySQL
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in the MySQL
table handle */
- dict_table_t* table, /* in: table to lock, or NULL
+ dict_table_t* table, /*!< in: table to lock, or NULL
if prebuilt->table should be
locked as
prebuilt->select_lock_type */
- ulint mode); /* in: lock mode of table
+ ulint mode); /*!< in: lock mode of table
(ignored if table==NULL) */
-/*************************************************************************
-Does an insert for MySQL. */
+/*********************************************************************//**
+Does an insert for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_insert_for_mysql(
/*=================*/
- /* out: error code or DB_SUCCESS */
- byte* mysql_rec, /* in: row in the MySQL format */
- row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL
+ byte* mysql_rec, /*!< in: row in the MySQL format */
+ row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL
handle */
-/*************************************************************************
+/*********************************************************************//**
Builds a dummy query graph used in selects. */
UNIV_INTERN
void
row_prebuild_sel_graph(
/*===================*/
- row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL
handle */
-/*************************************************************************
+/*********************************************************************//**
Gets pointer to a prebuilt update vector used in updates. If the update
graph has not yet been built in the prebuilt struct, then this function
-first builds it. */
+first builds it.
+@return prebuilt update vector */
UNIV_INTERN
upd_t*
row_get_prebuilt_update_vector(
/*===========================*/
- /* out: prebuilt update vector */
- row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL
handle */
-/*************************************************************************
+/*********************************************************************//**
Checks if a table is such that we automatically created a clustered
-index on it (on row id). */
+index on it (on row id).
+@return TRUE if the clustered index was generated automatically */
UNIV_INTERN
ibool
row_table_got_default_clust_index(
/*==============================*/
- const dict_table_t* table);
-/*************************************************************************
+ 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 */
+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);
-/*************************************************************************
-Does an update or delete of a row for MySQL. */
+ 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
int
row_update_for_mysql(
/*=================*/
- /* out: error code or DB_SUCCESS */
- byte* mysql_rec, /* in: the row to be updated, in
+ byte* mysql_rec, /*!< in: the row to be updated, in
the MySQL format */
- row_prebuilt_t* prebuilt); /* in: prebuilt struct in 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
@@ -280,238 +280,235 @@ 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. */
+locks we set.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_unlock_for_mysql(
/*=================*/
- /* out: error code or DB_SUCCESS */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL
handle */
- ibool has_latches_on_recs);/* TRUE if called so that we have
+ 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. */
-/*************************************************************************
+/*********************************************************************//**
Creates an query graph node of 'update' type to be used in the MySQL
-interface. */
+interface.
+@return own: update node */
UNIV_INTERN
upd_node_t*
row_create_update_node_for_mysql(
/*=============================*/
- /* out, own: update node */
- dict_table_t* table, /* in: table to update */
- mem_heap_t* heap); /* in: mem heap from which allocated */
-/**************************************************************************
-Does a cascaded delete or set null in a foreign key operation. */
+ dict_table_t* table, /*!< in: table to update */
+ mem_heap_t* heap); /*!< in: mem heap from which allocated */
+/**********************************************************************//**
+Does a cascaded delete or set null in a foreign key operation.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_update_cascade_for_mysql(
/*=========================*/
- /* out: error code or DB_SUCCESS */
- que_thr_t* thr, /* in: query thread */
- upd_node_t* node, /* in: update node used in the cascade
+ que_thr_t* thr, /*!< in: query thread */
+ upd_node_t* node, /*!< in: update node used in the cascade
or set null operation */
- dict_table_t* table); /* in: table where we do the operation */
-/*************************************************************************
+ dict_table_t* table); /*!< in: table where we do the operation */
+/*********************************************************************//**
Locks the data dictionary exclusively for performing a table create or other
data dictionary modification operation. */
UNIV_INTERN
void
row_mysql_lock_data_dictionary_func(
/*================================*/
- trx_t* trx, /* in/out: transaction */
- const char* file, /* in: file name */
- ulint line); /* in: line number */
+ trx_t* trx, /*!< in/out: transaction */
+ const char* file, /*!< in: file name */
+ ulint line); /*!< in: line number */
#define row_mysql_lock_data_dictionary(trx) \
row_mysql_lock_data_dictionary_func(trx, __FILE__, __LINE__)
-/*************************************************************************
+/*********************************************************************//**
Unlocks the data dictionary exclusive lock. */
UNIV_INTERN
void
row_mysql_unlock_data_dictionary(
/*=============================*/
- trx_t* trx); /* in/out: transaction */
-/*************************************************************************
+ trx_t* trx); /*!< in/out: transaction */
+/*********************************************************************//**
Locks the data dictionary in shared mode from modifications, for performing
foreign key check, rollback, or other operation invisible to MySQL. */
UNIV_INTERN
void
row_mysql_freeze_data_dictionary_func(
/*==================================*/
- trx_t* trx, /* in/out: transaction */
- const char* file, /* in: file name */
- ulint line); /* in: line number */
+ trx_t* trx, /*!< in/out: transaction */
+ const char* file, /*!< in: file name */
+ ulint line); /*!< in: line number */
#define row_mysql_freeze_data_dictionary(trx) \
row_mysql_freeze_data_dictionary_func(trx, __FILE__, __LINE__)
-/*************************************************************************
+/*********************************************************************//**
Unlocks the data dictionary shared lock. */
UNIV_INTERN
void
row_mysql_unfreeze_data_dictionary(
/*===============================*/
- trx_t* trx); /* in/out: transaction */
-#ifndef UNIV_HOTBACKUP
-/*************************************************************************
+ trx_t* trx); /*!< in/out: transaction */
+/*********************************************************************//**
Creates a table for MySQL. If the name of the table ends in
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
"innodb_table_monitor", then this will also start the printing of monitor
output by the master thread. If the table name ends in "innodb_mem_validate",
-InnoDB will try to invoke mem_validate(). */
+InnoDB will try to invoke mem_validate().
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_create_table_for_mysql(
/*=======================*/
- /* out: error code or DB_SUCCESS */
- dict_table_t* table, /* in, own: table definition
+ dict_table_t* table, /*!< in, own: table definition
(will be freed) */
- trx_t* trx); /* in: transaction handle */
-/*************************************************************************
+ trx_t* trx); /*!< in: transaction handle */
+/*********************************************************************//**
Does an index creation operation for MySQL. TODO: currently failure
to create an index results in dropping the whole table! This is no problem
-currently as all indexes must be created at the same time as the table. */
+currently as all indexes must be created at the same time as the table.
+@return error number or DB_SUCCESS */
UNIV_INTERN
int
row_create_index_for_mysql(
/*=======================*/
- /* out: error number or DB_SUCCESS */
- dict_index_t* index, /* in, own: index definition
+ dict_index_t* index, /*!< in, own: index definition
(will be freed) */
- trx_t* trx, /* in: transaction handle */
- const ulint* field_lengths); /* in: if not NULL, must contain
+ trx_t* trx, /*!< in: transaction handle */
+ const ulint* field_lengths); /*!< in: if not NULL, must contain
dict_index_get_n_fields(index)
actual field lengths for the
index columns, which are
then checked for not being too
large. */
-/*************************************************************************
+/*********************************************************************//**
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.
Each foreign key constraint must be accompanied with indexes in
bot participating tables. The indexes are allowed to contain more
-fields than mentioned in the constraint. */
+fields than mentioned in the constraint.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_table_add_foreign_constraints(
/*==============================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in: transaction */
- const char* sql_string, /* in: table create statement where
+ trx_t* trx, /*!< in: transaction */
+ const char* sql_string, /*!< in: table create statement where
foreign keys are declared like:
FOREIGN KEY (a, b) REFERENCES table2(c, d),
table2 can be written also with the
database name before it: test.table2 */
- const char* name, /* in: table full name in the
+ const char* name, /*!< in: table full name in the
normalized form
database_name/table_name */
- ibool reject_fks); /* in: if TRUE, fail with error
+ ibool reject_fks); /*!< in: if TRUE, fail with error
code DB_CANNOT_ADD_CONSTRAINT if
any foreign keys are found. */
-/*************************************************************************
+/*********************************************************************//**
The master thread in srv0srv.c calls this regularly to drop tables which
we must drop in background after queries to them have ended. Such lazy
-dropping of tables is needed in ALTER TABLE on Unix. */
+dropping of tables is needed in ALTER TABLE on Unix.
+@return how many tables dropped + remaining tables in list */
UNIV_INTERN
ulint
row_drop_tables_for_mysql_in_background(void);
/*=========================================*/
- /* out: how many tables dropped
- + remaining tables in list */
-/*************************************************************************
+/*********************************************************************//**
Get the background drop list length. NOTE: the caller must own the kernel
-mutex! */
+mutex!
+@return how many tables in list */
UNIV_INTERN
ulint
row_get_background_drop_list_len_low(void);
/*======================================*/
- /* out: how many tables in list */
-/*************************************************************************
-Truncates a table for MySQL. */
+/*********************************************************************//**
+Truncates a table for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_truncate_table_for_mysql(
/*=========================*/
- /* out: error code or DB_SUCCESS */
- dict_table_t* table, /* in: table handle */
- trx_t* trx); /* in: transaction handle */
-/*************************************************************************
+ dict_table_t* table, /*!< in: table handle */
+ trx_t* trx); /*!< in: transaction handle */
+/*********************************************************************//**
Drops a table for MySQL. If the name of the dropped table ends in
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
"innodb_table_monitor", then this will also stop the printing of monitor
output by the master thread. If the data dictionary was not already locked
by the transaction, the transaction will be committed. Otherwise, the
-data dictionary will remain locked. */
+data dictionary will remain locked.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_drop_table_for_mysql(
/*=====================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: table name */
- trx_t* trx, /* in: transaction handle */
- ibool drop_db);/* in: TRUE=dropping whole database */
+ const char* name, /*!< in: table name */
+ trx_t* trx, /*!< in: transaction handle */
+ ibool drop_db);/*!< in: TRUE=dropping whole database */
-/*************************************************************************
+/*********************************************************************//**
Discards the tablespace of a table which stored in an .ibd file. Discarding
means that this function deletes the .ibd file and assigns a new table id for
-the table. Also the flag table->ibd_file_missing is set TRUE. */
+the table. Also the flag table->ibd_file_missing is set TRUE.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_discard_tablespace_for_mysql(
/*=============================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: table name */
- trx_t* trx); /* in: transaction handle */
-/*********************************************************************
+ const char* name, /*!< in: table name */
+ trx_t* trx); /*!< in: transaction handle */
+/*****************************************************************//**
Imports a tablespace. The space id in the .ibd file must match the space id
-of the table in the data dictionary. */
+of the table in the data dictionary.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_import_tablespace_for_mysql(
/*============================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: table name */
- trx_t* trx); /* in: transaction handle */
-/*************************************************************************
-Drops a database for MySQL. */
+ const char* name, /*!< in: table name */
+ trx_t* trx); /*!< in: transaction handle */
+/*********************************************************************//**
+Drops a database for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_drop_database_for_mysql(
/*========================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: database name which ends to '/' */
- trx_t* trx); /* in: transaction handle */
-/*************************************************************************
-Renames a table for MySQL. */
+ const char* name, /*!< in: database name which ends to '/' */
+ trx_t* trx); /*!< in: transaction handle */
+/*********************************************************************//**
+Renames a table for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_rename_table_for_mysql(
/*=======================*/
- /* out: error code or DB_SUCCESS */
- const char* old_name, /* in: old table name */
- const char* new_name, /* in: new table name */
- trx_t* trx, /* in: transaction handle */
- ibool commit); /* in: if TRUE then commit trx */
-/*************************************************************************
-Checks a table for corruption. */
+ const char* old_name, /*!< in: old table name */
+ const char* new_name, /*!< in: new table name */
+ trx_t* trx, /*!< in: transaction handle */
+ ibool commit); /*!< in: if TRUE then commit trx */
+/*********************************************************************//**
+Checks a table for corruption.
+@return DB_ERROR or DB_SUCCESS */
UNIV_INTERN
ulint
row_check_table_for_mysql(
/*======================*/
- /* out: DB_ERROR or DB_SUCCESS */
- row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL
handle */
-#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
-Determines if a table is a magic monitor table. */
+/*********************************************************************//**
+Determines if a table is a magic monitor table.
+@return TRUE if monitor table */
UNIV_INTERN
ibool
row_is_magic_monitor_table(
/*=======================*/
- /* out: TRUE if monitor table */
- const char* table_name); /* in: name of the table, in the
+ const char* table_name); /*!< in: name of the table, in the
form database/table_name */
/* A struct describing a place for an individual column in the MySQL
@@ -521,24 +518,24 @@ Innobase and MySQL. */
typedef struct mysql_row_templ_struct mysql_row_templ_t;
struct mysql_row_templ_struct {
- ulint col_no; /* column number of the column */
- ulint rec_field_no; /* field number of the column in an
+ ulint col_no; /*!< column number of the column */
+ ulint rec_field_no; /*!< field number of the column in an
Innobase record in the current index;
not defined if template_type is
ROW_MYSQL_WHOLE_ROW */
- ulint mysql_col_offset; /* offset of the column in the MySQL
+ ulint mysql_col_offset; /*!< offset of the column in the MySQL
row format */
- ulint mysql_col_len; /* length of the column in the MySQL
+ ulint mysql_col_len; /*!< length of the column in the MySQL
row format */
- ulint mysql_null_byte_offset; /* MySQL NULL bit byte offset in a
+ ulint mysql_null_byte_offset; /*!< MySQL NULL bit byte offset in a
MySQL record */
- ulint mysql_null_bit_mask; /* bit mask to get the NULL bit,
+ ulint mysql_null_bit_mask; /*!< bit mask to get the NULL bit,
zero if column cannot be NULL */
- ulint type; /* column type in Innobase mtype
+ ulint type; /*!< column type in Innobase mtype
numbers DATA_CHAR... */
- ulint mysql_type; /* MySQL type code; this is always
+ ulint mysql_type; /*!< MySQL type code; this is always
< 256 */
- ulint mysql_length_bytes; /* if mysql_type
+ ulint mysql_length_bytes; /*!< if mysql_type
== DATA_MYSQL_TRUE_VARCHAR, this tells
whether we should use 1 or 2 bytes to
store the MySQL true VARCHAR data
@@ -546,13 +543,13 @@ struct mysql_row_templ_struct {
format (NOTE that the MySQL key value
format always uses 2 bytes for the data
len) */
- ulint charset; /* MySQL charset-collation code
+ ulint charset; /*!< MySQL charset-collation code
of the column, or zero */
- ulint mbminlen; /* minimum length of a char, in bytes,
+ ulint mbminlen; /*!< minimum length of a char, in bytes,
or zero if not a char type */
- ulint mbmaxlen; /* maximum length of a char, in bytes,
+ ulint mbmaxlen; /*!< maximum length of a char, in bytes,
or zero if not a char type */
- ulint is_unsigned; /* if a column type is an integer
+ ulint is_unsigned; /*!< if a column type is an integer
type and this field is != 0, then
it is an unsigned integer type */
};
@@ -564,79 +561,81 @@ struct mysql_row_templ_struct {
#define ROW_PREBUILT_ALLOCATED 78540783
#define ROW_PREBUILT_FREED 26423527
-/* A struct for (sometimes lazily) prebuilt structures in an Innobase table
+/** A struct for (sometimes lazily) prebuilt structures in an Innobase table
handle used within MySQL; these are used to save CPU time. */
struct row_prebuilt_struct {
- ulint magic_n; /* this magic number is set to
+ ulint magic_n; /*!< this magic number is set to
ROW_PREBUILT_ALLOCATED when created,
or ROW_PREBUILT_FREED when the
struct has been freed */
- dict_table_t* table; /* Innobase table handle */
- trx_t* trx; /* current transaction handle */
- ibool sql_stat_start; /* TRUE when we start processing of
+ dict_table_t* table; /*!< Innobase table handle */
+ dict_index_t* index; /*!< current index for a search, if
+ any */
+ trx_t* trx; /*!< current transaction handle */
+ unsigned sql_stat_start:1;/*!< TRUE when we start processing of
an SQL statement: we may have to set
an intention lock on the table,
create a consistent read view etc. */
- ibool mysql_has_locked; /* this is set TRUE when MySQL
+ unsigned mysql_has_locked:1;/*!< this is set TRUE when MySQL
calls external_lock on this handle
with a lock flag, and set FALSE when
with the F_UNLOCK flag */
- ibool clust_index_was_generated;
- /* if the user did not define a
+ unsigned clust_index_was_generated:1;
+ /*!< if the user did not define a
primary key in MySQL, then Innobase
automatically generated a clustered
index where the ordering column is
the row id: in this case this flag
is set to TRUE */
- dict_index_t* index; /* current index for a search, if
- any */
- ulint read_just_key; /* set to 1 when MySQL calls
+ unsigned index_usable:1; /*!< caches the value of
+ row_merge_is_index_usable(trx,index) */
+ unsigned read_just_key:1;/*!< set to 1 when MySQL calls
ha_innobase::extra with the
argument HA_EXTRA_KEYREAD; it is enough
to read just columns defined in
the index (i.e., no read of the
clustered index record necessary) */
- ibool used_in_HANDLER;/* TRUE if we have been using this
+ unsigned used_in_HANDLER:1;/*!< TRUE if we have been using this
handle in a MySQL HANDLER low level
index cursor command: then we must
store the pcur position even in a
unique search from a clustered index,
because HANDLER allows NEXT and PREV
in such a situation */
- ulint template_type; /* ROW_MYSQL_WHOLE_ROW,
+ unsigned template_type:2;/*!< ROW_MYSQL_WHOLE_ROW,
ROW_MYSQL_REC_FIELDS,
ROW_MYSQL_DUMMY_TEMPLATE, or
ROW_MYSQL_NO_TEMPLATE */
- ulint n_template; /* number of elements in the
+ unsigned n_template:10; /*!< number of elements in the
template */
- ulint null_bitmap_len;/* number of bytes in the SQL NULL
+ unsigned null_bitmap_len:10;/*!< number of bytes in the SQL NULL
bitmap at the start of a row in the
MySQL format */
- ibool need_to_access_clustered; /* if we are fetching
+ unsigned need_to_access_clustered:1; /*!< if we are fetching
columns through a secondary index
and at least one column is not in
the secondary index, then this is
set to TRUE */
- ibool templ_contains_blob;/* TRUE if the template contains
+ unsigned templ_contains_blob:1;/*!< TRUE if the template contains
BLOB column(s) */
- mysql_row_templ_t* mysql_template;/* template used to transform
+ mysql_row_templ_t* mysql_template;/*!< template used to transform
rows fast between MySQL and Innobase
formats; memory for this template
is not allocated from 'heap' */
- mem_heap_t* heap; /* memory heap from which
+ mem_heap_t* heap; /*!< memory heap from which
these auxiliary structures are
allocated when needed */
- ins_node_t* ins_node; /* Innobase SQL insert node
+ ins_node_t* ins_node; /*!< Innobase SQL insert node
used to perform inserts
to the table */
- byte* ins_upd_rec_buff;/* buffer for storing data converted
+ byte* ins_upd_rec_buff;/*!< buffer for storing data converted
to the Innobase format from the MySQL
format */
- const byte* default_rec; /* the default values of all columns
+ const byte* default_rec; /*!< the default values of all columns
(a "default row") in MySQL format */
ulint hint_need_to_fetch_extra_cols;
- /* normally this is set to 0; if this
+ /*!< normally this is set to 0; if this
is set to ROW_RETRIEVE_PRIMARY_KEY,
then we should at least retrieve all
columns in the primary key; if this
@@ -644,33 +643,33 @@ struct row_prebuilt_struct {
we must retrieve all columns in the
key (if read_just_key == 1), or all
columns in the table */
- upd_node_t* upd_node; /* Innobase SQL update node used
+ upd_node_t* upd_node; /*!< Innobase SQL update node used
to perform updates and deletes */
- que_fork_t* ins_graph; /* Innobase SQL query graph used
+ que_fork_t* ins_graph; /*!< Innobase SQL query graph used
in inserts */
- que_fork_t* upd_graph; /* Innobase SQL query graph used
+ que_fork_t* upd_graph; /*!< Innobase SQL query graph used
in updates or deletes */
- btr_pcur_t* pcur; /* persistent cursor used in selects
+ btr_pcur_t* pcur; /*!< persistent cursor used in selects
and updates */
- btr_pcur_t* clust_pcur; /* persistent cursor used in
+ btr_pcur_t* clust_pcur; /*!< persistent cursor used in
some selects and updates */
- que_fork_t* sel_graph; /* dummy query graph used in
+ que_fork_t* sel_graph; /*!< dummy query graph used in
selects */
- dtuple_t* search_tuple; /* prebuilt dtuple used in selects */
+ dtuple_t* search_tuple; /*!< prebuilt dtuple used in selects */
byte row_id[DATA_ROW_ID_LEN];
- /* if the clustered index was
+ /*!< if the clustered index was
generated, the row id of the
last row fetched is stored
here */
- dtuple_t* clust_ref; /* prebuilt dtuple used in
+ dtuple_t* clust_ref; /*!< prebuilt dtuple used in
sel/upd/del */
- ulint select_lock_type;/* LOCK_NONE, LOCK_S, or LOCK_X */
- ulint stored_select_lock_type;/* this field is used to
+ ulint select_lock_type;/*!< LOCK_NONE, LOCK_S, or LOCK_X */
+ ulint stored_select_lock_type;/*!< this field is used to
remember the original select_lock_type
that was decided in ha_innodb.cc,
::store_lock(), ::external_lock(),
etc. */
- ulint row_read_type; /* ROW_READ_WITH_LOCKS if row locks
+ ulint row_read_type; /*!< ROW_READ_WITH_LOCKS if row locks
should be the obtained for records
under an UPDATE or DELETE cursor.
If innodb_locks_unsafe_for_binlog
@@ -695,7 +694,7 @@ struct row_prebuilt_struct {
This eliminates lock waits in some
cases; note that this breaks
serializability. */
- ulint new_rec_locks; /* normally 0; if
+ ulint new_rec_locks; /*!< normally 0; if
srv_locks_unsafe_for_binlog is
TRUE or session is using READ
COMMITTED isolation level, in a
@@ -710,15 +709,15 @@ struct row_prebuilt_struct {
these can be used to implement a
'mini-rollback' that releases
the latest record locks */
- ulint mysql_prefix_len;/* byte offset of the end of
+ 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
+ ulint mysql_row_len; /*!< length in bytes of a row in the
MySQL format */
- ulint n_rows_fetched; /* number of rows fetched after
+ ulint n_rows_fetched; /*!< number of rows fetched after
positioning the current cursor */
- ulint fetch_direction;/* ROW_SEL_NEXT or ROW_SEL_PREV */
+ ulint fetch_direction;/*!< ROW_SEL_NEXT or ROW_SEL_PREV */
byte* fetch_cache[MYSQL_FETCH_CACHE_SIZE];
- /* a cache for fetched rows if we
+ /*!< a cache for fetched rows if we
fetch many rows from the same cursor:
it saves CPU time to fetch them in a
batch; we reserve mysql_row_len
@@ -727,36 +726,37 @@ struct row_prebuilt_struct {
allocated mem buf start, because
there is a 4 byte magic number at the
start and at the end */
- ibool keep_other_fields_on_keyread; /* when using fetch
+ ibool keep_other_fields_on_keyread; /*!< when using fetch
cache with HA_EXTRA_KEYREAD, don't
overwrite other fields in mysql row
row buffer.*/
- ulint fetch_cache_first;/* position of the first not yet
+ ulint fetch_cache_first;/*!< position of the first not yet
fetched row in fetch_cache */
- ulint n_fetch_cached; /* number of not yet fetched rows
+ ulint n_fetch_cached; /*!< number of not yet fetched rows
in fetch_cache */
- mem_heap_t* blob_heap; /* in SELECTS BLOB fields are copied
+ mem_heap_t* blob_heap; /*!< in SELECTS BLOB fields are copied
to this heap */
- mem_heap_t* old_vers_heap; /* memory heap where a previous
+ mem_heap_t* old_vers_heap; /*!< memory heap where a previous
version is built in consistent read */
/*----------------------*/
- ulonglong autoinc_last_value;/* last value of AUTO-INC interval */
- ulonglong autoinc_increment;/* The increment step of the auto
+ ulonglong autoinc_last_value;
+ /*!< last value of AUTO-INC interval */
+ ulonglong autoinc_increment;/*!< The increment step of the auto
increment column. Value must be
greater than or equal to 1. Required to
calculate the next value */
- ulonglong autoinc_offset; /* The offset passed to
+ ulonglong autoinc_offset; /*!< The offset passed to
get_auto_increment() by MySQL. Required
to calculate the next value */
- ulint autoinc_error; /* The actual error code encountered
+ ulint autoinc_error; /*!< The actual error code encountered
while trying to init or read the
autoinc value from the table. We
store it here so that we can return
it to MySQL */
/*----------------------*/
UT_LIST_NODE_T(row_prebuilt_t) prebuilts;
- /* list node of table->prebuilts */
- ulint magic_n2; /* this should be the same as
+ /*!< list node of table->prebuilts */
+ ulint magic_n2; /*!< this should be the same as
magic_n */
};
diff --git a/storage/xtradb/include/row0mysql.ic b/storage/xtradb/include/row0mysql.ic
index 5260ae17924..35033aa2ad1 100644
--- a/storage/xtradb/include/row0mysql.ic
+++ b/storage/xtradb/include/row0mysql.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0mysql.ic
MySQL interface for Innobase
Created 1/23/2001 Heikki Tuuri
diff --git a/storage/xtradb/include/row0purge.h b/storage/xtradb/include/row0purge.h
index fbc12f8d389..89ec54fb54a 100644
--- a/storage/xtradb/include/row0purge.h
+++ b/storage/xtradb/include/row0purge.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0purge.h
Purge obsolete records
Created 3/14/1997 Heikki Tuuri
@@ -34,56 +35,56 @@ Created 3/14/1997 Heikki Tuuri
#include "que0types.h"
#include "row0types.h"
-/************************************************************************
-Creates a purge node to a query graph. */
+/********************************************************************//**
+Creates a purge node to a query graph.
+@return own: purge node */
UNIV_INTERN
purge_node_t*
row_purge_node_create(
/*==================*/
- /* out, own: purge node */
- que_thr_t* parent, /* in: parent node, i.e., a thr node */
- mem_heap_t* heap); /* in: memory heap where created */
-/***************************************************************
+ que_thr_t* parent, /*!< in: parent node, i.e., a thr node */
+ mem_heap_t* heap); /*!< in: memory heap where created */
+/***********************************************************//**
Does the purge operation for a single undo log record. This is a high-level
-function used in an SQL execution graph. */
+function used in an SQL execution graph.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_purge_step(
/*===========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
+ que_thr_t* thr); /*!< in: query thread */
/* Purge node structure */
struct purge_node_struct{
- que_common_t common; /* node type: QUE_NODE_PURGE */
+ que_common_t common; /*!< node type: QUE_NODE_PURGE */
/*----------------------*/
/* Local storage for this graph node */
- dulint roll_ptr;/* roll pointer to undo log record */
+ roll_ptr_t roll_ptr;/* roll pointer to undo log record */
trx_undo_rec_t* undo_rec;/* undo log record */
trx_undo_inf_t* reservation;/* reservation for the undo log record in
the purge array */
- dulint undo_no;/* undo number of the record */
+ undo_no_t undo_no;/* undo number of the record */
ulint rec_type;/* undo log record type: TRX_UNDO_INSERT_REC,
... */
- btr_pcur_t pcur; /* persistent cursor used in searching the
+ btr_pcur_t pcur; /*!< persistent cursor used in searching the
clustered index record */
ibool found_clust;/* TRUE if the clustered index record
determined by ref was found in the clustered
index, and we were able to position pcur on
it */
- dict_table_t* table; /* table where purge is done */
+ dict_table_t* table; /*!< table where purge is done */
ulint cmpl_info;/* compiler analysis info of an update */
- upd_t* update; /* update vector for a clustered index
+ upd_t* update; /*!< update vector for a clustered index
record */
- dtuple_t* ref; /* NULL, or row reference to the next row to
+ dtuple_t* ref; /*!< NULL, or row reference to the next row to
handle */
- dtuple_t* row; /* NULL, or a copy (also fields copied to
+ dtuple_t* row; /*!< NULL, or a copy (also fields copied to
heap) of the indexed fields of the row to
handle */
- dict_index_t* index; /* NULL, or the next index whose record should
+ dict_index_t* index; /*!< NULL, or the next index whose record should
be handled */
- mem_heap_t* heap; /* memory heap used as auxiliary storage for
+ mem_heap_t* heap; /*!< memory heap used as auxiliary storage for
row; this must be emptied after a successful
purge of a row */
};
diff --git a/storage/xtradb/include/row0purge.ic b/storage/xtradb/include/row0purge.ic
index 5fc665e9d20..23d7d3845a4 100644
--- a/storage/xtradb/include/row0purge.ic
+++ b/storage/xtradb/include/row0purge.ic
@@ -17,7 +17,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0purge.ic
Purge obsolete records
Created 3/14/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/row0row.h b/storage/xtradb/include/row0row.h
index 26c4b5e4e71..723b7b53395 100644
--- a/storage/xtradb/include/row0row.h
+++ b/storage/xtradb/include/row0row.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0row.h
General row routines
Created 4/20/1996 Heikki Tuuri
@@ -36,74 +37,71 @@ Created 4/20/1996 Heikki Tuuri
#include "row0types.h"
#include "btr0types.h"
-/*************************************************************************
+/*********************************************************************//**
Gets the offset of the trx id field, in bytes relative to the origin of
-a clustered index record. */
+a clustered index record.
+@return offset of DATA_TRX_ID */
UNIV_INTERN
ulint
row_get_trx_id_offset(
/*==================*/
- /* out: offset of DATA_TRX_ID */
- const rec_t* rec, /* in: record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets);/* in: rec_get_offsets(rec, index) */
-/*************************************************************************
-Reads the trx id field from a clustered index record. */
+ const rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */
+/*********************************************************************//**
+Reads the trx id field from a clustered index record.
+@return value of the field */
UNIV_INLINE
-dulint
+trx_id_t
row_get_rec_trx_id(
/*===============*/
- /* out: value of the field */
- const rec_t* rec, /* in: record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets);/* in: rec_get_offsets(rec, index) */
-/*************************************************************************
-Reads the roll pointer field from a clustered index record. */
+ const rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */
+/*********************************************************************//**
+Reads the roll pointer field from a clustered index record.
+@return value of the field */
UNIV_INLINE
-dulint
+roll_ptr_t
row_get_rec_roll_ptr(
/*=================*/
- /* out: value of the field */
- const rec_t* rec, /* in: record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets);/* in: rec_get_offsets(rec, index) */
-/*********************************************************************
+ const rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */
+/*****************************************************************//**
When an insert or purge to a table is performed, this function builds
-the entry to be inserted into or purged from an index on the table. */
+the entry to be inserted into or purged from an index on the table.
+@return index entry which should be inserted or purged, or NULL if the
+externally stored columns in the clustered index record are
+unavailable and ext != NULL */
UNIV_INTERN
dtuple_t*
row_build_index_entry(
/*==================*/
- /* out: index entry which should be
- inserted or purged, or NULL if the
- externally stored columns in the
- clustered index record are unavailable
- and ext != NULL */
- const dtuple_t* row, /* in: row which should be
+ const dtuple_t* row, /*!< in: row which should be
inserted or purged */
- row_ext_t* ext, /* in: externally stored column prefixes,
+ row_ext_t* ext, /*!< in: externally stored column prefixes,
or NULL */
- dict_index_t* index, /* in: index on the table */
- mem_heap_t* heap); /* in: memory heap from which the memory for
+ dict_index_t* index, /*!< in: index on the table */
+ mem_heap_t* heap); /*!< in: memory heap from which the memory for
the index entry is allocated */
-/***********************************************************************
+/*******************************************************************//**
An inverse function to row_build_index_entry. Builds a row from a
-record in a clustered index. */
+record in a clustered index.
+@return own: row built; see the NOTE below! */
UNIV_INTERN
dtuple_t*
row_build(
/*======*/
- /* out, own: row built;
- see the NOTE below! */
- ulint type, /* in: ROW_COPY_POINTERS or
+ ulint type, /*!< in: ROW_COPY_POINTERS or
ROW_COPY_DATA; the latter
copies also the data fields to
heap while the first only
places pointers to data fields
on the index page, and thus is
more efficient */
- const dict_index_t* index, /* in: clustered index */
- const rec_t* rec, /* in: record in the clustered
+ const dict_index_t* index, /*!< in: clustered index */
+ const rec_t* rec, /*!< in: record in the clustered
index; NOTE: in the case
ROW_COPY_POINTERS the data
fields in the row will point
@@ -112,11 +110,11 @@ row_build(
this record must be at least
s-latched and the latch held
as long as the row dtuple is used! */
- const ulint* offsets,/* in: rec_get_offsets(rec,index)
+ const ulint* offsets,/*!< in: rec_get_offsets(rec,index)
or NULL, in which case this function
will invoke rec_get_offsets() */
const dict_table_t* col_table,
- /* in: table, to check which
+ /*!< in: table, to check which
externally stored columns
occur in the ordering columns
of an index, or NULL if
@@ -124,43 +122,41 @@ row_build(
consulted instead; the user
columns in this table should be
the same columns as in index->table */
- row_ext_t** ext, /* out, own: cache of
+ row_ext_t** ext, /*!< out, own: cache of
externally stored column
prefixes, or NULL */
- mem_heap_t* heap); /* in: memory heap from which
+ mem_heap_t* heap); /*!< in: memory heap from which
the memory needed is allocated */
-/***********************************************************************
-Converts an index record to a typed data tuple. */
+/*******************************************************************//**
+Converts an index record to a typed data tuple.
+@return index entry built; does not set info_bits, and the data fields
+in the entry will point directly to rec */
UNIV_INTERN
dtuple_t*
row_rec_to_index_entry_low(
/*=======================*/
- /* out: index entry built; does not
- set info_bits, and the data fields in
- the entry will point directly to rec */
- const rec_t* rec, /* in: record in the index */
- const dict_index_t* index, /* in: index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- ulint* n_ext, /* out: number of externally
+ const rec_t* rec, /*!< in: record in the index */
+ const dict_index_t* index, /*!< in: index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ ulint* n_ext, /*!< out: number of externally
stored columns */
- mem_heap_t* heap); /* in: memory heap from which
+ mem_heap_t* heap); /*!< in: memory heap from which
the memory needed is allocated */
-/***********************************************************************
+/*******************************************************************//**
Converts an index record to a typed data tuple. NOTE that externally
-stored (often big) fields are NOT copied to heap. */
+stored (often big) fields are NOT copied to heap.
+@return own: index entry built; see the NOTE below! */
UNIV_INTERN
dtuple_t*
row_rec_to_index_entry(
/*===================*/
- /* out, own: index entry
- built; see the NOTE below! */
- ulint type, /* in: ROW_COPY_DATA, or
+ ulint type, /*!< in: ROW_COPY_DATA, or
ROW_COPY_POINTERS: the former
copies also the data fields to
heap as the latter only places
pointers to data fields on the
index page */
- const rec_t* rec, /* in: record in the index;
+ const rec_t* rec, /*!< in: record in the index;
NOTE: in the case
ROW_COPY_POINTERS the data
fields in the row will point
@@ -169,45 +165,44 @@ row_rec_to_index_entry(
this record must be at least
s-latched and the latch held
as long as the dtuple is used! */
- const dict_index_t* index, /* in: index */
- ulint* offsets,/* in/out: rec_get_offsets(rec) */
- ulint* n_ext, /* out: number of externally
+ const dict_index_t* index, /*!< in: index */
+ ulint* offsets,/*!< in/out: rec_get_offsets(rec) */
+ ulint* n_ext, /*!< out: number of externally
stored columns */
- mem_heap_t* heap); /* in: memory heap from which
+ mem_heap_t* heap); /*!< in: memory heap from which
the memory needed is allocated */
-/***********************************************************************
+/*******************************************************************//**
Builds from a secondary index record a row reference with which we can
-search the clustered index record. */
+search the clustered index record.
+@return own: row reference built; see the NOTE below! */
UNIV_INTERN
dtuple_t*
row_build_row_ref(
/*==============*/
- /* out, own: row reference built; see the
- NOTE below! */
- ulint type, /* in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
+ ulint type, /*!< in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
the former copies also the data fields to
heap, whereas the latter only places pointers
to data fields on the index page */
- dict_index_t* index, /* in: secondary index */
- const rec_t* rec, /* in: record in the index;
+ dict_index_t* index, /*!< in: secondary index */
+ const rec_t* rec, /*!< in: record in the index;
NOTE: in the case ROW_COPY_POINTERS
the data fields in the row will point
directly into this record, therefore,
the buffer page of this record must be
at least s-latched and the latch held
as long as the row reference is used! */
- mem_heap_t* heap); /* in: memory heap from which the memory
+ mem_heap_t* heap); /*!< in: memory heap from which the memory
needed is allocated */
-/***********************************************************************
+/*******************************************************************//**
Builds from a secondary index record a row reference with which we can
search the clustered index record. */
UNIV_INTERN
void
row_build_row_ref_in_tuple(
/*=======================*/
- dtuple_t* ref, /* in/out: row reference built;
+ dtuple_t* ref, /*!< in/out: row reference built;
see the NOTE below! */
- const rec_t* rec, /* in: record in the index;
+ const rec_t* rec, /*!< in: record in the index;
NOTE: the data fields in ref
will point directly into this
record, therefore, the buffer
@@ -215,81 +210,66 @@ row_build_row_ref_in_tuple(
least s-latched and the latch
held as long as the row
reference is used! */
- const dict_index_t* index, /* in: secondary index */
- ulint* offsets,/* in: rec_get_offsets(rec, index)
+ const dict_index_t* index, /*!< in: secondary index */
+ ulint* offsets,/*!< in: rec_get_offsets(rec, index)
or NULL */
- trx_t* trx); /* in: transaction */
-/***********************************************************************
-From a row build a row reference with which we can search the clustered
-index record. */
-UNIV_INTERN
-void
-row_build_row_ref_from_row(
-/*=======================*/
- dtuple_t* ref, /* in/out: row reference built;
- see the NOTE below!
- ref must have the right number
- of fields! */
- const dict_table_t* table, /* in: table */
- const dtuple_t* row); /* in: row
- NOTE: the data fields in ref will point
- directly into data of this row */
-/***********************************************************************
+ trx_t* trx); /*!< in: transaction */
+/*******************************************************************//**
Builds from a secondary index record a row reference with which we can
search the clustered index record. */
UNIV_INLINE
void
row_build_row_ref_fast(
/*===================*/
- dtuple_t* ref, /* in/out: typed data tuple where the
+ dtuple_t* ref, /*!< in/out: typed data tuple where the
reference is built */
- const ulint* map, /* in: array of field numbers in rec
+ const ulint* map, /*!< in: array of field numbers in rec
telling how ref should be built from
the fields of rec */
- const rec_t* rec, /* in: record in the index; must be
+ const rec_t* rec, /*!< in: record in the index; must be
preserved while ref is used, as we do
not copy field values to heap */
- const ulint* offsets);/* in: array returned by rec_get_offsets() */
-/*******************************************************************
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+/***************************************************************//**
Searches the clustered index record for a row, if we have the row
-reference. */
+reference.
+@return TRUE if found */
UNIV_INTERN
ibool
row_search_on_row_ref(
/*==================*/
- /* out: TRUE if found */
- btr_pcur_t* pcur, /* out: persistent cursor, which must
+ btr_pcur_t* pcur, /*!< out: persistent cursor, which must
be closed by the caller */
- ulint mode, /* in: BTR_MODIFY_LEAF, ... */
- const dict_table_t* table, /* in: table */
- const dtuple_t* ref, /* in: row reference */
- mtr_t* mtr); /* in/out: mtr */
-/*************************************************************************
+ ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */
+ const dict_table_t* table, /*!< in: table */
+ const dtuple_t* ref, /*!< in: row reference */
+ mtr_t* mtr); /*!< in/out: mtr */
+/*********************************************************************//**
Fetches the clustered index record for a secondary index record. The latches
-on the secondary index record are preserved. */
+on the secondary index record are preserved.
+@return record or NULL, if no record found */
UNIV_INTERN
rec_t*
row_get_clust_rec(
/*==============*/
- /* out: record or NULL, if no record found */
- ulint mode, /* in: BTR_MODIFY_LEAF, ... */
- const rec_t* rec, /* in: record in a secondary index */
- dict_index_t* index, /* in: secondary index */
- dict_index_t** clust_index,/* out: clustered index */
- mtr_t* mtr); /* in: mtr */
-/*******************************************************************
-Searches an index record. */
+ ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */
+ const rec_t* rec, /*!< in: record in a secondary index */
+ dict_index_t* index, /*!< in: secondary index */
+ dict_index_t** clust_index,/*!< out: clustered index */
+ mtr_t* mtr); /*!< in: mtr */
+/***************************************************************//**
+Searches an index record.
+@return TRUE if found */
UNIV_INTERN
ibool
row_search_index_entry(
/*===================*/
- /* out: TRUE if found */
- dict_index_t* index, /* in: index */
- const dtuple_t* entry, /* in: index entry */
- ulint mode, /* in: BTR_MODIFY_LEAF, ... */
- btr_pcur_t* pcur, /* in/out: persistent cursor, which must
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* entry, /*!< in: index entry */
+ ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */
+ btr_pcur_t* pcur, /*!< in/out: persistent cursor, which must
be closed by the caller */
- mtr_t* mtr); /* in: mtr */
+ mtr_t* mtr); /*!< in: mtr */
#define ROW_COPY_DATA 1
@@ -303,25 +283,24 @@ row_search_index_entry(
No new latches may be obtained while the kernel mutex is reserved.
However, the kernel mutex can be reserved while latches are owned. */
-/***********************************************************************
+/*******************************************************************//**
Formats the raw data in "data" (in InnoDB on-disk format) using
"dict_field" and writes the result to "buf".
Not more than "buf_size" bytes are written to "buf".
-The result is always '\0'-terminated (provided buf_size > 0) and the
+The result is always NUL-terminated (provided buf_size is positive) and the
number of bytes that were written to "buf" is returned (including the
-terminating '\0'). */
+terminating NUL).
+@return number of bytes that were written */
UNIV_INTERN
ulint
row_raw_format(
/*===========*/
- /* out: number of bytes
- that were written */
- const char* data, /* in: raw data */
- ulint data_len, /* in: raw data length
+ const char* data, /*!< in: raw data */
+ ulint data_len, /*!< in: raw data length
in bytes */
- const dict_field_t* dict_field, /* in: index field */
- char* buf, /* out: output buffer */
- ulint buf_size); /* in: output buffer size
+ const dict_field_t* dict_field, /*!< in: index field */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size); /*!< in: output buffer size
in bytes */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/row0row.ic b/storage/xtradb/include/row0row.ic
index 9947dd43257..05c007641af 100644
--- a/storage/xtradb/include/row0row.ic
+++ b/storage/xtradb/include/row0row.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0row.ic
General row routines
Created 4/20/1996 Heikki Tuuri
@@ -26,16 +27,16 @@ Created 4/20/1996 Heikki Tuuri
#include "rem0rec.h"
#include "trx0undo.h"
-/*************************************************************************
-Reads the trx id field from a clustered index record. */
+/*********************************************************************//**
+Reads the trx id field from a clustered index record.
+@return value of the field */
UNIV_INLINE
-dulint
+trx_id_t
row_get_rec_trx_id(
/*===============*/
- /* out: value of the field */
- const rec_t* rec, /* in: record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ const rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
ulint offset;
@@ -51,16 +52,16 @@ row_get_rec_trx_id(
return(trx_read_trx_id(rec + offset));
}
-/*************************************************************************
-Reads the roll pointer field from a clustered index record. */
+/*********************************************************************//**
+Reads the roll pointer field from a clustered index record.
+@return value of the field */
UNIV_INLINE
-dulint
+roll_ptr_t
row_get_rec_roll_ptr(
/*=================*/
- /* out: value of the field */
- const rec_t* rec, /* in: record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ const rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
ulint offset;
@@ -76,22 +77,22 @@ row_get_rec_roll_ptr(
return(trx_read_roll_ptr(rec + offset + DATA_TRX_ID_LEN));
}
-/***********************************************************************
+/*******************************************************************//**
Builds from a secondary index record a row reference with which we can
search the clustered index record. */
UNIV_INLINE
void
row_build_row_ref_fast(
/*===================*/
- dtuple_t* ref, /* in/out: typed data tuple where the
+ dtuple_t* ref, /*!< in/out: typed data tuple where the
reference is built */
- const ulint* map, /* in: array of field numbers in rec
+ const ulint* map, /*!< in: array of field numbers in rec
telling how ref should be built from
the fields of rec */
- const rec_t* rec, /* in: record in the index; must be
+ const rec_t* rec, /*!< in: record in the index; must be
preserved while ref is used, as we do
not copy field values to heap */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
dfield_t* dfield;
const byte* field;
diff --git a/storage/xtradb/include/row0sel.h b/storage/xtradb/include/row0sel.h
index 2f8574d0691..01a5afaa23e 100644
--- a/storage/xtradb/include/row0sel.h
+++ b/storage/xtradb/include/row0sel.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0sel.h
Select
Created 12/19/1997 Heikki Tuuri
@@ -37,92 +38,93 @@ Created 12/19/1997 Heikki Tuuri
#include "read0read.h"
#include "row0mysql.h"
-/*************************************************************************
-Creates a select node struct. */
+/*********************************************************************//**
+Creates a select node struct.
+@return own: select node struct */
UNIV_INTERN
sel_node_t*
sel_node_create(
/*============*/
- /* out, own: select node struct */
- mem_heap_t* heap); /* in: memory heap where created */
-/*************************************************************************
+ mem_heap_t* heap); /*!< in: memory heap where created */
+/*********************************************************************//**
Frees the memory private to a select node when a query graph is freed,
does not free the heap where the node was originally created. */
UNIV_INTERN
void
sel_node_free_private(
/*==================*/
- sel_node_t* node); /* in: select node struct */
-/*************************************************************************
+ sel_node_t* node); /*!< in: select node struct */
+/*********************************************************************//**
Frees a prefetch buffer for a column, including the dynamically allocated
memory for data stored there. */
UNIV_INTERN
void
sel_col_prefetch_buf_free(
/*======================*/
- sel_buf_t* prefetch_buf); /* in, own: prefetch buffer */
-/*************************************************************************
-Gets the plan node for the nth table in a join. */
+ sel_buf_t* prefetch_buf); /*!< in, own: prefetch buffer */
+/*********************************************************************//**
+Gets the plan node for the nth table in a join.
+@return plan node */
UNIV_INLINE
plan_t*
sel_node_get_nth_plan(
/*==================*/
- sel_node_t* node,
- ulint i);
-/**************************************************************************
+ sel_node_t* node, /*!< in: select node */
+ ulint i); /*!< in: get ith plan node */
+/**********************************************************************//**
Performs a select step. This is a high-level function used in SQL execution
-graphs. */
+graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_sel_step(
/*=========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs an execution step of an open or close cursor statement node. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs an execution step of an open or close cursor statement node.
+@return query thread to run next or NULL */
UNIV_INLINE
que_thr_t*
open_step(
/*======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Performs a fetch for a cursor. */
+ que_thr_t* thr); /*!< in: query thread */
+/**********************************************************************//**
+Performs a fetch for a cursor.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
fetch_step(
/*=======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/********************************************************************
-Sample callback function for fetch that prints each row.*/
+ que_thr_t* thr); /*!< in: query thread */
+/****************************************************************//**
+Sample callback function for fetch that prints each row.
+@return always returns non-NULL */
UNIV_INTERN
void*
row_fetch_print(
/*============*/
- /* out: always returns non-NULL */
- void* row, /* in: sel_node_t* */
- void* user_arg); /* in: not used */
-/********************************************************************
+ void* row, /*!< in: sel_node_t* */
+ void* user_arg); /*!< in: not used */
+/****************************************************************//**
Callback function for fetch that stores an unsigned 4 byte integer to the
location pointed. The column's type must be DATA_INT, DATA_UNSIGNED, length
-= 4. */
+= 4.
+@return always returns NULL */
UNIV_INTERN
void*
row_fetch_store_uint4(
/*==================*/
- /* out: always returns NULL */
- void* row, /* in: sel_node_t* */
- void* user_arg); /* in: data pointer */
-/***************************************************************
-Prints a row in a select result. */
+ void* row, /*!< in: sel_node_t* */
+ void* user_arg); /*!< in: data pointer */
+/***********************************************************//**
+Prints a row in a select result.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_printf_step(
/*============*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/********************************************************************
+ que_thr_t* thr); /*!< in: query thread */
+/****************************************************************//**
Converts a key value stored in MySQL format to an Innobase dtuple. The last
field of the key value may be just a prefix of a fixed length field: hence
the parameter key_len. But currently we do not allow search keys where the
@@ -132,96 +134,92 @@ UNIV_INTERN
void
row_sel_convert_mysql_key_to_innobase(
/*==================================*/
- dtuple_t* tuple, /* in/out: tuple where to build;
+ dtuple_t* tuple, /*!< in/out: tuple where to build;
NOTE: we assume that the type info
in the tuple is already according
to index! */
- byte* buf, /* in: buffer to use in field
+ byte* buf, /*!< in: buffer to use in field
conversions */
- ulint buf_len, /* in: buffer length */
- dict_index_t* index, /* in: index of the key value */
- const byte* key_ptr, /* in: MySQL key value */
- ulint key_len, /* in: MySQL key value length */
- trx_t* trx); /* in: transaction */
-/************************************************************************
+ ulint buf_len, /*!< in: buffer length */
+ dict_index_t* index, /*!< in: index of the key value */
+ const byte* key_ptr, /*!< in: MySQL key value */
+ ulint key_len, /*!< in: MySQL key value length */
+ trx_t* trx); /*!< in: transaction */
+/********************************************************************//**
Searches for rows in the database. This is used in the interface to
MySQL. This function opens a cursor, and also implements fetch next
and fetch prev. NOTE that if we do a search with a full key value
from a unique index (ROW_SEL_EXACT), then we will not store the cursor
-position and fetch next or fetch prev must not be tried to the cursor! */
+position and fetch next or fetch prev must not be tried to the cursor!
+@return DB_SUCCESS, DB_RECORD_NOT_FOUND, DB_END_OF_INDEX, DB_DEADLOCK,
+DB_LOCK_TABLE_FULL, or DB_TOO_BIG_RECORD */
UNIV_INTERN
ulint
row_search_for_mysql(
/*=================*/
- /* out: DB_SUCCESS,
- DB_RECORD_NOT_FOUND,
- DB_END_OF_INDEX, DB_DEADLOCK,
- DB_LOCK_TABLE_FULL,
- or DB_TOO_BIG_RECORD */
- byte* buf, /* in/out: buffer for the fetched
+ byte* buf, /*!< in/out: buffer for the fetched
row in the MySQL format */
- ulint mode, /* in: search mode PAGE_CUR_L, ... */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct for the
+ ulint mode, /*!< in: search mode PAGE_CUR_L, ... */
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct for the
table handle; this contains the info
of search_tuple, index; if search
tuple contains 0 fields then we
position the cursor at the start or
the end of the index, depending on
'mode' */
- ulint match_mode, /* in: 0 or ROW_SEL_EXACT or
+ ulint match_mode, /*!< in: 0 or ROW_SEL_EXACT or
ROW_SEL_EXACT_PREFIX */
- ulint direction); /* in: 0 or ROW_SEL_NEXT or
+ ulint direction); /*!< in: 0 or ROW_SEL_NEXT or
ROW_SEL_PREV; NOTE: if this is != 0,
then prebuilt must have a pcur
with stored position! In opening of a
cursor 'direction' should be 0. */
-/***********************************************************************
+/*******************************************************************//**
Checks if MySQL at the moment is allowed for this table to retrieve a
-consistent read result, or store it to the query cache. */
+consistent read result, or store it to the query cache.
+@return TRUE if storing or retrieving from the query cache is permitted */
UNIV_INTERN
ibool
row_search_check_if_query_cache_permitted(
/*======================================*/
- /* out: TRUE if storing or retrieving
- from the query cache is permitted */
- trx_t* trx, /* in: transaction object */
- const char* norm_name); /* in: concatenation of database name,
+ trx_t* trx, /*!< in: transaction object */
+ const char* norm_name); /*!< in: concatenation of database name,
'/' char, table name */
-/***********************************************************************
-Read the max AUTOINC value from an index. */
+/*******************************************************************//**
+Read the max AUTOINC value from an index.
+@return DB_SUCCESS if all OK else error code */
UNIV_INTERN
ulint
row_search_max_autoinc(
/*===================*/
- /* out: DB_SUCCESS if all OK else
- error code */
- dict_index_t* index, /* in: index to search */
- const char* col_name, /* in: autoinc column name */
- ib_uint64_t* value); /* out: AUTOINC value read */
+ dict_index_t* index, /*!< in: index to search */
+ const char* col_name, /*!< in: autoinc column name */
+ ib_uint64_t* value); /*!< out: AUTOINC value read */
-/* A structure for caching column values for prefetched rows */
+/** A structure for caching column values for prefetched rows */
struct sel_buf_struct{
- byte* data; /* data, or NULL; if not NULL, this field
+ byte* data; /*!< data, or NULL; if not NULL, this field
has allocated memory which must be explicitly
freed; can be != NULL even when len is
UNIV_SQL_NULL */
- ulint len; /* data length or UNIV_SQL_NULL */
+ ulint len; /*!< data length or UNIV_SQL_NULL */
ulint val_buf_size;
- /* size of memory buffer allocated for data:
+ /*!< size of memory buffer allocated for data:
this can be more than len; this is defined
when data != NULL */
};
+/** Query plan */
struct plan_struct{
- dict_table_t* table; /* table struct in the dictionary
+ dict_table_t* table; /*!< table struct in the dictionary
cache */
- dict_index_t* index; /* table index used in the search */
- btr_pcur_t pcur; /* persistent cursor used to search
+ dict_index_t* index; /*!< table index used in the search */
+ btr_pcur_t pcur; /*!< persistent cursor used to search
the index */
- ibool asc; /* TRUE if cursor traveling upwards */
- ibool pcur_is_open; /* TRUE if pcur has been positioned
+ ibool asc; /*!< TRUE if cursor traveling upwards */
+ ibool pcur_is_open; /*!< TRUE if pcur has been positioned
and we can try to fetch new rows */
- ibool cursor_at_end; /* TRUE if the cursor is open but
+ ibool cursor_at_end; /*!< TRUE if the cursor is open but
we know that there are no more
qualifying rows left to retrieve from
the index tree; NOTE though, that
@@ -229,31 +227,34 @@ struct plan_struct{
the prefetch stack; always FALSE when
pcur_is_open is FALSE */
ibool stored_cursor_rec_processed;
- /* TRUE if the pcur position has been
+ /*!< TRUE if the pcur position has been
stored and the record it is positioned
on has already been processed */
- que_node_t** tuple_exps; /* array of expressions which are used
- to calculate the field values in the
- search tuple: there is one expression
- for each field in the search tuple */
- dtuple_t* tuple; /* search tuple */
- ulint mode; /* search mode: PAGE_CUR_G, ... */
- ulint n_exact_match; /* number of first fields in the search
- tuple which must be exactly matched */
- ibool unique_search; /* TRUE if we are searching an
+ que_node_t** tuple_exps; /*!< array of expressions
+ which are used to calculate
+ the field values in the search
+ tuple: there is one expression
+ for each field in the search
+ tuple */
+ dtuple_t* tuple; /*!< search tuple */
+ ulint mode; /*!< search mode: PAGE_CUR_G, ... */
+ ulint n_exact_match; /*!< number of first fields in
+ the search tuple which must be
+ exactly matched */
+ ibool unique_search; /*!< TRUE if we are searching an
index record with a unique key */
- ulint n_rows_fetched; /* number of rows fetched using pcur
+ ulint n_rows_fetched; /*!< number of rows fetched using pcur
after it was opened */
- ulint n_rows_prefetched;/* number of prefetched rows cached
+ ulint n_rows_prefetched;/*!< number of prefetched rows cached
for fetch: fetching several rows in
the same mtr saves CPU time */
- ulint first_prefetched;/* index of the first cached row in
+ ulint first_prefetched;/*!< index of the first cached row in
select buffer arrays for each column */
- ibool no_prefetch; /* no prefetch for this table */
- sym_node_list_t columns; /* symbol table nodes for the columns
+ ibool no_prefetch; /*!< no prefetch for this table */
+ sym_node_list_t columns; /*!< symbol table nodes for the columns
to retrieve from the table */
UT_LIST_BASE_NODE_T(func_node_t)
- end_conds; /* conditions which determine the
+ end_conds; /*!< conditions which determine the
fetch limit of the index segment we
have to look at: when one of these
fails, the result set has been
@@ -262,9 +263,9 @@ struct plan_struct{
so that in a comparison the column
for this table is the first argument */
UT_LIST_BASE_NODE_T(func_node_t)
- other_conds; /* the rest of search conditions we can
+ other_conds; /*!< the rest of search conditions we can
test at this table in a join */
- ibool must_get_clust; /* TRUE if index is a non-clustered
+ ibool must_get_clust; /*!< TRUE if index is a non-clustered
index and we must also fetch the
clustered index record; this is the
case if the non-clustered record does
@@ -272,52 +273,63 @@ struct plan_struct{
if this is a single-table explicit
cursor, or a searched update or
delete */
- ulint* clust_map; /* map telling how clust_ref is built
+ ulint* clust_map; /*!< map telling how clust_ref is built
from the fields of a non-clustered
record */
- dtuple_t* clust_ref; /* the reference to the clustered
+ dtuple_t* clust_ref; /*!< the reference to the clustered
index entry is built here if index is
a non-clustered index */
- btr_pcur_t clust_pcur; /* if index is non-clustered, we use
+ btr_pcur_t clust_pcur; /*!< if index is non-clustered, we use
this pcur to search the clustered
index */
- mem_heap_t* old_vers_heap; /* memory heap used in building an old
+ mem_heap_t* old_vers_heap; /*!< memory heap used in building an old
version of a row, or NULL */
};
+/** Select node states */
+enum sel_node_state {
+ SEL_NODE_CLOSED, /*!< it is a declared cursor which is not
+ currently open */
+ SEL_NODE_OPEN, /*!< intention locks not yet set on tables */
+ SEL_NODE_FETCH, /*!< intention locks have been set */
+ SEL_NODE_NO_MORE_ROWS /*!< cursor has reached the result set end */
+};
+
+/** Select statement node */
struct sel_node_struct{
- que_common_t common; /* node type: QUE_NODE_SELECT */
- ulint state; /* node state */
- que_node_t* select_list; /* select list */
- sym_node_t* into_list; /* variables list or NULL */
- sym_node_t* table_list; /* table list */
- ibool asc; /* TRUE if the rows should be fetched
+ que_common_t common; /*!< node type: QUE_NODE_SELECT */
+ enum sel_node_state
+ state; /*!< node state */
+ que_node_t* select_list; /*!< select list */
+ sym_node_t* into_list; /*!< variables list or NULL */
+ sym_node_t* table_list; /*!< table list */
+ ibool asc; /*!< TRUE if the rows should be fetched
in an ascending order */
- ibool set_x_locks; /* TRUE if the cursor is for update or
+ ibool set_x_locks; /*!< TRUE if the cursor is for update or
delete, which means that a row x-lock
should be placed on the cursor row */
- ulint row_lock_mode; /* LOCK_X or LOCK_S */
- ulint n_tables; /* number of tables */
- ulint fetch_table; /* number of the next table to access
+ ulint row_lock_mode; /*!< LOCK_X or LOCK_S */
+ ulint n_tables; /*!< number of tables */
+ ulint fetch_table; /*!< number of the next table to access
in the join */
- plan_t* plans; /* array of n_tables many plan nodes
+ plan_t* plans; /*!< array of n_tables many plan nodes
containing the search plan and the
search data structures */
- que_node_t* search_cond; /* search condition */
- read_view_t* read_view; /* if the query is a non-locking
+ que_node_t* search_cond; /*!< search condition */
+ read_view_t* read_view; /*!< if the query is a non-locking
consistent read, its read view is
placed here, otherwise NULL */
- ibool consistent_read;/* TRUE if the select is a consistent,
+ ibool consistent_read;/*!< TRUE if the select is a consistent,
non-locking read */
- order_node_t* order_by; /* order by column definition, or
+ order_node_t* order_by; /*!< order by column definition, or
NULL */
- ibool is_aggregate; /* TRUE if the select list consists of
+ ibool is_aggregate; /*!< TRUE if the select list consists of
aggregate functions */
ibool aggregate_already_fetched;
- /* TRUE if the aggregate row has
+ /*!< TRUE if the aggregate row has
already been fetched for the current
cursor */
- ibool can_get_updated;/* this is TRUE if the select
+ ibool can_get_updated;/*!< this is TRUE if the select
is in a single-table explicit
cursor which can get updated
within the stored procedure,
@@ -328,31 +340,22 @@ struct sel_node_struct{
checks from a stored procedure
if it contains positioned
update or delete statements */
- sym_node_t* explicit_cursor;/* not NULL if an explicit cursor */
+ sym_node_t* explicit_cursor;/*!< not NULL if an explicit cursor */
UT_LIST_BASE_NODE_T(sym_node_t)
- copy_variables; /* variables whose values we have to
+ copy_variables; /*!< variables whose values we have to
copy when an explicit cursor is opened,
so that they do not change between
fetches */
};
-/* Select node states */
-#define SEL_NODE_CLOSED 0 /* it is a declared cursor which is not
- currently open */
-#define SEL_NODE_OPEN 1 /* intention locks not yet set on
- tables */
-#define SEL_NODE_FETCH 2 /* intention locks have been set */
-#define SEL_NODE_NO_MORE_ROWS 3 /* cursor has reached the result set
- end */
-
-/* Fetch statement node */
+/** Fetch statement node */
struct fetch_node_struct{
- que_common_t common; /* type: QUE_NODE_FETCH */
- sel_node_t* cursor_def; /* cursor definition */
- sym_node_t* into_list; /* variables to set */
+ que_common_t common; /*!< type: QUE_NODE_FETCH */
+ sel_node_t* cursor_def; /*!< cursor definition */
+ sym_node_t* into_list; /*!< variables to set */
pars_user_func_t*
- func; /* User callback function or NULL.
+ func; /*!< User callback function or NULL.
The first argument to the function
is a sel_node_t*, containing the
results of the SELECT operation for
@@ -366,33 +369,42 @@ struct fetch_node_struct{
(and a useful debugging tool). */
};
-/* Open or close cursor statement node */
+/** Open or close cursor operation type */
+enum open_node_op {
+ ROW_SEL_OPEN_CURSOR, /*!< open cursor */
+ ROW_SEL_CLOSE_CURSOR /*!< close cursor */
+};
+
+/** Open or close cursor statement node */
struct open_node_struct{
- que_common_t common; /* type: QUE_NODE_OPEN */
- ulint op_type; /* ROW_SEL_OPEN_CURSOR or
- ROW_SEL_CLOSE_CURSOR */
- sel_node_t* cursor_def; /* cursor definition */
+ que_common_t common; /*!< type: QUE_NODE_OPEN */
+ enum open_node_op
+ op_type; /*!< operation type: open or
+ close cursor */
+ sel_node_t* cursor_def; /*!< cursor definition */
};
-/* Row printf statement node */
+/** Row printf statement node */
struct row_printf_node_struct{
- que_common_t common; /* type: QUE_NODE_ROW_PRINTF */
- sel_node_t* sel_node; /* select */
+ que_common_t common; /*!< type: QUE_NODE_ROW_PRINTF */
+ sel_node_t* sel_node; /*!< select */
};
-#define ROW_SEL_OPEN_CURSOR 0
-#define ROW_SEL_CLOSE_CURSOR 1
-
-/* Flags for the MySQL interface */
-#define ROW_SEL_NEXT 1
-#define ROW_SEL_PREV 2
+/** Search direction for the MySQL interface */
+enum row_sel_direction {
+ ROW_SEL_NEXT = 1, /*!< ascending direction */
+ ROW_SEL_PREV = 2 /*!< descending direction */
+};
-#define ROW_SEL_EXACT 1 /* search using a complete key value */
-#define ROW_SEL_EXACT_PREFIX 2 /* search using a key prefix which
- must match to rows: the prefix may
- contain an incomplete field (the
- last field in prefix may be just
- a prefix of a fixed length column) */
+/** Match mode for the MySQL interface */
+enum row_sel_match_mode {
+ ROW_SEL_EXACT = 1, /*!< search using a complete key value */
+ ROW_SEL_EXACT_PREFIX /*!< search using a key prefix which
+ must match rows: the prefix may
+ contain an incomplete field (the last
+ field in prefix may be just a prefix
+ of a fixed length column) */
+};
#ifndef UNIV_NONINL
#include "row0sel.ic"
diff --git a/storage/xtradb/include/row0sel.ic b/storage/xtradb/include/row0sel.ic
index a21181e3237..5907f9913da 100644
--- a/storage/xtradb/include/row0sel.ic
+++ b/storage/xtradb/include/row0sel.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0sel.ic
Select
Created 12/19/1997 Heikki Tuuri
@@ -24,22 +25,22 @@ Created 12/19/1997 Heikki Tuuri
#include "que0que.h"
-/*************************************************************************
-Gets the plan node for the nth table in a join. */
+/*********************************************************************//**
+Gets the plan node for the nth table in a join.
+@return plan node */
UNIV_INLINE
plan_t*
sel_node_get_nth_plan(
/*==================*/
- /* out: plan node */
- sel_node_t* node, /* in: select node */
- ulint i) /* in: get ith plan node */
+ sel_node_t* node, /*!< in: select node */
+ ulint i) /*!< in: get ith plan node */
{
ut_ad(i < node->n_tables);
return(node->plans + i);
}
-/*************************************************************************
+/*********************************************************************//**
Resets the cursor defined by sel_node to the SEL_NODE_OPEN state, which means
that it will start fetching from the start of the result set again, regardless
of where it was before, and it will set intention locks on the tables. */
@@ -47,19 +48,19 @@ UNIV_INLINE
void
sel_node_reset_cursor(
/*==================*/
- sel_node_t* node) /* in: select node */
+ sel_node_t* node) /*!< in: select node */
{
node->state = SEL_NODE_OPEN;
}
-/**************************************************************************
-Performs an execution step of an open or close cursor statement node. */
+/**********************************************************************//**
+Performs an execution step of an open or close cursor statement node.
+@return query thread to run next or NULL */
UNIV_INLINE
que_thr_t*
open_step(
/*======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
sel_node_t* sel_node;
open_node_t* node;
diff --git a/storage/xtradb/include/row0types.h b/storage/xtradb/include/row0types.h
index f0af7c2bf53..7920fd75061 100644
--- a/storage/xtradb/include/row0types.h
+++ b/storage/xtradb/include/row0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0types.h
Row operation global types
Created 12/27/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/row0uins.h b/storage/xtradb/include/row0uins.h
index 16bbbbd0d12..77b071c3a6b 100644
--- a/storage/xtradb/include/row0uins.h
+++ b/storage/xtradb/include/row0uins.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0uins.h
Fresh insert undo
Created 2/25/1997 Heikki Tuuri
@@ -33,18 +34,18 @@ Created 2/25/1997 Heikki Tuuri
#include "row0types.h"
#include "mtr0mtr.h"
-/***************************************************************
+/***********************************************************//**
Undoes a fresh insert of a row to a table. A fresh insert means that
the same clustered index unique key did not have any record, even delete
marked, at the time of the insert. InnoDB is eager in a rollback:
if it figures out that an index record will be removed in the purge
-anyway, it will remove it in the rollback. */
+anyway, it will remove it in the rollback.
+@return DB_SUCCESS */
UNIV_INTERN
ulint
row_undo_ins(
/*=========*/
- /* out: DB_SUCCESS */
- undo_node_t* node); /* in: row undo node */
+ undo_node_t* node); /*!< in: row undo node */
#ifndef UNIV_NONINL
#include "row0uins.ic"
diff --git a/storage/xtradb/include/row0uins.ic b/storage/xtradb/include/row0uins.ic
index 75bef8431eb..27606150d8e 100644
--- a/storage/xtradb/include/row0uins.ic
+++ b/storage/xtradb/include/row0uins.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0uins.ic
Fresh insert undo
Created 2/25/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/row0umod.h b/storage/xtradb/include/row0umod.h
index 3a4e8c2f9a3..ed44cc8d601 100644
--- a/storage/xtradb/include/row0umod.h
+++ b/storage/xtradb/include/row0umod.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0umod.h
Undo modify of a row
Created 2/27/1997 Heikki Tuuri
@@ -33,15 +34,15 @@ Created 2/27/1997 Heikki Tuuri
#include "row0types.h"
#include "mtr0mtr.h"
-/***************************************************************
-Undoes a modify operation on a row of a table. */
+/***********************************************************//**
+Undoes a modify operation on a row of a table.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
row_undo_mod(
/*=========*/
- /* out: DB_SUCCESS or error code */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr); /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr); /*!< in: query thread */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/row0umod.ic b/storage/xtradb/include/row0umod.ic
index 7ac7bc2fea7..ea3fd3b43c7 100644
--- a/storage/xtradb/include/row0umod.ic
+++ b/storage/xtradb/include/row0umod.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0umod.ic
Undo modify of a row
Created 2/27/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/row0undo.h b/storage/xtradb/include/row0undo.h
index a17cfb1babd..6eb4ca448b3 100644
--- a/storage/xtradb/include/row0undo.h
+++ b/storage/xtradb/include/row0undo.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0undo.h
Row undo
Created 1/8/1997 Heikki Tuuri
@@ -35,38 +36,37 @@ Created 1/8/1997 Heikki Tuuri
#include "que0types.h"
#include "row0types.h"
-/************************************************************************
-Creates a row undo node to a query graph. */
+/********************************************************************//**
+Creates a row undo node to a query graph.
+@return own: undo node */
UNIV_INTERN
undo_node_t*
row_undo_node_create(
/*=================*/
- /* out, own: undo node */
- trx_t* trx, /* in: transaction */
- que_thr_t* parent, /* in: parent node, i.e., a thr node */
- mem_heap_t* heap); /* in: memory heap where created */
-/***************************************************************
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t* parent, /*!< in: parent node, i.e., a thr node */
+ mem_heap_t* heap); /*!< in: memory heap where created */
+/***********************************************************//**
Looks for the clustered index record when node has the row reference.
The pcur in node is used in the search. If found, stores the row to node,
and stores the position of pcur, and detaches it. The pcur must be closed
-by the caller in any case. */
+by the caller in any case.
+@return TRUE if found; NOTE the node->pcur must be closed by the
+caller, regardless of the return value */
UNIV_INTERN
ibool
row_undo_search_clust_to_pcur(
/*==========================*/
- /* out: TRUE if found; NOTE the node->pcur
- must be closed by the caller, regardless of
- the return value */
- undo_node_t* node); /* in: row undo node */
-/***************************************************************
+ undo_node_t* node); /*!< in: row undo node */
+/***********************************************************//**
Undoes a row operation in a table. This is a high-level function used
-in SQL execution graphs. */
+in SQL execution graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_undo_step(
/*==========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
+ que_thr_t* thr); /*!< in: query thread */
/* A single query thread will try to perform the undo for all successive
versions of a clustered index record, if the transaction has modified it
@@ -83,51 +83,57 @@ just in the case where the transaction modified the same record several times
and another thread is currently doing the undo for successive versions of
that index record. */
-/* Undo node structure */
+/** Execution state of an undo node */
+enum undo_exec {
+ UNDO_NODE_FETCH_NEXT = 1, /*!< we should fetch the next
+ undo log record */
+ UNDO_NODE_PREV_VERS, /*!< the roll ptr to previous
+ version of a row is stored in
+ node, and undo should be done
+ based on it */
+ UNDO_NODE_INSERT, /*!< undo a fresh insert of a
+ row to a table */
+ UNDO_NODE_MODIFY /*!< undo a modify operation
+ (DELETE or UPDATE) on a row
+ of a table */
+};
+/** Undo node structure */
struct undo_node_struct{
- que_common_t common; /* node type: QUE_NODE_UNDO */
- ulint state; /* node execution state */
- trx_t* trx; /* trx for which undo is done */
- dulint roll_ptr;/* roll pointer to undo log record */
- trx_undo_rec_t* undo_rec;/* undo log record */
- dulint undo_no;/* undo number of the record */
- ulint rec_type;/* undo log record type: TRX_UNDO_INSERT_REC,
+ que_common_t common; /*!< node type: QUE_NODE_UNDO */
+ enum undo_exec state; /*!< node execution state */
+ trx_t* trx; /*!< trx for which undo is done */
+ roll_ptr_t roll_ptr;/*!< roll pointer to undo log record */
+ trx_undo_rec_t* undo_rec;/*!< undo log record */
+ undo_no_t undo_no;/*!< undo number of the record */
+ ulint rec_type;/*!< undo log record type: TRX_UNDO_INSERT_REC,
... */
- dulint new_roll_ptr; /* roll ptr to restore to clustered index
+ roll_ptr_t new_roll_ptr;
+ /*!< roll ptr to restore to clustered index
record */
- dulint new_trx_id; /* trx id to restore to clustered index
+ trx_id_t new_trx_id; /*!< trx id to restore to clustered index
record */
- btr_pcur_t pcur; /* persistent cursor used in searching the
+ btr_pcur_t pcur; /*!< persistent cursor used in searching the
clustered index record */
- dict_table_t* table; /* table where undo is done */
- ulint cmpl_info;/* compiler analysis of an update */
- upd_t* update; /* update vector for a clustered index
+ dict_table_t* table; /*!< table where undo is done */
+ ulint cmpl_info;/*!< compiler analysis of an update */
+ upd_t* update; /*!< update vector for a clustered index
record */
- dtuple_t* ref; /* row reference to the next row to handle */
- dtuple_t* row; /* a copy (also fields copied to heap) of the
+ dtuple_t* ref; /*!< row reference to the next row to handle */
+ dtuple_t* row; /*!< a copy (also fields copied to heap) of the
row to handle */
- row_ext_t* ext; /* NULL, or prefixes of the externally
+ row_ext_t* ext; /*!< NULL, or prefixes of the externally
stored columns of the row */
- dtuple_t* undo_row;/* NULL, or the row after undo */
- row_ext_t* undo_ext;/* NULL, or prefixes of the externally
+ dtuple_t* undo_row;/*!< NULL, or the row after undo */
+ row_ext_t* undo_ext;/*!< NULL, or prefixes of the externally
stored columns of undo_row */
- dict_index_t* index; /* the next index whose record should be
+ dict_index_t* index; /*!< the next index whose record should be
handled */
- mem_heap_t* heap; /* memory heap used as auxiliary storage for
+ mem_heap_t* heap; /*!< memory heap used as auxiliary storage for
row; this must be emptied after undo is tried
on a row */
};
-/* Execution states for an undo node */
-#define UNDO_NODE_FETCH_NEXT 1 /* we should fetch the next undo log
- record */
-#define UNDO_NODE_PREV_VERS 2 /* the roll ptr to previous version of
- a row is stored in node, and undo
- should be done based on it */
-#define UNDO_NODE_INSERT 3
-#define UNDO_NODE_MODIFY 4
-
#ifndef UNIV_NONINL
#include "row0undo.ic"
diff --git a/storage/xtradb/include/row0undo.ic b/storage/xtradb/include/row0undo.ic
index 921e3633b10..dc788debc14 100644
--- a/storage/xtradb/include/row0undo.ic
+++ b/storage/xtradb/include/row0undo.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0undo.ic
Row undo
Created 1/8/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/row0upd.h b/storage/xtradb/include/row0upd.h
index 71aa20d158c..635d746d5a1 100644
--- a/storage/xtradb/include/row0upd.h
+++ b/storage/xtradb/include/row0upd.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0upd.h
Update of a row
Created 12/27/1996 Heikki Tuuri
@@ -27,355 +28,360 @@ Created 12/27/1996 Heikki Tuuri
#include "univ.i"
#include "data0data.h"
+#include "row0types.h"
#include "btr0types.h"
-#include "btr0pcur.h"
#include "dict0types.h"
#include "trx0types.h"
-#include "que0types.h"
-#include "row0types.h"
-#include "pars0types.h"
-/*************************************************************************
-Creates an update vector object. */
+#ifndef UNIV_HOTBACKUP
+# include "btr0pcur.h"
+# include "que0types.h"
+# include "pars0types.h"
+#endif /* !UNIV_HOTBACKUP */
+
+/*********************************************************************//**
+Creates an update vector object.
+@return own: update vector object */
UNIV_INLINE
upd_t*
upd_create(
/*=======*/
- /* out, own: update vector object */
- ulint n, /* in: number of fields */
- mem_heap_t* heap); /* in: heap from which memory allocated */
-/*************************************************************************
+ ulint n, /*!< in: number of fields */
+ mem_heap_t* heap); /*!< in: heap from which memory allocated */
+/*********************************************************************//**
Returns the number of fields in the update vector == number of columns
-to be updated by an update vector. */
+to be updated by an update vector.
+@return number of fields */
UNIV_INLINE
ulint
upd_get_n_fields(
/*=============*/
- /* out: number of fields */
- const upd_t* update); /* in: update vector */
+ const upd_t* update); /*!< in: update vector */
#ifdef UNIV_DEBUG
-/*************************************************************************
-Returns the nth field of an update vector. */
+/*********************************************************************//**
+Returns the nth field of an update vector.
+@return update vector field */
UNIV_INLINE
upd_field_t*
upd_get_nth_field(
/*==============*/
- /* out: update vector field */
- const upd_t* update, /* in: update vector */
- ulint n); /* in: field position in update vector */
+ const upd_t* update, /*!< in: update vector */
+ ulint n); /*!< in: field position in update vector */
#else
# define upd_get_nth_field(update, n) ((update)->fields + (n))
#endif
-/*************************************************************************
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
Sets an index field number to be updated by an update vector field. */
UNIV_INLINE
void
upd_field_set_field_no(
/*===================*/
- upd_field_t* upd_field, /* in: update vector field */
- ulint field_no, /* in: field number in a clustered
+ upd_field_t* upd_field, /*!< in: update vector field */
+ ulint field_no, /*!< in: field number in a clustered
index */
- dict_index_t* index, /* in: index */
- trx_t* trx); /* in: transaction */
-/*************************************************************************
-Returns a field of an update vector by field_no. */
+ dict_index_t* index, /*!< in: index */
+ trx_t* trx); /*!< in: transaction */
+/*********************************************************************//**
+Returns a field of an update vector by field_no.
+@return update vector field, or NULL */
UNIV_INLINE
const upd_field_t*
upd_get_field_by_field_no(
/*======================*/
- /* out: update vector field, or NULL */
- const upd_t* update, /* in: update vector */
- ulint no) /* in: field_no */
+ const upd_t* update, /*!< in: update vector */
+ ulint no) /*!< in: field_no */
__attribute__((nonnull, pure));
-/*************************************************************************
+/*********************************************************************//**
Writes into the redo log the values of trx id and roll ptr and enough info
-to determine their positions within a clustered index record. */
+to determine their positions within a clustered index record.
+@return new pointer to mlog */
UNIV_INTERN
byte*
row_upd_write_sys_vals_to_log(
/*==========================*/
- /* out: new pointer to mlog */
- dict_index_t* index, /* in: clustered index */
- trx_t* trx, /* in: transaction */
- dulint roll_ptr,/* in: roll ptr of the undo log record */
- byte* log_ptr,/* pointer to a buffer of size > 20 opened
+ dict_index_t* index, /*!< in: clustered index */
+ trx_t* trx, /*!< in: transaction */
+ roll_ptr_t roll_ptr,/*!< in: roll ptr of the undo log record */
+ byte* log_ptr,/*!< pointer to a buffer of size > 20 opened
in mlog */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************************//**
Updates the trx id and roll ptr field in a clustered index record when
a row is updated or marked deleted. */
UNIV_INLINE
void
row_upd_rec_sys_fields(
/*===================*/
- rec_t* rec, /* in/out: record */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ rec_t* rec, /*!< in/out: record */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- trx_t* trx, /* in: transaction */
- dulint roll_ptr);/* in: roll ptr of the undo log record */
-/*************************************************************************
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ trx_t* trx, /*!< in: transaction */
+ roll_ptr_t roll_ptr);/*!< in: roll ptr of the undo log record */
+/*********************************************************************//**
Sets the trx id or roll ptr field of a clustered index entry. */
UNIV_INTERN
void
row_upd_index_entry_sys_field(
/*==========================*/
- const dtuple_t* entry, /* in: index entry, where the memory buffers
+ const dtuple_t* entry, /*!< in: index entry, where the memory buffers
for sys fields are already allocated:
the function just copies the new values to
them */
- dict_index_t* index, /* in: clustered index */
- ulint type, /* in: DATA_TRX_ID or DATA_ROLL_PTR */
- dulint val); /* in: value to write */
-/*************************************************************************
-Creates an update node for a query graph. */
+ dict_index_t* index, /*!< in: clustered index */
+ ulint type, /*!< in: DATA_TRX_ID or DATA_ROLL_PTR */
+ dulint val); /*!< in: value to write */
+/*********************************************************************//**
+Creates an update node for a query graph.
+@return own: update node */
UNIV_INTERN
upd_node_t*
upd_node_create(
/*============*/
- /* out, own: update node */
- mem_heap_t* heap); /* in: mem heap where created */
-/***************************************************************
+ mem_heap_t* heap); /*!< in: mem heap where created */
+/***********************************************************//**
Writes to the redo log the new values of the fields occurring in the index. */
UNIV_INTERN
void
row_upd_index_write_log(
/*====================*/
- const upd_t* update, /* in: update vector */
- byte* log_ptr,/* in: pointer to mlog buffer: must
+ const upd_t* update, /*!< in: update vector */
+ byte* log_ptr,/*!< in: pointer to mlog buffer: must
contain at least MLOG_BUF_MARGIN bytes
of free space; the buffer is closed
within this function */
- mtr_t* mtr); /* in: mtr into whose log to write */
-/***************************************************************
+ mtr_t* mtr); /*!< in: mtr into whose log to write */
+/***********************************************************//**
Returns TRUE if row update changes size of some field in index or if some
-field to be updated is stored externally in rec or update. */
+field to be updated is stored externally in rec or update.
+@return TRUE if the update changes the size of some field in index or
+the field is external in rec or update */
UNIV_INTERN
ibool
row_upd_changes_field_size_or_external(
/*===================================*/
- /* out: TRUE if the update changes the size of
- some field in index or the field is external
- in rec or update */
- dict_index_t* index, /* in: index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- const upd_t* update);/* in: update vector */
-/***************************************************************
+ dict_index_t* index, /*!< in: index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const upd_t* update);/*!< in: update vector */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************//**
Replaces the new column values stored in the update vector to the record
given. No field size changes are allowed. */
UNIV_INTERN
void
row_upd_rec_in_place(
/*=================*/
- rec_t* rec, /* in/out: record where replaced */
- dict_index_t* index, /* in: the index the record belongs to */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- const upd_t* update, /* in: update vector */
- page_zip_des_t* page_zip);/* in: compressed page with enough space
+ rec_t* rec, /*!< in/out: record where replaced */
+ dict_index_t* index, /*!< in: the index the record belongs to */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const upd_t* update, /*!< in: update vector */
+ page_zip_des_t* page_zip);/*!< in: compressed page with enough space
available, or NULL */
-/*******************************************************************
+#ifndef UNIV_HOTBACKUP
+/***************************************************************//**
Builds an update vector from those fields which in a secondary index entry
differ from a record that has the equal ordering fields. NOTE: we compare
-the fields as binary strings! */
+the fields as binary strings!
+@return own: update vector of differing fields */
UNIV_INTERN
upd_t*
row_upd_build_sec_rec_difference_binary(
/*====================================*/
- /* out, own: update vector of differing
- fields */
- dict_index_t* index, /* in: index */
- const dtuple_t* entry, /* in: entry to insert */
- const rec_t* rec, /* in: secondary index record */
- trx_t* trx, /* in: transaction */
- mem_heap_t* heap); /* in: memory heap from which allocated */
-/*******************************************************************
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* entry, /*!< in: entry to insert */
+ const rec_t* rec, /*!< in: secondary index record */
+ trx_t* trx, /*!< in: transaction */
+ mem_heap_t* heap); /*!< in: memory heap from which allocated */
+/***************************************************************//**
Builds an update vector from those fields, excluding the roll ptr and
trx id fields, which in an index entry differ from a record that has
-the equal ordering fields. NOTE: we compare the fields as binary strings! */
+the equal ordering fields. NOTE: we compare the fields as binary strings!
+@return own: update vector of differing fields, excluding roll ptr and
+trx id */
UNIV_INTERN
upd_t*
row_upd_build_difference_binary(
/*============================*/
- /* out, own: update vector of differing
- fields, excluding roll ptr and trx id */
- dict_index_t* index, /* in: clustered index */
- const dtuple_t* entry, /* in: entry to insert */
- const rec_t* rec, /* in: clustered index record */
- trx_t* trx, /* in: transaction */
- mem_heap_t* heap); /* in: memory heap from which allocated */
-/***************************************************************
+ dict_index_t* index, /*!< in: clustered index */
+ const dtuple_t* entry, /*!< in: entry to insert */
+ const rec_t* rec, /*!< in: clustered index record */
+ trx_t* trx, /*!< in: transaction */
+ mem_heap_t* heap); /*!< in: memory heap from which allocated */
+/***********************************************************//**
Replaces the new column values stored in the update vector to the index entry
given. */
UNIV_INTERN
void
row_upd_index_replace_new_col_vals_index_pos(
/*=========================================*/
- dtuple_t* entry, /* in/out: index entry where replaced;
+ dtuple_t* entry, /*!< in/out: index entry where replaced;
the clustered index record must be
covered by a lock or a page latch to
prevent deletion (rollback or purge) */
- dict_index_t* index, /* in: index; NOTE that this may also be a
+ dict_index_t* index, /*!< in: index; NOTE that this may also be a
non-clustered index */
- const upd_t* update, /* in: an update vector built for the index so
+ const upd_t* update, /*!< in: an update vector built for the index so
that the field number in an upd_field is the
index position */
ibool order_only,
- /* in: if TRUE, limit the replacement to
+ /*!< in: if TRUE, limit the replacement to
ordering fields of index; note that this
does not work for non-clustered indexes. */
- mem_heap_t* heap) /* in: memory heap for allocating and
+ mem_heap_t* heap) /*!< in: memory heap for allocating and
copying the new values */
__attribute__((nonnull));
-/***************************************************************
+/***********************************************************//**
Replaces the new column values stored in the update vector to the index entry
given. */
UNIV_INTERN
void
row_upd_index_replace_new_col_vals(
/*===============================*/
- dtuple_t* entry, /* in/out: index entry where replaced;
+ dtuple_t* entry, /*!< in/out: index entry where replaced;
the clustered index record must be
covered by a lock or a page latch to
prevent deletion (rollback or purge) */
- dict_index_t* index, /* in: index; NOTE that this may also be a
+ dict_index_t* index, /*!< in: index; NOTE that this may also be a
non-clustered index */
- const upd_t* update, /* in: an update vector built for the
+ const upd_t* update, /*!< in: an update vector built for the
CLUSTERED index so that the field number in
an upd_field is the clustered index position */
- mem_heap_t* heap) /* in: memory heap for allocating and
+ mem_heap_t* heap) /*!< in: memory heap for allocating and
copying the new values */
__attribute__((nonnull));
-/***************************************************************
+/***********************************************************//**
Replaces the new column values stored in the update vector. */
UNIV_INTERN
void
row_upd_replace(
/*============*/
- dtuple_t* row, /* in/out: row where replaced,
+ dtuple_t* row, /*!< in/out: row where replaced,
indexed by col_no;
the clustered index record must be
covered by a lock or a page latch to
prevent deletion (rollback or purge) */
- row_ext_t** ext, /* out, own: NULL, or externally
+ row_ext_t** ext, /*!< out, own: NULL, or externally
stored column prefixes */
- const dict_index_t* index, /* in: clustered index */
- const upd_t* update, /* in: an update vector built for the
+ const dict_index_t* index, /*!< in: clustered index */
+ const upd_t* update, /*!< in: an update vector built for the
clustered index */
- mem_heap_t* heap); /* in: memory heap */
-/***************************************************************
+ mem_heap_t* heap); /*!< in: memory heap */
+/***********************************************************//**
Checks if an update vector changes an ordering field of an index record.
+
This function is fast if the update vector is short or the number of ordering
fields in the index is small. Otherwise, this can be quadratic.
-NOTE: we compare the fields as binary strings! */
+NOTE: we compare the fields as binary strings!
+@return TRUE if update vector changes an ordering field in the index record */
UNIV_INTERN
ibool
row_upd_changes_ord_field_binary(
/*=============================*/
- /* out: TRUE if update vector changes
- an ordering field in the index record;
- NOTE: the fields are compared as binary
- strings */
- const dtuple_t* row, /* in: old value of row, or NULL if the
+ const dtuple_t* row, /*!< in: old value of row, or NULL if the
row and the data values in update are not
known when this function is called, e.g., at
compile time */
- dict_index_t* index, /* in: index of the record */
- const upd_t* update);/* in: update vector for the row; NOTE: the
+ dict_index_t* index, /*!< in: index of the record */
+ const upd_t* update);/*!< in: update vector for the row; NOTE: the
field numbers in this MUST be clustered index
positions! */
-/***************************************************************
+/***********************************************************//**
Checks if an update vector changes an ordering field of an index record.
This function is fast if the update vector is short or the number of ordering
fields in the index is small. Otherwise, this can be quadratic.
-NOTE: we compare the fields as binary strings! */
+NOTE: we compare the fields as binary strings!
+@return TRUE if update vector may change an ordering field in an index
+record */
UNIV_INTERN
ibool
row_upd_changes_some_index_ord_field_binary(
/*========================================*/
- /* out: TRUE if update vector
- may change an ordering field
- in an index record */
- const dict_table_t* table, /* in: table */
- const upd_t* update);/* in: update vector for the row */
-/***************************************************************
+ const dict_table_t* table, /*!< in: table */
+ const upd_t* update);/*!< in: update vector for the row */
+/***********************************************************//**
Updates a row in a table. This is a high-level function used
-in SQL execution graphs. */
+in SQL execution graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_upd_step(
/*=========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr); /* in: query thread */
-/*************************************************************************
-Parses the log data of system field values. */
+ que_thr_t* thr); /*!< in: query thread */
+#endif /* !UNIV_HOTBACKUP */
+/*********************************************************************//**
+Parses the log data of system field values.
+@return log data end or NULL */
UNIV_INTERN
byte*
row_upd_parse_sys_vals(
/*===================*/
- /* out: log data end or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- ulint* pos, /* out: TRX_ID position in record */
- dulint* trx_id, /* out: trx id */
- dulint* roll_ptr);/* out: roll ptr */
-/*************************************************************************
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ ulint* pos, /*!< out: TRX_ID position in record */
+ trx_id_t* trx_id, /*!< out: trx id */
+ roll_ptr_t* roll_ptr);/*!< out: roll ptr */
+/*********************************************************************//**
Updates the trx id and roll ptr field in a clustered index record in database
recovery. */
UNIV_INTERN
void
row_upd_rec_sys_fields_in_recovery(
/*===============================*/
- rec_t* rec, /* in/out: record */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint pos, /* in: TRX_ID position in rec */
- dulint trx_id, /* in: transaction id */
- dulint roll_ptr);/* in: roll ptr of the undo log record */
-/*************************************************************************
-Parses the log data written by row_upd_index_write_log. */
+ rec_t* rec, /*!< in/out: record */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint pos, /*!< in: TRX_ID position in rec */
+ trx_id_t trx_id, /*!< in: transaction id */
+ roll_ptr_t roll_ptr);/*!< in: roll ptr of the undo log record */
+/*********************************************************************//**
+Parses the log data written by row_upd_index_write_log.
+@return log data end or NULL */
UNIV_INTERN
byte*
row_upd_index_parse(
/*================*/
- /* out: log data end or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- mem_heap_t* heap, /* in: memory heap where update vector is
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ mem_heap_t* heap, /*!< in: memory heap where update vector is
built */
- upd_t** update_out);/* out: update vector */
+ upd_t** update_out);/*!< out: update vector */
/* Update vector field */
struct upd_field_struct{
- unsigned field_no:16; /* field number in an index, usually
+ unsigned field_no:16; /*!< field number in an index, usually
the clustered index, but in updating
a secondary index record in btr0cur.c
this is the position in the secondary
index */
- unsigned orig_len:16; /* original length of the locally
+#ifndef UNIV_HOTBACKUP
+ unsigned orig_len:16; /*!< original length of the locally
stored part of an externally stored
column, or 0 */
- que_node_t* exp; /* expression for calculating a new
+ que_node_t* exp; /*!< expression for calculating a new
value: it refers to column values and
constants in the symbol table of the
query graph */
- dfield_t new_val; /* new value for the column */
+#endif /* !UNIV_HOTBACKUP */
+ dfield_t new_val; /*!< new value for the column */
};
/* Update vector structure */
struct upd_struct{
- ulint info_bits; /* new value of info bits to record;
+ ulint info_bits; /*!< new value of info bits to record;
default is 0 */
- ulint n_fields; /* number of update fields */
- upd_field_t* fields; /* array of update fields */
+ ulint n_fields; /*!< number of update fields */
+ upd_field_t* fields; /*!< array of update fields */
};
+#ifndef UNIV_HOTBACKUP
/* Update node structure which also implements the delete operation
of a row */
struct upd_node_struct{
- que_common_t common; /* node type: QUE_NODE_UPDATE */
+ que_common_t common; /*!< node type: QUE_NODE_UPDATE */
ibool is_delete;/* TRUE if delete, FALSE if update */
ibool searched_update;
/* TRUE if searched update, FALSE if
@@ -391,16 +397,16 @@ struct upd_node_struct{
or ... SET NULL for foreign keys */
mem_heap_t* cascade_heap;/* NULL or a mem heap where the cascade
node is created */
- sel_node_t* select; /* query graph subtree implementing a base
+ sel_node_t* select; /*!< query graph subtree implementing a base
table cursor: the rows returned will be
updated */
- btr_pcur_t* pcur; /* persistent cursor placed on the clustered
+ btr_pcur_t* pcur; /*!< persistent cursor placed on the clustered
index record which should be updated or
deleted; the cursor is stored in the graph
of 'select' field above, except in the case
of the MySQL interface */
- dict_table_t* table; /* table where updated */
- upd_t* update; /* update vector for the row */
+ dict_table_t* table; /*!< table where updated */
+ upd_t* update; /*!< update vector for the row */
ulint update_n_fields;
/* when this struct is used to implement
a cascade operation for foreign keys, we store
@@ -419,18 +425,18 @@ struct upd_node_struct{
UPD_NODE_NO_SIZE_CHANGE, ORed */
/*----------------------*/
/* Local storage for this graph node */
- ulint state; /* node execution state */
- dict_index_t* index; /* NULL, or the next index whose record should
+ ulint state; /*!< node execution state */
+ dict_index_t* index; /*!< NULL, or the next index whose record should
be updated */
- dtuple_t* row; /* NULL, or a copy (also fields copied to
+ dtuple_t* row; /*!< NULL, or a copy (also fields copied to
heap) of the row to update; this must be reset
to NULL after a successful update */
- row_ext_t* ext; /* NULL, or prefixes of the externally
+ row_ext_t* ext; /*!< NULL, or prefixes of the externally
stored columns in the old row */
dtuple_t* upd_row;/* NULL, or a copy of the updated row */
row_ext_t* upd_ext;/* NULL, or prefixes of the externally
stored columns in upd_row */
- mem_heap_t* heap; /* memory heap used as auxiliary storage;
+ mem_heap_t* heap; /*!< memory heap used as auxiliary storage;
this must be emptied after a successful
update */
/*----------------------*/
@@ -468,6 +474,8 @@ struct upd_node_struct{
#define UPD_NODE_NO_SIZE_CHANGE 2 /* no record field size will be
changed in the update */
+#endif /* !UNIV_HOTBACKUP */
+
#ifndef UNIV_NONINL
#include "row0upd.ic"
#endif
diff --git a/storage/xtradb/include/row0upd.ic b/storage/xtradb/include/row0upd.ic
index a0c23aa6b07..18e22f1eca9 100644
--- a/storage/xtradb/include/row0upd.ic
+++ b/storage/xtradb/include/row0upd.ic
@@ -16,28 +16,31 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0upd.ic
Update of a row
Created 12/27/1996 Heikki Tuuri
*******************************************************/
#include "mtr0log.h"
-#include "trx0trx.h"
-#include "trx0undo.h"
-#include "row0row.h"
-#include "btr0sea.h"
+#ifndef UNIV_HOTBACKUP
+# include "trx0trx.h"
+# include "trx0undo.h"
+# include "row0row.h"
+# include "btr0sea.h"
+#endif /* !UNIV_HOTBACKUP */
#include "page0zip.h"
-/*************************************************************************
-Creates an update vector object. */
+/*********************************************************************//**
+Creates an update vector object.
+@return own: update vector object */
UNIV_INLINE
upd_t*
upd_create(
/*=======*/
- /* out, own: update vector object */
- ulint n, /* in: number of fields */
- mem_heap_t* heap) /* in: heap from which memory allocated */
+ ulint n, /*!< in: number of fields */
+ mem_heap_t* heap) /*!< in: heap from which memory allocated */
{
upd_t* update;
@@ -51,15 +54,15 @@ upd_create(
return(update);
}
-/*************************************************************************
+/*********************************************************************//**
Returns the number of fields in the update vector == number of columns
-to be updated by an update vector. */
+to be updated by an update vector.
+@return number of fields */
UNIV_INLINE
ulint
upd_get_n_fields(
/*=============*/
- /* out: number of fields */
- const upd_t* update) /* in: update vector */
+ const upd_t* update) /*!< in: update vector */
{
ut_ad(update);
@@ -67,15 +70,15 @@ upd_get_n_fields(
}
#ifdef UNIV_DEBUG
-/*************************************************************************
-Returns the nth field of an update vector. */
+/*********************************************************************//**
+Returns the nth field of an update vector.
+@return update vector field */
UNIV_INLINE
upd_field_t*
upd_get_nth_field(
/*==============*/
- /* out: update vector field */
- const upd_t* update, /* in: update vector */
- ulint n) /* in: field position in update vector */
+ const upd_t* update, /*!< in: update vector */
+ ulint n) /*!< in: field position in update vector */
{
ut_ad(update);
ut_ad(n < update->n_fields);
@@ -84,17 +87,18 @@ upd_get_nth_field(
}
#endif /* UNIV_DEBUG */
-/*************************************************************************
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
Sets an index field number to be updated by an update vector field. */
UNIV_INLINE
void
upd_field_set_field_no(
/*===================*/
- upd_field_t* upd_field, /* in: update vector field */
- ulint field_no, /* in: field number in a clustered
+ upd_field_t* upd_field, /*!< in: update vector field */
+ ulint field_no, /*!< in: field number in a clustered
index */
- dict_index_t* index, /* in: index */
- trx_t* trx) /* in: transaction */
+ dict_index_t* index, /*!< in: index */
+ trx_t* trx) /*!< in: transaction */
{
upd_field->field_no = field_no;
upd_field->orig_len = 0;
@@ -113,15 +117,15 @@ upd_field_set_field_no(
dfield_get_type(&upd_field->new_val));
}
-/*************************************************************************
-Returns a field of an update vector by field_no. */
+/*********************************************************************//**
+Returns a field of an update vector by field_no.
+@return update vector field, or NULL */
UNIV_INLINE
const upd_field_t*
upd_get_field_by_field_no(
/*======================*/
- /* out: update vector field, or NULL */
- const upd_t* update, /* in: update vector */
- ulint no) /* in: field_no */
+ const upd_t* update, /*!< in: update vector */
+ ulint no) /*!< in: field_no */
{
ulint i;
for (i = 0; i < upd_get_n_fields(update); i++) {
@@ -136,20 +140,20 @@ upd_get_field_by_field_no(
return(NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Updates the trx id and roll ptr field in a clustered index record when
a row is updated or marked deleted. */
UNIV_INLINE
void
row_upd_rec_sys_fields(
/*===================*/
- rec_t* rec, /* in/out: record */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ rec_t* rec, /*!< in/out: record */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- trx_t* trx, /* in: transaction */
- dulint roll_ptr)/* in: roll ptr of the undo log record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ trx_t* trx, /*!< in: transaction */
+ roll_ptr_t roll_ptr)/*!< in: roll ptr of the undo log record */
{
ut_ad(dict_index_is_clust(index));
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -177,3 +181,4 @@ row_upd_rec_sys_fields(
trx_write_roll_ptr(rec + offset + DATA_TRX_ID_LEN, roll_ptr);
}
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/row0vers.h b/storage/xtradb/include/row0vers.h
index 0feae77e8b5..5a2e38230d5 100644
--- a/storage/xtradb/include/row0vers.h
+++ b/storage/xtradb/include/row0vers.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0vers.h
Row versions
Created 2/6/1997 Heikki Tuuri
@@ -34,103 +35,102 @@ Created 2/6/1997 Heikki Tuuri
#include "mtr0mtr.h"
#include "read0types.h"
-/*********************************************************************
+/*****************************************************************//**
Finds out if an active transaction has inserted or modified a secondary
index record. NOTE: the kernel mutex is temporarily released in this
-function! */
+function!
+@return NULL if committed, else the active transaction */
UNIV_INTERN
trx_t*
row_vers_impl_x_locked_off_kernel(
/*==============================*/
- /* out: NULL if committed, else the active
- transaction; NOTE that the kernel mutex is
- temporarily released! */
- const rec_t* rec, /* in: record in a secondary index */
- dict_index_t* index, /* in: the secondary index */
- const ulint* offsets);/* in: rec_get_offsets(rec, index) */
-/*********************************************************************
+ const rec_t* rec, /*!< in: record in a secondary index */
+ dict_index_t* index, /*!< in: the secondary index */
+ const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */
+/*****************************************************************//**
Finds out if we must preserve a delete marked earlier version of a clustered
-index record, because it is >= the purge view. */
+index record, because it is >= the purge view.
+@return TRUE if earlier version should be preserved */
UNIV_INTERN
ibool
row_vers_must_preserve_del_marked(
/*==============================*/
- /* out: TRUE if earlier version should be preserved */
- dulint trx_id, /* in: transaction id in the version */
- mtr_t* mtr); /* in: mtr holding the latch on the clustered index
- record; it will also hold the latch on purge_view */
-/*********************************************************************
+ trx_id_t trx_id, /*!< in: transaction id in the version */
+ mtr_t* mtr); /*!< in: mtr holding the latch on the
+ clustered index record; it will also
+ hold the latch on purge_view */
+/*****************************************************************//**
Finds out if a version of the record, where the version >= the current
purge view, should have ientry as its secondary index entry. We check
if there is any not delete marked version of the record where the trx
id >= purge view, and the secondary index entry == ientry; exactly in
-this case we return TRUE. */
+this case we return TRUE.
+@return TRUE if earlier version should have */
UNIV_INTERN
ibool
row_vers_old_has_index_entry(
/*=========================*/
- /* out: TRUE if earlier version should have */
- ibool also_curr,/* in: TRUE if also rec is included in the
+ ibool also_curr,/*!< in: TRUE if also rec is included in the
versions to search; otherwise only versions
prior to it are searched */
- const rec_t* rec, /* in: record in the clustered index; the
+ const rec_t* rec, /*!< in: record in the clustered index; the
caller must have a latch on the page */
- mtr_t* mtr, /* in: mtr holding the latch on rec; it will
+ mtr_t* mtr, /*!< in: mtr holding the latch on rec; it will
also hold the latch on purge_view */
- dict_index_t* index, /* in: the secondary index */
- const dtuple_t* ientry);/* in: the secondary index entry */
-/*********************************************************************
+ dict_index_t* index, /*!< in: the secondary index */
+ const dtuple_t* ientry);/*!< in: the secondary index entry */
+/*****************************************************************//**
Constructs the version of a clustered index record which a consistent
read should see. We assume that the trx id stored in rec is such that
-the consistent read should not see rec in its present version. */
+the consistent read should not see rec in its present version.
+@return DB_SUCCESS or DB_MISSING_HISTORY */
UNIV_INTERN
ulint
row_vers_build_for_consistent_read(
/*===============================*/
- /* out: DB_SUCCESS or DB_MISSING_HISTORY */
- const rec_t* rec, /* in: record in a clustered index; the
+ const rec_t* rec, /*!< in: record in a clustered index; the
caller must have a latch on the page; this
latch locks the top of the stack of versions
of this records */
- mtr_t* mtr, /* in: mtr holding the latch on rec; it will
+ mtr_t* mtr, /*!< in: mtr holding the latch on rec; it will
also hold the latch on purge_view */
- dict_index_t* index, /* in: the clustered index */
- ulint** offsets,/* in/out: offsets returned by
+ dict_index_t* index, /*!< in: the clustered index */
+ ulint** offsets,/*!< in/out: offsets returned by
rec_get_offsets(rec, index) */
- read_view_t* view, /* in: the consistent read view */
- mem_heap_t** offset_heap,/* in/out: memory heap from which
+ read_view_t* view, /*!< in: the consistent read view */
+ mem_heap_t** offset_heap,/*!< in/out: memory heap from which
the offsets are allocated */
- mem_heap_t* in_heap,/* in: memory heap from which the memory for
+ mem_heap_t* in_heap,/*!< in: memory heap from which the memory for
*old_vers is allocated; memory for possible
intermediate versions is allocated and freed
locally within the function */
- rec_t** old_vers);/* out, own: old version, or NULL if the
+ rec_t** old_vers);/*!< out, own: old version, or NULL if the
record does not exist in the view, that is,
it was freshly inserted afterwards */
-/*********************************************************************
+/*****************************************************************//**
Constructs the last committed version of a clustered index record,
-which should be seen by a semi-consistent read. */
+which should be seen by a semi-consistent read.
+@return DB_SUCCESS or DB_MISSING_HISTORY */
UNIV_INTERN
ulint
row_vers_build_for_semi_consistent_read(
/*====================================*/
- /* out: DB_SUCCESS or DB_MISSING_HISTORY */
- const rec_t* rec, /* in: record in a clustered index; the
+ const rec_t* rec, /*!< in: record in a clustered index; the
caller must have a latch on the page; this
latch locks the top of the stack of versions
of this records */
- mtr_t* mtr, /* in: mtr holding the latch on rec */
- dict_index_t* index, /* in: the clustered index */
- ulint** offsets,/* in/out: offsets returned by
+ mtr_t* mtr, /*!< in: mtr holding the latch on rec */
+ dict_index_t* index, /*!< in: the clustered index */
+ ulint** offsets,/*!< in/out: offsets returned by
rec_get_offsets(rec, index) */
- mem_heap_t** offset_heap,/* in/out: memory heap from which
+ mem_heap_t** offset_heap,/*!< in/out: memory heap from which
the offsets are allocated */
- mem_heap_t* in_heap,/* in: memory heap from which the memory for
+ mem_heap_t* in_heap,/*!< in: memory heap from which the memory for
*old_vers is allocated; memory for possible
intermediate versions is allocated and freed
locally within the function */
- const rec_t** old_vers);/* out: rec, old version, or NULL if the
+ const rec_t** old_vers);/*!< out: rec, old version, or NULL if the
record does not exist in the view, that is,
it was freshly inserted afterwards */
diff --git a/storage/xtradb/include/row0vers.ic b/storage/xtradb/include/row0vers.ic
index aac95ea6593..8bb3a5c0cb3 100644
--- a/storage/xtradb/include/row0vers.ic
+++ b/storage/xtradb/include/row0vers.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/row0vers.ic
Row versions
Created 2/6/1997 Heikki Tuuri
diff --git a/storage/xtradb/include/srv0que.h b/storage/xtradb/include/srv0que.h
index 88db1a013f6..82ee7739ef7 100644
--- a/storage/xtradb/include/srv0que.h
+++ b/storage/xtradb/include/srv0que.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/srv0que.h
Server query execution
Created 6/5/1996 Heikki Tuuri
@@ -28,41 +29,14 @@ Created 6/5/1996 Heikki Tuuri
#include "univ.i"
#include "que0types.h"
-/**************************************************************************
-Checks if there is work to do in the server task queue. If there is, the
-thread starts processing a task. Before leaving, it again checks the task
-queue and picks a new task if any exists. This is called by a SRV_WORKER
-thread. */
-UNIV_INTERN
-void
-srv_que_task_queue_check(void);
-/*==========================*/
-/**************************************************************************
-Performs round-robin on the server tasks. This is called by a SRV_WORKER
-thread every second or so. */
-UNIV_INTERN
-que_thr_t*
-srv_que_round_robin(
-/*================*/
- /* out: the new (may be == thr) query thread
- to run */
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Enqueues a task to server task queue and releases a worker thread, if
-there exists one suspended. */
-UNIV_INTERN
-void
-srv_que_task_enqueue(
-/*=================*/
- que_thr_t* thr); /* in: query thread */
-/**************************************************************************
-Enqueues a task to server task queue and releases a worker thread, if
-there exists one suspended. */
+/**********************************************************************//**
+Enqueues a task to server task queue and releases a worker thread, if there
+is a suspended one. */
UNIV_INTERN
void
srv_que_task_enqueue_low(
/*=====================*/
- que_thr_t* thr); /* in: query thread */
+ que_thr_t* thr); /*!< in: query thread */
#endif
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index 6e5e955f9a5..d98e2ad5013 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
-Copyright (c) 2008, Google Inc.
+Copyright (c) 2008, 2009, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -22,8 +22,35 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+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
+
+***********************************************************************/
+
+/**************************************************//**
+@file include/srv0srv.h
The server main program
Created 10/10/1995 Heikki Tuuri
@@ -33,6 +60,7 @@ Created 10/10/1995 Heikki Tuuri
#define srv0srv_h
#include "univ.i"
+#ifndef UNIV_HOTBACKUP
#include "sync0sync.h"
#include "os0sync.h"
#include "que0types.h"
@@ -40,7 +68,7 @@ Created 10/10/1995 Heikki Tuuri
extern const char* srv_main_thread_op_info;
-/* Prefix used by MySQL to indicate pre-5.1 table name encoding */
+/** Prefix used by MySQL to indicate pre-5.1 table name encoding */
extern const char srv_mysql50_table_name_prefix[9];
/* When this event is set the lock timeout and InnoDB monitor
@@ -79,16 +107,23 @@ extern char* srv_data_home;
extern char* srv_arch_dir;
#endif /* UNIV_LOG_ARCHIVE */
-/* store to its own file each table created by an user; data
+/** store to its own file each table created by an user; data
dictionary tables are in the system tablespace 0 */
+#ifndef UNIV_HOTBACKUP
extern my_bool srv_file_per_table;
-/* The file format to use on new *.ibd files. */
+#else
+extern ibool srv_file_per_table;
+#endif /* UNIV_HOTBACKUP */
+/** The file format to use on new *.ibd files. */
extern ulint srv_file_format;
-/* Whether to check file format during startup.*/
+/** Whether to check file format during startup. A value of
+DICT_TF_FORMAT_MAX + 1 means no checking ie. FALSE. The default is to
+set it to the highest format we support. */
extern ulint srv_check_file_format_at_startup;
-/* Place locks to records only i.e. do not use next-key locking except
+/** Place locks to records only i.e. do not use next-key locking except
on duplicate key checking and foreign key checking */
extern ibool srv_locks_unsafe_for_binlog;
+#endif /* !UNIV_HOTBACKUP */
extern ulint srv_n_data_files;
extern char** srv_data_file_names;
@@ -99,22 +134,23 @@ extern ibool srv_extra_undoslots;
extern ibool srv_fast_recovery;
+extern ibool srv_use_purge_thread;
+
extern ibool srv_auto_extend_last_data_file;
extern ulint srv_last_file_size_max;
+extern char** srv_log_group_home_dirs;
+#ifndef UNIV_HOTBACKUP
extern ulong srv_auto_extend_increment;
extern ibool srv_created_new_raw;
-#define SRV_NEW_RAW 1
-#define SRV_OLD_RAW 2
-
-extern char** srv_log_group_home_dirs;
-
extern ulint srv_n_log_groups;
extern ulint srv_n_log_files;
extern ulint srv_log_file_size;
extern ulint srv_log_buffer_size;
extern ulong srv_flush_log_at_trx_commit;
+extern char srv_adaptive_flushing;
+
extern ulong srv_show_locks_held;
extern ulong srv_show_verbose_locks;
@@ -122,19 +158,31 @@ extern ulong srv_show_verbose_locks;
/* The sort order table of the MySQL latin1_swedish_ci character set
collation */
extern const byte* srv_latin1_ordering;
+#ifndef UNIV_HOTBACKUP
extern my_bool srv_use_sys_malloc;
-extern ulint srv_buf_pool_size; /* requested size in bytes */
-extern ulint srv_buf_pool_old_size; /* previously requested size */
-extern ulint srv_buf_pool_curr_size; /* current size in bytes */
+#else
+extern ibool srv_use_sys_malloc;
+#endif /* UNIV_HOTBACKUP */
+extern ulint srv_buf_pool_size; /*!< requested size in bytes */
+extern ulint srv_buf_pool_old_size; /*!< previously requested size */
+extern ulint srv_buf_pool_curr_size; /*!< current size in bytes */
extern ulint srv_mem_pool_size;
extern ulint srv_lock_table_size;
extern ibool srv_thread_concurrency_timer_based;
extern ulint srv_n_file_io_threads;
+extern ulong srv_read_ahead_threshold;
extern ulint srv_n_read_io_threads;
extern ulint srv_n_write_io_threads;
+/* Number of IO operations per second the server can do */
+extern ulong srv_io_capacity;
+/* Returns the number of IO operations that is X percent of the
+capacity. PCT_IO(5) -> returns the number of IO operations that
+is 5% of the max where max is srv_io_capacity. */
+#define PCT_IO(p) ((ulong) (srv_io_capacity * ((double) p / 100.0)))
+
#ifdef UNIV_LOG_ARCHIVE
extern ibool srv_log_archive_on;
extern ibool srv_archive_recovery;
@@ -171,6 +219,7 @@ extern ulong srv_stats_method;
#define SRV_STATS_METHOD_NULLS_NOT_EQUAL 1
#define SRV_STATS_METHOD_IGNORE_NULLS 2
extern ulong srv_stats_auto_update;
+extern ulint srv_stats_update_need_lock;
extern ibool srv_use_doublewrite_buf;
extern ibool srv_use_checksums;
@@ -183,7 +232,6 @@ extern ulong srv_max_purge_lag;
extern ulong srv_replication_delay;
-extern ulong srv_io_capacity;
extern long long srv_ibuf_max_size;
extern ulong srv_ibuf_active_contract;
extern ulong srv_ibuf_accel_rate;
@@ -215,7 +263,7 @@ extern ibool srv_error_monitor_active;
extern ulong srv_n_spin_wait_rounds;
extern ulong srv_n_free_tickets_to_enter;
extern ulong srv_thread_sleep_delay;
-extern ulint srv_spin_wait_delay;
+extern ulong srv_spin_wait_delay;
extern ibool srv_priority_boost;
extern ulint srv_mem_pool_size;
@@ -245,7 +293,7 @@ extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs,
same DRAM page as other hotspot semaphores */
#define kernel_mutex (*kernel_mutex_temp)
-#define SRV_MAX_N_IO_THREADS 100
+#define SRV_MAX_N_IO_THREADS 130
/* Array of English strings describing the current state of an
i/o handler thread */
@@ -294,61 +342,79 @@ extern ulint srv_buf_pool_wait_free;
buffer pool to disk */
extern ulint srv_buf_pool_flushed;
-/* variable to count the number of buffer pool reads that led to the
+/** Number of buffer pool reads that led to the
reading of a disk page */
extern ulint srv_buf_pool_reads;
-
-/* variable to count the number of sequential read-aheads were done */
+/** Number of sequential read-aheads */
extern ulint srv_read_ahead_seq;
-
-/* variable to count the number of random read-aheads were done */
+/** Number of random read-aheads */
extern ulint srv_read_ahead_rnd;
-/* In this structure we store status variables to be passed to MySQL */
+/** Status variables to be passed to MySQL */
typedef struct export_var_struct export_struc;
+/** Status variables to be passed to MySQL */
extern export_struc export_vars;
+/** The server system */
typedef struct srv_sys_struct srv_sys_t;
-/* The server system */
+/** The server system */
extern srv_sys_t* srv_sys;
+#endif /* !UNIV_HOTBACKUP */
+
+/** Types of raw partitions in innodb_data_file_path */
+enum {
+ SRV_NOT_RAW = 0, /*!< Not a raw partition */
+ SRV_NEW_RAW, /*!< A 'newraw' partition, only to be
+ initialized */
+ SRV_OLD_RAW /*!< An initialized raw partition */
+};
-/* Alternatives for the file flush option in Unix; see the InnoDB manual
+/** Alternatives for the file flush option in Unix; see the InnoDB manual
about what these mean */
-#define SRV_UNIX_FSYNC 1 /* This is the default */
-#define SRV_UNIX_O_DSYNC 2
-#define SRV_UNIX_LITTLESYNC 3
-#define SRV_UNIX_NOSYNC 4
-#define SRV_UNIX_O_DIRECT 5
+enum {
+ SRV_UNIX_FSYNC = 1, /*!< fsync, the default */
+ SRV_UNIX_O_DSYNC, /*!< open log files in O_SYNC mode */
+ SRV_UNIX_LITTLESYNC, /*!< do not call os_file_flush()
+ 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
+ data files */
+};
-/* Alternatives for file i/o in Windows */
-#define SRV_WIN_IO_NORMAL 1
-#define SRV_WIN_IO_UNBUFFERED 2 /* This is the default */
+/** Alternatives for file i/o in Windows */
+enum {
+ SRV_WIN_IO_NORMAL = 1, /*!< buffered I/O */
+ SRV_WIN_IO_UNBUFFERED /*!< unbuffered I/O; this is the default */
+};
-/* Alternatives for srv_force_recovery. Non-zero values are intended
+/** Alternatives for srv_force_recovery. Non-zero values are intended
to help the user get a damaged database up so that he can dump intact
tables and rows with SELECT INTO OUTFILE. The database must not otherwise
be used with these options! A bigger number below means that all precautions
of lower numbers are included. */
-
-#define SRV_FORCE_IGNORE_CORRUPT 1 /* let the server run even if it
+enum {
+ SRV_FORCE_IGNORE_CORRUPT = 1, /*!< let the server run even if it
detects a corrupt page */
-#define SRV_FORCE_NO_BACKGROUND 2 /* prevent the main thread from
+ SRV_FORCE_NO_BACKGROUND = 2, /*!< prevent the main thread from
running: if a crash would occur
in purge, this prevents it */
-#define SRV_FORCE_NO_TRX_UNDO 3 /* do not run trx rollback after
+ SRV_FORCE_NO_TRX_UNDO = 3, /*!< do not run trx rollback after
recovery */
-#define SRV_FORCE_NO_IBUF_MERGE 4 /* prevent also ibuf operations:
+ SRV_FORCE_NO_IBUF_MERGE = 4, /*!< prevent also ibuf operations:
if they would cause a crash, better
not do them */
-#define SRV_FORCE_NO_UNDO_LOG_SCAN 5 /* do not look at undo logs when
+ SRV_FORCE_NO_UNDO_LOG_SCAN = 5, /*!< do not look at undo logs when
starting the database: InnoDB will
treat even incomplete transactions
as committed */
-#define SRV_FORCE_NO_LOG_REDO 6 /* do not do the log roll-forward
+ SRV_FORCE_NO_LOG_REDO = 6 /*!< do not do the log roll-forward
in connection with recovery */
+};
+#ifndef UNIV_HOTBACKUP
/** Types of threads existing in the system. */
enum srv_thread_type {
SRV_COM = 1, /**< threads serving communication and queries */
@@ -361,81 +427,89 @@ enum srv_thread_type {
SRV_RECOVERY, /**< threads finishing a recovery */
SRV_INSERT, /**< thread flushing the insert buffer to disk */
#endif
+ SRV_PURGE, /* thread purging undo records */
SRV_MASTER /**< the master thread, (whose type number must
be biggest) */
};
-/*************************************************************************
-Boots Innobase server. */
+/*********************************************************************//**
+Boots Innobase server.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
srv_boot(void);
/*==========*/
- /* out: DB_SUCCESS or error code */
-/*************************************************************************
+/*********************************************************************//**
Initializes the server. */
UNIV_INTERN
void
srv_init(void);
/*==========*/
-/*************************************************************************
+/*********************************************************************//**
Frees the OS fast mutex created in srv_boot(). */
UNIV_INTERN
void
srv_free(void);
/*==========*/
-/*************************************************************************
+/*********************************************************************//**
Initializes the synchronization primitives, memory system, and the thread
local storage. */
UNIV_INTERN
void
srv_general_init(void);
/*==================*/
-/*************************************************************************
-Gets the number of threads in the system. */
+/*********************************************************************//**
+Gets the number of threads in the system.
+@return sum of srv_n_threads[] */
UNIV_INTERN
ulint
srv_get_n_threads(void);
/*===================*/
-/*************************************************************************
-Returns the calling thread type. */
+/*********************************************************************//**
+Returns the calling thread type.
+@return SRV_COM, ... */
enum srv_thread_type
srv_get_thread_type(void);
/*=====================*/
- /* out: SRV_COM, ... */
-/*************************************************************************
+/*********************************************************************//**
Sets the info describing an i/o thread current state. */
UNIV_INTERN
void
srv_set_io_thread_op_info(
/*======================*/
- ulint i, /* in: the 'segment' of the i/o thread */
- const char* str); /* in: constant char string describing the
+ ulint i, /*!< in: the 'segment' of the i/o thread */
+ const char* str); /*!< in: constant char string describing the
state */
-/*************************************************************************
+/*********************************************************************//**
Releases threads of the type given from suspension in the thread table.
-NOTE! The server mutex has to be reserved by the caller! */
+NOTE! The server mutex has to be reserved by the caller!
+@return number of threads released: this may be less than n if not
+enough threads were suspended at the moment */
UNIV_INTERN
ulint
srv_release_threads(
/*================*/
- /* out: number of threads
- released: this may be < n if
- not enough threads were
- suspended at the moment */
- enum srv_thread_type type, /* in: thread type */
- ulint n); /* in: number of threads to release */
-/*************************************************************************
-The master thread controlling the server. */
+ enum srv_thread_type type, /*!< in: thread type */
+ ulint n); /*!< in: number of threads to release */
+/*********************************************************************//**
+The master thread controlling the server.
+@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
srv_master_thread(
/*==============*/
- /* out: a dummy parameter */
+ void* arg); /*!< in: a dummy parameter required by
+ os_thread_create */
+/*************************************************************************
+The undo purge thread. */
+UNIV_INTERN
+os_thread_ret_t
+srv_purge_thread(
+/*=============*/
void* arg); /* in: a dummy parameter required by
os_thread_create */
-/***********************************************************************
+/*******************************************************************//**
Tells the Innobase server that there has been activity in the database
and wakes up the master thread if it is suspended (not sleeping). Used
in the MySQL interface. Note that there is a small chance that the master
@@ -445,48 +519,48 @@ UNIV_INTERN
void
srv_active_wake_master_thread(void);
/*===============================*/
-/***********************************************************************
+/*******************************************************************//**
Wakes up the master thread if it is suspended or being suspended. */
UNIV_INTERN
void
srv_wake_master_thread(void);
/*========================*/
-/*************************************************************************
+/*********************************************************************//**
Puts an OS thread to wait if there are too many concurrent threads
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
UNIV_INTERN
void
srv_conc_enter_innodb(
/*==================*/
- trx_t* trx); /* in: transaction object associated with the
+ trx_t* trx); /*!< in: transaction object associated with the
thread */
-/*************************************************************************
+/*********************************************************************//**
This lets a thread enter InnoDB regardless of the number of threads inside
InnoDB. This must be called when a thread ends a lock wait. */
UNIV_INTERN
void
srv_conc_force_enter_innodb(
/*========================*/
- trx_t* trx); /* in: transaction object associated with the
+ trx_t* trx); /*!< in: transaction object associated with the
thread */
-/*************************************************************************
+/*********************************************************************//**
This must be called when a thread exits InnoDB in a lock wait or at the
end of an SQL statement. */
UNIV_INTERN
void
srv_conc_force_exit_innodb(
/*=======================*/
- trx_t* trx); /* in: transaction object associated with the
+ trx_t* trx); /*!< in: transaction object associated with the
thread */
-/*************************************************************************
+/*********************************************************************//**
This must be called when a thread exits InnoDB. */
UNIV_INTERN
void
srv_conc_exit_innodb(
/*=================*/
- trx_t* trx); /* in: transaction object associated with the
+ trx_t* trx); /*!< in: transaction object associated with the
thread */
-/*******************************************************************
+/***************************************************************//**
Puts a MySQL OS thread to wait for a lock to be released. If an error
occurs during the wait trx->error_state associated with thr is
!= DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK
@@ -496,124 +570,135 @@ UNIV_INTERN
void
srv_suspend_mysql_thread(
/*=====================*/
- que_thr_t* thr); /* in: query thread associated with the MySQL
+ que_thr_t* thr); /*!< in: query thread associated with the MySQL
OS thread */
-/************************************************************************
+/********************************************************************//**
Releases a MySQL OS thread waiting for a lock to be released, if the
thread is already suspended. */
UNIV_INTERN
void
srv_release_mysql_thread_if_suspended(
/*==================================*/
- que_thr_t* thr); /* in: query thread associated with the
+ que_thr_t* thr); /*!< in: query thread associated with the
MySQL OS thread */
-/*************************************************************************
+/*********************************************************************//**
A thread which wakes up threads whose lock wait may have lasted too long.
-This also prints the info output by various InnoDB monitors. */
+This also prints the info output by various InnoDB monitors.
+@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
srv_lock_timeout_and_monitor_thread(
/*================================*/
- /* out: a dummy parameter */
- void* arg); /* in: a dummy parameter required by
+ void* arg); /*!< in: a dummy parameter required by
os_thread_create */
-/*************************************************************************
+/*********************************************************************//**
A thread which prints warnings about semaphore waits which have lasted
-too long. These can be used to track bugs which cause hangs. */
+too long. These can be used to track bugs which cause hangs.
+@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
srv_error_monitor_thread(
/*=====================*/
- /* out: a dummy parameter */
- void* arg); /* in: a dummy parameter required by
+ void* arg); /*!< in: a dummy parameter required by
os_thread_create */
-/**********************************************************************
+/******************************************************************//**
Outputs to a file the output of the InnoDB Monitor. */
UNIV_INTERN
void
srv_printf_innodb_monitor(
/*======================*/
- FILE* file, /* in: output stream */
- ulint* trx_start, /* out: file position of the start of
+ FILE* file, /*!< in: output stream */
+ ulint* trx_start, /*!< out: file position of the start of
the list of active transactions */
- ulint* trx_end); /* out: file position of the end of
+ ulint* trx_end); /*!< out: file position of the end of
the list of active transactions */
-/**********************************************************************
+/******************************************************************//**
Function to pass InnoDB status variables to MySQL */
UNIV_INTERN
void
srv_export_innodb_status(void);
-/*=====================*/
+/*==========================*/
-/* Thread slot in the thread table */
+/** Thread slot in the thread table */
typedef struct srv_slot_struct srv_slot_t;
-/* Thread table is an array of slots */
+/** Thread table is an array of slots */
typedef srv_slot_t srv_table_t;
-/* In this structure we store status variables to be passed to MySQL */
+/** Status variables to be passed to MySQL */
struct export_var_struct{
- ulint innodb_data_pending_reads;
- ulint innodb_data_pending_writes;
- ulint innodb_data_pending_fsyncs;
- ulint innodb_data_fsyncs;
- ulint innodb_data_read;
- ulint innodb_data_writes;
- ulint innodb_data_written;
- ulint innodb_data_reads;
+ ulint innodb_data_pending_reads; /*!< Pending reads */
+ ulint innodb_data_pending_writes; /*!< Pending writes */
+ ulint innodb_data_pending_fsyncs; /*!< Pending fsyncs */
+ ulint innodb_data_fsyncs; /*!< Number of fsyncs so far */
+ ulint innodb_data_read; /*!< Data bytes read */
+ ulint innodb_data_writes; /*!< I/O write requests */
+ ulint innodb_data_written; /*!< Data bytes written */
+ ulint innodb_data_reads; /*!< I/O read requests */
ulint innodb_dict_tables;
- ulint innodb_buffer_pool_pages_total;
- ulint innodb_buffer_pool_pages_data;
- ulint innodb_buffer_pool_pages_dirty;
- ulint innodb_buffer_pool_pages_misc;
- ulint innodb_buffer_pool_pages_free;
+ ulint innodb_buffer_pool_pages_total; /*!< Buffer pool size */
+ ulint innodb_buffer_pool_pages_data; /*!< Data pages */
+ ulint innodb_buffer_pool_pages_dirty; /*!< Dirty data pages */
+ ulint innodb_buffer_pool_pages_misc; /*!< Miscellanous pages */
+ ulint innodb_buffer_pool_pages_free; /*!< Free pages */
#ifdef UNIV_DEBUG
- ulint innodb_buffer_pool_pages_latched;
+ ulint innodb_buffer_pool_pages_latched; /*!< Latched pages */
#endif /* UNIV_DEBUG */
- ulint innodb_buffer_pool_read_requests;
- ulint innodb_buffer_pool_reads;
- ulint innodb_buffer_pool_wait_free;
- ulint innodb_buffer_pool_pages_flushed;
- ulint innodb_buffer_pool_write_requests;
- ulint innodb_buffer_pool_read_ahead_seq;
- ulint innodb_buffer_pool_read_ahead_rnd;
- ulint innodb_dblwr_pages_written;
- ulint innodb_dblwr_writes;
- ibool innodb_have_atomic_builtins;
- ulint innodb_log_waits;
- ulint innodb_log_write_requests;
- ulint innodb_log_writes;
- ulint innodb_os_log_written;
- ulint innodb_os_log_fsyncs;
- ulint innodb_os_log_pending_writes;
- ulint innodb_os_log_pending_fsyncs;
- ulint innodb_page_size;
- ulint innodb_pages_created;
- ulint innodb_pages_read;
- ulint innodb_pages_written;
- ulint innodb_row_lock_waits;
- ulint innodb_row_lock_current_waits;
- ib_int64_t innodb_row_lock_time;
- ulint innodb_row_lock_time_avg;
- ulint innodb_row_lock_time_max;
- ulint innodb_rows_read;
- ulint innodb_rows_inserted;
- ulint innodb_rows_updated;
- ulint innodb_rows_deleted;
+ ulint innodb_buffer_pool_read_requests; /*!< buf_pool->n_page_gets */
+ ulint innodb_buffer_pool_reads; /*!< srv_buf_pool_reads */
+ ulint innodb_buffer_pool_wait_free; /*!< srv_buf_pool_wait_free */
+ ulint innodb_buffer_pool_pages_flushed; /*!< srv_buf_pool_flushed */
+ ulint innodb_buffer_pool_write_requests;/*!< srv_buf_pool_write_requests */
+ ulint innodb_buffer_pool_read_ahead_seq;/*!< srv_read_ahead_seq */
+ ulint innodb_buffer_pool_read_ahead_rnd;/*!< srv_read_ahead_rnd */
+ ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */
+ ulint innodb_dblwr_writes; /*!< srv_dblwr_writes */
+ ibool innodb_have_atomic_builtins; /*!< HAVE_ATOMIC_BUILTINS */
+ ulint innodb_log_waits; /*!< srv_log_waits */
+ ulint innodb_log_write_requests; /*!< srv_log_write_requests */
+ ulint innodb_log_writes; /*!< srv_log_writes */
+ ulint innodb_os_log_written; /*!< srv_os_log_written */
+ ulint innodb_os_log_fsyncs; /*!< fil_n_log_flushes */
+ ulint innodb_os_log_pending_writes; /*!< srv_os_log_pending_writes */
+ ulint innodb_os_log_pending_fsyncs; /*!< fil_n_pending_log_flushes */
+ ulint innodb_page_size; /*!< UNIV_PAGE_SIZE */
+ ulint innodb_pages_created; /*!< buf_pool->n_pages_created */
+ ulint innodb_pages_read; /*!< buf_pool->n_pages_read */
+ ulint innodb_pages_written; /*!< buf_pool->n_pages_written */
+ ulint innodb_row_lock_waits; /*!< srv_n_lock_wait_count */
+ ulint innodb_row_lock_current_waits; /*!< srv_n_lock_wait_current_count */
+ ib_int64_t innodb_row_lock_time; /*!< srv_n_lock_wait_time
+ / 1000 */
+ ulint innodb_row_lock_time_avg; /*!< srv_n_lock_wait_time
+ / 1000
+ / srv_n_lock_wait_count */
+ ulint innodb_row_lock_time_max; /*!< srv_n_lock_max_wait_time
+ / 1000 */
+ ulint innodb_rows_read; /*!< srv_n_rows_read */
+ ulint innodb_rows_inserted; /*!< srv_n_rows_inserted */
+ ulint innodb_rows_updated; /*!< srv_n_rows_updated */
+ ulint innodb_rows_deleted; /*!< srv_n_rows_deleted */
};
-/* The server system struct */
+/** The server system struct */
struct srv_sys_struct{
- srv_table_t* threads; /* server thread table */
+ srv_table_t* threads; /*!< server thread table */
UT_LIST_BASE_NODE_T(que_thr_t)
- tasks; /* task queue */
- dict_index_t* dummy_ind1; /* dummy index for old-style
- supremum and infimum records */
- dict_index_t* dummy_ind2; /* dummy index for new-style
- supremum and infimum records */
+ tasks; /*!< task queue */
};
extern ulint srv_n_threads_active[];
+#else /* !UNIV_HOTBACKUP */
+# define srv_use_checksums TRUE
+# define srv_use_adaptive_hash_indexes FALSE
+# define srv_force_recovery 0UL
+# define srv_set_io_thread_op_info(t,info) ((void) 0)
+# define srv_is_being_started 0
+# define srv_win_file_flush_method SRV_WIN_IO_UNBUFFERED
+# define srv_unix_file_flush_method SRV_UNIX_O_DSYNC
+# define srv_start_raw_disk_in_use 0
+# define srv_file_per_table 1
+#endif /* !UNIV_HOTBACKUP */
#endif
diff --git a/storage/xtradb/include/srv0srv.ic b/storage/xtradb/include/srv0srv.ic
index 93d675f1dca..8a1a678a016 100644
--- a/storage/xtradb/include/srv0srv.ic
+++ b/storage/xtradb/include/srv0srv.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/srv0srv.ic
Server main program
Created 10/4/1995 Heikki Tuuri
diff --git a/storage/xtradb/include/srv0start.h b/storage/xtradb/include/srv0start.h
index 15fa3b8f95f..8abf15da9c1 100644
--- a/storage/xtradb/include/srv0start.h
+++ b/storage/xtradb/include/srv0start.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/srv0start.h
Starts the Innobase database server
Created 10/10/1995 Heikki Tuuri
@@ -28,64 +29,66 @@ Created 10/10/1995 Heikki Tuuri
#include "univ.i"
#include "ut0byte.h"
-/*************************************************************************
+/*********************************************************************//**
Normalizes a directory path for Windows: converts slashes to backslashes. */
UNIV_INTERN
void
srv_normalize_path_for_win(
/*=======================*/
- char* str); /* in/out: null-terminated character string */
-/*************************************************************************
+ char* str); /*!< in/out: null-terminated character string */
+/*********************************************************************//**
Reads the data files and their sizes from a character string given in
-the .cnf file. */
+the .cnf file.
+@return TRUE if ok, FALSE on parse error */
UNIV_INTERN
ibool
srv_parse_data_file_paths_and_sizes(
/*================================*/
- /* out: TRUE if ok, FALSE on parse error */
- char* str); /* in/out: the data file path string */
-/*************************************************************************
+ char* str); /*!< in/out: the data file path string */
+/*********************************************************************//**
Reads log group home directories from a character string given in
-the .cnf file. */
+the .cnf file.
+@return TRUE if ok, FALSE on parse error */
UNIV_INTERN
ibool
srv_parse_log_group_home_dirs(
/*==========================*/
- /* out: TRUE if ok, FALSE on parse error */
- char* str); /* in/out: character string */
-/*************************************************************************
+ char* str); /*!< in/out: character string */
+/*********************************************************************//**
Frees the memory allocated by srv_parse_data_file_paths_and_sizes()
and srv_parse_log_group_home_dirs(). */
UNIV_INTERN
void
srv_free_paths_and_sizes(void);
/*==========================*/
-/*************************************************************************
+/*********************************************************************//**
Adds a slash or a backslash to the end of a string if it is missing
-and the string is not empty. */
+and the string is not empty.
+@return string which has the separator if the string is not empty */
UNIV_INTERN
char*
srv_add_path_separator_if_needed(
/*=============================*/
- /* out: string which has the separator if the
- string is not empty */
- char* str); /* in: null-terminated character string */
-/********************************************************************
+ char* str); /*!< in: null-terminated character string */
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
Starts Innobase and creates a new database if database files
-are not found and the user wants. */
+are not found and the user wants.
+@return DB_SUCCESS or error code */
UNIV_INTERN
int
innobase_start_or_create_for_mysql(void);
/*====================================*/
- /* out: DB_SUCCESS or error code */
-/********************************************************************
-Shuts down the Innobase database. */
+/****************************************************************//**
+Shuts down the Innobase database.
+@return DB_SUCCESS or error code */
UNIV_INTERN
int
innobase_shutdown_for_mysql(void);
/*=============================*/
- /* out: DB_SUCCESS or error code */
+/** Log sequence number at shutdown */
extern ib_uint64_t srv_shutdown_lsn;
+/** Log sequence number immediately after startup */
extern ib_uint64_t srv_start_lsn;
#ifdef __NETWARE__
@@ -93,26 +96,39 @@ void set_panic_flag_for_netware(void);
#endif
#ifdef HAVE_DARWIN_THREADS
+/** TRUE if the F_FULLFSYNC option is available */
extern ibool srv_have_fullfsync;
#endif
+/** TRUE if the server is being started */
extern ibool srv_is_being_started;
+/** TRUE if the server was successfully started */
extern ibool srv_was_started;
+/** TRUE if the server is being started, before rolling back any
+incomplete transactions */
extern ibool srv_startup_is_before_trx_rollback_phase;
-extern ibool srv_is_being_shut_down;
+/** TRUE if a raw partition is in use */
extern ibool srv_start_raw_disk_in_use;
-/* At a shutdown the value first climbs from 0 to SRV_SHUTDOWN_CLEANUP
-and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
-extern ulint srv_shutdown_state;
+/** Shutdown state */
+enum srv_shutdown_state {
+ SRV_SHUTDOWN_NONE = 0, /*!< Database running normally */
+ SRV_SHUTDOWN_CLEANUP, /*!< Cleaning up in
+ logs_empty_and_mark_files_at_shutdown() */
+ SRV_SHUTDOWN_LAST_PHASE,/*!< Last phase after ensuring that
+ the buffer pool can be freed: flush
+ all file spaces and close all files */
+ SRV_SHUTDOWN_EXIT_THREADS/*!< Exit all threads */
+};
-#define SRV_SHUTDOWN_CLEANUP 1
-#define SRV_SHUTDOWN_LAST_PHASE 2
-#define SRV_SHUTDOWN_EXIT_THREADS 3
+/** At a shutdown this value climbs from SRV_SHUTDOWN_NONE to
+SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
+extern enum srv_shutdown_state srv_shutdown_state;
+#endif /* !UNIV_HOTBACKUP */
-/* Log 'spaces' have id's >= this */
+/** Log 'spaces' have id's >= this */
#define SRV_LOG_SPACE_FIRST_ID 0xFFFFFFF0UL
#endif
diff --git a/storage/xtradb/include/sync0arr.h b/storage/xtradb/include/sync0arr.h
index cc01c9ac5c8..5f1280f5e28 100644
--- a/storage/xtradb/include/sync0arr.h
+++ b/storage/xtradb/include/sync0arr.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/sync0arr.h
The wait array used in synchronization primitives
Created 9/5/1995 Heikki Tuuri
@@ -30,47 +31,51 @@ Created 9/5/1995 Heikki Tuuri
#include "ut0mem.h"
#include "os0thread.h"
+/** Synchronization wait array cell */
typedef struct sync_cell_struct sync_cell_t;
+/** Synchronization wait array */
typedef struct sync_array_struct sync_array_t;
-#define SYNC_ARRAY_OS_MUTEX 1
-#define SYNC_ARRAY_MUTEX 2
+/** Parameters for sync_array_create() @{ */
+#define SYNC_ARRAY_OS_MUTEX 1 /*!< protected by os_mutex_t */
+#define SYNC_ARRAY_MUTEX 2 /*!< protected by mutex_t */
+/* @} */
-/***********************************************************************
+/*******************************************************************//**
Creates a synchronization wait array. It is protected by a mutex
which is automatically reserved when the functions operating on it
-are called. */
+are called.
+@return own: created wait array */
UNIV_INTERN
sync_array_t*
sync_array_create(
/*==============*/
- /* out, own: created wait array */
- ulint n_cells, /* in: number of cells in the array
+ ulint n_cells, /*!< in: number of cells in the array
to create */
- ulint protection); /* in: either SYNC_ARRAY_OS_MUTEX or
+ ulint protection); /*!< in: either SYNC_ARRAY_OS_MUTEX or
SYNC_ARRAY_MUTEX: determines the type
of mutex protecting the data structure */
-/**********************************************************************
+/******************************************************************//**
Frees the resources in a wait array. */
UNIV_INTERN
void
sync_array_free(
/*============*/
- sync_array_t* arr); /* in, own: sync wait array */
-/**********************************************************************
+ sync_array_t* arr); /*!< in, own: sync wait array */
+/******************************************************************//**
Reserves a wait array cell for waiting for an object.
The event of the cell is reset to nonsignalled state. */
UNIV_INTERN
void
sync_array_reserve_cell(
/*====================*/
- sync_array_t* arr, /* in: wait array */
- void* object, /* in: pointer to the object to wait for */
- ulint type, /* in: lock request type */
- const char* file, /* in: file where requested */
- ulint line, /* in: line where requested */
- ulint* index); /* out: index of the reserved cell */
-/**********************************************************************
+ sync_array_t* arr, /*!< in: wait array */
+ void* object, /*!< in: pointer to the object to wait for */
+ ulint type, /*!< in: lock request type */
+ const char* file, /*!< in: file where requested */
+ ulint line, /*!< in: line where requested */
+ ulint* index); /*!< out: index of the reserved cell */
+/******************************************************************//**
This function should be called when a thread starts to wait on
a wait array cell. In the debug version this function checks
if the wait for a semaphore will result in a deadlock, in which
@@ -79,25 +84,25 @@ UNIV_INTERN
void
sync_array_wait_event(
/*==================*/
- sync_array_t* arr, /* in: wait array */
- ulint index); /* in: index of the reserved cell */
-/**********************************************************************
+ sync_array_t* arr, /*!< in: wait array */
+ ulint index); /*!< in: index of the reserved cell */
+/******************************************************************//**
Frees the cell. NOTE! sync_array_wait_event frees the cell
automatically! */
UNIV_INTERN
void
sync_array_free_cell(
/*=================*/
- sync_array_t* arr, /* in: wait array */
- ulint index); /* in: index of the cell in array */
-/**************************************************************************
+ sync_array_t* arr, /*!< in: wait array */
+ ulint index); /*!< in: index of the cell in array */
+/**********************************************************************//**
Note that one of the wait objects was signalled. */
UNIV_INTERN
void
sync_array_object_signalled(
/*========================*/
- sync_array_t* arr); /* in: wait array */
-/**************************************************************************
+ sync_array_t* arr); /*!< in: wait array */
+/**********************************************************************//**
If the wakeup algorithm does not work perfectly at semaphore relases,
this function will do the waking (see the comment in mutex_exit). This
function should be called about every 1 second in the server. */
@@ -105,30 +110,29 @@ UNIV_INTERN
void
sync_arr_wake_threads_if_sema_free(void);
/*====================================*/
-/**************************************************************************
-Prints warnings of long semaphore waits to stderr. */
+/**********************************************************************//**
+Prints warnings of long semaphore waits to stderr.
+@return TRUE if fatal semaphore wait threshold was exceeded */
UNIV_INTERN
ibool
sync_array_print_long_waits(void);
/*=============================*/
- /* out: TRUE if fatal semaphore wait threshold
- was exceeded */
-/************************************************************************
+/********************************************************************//**
Validates the integrity of the wait array. Checks
that the number of reserved cells equals the count variable. */
UNIV_INTERN
void
sync_array_validate(
/*================*/
- sync_array_t* arr); /* in: sync wait array */
-/**************************************************************************
+ sync_array_t* arr); /*!< in: sync wait array */
+/**********************************************************************//**
Prints info of the wait array. */
UNIV_INTERN
void
sync_array_print_info(
/*==================*/
- FILE* file, /* in: file where to print */
- sync_array_t* arr); /* in: wait array */
+ FILE* file, /*!< in: file where to print */
+ sync_array_t* arr); /*!< in: wait array */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/sync0arr.ic b/storage/xtradb/include/sync0arr.ic
index 09a562a4723..bf57f5b2dc2 100644
--- a/storage/xtradb/include/sync0arr.ic
+++ b/storage/xtradb/include/sync0arr.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/sync0arr.ic
The wait array for synchronization primitives
Inline code
diff --git a/storage/xtradb/include/sync0rw.h b/storage/xtradb/include/sync0rw.h
index e3fe0dc9ccc..aedfd5f3f86 100644
--- a/storage/xtradb/include/sync0rw.h
+++ b/storage/xtradb/include/sync0rw.h
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/sync0rw.h
The read-write lock (for threads, not for database transactions)
Created 9/11/1995 Heikki Tuuri
@@ -33,6 +34,7 @@ Created 9/11/1995 Heikki Tuuri
#define sync0rw_h
#include "univ.i"
+#ifndef UNIV_HOTBACKUP
#include "ut0lst.h"
#include "sync0sync.h"
#include "os0sync.h"
@@ -40,6 +42,7 @@ Created 9/11/1995 Heikki Tuuri
/* The following undef is to prevent a name conflict with a macro
in MySQL: */
#undef rw_lock_t
+#endif /* !UNIV_HOTBACKUP */
/* Latch types; these are used also in btr0btr.h: keep the numerical values
smaller than 30 and the order of the numerical values like below! */
@@ -47,6 +50,7 @@ smaller than 30 and the order of the numerical values like below! */
#define RW_X_LATCH 2
#define RW_NO_LATCH 3
+#ifndef UNIV_HOTBACKUP
/* We decrement lock_word by this amount for each x_lock. It is also the
start value for the lock_word, meaning that it limits the maximum number
of concurrent read locks before the rw_lock breaks. The current value of
@@ -69,23 +73,39 @@ To modify the debug info list of an rw-lock, this mutex has to be
acquired in addition to the mutex protecting the lock. */
extern mutex_t rw_lock_debug_mutex;
-extern os_event_t rw_lock_debug_event; /* If deadlock detection does
+extern os_event_t rw_lock_debug_event; /*!< If deadlock detection does
not get immediately the mutex it
may wait for this event */
-extern ibool rw_lock_debug_waiters; /* This is set to TRUE, if
+extern ibool rw_lock_debug_waiters; /*!< This is set to TRUE, if
there may be waiters for the event */
#endif /* UNIV_SYNC_DEBUG */
+/** number of spin waits on rw-latches,
+resulted during exclusive (write) locks */
extern ib_int64_t rw_s_spin_wait_count;
+/** number of spin loop rounds on rw-latches,
+resulted during exclusive (write) locks */
extern ib_int64_t rw_s_spin_round_count;
+/** number of unlocks (that unlock shared locks),
+set only when UNIV_SYNC_PERF_STAT is defined */
extern ib_int64_t rw_s_exit_count;
+/** number of OS waits on rw-latches,
+resulted during shared (read) locks */
extern ib_int64_t rw_s_os_wait_count;
+/** number of spin waits on rw-latches,
+resulted during shared (read) locks */
extern ib_int64_t rw_x_spin_wait_count;
+/** number of spin loop rounds on rw-latches,
+resulted during shared (read) locks */
extern ib_int64_t rw_x_spin_round_count;
+/** number of OS waits on rw-latches,
+resulted during exclusive (write) locks */
extern ib_int64_t rw_x_os_wait_count;
+/** number of unlocks (that unlock exclusive locks),
+set only when UNIV_SYNC_PERF_STAT is defined */
extern ib_int64_t rw_x_exit_count;
-/**********************************************************************
+/******************************************************************//**
Creates, or rather, initializes an rw-lock object in a specified memory
location (which must be appropriately aligned). The rw-lock is initialized
to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
@@ -103,7 +123,7 @@ is necessary only if the memory block containing it is freed. */
rw_lock_create_func((L), __FILE__, __LINE__)
#endif /* UNIV_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Creates, or rather, initializes an rw-lock object in a specified memory
location (which must be appropriately aligned). The rw-lock is initialized
to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
@@ -112,16 +132,16 @@ UNIV_INTERN
void
rw_lock_create_func(
/*================*/
- rw_lock_t* lock, /* in: pointer to memory */
+ rw_lock_t* lock, /*!< in: pointer to memory */
#ifdef UNIV_DEBUG
# ifdef UNIV_SYNC_DEBUG
- ulint level, /* in: level */
+ ulint level, /*!< in: level */
# endif /* UNIV_SYNC_DEBUG */
- const char* cmutex_name, /* in: mutex name */
+ const char* cmutex_name, /*!< in: mutex name */
#endif /* UNIV_DEBUG */
- const char* cfile_name, /* in: file name where created */
- ulint cline); /* in: file line where created */
-/**********************************************************************
+ const char* cfile_name, /*!< in: file name where created */
+ ulint cline); /*!< in: file line where created */
+/******************************************************************//**
Calling this function is obligatory only if the memory buffer containing
the rw-lock is freed. Removes an rw-lock object from the global list. The
rw-lock is checked to be in the non-locked state. */
@@ -129,50 +149,51 @@ UNIV_INTERN
void
rw_lock_free(
/*=========*/
- rw_lock_t* lock); /* in: rw-lock */
+ rw_lock_t* lock); /*!< in: rw-lock */
#ifdef UNIV_DEBUG
-/**********************************************************************
+/******************************************************************//**
Checks that the rw-lock has been initialized and that there are no
-simultaneous shared and exclusive locks. */
+simultaneous shared and exclusive locks.
+@return TRUE */
UNIV_INTERN
ibool
rw_lock_validate(
/*=============*/
- rw_lock_t* lock);
+ rw_lock_t* lock); /*!< in: rw-lock */
#endif /* UNIV_DEBUG */
-/******************************************************************
+/**************************************************************//**
NOTE! The following macros should be used in rw s-locking, not the
corresponding function. */
#define rw_lock_s_lock(M) rw_lock_s_lock_func(\
(M), 0, __FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
NOTE! The following macros should be used in rw s-locking, not the
corresponding function. */
#define rw_lock_s_lock_gen(M, P) rw_lock_s_lock_func(\
(M), (P), __FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
NOTE! The following macros should be used in rw s-locking, not the
corresponding function. */
#define rw_lock_s_lock_nowait(M, F, L) rw_lock_s_lock_low(\
(M), 0, (F), (L))
-/**********************************************************************
+/******************************************************************//**
Low-level function which tries to lock an rw-lock in s-mode. Performs no
-spinning. */
+spinning.
+@return TRUE if success */
UNIV_INLINE
ibool
rw_lock_s_lock_low(
/*===============*/
- /* out: TRUE if success */
- rw_lock_t* lock, /* in: pointer to rw-lock */
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
ulint pass __attribute__((unused)),
- /* in: pass value; != 0, if the lock will be
+ /*!< in: pass value; != 0, if the lock will be
passed to another thread to unlock */
- const char* file_name, /* in: file name where lock requested */
- ulint line); /* in: line where requested */
-/**********************************************************************
+ const char* file_name, /*!< in: file name where lock requested */
+ ulint line); /*!< in: line where requested */
+/******************************************************************//**
NOTE! Use the corresponding macro, not directly this function, except if
you supply the file name and line number. Lock an rw-lock in shared mode
for the current thread. If the rw-lock is locked in exclusive mode, or
@@ -183,70 +204,63 @@ UNIV_INLINE
void
rw_lock_s_lock_func(
/*================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock will
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ ulint pass, /*!< in: pass value; != 0, if the lock will
be passed to another thread to unlock */
- const char* file_name,/* in: file name where lock requested */
- ulint line); /* in: line where requested */
-/**********************************************************************
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line); /*!< in: line where requested */
+/******************************************************************//**
NOTE! Use the corresponding macro, not directly this function! Lock an
rw-lock in exclusive mode for the current thread if the lock can be
-obtained immediately. */
+obtained immediately.
+@return TRUE if success */
UNIV_INLINE
ibool
rw_lock_x_lock_func_nowait(
/*=======================*/
- /* out: TRUE if success */
- rw_lock_t* lock, /* in: pointer to rw-lock */
- const char* file_name,/* in: file name where lock requested */
- ulint line); /* in: line where requested */
-/**********************************************************************
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line); /*!< in: line where requested */
+/******************************************************************//**
Releases a shared mode lock. */
UNIV_INLINE
void
rw_lock_s_unlock_func(
/*==================*/
- rw_lock_t* lock /* in: rw-lock */
#ifdef UNIV_SYNC_DEBUG
- ,ulint pass /* in: pass value; != 0, if the lock may have
+ ulint pass, /*!< in: pass value; != 0, if the lock may have
been passed to another thread to unlock */
#endif
- );
-/***********************************************************************
-Releases a shared mode lock. */
+ rw_lock_t* lock); /*!< in/out: rw-lock */
#ifdef UNIV_SYNC_DEBUG
-#define rw_lock_s_unlock(L) rw_lock_s_unlock_func(L, 0)
+# define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(P, L)
#else
-#define rw_lock_s_unlock(L) rw_lock_s_unlock_func(L)
+# define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L)
#endif
-/***********************************************************************
+/*******************************************************************//**
Releases a shared mode lock. */
+#define rw_lock_s_unlock(L) rw_lock_s_unlock_gen(L, 0)
-#ifdef UNIV_SYNC_DEBUG
-#define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L, P)
-#else
-#define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L)
-#endif
-/******************************************************************
+/**************************************************************//**
NOTE! The following macro should be used in rw x-locking, not the
corresponding function. */
#define rw_lock_x_lock(M) rw_lock_x_lock_func(\
(M), 0, __FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
NOTE! The following macro should be used in rw x-locking, not the
corresponding function. */
#define rw_lock_x_lock_gen(M, P) rw_lock_x_lock_func(\
(M), (P), __FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
NOTE! The following macros should be used in rw x-locking, not the
corresponding function. */
#define rw_lock_x_lock_nowait(M) rw_lock_x_lock_func_nowait(\
(M), __FILE__, __LINE__)
-/**********************************************************************
+/******************************************************************//**
NOTE! Use the corresponding macro, not directly this function! Lock an
rw-lock in exclusive mode for the current thread. If the rw-lock is locked
in shared or exclusive mode, or there is an exclusive lock request waiting,
@@ -259,40 +273,33 @@ UNIV_INTERN
void
rw_lock_x_lock_func(
/*================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock will
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ ulint pass, /*!< in: pass value; != 0, if the lock will
be passed to another thread to unlock */
- const char* file_name,/* in: file name where lock requested */
- ulint line); /* in: line where requested */
-/**********************************************************************
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line); /*!< in: line where requested */
+/******************************************************************//**
Releases an exclusive mode lock. */
UNIV_INLINE
void
rw_lock_x_unlock_func(
/*==================*/
- rw_lock_t* lock /* in: rw-lock */
#ifdef UNIV_SYNC_DEBUG
- ,ulint pass /* in: pass value; != 0, if the lock may have
+ ulint pass, /*!< in: pass value; != 0, if the lock may have
been passed to another thread to unlock */
#endif
- );
-/***********************************************************************
-Releases an exclusive mode lock. */
+ rw_lock_t* lock); /*!< in/out: rw-lock */
#ifdef UNIV_SYNC_DEBUG
-#define rw_lock_x_unlock(L) rw_lock_x_unlock_func(L, 0)
+# define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(P, L)
#else
-#define rw_lock_x_unlock(L) rw_lock_x_unlock_func(L)
+# define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L)
#endif
-/***********************************************************************
+/*******************************************************************//**
Releases an exclusive mode lock. */
+#define rw_lock_x_unlock(L) rw_lock_x_unlock_gen(L, 0)
-#ifdef UNIV_SYNC_DEBUG
-#define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L, P)
-#else
-#define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L)
-#endif
-/**********************************************************************
+/******************************************************************//**
Low-level function which locks an rw-lock in s-mode when we know that it
is possible and none else is currently accessing the rw-lock structure.
Then we can do the locking without reserving the mutex. */
@@ -300,11 +307,10 @@ UNIV_INLINE
void
rw_lock_s_lock_direct(
/*==================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- const char* file_name, /* in: file name where requested */
- ulint line /* in: line where lock requested */
-);
-/**********************************************************************
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ const char* file_name, /*!< in: file name where requested */
+ ulint line); /*!< in: line where lock requested */
+/******************************************************************//**
Low-level function which locks an rw-lock in x-mode when we know that it
is not locked and none else is currently accessing the rw-lock structure.
Then we can do the locking without reserving the mutex. */
@@ -312,11 +318,10 @@ UNIV_INLINE
void
rw_lock_x_lock_direct(
/*==================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- const char* file_name, /* in: file name where requested */
- ulint line /* in: line where lock requested */
-);
-/**********************************************************************
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ const char* file_name, /*!< in: file name where requested */
+ ulint line); /*!< in: line where lock requested */
+/******************************************************************//**
This function is used in the insert buffer to move the ownership of an
x-latch on a buffer frame to the current thread. The x-latch was set by
the buffer read operation and it protected the buffer frame while the
@@ -328,70 +333,78 @@ UNIV_INTERN
void
rw_lock_x_lock_move_ownership(
/*==========================*/
- rw_lock_t* lock); /* in: lock which was x-locked in the
+ rw_lock_t* lock); /*!< in: lock which was x-locked in the
buffer read */
-/**********************************************************************
+/******************************************************************//**
Releases a shared mode lock when we know there are no waiters and none
else will access the lock during the time this function is executed. */
UNIV_INLINE
void
rw_lock_s_unlock_direct(
/*====================*/
- rw_lock_t* lock); /* in: rw-lock */
-/**********************************************************************
+ rw_lock_t* lock); /*!< in/out: rw-lock */
+/******************************************************************//**
Releases an exclusive mode lock when we know there are no waiters, and
none else will access the lock durint the time this function is executed. */
UNIV_INLINE
void
rw_lock_x_unlock_direct(
/*====================*/
- rw_lock_t* lock); /* in: rw-lock */
-/**********************************************************************
+ rw_lock_t* lock); /*!< in/out: rw-lock */
+/******************************************************************//**
Returns the value of writer_count for the lock. Does not reserve the lock
-mutex, so the caller must be sure it is not changed during the call. */
+mutex, so the caller must be sure it is not changed during the call.
+@return value of writer_count */
UNIV_INLINE
ulint
rw_lock_get_x_lock_count(
/*=====================*/
- /* out: value of writer_count */
- rw_lock_t* lock); /* in: rw-lock */
-/************************************************************************
-Accessor functions for rw lock. */
+ const rw_lock_t* lock); /*!< in: rw-lock */
+/********************************************************************//**
+Check if there are threads waiting for the rw-lock.
+@return 1 if waiters, 0 otherwise */
UNIV_INLINE
ulint
rw_lock_get_waiters(
/*================*/
- rw_lock_t* lock);
+ const rw_lock_t* lock); /*!< in: rw-lock */
+/******************************************************************//**
+Returns the write-status of the lock - this function made more sense
+with the old rw_lock implementation.
+@return RW_LOCK_NOT_LOCKED, RW_LOCK_EX, RW_LOCK_WAIT_EX */
UNIV_INLINE
ulint
rw_lock_get_writer(
/*===============*/
- rw_lock_t* lock);
+ const rw_lock_t* lock); /*!< in: rw-lock */
+/******************************************************************//**
+Returns the number of readers.
+@return number of readers */
UNIV_INLINE
ulint
rw_lock_get_reader_count(
/*=====================*/
- rw_lock_t* lock);
-/**********************************************************************
+ const rw_lock_t* lock); /*!< in: rw-lock */
+/******************************************************************//**
Decrements lock_word the specified amount if it is greater than 0.
-This is used by both s_lock and x_lock operations. */
+This is used by both s_lock and x_lock operations.
+@return TRUE if decr occurs */
UNIV_INLINE
ibool
rw_lock_lock_word_decr(
/*===================*/
- /* out: TRUE if decr occurs */
- rw_lock_t* lock, /* in: rw-lock */
- ulint amount); /* in: amount to decrement */
-/**********************************************************************
-Increments lock_word the specified amount and returns new value. */
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ ulint amount); /*!< in: amount to decrement */
+/******************************************************************//**
+Increments lock_word the specified amount and returns new value.
+@return lock->lock_word after increment */
UNIV_INLINE
lint
rw_lock_lock_word_incr(
/*===================*/
- /* out: TRUE if decr occurs */
- rw_lock_t* lock,
- ulint amount); /* in: rw-lock */
-/**********************************************************************
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ ulint amount); /*!< in: amount to increment */
+/******************************************************************//**
This function sets the lock->writer_thread and lock->recursive fields.
For platforms where we are using atomic builtins instead of lock->mutex
it sets the lock->writer_thread field using atomics to ensure memory
@@ -404,48 +417,49 @@ UNIV_INLINE
void
rw_lock_set_writer_id_and_recursion_flag(
/*=====================================*/
- rw_lock_t* lock, /* in/out: lock to work on */
- ibool recursive); /* in: TRUE if recursion
+ rw_lock_t* lock, /*!< in/out: lock to work on */
+ ibool recursive); /*!< in: TRUE if recursion
allowed */
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
Checks if the thread has locked the rw-lock in the specified mode, with
the pass value == 0. */
UNIV_INTERN
ibool
rw_lock_own(
/*========*/
- rw_lock_t* lock, /* in: rw-lock */
- ulint lock_type); /* in: lock type: RW_LOCK_SHARED,
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint lock_type); /*!< in: lock type: RW_LOCK_SHARED,
RW_LOCK_EX */
#endif /* UNIV_SYNC_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Checks if somebody has locked the rw-lock in the specified mode. */
UNIV_INTERN
ibool
rw_lock_is_locked(
/*==============*/
- rw_lock_t* lock, /* in: rw-lock */
- ulint lock_type); /* in: lock type: RW_LOCK_SHARED,
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint lock_type); /*!< in: lock type: RW_LOCK_SHARED,
RW_LOCK_EX */
#ifdef UNIV_SYNC_DEBUG
-/*******************************************************************
+/***************************************************************//**
Prints debug info of an rw-lock. */
UNIV_INTERN
void
rw_lock_print(
/*==========*/
- rw_lock_t* lock); /* in: rw-lock */
-/*******************************************************************
+ rw_lock_t* lock); /*!< in: rw-lock */
+/***************************************************************//**
Prints debug info of currently locked rw-locks. */
UNIV_INTERN
void
rw_lock_list_print_info(
/*====================*/
- FILE* file); /* in: file where to print */
-/*******************************************************************
+ FILE* file); /*!< in: file where to print */
+/***************************************************************//**
Returns the number of currently locked rw-locks.
-Works only in the debug version. */
+Works only in the debug version.
+@return number of locked rw-locks */
UNIV_INTERN
ulint
rw_lock_n_locked(void);
@@ -453,7 +467,7 @@ rw_lock_n_locked(void);
/*#####################################################################*/
-/**********************************************************************
+/******************************************************************//**
Acquires the debug mutex. We cannot use the mutex defined in sync0sync,
because the debug mutex is also acquired in sync0arr while holding the OS
mutex protecting the sync array, and the ordinary mutex_enter might
@@ -463,34 +477,36 @@ UNIV_INTERN
void
rw_lock_debug_mutex_enter(void);
/*==========================*/
-/**********************************************************************
+/******************************************************************//**
Releases the debug mutex. */
UNIV_INTERN
void
rw_lock_debug_mutex_exit(void);
/*==========================*/
-/*************************************************************************
+/*********************************************************************//**
Prints info of a debug struct. */
UNIV_INTERN
void
rw_lock_debug_print(
/*================*/
- rw_lock_debug_t* info); /* in: debug struct */
+ rw_lock_debug_t* info); /*!< in: debug struct */
#endif /* UNIV_SYNC_DEBUG */
/* NOTE! The structure appears here only for the compiler to know its size.
-Do not use its fields directly! The structure used in the spin lock
-implementation of a read-write lock. Several threads may have a shared lock
-simultaneously in this lock, but only one writer may have an exclusive lock,
-in which case no shared locks are allowed. To prevent starving of a writer
-blocked by readers, a writer may queue for x-lock by decrementing lock_word:
-no new readers will be let in while the thread waits for readers to exit. */
-
+Do not use its fields directly! */
+
+/** The structure used in the spin lock implementation of a read-write
+lock. Several threads may have a shared lock simultaneously in this
+lock, but only one writer may have an exclusive lock, in which case no
+shared locks are allowed. To prevent starving of a writer blocked by
+readers, a writer may queue for x-lock by decrementing lock_word: no
+new readers will be let in while the thread waits for readers to
+exit. */
struct rw_lock_struct {
volatile lint lock_word;
- /* Holds the state of the lock. */
- volatile ulint waiters;/* 1: there are waiters */
- volatile ibool recursive;/* Default value FALSE which means the lock
+ /*!< Holds the state of the lock. */
+ volatile ulint waiters;/*!< 1: there are waiters */
+ volatile ibool recursive;/*!< Default value FALSE which means the lock
is non-recursive. The value is typically set
to TRUE making normal rw_locks recursive. In
case of asynchronous IO, when a non-zero
@@ -503,59 +519,60 @@ struct rw_lock_struct {
This flag must be reset in x_unlock
functions before incrementing the lock_word */
volatile os_thread_id_t writer_thread;
- /* Thread id of writer thread. Is only
+ /*!< Thread id of writer thread. Is only
guaranteed to have sane and non-stale
value iff recursive flag is set. */
- os_event_t event; /* Used by sync0arr.c for thread queueing */
+ os_event_t event; /*!< Used by sync0arr.c for thread queueing */
os_event_t wait_ex_event;
- /* Event for next-writer to wait on. A thread
+ /*!< Event for next-writer to wait on. A thread
must decrement lock_word before waiting. */
#ifndef INNODB_RW_LOCKS_USE_ATOMICS
- mutex_t mutex; /* The mutex protecting rw_lock_struct */
+ mutex_t mutex; /*!< The mutex protecting rw_lock_struct */
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
UT_LIST_NODE_T(rw_lock_t) list;
- /* All allocated rw locks are put into a
+ /*!< All allocated rw locks are put into a
list */
#ifdef UNIV_SYNC_DEBUG
UT_LIST_BASE_NODE_T(rw_lock_debug_t) debug_list;
- /* In the debug version: pointer to the debug
+ /*!< In the debug version: pointer to the debug
info list of the lock */
- ulint level; /* Level in the global latching order. */
+ ulint level; /*!< Level in the global latching order. */
#endif /* UNIV_SYNC_DEBUG */
- ulint count_os_wait; /* Count of os_waits. May not be accurate */
- const char* cfile_name;/* File name where lock created */
+ ulint count_os_wait; /*!< Count of os_waits. May not be accurate */
+ const char* cfile_name;/*!< File name where lock created */
/* last s-lock file/line is not guaranteed to be correct */
- const char* last_s_file_name;/* File name where last s-locked */
- const char* last_x_file_name;/* File name where last x-locked */
+ const char* last_s_file_name;/*!< File name where last s-locked */
+ const char* last_x_file_name;/*!< File name where last x-locked */
ibool writer_is_wait_ex;
- /* This is TRUE if the writer field is
+ /*!< This is TRUE if the writer field is
RW_LOCK_WAIT_EX; this field is located far
from the memory update hotspot fields which
are at the start of this struct, thus we can
peek this field without causing much memory
bus traffic */
- 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 */
- ulint magic_n;
+ 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 */
+ ulint magic_n; /*!< RW_LOCK_MAGIC_N */
};
+/** Value of rw_lock_struct::magic_n */
#define RW_LOCK_MAGIC_N 22643
#ifdef UNIV_SYNC_DEBUG
-/* The structure for storing debug info of an rw-lock */
+/** The structure for storing debug info of an rw-lock */
struct rw_lock_debug_struct {
- os_thread_id_t thread_id; /* The thread id of the thread which
+ os_thread_id_t thread_id; /*!< The thread id of the thread which
locked the rw-lock */
- ulint pass; /* Pass value given in the lock operation */
- ulint lock_type; /* Type of the lock: RW_LOCK_EX,
+ ulint pass; /*!< Pass value given in the lock operation */
+ ulint lock_type; /*!< Type of the lock: RW_LOCK_EX,
RW_LOCK_SHARED, RW_LOCK_WAIT_EX */
- const char* file_name;/* File name where the lock was obtained */
- ulint line; /* Line where the rw-lock was locked */
+ const char* file_name;/*!< File name where the lock was obtained */
+ ulint line; /*!< Line where the rw-lock was locked */
UT_LIST_NODE_T(rw_lock_debug_t) list;
- /* Debug structs are linked in a two-way
+ /*!< Debug structs are linked in a two-way
list */
};
#endif /* UNIV_SYNC_DEBUG */
@@ -563,5 +580,6 @@ struct rw_lock_debug_struct {
#ifndef UNIV_NONINL
#include "sync0rw.ic"
#endif
+#endif /* !UNIV_HOTBACKUP */
#endif
diff --git a/storage/xtradb/include/sync0rw.ic b/storage/xtradb/include/sync0rw.ic
index 9e7e4dc9bd8..7116f1b7c9b 100644
--- a/storage/xtradb/include/sync0rw.ic
+++ b/storage/xtradb/include/sync0rw.ic
@@ -23,13 +23,14 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/sync0rw.ic
The read-write lock (for threads)
Created 9/11/1995 Heikki Tuuri
*******************************************************/
-/**********************************************************************
+/******************************************************************//**
Lock an rw-lock in shared mode for the current thread. If the rw-lock is
locked in exclusive mode, or there is an exclusive lock request waiting,
the function spins a preset time (controlled by SYNC_SPIN_ROUNDS),
@@ -38,47 +39,47 @@ UNIV_INTERN
void
rw_lock_s_lock_spin(
/*================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock will
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ ulint pass, /*!< in: pass value; != 0, if the lock will
be passed to another thread to unlock */
- const char* file_name,/* in: file name where lock requested */
- ulint line); /* in: line where requested */
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line); /*!< in: line where requested */
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
Inserts the debug information for an rw-lock. */
UNIV_INTERN
void
rw_lock_add_debug_info(
/*===================*/
- rw_lock_t* lock, /* in: rw-lock */
- ulint pass, /* in: pass value */
- ulint lock_type, /* in: lock type */
- const char* file_name, /* in: file where requested */
- ulint line); /* in: line where requested */
-/**********************************************************************
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint pass, /*!< in: pass value */
+ ulint lock_type, /*!< in: lock type */
+ const char* file_name, /*!< in: file where requested */
+ ulint line); /*!< in: line where requested */
+/******************************************************************//**
Removes a debug information struct for an rw-lock. */
UNIV_INTERN
void
rw_lock_remove_debug_info(
/*======================*/
- rw_lock_t* lock, /* in: rw-lock */
- ulint pass, /* in: pass value */
- ulint lock_type); /* in: lock type */
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint pass, /*!< in: pass value */
+ ulint lock_type); /*!< in: lock type */
#endif /* UNIV_SYNC_DEBUG */
-/************************************************************************
-Accessor functions for rw lock. */
+/********************************************************************//**
+Check if there are threads waiting for the rw-lock.
+@return 1 if waiters, 0 otherwise */
UNIV_INLINE
ulint
rw_lock_get_waiters(
/*================*/
- /* out: 1 if waiters, 0 otherwise */
- rw_lock_t* lock) /* in: rw-lock */
+ const rw_lock_t* lock) /*!< in: rw-lock */
{
return(lock->waiters);
}
-/************************************************************************
+/********************************************************************//**
Sets lock->waiters to 1. It is not an error if lock->waiters is already
1. On platforms where ATOMIC builtins are used this function enforces a
memory barrier. */
@@ -86,16 +87,16 @@ UNIV_INLINE
void
rw_lock_set_waiter_flag(
/*====================*/
- rw_lock_t* lock) /* in: rw-lock */
+ rw_lock_t* lock) /*!< in/out: rw-lock */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
- os_compare_and_swap(&lock->waiters, 0, 1);
+ os_compare_and_swap_ulint(&lock->waiters, 0, 1);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
lock->waiters = 1;
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
-/************************************************************************
+/********************************************************************//**
Resets lock->waiters to 0. It is not an error if lock->waiters is already
0. On platforms where ATOMIC builtins are used this function enforces a
memory barrier. */
@@ -103,26 +104,27 @@ UNIV_INLINE
void
rw_lock_reset_waiter_flag(
/*======================*/
- rw_lock_t* lock) /* in: rw-lock */
+ rw_lock_t* lock) /*!< in/out: rw-lock */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
- os_compare_and_swap(&lock->waiters, 1, 0);
+ os_compare_and_swap_ulint(&lock->waiters, 1, 0);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
lock->waiters = 0;
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
-/**********************************************************************
+/******************************************************************//**
Returns the write-status of the lock - this function made more sense
-with the old rw_lock implementation. */
+with the old rw_lock implementation.
+@return RW_LOCK_NOT_LOCKED, RW_LOCK_EX, RW_LOCK_WAIT_EX */
UNIV_INLINE
ulint
rw_lock_get_writer(
/*===============*/
- rw_lock_t* lock)
+ const rw_lock_t* lock) /*!< in: rw-lock */
{
lint lock_word = lock->lock_word;
- if(lock_word > 0) {
+ if (lock_word > 0) {
/* return NOT_LOCKED in s-lock state, like the writer
member of the old lock implementation. */
return(RW_LOCK_NOT_LOCKED);
@@ -134,16 +136,17 @@ rw_lock_get_writer(
}
}
-/**********************************************************************
-Returns number of readers. */
+/******************************************************************//**
+Returns the number of readers.
+@return number of readers */
UNIV_INLINE
ulint
rw_lock_get_reader_count(
/*=====================*/
- rw_lock_t* lock)
+ const rw_lock_t* lock) /*!< in: rw-lock */
{
lint lock_word = lock->lock_word;
- if(lock_word > 0) {
+ if (lock_word > 0) {
/* s-locked, no x-waiters */
return(X_LOCK_DECR - lock_word);
} else if (lock_word < 0 && lock_word > -X_LOCK_DECR) {
@@ -164,85 +167,74 @@ rw_lock_get_mutex(
}
#endif
-/**********************************************************************
+/******************************************************************//**
Returns the value of writer_count for the lock. Does not reserve the lock
-mutex, so the caller must be sure it is not changed during the call. */
+mutex, so the caller must be sure it is not changed during the call.
+@return value of writer_count */
UNIV_INLINE
ulint
rw_lock_get_x_lock_count(
/*=====================*/
- /* out: value of writer_count */
- rw_lock_t* lock) /* in: rw-lock */
+ const rw_lock_t* lock) /*!< in: rw-lock */
{
lint lock_copy = lock->lock_word;
/* If there is a reader, lock_word is not divisible by X_LOCK_DECR */
- if(lock_copy > 0 || (-lock_copy) % X_LOCK_DECR != 0) {
+ if (lock_copy > 0 || (-lock_copy) % X_LOCK_DECR != 0) {
return(0);
}
return(((-lock_copy) / X_LOCK_DECR) + 1);
}
-/**********************************************************************
+/******************************************************************//**
Two different implementations for decrementing the lock_word of a rw_lock:
one for systems supporting atomic operations, one for others. This does
does not support recusive x-locks: they should be handled by the caller and
need not be atomic since they are performed by the current lock holder.
-Returns true if the decrement was made, false if not. */
+Returns true if the decrement was made, false if not.
+@return TRUE if decr occurs */
UNIV_INLINE
ibool
rw_lock_lock_word_decr(
/*===================*/
- /* out: TRUE if decr occurs */
- rw_lock_t* lock, /* in: rw-lock */
- ulint amount) /* in: amount of decrement */
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ ulint amount) /*!< in: amount to decrement */
{
-
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
-
lint local_lock_word = lock->lock_word;
while (local_lock_word > 0) {
- if(os_compare_and_swap(&(lock->lock_word),
- local_lock_word,
- local_lock_word - amount)) {
+ if (os_compare_and_swap_lint(&lock->lock_word,
+ local_lock_word,
+ local_lock_word - amount)) {
return(TRUE);
}
local_lock_word = lock->lock_word;
}
return(FALSE);
-
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
-
ibool success = FALSE;
mutex_enter(&(lock->mutex));
- if(lock->lock_word > 0) {
+ if (lock->lock_word > 0) {
lock->lock_word -= amount;
success = TRUE;
}
mutex_exit(&(lock->mutex));
return(success);
-
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
-/**********************************************************************
-Two different implementations for incrementing the lock_word of a rw_lock:
-one for systems supporting atomic operations, one for others.
-Returns the value of lock_word after increment. */
+/******************************************************************//**
+Increments lock_word the specified amount and returns new value.
+@return lock->lock_word after increment */
UNIV_INLINE
lint
rw_lock_lock_word_incr(
/*===================*/
- /* out: lock->lock_word after increment */
- rw_lock_t* lock, /* in: rw-lock */
- ulint amount) /* in: amount of increment */
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ ulint amount) /*!< in: amount of increment */
{
-
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
-
- return(os_atomic_increment(&(lock->lock_word), amount));
-
+ return(os_atomic_increment_lint(&lock->lock_word, amount));
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
-
lint local_lock_word;
mutex_enter(&(lock->mutex));
@@ -253,11 +245,10 @@ rw_lock_lock_word_incr(
mutex_exit(&(lock->mutex));
return(local_lock_word);
-
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
-/**********************************************************************
+/******************************************************************//**
This function sets the lock->writer_thread and lock->recursive fields.
For platforms where we are using atomic builtins instead of lock->mutex
it sets the lock->writer_thread field using atomics to ensure memory
@@ -270,8 +261,8 @@ UNIV_INLINE
void
rw_lock_set_writer_id_and_recursion_flag(
/*=====================================*/
- rw_lock_t* lock, /* in/out: lock to work on */
- ibool recursive) /* in: TRUE if recursion
+ rw_lock_t* lock, /*!< in/out: lock to work on */
+ ibool recursive) /*!< in: TRUE if recursion
allowed */
{
os_thread_id_t curr_thread = os_thread_get_curr_id();
@@ -287,8 +278,8 @@ rw_lock_set_writer_id_and_recursion_flag(
UNIV_MEM_VALID(&lock->writer_thread, sizeof lock->writer_thread);
local_thread = lock->writer_thread;
- success = os_compare_and_swap(&lock->writer_thread,
- local_thread, curr_thread);
+ success = os_compare_and_swap_thread_id(
+ &lock->writer_thread, local_thread, curr_thread);
ut_a(success);
lock->recursive = recursive;
@@ -302,20 +293,20 @@ rw_lock_set_writer_id_and_recursion_flag(
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
}
-/**********************************************************************
+/******************************************************************//**
Low-level function which tries to lock an rw-lock in s-mode. Performs no
-spinning. */
+spinning.
+@return TRUE if success */
UNIV_INLINE
ibool
rw_lock_s_lock_low(
/*===============*/
- /* out: TRUE if success */
- rw_lock_t* lock, /* in: pointer to rw-lock */
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
ulint pass __attribute__((unused)),
- /* in: pass value; != 0, if the lock will be
+ /*!< in: pass value; != 0, if the lock will be
passed to another thread to unlock */
- const char* file_name, /* in: file name where lock requested */
- ulint line) /* in: line where requested */
+ const char* file_name, /*!< in: file name where lock requested */
+ ulint line) /*!< in: line where requested */
{
/* TODO: study performance of UNIV_LIKELY branch prediction hints. */
if (!rw_lock_lock_word_decr(lock, 1)) {
@@ -334,7 +325,7 @@ rw_lock_s_lock_low(
return(TRUE); /* locking succeeded */
}
-/**********************************************************************
+/******************************************************************//**
Low-level function which locks an rw-lock in s-mode when we know that it
is possible and none else is currently accessing the rw-lock structure.
Then we can do the locking without reserving the mutex. */
@@ -342,9 +333,9 @@ UNIV_INLINE
void
rw_lock_s_lock_direct(
/*==================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- const char* file_name, /* in: file name where requested */
- ulint line) /* in: line where lock requested */
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ const char* file_name, /*!< in: file name where requested */
+ ulint line) /*!< in: line where lock requested */
{
ut_ad(lock->lock_word == X_LOCK_DECR);
@@ -359,7 +350,7 @@ rw_lock_s_lock_direct(
#endif
}
-/**********************************************************************
+/******************************************************************//**
Low-level function which locks an rw-lock in x-mode when we know that it
is not locked and none else is currently accessing the rw-lock structure.
Then we can do the locking without reserving the mutex. */
@@ -367,9 +358,9 @@ UNIV_INLINE
void
rw_lock_x_lock_direct(
/*==================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- const char* file_name, /* in: file name where requested */
- ulint line) /* in: line where lock requested */
+ rw_lock_t* lock, /*!< in/out: rw-lock */
+ const char* file_name, /*!< in: file name where requested */
+ ulint line) /*!< in: line where lock requested */
{
ut_ad(rw_lock_validate(lock));
ut_ad(lock->lock_word == X_LOCK_DECR);
@@ -386,7 +377,7 @@ rw_lock_x_lock_direct(
#endif
}
-/**********************************************************************
+/******************************************************************//**
NOTE! Use the corresponding macro, not directly this function! Lock an
rw-lock in shared mode for the current thread. If the rw-lock is locked
in exclusive mode, or there is an exclusive lock request waiting, the
@@ -396,11 +387,11 @@ UNIV_INLINE
void
rw_lock_s_lock_func(
/*================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock will
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ ulint pass, /*!< in: pass value; != 0, if the lock will
be passed to another thread to unlock */
- const char* file_name,/* in: file name where lock requested */
- ulint line) /* in: line where requested */
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line) /*!< in: line where requested */
{
/* NOTE: As we do not know the thread ids for threads which have
s-locked a latch, and s-lockers will be served only after waiting
@@ -430,25 +421,25 @@ rw_lock_s_lock_func(
}
}
-/**********************************************************************
+/******************************************************************//**
NOTE! Use the corresponding macro, not directly this function! Lock an
rw-lock in exclusive mode for the current thread if the lock can be
-obtained immediately. */
+obtained immediately.
+@return TRUE if success */
UNIV_INLINE
ibool
rw_lock_x_lock_func_nowait(
/*=======================*/
- /* out: TRUE if success */
- rw_lock_t* lock, /* in: pointer to rw-lock */
- const char* file_name,/* in: file name where lock requested */
- ulint line) /* in: line where requested */
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line) /*!< in: line where requested */
{
os_thread_id_t curr_thread = os_thread_get_curr_id();
ibool success;
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
- success = os_compare_and_swap(&(lock->lock_word), X_LOCK_DECR, 0);
+ success = os_compare_and_swap_lint(&lock->lock_word, X_LOCK_DECR, 0);
#else
success = FALSE;
@@ -488,18 +479,17 @@ rw_lock_x_lock_func_nowait(
return(TRUE);
}
-/**********************************************************************
+/******************************************************************//**
Releases a shared mode lock. */
UNIV_INLINE
void
rw_lock_s_unlock_func(
/*==================*/
- rw_lock_t* lock /* in: rw-lock */
#ifdef UNIV_SYNC_DEBUG
- ,ulint pass /* in: pass value; != 0, if the lock may have
+ ulint pass, /*!< in: pass value; != 0, if the lock may have
been passed to another thread to unlock */
#endif
- )
+ rw_lock_t* lock) /*!< in/out: rw-lock */
{
ut_ad((lock->lock_word % X_LOCK_DECR) != 0);
@@ -525,14 +515,14 @@ rw_lock_s_unlock_func(
#endif
}
-/**********************************************************************
+/******************************************************************//**
Releases a shared mode lock when we know there are no waiters and none
else will access the lock during the time this function is executed. */
UNIV_INLINE
void
rw_lock_s_unlock_direct(
/*====================*/
- rw_lock_t* lock) /* in: rw-lock */
+ rw_lock_t* lock) /*!< in/out: rw-lock */
{
ut_ad(lock->lock_word < X_LOCK_DECR);
@@ -550,18 +540,17 @@ rw_lock_s_unlock_direct(
#endif
}
-/**********************************************************************
+/******************************************************************//**
Releases an exclusive mode lock. */
UNIV_INLINE
void
rw_lock_x_unlock_func(
/*==================*/
- rw_lock_t* lock /* in: rw-lock */
#ifdef UNIV_SYNC_DEBUG
- ,ulint pass /* in: pass value; != 0, if the lock may have
+ ulint pass, /*!< in: pass value; != 0, if the lock may have
been passed to another thread to unlock */
#endif
- )
+ rw_lock_t* lock) /*!< in/out: rw-lock */
{
ut_ad((lock->lock_word % X_LOCK_DECR) == 0);
@@ -600,14 +589,14 @@ rw_lock_x_unlock_func(
#endif
}
-/**********************************************************************
+/******************************************************************//**
Releases an exclusive mode lock when we know there are no waiters, and
none else will access the lock during the time this function is executed. */
UNIV_INLINE
void
rw_lock_x_unlock_direct(
/*====================*/
- rw_lock_t* lock) /* in: rw-lock */
+ rw_lock_t* lock) /*!< in/out: rw-lock */
{
/* Reset the exclusive lock if this thread no longer has an x-mode
lock */
diff --git a/storage/xtradb/include/sync0sync.h b/storage/xtradb/include/sync0sync.h
index dccfc020681..966bcced722 100644
--- a/storage/xtradb/include/sync0sync.h
+++ b/storage/xtradb/include/sync0sync.h
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/sync0sync.h
Mutex, the basic synchronization primitive
Created 9/5/1995 Heikki Tuuri
@@ -40,23 +41,30 @@ Created 9/5/1995 Heikki Tuuri
#include "os0sync.h"
#include "sync0arr.h"
-#ifndef UNIV_HOTBACKUP
+#if defined(UNIV_DEBUG) && !defined(UNIV_HOTBACKUP)
extern my_bool timed_mutexes;
-#endif /* UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
-/**********************************************************************
+#ifdef HAVE_WINDOWS_ATOMICS
+typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates
+ on LONG variable */
+#else
+typedef byte lock_word_t;
+#endif
+
+/******************************************************************//**
Initializes the synchronization data structures. */
UNIV_INTERN
void
sync_init(void);
/*===========*/
-/**********************************************************************
+/******************************************************************//**
Frees the resources in synchronization data structures. */
UNIV_INTERN
void
sync_close(void);
/*===========*/
-/**********************************************************************
+/******************************************************************//**
Creates, or rather, initializes a mutex object to a specified memory
location (which must be appropriately aligned). The mutex is initialized
in the reset state. Explicit freeing of the mutex with mutex_free is
@@ -75,7 +83,7 @@ necessary only if the memory block containing it is freed. */
mutex_create_func((M), __FILE__, __LINE__)
#endif
-/**********************************************************************
+/******************************************************************//**
Creates, or rather, initializes a mutex object in a specified memory
location (which must be appropriately aligned). The mutex is initialized
in the reset state. Explicit freeing of the mutex with mutex_free is
@@ -84,19 +92,19 @@ UNIV_INTERN
void
mutex_create_func(
/*==============*/
- mutex_t* mutex, /* in: pointer to memory */
+ mutex_t* mutex, /*!< in: pointer to memory */
#ifdef UNIV_DEBUG
- const char* cmutex_name, /* in: mutex name */
+ const char* cmutex_name, /*!< in: mutex name */
# ifdef UNIV_SYNC_DEBUG
- ulint level, /* in: level */
+ ulint level, /*!< in: level */
# endif /* UNIV_SYNC_DEBUG */
#endif /* UNIV_DEBUG */
- const char* cfile_name, /* in: file name where created */
- ulint cline); /* in: file line where created */
+ const char* cfile_name, /*!< in: file name where created */
+ ulint cline); /*!< in: file line where created */
#undef mutex_free /* Fix for MacOS X */
-/**********************************************************************
+/******************************************************************//**
Calling this function is obligatory only if the memory buffer containing
the mutex is freed. Removes a mutex object from the mutex list. The mutex
is checked to be in the reset state. */
@@ -104,20 +112,20 @@ UNIV_INTERN
void
mutex_free(
/*=======*/
- mutex_t* mutex); /* in: mutex */
-/******************************************************************
+ mutex_t* mutex); /*!< in: mutex */
+/**************************************************************//**
NOTE! The following macro should be used in mutex locking, not the
corresponding function. */
#define mutex_enter(M) mutex_enter_func((M), __FILE__, __LINE__)
-/******************************************************************
+/**************************************************************//**
NOTE! The following macro should be used in mutex locking, not the
corresponding function. */
/* NOTE! currently same as mutex_enter! */
#define mutex_enter_fast(M) mutex_enter_func((M), __FILE__, __LINE__)
-/**********************************************************************
+/******************************************************************//**
NOTE! Use the corresponding macro in the header file, not this function
directly. Locks a mutex for the current thread. If the mutex is reserved
the function spins a preset time (controlled by SYNC_SPIN_ROUNDS) waiting
@@ -126,78 +134,82 @@ UNIV_INLINE
void
mutex_enter_func(
/*=============*/
- mutex_t* mutex, /* in: pointer to mutex */
- const char* file_name, /* in: file name where locked */
- ulint line); /* in: line where locked */
-/******************************************************************
+ mutex_t* mutex, /*!< in: pointer to mutex */
+ const char* file_name, /*!< in: file name where locked */
+ ulint line); /*!< in: line where locked */
+/**************************************************************//**
NOTE! The following macro should be used in mutex locking, not the
corresponding function. */
#define mutex_enter_nowait(M) \
mutex_enter_nowait_func((M), __FILE__, __LINE__)
-/************************************************************************
+/********************************************************************//**
NOTE! Use the corresponding macro in the header file, not this function
directly. Tries to lock the mutex for the current thread. If the lock is not
-acquired immediately, returns with return value 1. */
+acquired immediately, returns with return value 1.
+@return 0 if succeed, 1 if not */
UNIV_INTERN
ulint
mutex_enter_nowait_func(
/*====================*/
- /* out: 0 if succeed, 1 if not */
- mutex_t* mutex, /* in: pointer to mutex */
- const char* file_name, /* in: file name where mutex
+ mutex_t* mutex, /*!< in: pointer to mutex */
+ const char* file_name, /*!< in: file name where mutex
requested */
- ulint line); /* in: line where requested */
-/**********************************************************************
+ ulint line); /*!< in: line where requested */
+/******************************************************************//**
Unlocks a mutex owned by the current thread. */
UNIV_INLINE
void
mutex_exit(
/*=======*/
- mutex_t* mutex); /* in: pointer to mutex */
-/**********************************************************************
+ mutex_t* mutex); /*!< in: pointer to mutex */
+#ifdef UNIV_SYNC_DEBUG
+/******************************************************************//**
Returns TRUE if no mutex or rw-lock is currently locked.
-Works only in the debug version. */
+Works only in the debug version.
+@return TRUE if no mutexes and rw-locks reserved */
UNIV_INTERN
ibool
sync_all_freed(void);
/*================*/
+#endif /* UNIV_SYNC_DEBUG */
/*#####################################################################
FUNCTION PROTOTYPES FOR DEBUGGING */
-/***********************************************************************
+/*******************************************************************//**
Prints wait info of the sync system. */
UNIV_INTERN
void
sync_print_wait_info(
/*=================*/
- FILE* file); /* in: file where to print */
-/***********************************************************************
+ FILE* file); /*!< in: file where to print */
+/*******************************************************************//**
Prints info of the sync system. */
UNIV_INTERN
void
sync_print(
/*=======*/
- FILE* file); /* in: file where to print */
+ FILE* file); /*!< in: file where to print */
#ifdef UNIV_DEBUG
-/**********************************************************************
-Checks that the mutex has been initialized. */
+/******************************************************************//**
+Checks that the mutex has been initialized.
+@return TRUE */
UNIV_INTERN
ibool
mutex_validate(
/*===========*/
- const mutex_t* mutex);
-/**********************************************************************
+ const mutex_t* mutex); /*!< in: mutex */
+/******************************************************************//**
Checks that the current thread owns the mutex. Works only
-in the debug version. */
+in the debug version.
+@return TRUE if owns */
UNIV_INTERN
ibool
mutex_own(
/*======*/
- /* out: TRUE if owns */
- const mutex_t* mutex); /* in: mutex */
+ const mutex_t* mutex); /*!< in: mutex */
#endif /* UNIV_DEBUG */
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
Adds a latch and its level in the thread level array. Allocates the memory
for the array if called first time for this OS thread. Makes the checks
against other latch levels stored in the array for this thread. */
@@ -205,75 +217,74 @@ UNIV_INTERN
void
sync_thread_add_level(
/*==================*/
- void* latch, /* in: pointer to a mutex or an rw-lock */
- ulint level); /* in: level in the latching order; if
+ void* latch, /*!< in: pointer to a mutex or an rw-lock */
+ ulint level); /*!< in: level in the latching order; if
SYNC_LEVEL_VARYING, nothing is done */
-/**********************************************************************
-Removes a latch from the thread level array if it is found there. */
+/******************************************************************//**
+Removes a latch from the thread level array if it is found there.
+@return TRUE if found in the array; it is no error if the latch is
+not found, as we presently are not able to determine the level for
+every latch reservation the program does */
UNIV_INTERN
ibool
sync_thread_reset_level(
/*====================*/
- /* out: TRUE if found from the array; it is no error
- if the latch is not found, as we presently are not
- able to determine the level for every latch
- reservation the program does */
- void* latch); /* in: pointer to a mutex or an rw-lock */
-/**********************************************************************
-Checks that the level array for the current thread is empty. */
+ void* latch); /*!< in: pointer to a mutex or an rw-lock */
+/******************************************************************//**
+Checks that the level array for the current thread is empty.
+@return TRUE if empty */
UNIV_INTERN
ibool
sync_thread_levels_empty(void);
/*==========================*/
- /* out: TRUE if empty */
-/**********************************************************************
-Checks that the level array for the current thread is empty. */
+/******************************************************************//**
+Checks that the level array for the current thread is empty.
+@return TRUE if empty except the exceptions specified below */
UNIV_INTERN
ibool
sync_thread_levels_empty_gen(
/*=========================*/
- /* out: TRUE if empty except the
- exceptions specified below */
- ibool dict_mutex_allowed); /* in: TRUE if dictionary mutex is
+ ibool dict_mutex_allowed); /*!< in: TRUE if dictionary mutex is
allowed to be owned by the thread,
also purge_is_running mutex is
allowed */
-/**********************************************************************
+/******************************************************************//**
Gets the debug information for a reserved mutex. */
UNIV_INTERN
void
mutex_get_debug_info(
/*=================*/
- mutex_t* mutex, /* in: mutex */
- const char** file_name, /* out: file where requested */
- ulint* line, /* out: line where requested */
- os_thread_id_t* thread_id); /* out: id of the thread which owns
+ mutex_t* mutex, /*!< in: mutex */
+ const char** file_name, /*!< out: file where requested */
+ ulint* line, /*!< out: line where requested */
+ os_thread_id_t* thread_id); /*!< out: id of the thread which owns
the mutex */
-/**********************************************************************
-Counts currently reserved mutexes. Works only in the debug version. */
+/******************************************************************//**
+Counts currently reserved mutexes. Works only in the debug version.
+@return number of reserved mutexes */
UNIV_INTERN
ulint
mutex_n_reserved(void);
/*==================*/
#endif /* UNIV_SYNC_DEBUG */
-/**********************************************************************
+/******************************************************************//**
NOT to be used outside this module except in debugging! Gets the value
of the lock word. */
UNIV_INLINE
-byte
+lock_word_t
mutex_get_lock_word(
/*================*/
- const mutex_t* mutex); /* in: mutex */
+ const mutex_t* mutex); /*!< in: mutex */
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
NOT to be used outside this module except in debugging! Gets the waiters
-field in a mutex. */
+field in a mutex.
+@return value to set */
UNIV_INLINE
ulint
mutex_get_waiters(
/*==============*/
- /* out: value to set */
- const mutex_t* mutex); /* in: mutex */
+ const mutex_t* mutex); /*!< in: mutex */
#endif /* UNIV_SYNC_DEBUG */
/*
@@ -490,81 +501,79 @@ or row lock! */
Do not use its fields directly! The structure used in the spin lock
implementation of a mutual exclusion semaphore. */
+/** InnoDB mutex */
struct mutex_struct {
- os_event_t event; /* Used by sync0arr.c for the wait queue */
- byte lock_word; /* This byte is the target of the atomic
- test-and-set instruction in Win32 and
- x86 32/64 with GCC 4.1.0 or later version */
-#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
-#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
-#else
+ os_event_t event; /*!< Used by sync0arr.c for the wait queue */
+ volatile lock_word_t lock_word; /*!< lock_word is the target
+ of the atomic test-and-set instruction when
+ atomic operations are enabled. */
+
+#if !defined(HAVE_ATOMIC_BUILTINS)
os_fast_mutex_t
- os_fast_mutex; /* In other systems we use this OS mutex
- in place of lock_word */
+ os_fast_mutex; /*!< We use this OS mutex in place of lock_word
+ when atomic operations are not enabled */
#endif
- ulint waiters; /* This ulint is set to 1 if there are (or
+ ulint waiters; /*!< This ulint is set to 1 if there are (or
may be) threads waiting in the global wait
array for this mutex to be released.
Otherwise, this is 0. */
- UT_LIST_NODE_T(mutex_t) list; /* All allocated mutexes are put into
+ UT_LIST_NODE_T(mutex_t) list; /*!< All allocated mutexes are put into
a list. Pointers to the next and prev. */
#ifdef UNIV_SYNC_DEBUG
- const char* file_name; /* File where the mutex was locked */
- ulint line; /* Line where the mutex was locked */
- ulint level; /* Level in the global latching order */
+ const char* file_name; /*!< File where the mutex was locked */
+ ulint line; /*!< Line where the mutex was locked */
+ ulint level; /*!< Level in the global latching order */
#endif /* UNIV_SYNC_DEBUG */
- const char* cfile_name;/* File name where mutex created */
- ulint cline; /* Line where created */
+ const char* cfile_name;/*!< File name where mutex created */
+ ulint cline; /*!< Line where created */
#ifdef UNIV_DEBUG
- os_thread_id_t thread_id; /* The thread id of the thread
+ os_thread_id_t thread_id; /*!< The thread id of the thread
which locked the mutex. */
- ulint magic_n;
+ ulint magic_n; /*!< MUTEX_MAGIC_N */
+/** Value of mutex_struct::magic_n */
# define MUTEX_MAGIC_N (ulint)979585
#endif /* UNIV_DEBUG */
-#ifndef UNIV_HOTBACKUP
- ulong count_os_wait; /* count of os_wait */
-# ifdef UNIV_DEBUG
- ulong count_using; /* count of times mutex used */
- ulong count_spin_loop; /* count of spin loops */
- ulong count_spin_rounds; /* count of spin rounds */
- ulong count_os_yield; /* count of os_wait */
- ulonglong lspent_time; /* mutex os_wait timer msec */
- ulonglong lmax_spent_time; /* mutex os_wait timer msec */
- const char* cmutex_name;/* mutex name */
- ulint mutex_type;/* 0 - usual mutex 1 - rw_lock mutex */
-# endif /* UNIV_DEBUG */
-#endif /* !UNIV_HOTBACKUP */
+ ulong count_os_wait; /*!< count of os_wait */
+#ifdef UNIV_DEBUG
+ ulong count_using; /*!< count of times mutex used */
+ ulong count_spin_loop; /*!< count of spin loops */
+ ulong count_spin_rounds;/*!< count of spin rounds */
+ ulong count_os_yield; /*!< count of os_wait */
+ ulonglong lspent_time; /*!< mutex os_wait timer msec */
+ ulonglong lmax_spent_time;/*!< mutex os_wait timer msec */
+ const char* cmutex_name; /*!< mutex name */
+ ulint mutex_type; /*!< 0=usual mutex, 1=rw_lock mutex */
+#endif /* UNIV_DEBUG */
};
-/* The global array of wait cells for implementation of the databases own
-mutexes and read-write locks. Appears here for debugging purposes only! */
+/** The global array of wait cells for implementation of the databases own
+mutexes and read-write locks. */
+extern sync_array_t* sync_primary_wait_array;/* Appears here for
+ debugging purposes only! */
-extern sync_array_t* sync_primary_wait_array;
-
-/* Constant determining how long spin wait is continued before suspending
+/** Constant determining how long spin wait is continued before suspending
the thread. A value 600 rounds on a 1995 100 MHz Pentium seems to correspond
to 20 microseconds. */
#define SYNC_SPIN_ROUNDS srv_n_spin_wait_rounds
-/* The number of system calls made in this module. Intended for performance
-monitoring. */
-
+/** The number of mutex_exit calls. Intended for performance monitoring. */
extern ib_int64_t mutex_exit_count;
#ifdef UNIV_SYNC_DEBUG
-/* Latching order checks start when this is set TRUE */
+/** Latching order checks start when this is set TRUE */
extern ibool sync_order_checks_on;
#endif /* UNIV_SYNC_DEBUG */
-/* This variable is set to TRUE when sync_init is called */
+/** This variable is set to TRUE when sync_init is called */
extern ibool sync_initialized;
-/* Global list of database mutexes (not OS mutexes) created. */
+/** Global list of database mutexes (not OS mutexes) created. */
typedef UT_LIST_BASE_NODE_T(mutex_t) ut_list_base_node_t;
+/** Global list of database mutexes (not OS mutexes) created. */
extern ut_list_base_node_t mutex_list;
-/* Mutex protecting the mutex_list variable */
+/** Mutex protecting the mutex_list variable */
extern mutex_t mutex_list_mutex;
diff --git a/storage/xtradb/include/sync0sync.ic b/storage/xtradb/include/sync0sync.ic
index c43121ebd0b..b05020b5660 100644
--- a/storage/xtradb/include/sync0sync.ic
+++ b/storage/xtradb/include/sync0sync.ic
@@ -23,21 +23,22 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/sync0sync.ic
Mutex, the basic synchronization primitive
Created 9/5/1995 Heikki Tuuri
*******************************************************/
-/**********************************************************************
+/******************************************************************//**
Sets the waiters field in a mutex. */
UNIV_INTERN
void
mutex_set_waiters(
/*==============*/
- mutex_t* mutex, /* in: mutex */
- ulint n); /* in: value to set */
-/**********************************************************************
+ mutex_t* mutex, /*!< in: mutex */
+ ulint n); /*!< in: value to set */
+/******************************************************************//**
Reserves a mutex for the current thread. If the mutex is reserved, the
function spins a preset time (controlled by SYNC_SPIN_ROUNDS) waiting
for the mutex before suspending the thread. */
@@ -45,74 +46,41 @@ UNIV_INTERN
void
mutex_spin_wait(
/*============*/
- mutex_t* mutex, /* in: pointer to mutex */
- const char* file_name, /* in: file name where mutex
+ mutex_t* mutex, /*!< in: pointer to mutex */
+ const char* file_name, /*!< in: file name where mutex
requested */
- ulint line); /* in: line where requested */
+ ulint line); /*!< in: line where requested */
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
Sets the debug information for a reserved mutex. */
UNIV_INTERN
void
mutex_set_debug_info(
/*=================*/
- mutex_t* mutex, /* in: mutex */
- const char* file_name, /* in: file where requested */
- ulint line); /* in: line where requested */
+ mutex_t* mutex, /*!< in: mutex */
+ const char* file_name, /*!< in: file where requested */
+ ulint line); /*!< in: line where requested */
#endif /* UNIV_SYNC_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Releases the threads waiting in the primary wait array for this mutex. */
UNIV_INTERN
void
mutex_signal_object(
/*================*/
- mutex_t* mutex); /* in: mutex */
+ mutex_t* mutex); /*!< in: mutex */
-/**********************************************************************
+/******************************************************************//**
Performs an atomic test-and-set instruction to the lock_word field of a
-mutex. */
+mutex.
+@return the previous value of lock_word: 0 or 1 */
UNIV_INLINE
byte
mutex_test_and_set(
/*===============*/
- /* out: the previous value of lock_word: 0 or
- 1 */
- mutex_t* mutex) /* in: mutex */
+ mutex_t* mutex) /*!< in: mutex */
{
-#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
- byte res;
- byte* lw; /* assembler code is used to ensure that
- lock_word is loaded from memory */
- ut_ad(mutex);
- ut_ad(sizeof(byte) == 1);
-
- lw = &(mutex->lock_word);
-
- __asm MOV ECX, lw
- __asm MOV EDX, 1
- __asm XCHG DL, BYTE PTR [ECX]
- __asm MOV res, DL
-
- /* The fence below would prevent this thread from
- reading the data structure protected by the mutex
- before the test-and-set operation is committed, but
- the fence is apparently not needed:
-
- In a posting to comp.arch newsgroup (August 10, 1997)
- Andy Glew said that in P6 a LOCKed instruction like
- XCHG establishes a fence with respect to memory reads
- and writes and thus an explicit fence is not
- needed. In P5 he seemed to agree with a previous
- newsgroup poster that LOCKed instructions serialize
- all instruction execution, and, consequently, also
- memory operations. This is confirmed in Intel Software
- Dev. Manual, Vol. 3. */
-
- /* mutex_fence(); */
-
- return(res);
-#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
- return __sync_lock_test_and_set(&(mutex->lock_word), 1);
+#if defined(HAVE_ATOMIC_BUILTINS)
+ return(os_atomic_test_and_set_byte(&mutex->lock_word, 1));
#else
ibool ret;
@@ -130,30 +98,20 @@ mutex_test_and_set(
#endif
}
-/**********************************************************************
+/******************************************************************//**
Performs a reset instruction to the lock_word field of a mutex. This
instruction also serializes memory operations to the program order. */
UNIV_INLINE
void
mutex_reset_lock_word(
/*==================*/
- mutex_t* mutex) /* in: mutex */
+ mutex_t* mutex) /*!< in: mutex */
{
-#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
- byte* lw; /* assembler code is used to ensure that
- lock_word is loaded from memory */
- ut_ad(mutex);
-
- lw = &(mutex->lock_word);
-
- __asm MOV EDX, 0
- __asm MOV ECX, lw
- __asm XCHG DL, BYTE PTR [ECX]
-#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
+#if defined(HAVE_ATOMIC_BUILTINS)
/* In theory __sync_lock_release should be used to release the lock.
Unfortunately, it does not work properly alone. The workaround is
that more conservative __sync_lock_test_and_set is used instead. */
- __sync_lock_test_and_set(&(mutex->lock_word), 0);
+ os_atomic_test_and_set_byte(&mutex->lock_word, 0);
#else
mutex->lock_word = 0;
@@ -161,33 +119,29 @@ mutex_reset_lock_word(
#endif
}
-/**********************************************************************
+/******************************************************************//**
Gets the value of the lock word. */
UNIV_INLINE
-byte
+lock_word_t
mutex_get_lock_word(
/*================*/
- const mutex_t* mutex) /* in: mutex */
+ const mutex_t* mutex) /*!< in: mutex */
{
- const volatile byte* ptr; /* declared volatile to ensure that
- lock_word is loaded from memory */
ut_ad(mutex);
- ptr = &(mutex->lock_word);
-
- return(*ptr);
+ return(mutex->lock_word);
}
-/**********************************************************************
-Gets the waiters field in a mutex. */
+/******************************************************************//**
+Gets the waiters field in a mutex.
+@return value to set */
UNIV_INLINE
ulint
mutex_get_waiters(
/*==============*/
- /* out: value to set */
- const mutex_t* mutex) /* in: mutex */
+ const mutex_t* mutex) /*!< in: mutex */
{
- const volatile ulint* ptr; /* declared volatile to ensure that
+ const volatile ulint* ptr; /*!< declared volatile to ensure that
the value is read from memory */
ut_ad(mutex);
@@ -197,13 +151,13 @@ mutex_get_waiters(
word from memory is atomic */
}
-/**********************************************************************
+/******************************************************************//**
Unlocks a mutex owned by the current thread. */
UNIV_INLINE
void
mutex_exit(
/*=======*/
- mutex_t* mutex) /* in: pointer to mutex */
+ mutex_t* mutex) /*!< in: pointer to mutex */
{
ut_ad(mutex_own(mutex));
@@ -236,7 +190,7 @@ mutex_exit(
#endif
}
-/**********************************************************************
+/******************************************************************//**
Locks a mutex for the current thread. If the mutex is reserved, the function
spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting for the mutex
before suspending the thread. */
@@ -244,9 +198,9 @@ UNIV_INLINE
void
mutex_enter_func(
/*=============*/
- mutex_t* mutex, /* in: pointer to mutex */
- const char* file_name, /* in: file name where locked */
- ulint line) /* in: line where locked */
+ mutex_t* mutex, /*!< in: pointer to mutex */
+ const char* file_name, /*!< in: file name where locked */
+ ulint line) /*!< in: line where locked */
{
ut_ad(mutex_validate(mutex));
ut_ad(!mutex_own(mutex));
@@ -254,9 +208,7 @@ mutex_enter_func(
/* Note that we do not peek at the value of lock_word before trying
the atomic test_and_set; we could peek, and possibly save time. */
-#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
- mutex->count_using++;
-#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
+ ut_d(mutex->count_using++);
if (!mutex_test_and_set(mutex)) {
ut_d(mutex->thread_id = os_thread_get_curr_id());
diff --git a/storage/xtradb/include/sync0types.h b/storage/xtradb/include/sync0types.h
index 3c1021b1a30..1911bbac7fd 100644
--- a/storage/xtradb/include/sync0types.h
+++ b/storage/xtradb/include/sync0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/sync0types.h
Global types for sync
Created 9/5/1995 Heikki Tuuri
@@ -25,7 +26,9 @@ Created 9/5/1995 Heikki Tuuri
#ifndef sync0types_h
#define sync0types_h
+/** Rename mutex_t to avoid name space collision on some systems */
#define mutex_t ib_mutex_t
+/** InnoDB mutex */
typedef struct mutex_struct mutex_t;
#endif
diff --git a/storage/xtradb/include/thr0loc.h b/storage/xtradb/include/thr0loc.h
index 96ec13cc8e4..34c5232238d 100644
--- a/storage/xtradb/include/thr0loc.h
+++ b/storage/xtradb/include/thr0loc.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/thr0loc.h
The thread local storage
Created 10/5/1995 Heikki Tuuri
@@ -32,49 +33,49 @@ OS handle to the current thread, or its priority. */
#include "univ.i"
#include "os0thread.h"
-/********************************************************************
+/****************************************************************//**
Initializes the thread local storage module. */
UNIV_INTERN
void
thr_local_init(void);
/*================*/
-/***********************************************************************
+/*******************************************************************//**
Creates a local storage struct for the calling new thread. */
UNIV_INTERN
void
thr_local_create(void);
/*==================*/
-/***********************************************************************
+/*******************************************************************//**
Frees the local storage struct for the specified thread. */
UNIV_INTERN
void
thr_local_free(
/*===========*/
- os_thread_id_t id); /* in: thread id */
-/***********************************************************************
-Gets the slot number in the thread table of a thread. */
+ os_thread_id_t id); /*!< in: thread id */
+/*******************************************************************//**
+Gets the slot number in the thread table of a thread.
+@return slot number */
UNIV_INTERN
ulint
thr_local_get_slot_no(
/*==================*/
- /* out: slot number */
- os_thread_id_t id); /* in: thread id of the thread */
-/***********************************************************************
+ os_thread_id_t id); /*!< in: thread id of the thread */
+/*******************************************************************//**
Sets in the local storage the slot number in the thread table of a thread. */
UNIV_INTERN
void
thr_local_set_slot_no(
/*==================*/
- os_thread_id_t id, /* in: thread id of the thread */
- ulint slot_no);/* in: slot number */
-/***********************************************************************
+ os_thread_id_t id, /*!< in: thread id of the thread */
+ ulint slot_no);/*!< in: slot number */
+/*******************************************************************//**
Returns pointer to the 'in_ibuf' field within the current thread local
-storage. */
+storage.
+@return pointer to the in_ibuf field */
UNIV_INTERN
ibool*
thr_local_get_in_ibuf_field(void);
/*=============================*/
- /* out: pointer to the in_ibuf field */
/*************************************************************************
Return local hash table informations. */
diff --git a/storage/xtradb/include/thr0loc.ic b/storage/xtradb/include/thr0loc.ic
index 6de183fd857..ce44e512320 100644
--- a/storage/xtradb/include/thr0loc.ic
+++ b/storage/xtradb/include/thr0loc.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/thr0loc.ic
Thread local storage
Created 10/4/1995 Heikki Tuuri
diff --git a/storage/xtradb/include/trx0i_s.h b/storage/xtradb/include/trx0i_s.h
index cf2865af127..9bf032de9f9 100644
--- a/storage/xtradb/include/trx0i_s.h
+++ b/storage/xtradb/include/trx0i_s.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0i_s.h
INFORMATION SCHEMA innodb_trx, innodb_locks and
innodb_lock_waits tables cache structures and public
functions.
@@ -31,182 +32,209 @@ Created July 17, 2007 Vasil Dimov
#include "trx0types.h"
#include "ut0ut.h"
-/* the maximum amount of memory that can be consumed by innodb_trx,
+/** The maximum amount of memory that can be consumed by innodb_trx,
innodb_locks and innodb_lock_waits information schema tables. */
#define TRX_I_S_MEM_LIMIT 16777216 /* 16 MiB */
-/* the maximum length of a string that can be stored in
+/** The maximum length of a string that can be stored in
i_s_locks_row_t::lock_data */
#define TRX_I_S_LOCK_DATA_MAX_LEN 8192
-/* the maximum length of a string that can be stored in
+/** The maximum length of a string that can be stored in
i_s_trx_row_t::trx_query */
#define TRX_I_S_TRX_QUERY_MAX_LEN 1024
+/** A row of INFORMATION_SCHEMA.innodb_locks */
typedef struct i_s_locks_row_struct i_s_locks_row_t;
+/** A row of INFORMATION_SCHEMA.innodb_trx */
+typedef struct i_s_trx_row_struct i_s_trx_row_t;
+/** A row of INFORMATION_SCHEMA.innodb_lock_waits */
+typedef struct i_s_lock_waits_row_struct i_s_lock_waits_row_t;
+
+/** Objects of trx_i_s_cache_t::locks_hash */
typedef struct i_s_hash_chain_struct i_s_hash_chain_t;
-/* Objects of this type are added to the hash table
+/** Objects of this type are added to the hash table
trx_i_s_cache_t::locks_hash */
struct i_s_hash_chain_struct {
- i_s_locks_row_t* value;
- i_s_hash_chain_t* next;
+ i_s_locks_row_t* value; /*!< row of
+ INFORMATION_SCHEMA.innodb_locks*/
+ i_s_hash_chain_t* next; /*!< next item in the hash chain */
};
-/* This structure represents INFORMATION_SCHEMA.innodb_locks row */
+/** This structure represents INFORMATION_SCHEMA.innodb_locks row */
struct i_s_locks_row_struct {
- ullint lock_trx_id;
- const char* lock_mode;
- const char* lock_type;
- const char* lock_table;
- const char* lock_index;
- ulint lock_space;
- ulint lock_page;
- ulint lock_rec;
- const char* lock_data;
-
- /* The following are auxiliary and not included in the table */
+ ullint lock_trx_id; /*!< transaction identifier */
+ const char* lock_mode; /*!< lock mode from
+ lock_get_mode_str() */
+ const char* lock_type; /*!< lock type from
+ lock_get_type_str() */
+ const char* lock_table; /*!< table name from
+ lock_get_table_name() */
+ const char* lock_index; /*!< index name from
+ lock_rec_get_index_name() */
+ /** Information for record locks. All these are
+ ULINT_UNDEFINED for table locks. */
+ /* @{ */
+ ulint lock_space; /*!< tablespace identifier */
+ ulint lock_page; /*!< page number within the_space */
+ ulint lock_rec; /*!< heap number of the record
+ on the page */
+ const char* lock_data; /*!< (some) content of the record */
+ /* @} */
+
+ /** The following are auxiliary and not included in the table */
+ /* @{ */
ullint lock_table_id;
- i_s_hash_chain_t hash_chain; /* this object is added to the hash
- table
- trx_i_s_cache_t::locks_hash */
+ /*!< table identifier from
+ lock_get_table_id */
+ i_s_hash_chain_t hash_chain; /*!< hash table chain node for
+ trx_i_s_cache_t::locks_hash */
+ /* @} */
};
-/* This structure represents INFORMATION_SCHEMA.innodb_trx row */
-typedef struct i_s_trx_row_struct {
- ullint trx_id;
- const char* trx_state;
- ib_time_t trx_started;
+/** This structure represents INFORMATION_SCHEMA.innodb_trx row */
+struct i_s_trx_row_struct {
+ ullint trx_id; /*!< transaction identifier */
+ const char* trx_state; /*!< transaction state from
+ trx_get_que_state_str() */
+ ib_time_t trx_started; /*!< trx_struct::start_time */
const i_s_locks_row_t* requested_lock_row;
+ /*!< pointer to a row
+ in innodb_locks if trx
+ is waiting, or NULL */
ib_time_t trx_wait_started;
- ullint trx_weight;
+ /*!< trx_struct::wait_started */
+ ullint trx_weight; /*!< TRX_WEIGHT() */
ulint trx_mysql_thread_id;
- const char* trx_query;
-} i_s_trx_row_t;
+ /*!< thd_get_thread_id() */
+ const char* trx_query; /*!< MySQL statement being
+ executed in the transaction */
+};
-/* This structure represents INFORMATION_SCHEMA.innodb_lock_waits row */
-typedef struct i_s_lock_waits_row_struct {
- const i_s_locks_row_t* requested_lock_row;
- const i_s_locks_row_t* blocking_lock_row;
-} i_s_lock_waits_row_t;
+/** This structure represents INFORMATION_SCHEMA.innodb_lock_waits row */
+struct i_s_lock_waits_row_struct {
+ const i_s_locks_row_t* requested_lock_row; /*!< requested lock */
+ const i_s_locks_row_t* blocking_lock_row; /*!< blocking lock */
+};
-/* This type is opaque and is defined in trx/trx0i_s.c */
+/** Cache of INFORMATION_SCHEMA table data */
typedef struct trx_i_s_cache_struct trx_i_s_cache_t;
-/* Auxiliary enum used by functions that need to select one of the
+/** Auxiliary enum used by functions that need to select one of the
INFORMATION_SCHEMA tables */
enum i_s_table {
- I_S_INNODB_TRX,
- I_S_INNODB_LOCKS,
- I_S_INNODB_LOCK_WAITS
+ I_S_INNODB_TRX, /*!< INFORMATION_SCHEMA.innodb_trx */
+ I_S_INNODB_LOCKS, /*!< INFORMATION_SCHEMA.innodb_locks */
+ I_S_INNODB_LOCK_WAITS /*!< INFORMATION_SCHEMA.innodb_lock_waits */
};
-/* This is the intermediate buffer where data needed to fill the
+/** This is the intermediate buffer where data needed to fill the
INFORMATION SCHEMA tables is fetched and later retrieved by the C++
code in handler/i_s.cc. */
extern trx_i_s_cache_t* trx_i_s_cache;
-/***********************************************************************
+/*******************************************************************//**
Initialize INFORMATION SCHEMA trx related cache. */
UNIV_INTERN
void
trx_i_s_cache_init(
/*===============*/
- trx_i_s_cache_t* cache); /* out: cache to init */
+ trx_i_s_cache_t* cache); /*!< out: cache to init */
-/***********************************************************************
+/*******************************************************************//**
Issue a shared/read lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_start_read(
/*=====================*/
- trx_i_s_cache_t* cache); /* in: cache */
+ trx_i_s_cache_t* cache); /*!< in: cache */
-/***********************************************************************
+/*******************************************************************//**
Release a shared/read lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_end_read(
/*===================*/
- trx_i_s_cache_t* cache); /* in: cache */
+ trx_i_s_cache_t* cache); /*!< in: cache */
-/***********************************************************************
+/*******************************************************************//**
Issue an exclusive/write lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_start_write(
/*======================*/
- trx_i_s_cache_t* cache); /* in: cache */
+ trx_i_s_cache_t* cache); /*!< in: cache */
-/***********************************************************************
+/*******************************************************************//**
Release an exclusive/write lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_end_write(
/*====================*/
- trx_i_s_cache_t* cache); /* in: cache */
+ trx_i_s_cache_t* cache); /*!< in: cache */
-/***********************************************************************
+/*******************************************************************//**
Retrieves the number of used rows in the cache for a given
-INFORMATION SCHEMA table. */
+INFORMATION SCHEMA table.
+@return number of rows */
UNIV_INTERN
ulint
trx_i_s_cache_get_rows_used(
/*========================*/
- /* out: number of rows */
- trx_i_s_cache_t* cache, /* in: cache */
- enum i_s_table table); /* in: which table */
+ trx_i_s_cache_t* cache, /*!< in: cache */
+ enum i_s_table table); /*!< in: which table */
-/***********************************************************************
+/*******************************************************************//**
Retrieves the nth row in the cache for a given INFORMATION SCHEMA
-table. */
+table.
+@return row */
UNIV_INTERN
void*
trx_i_s_cache_get_nth_row(
/*======================*/
- /* out: row */
- trx_i_s_cache_t* cache, /* in: cache */
- enum i_s_table table, /* in: which table */
- ulint n); /* in: row number */
+ trx_i_s_cache_t* cache, /*!< in: cache */
+ enum i_s_table table, /*!< in: which table */
+ ulint n); /*!< in: row number */
-/***********************************************************************
-Update the transactions cache if it has not been read for some time. */
+/*******************************************************************//**
+Update the transactions cache if it has not been read for some time.
+@return 0 - fetched, 1 - not */
UNIV_INTERN
int
trx_i_s_possibly_fetch_data_into_cache(
/*===================================*/
- /* out: 0 - fetched, 1 - not */
- trx_i_s_cache_t* cache); /* in/out: cache */
+ trx_i_s_cache_t* cache); /*!< in/out: cache */
-/***********************************************************************
+/*******************************************************************//**
Returns TRUE if the data in the cache is truncated due to the memory
-limit posed by TRX_I_S_MEM_LIMIT. */
+limit posed by TRX_I_S_MEM_LIMIT.
+@return TRUE if truncated */
UNIV_INTERN
ibool
trx_i_s_cache_is_truncated(
/*=======================*/
- /* out: TRUE if truncated */
- trx_i_s_cache_t* cache); /* in: cache */
+ trx_i_s_cache_t* cache); /*!< in: cache */
-/* The maximum length of a resulting lock_id_size in
-trx_i_s_create_lock_id(), not including the terminating '\0'.
+/** The maximum length of a resulting lock_id_size in
+trx_i_s_create_lock_id(), not including the terminating NUL.
":%lu:%lu:%lu" -> 63 chars */
#define TRX_I_S_LOCK_ID_MAX_LEN (TRX_ID_MAX_LEN + 63)
-/***********************************************************************
+/*******************************************************************//**
Crafts a lock id string from a i_s_locks_row_t object. Returns its
second argument. This function aborts if there is not enough space in
lock_id. Be sure to provide at least TRX_I_S_LOCK_ID_MAX_LEN + 1 if you
-want to be 100% sure that it will not abort. */
+want to be 100% sure that it will not abort.
+@return resulting lock id */
UNIV_INTERN
char*
trx_i_s_create_lock_id(
/*===================*/
- /* out: resulting lock id */
- const i_s_locks_row_t* row, /* in: innodb_locks row */
- char* lock_id,/* out: resulting lock_id */
- ulint lock_id_size);/* in: size of the lock id
+ const i_s_locks_row_t* row, /*!< in: innodb_locks row */
+ char* lock_id,/*!< out: resulting lock_id */
+ ulint lock_id_size);/*!< in: size of the lock id
buffer */
#endif /* trx0i_s_h */
diff --git a/storage/xtradb/include/trx0purge.h b/storage/xtradb/include/trx0purge.h
index 4921b860485..7812ad7eb92 100644
--- a/storage/xtradb/include/trx0purge.h
+++ b/storage/xtradb/include/trx0purge.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0purge.h
Purge old versions
Created 3/26/1996 Heikki Tuuri
@@ -34,143 +35,140 @@ Created 3/26/1996 Heikki Tuuri
#include "usr0sess.h"
#include "fil0fil.h"
-/* The global data structure coordinating a purge */
+/** The global data structure coordinating a purge */
extern trx_purge_t* purge_sys;
-/* A dummy undo record used as a return value when we have a whole undo log
+/** A dummy undo record used as a return value when we have a whole undo log
which needs no purge */
extern trx_undo_rec_t trx_purge_dummy_rec;
-/************************************************************************
+/********************************************************************//**
Calculates the file address of an undo log header when we have the file
-address of its history list node. */
+address of its history list node.
+@return file address of the log */
UNIV_INLINE
fil_addr_t
trx_purge_get_log_from_hist(
/*========================*/
- /* out: file address of the log */
- fil_addr_t node_addr); /* in: file address of the history
+ fil_addr_t node_addr); /*!< in: file address of the history
list node of the log */
-/*********************************************************************
+/*****************************************************************//**
Checks if trx_id is >= purge_view: then it is guaranteed that its update
-undo log still exists in the system. */
+undo log still exists in the system.
+@return TRUE if is sure that it is preserved, also if the function
+returns FALSE, it is possible that the undo log still exists in the
+system */
UNIV_INTERN
ibool
trx_purge_update_undo_must_exist(
/*=============================*/
- /* out: TRUE if is sure that it is preserved, also
- if the function returns FALSE, it is possible that
- the undo log still exists in the system */
- dulint trx_id);/* in: transaction id */
-/************************************************************************
+ trx_id_t trx_id);/*!< in: transaction id */
+/********************************************************************//**
Creates the global purge system control structure and inits the history
mutex. */
UNIV_INTERN
void
trx_purge_sys_create(void);
/*======================*/
-/************************************************************************
+/********************************************************************//**
Adds the update undo log as the first log in the history list. Removes the
update undo log segment from the rseg slot if it is too big for reuse. */
UNIV_INTERN
void
trx_purge_add_update_undo_to_history(
/*=================================*/
- trx_t* trx, /* in: transaction */
- page_t* undo_page, /* in: update undo log header page,
+ trx_t* trx, /*!< in: transaction */
+ page_t* undo_page, /*!< in: update undo log header page,
x-latched */
- mtr_t* mtr); /* in: mtr */
-/************************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/********************************************************************//**
Fetches the next undo log record from the history list to purge. It must be
-released with the corresponding release function. */
+released with the corresponding release function.
+@return copy of an undo log record or pointer to trx_purge_dummy_rec,
+if the whole undo log can skipped in purge; NULL if none left */
UNIV_INTERN
trx_undo_rec_t*
trx_purge_fetch_next_rec(
/*=====================*/
- /* out: copy of an undo log record, or
- pointer to the dummy undo log record
- &trx_purge_dummy_rec if the whole undo log
- can skipped in purge; NULL if none left */
- dulint* roll_ptr,/* out: roll pointer to undo record */
- trx_undo_inf_t** cell, /* out: storage cell for the record in the
+ roll_ptr_t* roll_ptr,/*!< out: roll pointer to undo record */
+ trx_undo_inf_t** cell, /*!< out: storage cell for the record in the
purge array */
- mem_heap_t* heap); /* in: memory heap where copied */
-/***********************************************************************
+ mem_heap_t* heap); /*!< in: memory heap where copied */
+/*******************************************************************//**
Releases a reserved purge undo record. */
UNIV_INTERN
void
trx_purge_rec_release(
/*==================*/
- trx_undo_inf_t* cell); /* in: storage cell */
-/***********************************************************************
-This function runs a purge batch. */
+ trx_undo_inf_t* cell); /*!< in: storage cell */
+/*******************************************************************//**
+This function runs a purge batch.
+@return number of undo log pages handled in the batch */
UNIV_INTERN
ulint
trx_purge(void);
/*===========*/
- /* out: number of undo log pages handled in
- the batch */
-/**********************************************************************
+/******************************************************************//**
Prints information of the purge system to stderr. */
UNIV_INTERN
void
trx_purge_sys_print(void);
/*======================*/
-/* The control structure used in the purge operation */
+/** The control structure used in the purge operation */
struct trx_purge_struct{
- ulint state; /* Purge system state */
- sess_t* sess; /* System session running the purge
+ ulint state; /*!< Purge system state */
+ sess_t* sess; /*!< System session running the purge
query */
- trx_t* trx; /* System transaction running the purge
+ trx_t* trx; /*!< System transaction running the purge
query: this trx is not in the trx list
of the trx system and it never ends */
- que_t* query; /* The query graph which will do the
+ que_t* query; /*!< The query graph which will do the
parallelized purge operation */
- rw_lock_t latch; /* The latch protecting the purge view.
+ rw_lock_t latch; /*!< The latch protecting the purge view.
A purge operation must acquire an
x-latch here for the instant at which
it changes the purge view: an undo
log operation can prevent this by
obtaining an s-latch here. */
- read_view_t* view; /* The purge will not remove undo logs
+ read_view_t* view; /*!< The purge will not remove undo logs
which are >= this view (purge view) */
- mutex_t mutex; /* Mutex protecting the fields below */
- ulint n_pages_handled;/* Approximate number of undo log
+ mutex_t mutex; /*!< Mutex protecting the fields below */
+ ulint n_pages_handled;/*!< Approximate number of undo log
pages processed in purge */
- ulint handle_limit; /* Target of how many pages to get
+ ulint handle_limit; /*!< Target of how many pages to get
processed in the current purge */
/*------------------------------*/
/* The following two fields form the 'purge pointer' which advances
during a purge, and which is used in history list truncation */
- dulint purge_trx_no; /* Purge has advanced past all
+ trx_id_t purge_trx_no; /*!< Purge has advanced past all
transactions whose number is less
than this */
- dulint purge_undo_no; /* Purge has advanced past all records
+ undo_no_t purge_undo_no; /*!< Purge has advanced past all records
whose undo number is less than this */
/*-----------------------------*/
- ibool next_stored; /* TRUE if the info of the next record
+ ibool next_stored; /*!< TRUE if the info of the next record
to purge is stored below: if yes, then
the transaction number and the undo
number of the record are stored in
purge_trx_no and purge_undo_no above */
- trx_rseg_t* rseg; /* Rollback segment for the next undo
+ trx_rseg_t* rseg; /*!< Rollback segment for the next undo
record to purge */
- ulint page_no; /* Page number for the next undo
+ ulint page_no; /*!< Page number for the next undo
record to purge, page number of the
log header, if dummy record */
- ulint offset; /* Page offset for the next undo
+ ulint offset; /*!< Page offset for the next undo
record to purge, 0 if the dummy
record */
- ulint hdr_page_no; /* Header page of the undo log where
+ ulint hdr_page_no; /*!< Header page of the undo log where
the next record to purge belongs */
- ulint hdr_offset; /* Header byte offset on the page */
+ ulint hdr_offset; /*!< Header byte offset on the page */
/*-----------------------------*/
- trx_undo_arr_t* arr; /* Array of transaction numbers and
+ trx_undo_arr_t* arr; /*!< Array of transaction numbers and
undo numbers of the undo records
currently under processing in purge */
- mem_heap_t* heap; /* Temporary storage used during a
+ mem_heap_t* heap; /*!< Temporary storage used during a
purge: can be emptied after purge
completes */
};
diff --git a/storage/xtradb/include/trx0purge.ic b/storage/xtradb/include/trx0purge.ic
index 2c1d2ac75af..de09e393654 100644
--- a/storage/xtradb/include/trx0purge.ic
+++ b/storage/xtradb/include/trx0purge.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0purge.ic
Purge old versions
Created 3/26/1996 Heikki Tuuri
@@ -24,15 +25,15 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0undo.h"
-/************************************************************************
+/********************************************************************//**
Calculates the file address of an undo log header when we have the file
-address of its history list node. */
+address of its history list node.
+@return file address of the log */
UNIV_INLINE
fil_addr_t
trx_purge_get_log_from_hist(
/*========================*/
- /* out: file address of the log */
- fil_addr_t node_addr) /* in: file address of the history
+ fil_addr_t node_addr) /*!< in: file address of the history
list node of the log */
{
node_addr.boffset -= TRX_UNDO_HISTORY_NODE;
diff --git a/storage/xtradb/include/trx0rec.h b/storage/xtradb/include/trx0rec.h
index 444d39e39db..0ae82c33afe 100644
--- a/storage/xtradb/include/trx0rec.h
+++ b/storage/xtradb/include/trx0rec.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0rec.h
Transaction undo log record
Created 3/26/1996 Heikki Tuuri
@@ -30,278 +31,280 @@ Created 3/26/1996 Heikki Tuuri
#include "row0types.h"
#include "mtr0mtr.h"
#include "dict0types.h"
-#include "que0types.h"
#include "data0data.h"
#include "rem0types.h"
-/***************************************************************************
-Copies the undo record to the heap. */
+#ifndef UNIV_HOTBACKUP
+# include "que0types.h"
+
+/***********************************************************************//**
+Copies the undo record to the heap.
+@return own: copy of undo log record */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_rec_copy(
/*==============*/
- /* out, own: copy of undo log record */
- trx_undo_rec_t* undo_rec, /* in: undo log record */
- mem_heap_t* heap); /* in: heap where copied */
-/**************************************************************************
-Reads the undo log record type. */
+ trx_undo_rec_t* undo_rec, /*!< in: undo log record */
+ mem_heap_t* heap); /*!< in: heap where copied */
+/**********************************************************************//**
+Reads the undo log record type.
+@return record type */
UNIV_INLINE
ulint
trx_undo_rec_get_type(
/*==================*/
- /* out: record type */
- trx_undo_rec_t* undo_rec); /* in: undo log record */
-/**************************************************************************
-Reads from an undo log record the record compiler info. */
+ const trx_undo_rec_t* undo_rec); /*!< in: undo log record */
+/**********************************************************************//**
+Reads from an undo log record the record compiler info.
+@return compiler info */
UNIV_INLINE
ulint
trx_undo_rec_get_cmpl_info(
/*=======================*/
- /* out: compiler info */
- trx_undo_rec_t* undo_rec); /* in: undo log record */
-/**************************************************************************
-Returns TRUE if an undo log record contains an extern storage field. */
+ const trx_undo_rec_t* undo_rec); /*!< in: undo log record */
+/**********************************************************************//**
+Returns TRUE if an undo log record contains an extern storage field.
+@return TRUE if extern */
UNIV_INLINE
ibool
trx_undo_rec_get_extern_storage(
/*============================*/
- /* out: TRUE if extern */
- trx_undo_rec_t* undo_rec); /* in: undo log record */
-/**************************************************************************
-Reads the undo log record number. */
+ const trx_undo_rec_t* undo_rec); /*!< in: undo log record */
+/**********************************************************************//**
+Reads the undo log record number.
+@return undo no */
UNIV_INLINE
-dulint
+undo_no_t
trx_undo_rec_get_undo_no(
/*=====================*/
- /* out: undo no */
- trx_undo_rec_t* undo_rec); /* in: undo log record */
-/**************************************************************************
- * Returns the start of the undo record data area. */
-
+ const trx_undo_rec_t* undo_rec); /*!< in: undo log record */
+/**********************************************************************//**
+Returns the start of the undo record data area.
+@return offset to the data area */
UNIV_INLINE
-byte*
-trx_undo_rec_get_ptr(
-/*==================*/
- /* out: compiler info */
- trx_undo_rec_t* undo_rec, /* in: undo log record */
- dulint undo_no); /* in: undo no read from node */
+ulint
+trx_undo_rec_get_offset(
+/*====================*/
+ undo_no_t undo_no) /*!< in: undo no read from node */
+ __attribute__((const));
+
+/**********************************************************************//**
+Returns the start of the undo record data area. */
+#define trx_undo_rec_get_ptr(undo_rec, undo_no) \
+ ((undo_rec) + trx_undo_rec_get_offset(undo_no))
-/**************************************************************************
-Reads from an undo log record the general parameters. */
+/**********************************************************************//**
+Reads from an undo log record the general parameters.
+@return remaining part of undo log record after reading these values */
UNIV_INTERN
byte*
trx_undo_rec_get_pars(
/*==================*/
- /* out: remaining part of undo log
- record after reading these values */
- trx_undo_rec_t* undo_rec, /* in: undo log record */
- ulint* type, /* out: undo record type:
+ trx_undo_rec_t* undo_rec, /*!< in: undo log record */
+ ulint* type, /*!< out: undo record type:
TRX_UNDO_INSERT_REC, ... */
- ulint* cmpl_info, /* out: compiler info, relevant only
+ ulint* cmpl_info, /*!< out: compiler info, relevant only
for update type records */
- ibool* updated_extern, /* out: TRUE if we updated an
+ ibool* updated_extern, /*!< out: TRUE if we updated an
externally stored fild */
- dulint* undo_no, /* out: undo log record number */
- dulint* table_id); /* out: table id */
-/***********************************************************************
-Builds a row reference from an undo log record. */
+ undo_no_t* undo_no, /*!< out: undo log record number */
+ dulint* table_id); /*!< out: table id */
+/*******************************************************************//**
+Builds a row reference from an undo log record.
+@return pointer to remaining part of undo record */
UNIV_INTERN
byte*
trx_undo_rec_get_row_ref(
/*=====================*/
- /* out: pointer to remaining part of undo
- record */
- byte* ptr, /* in: remaining part of a copy of an undo log
+ byte* ptr, /*!< in: remaining part of a copy of an undo log
record, at the start of the row reference;
NOTE that this copy of the undo log record must
be preserved as long as the row reference is
used, as we do NOT copy the data in the
record! */
- dict_index_t* index, /* in: clustered index */
- dtuple_t** ref, /* out, own: row reference */
- mem_heap_t* heap); /* in: memory heap from which the memory
+ dict_index_t* index, /*!< in: clustered index */
+ dtuple_t** ref, /*!< out, own: row reference */
+ mem_heap_t* heap); /*!< in: memory heap from which the memory
needed is allocated */
-/***********************************************************************
-Skips a row reference from an undo log record. */
+/*******************************************************************//**
+Skips a row reference from an undo log record.
+@return pointer to remaining part of undo record */
UNIV_INTERN
byte*
trx_undo_rec_skip_row_ref(
/*======================*/
- /* out: pointer to remaining part of undo
- record */
- byte* ptr, /* in: remaining part in update undo log
+ byte* ptr, /*!< in: remaining part in update undo log
record, at the start of the row reference */
- dict_index_t* index); /* in: clustered index */
-/**************************************************************************
+ dict_index_t* index); /*!< in: clustered index */
+/**********************************************************************//**
Reads from an undo log update record the system field values of the old
-version. */
+version.
+@return remaining part of undo log record after reading these values */
UNIV_INTERN
byte*
trx_undo_update_rec_get_sys_cols(
/*=============================*/
- /* out: remaining part of undo log
- record after reading these values */
- byte* ptr, /* in: remaining part of undo log
- record after reading general
- parameters */
- dulint* trx_id, /* out: trx id */
- dulint* roll_ptr, /* out: roll ptr */
- ulint* info_bits); /* out: info bits state */
-/***********************************************************************
-Builds an update vector based on a remaining part of an undo log record. */
+ byte* ptr, /*!< in: remaining part of undo
+ log record after reading
+ general parameters */
+ trx_id_t* trx_id, /*!< out: trx id */
+ roll_ptr_t* roll_ptr, /*!< out: roll ptr */
+ ulint* info_bits); /*!< out: info bits state */
+/*******************************************************************//**
+Builds an update vector based on a remaining part of an undo log record.
+@return remaining part of the record, NULL if an error detected, which
+means that the record is corrupted */
UNIV_INTERN
byte*
trx_undo_update_rec_get_update(
/*===========================*/
- /* out: remaining part of the record,
- NULL if an error detected, which means that
- the record is corrupted */
- byte* ptr, /* in: remaining part in update undo log
+ byte* ptr, /*!< in: remaining part in update undo log
record, after reading the row reference
NOTE that this copy of the undo log record must
be preserved as long as the update vector is
used, as we do NOT copy the data in the
record! */
- dict_index_t* index, /* in: clustered index */
- ulint type, /* in: TRX_UNDO_UPD_EXIST_REC,
+ dict_index_t* index, /*!< in: clustered index */
+ ulint type, /*!< in: TRX_UNDO_UPD_EXIST_REC,
TRX_UNDO_UPD_DEL_REC, or
TRX_UNDO_DEL_MARK_REC; in the last case,
only trx id and roll ptr fields are added to
the update vector */
- dulint trx_id, /* in: transaction id from this undorecord */
- dulint roll_ptr,/* in: roll pointer from this undo record */
- ulint info_bits,/* in: info bits from this undo record */
- trx_t* trx, /* in: transaction */
- mem_heap_t* heap, /* in: memory heap from which the memory
+ trx_id_t trx_id, /*!< in: transaction id from this undorecord */
+ roll_ptr_t roll_ptr,/*!< in: roll pointer from this undo record */
+ ulint info_bits,/*!< in: info bits from this undo record */
+ trx_t* trx, /*!< in: transaction */
+ mem_heap_t* heap, /*!< in: memory heap from which the memory
needed is allocated */
- upd_t** upd); /* out, own: update vector */
-/***********************************************************************
+ upd_t** upd); /*!< out, own: update vector */
+/*******************************************************************//**
Builds a partial row from an update undo log record. It contains the
-columns which occur as ordering in any index of the table. */
+columns which occur as ordering in any index of the table.
+@return pointer to remaining part of undo record */
UNIV_INTERN
byte*
trx_undo_rec_get_partial_row(
/*=========================*/
- /* out: pointer to remaining part of undo
- record */
- byte* ptr, /* in: remaining part in update undo log
+ byte* ptr, /*!< in: remaining part in update undo log
record of a suitable type, at the start of
the stored index columns;
NOTE that this copy of the undo log record must
be preserved as long as the partial row is
used, as we do NOT copy the data in the
record! */
- dict_index_t* index, /* in: clustered index */
- dtuple_t** row, /* out, own: partial row */
- ibool ignore_prefix, /* in: flag to indicate if we
+ dict_index_t* index, /*!< in: clustered index */
+ dtuple_t** row, /*!< out, own: partial row */
+ ibool ignore_prefix, /*!< in: flag to indicate if we
expect blob prefixes in undo. Used
only in the assertion. */
- mem_heap_t* heap); /* in: memory heap from which the memory
+ mem_heap_t* heap); /*!< in: memory heap from which the memory
needed is allocated */
-/***************************************************************************
+/***********************************************************************//**
Writes information to an undo log about an insert, update, or a delete marking
of a clustered index record. This information is used in a rollback of the
transaction and in consistent reads that must look to the history of this
-transaction. */
+transaction.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
trx_undo_report_row_operation(
/*==========================*/
- /* out: DB_SUCCESS or error code */
- ulint flags, /* in: if BTR_NO_UNDO_LOG_FLAG bit is
+ ulint flags, /*!< in: if BTR_NO_UNDO_LOG_FLAG bit is
set, does nothing */
- ulint op_type, /* in: TRX_UNDO_INSERT_OP or
+ ulint op_type, /*!< in: TRX_UNDO_INSERT_OP or
TRX_UNDO_MODIFY_OP */
- que_thr_t* thr, /* in: query thread */
- dict_index_t* index, /* in: clustered index */
- const dtuple_t* clust_entry, /* in: in the case of an insert,
+ que_thr_t* thr, /*!< in: query thread */
+ dict_index_t* index, /*!< in: clustered index */
+ const dtuple_t* clust_entry, /*!< in: in the case of an insert,
index entry to insert into the
clustered index, otherwise NULL */
- const upd_t* update, /* in: in the case of an update,
+ const upd_t* update, /*!< in: in the case of an update,
the update vector, otherwise NULL */
- ulint cmpl_info, /* in: compiler info on secondary
+ ulint cmpl_info, /*!< in: compiler info on secondary
index updates */
- const rec_t* rec, /* in: case of an update or delete
+ const rec_t* rec, /*!< in: case of an update or delete
marking, the record in the clustered
index, otherwise NULL */
- dulint* roll_ptr); /* out: rollback pointer to the
+ roll_ptr_t* roll_ptr); /*!< out: rollback pointer to the
inserted undo log record,
ut_dulint_zero if BTR_NO_UNDO_LOG
flag was specified */
-/**********************************************************************
+/******************************************************************//**
Copies an undo record to heap. This function can be called if we know that
-the undo log record exists. */
+the undo log record exists.
+@return own: copy of the record */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_undo_rec_low(
/*======================*/
- /* out, own: copy of the record */
- dulint roll_ptr, /* in: roll pointer to record */
- mem_heap_t* heap); /* in: memory heap where copied */
-/**********************************************************************
-Copies an undo record to heap. */
+ roll_ptr_t roll_ptr, /*!< in: roll pointer to record */
+ mem_heap_t* heap); /*!< in: memory heap where copied */
+/******************************************************************//**
+Copies an undo record to heap.
+
+NOTE: the caller must have latches on the clustered index page and
+purge_view.
+
+@return DB_SUCCESS, or DB_MISSING_HISTORY if the undo log has been
+truncated and we cannot fetch the old version */
UNIV_INTERN
ulint
trx_undo_get_undo_rec(
/*==================*/
- /* out: DB_SUCCESS, or
- DB_MISSING_HISTORY if the undo log
- has been truncated and we cannot
- fetch the old version; NOTE: the
- caller must have latches on the
- clustered index page and purge_view */
- dulint roll_ptr, /* in: roll pointer to record */
- dulint trx_id, /* in: id of the trx that generated
+ roll_ptr_t roll_ptr, /*!< in: roll pointer to record */
+ trx_id_t trx_id, /*!< in: id of the trx that generated
the roll pointer: it points to an
undo log of this transaction */
- trx_undo_rec_t** undo_rec, /* out, own: copy of the record */
- mem_heap_t* heap); /* in: memory heap where copied */
-/***********************************************************************
+ trx_undo_rec_t** undo_rec, /*!< out, own: copy of the record */
+ mem_heap_t* heap); /*!< in: memory heap where copied */
+/*******************************************************************//**
Build a previous version of a clustered index record. This function checks
that the caller has a latch on the index page of the clustered index record
and an s-latch on the purge_view. This guarantees that the stack of versions
-is locked. */
+is locked.
+@return DB_SUCCESS, or DB_MISSING_HISTORY if the previous version is
+earlier than purge_view, which means that it may have been removed,
+DB_ERROR if corrupted record */
UNIV_INTERN
ulint
trx_undo_prev_version_build(
/*========================*/
- /* out: DB_SUCCESS, or DB_MISSING_HISTORY if
- the previous version is not >= purge_view,
- which means that it may have been removed,
- DB_ERROR if corrupted record */
- const rec_t* index_rec,/* in: clustered index record in the
+ const rec_t* index_rec,/*!< in: clustered index record in the
index tree */
- mtr_t* index_mtr,/* in: mtr which contains the latch to
+ mtr_t* index_mtr,/*!< in: mtr which contains the latch to
index_rec page and purge_view */
- const rec_t* rec, /* in: version of a clustered index record */
- dict_index_t* index, /* in: clustered index */
- ulint* offsets,/* in: rec_get_offsets(rec, index) */
- mem_heap_t* heap, /* in: memory heap from which the memory
+ const rec_t* rec, /*!< in: version of a clustered index record */
+ dict_index_t* index, /*!< in: clustered index */
+ ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ mem_heap_t* heap, /*!< in: memory heap from which the memory
needed is allocated */
- rec_t** old_vers);/* out, own: previous version, or NULL if
+ rec_t** old_vers);/*!< out, own: previous version, or NULL if
rec is the first inserted version, or if
history data has been deleted */
-/***************************************************************
-Parses a redo log record of adding an undo log record. */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************//**
+Parses a redo log record of adding an undo log record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_add_undo_rec(
/*========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page); /* in: page or NULL */
-/***************************************************************
-Parses a redo log record of erasing of an undo page end. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page); /*!< in: page or NULL */
+/***********************************************************//**
+Parses a redo log record of erasing of an undo page end.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_erase_page_end(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+
+#ifndef UNIV_HOTBACKUP
/* Types of an undo log record: these have to be smaller than 16, as the
compilation info multiplied by 16 is ORed to this value in an undo log
@@ -330,4 +333,6 @@ record */
#include "trx0rec.ic"
#endif
-#endif
+#endif /* !UNIV_HOTBACKUP */
+
+#endif /* trx0rec_h */
diff --git a/storage/xtradb/include/trx0rec.ic b/storage/xtradb/include/trx0rec.ic
index bfd74eb9dfb..037b5d4f6cf 100644
--- a/storage/xtradb/include/trx0rec.ic
+++ b/storage/xtradb/include/trx0rec.ic
@@ -16,44 +16,46 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0rec.ic
Transaction undo log record
Created 3/26/1996 Heikki Tuuri
*******************************************************/
-/**************************************************************************
-Reads from an undo log record the record type. */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
+Reads from an undo log record the record type.
+@return record type */
UNIV_INLINE
ulint
trx_undo_rec_get_type(
/*==================*/
- /* out: record type */
- trx_undo_rec_t* undo_rec) /* in: undo log record */
+ const trx_undo_rec_t* undo_rec) /*!< in: undo log record */
{
return(mach_read_from_1(undo_rec + 2) & (TRX_UNDO_CMPL_INFO_MULT - 1));
}
-/**************************************************************************
-Reads from an undo log record the record compiler info. */
+/**********************************************************************//**
+Reads from an undo log record the record compiler info.
+@return compiler info */
UNIV_INLINE
ulint
trx_undo_rec_get_cmpl_info(
/*=======================*/
- /* out: compiler info */
- trx_undo_rec_t* undo_rec) /* in: undo log record */
+ const trx_undo_rec_t* undo_rec) /*!< in: undo log record */
{
return(mach_read_from_1(undo_rec + 2) / TRX_UNDO_CMPL_INFO_MULT);
}
-/**************************************************************************
-Returns TRUE if an undo log record contains an extern storage field. */
+/**********************************************************************//**
+Returns TRUE if an undo log record contains an extern storage field.
+@return TRUE if extern */
UNIV_INLINE
ibool
trx_undo_rec_get_extern_storage(
/*============================*/
- /* out: TRUE if extern */
- trx_undo_rec_t* undo_rec) /* in: undo log record */
+ const trx_undo_rec_t* undo_rec) /*!< in: undo log record */
{
if (mach_read_from_1(undo_rec + 2) & TRX_UNDO_UPD_EXTERN) {
@@ -63,54 +65,48 @@ trx_undo_rec_get_extern_storage(
return(FALSE);
}
-/**************************************************************************
-Reads the undo log record number. */
+/**********************************************************************//**
+Reads the undo log record number.
+@return undo no */
UNIV_INLINE
-dulint
+undo_no_t
trx_undo_rec_get_undo_no(
/*=====================*/
- /* out: undo no */
- trx_undo_rec_t* undo_rec) /* in: undo log record */
+ const trx_undo_rec_t* undo_rec) /*!< in: undo log record */
{
- byte* ptr;
+ const byte* ptr;
ptr = undo_rec + 3;
return(mach_dulint_read_much_compressed(ptr));
}
-/**************************************************************************
-Returns the start of the undo record data area. */
+/**********************************************************************//**
+Returns the start of the undo record data area.
+@return offset to the data area */
UNIV_INLINE
-byte*
-trx_undo_rec_get_ptr(
-/*=================*/
- /* out: compiler info */
- trx_undo_rec_t* undo_rec, /* in: undo log record */
- dulint undo_no) /* in: undo no read from node */
+ulint
+trx_undo_rec_get_offset(
+/*====================*/
+ undo_no_t undo_no) /*!< in: undo no read from node */
{
- return (((byte*) undo_rec) + 3
- + mach_dulint_get_much_compressed_size(undo_no));
+ return (3 + mach_dulint_get_much_compressed_size(undo_no));
}
-/***************************************************************************
-Copies the undo record to the heap. */
+/***********************************************************************//**
+Copies the undo record to the heap.
+@return own: copy of undo log record */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_rec_copy(
/*==============*/
- /* out, own: copy of undo log record */
- trx_undo_rec_t* undo_rec, /* in: undo log record */
- mem_heap_t* heap) /* in: heap where copied */
+ trx_undo_rec_t* undo_rec, /*!< in: undo log record */
+ mem_heap_t* heap) /*!< in: heap where copied */
{
ulint len;
- trx_undo_rec_t* rec_copy;
len = mach_read_from_2(undo_rec)
- ut_align_offset(undo_rec, UNIV_PAGE_SIZE);
- rec_copy = mem_heap_alloc(heap, len);
-
- ut_memcpy(rec_copy, undo_rec, len);
-
- return(rec_copy);
+ return(mem_heap_dup(heap, undo_rec, len));
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/trx0roll.h b/storage/xtradb/include/trx0roll.h
index 3318a5985d7..ddca9e9e4ef 100644
--- a/storage/xtradb/include/trx0roll.h
+++ b/storage/xtradb/include/trx0roll.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0roll.h
Transaction rollback
Created 3/26/1996 Heikki Tuuri
@@ -33,306 +34,306 @@ Created 3/26/1996 Heikki Tuuri
#define trx_roll_free_all_savepoints(s) trx_roll_savepoints_free((s), NULL)
-/***********************************************************************
+/*******************************************************************//**
Determines if this transaction is rolling back an incomplete transaction
-in crash recovery. */
+in crash recovery.
+@return TRUE if trx is an incomplete transaction that is being rolled
+back in crash recovery */
UNIV_INTERN
ibool
trx_is_recv(
/*========*/
- /* out: TRUE if trx is an incomplete
- transaction that is being rolled back
- in crash recovery */
- const trx_t* trx); /* in: transaction */
-/***********************************************************************
-Returns a transaction savepoint taken at this point in time. */
+ const trx_t* trx); /*!< in: transaction */
+/*******************************************************************//**
+Returns a transaction savepoint taken at this point in time.
+@return savepoint */
UNIV_INTERN
trx_savept_t
trx_savept_take(
/*============*/
- /* out: savepoint */
- trx_t* trx); /* in: transaction */
-/***********************************************************************
+ trx_t* trx); /*!< in: transaction */
+/*******************************************************************//**
Creates an undo number array. */
UNIV_INTERN
trx_undo_arr_t*
trx_undo_arr_create(void);
/*=====================*/
-/***********************************************************************
+/*******************************************************************//**
Frees an undo number array. */
UNIV_INTERN
void
trx_undo_arr_free(
/*==============*/
- trx_undo_arr_t* arr); /* in: undo number array */
-/***********************************************************************
-Returns pointer to nth element in an undo number array. */
+ trx_undo_arr_t* arr); /*!< in: undo number array */
+/*******************************************************************//**
+Returns pointer to nth element in an undo number array.
+@return pointer to the nth element */
UNIV_INLINE
trx_undo_inf_t*
trx_undo_arr_get_nth_info(
/*======================*/
- /* out: pointer to the nth element */
- trx_undo_arr_t* arr, /* in: undo number array */
- ulint n); /* in: position */
-/***************************************************************************
+ trx_undo_arr_t* arr, /*!< in: undo number array */
+ ulint n); /*!< in: position */
+/***********************************************************************//**
Tries truncate the undo logs. */
UNIV_INTERN
void
trx_roll_try_truncate(
/*==================*/
- trx_t* trx); /* in: transaction */
-/************************************************************************
+ trx_t* trx); /*!< in/out: transaction */
+/********************************************************************//**
Pops the topmost record when the two undo logs of a transaction are seen
as a single stack of records ordered by their undo numbers. Inserts the
undo number of the popped undo record to the array of currently processed
undo numbers in the transaction. When the query thread finishes processing
-of this undo record, it must be released with trx_undo_rec_release. */
+of this undo record, it must be released with trx_undo_rec_release.
+@return undo log record copied to heap, NULL if none left, or if the
+undo number of the top record would be less than the limit */
UNIV_INTERN
trx_undo_rec_t*
trx_roll_pop_top_rec_of_trx(
/*========================*/
- /* out: undo log record copied to heap, NULL
- if none left, or if the undo number of the
- top record would be less than the limit */
- trx_t* trx, /* in: transaction */
- dulint limit, /* in: least undo number we need */
- dulint* roll_ptr,/* out: roll pointer to undo record */
- mem_heap_t* heap); /* in: memory heap where copied */
-/************************************************************************
+ trx_t* trx, /*!< in: transaction */
+ undo_no_t limit, /*!< in: least undo number we need */
+ roll_ptr_t* roll_ptr,/*!< out: roll pointer to undo record */
+ mem_heap_t* heap); /*!< in: memory heap where copied */
+/********************************************************************//**
Reserves an undo log record for a query thread to undo. This should be
called if the query thread gets the undo log record not using the pop
-function above. */
+function above.
+@return TRUE if succeeded */
UNIV_INTERN
ibool
trx_undo_rec_reserve(
/*=================*/
- /* out: TRUE if succeeded */
- trx_t* trx, /* in: transaction */
- dulint undo_no);/* in: undo number of the record */
-/***********************************************************************
+ trx_t* trx, /*!< in/out: transaction */
+ undo_no_t undo_no);/*!< in: undo number of the record */
+/*******************************************************************//**
Releases a reserved undo record. */
UNIV_INTERN
void
trx_undo_rec_release(
/*=================*/
- trx_t* trx, /* in: transaction */
- dulint undo_no);/* in: undo number */
-/*************************************************************************
+ trx_t* trx, /*!< in/out: transaction */
+ undo_no_t undo_no);/*!< in: undo number */
+/*********************************************************************//**
Starts a rollback operation. */
UNIV_INTERN
void
trx_rollback(
/*=========*/
- trx_t* trx, /* in: transaction */
- trx_sig_t* sig, /* in: signal starting the rollback */
- que_thr_t** next_thr);/* in/out: next query thread to run;
+ trx_t* trx, /*!< in: transaction */
+ trx_sig_t* sig, /*!< in: signal starting the rollback */
+ que_thr_t** next_thr);/*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
a new query thread */
-/***********************************************************************
+/*******************************************************************//**
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
committed, then we clean up a possible insert undo log. If the
transaction was not yet committed, then we roll it back.
-Note: this is done in a background thread. */
+Note: this is done in a background thread.
+@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
trx_rollback_or_clean_all_recovered(
/*================================*/
- /* out: a dummy parameter */
void* arg __attribute__((unused)));
- /* in: a dummy parameter required by
+ /*!< in: a dummy parameter required by
os_thread_create */
-/********************************************************************
+/****************************************************************//**
Finishes a transaction rollback. */
UNIV_INTERN
void
trx_finish_rollback_off_kernel(
/*===========================*/
- que_t* graph, /* in: undo graph which can now be freed */
- trx_t* trx, /* in: transaction */
- que_thr_t** next_thr);/* in/out: next query thread to run;
+ que_t* graph, /*!< in: undo graph which can now be freed */
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t** next_thr);/*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
a new query thread; if this parameter is
NULL, it is ignored */
-/********************************************************************
+/****************************************************************//**
Builds an undo 'query' graph for a transaction. The actual rollback is
performed by executing this query graph like a query subprocedure call.
The reply about the completion of the rollback will be sent by this
-graph. */
+graph.
+@return own: the query graph */
UNIV_INTERN
que_t*
trx_roll_graph_build(
/*=================*/
- /* out, own: the query graph */
- trx_t* trx); /* in: trx handle */
-/*************************************************************************
-Creates a rollback command node struct. */
+ trx_t* trx); /*!< in: trx handle */
+/*********************************************************************//**
+Creates a rollback command node struct.
+@return own: rollback node struct */
UNIV_INTERN
roll_node_t*
roll_node_create(
/*=============*/
- /* out, own: rollback node struct */
- mem_heap_t* heap); /* in: mem heap where created */
-/***************************************************************
-Performs an execution step for a rollback command node in a query graph. */
+ mem_heap_t* heap); /*!< in: mem heap where created */
+/***********************************************************//**
+Performs an execution step for a rollback command node in a query graph.
+@return query thread to run next, or NULL */
UNIV_INTERN
que_thr_t*
trx_rollback_step(
/*==============*/
- /* out: query thread to run next, or NULL */
- que_thr_t* thr); /* in: query thread */
-/***********************************************************************
-Rollback a transaction used in MySQL. */
+ que_thr_t* thr); /*!< in: query thread */
+/*******************************************************************//**
+Rollback a transaction used in MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
trx_rollback_for_mysql(
/*===================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx); /* in: transaction handle */
-/***********************************************************************
-Rollback the latest SQL statement for MySQL. */
+ trx_t* trx); /*!< in: transaction handle */
+/*******************************************************************//**
+Rollback the latest SQL statement for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
trx_rollback_last_sql_stat_for_mysql(
/*=================================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx); /* in: transaction handle */
-/***********************************************************************
-Rollback a transaction used in MySQL. */
+ trx_t* trx); /*!< in: transaction handle */
+/*******************************************************************//**
+Rollback a transaction used in MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
trx_general_rollback_for_mysql(
/*===========================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- ibool partial,/* in: TRUE if partial rollback requested */
- trx_savept_t* savept);/* in: pointer to savepoint undo number, if
+ trx_t* trx, /*!< in: transaction handle */
+ ibool partial,/*!< in: TRUE if partial rollback requested */
+ trx_savept_t* savept);/*!< in: pointer to savepoint undo number, if
partial rollback requested */
-/***********************************************************************
+/*******************************************************************//**
Rolls back a transaction back to a named savepoint. Modifications after the
savepoint are undone but InnoDB does NOT release the corresponding locks
which are stored in memory. If a lock is 'implicit', that is, a new inserted
row holds a lock where the lock information is carried by the trx id stored in
the row, these locks are naturally released in the rollback. Savepoints which
-were set after this savepoint are deleted. */
+were set after this savepoint are deleted.
+@return if no savepoint of the name found then DB_NO_SAVEPOINT,
+otherwise DB_SUCCESS */
UNIV_INTERN
ulint
trx_rollback_to_savepoint_for_mysql(
/*================================*/
- /* out: if no savepoint
- of the name found then
- DB_NO_SAVEPOINT,
- otherwise DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- const char* savepoint_name, /* in: savepoint name */
- ib_int64_t* mysql_binlog_cache_pos);/* out: the MySQL binlog cache
+ trx_t* trx, /*!< in: transaction handle */
+ const char* savepoint_name, /*!< in: savepoint name */
+ ib_int64_t* mysql_binlog_cache_pos);/*!< out: the MySQL binlog cache
position corresponding to this
savepoint; MySQL needs this
information to remove the
binlog entries of the queries
executed after the savepoint */
-/***********************************************************************
+/*******************************************************************//**
Creates a named savepoint. If the transaction is not yet started, starts it.
If there is already a savepoint of the same name, this call erases that old
savepoint and replaces it with a new. Savepoints are deleted in a transaction
-commit or rollback. */
+commit or rollback.
+@return always DB_SUCCESS */
UNIV_INTERN
ulint
trx_savepoint_for_mysql(
/*====================*/
- /* out: always DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- const char* savepoint_name, /* in: savepoint name */
- ib_int64_t binlog_cache_pos); /* in: MySQL binlog cache
+ trx_t* trx, /*!< in: transaction handle */
+ const char* savepoint_name, /*!< in: savepoint name */
+ ib_int64_t binlog_cache_pos); /*!< in: MySQL binlog cache
position corresponding to this
connection at the time of the
savepoint */
-/***********************************************************************
+/*******************************************************************//**
Releases a named savepoint. Savepoints which
-were set after this savepoint are deleted. */
+were set after this savepoint are deleted.
+@return if no savepoint of the name found then DB_NO_SAVEPOINT,
+otherwise DB_SUCCESS */
UNIV_INTERN
ulint
trx_release_savepoint_for_mysql(
/*============================*/
- /* out: if no savepoint
- of the name found then
- DB_NO_SAVEPOINT,
- otherwise DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- const char* savepoint_name); /* in: savepoint name */
+ trx_t* trx, /*!< in: transaction handle */
+ const char* savepoint_name); /*!< in: savepoint name */
-/***********************************************************************
+/*******************************************************************//**
Frees a single savepoint struct. */
UNIV_INTERN
void
trx_roll_savepoint_free(
/*=====================*/
- trx_t* trx, /* in: transaction handle */
- trx_named_savept_t* savep); /* in: savepoint to free */
+ trx_t* trx, /*!< in: transaction handle */
+ trx_named_savept_t* savep); /*!< in: savepoint to free */
-/***********************************************************************
+/*******************************************************************//**
Frees savepoint structs starting from savep, if savep == NULL then
free all savepoints. */
-
+UNIV_INTERN
void
trx_roll_savepoints_free(
/*=====================*/
- trx_t* trx, /* in: transaction handle */
- trx_named_savept_t* savep); /* in: free all savepoints > this one;
+ trx_t* trx, /*!< in: transaction handle */
+ trx_named_savept_t* savep); /*!< in: free all savepoints > this one;
if this is NULL, free all savepoints
of trx */
-/* A cell in the array used during a rollback and a purge */
+/** A cell of trx_undo_arr_struct; used during a rollback and a purge */
struct trx_undo_inf_struct{
- dulint trx_no; /* transaction number: not defined during
+ trx_id_t trx_no; /*!< transaction number: not defined during
a rollback */
- dulint undo_no; /* undo number of an undo record */
- ibool in_use; /* TRUE if the cell is in use */
+ undo_no_t undo_no;/*!< undo number of an undo record */
+ ibool in_use; /*!< TRUE if the cell is in use */
};
-/* During a rollback and a purge, undo numbers of undo records currently being
+/** During a rollback and a purge, undo numbers of undo records currently being
processed are stored in this array */
struct trx_undo_arr_struct{
- ulint n_cells; /* number of cells in the array */
- ulint n_used; /* number of cells currently in use */
- trx_undo_inf_t* infos; /* the array of undo infos */
- mem_heap_t* heap; /* memory heap from which allocated */
+ ulint n_cells; /*!< number of cells in the array */
+ ulint n_used; /*!< number of cells currently in use */
+ trx_undo_inf_t* infos; /*!< the array of undo infos */
+ mem_heap_t* heap; /*!< memory heap from which allocated */
};
-/* Rollback command node in a query graph */
+/** Rollback node states */
+enum roll_node_state {
+ ROLL_NODE_SEND = 1, /*!< about to send a rollback signal to
+ the transaction */
+ ROLL_NODE_WAIT /*!< rollback signal sent to the transaction,
+ waiting for completion */
+};
+
+/** Rollback command node in a query graph */
struct roll_node_struct{
- que_common_t common; /* node type: QUE_NODE_ROLLBACK */
- ulint state; /* node execution state */
- ibool partial;/* TRUE if we want a partial rollback */
- trx_savept_t savept; /* savepoint to which to roll back, in the
- case of a partial rollback */
+ que_common_t common; /*!< node type: QUE_NODE_ROLLBACK */
+ enum roll_node_state state; /*!< node execution state */
+ ibool partial;/*!< TRUE if we want a partial
+ rollback */
+ trx_savept_t savept; /*!< savepoint to which to
+ roll back, in the case of a
+ partial rollback */
};
-/* A savepoint set with SQL's "SAVEPOINT savepoint_id" command */
+/** A savepoint set with SQL's "SAVEPOINT savepoint_id" command */
struct trx_named_savept_struct{
- char* name; /* savepoint name */
- trx_savept_t savept; /* the undo number corresponding to
+ char* name; /*!< savepoint name */
+ trx_savept_t savept; /*!< the undo number corresponding to
the savepoint */
ib_int64_t mysql_binlog_cache_pos;
- /* the MySQL binlog cache position
+ /*!< the MySQL binlog cache position
corresponding to this savepoint, not
defined if the MySQL binlogging is not
enabled */
UT_LIST_NODE_T(trx_named_savept_t)
- trx_savepoints; /* the list of savepoints of a
+ trx_savepoints; /*!< the list of savepoints of a
transaction */
};
-/* Rollback node states */
-#define ROLL_NODE_SEND 1
-#define ROLL_NODE_WAIT 2
-
#ifndef UNIV_NONINL
#include "trx0roll.ic"
#endif
diff --git a/storage/xtradb/include/trx0roll.ic b/storage/xtradb/include/trx0roll.ic
index 513b8b44847..3460832b18c 100644
--- a/storage/xtradb/include/trx0roll.ic
+++ b/storage/xtradb/include/trx0roll.ic
@@ -16,21 +16,22 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0roll.ic
Transaction rollback
Created 3/26/1996 Heikki Tuuri
*******************************************************/
-/***********************************************************************
-Returns pointer to nth element in an undo number array. */
+/*******************************************************************//**
+Returns pointer to nth element in an undo number array.
+@return pointer to the nth element */
UNIV_INLINE
trx_undo_inf_t*
trx_undo_arr_get_nth_info(
/*======================*/
- /* out: pointer to the nth element */
- trx_undo_arr_t* arr, /* in: undo number array */
- ulint n) /* in: position */
+ trx_undo_arr_t* arr, /*!< in: undo number array */
+ ulint n) /*!< in: position */
{
ut_ad(arr);
ut_ad(n < arr->n_cells);
diff --git a/storage/xtradb/include/trx0rseg.h b/storage/xtradb/include/trx0rseg.h
index f3aa736f788..f0f7a47279e 100644
--- a/storage/xtradb/include/trx0rseg.h
+++ b/storage/xtradb/include/trx0rseg.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0rseg.h
Rollback segment
Created 3/26/1996 Heikki Tuuri
@@ -29,106 +30,101 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0types.h"
#include "trx0sys.h"
-/**********************************************************************
-Gets a rollback segment header. */
+/******************************************************************//**
+Gets a rollback segment header.
+@return rollback segment header, page x-latched */
UNIV_INLINE
trx_rsegf_t*
trx_rsegf_get(
/*==========*/
- /* out: rollback segment header, page
- x-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number of the header */
- mtr_t* mtr); /* in: mtr */
-/**********************************************************************
-Gets a newly created rollback segment header. */
+ ulint page_no, /*!< in: page number of the header */
+ mtr_t* mtr); /*!< in: mtr */
+/******************************************************************//**
+Gets a newly created rollback segment header.
+@return rollback segment header, page x-latched */
UNIV_INLINE
trx_rsegf_t*
trx_rsegf_get_new(
/*==============*/
- /* out: rollback segment header, page
- x-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number of the header */
- mtr_t* mtr); /* in: mtr */
-/*******************************************************************
-Gets the file page number of the nth undo log slot. */
+ ulint page_no, /*!< in: page number of the header */
+ mtr_t* mtr); /*!< in: mtr */
+/***************************************************************//**
+Gets the file page number of the nth undo log slot.
+@return page number of the undo log segment */
UNIV_INLINE
ulint
trx_rsegf_get_nth_undo(
/*===================*/
- /* out: page number of the undo log segment */
- trx_rsegf_t* rsegf, /* in: rollback segment header */
- ulint n, /* in: index of slot */
- mtr_t* mtr); /* in: mtr */
-/*******************************************************************
+ trx_rsegf_t* rsegf, /*!< in: rollback segment header */
+ ulint n, /*!< in: index of slot */
+ mtr_t* mtr); /*!< in: mtr */
+/***************************************************************//**
Sets the file page number of the nth undo log slot. */
UNIV_INLINE
void
trx_rsegf_set_nth_undo(
/*===================*/
- trx_rsegf_t* rsegf, /* in: rollback segment header */
- ulint n, /* in: index of slot */
- ulint page_no,/* in: page number of the undo log segment */
- mtr_t* mtr); /* in: mtr */
-/********************************************************************
-Looks for a free slot for an undo log segment. */
+ trx_rsegf_t* rsegf, /*!< in: rollback segment header */
+ ulint n, /*!< in: index of slot */
+ ulint page_no,/*!< in: page number of the undo log segment */
+ mtr_t* mtr); /*!< in: mtr */
+/****************************************************************//**
+Looks for a free slot for an undo log segment.
+@return slot index or ULINT_UNDEFINED if not found */
UNIV_INLINE
ulint
trx_rsegf_undo_find_free(
/*=====================*/
- /* out: slot index or ULINT_UNDEFINED if not
- found */
- trx_rsegf_t* rsegf, /* in: rollback segment header */
- mtr_t* mtr); /* in: mtr */
-/**********************************************************************
-Looks for a rollback segment, based on the rollback segment id. */
+ trx_rsegf_t* rsegf, /*!< in: rollback segment header */
+ mtr_t* mtr); /*!< in: mtr */
+/******************************************************************//**
+Looks for a rollback segment, based on the rollback segment id.
+@return rollback segment */
UNIV_INTERN
trx_rseg_t*
trx_rseg_get_on_id(
/*===============*/
- /* out: rollback segment */
- ulint id); /* in: rollback segment id */
-/********************************************************************
+ ulint id); /*!< in: rollback segment id */
+/****************************************************************//**
Creates a rollback segment header. This function is called only when
-a new rollback segment is created in the database. */
+a new rollback segment is created in the database.
+@return page number of the created segment, FIL_NULL if fail */
UNIV_INTERN
ulint
trx_rseg_header_create(
/*===================*/
- /* out: page number of the created segment,
- FIL_NULL if fail */
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint max_size, /* in: max size in pages */
- ulint* slot_no, /* out: rseg id == slot number in trx sys */
- mtr_t* mtr); /* in: mtr */
-/*************************************************************************
+ ulint max_size, /*!< in: max size in pages */
+ ulint* slot_no, /*!< out: rseg id == slot number in trx sys */
+ mtr_t* mtr); /*!< in: mtr */
+/*********************************************************************//**
Creates the memory copies for rollback segments and initializes the
rseg list and array in trx_sys at a database startup. */
UNIV_INTERN
void
trx_rseg_list_and_array_init(
/*=========================*/
- trx_sysf_t* sys_header, /* in: trx system header */
- mtr_t* mtr); /* in: mtr */
-/********************************************************************
-Creates a new rollback segment to the database. */
+ trx_sysf_t* sys_header, /*!< in: trx system header */
+ mtr_t* mtr); /*!< in: mtr */
+/****************************************************************//**
+Creates a new rollback segment to the database.
+@return the created segment object, NULL if fail */
UNIV_INTERN
trx_rseg_t*
trx_rseg_create(
/*============*/
- /* out: the created segment object, NULL if
- fail */
- ulint space, /* in: space id */
- ulint max_size, /* in: max size in pages */
- ulint* id, /* out: rseg id */
- mtr_t* mtr); /* in: mtr */
+ ulint space, /*!< in: space id */
+ ulint max_size, /*!< in: max size in pages */
+ ulint* id, /*!< out: rseg id */
+ mtr_t* mtr); /*!< in: mtr */
/* Real max value may be 4076 in usual. But reserve 4 slot for safety or etc... */
@@ -143,15 +139,15 @@ trx_rseg_create(
/* The rollback segment memory object */
struct trx_rseg_struct{
/*--------------------------------------------------------*/
- ulint id; /* rollback segment id == the index of
+ ulint id; /*!< rollback segment id == the index of
its slot in the trx system file copy */
- mutex_t mutex; /* mutex protecting the fields in this
+ mutex_t mutex; /*!< mutex protecting the fields in this
struct except id; NOTE that the latching
order must always be kernel mutex ->
rseg mutex */
- ulint space; /* space where the rollback segment is
+ ulint space; /*!< space where the rollback segment is
header is placed */
- ulint zip_size;/* in: compressed page size of space
+ ulint zip_size;/* compressed page size of space
in bytes, or 0 for uncompressed spaces */
ulint page_no;/* page number of the rollback segment
header */
@@ -172,14 +168,14 @@ struct trx_rseg_struct{
/* List of insert undo log segments
cached for fast reuse */
/*--------------------------------------------------------*/
- ulint last_page_no; /* Page number of the last not yet
+ ulint last_page_no; /*!< Page number of the last not yet
purged log header in the history list;
FIL_NULL if all list purged */
- ulint last_offset; /* Byte offset of the last not yet
+ ulint last_offset; /*!< Byte offset of the last not yet
purged log header */
- dulint last_trx_no; /* Transaction number of the last not
+ trx_id_t last_trx_no; /*!< Transaction number of the last not
yet purged log */
- ibool last_del_marks; /* TRUE if the last not yet purged log
+ ibool last_del_marks; /*!< TRUE if the last not yet purged log
needs purging */
/*--------------------------------------------------------*/
UT_LIST_NODE_T(trx_rseg_t) rseg_list;
diff --git a/storage/xtradb/include/trx0rseg.ic b/storage/xtradb/include/trx0rseg.ic
index e665a40fa8b..daffa92fc7d 100644
--- a/storage/xtradb/include/trx0rseg.ic
+++ b/storage/xtradb/include/trx0rseg.ic
@@ -16,27 +16,28 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0rseg.ic
Rollback segment
Created 3/26/1996 Heikki Tuuri
*******************************************************/
#include "srv0srv.h"
+#include "mtr0log.h"
-/**********************************************************************
-Gets a rollback segment header. */
+/******************************************************************//**
+Gets a rollback segment header.
+@return rollback segment header, page x-latched */
UNIV_INLINE
trx_rsegf_t*
trx_rsegf_get(
/*==========*/
- /* out: rollback segment header, page
- x-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number of the header */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number of the header */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
trx_rsegf_t* header;
@@ -49,19 +50,18 @@ trx_rsegf_get(
return(header);
}
-/**********************************************************************
-Gets a newly created rollback segment header. */
+/******************************************************************//**
+Gets a newly created rollback segment header.
+@return rollback segment header, page x-latched */
UNIV_INLINE
trx_rsegf_t*
trx_rsegf_get_new(
/*==============*/
- /* out: rollback segment header, page
- x-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number of the header */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number of the header */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
trx_rsegf_t* header;
@@ -74,16 +74,16 @@ trx_rsegf_get_new(
return(header);
}
-/*******************************************************************
-Gets the file page number of the nth undo log slot. */
+/***************************************************************//**
+Gets the file page number of the nth undo log slot.
+@return page number of the undo log segment */
UNIV_INLINE
ulint
trx_rsegf_get_nth_undo(
/*===================*/
- /* out: page number of the undo log segment */
- trx_rsegf_t* rsegf, /* in: rollback segment header */
- ulint n, /* in: index of slot */
- mtr_t* mtr) /* in: mtr */
+ trx_rsegf_t* rsegf, /*!< in: rollback segment header */
+ ulint n, /*!< in: index of slot */
+ mtr_t* mtr) /*!< in: mtr */
{
if (UNIV_UNLIKELY(n >= TRX_RSEG_N_SLOTS)) {
fprintf(stderr,
@@ -96,16 +96,16 @@ trx_rsegf_get_nth_undo(
+ n * TRX_RSEG_SLOT_SIZE, MLOG_4BYTES, mtr));
}
-/*******************************************************************
+/***************************************************************//**
Sets the file page number of the nth undo log slot. */
UNIV_INLINE
void
trx_rsegf_set_nth_undo(
/*===================*/
- trx_rsegf_t* rsegf, /* in: rollback segment header */
- ulint n, /* in: index of slot */
- ulint page_no,/* in: page number of the undo log segment */
- mtr_t* mtr) /* in: mtr */
+ trx_rsegf_t* rsegf, /*!< in: rollback segment header */
+ ulint n, /*!< in: index of slot */
+ ulint page_no,/*!< in: page number of the undo log segment */
+ mtr_t* mtr) /*!< in: mtr */
{
if (UNIV_UNLIKELY(n >= TRX_RSEG_N_SLOTS)) {
fprintf(stderr,
@@ -118,16 +118,15 @@ trx_rsegf_set_nth_undo(
page_no, MLOG_4BYTES, mtr);
}
-/********************************************************************
-Looks for a free slot for an undo log segment. */
+/****************************************************************//**
+Looks for a free slot for an undo log segment.
+@return slot index or ULINT_UNDEFINED if not found */
UNIV_INLINE
ulint
trx_rsegf_undo_find_free(
/*=====================*/
- /* out: slot index or ULINT_UNDEFINED if not
- found */
- trx_rsegf_t* rsegf, /* in: rollback segment header */
- mtr_t* mtr) /* in: mtr */
+ trx_rsegf_t* rsegf, /*!< in: rollback segment header */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint i;
ulint page_no;
diff --git a/storage/xtradb/include/trx0sys.h b/storage/xtradb/include/trx0sys.h
index f7e7e082278..1f3f11926f8 100644
--- a/storage/xtradb/include/trx0sys.h
+++ b/storage/xtradb/include/trx0sys.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0sys.h
Transaction system
Created 3/26/1996 Heikki Tuuri
@@ -28,54 +29,65 @@ Created 3/26/1996 Heikki Tuuri
#include "univ.i"
#include "trx0types.h"
+#include "fsp0types.h"
+#include "fil0fil.h"
+#include "buf0buf.h"
+#ifndef UNIV_HOTBACKUP
#include "mtr0mtr.h"
-#include "mtr0log.h"
#include "ut0byte.h"
#include "mem0mem.h"
#include "sync0sync.h"
#include "ut0lst.h"
-#include "buf0buf.h"
-#include "fil0fil.h"
-#include "fut0lst.h"
-#include "fsp0fsp.h"
#include "read0types.h"
#include "page0types.h"
-/* In a MySQL replication slave, in crash recovery we store the master log
-file name and position here. We have successfully got the updates to InnoDB
-up to this position. If .._pos is -1, it means no crash recovery was needed,
-or there was no master log position info inside InnoDB. */
-
+/** In a MySQL replication slave, in crash recovery we store the master log
+file name and position here. */
+/* @{ */
+/** Master binlog file name */
extern char trx_sys_mysql_master_log_name[];
+/** Master binlog file position. We have successfully got the updates
+up to this position. -1 means that no crash recovery was needed, or
+there was no master log position info inside InnoDB.*/
extern ib_int64_t trx_sys_mysql_master_log_pos;
+/* @} */
extern char trx_sys_mysql_relay_log_name[];
extern ib_int64_t trx_sys_mysql_relay_log_pos;
-/* If this MySQL server uses binary logging, after InnoDB has been inited
+/** If this MySQL server uses binary logging, after InnoDB has been inited
and if it has done a crash recovery, we store the binlog file name and position
-here. If .._pos is -1, it means there was no binlog position info inside
-InnoDB. */
-
+here. */
+/* @{ */
+/** Binlog file name */
extern char trx_sys_mysql_bin_log_name[];
+/** Binlog file position, or -1 if unknown */
extern ib_int64_t trx_sys_mysql_bin_log_pos;
+/* @} */
-/* The transaction system */
+/** The transaction system */
extern trx_sys_t* trx_sys;
-/* Doublewrite system */
+/** Doublewrite system */
extern trx_doublewrite_t* trx_doublewrite;
+/** The following is set to TRUE when we are upgrading from pre-4.1
+format data files to the multiple tablespaces format data files */
extern ibool trx_doublewrite_must_reset_space_ids;
+/** Set to TRUE when the doublewrite buffer is being created */
+extern ibool trx_doublewrite_buf_is_being_created;
+/** The following is TRUE when we are using the database in the
+post-4.1 format, i.e., we have successfully upgraded, or have created
+a new database installation */
extern ibool trx_sys_multiple_tablespace_format;
-/********************************************************************
+/****************************************************************//**
Creates the doublewrite buffer to a new InnoDB installation. The header of the
doublewrite buffer is placed on the trx system header page. */
UNIV_INTERN
void
trx_sys_create_doublewrite_buf(void);
/*================================*/
-/********************************************************************
+/****************************************************************//**
At a database startup initializes the doublewrite buffer memory structure if
we already have a doublewrite buffer created in the data files. If we are
upgrading to an InnoDB version which supports multiple tablespaces, then this
@@ -86,40 +98,40 @@ UNIV_INTERN
void
trx_sys_doublewrite_init_or_restore_pages(
/*======================================*/
- ibool restore_corrupt_pages);
-/********************************************************************
+ ibool restore_corrupt_pages); /*!< in: TRUE=restore pages */
+/****************************************************************//**
Marks the trx sys header when we have successfully upgraded to the >= 4.1.x
multiple tablespace format. */
UNIV_INTERN
void
trx_sys_mark_upgraded_to_multiple_tablespaces(void);
/*===============================================*/
-/********************************************************************
-Determines if a page number is located inside the doublewrite buffer. */
+/****************************************************************//**
+Determines if a page number is located inside the doublewrite buffer.
+@return TRUE if the location is inside the two blocks of the
+doublewrite buffer */
UNIV_INTERN
ibool
trx_doublewrite_page_inside(
/*========================*/
- /* out: TRUE if the location is inside
- the two blocks of the doublewrite buffer */
- ulint page_no); /* in: page number */
-/*******************************************************************
-Checks if a page address is the trx sys header page. */
+ ulint page_no); /*!< in: page number */
+/***************************************************************//**
+Checks if a page address is the trx sys header page.
+@return TRUE if trx sys header page */
UNIV_INLINE
ibool
trx_sys_hdr_page(
/*=============*/
- /* out: TRUE if trx sys header page */
- ulint space, /* in: space */
- ulint page_no);/* in: page number */
-/*********************************************************************
+ ulint space, /*!< in: space */
+ ulint page_no);/*!< in: page number */
+/*****************************************************************//**
Creates and initializes the central memory structures for the transaction
system. This is called when the database is started. */
UNIV_INTERN
void
trx_sys_init_at_db_start(void);
/*==========================*/
-/*********************************************************************
+/*****************************************************************//**
Creates and initializes the transaction system at the database creation. */
UNIV_INTERN
void
@@ -132,104 +144,102 @@ void
trx_sys_create_extra_rseg(
/*======================*/
ulint num); /* in: number of extra user rollback segments */
-/********************************************************************
-Looks for a free slot for a rollback segment in the trx system file copy. */
+/****************************************************************//**
+Looks for a free slot for a rollback segment in the trx system file copy.
+@return slot index or ULINT_UNDEFINED if not found */
UNIV_INTERN
ulint
trx_sysf_rseg_find_free(
/*====================*/
- /* out: slot index or ULINT_UNDEFINED
- if not found */
- mtr_t* mtr); /* in: mtr */
-/*******************************************************************
-Gets the pointer in the nth slot of the rseg array. */
+ mtr_t* mtr); /*!< in: mtr */
+/***************************************************************//**
+Gets the pointer in the nth slot of the rseg array.
+@return pointer to rseg object, NULL if slot not in use */
UNIV_INLINE
trx_rseg_t*
trx_sys_get_nth_rseg(
/*=================*/
- /* out: pointer to rseg object, NULL if slot
- not in use */
- trx_sys_t* sys, /* in: trx system */
- ulint n); /* in: index of slot */
-/*******************************************************************
+ trx_sys_t* sys, /*!< in: trx system */
+ ulint n); /*!< in: index of slot */
+/***************************************************************//**
Sets the pointer in the nth slot of the rseg array. */
UNIV_INLINE
void
trx_sys_set_nth_rseg(
/*=================*/
- trx_sys_t* sys, /* in: trx system */
- ulint n, /* in: index of slot */
- trx_rseg_t* rseg); /* in: pointer to rseg object, NULL if slot
+ trx_sys_t* sys, /*!< in: trx system */
+ ulint n, /*!< in: index of slot */
+ trx_rseg_t* rseg); /*!< in: pointer to rseg object, NULL if slot
not in use */
-/**************************************************************************
-Gets a pointer to the transaction system file copy and x-locks its page. */
+/**********************************************************************//**
+Gets a pointer to the transaction system file copy and x-locks its page.
+@return pointer to system file copy, page x-locked */
UNIV_INLINE
trx_sysf_t*
trx_sysf_get(
/*=========*/
- /* out: pointer to system file copy, page x-locked */
- mtr_t* mtr); /* in: mtr */
-/*********************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
Gets the space of the nth rollback segment slot in the trx system
-file copy. */
+file copy.
+@return space id */
UNIV_INLINE
ulint
trx_sysf_rseg_get_space(
/*====================*/
- /* out: space id */
- trx_sysf_t* sys_header, /* in: trx sys file copy */
- ulint i, /* in: slot index == rseg id */
- mtr_t* mtr); /* in: mtr */
-/*********************************************************************
+ trx_sysf_t* sys_header, /*!< in: trx sys file copy */
+ ulint i, /*!< in: slot index == rseg id */
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
Gets the page number of the nth rollback segment slot in the trx system
-file copy. */
+file copy.
+@return page number, FIL_NULL if slot unused */
UNIV_INLINE
ulint
trx_sysf_rseg_get_page_no(
/*======================*/
- /* out: page number, FIL_NULL
- if slot unused */
- trx_sysf_t* sys_header, /* in: trx sys file copy */
- ulint i, /* in: slot index == rseg id */
- mtr_t* mtr); /* in: mtr */
-/*********************************************************************
+ trx_sysf_t* sys_header, /*!< in: trx sys file copy */
+ ulint i, /*!< in: slot index == rseg id */
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
Sets the space id of the nth rollback segment slot in the trx system
file copy. */
UNIV_INLINE
void
trx_sysf_rseg_set_space(
/*====================*/
- trx_sysf_t* sys_header, /* in: trx sys file copy */
- ulint i, /* in: slot index == rseg id */
- ulint space, /* in: space id */
- mtr_t* mtr); /* in: mtr */
-/*********************************************************************
+ trx_sysf_t* sys_header, /*!< in: trx sys file copy */
+ ulint i, /*!< in: slot index == rseg id */
+ ulint space, /*!< in: space id */
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
Sets the page number of the nth rollback segment slot in the trx system
file copy. */
UNIV_INLINE
void
trx_sysf_rseg_set_page_no(
/*======================*/
- trx_sysf_t* sys_header, /* in: trx sys file copy */
- ulint i, /* in: slot index == rseg id */
- ulint page_no, /* in: page number, FIL_NULL if
+ trx_sysf_t* sys_header, /*!< in: trx sys file copy */
+ ulint i, /*!< in: slot index == rseg id */
+ ulint page_no, /*!< in: page number, FIL_NULL if
the slot is reset to unused */
- mtr_t* mtr); /* in: mtr */
-/*********************************************************************
-Allocates a new transaction id. */
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
+Allocates a new transaction id.
+@return new, allocated trx id */
UNIV_INLINE
-dulint
+trx_id_t
trx_sys_get_new_trx_id(void);
/*========================*/
- /* out: new, allocated trx id */
-/*********************************************************************
-Allocates a new transaction number. */
+/*****************************************************************//**
+Allocates a new transaction number.
+@return new, allocated trx number */
UNIV_INLINE
-dulint
+trx_id_t
trx_sys_get_new_trx_no(void);
/*========================*/
- /* out: new, allocated trx number */
-/*********************************************************************
+#endif /* !UNIV_HOTBACKUP */
+/*****************************************************************//**
Writes a trx id to an index page. In case that the id size changes in
some future version, this function should be used instead of
mach_write_... */
@@ -237,54 +247,54 @@ UNIV_INLINE
void
trx_write_trx_id(
/*=============*/
- byte* ptr, /* in: pointer to memory where written */
- dulint id); /* in: id */
-/*********************************************************************
+ byte* ptr, /*!< in: pointer to memory where written */
+ trx_id_t id); /*!< in: id */
+#ifndef UNIV_HOTBACKUP
+/*****************************************************************//**
Reads a trx id from an index page. In case that the id size changes in
some future version, this function should be used instead of
-mach_read_... */
+mach_read_...
+@return id */
UNIV_INLINE
-dulint
+trx_id_t
trx_read_trx_id(
/*============*/
- /* out: id */
- const byte* ptr); /* in: pointer to memory from where to read */
-/********************************************************************
-Looks for the trx handle with the given id in trx_list. */
+ const byte* ptr); /*!< in: pointer to memory from where to read */
+/****************************************************************//**
+Looks for the trx handle with the given id in trx_list.
+@return the trx handle or NULL if not found */
UNIV_INLINE
trx_t*
trx_get_on_id(
/*==========*/
- /* out: the trx handle or NULL if not found */
- dulint trx_id); /* in: trx id to search for */
-/********************************************************************
+ trx_id_t trx_id);/*!< in: trx id to search for */
+/****************************************************************//**
Returns the minumum trx id in trx list. This is the smallest id for which
the trx can possibly be active. (But, you must look at the trx->conc_state to
find out if the minimum trx id transaction itself is active, or already
-committed.) */
+committed.)
+@return the minimum trx id, or trx_sys->max_trx_id if the trx list is empty */
UNIV_INLINE
-dulint
+trx_id_t
trx_list_get_min_trx_id(void);
/*=========================*/
- /* out: the minimum trx id, or trx_sys->max_trx_id
- if the trx list is empty */
-/********************************************************************
-Checks if a transaction with the given id is active. */
+/****************************************************************//**
+Checks if a transaction with the given id is active.
+@return TRUE if active */
UNIV_INLINE
ibool
trx_is_active(
/*==========*/
- /* out: TRUE if active */
- dulint trx_id);/* in: trx id of the transaction */
-/********************************************************************
-Checks that trx is in the trx list. */
+ trx_id_t trx_id);/*!< in: trx id of the transaction */
+/****************************************************************//**
+Checks that trx is in the trx list.
+@return TRUE if is in */
UNIV_INTERN
ibool
trx_in_trx_list(
/*============*/
- /* out: TRUE if is in */
- trx_t* in_trx);/* in: trx */
-/*********************************************************************
+ trx_t* in_trx);/*!< in: trx */
+/*****************************************************************//**
Updates the offset information about the end of the MySQL binlog entry
which corresponds to the transaction just being committed. In a MySQL
replication slave updates the latest master binlog position up to which
@@ -293,50 +303,38 @@ UNIV_INTERN
void
trx_sys_update_mysql_binlog_offset(
/*===============================*/
- 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
+ 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 */
-/*********************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/*****************************************************************//**
Prints to stderr the MySQL binlog offset info in the trx system header if
the magic number shows it valid. */
UNIV_INTERN
void
trx_sys_print_mysql_binlog_offset(void);
/*===================================*/
-#ifdef UNIV_HOTBACKUP
-/*********************************************************************
-Prints to stderr the MySQL binlog info in the system header if the
-magic number shows it valid. */
-UNIV_INTERN
-void
-trx_sys_print_mysql_binlog_offset_from_page(
-/*========================================*/
- const byte* page); /* in: buffer containing the trx
- system header page, i.e., page number
- TRX_SYS_PAGE_NO in the tablespace */
-#endif /* UNIV_HOTBACKUP */
-/*********************************************************************
+/*****************************************************************//**
Prints to stderr the MySQL master log offset info in the trx system header if
the magic number shows it valid. */
UNIV_INTERN
void
trx_sys_print_mysql_master_log_pos(void);
/*====================================*/
-/*********************************************************************
+/*****************************************************************//**
Initializes the tablespace tag system. */
UNIV_INTERN
void
trx_sys_file_format_init(void);
/*==========================*/
-/*********************************************************************
+/*****************************************************************//**
Closes the tablespace tag system. */
UNIV_INTERN
void
trx_sys_file_format_close(void);
/*===========================*/
-/************************************************************************
+/********************************************************************//**
Tags the system table space with minimum format id if it has not been
tagged yet.
WARNING: This function is only called during the startup and AFTER the
@@ -345,213 +343,285 @@ UNIV_INTERN
void
trx_sys_file_format_tag_init(void);
/*==============================*/
-/*********************************************************************
-Get the name representation of the file format from its id. */
+/*****************************************************************//**
+Get the name representation of the file format from its id.
+@return pointer to the name */
UNIV_INTERN
const char*
trx_sys_file_format_id_to_name(
/*===========================*/
- /* out: pointer to the name */
- const ulint id); /* in: id of the file format */
-/*********************************************************************
+ const ulint id); /*!< in: id of the file format */
+/*****************************************************************//**
Set the file format id unconditionally except if it's already the
-same value. */
+same value.
+@return TRUE if value updated */
UNIV_INTERN
ibool
trx_sys_file_format_max_set(
/*========================*/
- /* out: TRUE if value updated */
- ulint format_id, /* in: file format id */
- const char** name); /* out: max file format name or
+ ulint format_id, /*!< in: file format id */
+ const char** name); /*!< out: max file format name or
NULL if not needed. */
-/*********************************************************************
-Get the name representation of the file format from its id. */
+/*****************************************************************//**
+Get the name representation of the file format from its id.
+@return pointer to the max format name */
UNIV_INTERN
const char*
trx_sys_file_format_max_get(void);
/*=============================*/
- /* out: pointer to the max format name */
-/*********************************************************************
-Check for the max file format tag stored on disk. */
+/*****************************************************************//**
+Check for the max file format tag stored on disk.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
trx_sys_file_format_max_check(
/*==========================*/
- /* out: DB_SUCCESS or error code */
- ulint max_format_id); /* in: the max format id to check */
-/************************************************************************
+ ulint max_format_id); /*!< in: the max format id to check */
+/********************************************************************//**
Update the file format tag in the system tablespace only if the given
-format id is greater than the known max id. */
+format id is greater than the known max id.
+@return TRUE if format_id was bigger than the known max id */
UNIV_INTERN
ibool
trx_sys_file_format_max_upgrade(
/*============================*/
- /* out: TRUE if format_id was
- bigger than the known max id */
- const char** name, /* out: max file format name */
- ulint format_id); /* in: file format identifier */
+ const char** name, /*!< out: max file format name */
+ ulint format_id); /*!< in: file format identifier */
+#else /* !UNIV_HOTBACKUP */
+/*****************************************************************//**
+Prints to stderr the MySQL binlog info in the system header if the
+magic number shows it valid. */
+UNIV_INTERN
+void
+trx_sys_print_mysql_binlog_offset_from_page(
+/*========================================*/
+ const byte* page); /*!< in: buffer containing the trx
+ system header page, i.e., page number
+ TRX_SYS_PAGE_NO in the tablespace */
+/*****************************************************************//**
+Reads the file format id from the first system table space file.
+Even if the call succeeds and returns TRUE, the returned format id
+may be ULINT_UNDEFINED signalling that the format id was not present
+in the data file.
+@return TRUE if call succeeds */
+UNIV_INTERN
+ibool
+trx_sys_read_file_format_id(
+/*========================*/
+ const char *pathname, /*!< in: pathname of the first system
+ table space file */
+ ulint *format_id); /*!< out: file format of the system table
+ space */
+/*****************************************************************//**
+Reads the file format id from the given per-table data file.
+@return TRUE if call succeeds */
+UNIV_INTERN
+ibool
+trx_sys_read_pertable_file_format_id(
+/*=================================*/
+ const char *pathname, /*!< in: pathname of a per-table
+ datafile */
+ ulint *format_id); /*!< out: file format of the per-table
+ data file */
+/*****************************************************************//**
+Get the name representation of the file format from its id.
+@return pointer to the name */
+UNIV_INTERN
+const char*
+trx_sys_file_format_id_to_name(
+/*===========================*/
+ const ulint id); /*!< in: id of the file format */
+
+#endif /* !UNIV_HOTBACKUP */
/* The automatically created system rollback segment has this id */
#define TRX_SYS_SYSTEM_RSEG_ID 0
/* Space id and page no where the trx system file copy resides */
#define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */
+#include "fsp0fsp.h"
#define TRX_SYS_PAGE_NO FSP_TRX_SYS_PAGE_NO
/* The offset of the transaction system header on the page */
#define TRX_SYS FSEG_PAGE_DATA
-/* Transaction system header */
-/*-------------------------------------------------------------*/
-#define TRX_SYS_TRX_ID_STORE 0 /* the maximum trx id or trx number
- modulo TRX_SYS_TRX_ID_UPDATE_MARGIN
+/** Transaction system header */
+/*------------------------------------------------------------- @{ */
+#define TRX_SYS_TRX_ID_STORE 0 /*!< the maximum trx id or trx
+ number modulo
+ TRX_SYS_TRX_ID_UPDATE_MARGIN
written to a file page by any
transaction; the assignment of
- transaction ids continues from this
- number rounded up by .._MARGIN plus
- .._MARGIN when the database is
+ transaction ids continues from
+ this number rounded up by
+ TRX_SYS_TRX_ID_UPDATE_MARGIN
+ plus
+ TRX_SYS_TRX_ID_UPDATE_MARGIN
+ when the database is
started */
-#define TRX_SYS_FSEG_HEADER 8 /* segment header for the tablespace
- segment the trx system is created
- into */
+#define TRX_SYS_FSEG_HEADER 8 /*!< segment header for the
+ tablespace segment the trx
+ system is created into */
#define TRX_SYS_RSEGS (8 + FSEG_HEADER_SIZE)
- /* the start of the array of rollback
- segment specification slots */
-/*-------------------------------------------------------------*/
-
-/* Max number of rollback segments: the number of segment specification slots
-in the transaction system array; rollback segment id must fit in one byte,
-therefore 256; each slot is currently 8 bytes in size */
+ /*!< the start of the array of
+ rollback segment specification
+ slots */
+/*------------------------------------------------------------- @} */
+
+/** Maximum number of rollback segments: the number of segment
+specification slots in the transaction system array; rollback segment
+id must fit in one byte, therefore 256; each slot is currently 8 bytes
+in size */
#define TRX_SYS_N_RSEGS 256
+/** Maximum length of MySQL binlog file name, in bytes.
+@see trx_sys_mysql_master_log_name
+@see trx_sys_mysql_bin_log_name */
#define TRX_SYS_MYSQL_LOG_NAME_LEN 512
#define TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN 480 /* (500 - 12) is dead line. */
+/** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */
#define TRX_SYS_MYSQL_LOG_MAGIC_N 873422344
#if UNIV_PAGE_SIZE < 4096
# error "UNIV_PAGE_SIZE < 4096"
#endif
-/* The offset of the MySQL replication info in the trx system header;
+/** The offset of the MySQL replication info in the trx system header;
this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
#define TRX_SYS_MYSQL_MASTER_LOG_INFO (UNIV_PAGE_SIZE - 2000)
#define TRX_SYS_MYSQL_RELAY_LOG_INFO (UNIV_PAGE_SIZE - 1500)
-/* The offset of the MySQL binlog offset info in the trx system header */
+/** The offset of the MySQL binlog offset info in the trx system header */
#define TRX_SYS_MYSQL_LOG_INFO (UNIV_PAGE_SIZE - 1000)
-#define TRX_SYS_MYSQL_LOG_MAGIC_N_FLD 0 /* magic number which shows
+#define TRX_SYS_MYSQL_LOG_MAGIC_N_FLD 0 /*!< magic number which is
+ TRX_SYS_MYSQL_LOG_MAGIC_N
if we have valid data in the
- MySQL binlog info; the value
- is ..._MAGIC_N if yes */
-#define TRX_SYS_MYSQL_LOG_OFFSET_HIGH 4 /* high 4 bytes of the offset
+ MySQL binlog info */
+#define TRX_SYS_MYSQL_LOG_OFFSET_HIGH 4 /*!< high 4 bytes of the offset
within that file */
-#define TRX_SYS_MYSQL_LOG_OFFSET_LOW 8 /* low 4 bytes of the offset
+#define TRX_SYS_MYSQL_LOG_OFFSET_LOW 8 /*!< low 4 bytes of the offset
within that file */
-#define TRX_SYS_MYSQL_LOG_NAME 12 /* MySQL log file name */
+#define TRX_SYS_MYSQL_LOG_NAME 12 /*!< MySQL log file name */
-/* The offset of the doublewrite buffer header on the trx system header page */
+#ifndef UNIV_HOTBACKUP
+/** Doublewrite buffer */
+/* @{ */
+/** The offset of the doublewrite buffer header on the trx system header page */
#define TRX_SYS_DOUBLEWRITE (UNIV_PAGE_SIZE - 200)
/*-------------------------------------------------------------*/
-#define TRX_SYS_DOUBLEWRITE_FSEG 0 /* fseg header of the fseg
+#define TRX_SYS_DOUBLEWRITE_FSEG 0 /*!< fseg header of the fseg
containing the doublewrite
buffer */
#define TRX_SYS_DOUBLEWRITE_MAGIC FSEG_HEADER_SIZE
- /* 4-byte magic number which
+ /*!< 4-byte magic number which
shows if we already have
created the doublewrite
buffer */
#define TRX_SYS_DOUBLEWRITE_BLOCK1 (4 + FSEG_HEADER_SIZE)
- /* page number of the
+ /*!< page number of the
first page in the first
sequence of 64
(= FSP_EXTENT_SIZE) consecutive
pages in the doublewrite
buffer */
#define TRX_SYS_DOUBLEWRITE_BLOCK2 (8 + FSEG_HEADER_SIZE)
- /* page number of the
+ /*!< page number of the
first page in the second
sequence of 64 consecutive
pages in the doublewrite
buffer */
-#define TRX_SYS_DOUBLEWRITE_REPEAT 12 /* we repeat the above 3
- numbers so that if the trx
- sys header is half-written
- to disk, we still may be able
- to recover the information */
+#define TRX_SYS_DOUBLEWRITE_REPEAT 12 /*!< we repeat
+ TRX_SYS_DOUBLEWRITE_MAGIC,
+ TRX_SYS_DOUBLEWRITE_BLOCK1,
+ TRX_SYS_DOUBLEWRITE_BLOCK2
+ so that if the trx sys
+ header is half-written
+ to disk, we still may
+ be able to recover the
+ information */
+/** If this is not yet set to TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N,
+we must reset the doublewrite buffer, because starting from 4.1.x the
+space id of a data page is stored into
+FIL_PAGE_ARCH_LOG_NO_OR_SPACE_NO. */
#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED (24 + FSEG_HEADER_SIZE)
- /* If this is not yet set to
- .._N, we must reset the
- doublewrite buffer, because
- starting from 4.1.x the space
- id of a data page is stored to
- FIL_PAGE_ARCH_LOG_NO_OR_SPACE_NO */
+
/*-------------------------------------------------------------*/
+/** Contents of TRX_SYS_DOUBLEWRITE_MAGIC */
#define TRX_SYS_DOUBLEWRITE_MAGIC_N 536853855
+/** Contents of TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED */
#define TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N 1783657386
-
+/** Size of the doublewrite block in pages */
#define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE FSP_EXTENT_SIZE
+/* @} */
-/* The offset of the file format tag on the trx system header page */
+/** File format tag */
+/* @{ */
+/** The offset of the file format tag on the trx system header page
+(TRX_SYS_PAGE_NO of TRX_SYS_SPACE) */
#define TRX_SYS_FILE_FORMAT_TAG (UNIV_PAGE_SIZE - 16)
-/* We use these random constants to reduce the probability of reading
-garbage (from previous versions) that maps to an actual format id. We
-use these as bit masks at the time of reading and writing from/to disk. */
+/** Contents of TRX_SYS_FILE_FORMAT_TAG when valid. The file format
+identifier is added to this constant. */
#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW 3645922177UL
+/** Contents of TRX_SYS_FILE_FORMAT_TAG+4 when valid */
#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH 2745987765UL
+/* @} */
-/* Doublewrite control struct */
+/** Doublewrite control struct */
struct trx_doublewrite_struct{
- mutex_t mutex; /* mutex protecting the first_free field and
+ mutex_t mutex; /*!< mutex protecting the first_free field and
write_buf */
- ulint block1; /* the page number of the first
+ ulint block1; /*!< the page number of the first
doublewrite block (64 pages) */
- ulint block2; /* page number of the second block */
- ulint first_free; /* first free position in write_buf measured
+ ulint block2; /*!< page number of the second block */
+ ulint first_free; /*!< first free position in write_buf measured
in units of UNIV_PAGE_SIZE */
- byte* write_buf; /* write buffer used in writing to the
+ byte* write_buf; /*!< write buffer used in writing to the
doublewrite buffer, aligned to an
address divisible by UNIV_PAGE_SIZE
(which is required by Windows aio) */
- byte* write_buf_unaligned; /* pointer to write_buf, but unaligned */
+ byte* write_buf_unaligned;
+ /*!< pointer to write_buf, but unaligned */
buf_page_t**
- buf_block_arr; /* array to store pointers to the buffer
+ buf_block_arr; /*!< array to store pointers to the buffer
blocks which have been cached to write_buf */
};
-/* The transaction system central memory data structure; protected by the
+/** The transaction system central memory data structure; protected by the
kernel mutex */
struct trx_sys_struct{
- dulint max_trx_id; /* The smallest number not yet
+ trx_id_t max_trx_id; /*!< The smallest number not yet
assigned as a transaction id or
transaction number */
UT_LIST_BASE_NODE_T(trx_t) trx_list;
- /* List of active and committed in
+ /*!< List of active and committed in
memory transactions, sorted on trx id,
biggest first */
UT_LIST_BASE_NODE_T(trx_t) mysql_trx_list;
- /* List of transactions created
+ /*!< List of transactions created
for MySQL */
UT_LIST_BASE_NODE_T(trx_rseg_t) rseg_list;
- /* List of rollback segment objects */
- trx_rseg_t* latest_rseg; /* Latest rollback segment in the
+ /*!< List of rollback segment
+ objects */
+ trx_rseg_t* latest_rseg; /*!< Latest rollback segment in the
round-robin assignment of rollback
segments to transactions */
trx_rseg_t* rseg_array[TRX_SYS_N_RSEGS];
- /* Pointer array to rollback segments;
- NULL if slot not in use */
- ulint rseg_history_len;/* Length of the TRX_RSEG_HISTORY
+ /*!< Pointer array to rollback
+ segments; NULL if slot not in use */
+ ulint rseg_history_len;/*!< Length of the TRX_RSEG_HISTORY
list (update undo logs for committed
transactions), protected by
rseg->mutex */
UT_LIST_BASE_NODE_T(read_view_t) view_list;
- /* List of read views sorted on trx no,
- biggest first */
+ /*!< List of read views sorted
+ on trx no, biggest first */
};
-/* When a trx id which is zero modulo this number (which must be a power of
+/** When a trx id which is zero modulo this number (which must be a power of
two) is assigned, the field TRX_SYS_TRX_ID_STORE on the transaction system
page is updated */
#define TRX_SYS_TRX_ID_WRITE_MARGIN 256
+#endif /* !UNIV_HOTBACKUP */
#ifndef UNIV_NONINL
#include "trx0sys.ic"
diff --git a/storage/xtradb/include/trx0sys.ic b/storage/xtradb/include/trx0sys.ic
index 4437133188f..1c7c732751b 100644
--- a/storage/xtradb/include/trx0sys.ic
+++ b/storage/xtradb/include/trx0sys.ic
@@ -16,14 +16,18 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0sys.ic
Transaction system
Created 3/26/1996 Heikki Tuuri
*******************************************************/
-#include "srv0srv.h"
#include "trx0trx.h"
+#include "data0type.h"
+#ifndef UNIV_HOTBACKUP
+# include "srv0srv.h"
+# include "mtr0log.h"
/* The typedef for rseg slot in the file copy */
typedef byte trx_sysf_rseg_t;
@@ -41,22 +45,22 @@ typedef byte trx_sysf_rseg_t;
/* Size of a rollback segment specification slot */
#define TRX_SYS_RSEG_SLOT_SIZE 8
-/*********************************************************************
+/*****************************************************************//**
Writes the value of max_trx_id to the file based trx system header. */
UNIV_INTERN
void
trx_sys_flush_max_trx_id(void);
/*==========================*/
-/*******************************************************************
-Checks if a page address is the trx sys header page. */
+/***************************************************************//**
+Checks if a page address is the trx sys header page.
+@return TRUE if trx sys header page */
UNIV_INLINE
ibool
trx_sys_hdr_page(
/*=============*/
- /* out: TRUE if trx sys header page */
- ulint space, /* in: space */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no)/*!< in: page number */
{
if ((space == TRX_SYS_SPACE) && (page_no == TRX_SYS_PAGE_NO)) {
@@ -66,16 +70,15 @@ trx_sys_hdr_page(
return(FALSE);
}
-/*******************************************************************
-Gets the pointer in the nth slot of the rseg array. */
+/***************************************************************//**
+Gets the pointer in the nth slot of the rseg array.
+@return pointer to rseg object, NULL if slot not in use */
UNIV_INLINE
trx_rseg_t*
trx_sys_get_nth_rseg(
/*=================*/
- /* out: pointer to rseg object, NULL if slot
- not in use */
- trx_sys_t* sys, /* in: trx system */
- ulint n) /* in: index of slot */
+ trx_sys_t* sys, /*!< in: trx system */
+ ulint n) /*!< in: index of slot */
{
ut_ad(mutex_own(&(kernel_mutex)));
ut_ad(n < TRX_SYS_N_RSEGS);
@@ -83,15 +86,15 @@ trx_sys_get_nth_rseg(
return(sys->rseg_array[n]);
}
-/*******************************************************************
+/***************************************************************//**
Sets the pointer in the nth slot of the rseg array. */
UNIV_INLINE
void
trx_sys_set_nth_rseg(
/*=================*/
- trx_sys_t* sys, /* in: trx system */
- ulint n, /* in: index of slot */
- trx_rseg_t* rseg) /* in: pointer to rseg object, NULL if slot
+ trx_sys_t* sys, /*!< in: trx system */
+ ulint n, /*!< in: index of slot */
+ trx_rseg_t* rseg) /*!< in: pointer to rseg object, NULL if slot
not in use */
{
ut_ad(n < TRX_SYS_N_RSEGS);
@@ -99,14 +102,14 @@ trx_sys_set_nth_rseg(
sys->rseg_array[n] = rseg;
}
-/**************************************************************************
-Gets a pointer to the transaction system header and x-latches its page. */
+/**********************************************************************//**
+Gets a pointer to the transaction system header and x-latches its page.
+@return pointer to system header, page x-latched. */
UNIV_INLINE
trx_sysf_t*
trx_sysf_get(
/*=========*/
- /* out: pointer to system header, page x-latched. */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block;
trx_sysf_t* header;
@@ -122,17 +125,17 @@ trx_sysf_get(
return(header);
}
-/*********************************************************************
+/*****************************************************************//**
Gets the space of the nth rollback segment slot in the trx system
-file copy. */
+file copy.
+@return space id */
UNIV_INLINE
ulint
trx_sysf_rseg_get_space(
/*====================*/
- /* out: space id */
- trx_sysf_t* sys_header, /* in: trx sys header */
- ulint i, /* in: slot index == rseg id */
- mtr_t* mtr) /* in: mtr */
+ trx_sysf_t* sys_header, /*!< in: trx sys header */
+ ulint i, /*!< in: slot index == rseg id */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mutex_own(&(kernel_mutex)));
ut_ad(sys_header);
@@ -143,18 +146,17 @@ trx_sysf_rseg_get_space(
+ TRX_SYS_RSEG_SPACE, MLOG_4BYTES, mtr));
}
-/*********************************************************************
+/*****************************************************************//**
Gets the page number of the nth rollback segment slot in the trx system
-header. */
+header.
+@return page number, FIL_NULL if slot unused */
UNIV_INLINE
ulint
trx_sysf_rseg_get_page_no(
/*======================*/
- /* out: page number, FIL_NULL
- if slot unused */
- trx_sysf_t* sys_header, /* in: trx system header */
- ulint i, /* in: slot index == rseg id */
- mtr_t* mtr) /* in: mtr */
+ trx_sysf_t* sys_header, /*!< in: trx system header */
+ ulint i, /*!< in: slot index == rseg id */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(sys_header);
ut_ad(mutex_own(&(kernel_mutex)));
@@ -165,17 +167,17 @@ trx_sysf_rseg_get_page_no(
+ TRX_SYS_RSEG_PAGE_NO, MLOG_4BYTES, mtr));
}
-/*********************************************************************
+/*****************************************************************//**
Sets the space id of the nth rollback segment slot in the trx system
file copy. */
UNIV_INLINE
void
trx_sysf_rseg_set_space(
/*====================*/
- trx_sysf_t* sys_header, /* in: trx sys file copy */
- ulint i, /* in: slot index == rseg id */
- ulint space, /* in: space id */
- mtr_t* mtr) /* in: mtr */
+ trx_sysf_t* sys_header, /*!< in: trx sys file copy */
+ ulint i, /*!< in: slot index == rseg id */
+ ulint space, /*!< in: space id */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mutex_own(&(kernel_mutex)));
ut_ad(sys_header);
@@ -188,18 +190,18 @@ trx_sysf_rseg_set_space(
MLOG_4BYTES, mtr);
}
-/*********************************************************************
+/*****************************************************************//**
Sets the page number of the nth rollback segment slot in the trx system
header. */
UNIV_INLINE
void
trx_sysf_rseg_set_page_no(
/*======================*/
- trx_sysf_t* sys_header, /* in: trx sys header */
- ulint i, /* in: slot index == rseg id */
- ulint page_no, /* in: page number, FIL_NULL if the
+ trx_sysf_t* sys_header, /*!< in: trx sys header */
+ ulint i, /*!< in: slot index == rseg id */
+ ulint page_no, /*!< in: page number, FIL_NULL if the
slot is reset to unused */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ut_ad(mutex_own(&(kernel_mutex)));
ut_ad(sys_header);
@@ -211,8 +213,9 @@ trx_sysf_rseg_set_page_no(
page_no,
MLOG_4BYTES, mtr);
}
+#endif /* !UNIV_HOTBACKUP */
-/*********************************************************************
+/*****************************************************************//**
Writes a trx id to an index page. In case that the id size changes in
some future version, this function should be used instead of
mach_write_... */
@@ -220,8 +223,8 @@ UNIV_INLINE
void
trx_write_trx_id(
/*=============*/
- byte* ptr, /* in: pointer to memory where written */
- dulint id) /* in: id */
+ byte* ptr, /*!< in: pointer to memory where written */
+ trx_id_t id) /*!< in: id */
{
#if DATA_TRX_ID_LEN != 6
# error "DATA_TRX_ID_LEN != 6"
@@ -229,16 +232,17 @@ trx_write_trx_id(
mach_write_to_6(ptr, id);
}
-/*********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*****************************************************************//**
Reads a trx id from an index page. In case that the id size changes in
some future version, this function should be used instead of
-mach_read_... */
+mach_read_...
+@return id */
UNIV_INLINE
-dulint
+trx_id_t
trx_read_trx_id(
/*============*/
- /* out: id */
- const byte* ptr) /* in: pointer to memory from where to read */
+ const byte* ptr) /*!< in: pointer to memory from where to read */
{
#if DATA_TRX_ID_LEN != 6
# error "DATA_TRX_ID_LEN != 6"
@@ -246,14 +250,14 @@ trx_read_trx_id(
return(mach_read_from_6(ptr));
}
-/********************************************************************
-Looks for the trx handle with the given id in trx_list. */
+/****************************************************************//**
+Looks for the trx handle with the given id in trx_list.
+@return the trx handle or NULL if not found */
UNIV_INLINE
trx_t*
trx_get_on_id(
/*==========*/
- /* out: the trx handle or NULL if not found */
- dulint trx_id) /* in: trx id to search for */
+ trx_id_t trx_id) /*!< in: trx id to search for */
{
trx_t* trx;
@@ -273,17 +277,16 @@ trx_get_on_id(
return(NULL);
}
-/********************************************************************
+/****************************************************************//**
Returns the minumum trx id in trx list. This is the smallest id for which
the trx can possibly be active. (But, you must look at the trx->conc_state to
find out if the minimum trx id transaction itself is active, or already
-committed.) */
+committed.)
+@return the minimum trx id, or trx_sys->max_trx_id if the trx list is empty */
UNIV_INLINE
-dulint
+trx_id_t
trx_list_get_min_trx_id(void)
/*=========================*/
- /* out: the minimum trx id, or trx_sys->max_trx_id
- if the trx list is empty */
{
trx_t* trx;
@@ -299,14 +302,14 @@ trx_list_get_min_trx_id(void)
return(trx->id);
}
-/********************************************************************
-Checks if a transaction with the given id is active. */
+/****************************************************************//**
+Checks if a transaction with the given id is active.
+@return TRUE if active */
UNIV_INLINE
ibool
trx_is_active(
/*==========*/
- /* out: TRUE if active */
- dulint trx_id) /* in: trx id of the transaction */
+ trx_id_t trx_id) /*!< in: trx id of the transaction */
{
trx_t* trx;
@@ -337,15 +340,15 @@ trx_is_active(
return(FALSE);
}
-/*********************************************************************
-Allocates a new transaction id. */
+/*****************************************************************//**
+Allocates a new transaction id.
+@return new, allocated trx id */
UNIV_INLINE
-dulint
+trx_id_t
trx_sys_get_new_trx_id(void)
/*========================*/
- /* out: new, allocated trx id */
{
- dulint id;
+ trx_id_t id;
ut_ad(mutex_own(&kernel_mutex));
@@ -369,15 +372,16 @@ trx_sys_get_new_trx_id(void)
return(id);
}
-/*********************************************************************
-Allocates a new transaction number. */
+/*****************************************************************//**
+Allocates a new transaction number.
+@return new, allocated trx number */
UNIV_INLINE
-dulint
+trx_id_t
trx_sys_get_new_trx_no(void)
/*========================*/
- /* out: new, allocated trx number */
{
ut_ad(mutex_own(&kernel_mutex));
return(trx_sys_get_new_trx_id());
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h
index 1bec1ff73be..da031d9d5d3 100644
--- a/storage/xtradb/include/trx0trx.h
+++ b/storage/xtradb/include/trx0trx.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0trx.h
The transaction
Created 3/26/1996 Heikki Tuuri
@@ -27,99 +28,100 @@ Created 3/26/1996 Heikki Tuuri
#include "univ.i"
#include "trx0types.h"
+#include "dict0types.h"
+#ifndef UNIV_HOTBACKUP
#include "lock0types.h"
#include "usr0types.h"
#include "que0types.h"
#include "mem0mem.h"
#include "read0types.h"
-#include "dict0types.h"
#include "trx0xa.h"
#include "ut0vec.h"
-/* Dummy session used currently in MySQL interface */
+/** Dummy session used currently in MySQL interface */
extern sess_t* trx_dummy_sess;
-/* Number of transactions currently allocated for MySQL: protected by
+/** Number of transactions currently allocated for MySQL: protected by
the kernel mutex */
extern ulint trx_n_mysql_transactions;
-/************************************************************************
+/********************************************************************//**
Releases the search latch if trx has reserved it. */
UNIV_INTERN
void
trx_search_latch_release_if_reserved(
/*=================================*/
- trx_t* trx); /* in: transaction */
-/**********************************************************************
+ trx_t* trx); /*!< in: transaction */
+/******************************************************************//**
Set detailed error message for the transaction. */
UNIV_INTERN
void
trx_set_detailed_error(
/*===================*/
- trx_t* trx, /* in: transaction struct */
- const char* msg); /* in: detailed error message */
-/*****************************************************************
+ trx_t* trx, /*!< in: transaction struct */
+ const char* msg); /*!< in: detailed error message */
+/*************************************************************//**
Set detailed error message for the transaction from a file. Note that the
file is rewinded before reading from it. */
UNIV_INTERN
void
trx_set_detailed_error_from_file(
/*=============================*/
- trx_t* trx, /* in: transaction struct */
- FILE* file); /* in: file to read message from */
-/********************************************************************
-Retrieves the error_info field from a trx. */
+ trx_t* trx, /*!< in: transaction struct */
+ FILE* file); /*!< in: file to read message from */
+/****************************************************************//**
+Retrieves the error_info field from a trx.
+@return the error info */
UNIV_INLINE
const dict_index_t*
trx_get_error_info(
/*===============*/
- /* out: the error info */
- const trx_t* trx); /* in: trx object */
-/********************************************************************
-Creates and initializes a transaction object. */
+ const trx_t* trx); /*!< in: trx object */
+/****************************************************************//**
+Creates and initializes a transaction object.
+@return own: the transaction */
UNIV_INTERN
trx_t*
trx_create(
/*=======*/
- /* out, own: the transaction */
- sess_t* sess) /* in: session */
+ sess_t* sess) /*!< in: session */
__attribute__((nonnull));
-/************************************************************************
-Creates a transaction object for MySQL. */
+/********************************************************************//**
+Creates a transaction object for MySQL.
+@return own: transaction object */
UNIV_INTERN
trx_t*
trx_allocate_for_mysql(void);
/*========================*/
- /* out, own: transaction object */
-/************************************************************************
-Creates a transaction object for background operations by the master thread. */
+/********************************************************************//**
+Creates a transaction object for background operations by the master thread.
+@return own: transaction object */
UNIV_INTERN
trx_t*
trx_allocate_for_background(void);
/*=============================*/
- /* out, own: transaction object */
-/************************************************************************
+/********************************************************************//**
Frees a transaction object. */
UNIV_INTERN
void
trx_free(
/*=====*/
- trx_t* trx); /* in, own: trx object */
-/************************************************************************
+ trx_t* trx); /*!< in, own: trx object */
+/********************************************************************//**
Frees a transaction object for MySQL. */
UNIV_INTERN
void
trx_free_for_mysql(
/*===============*/
- trx_t* trx); /* in, own: trx object */
-/************************************************************************
+ trx_t* trx); /*!< in, own: trx object */
+/********************************************************************//**
Frees a transaction object of a background operation of the master thread. */
UNIV_INTERN
void
trx_free_for_background(
/*====================*/
- trx_t* trx); /* in, own: trx object */
-/********************************************************************
+ trx_t* trx); /*!< in, own: trx object */
+/****************************************************************//**
Creates trx objects for transactions and initializes the trx list of
trx_sys at database start. Rollback segment and undo log lists must
already exist when this function is called, because the lists of
@@ -129,52 +131,52 @@ UNIV_INTERN
void
trx_lists_init_at_db_start(void);
/*============================*/
-/********************************************************************
-Starts a new transaction. */
+/****************************************************************//**
+Starts a new transaction.
+@return TRUE if success, FALSE if the rollback segment could not
+support this many transactions */
UNIV_INTERN
ibool
trx_start(
/*======*/
- /* out: TRUE if success, FALSE if the rollback
- segment could not support this many transactions */
- trx_t* trx, /* in: transaction */
- ulint rseg_id);/* in: rollback segment id; if ULINT_UNDEFINED
+ trx_t* trx, /*!< in: transaction */
+ ulint rseg_id);/*!< in: rollback segment id; if ULINT_UNDEFINED
is passed, the system chooses the rollback segment
automatically in a round-robin fashion */
-/********************************************************************
-Starts a new transaction. */
+/****************************************************************//**
+Starts a new transaction.
+@return TRUE */
UNIV_INTERN
ibool
trx_start_low(
/*==========*/
- /* out: TRUE */
- trx_t* trx, /* in: transaction */
- ulint rseg_id);/* in: rollback segment id; if ULINT_UNDEFINED
+ trx_t* trx, /*!< in: transaction */
+ ulint rseg_id);/*!< in: rollback segment id; if ULINT_UNDEFINED
is passed, the system chooses the rollback segment
automatically in a round-robin fashion */
-/*****************************************************************
+/*************************************************************//**
Starts the transaction if it is not yet started. */
UNIV_INLINE
void
trx_start_if_not_started(
/*=====================*/
- trx_t* trx); /* in: transaction */
-/*****************************************************************
+ trx_t* trx); /*!< in: transaction */
+/*************************************************************//**
Starts the transaction if it is not yet started. Assumes we have reserved
the kernel mutex! */
UNIV_INLINE
void
trx_start_if_not_started_low(
/*=========================*/
- trx_t* trx); /* in: transaction */
-/********************************************************************
+ trx_t* trx); /*!< in: transaction */
+/****************************************************************//**
Commits a transaction. */
UNIV_INTERN
void
trx_commit_off_kernel(
/*==================*/
- trx_t* trx); /* in: transaction */
-/********************************************************************
+ trx_t* trx); /*!< in: transaction */
+/****************************************************************//**
Cleans up a transaction at database startup. The cleanup is needed if
the transaction already got to the middle of a commit when the database
crashed, andf we cannot roll it back. */
@@ -182,69 +184,69 @@ UNIV_INTERN
void
trx_cleanup_at_db_startup(
/*======================*/
- trx_t* trx); /* in: transaction */
-/**************************************************************************
-Does the transaction commit for MySQL. */
+ trx_t* trx); /*!< in: transaction */
+/**********************************************************************//**
+Does the transaction commit for MySQL.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
trx_commit_for_mysql(
/*=================*/
- /* out: DB_SUCCESS or error number */
- trx_t* trx); /* in: trx handle */
-/**************************************************************************
-Does the transaction prepare for MySQL. */
+ trx_t* trx); /*!< in: trx handle */
+/**********************************************************************//**
+Does the transaction prepare for MySQL.
+@return 0 or error number */
UNIV_INTERN
ulint
trx_prepare_for_mysql(
/*==================*/
- /* out: 0 or error number */
- trx_t* trx); /* in: trx handle */
-/**************************************************************************
+ trx_t* trx); /*!< in: trx handle */
+/**********************************************************************//**
This function is used to find number of prepared transactions and
-their transaction objects for a recovery. */
+their transaction objects for a recovery.
+@return number of prepared transactions */
UNIV_INTERN
int
trx_recover_for_mysql(
/*==================*/
- /* out: number of prepared transactions */
- XID* xid_list, /* in/out: prepared transactions */
- ulint len); /* in: number of slots in xid_list */
-/***********************************************************************
+ XID* xid_list, /*!< in/out: prepared transactions */
+ ulint len); /*!< in: number of slots in xid_list */
+/*******************************************************************//**
This function is used to find one X/Open XA distributed transaction
-which is in the prepared state */
+which is in the prepared state
+@return trx or NULL */
UNIV_INTERN
trx_t *
trx_get_trx_by_xid(
/*===============*/
- /* out: trx or NULL */
- XID* xid); /* in: X/Open XA transaction identification */
-/**************************************************************************
+ XID* xid); /*!< in: X/Open XA transaction identification */
+/**********************************************************************//**
If required, flushes the log to disk if we called trx_commit_for_mysql()
-with trx->flush_log_later == TRUE. */
+with trx->flush_log_later == TRUE.
+@return 0 or error number */
UNIV_INTERN
ulint
trx_commit_complete_for_mysql(
/*==========================*/
- /* out: 0 or error number */
- trx_t* trx); /* in: trx handle */
-/**************************************************************************
+ trx_t* trx); /*!< in: trx handle */
+/**********************************************************************//**
Marks the latest SQL statement ended. */
UNIV_INTERN
void
trx_mark_sql_stat_end(
/*==================*/
- trx_t* trx); /* in: trx handle */
-/************************************************************************
+ trx_t* trx); /*!< in: trx handle */
+/********************************************************************//**
Assigns a read view for a consistent read query. All the consistent reads
within the same transaction will get the same read view, which is created
-when this function is first called for a new started transaction. */
+when this function is first called for a new started transaction.
+@return consistent read view */
UNIV_INTERN
read_view_t*
trx_assign_read_view(
/*=================*/
- /* out: consistent read view */
- trx_t* trx); /* in: active transaction */
-/***************************************************************
+ trx_t* trx); /*!< in: active transaction */
+/***********************************************************//**
The transaction must be in the TRX_QUE_LOCK_WAIT state. Puts it to
the TRX_QUE_RUNNING state and releases query threads which were
waiting for a lock in the wait_thrs list. */
@@ -252,62 +254,62 @@ UNIV_INTERN
void
trx_end_lock_wait(
/*==============*/
- trx_t* trx); /* in: transaction */
-/********************************************************************
+ trx_t* trx); /*!< in: transaction */
+/****************************************************************//**
Sends a signal to a trx object. */
UNIV_INTERN
void
trx_sig_send(
/*=========*/
- trx_t* trx, /* in: trx handle */
- ulint type, /* in: signal type */
- ulint sender, /* in: TRX_SIG_SELF or
+ trx_t* trx, /*!< in: trx handle */
+ ulint type, /*!< in: signal type */
+ ulint sender, /*!< in: TRX_SIG_SELF or
TRX_SIG_OTHER_SESS */
- que_thr_t* receiver_thr, /* in: query thread which wants the
+ que_thr_t* receiver_thr, /*!< in: query thread which wants the
reply, or NULL; if type is
TRX_SIG_END_WAIT, this must be NULL */
- trx_savept_t* savept, /* in: possible rollback savepoint, or
+ trx_savept_t* savept, /*!< in: possible rollback savepoint, or
NULL */
- que_thr_t** next_thr); /* in/out: next query thread to run;
+ que_thr_t** next_thr); /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
a new query thread; if the parameter
is NULL, it is ignored */
-/********************************************************************
+/****************************************************************//**
Send the reply message when a signal in the queue of the trx has
been handled. */
UNIV_INTERN
void
trx_sig_reply(
/*==========*/
- trx_sig_t* sig, /* in: signal */
- que_thr_t** next_thr); /* in/out: next query thread to run;
+ trx_sig_t* sig, /*!< in: signal */
+ que_thr_t** next_thr); /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
a new query thread */
-/********************************************************************
+/****************************************************************//**
Removes the signal object from a trx signal queue. */
UNIV_INTERN
void
trx_sig_remove(
/*===========*/
- trx_t* trx, /* in: trx handle */
- trx_sig_t* sig); /* in, own: signal */
-/********************************************************************
+ trx_t* trx, /*!< in: trx handle */
+ trx_sig_t* sig); /*!< in, own: signal */
+/****************************************************************//**
Starts handling of a trx signal. */
UNIV_INTERN
void
trx_sig_start_handle(
/*=================*/
- trx_t* trx, /* in: trx handle */
- que_thr_t** next_thr); /* in/out: next query thread to run;
+ trx_t* trx, /*!< in: trx handle */
+ que_thr_t** next_thr); /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
a new query thread */
-/********************************************************************
+/****************************************************************//**
Ends signal handling. If the session is in the error state, and
trx->graph_before_signal_handling != NULL, returns control to the error
handling routine of the graph (currently only returns the control to the
@@ -316,25 +318,25 @@ UNIV_INTERN
void
trx_end_signal_handling(
/*====================*/
- trx_t* trx); /* in: trx */
-/*************************************************************************
-Creates a commit command node struct. */
+ trx_t* trx); /*!< in: trx */
+/*********************************************************************//**
+Creates a commit command node struct.
+@return own: commit node struct */
UNIV_INTERN
commit_node_t*
commit_node_create(
/*===============*/
- /* out, own: commit node struct */
- mem_heap_t* heap); /* in: mem heap where created */
-/***************************************************************
-Performs an execution step for a commit type node in a query graph. */
+ mem_heap_t* heap); /*!< in: mem heap where created */
+/***********************************************************//**
+Performs an execution step for a commit type node in a query graph.
+@return query thread to run next, or NULL */
UNIV_INTERN
que_thr_t*
trx_commit_step(
/*============*/
- /* out: query thread to run next, or NULL */
- que_thr_t* thr); /* in: query thread */
+ que_thr_t* thr); /*!< in: query thread */
-/**************************************************************************
+/**********************************************************************//**
Prints info about a transaction to the given file. The caller must own the
kernel mutex and must have called
innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL
@@ -343,9 +345,9 @@ UNIV_INTERN
void
trx_print(
/*======*/
- FILE* f, /* in: output stream */
- trx_t* trx, /* in: transaction */
- ulint max_query_len); /* in: max query length to print, or 0 to
+ FILE* f, /*!< in: output stream */
+ trx_t* trx, /*!< in: transaction */
+ ulint max_query_len); /*!< in: max query length to print, or 0 to
use the default max length */
/** Type of data dictionary operation */
@@ -363,95 +365,95 @@ enum trx_dict_op {
TRX_DICT_OP_INDEX = 2
};
-/**************************************************************************
-Determine if a transaction is a dictionary operation. */
+/**********************************************************************//**
+Determine if a transaction is a dictionary operation.
+@return dictionary operation mode */
UNIV_INLINE
enum trx_dict_op
trx_get_dict_operation(
/*===================*/
- /* out: dictionary operation mode */
- const trx_t* trx) /* in: transaction */
+ const trx_t* trx) /*!< in: transaction */
__attribute__((pure));
-/**************************************************************************
+/**********************************************************************//**
Flag a transaction a dictionary operation. */
UNIV_INLINE
void
trx_set_dict_operation(
/*===================*/
- trx_t* trx, /* in/out: transaction */
- enum trx_dict_op op); /* in: operation, not
+ trx_t* trx, /*!< in/out: transaction */
+ enum trx_dict_op op); /*!< in: operation, not
TRX_DICT_OP_NONE */
#ifndef UNIV_HOTBACKUP
-/**************************************************************************
-Determines if the currently running transaction has been interrupted. */
+/**********************************************************************//**
+Determines if the currently running transaction has been interrupted.
+@return TRUE if interrupted */
UNIV_INTERN
ibool
trx_is_interrupted(
/*===============*/
- /* out: TRUE if interrupted */
- trx_t* trx); /* in: transaction */
+ trx_t* trx); /*!< in: transaction */
#else /* !UNIV_HOTBACKUP */
#define trx_is_interrupted(trx) FALSE
#endif /* !UNIV_HOTBACKUP */
-/***********************************************************************
+/*******************************************************************//**
Calculates the "weight" of a transaction. The weight of one transaction
is estimated as the number of altered rows + the number of locked rows.
-*/
-
+@param t transaction
+@return transaction weight */
#define TRX_WEIGHT(t) \
ut_dulint_add((t)->undo_no, UT_LIST_GET_LEN((t)->trx_locks))
-/***********************************************************************
+/*******************************************************************//**
Compares the "weight" (or size) of two transactions. Transactions that
have edited non-transactional tables are considered heavier than ones
-that have not. */
+that have not.
+@return <0, 0 or >0; similar to strcmp(3) */
UNIV_INTERN
int
trx_weight_cmp(
/*===========*/
- /* out: <0, 0 or >0; similar to strcmp(3) */
- const trx_t* a, /* in: the first transaction to be compared */
- const trx_t* b); /* in: the second transaction to be compared */
+ const trx_t* a, /*!< in: the first transaction to be compared */
+ const trx_t* b); /*!< in: the second transaction to be compared */
-/***********************************************************************
-Retrieves transacion's id, represented as unsigned long long. */
+/*******************************************************************//**
+Retrieves transacion's id, represented as unsigned long long.
+@return transaction's id */
UNIV_INLINE
ullint
trx_get_id(
/*=======*/
- /* out: transaction's id */
- const trx_t* trx); /* in: transaction */
+ const trx_t* trx); /*!< in: transaction */
/* Maximum length of a string that can be returned by
trx_get_que_state_str(). */
#define TRX_QUE_STATE_STR_MAX_LEN 12 /* "ROLLING BACK" */
-/***********************************************************************
+/*******************************************************************//**
Retrieves transaction's que state in a human readable string. The string
-should not be free()'d or modified. */
+should not be free()'d or modified.
+@return string in the data segment */
UNIV_INLINE
const char*
trx_get_que_state_str(
/*==================*/
- /* out: string in the data segment */
- const trx_t* trx); /* in: transaction */
+ const trx_t* trx); /*!< in: transaction */
/* Signal to a transaction */
struct trx_sig_struct{
- unsigned type:3; /* signal type */
- unsigned sender:1; /* TRX_SIG_SELF or
+ unsigned type:3; /*!< signal type */
+ unsigned sender:1; /*!< TRX_SIG_SELF or
TRX_SIG_OTHER_SESS */
- que_thr_t* receiver; /* non-NULL if the sender of the signal
+ que_thr_t* receiver; /*!< non-NULL if the sender of the signal
wants reply after the operation induced
by the signal is completed */
- trx_savept_t savept; /* possible rollback savepoint */
+ trx_savept_t savept; /*!< possible rollback savepoint */
UT_LIST_NODE_T(trx_sig_t)
- signals; /* queue of pending signals to the
+ signals; /*!< queue of pending signals to the
transaction */
UT_LIST_NODE_T(trx_sig_t)
- reply_signals; /* list of signals for which the sender
+ reply_signals; /*!< list of signals for which the sender
transaction is waiting a reply */
};
@@ -465,17 +467,17 @@ struct trx_struct{
ulint magic_n;
/* All the next fields are protected by the kernel mutex, except the
undo logs which are protected by undo_mutex */
- const char* op_info; /* English text describing the
+ const char* op_info; /*!< English text describing the
current operation, or an empty
string */
- unsigned is_purge:1; /* 0=user transaction, 1=purge */
- unsigned is_recovered:1; /* 0=normal transaction,
+ unsigned is_purge:1; /*!< 0=user transaction, 1=purge */
+ unsigned is_recovered:1; /*!< 0=normal transaction,
1=recovered, must be rolled back */
- unsigned conc_state:2; /* state of the trx from the point
+ unsigned conc_state:2; /*!< state of the trx from the point
of view of concurrency control:
TRX_ACTIVE, TRX_COMMITTED_IN_MEMORY,
... */
- unsigned que_state:2; /* valid when conc_state == TRX_ACTIVE:
+ unsigned que_state:2; /*!< valid when conc_state == TRX_ACTIVE:
TRX_QUE_RUNNING, TRX_QUE_LOCK_WAIT,
... */
unsigned isolation_level:2;/* TRX_ISO_REPEATABLE_READ, ... */
@@ -490,15 +492,17 @@ struct trx_struct{
for secondary indexes when we decide
if we can use the insert buffer for
them, we set this FALSE */
- unsigned support_xa:1; /* normally we do the XA two-phase
+ unsigned support_xa:1; /*!< normally we do the XA two-phase
commit steps, but by setting this to
FALSE, one can save CPU time and about
150 bytes in the undo log size as then
we skip XA steps */
- unsigned flush_log_later:1;/* when we commit the transaction
- in MySQL's binlog write, we will
- flush the log to disk later in
- a separate call */
+ unsigned flush_log_later:1;/* In 2PC, we hold the
+ prepare_commit mutex across
+ both phases. In that case, we
+ defer flush of the logs to disk
+ until after we release the
+ mutex. */
unsigned must_flush_log_later:1;/* this flag is set to TRUE in
trx_commit_off_kernel() if
flush_log_later was TRUE, and there
@@ -506,8 +510,8 @@ struct trx_struct{
in that case we must flush the log
in trx_commit_complete_for_mysql() */
unsigned dict_operation:2;/**< @see enum trx_dict_op */
- unsigned duplicates:2; /* TRX_DUP_IGNORE | TRX_DUP_REPLACE */
- unsigned active_trans:2; /* 1 - if a transaction in MySQL
+ unsigned duplicates:2; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */
+ unsigned active_trans:2; /*!< 1 - if a transaction in MySQL
is active. 2 - if prepare_commit_mutex
was taken */
unsigned has_search_latch:1;
@@ -524,21 +528,21 @@ struct trx_struct{
/* 0, RW_S_LATCH, or RW_X_LATCH:
the latch mode trx currently holds
on dict_operation_lock */
- time_t start_time; /* time the trx object was created
+ time_t start_time; /*!< time the trx object was created
or the state last time became
TRX_ACTIVE */
- dulint id; /* transaction id */
- XID xid; /* X/Open XA transaction
+ trx_id_t id; /*!< transaction id */
+ XID xid; /*!< X/Open XA transaction
identification to identify a
transaction branch */
- dulint no; /* transaction serialization number ==
+ trx_id_t no; /*!< transaction serialization number ==
max trx id when the transaction is
moved to COMMITTED_IN_MEMORY state */
- ib_uint64_t commit_lsn; /* lsn at the time of the commit */
- dulint table_id; /* Table to drop iff dict_operation
+ ib_uint64_t commit_lsn; /*!< lsn at the time of the commit */
+ trx_id_t table_id; /*!< Table to drop iff dict_operation
is TRUE, or ut_dulint_zero. */
/*------------------------------*/
- void* mysql_thd; /* MySQL thread handle corresponding
+ 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
@@ -597,48 +601,48 @@ struct trx_struct{
here is > 0, we decrement this by 1 */
/*------------------------------*/
UT_LIST_NODE_T(trx_t)
- trx_list; /* list of transactions */
+ trx_list; /*!< list of transactions */
UT_LIST_NODE_T(trx_t)
- mysql_trx_list; /* list of transactions created for
+ mysql_trx_list; /*!< list of transactions created for
MySQL */
/*------------------------------*/
- ulint error_state; /* 0 if no error, otherwise error
+ ulint error_state; /*!< 0 if no error, otherwise error
number; NOTE That ONLY the thread
doing the transaction is allowed to
set this field: this is NOT protected
by the kernel mutex */
- const dict_index_t*error_info; /* if the error number indicates a
+ const dict_index_t*error_info; /*!< if the error number indicates a
duplicate key error, a pointer to
the problematic index is stored here */
- ulint error_key_num; /* if the index creation fails to a
+ ulint error_key_num; /*!< if the index creation fails to a
duplicate key error, a mysql key
number of that index is stored here */
- sess_t* sess; /* session of the trx, NULL if none */
- que_t* graph; /* query currently run in the session,
+ sess_t* sess; /*!< session of the trx, NULL if none */
+ que_t* graph; /*!< query currently run in the session,
or NULL if none; NOTE that the query
belongs to the session, and it can
survive over a transaction commit, if
it is a stored procedure with a COMMIT
WORK statement, for instance */
- ulint n_active_thrs; /* number of active query threads */
+ ulint n_active_thrs; /*!< number of active query threads */
que_t* graph_before_signal_handling;
/* value of graph when signal handling
for this trx started: this is used to
return control to the original query
graph for error processing */
- trx_sig_t sig; /* one signal object can be allocated
+ trx_sig_t sig; /*!< one signal object can be allocated
in this space, avoiding mem_alloc */
UT_LIST_BASE_NODE_T(trx_sig_t)
- signals; /* queue of processed or pending
+ signals; /*!< queue of processed or pending
signals to the trx */
UT_LIST_BASE_NODE_T(trx_sig_t)
- reply_signals; /* list of signals sent by the query
+ reply_signals; /*!< list of signals sent by the query
threads of this trx for which a thread
is waiting for a reply; if this trx is
killed, the reply requests in the list
must be canceled */
/*------------------------------*/
- lock_t* wait_lock; /* if trx execution state is
+ lock_t* wait_lock; /*!< if trx execution state is
TRX_QUE_LOCK_WAIT, this points to
the lock request, otherwise this is
NULL */
@@ -648,21 +652,21 @@ struct trx_struct{
if another transaction chooses this
transaction as a victim in deadlock
resolution, it sets this to TRUE */
- time_t wait_started; /* lock wait started at this time */
+ time_t wait_started; /*!< lock wait started at this time */
UT_LIST_BASE_NODE_T(que_thr_t)
- wait_thrs; /* query threads belonging to this
+ wait_thrs; /*!< query threads belonging to this
trx that are in the QUE_THR_LOCK_WAIT
state */
- ulint deadlock_mark; /* a mark field used in deadlock
+ ulint deadlock_mark; /*!< a mark field used in deadlock
checking algorithm. This must be
in its own machine word, because
it can be changed by other
threads while holding kernel_mutex. */
/*------------------------------*/
- mem_heap_t* lock_heap; /* memory heap for the locks of the
+ mem_heap_t* lock_heap; /*!< memory heap for the locks of the
transaction */
UT_LIST_BASE_NODE_T(lock_t)
- trx_locks; /* locks reserved by the transaction */
+ trx_locks; /*!< locks reserved by the transaction */
/*------------------------------*/
mem_heap_t* global_read_view_heap;
/* memory heap for the global read
@@ -670,7 +674,7 @@ struct trx_struct{
read_view_t* global_read_view;
/* consistent read view associated
to a transaction or NULL */
- read_view_t* read_view; /* consistent read view used in the
+ read_view_t* read_view; /*!< consistent read view used in the
transaction or NULL, this read view
if defined can be normal read view
associated to a transaction (i.e.
@@ -678,16 +682,16 @@ struct trx_struct{
associated to a cursor */
/*------------------------------*/
UT_LIST_BASE_NODE_T(trx_named_savept_t)
- trx_savepoints; /* savepoints set with SAVEPOINT ...,
+ trx_savepoints; /*!< savepoints set with SAVEPOINT ...,
oldest first */
/*------------------------------*/
- mutex_t undo_mutex; /* mutex protecting the fields in this
+ mutex_t undo_mutex; /*!< mutex protecting the fields in this
section (down to undo_no_arr), EXCEPT
last_sql_stat_start, which can be
accessed only when we know that there
cannot be any activity in the undo
logs! */
- dulint undo_no; /* next undo log record number to
+ undo_no_t undo_no; /*!< next undo log record number to
assign; since the undo log is
private for a transaction, this
is a simple ascending sequence
@@ -699,22 +703,22 @@ struct trx_struct{
was started: in case of an error, trx
is rolled back down to this undo
number; see note at undo_mutex! */
- trx_rseg_t* rseg; /* rollback segment assigned to the
+ trx_rseg_t* rseg; /*!< rollback segment assigned to the
transaction, or NULL if not assigned
yet */
- trx_undo_t* insert_undo; /* pointer to the insert undo log, or
+ trx_undo_t* insert_undo; /*!< pointer to the insert undo log, or
NULL if no inserts performed yet */
- trx_undo_t* update_undo; /* pointer to the update undo log, or
+ trx_undo_t* update_undo; /*!< pointer to the update undo log, or
NULL if no update performed yet */
- dulint roll_limit; /* least undo number to undo during
+ undo_no_t roll_limit; /*!< least undo number to undo during
a rollback */
- ulint pages_undone; /* number of undo log pages undone
+ ulint pages_undone; /*!< number of undo log pages undone
since the last undo log truncation */
- trx_undo_arr_t* undo_no_arr; /* array of undo numbers of undo log
+ trx_undo_arr_t* undo_no_arr; /*!< array of undo numbers of undo log
records which are currently processed
by a rollback operation */
/*------------------------------*/
- ulint n_autoinc_rows; /* no. of AUTO-INC rows required for
+ ulint n_autoinc_rows; /*!< no. of AUTO-INC rows required for
an SQL statement. This is useful for
multi-row INSERTs */
ib_vector_t* autoinc_locks; /* AUTOINC locks held by this
@@ -723,7 +727,7 @@ struct trx_struct{
vector needs to be freed explicitly
when the trx_t instance is desrtoyed */
/*------------------------------*/
- char detailed_error[256]; /* detailed error message for last
+ char detailed_error[256]; /*!< detailed error message for last
error, or empty. */
};
@@ -800,19 +804,26 @@ Multiple flags can be combined with bitwise OR. */
#define TRX_SIG_OTHER_SESS 1 /* sent by another session (which
must hold rights to this) */
-/* Commit command node in a query graph */
+/** Commit node states */
+enum commit_node_state {
+ COMMIT_NODE_SEND = 1, /*!< about to send a commit signal to
+ the transaction */
+ COMMIT_NODE_WAIT /*!< commit signal sent to the transaction,
+ waiting for completion */
+};
+
+/** Commit command node in a query graph */
struct commit_node_struct{
- que_common_t common; /* node type: QUE_NODE_COMMIT */
- ulint state; /* node execution state */
+ que_common_t common; /*!< node type: QUE_NODE_COMMIT */
+ enum commit_node_state
+ state; /*!< node execution state */
};
-/* Commit node states */
-#define COMMIT_NODE_SEND 1
-#define COMMIT_NODE_WAIT 2
#ifndef UNIV_NONINL
#include "trx0trx.ic"
#endif
+#endif /* !UNIV_HOTBACKUP */
#endif
diff --git a/storage/xtradb/include/trx0trx.ic b/storage/xtradb/include/trx0trx.ic
index 51212539c09..7332eeece85 100644
--- a/storage/xtradb/include/trx0trx.ic
+++ b/storage/xtradb/include/trx0trx.ic
@@ -16,19 +16,20 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0trx.ic
The transaction
Created 3/26/1996 Heikki Tuuri
*******************************************************/
-/*****************************************************************
+/*************************************************************//**
Starts the transaction if it is not yet started. */
UNIV_INLINE
void
trx_start_if_not_started(
/*=====================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
ut_ad(trx->conc_state != TRX_COMMITTED_IN_MEMORY);
@@ -38,14 +39,14 @@ trx_start_if_not_started(
}
}
-/*****************************************************************
+/*************************************************************//**
Starts the transaction if it is not yet started. Assumes we have reserved
the kernel mutex! */
UNIV_INLINE
void
trx_start_if_not_started_low(
/*=========================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
ut_ad(trx->conc_state != TRX_COMMITTED_IN_MEMORY);
@@ -55,39 +56,39 @@ trx_start_if_not_started_low(
}
}
-/********************************************************************
-Retrieves the error_info field from a trx. */
+/****************************************************************//**
+Retrieves the error_info field from a trx.
+@return the error info */
UNIV_INLINE
const dict_index_t*
trx_get_error_info(
/*===============*/
- /* out: the error info */
- const trx_t* trx) /* in: trx object */
+ const trx_t* trx) /*!< in: trx object */
{
return(trx->error_info);
}
-/***********************************************************************
-Retrieves transacion's id, represented as unsigned long long. */
+/*******************************************************************//**
+Retrieves transacion's id, represented as unsigned long long.
+@return transaction's id */
UNIV_INLINE
ullint
trx_get_id(
/*=======*/
- /* out: transaction's id */
- const trx_t* trx) /* in: transaction */
+ const trx_t* trx) /*!< in: transaction */
{
return((ullint)ut_conv_dulint_to_longlong(trx->id));
}
-/***********************************************************************
+/*******************************************************************//**
Retrieves transaction's que state in a human readable string. The string
-should not be free()'d or modified. */
+should not be free()'d or modified.
+@return string in the data segment */
UNIV_INLINE
const char*
trx_get_que_state_str(
/*==================*/
- /* out: string in the data segment */
- const trx_t* trx) /* in: transaction */
+ const trx_t* trx) /*!< in: transaction */
{
/* be sure to adjust TRX_QUE_STATE_STR_MAX_LEN if you change this */
switch (trx->que_state) {
@@ -104,14 +105,14 @@ trx_get_que_state_str(
}
}
-/**************************************************************************
-Determine if a transaction is a dictionary operation. */
+/**********************************************************************//**
+Determine if a transaction is a dictionary operation.
+@return dictionary operation mode */
UNIV_INLINE
enum trx_dict_op
trx_get_dict_operation(
/*===================*/
- /* out: dictionary operation mode */
- const trx_t* trx) /* in: transaction */
+ const trx_t* trx) /*!< in: transaction */
{
enum trx_dict_op op = (enum trx_dict_op) trx->dict_operation;
@@ -126,14 +127,14 @@ trx_get_dict_operation(
#endif /* UNIV_DEBUG */
return((enum trx_dict_op) UNIV_EXPECT(op, TRX_DICT_OP_NONE));
}
-/**************************************************************************
+/**********************************************************************//**
Flag a transaction a dictionary operation. */
UNIV_INLINE
void
trx_set_dict_operation(
/*===================*/
- trx_t* trx, /* in/out: transaction */
- enum trx_dict_op op) /* in: operation, not
+ trx_t* trx, /*!< in/out: transaction */
+ enum trx_dict_op op) /*!< in: operation, not
TRX_DICT_OP_NONE */
{
#ifdef UNIV_DEBUG
diff --git a/storage/xtradb/include/trx0types.h b/storage/xtradb/include/trx0types.h
index 896f4e8c0a2..08cc9622d02 100644
--- a/storage/xtradb/include/trx0types.h
+++ b/storage/xtradb/include/trx0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0types.h
Transaction system global type definitions
Created 3/26/1996 Heikki Tuuri
@@ -27,52 +28,81 @@ Created 3/26/1996 Heikki Tuuri
#include "ut0byte.h"
-/* prepare trx_t::id for being printed via printf(3) */
+/** prepare trx_t::id for being printed via printf(3) */
#define TRX_ID_PREP_PRINTF(id) (ullint) ut_conv_dulint_to_longlong(id)
-/* printf(3) format used for printing TRX_ID_PRINTF_PREP() */
+/** printf(3) format used for printing TRX_ID_PRINTF_PREP() */
#define TRX_ID_FMT "%llX"
-/* maximum length that a formatted trx_t::id could take, not including
-the terminating '\0'. */
+/** maximum length that a formatted trx_t::id could take, not including
+the terminating NUL character. */
#define TRX_ID_MAX_LEN 17
-/* Memory objects */
+/** Memory objects */
+/* @{ */
+/** Transaction */
typedef struct trx_struct trx_t;
+/** Transaction system */
typedef struct trx_sys_struct trx_sys_t;
+/** Doublewrite information */
typedef struct trx_doublewrite_struct trx_doublewrite_t;
+/** Signal */
typedef struct trx_sig_struct trx_sig_t;
+/** Rollback segment */
typedef struct trx_rseg_struct trx_rseg_t;
+/** Transaction undo log */
typedef struct trx_undo_struct trx_undo_t;
+/** Array of undo numbers of undo records being rolled back or purged */
typedef struct trx_undo_arr_struct trx_undo_arr_t;
+/** A cell of trx_undo_arr_t */
typedef struct trx_undo_inf_struct trx_undo_inf_t;
+/** The control structure used in the purge operation */
typedef struct trx_purge_struct trx_purge_t;
+/** Rollback command node in a query graph */
typedef struct roll_node_struct roll_node_t;
+/** Commit command node in a query graph */
typedef struct commit_node_struct commit_node_t;
+/** SAVEPOINT command node in a query graph */
typedef struct trx_named_savept_struct trx_named_savept_t;
+/* @} */
-/* Rollback contexts */
+/** Rollback contexts */
enum trx_rb_ctx {
- RB_NONE = 0, /* no rollback */
- RB_NORMAL, /* normal rollback */
- RB_RECOVERY, /* rolling back an incomplete transaction,
+ RB_NONE = 0, /*!< no rollback */
+ RB_NORMAL, /*!< normal rollback */
+ RB_RECOVERY, /*!< rolling back an incomplete transaction,
in crash recovery */
};
-/* Transaction savepoint */
+/** Transaction identifier (DB_TRX_ID, DATA_TRX_ID) */
+typedef dulint trx_id_t;
+/** Rollback pointer (DB_ROLL_PTR, DATA_ROLL_PTR) */
+typedef dulint roll_ptr_t;
+/** Undo number */
+typedef dulint undo_no_t;
+
+/** Transaction savepoint */
typedef struct trx_savept_struct trx_savept_t;
+/** Transaction savepoint */
struct trx_savept_struct{
- dulint least_undo_no; /* least undo number to undo */
+ undo_no_t least_undo_no; /*!< least undo number to undo */
};
-/* File objects */
+/** File objects */
+/* @{ */
+/** Transaction system header */
typedef byte trx_sysf_t;
+/** Rollback segment header */
typedef byte trx_rsegf_t;
+/** Undo segment header */
typedef byte trx_usegf_t;
+/** Undo log header */
typedef byte trx_ulogf_t;
+/** Undo log page header */
typedef byte trx_upagef_t;
-/* Undo log record */
+/** Undo log record */
typedef byte trx_undo_rec_t;
+/* @} */
#endif
diff --git a/storage/xtradb/include/trx0undo.h b/storage/xtradb/include/trx0undo.h
index 7f7408931da..4db10eaa92e 100644
--- a/storage/xtradb/include/trx0undo.h
+++ b/storage/xtradb/include/trx0undo.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0undo.h
Transaction undo log
Created 3/26/1996 Heikki Tuuri
@@ -32,37 +33,40 @@ Created 3/26/1996 Heikki Tuuri
#include "page0types.h"
#include "trx0xa.h"
-/***************************************************************************
-Builds a roll pointer dulint. */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
+Builds a roll pointer.
+@return roll pointer */
UNIV_INLINE
-dulint
+roll_ptr_t
trx_undo_build_roll_ptr(
/*====================*/
- /* out: roll pointer */
- ibool is_insert, /* in: TRUE if insert undo log */
- ulint rseg_id, /* in: rollback segment id */
- ulint page_no, /* in: page number */
- ulint offset); /* in: offset of the undo entry within page */
-/***************************************************************************
-Decodes a roll pointer dulint. */
+ ibool is_insert, /*!< in: TRUE if insert undo log */
+ ulint rseg_id, /*!< in: rollback segment id */
+ ulint page_no, /*!< in: page number */
+ ulint offset); /*!< in: offset of the undo entry within page */
+/***********************************************************************//**
+Decodes a roll pointer. */
UNIV_INLINE
void
trx_undo_decode_roll_ptr(
/*=====================*/
- dulint roll_ptr, /* in: roll pointer */
- ibool* is_insert, /* out: TRUE if insert undo log */
- ulint* rseg_id, /* out: rollback segment id */
- ulint* page_no, /* out: page number */
- ulint* offset); /* out: offset of the undo entry within page */
-/***************************************************************************
-Returns TRUE if the roll pointer is of the insert type. */
+ roll_ptr_t roll_ptr, /*!< in: roll pointer */
+ ibool* is_insert, /*!< out: TRUE if insert undo log */
+ ulint* rseg_id, /*!< out: rollback segment id */
+ ulint* page_no, /*!< out: page number */
+ ulint* offset); /*!< out: offset of the undo
+ entry within page */
+/***********************************************************************//**
+Returns TRUE if the roll pointer is of the insert type.
+@return TRUE if insert undo log */
UNIV_INLINE
ibool
trx_undo_roll_ptr_is_insert(
/*========================*/
- /* out: TRUE if insert undo log */
- dulint roll_ptr); /* in: roll pointer */
-/*********************************************************************
+ roll_ptr_t roll_ptr); /*!< in: roll pointer */
+#endif /* !UNIV_HOTBACKUP */
+/*****************************************************************//**
Writes a roll ptr to an index page. In case that the size changes in
some future version, this function should be used instead of
mach_write_... */
@@ -70,214 +74,210 @@ UNIV_INLINE
void
trx_write_roll_ptr(
/*===============*/
- byte* ptr, /* in: pointer to memory where written */
- dulint roll_ptr); /* in: roll ptr */
-/*********************************************************************
+ byte* ptr, /*!< in: pointer to memory where
+ written */
+ roll_ptr_t roll_ptr); /*!< in: roll ptr */
+/*****************************************************************//**
Reads a roll ptr from an index page. In case that the roll ptr size
changes in some future version, this function should be used instead of
-mach_read_... */
+mach_read_...
+@return roll ptr */
UNIV_INLINE
-dulint
+roll_ptr_t
trx_read_roll_ptr(
/*==============*/
- /* out: roll ptr */
- const byte* ptr); /* in: pointer to memory from where to read */
-/**********************************************************************
-Gets an undo log page and x-latches it. */
+ const byte* ptr); /*!< in: pointer to memory from where to read */
+#ifndef UNIV_HOTBACKUP
+/******************************************************************//**
+Gets an undo log page and x-latches it.
+@return pointer to page x-latched */
UNIV_INLINE
page_t*
trx_undo_page_get(
/*==============*/
- /* out: pointer to page x-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- mtr_t* mtr); /* in: mtr */
-/**********************************************************************
-Gets an undo log page and s-latches it. */
+ ulint page_no, /*!< in: page number */
+ mtr_t* mtr); /*!< in: mtr */
+/******************************************************************//**
+Gets an undo log page and s-latches it.
+@return pointer to page s-latched */
UNIV_INLINE
page_t*
trx_undo_page_get_s_latched(
/*========================*/
- /* out: pointer to page s-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- mtr_t* mtr); /* in: mtr */
-/**********************************************************************
+ ulint page_no, /*!< in: page number */
+ mtr_t* mtr); /*!< in: mtr */
+/******************************************************************//**
Returns the previous undo record on the page in the specified log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_prev_rec(
/*=======================*/
- /* out: pointer to record, NULL if none */
- trx_undo_rec_t* rec, /* in: undo log record */
- ulint page_no,/* in: undo log header page number */
- ulint offset);/* in: undo log header offset on page */
-/**********************************************************************
+ trx_undo_rec_t* rec, /*!< in: undo log record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset);/*!< in: undo log header offset on page */
+/******************************************************************//**
Returns the next undo log record on the page in the specified log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_next_rec(
/*=======================*/
- /* out: pointer to record, NULL if none */
- trx_undo_rec_t* rec, /* in: undo log record */
- ulint page_no,/* in: undo log header page number */
- ulint offset);/* in: undo log header offset on page */
-/**********************************************************************
+ trx_undo_rec_t* rec, /*!< in: undo log record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset);/*!< in: undo log header offset on page */
+/******************************************************************//**
Returns the last undo record on the page in the specified undo log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_last_rec(
/*=======================*/
- /* out: pointer to record, NULL if none */
- page_t* undo_page,/* in: undo log page */
- ulint page_no,/* in: undo log header page number */
- ulint offset); /* in: undo log header offset on page */
-/**********************************************************************
+ page_t* undo_page,/*!< in: undo log page */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset); /*!< in: undo log header offset on page */
+/******************************************************************//**
Returns the first undo record on the page in the specified undo log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_first_rec(
/*========================*/
- /* out: pointer to record, NULL if none */
- page_t* undo_page,/* in: undo log page */
- ulint page_no,/* in: undo log header page number */
- ulint offset);/* in: undo log header offset on page */
-/***************************************************************************
-Gets the previous record in an undo log. */
+ page_t* undo_page,/*!< in: undo log page */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset);/*!< in: undo log header offset on page */
+/***********************************************************************//**
+Gets the previous record in an undo log.
+@return undo log record, the page s-latched, NULL if none */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_prev_rec(
/*==================*/
- /* out: undo log record, the page s-latched,
- NULL if none */
- trx_undo_rec_t* rec, /* in: undo record */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- mtr_t* mtr); /* in: mtr */
-/***************************************************************************
-Gets the next record in an undo log. */
+ trx_undo_rec_t* rec, /*!< in: undo record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ mtr_t* mtr); /*!< in: mtr */
+/***********************************************************************//**
+Gets the next record in an undo log.
+@return undo log record, the page s-latched, NULL if none */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_next_rec(
/*==================*/
- /* out: undo log record, the page s-latched,
- NULL if none */
- trx_undo_rec_t* rec, /* in: undo record */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- mtr_t* mtr); /* in: mtr */
-/***************************************************************************
-Gets the first record in an undo log. */
+ trx_undo_rec_t* rec, /*!< in: undo record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ mtr_t* mtr); /*!< in: mtr */
+/***********************************************************************//**
+Gets the first record in an undo log.
+@return undo log record, the page latched, NULL if none */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_first_rec(
/*===================*/
- /* out: undo log record, the page latched, NULL if
- none */
- ulint space, /* in: undo log header space */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: undo log header space */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- ulint mode, /* in: latching mode: RW_S_LATCH or RW_X_LATCH */
- mtr_t* mtr); /* in: mtr */
-/************************************************************************
-Tries to add a page to the undo log segment where the undo log is placed. */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ ulint mode, /*!< in: latching mode: RW_S_LATCH or RW_X_LATCH */
+ mtr_t* mtr); /*!< in: mtr */
+/********************************************************************//**
+Tries to add a page to the undo log segment where the undo log is placed.
+@return page number if success, else FIL_NULL */
UNIV_INTERN
ulint
trx_undo_add_page(
/*==============*/
- /* out: page number if success, else
- FIL_NULL */
- trx_t* trx, /* in: transaction */
- trx_undo_t* undo, /* in: undo log memory object */
- mtr_t* mtr); /* in: mtr which does not have a latch to any
+ trx_t* trx, /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log memory object */
+ mtr_t* mtr); /*!< in: mtr which does not have a latch to any
undo log page; the caller must have reserved
the rollback segment mutex */
-/***************************************************************************
+/***********************************************************************//**
Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
trx_undo_truncate_end(
/*==================*/
- trx_t* trx, /* in: transaction whose undo log it is */
- trx_undo_t* undo, /* in: undo log */
- dulint limit); /* in: all undo records with undo number
+ trx_t* trx, /*!< in: transaction whose undo log it is */
+ trx_undo_t* undo, /*!< in: undo log */
+ undo_no_t limit); /*!< in: all undo records with undo number
>= this value should be truncated */
-/***************************************************************************
+/***********************************************************************//**
Truncates an undo log from the start. This function is used during a purge
operation. */
UNIV_INTERN
void
trx_undo_truncate_start(
/*====================*/
- trx_rseg_t* rseg, /* in: rollback segment */
- ulint space, /* in: space id of the log */
- ulint hdr_page_no, /* in: header page number */
- ulint hdr_offset, /* in: header offset on the page */
- dulint limit); /* in: all undo pages with undo numbers <
- this value should be truncated; NOTE that
- the function only frees whole pages; the
- header page is not freed, but emptied, if
- all the records there are < limit */
-/************************************************************************
+ trx_rseg_t* rseg, /*!< in: rollback segment */
+ ulint space, /*!< in: space id of the log */
+ ulint hdr_page_no, /*!< in: header page number */
+ ulint hdr_offset, /*!< in: header offset on the page */
+ undo_no_t limit); /*!< in: all undo pages with
+ undo numbers < this value
+ should be truncated; NOTE that
+ the function only frees whole
+ pages; the header page is not
+ freed, but emptied, if all the
+ records there are < limit */
+/********************************************************************//**
Initializes the undo log lists for a rollback segment memory copy.
This function is only called when the database is started or a new
-rollback segment created. */
+rollback segment created.
+@return the combined size of undo log segments in pages */
UNIV_INTERN
ulint
trx_undo_lists_init(
/*================*/
- /* out: the combined size of undo log segments
- in pages */
- trx_rseg_t* rseg); /* in: rollback segment memory object */
-/**************************************************************************
+ trx_rseg_t* rseg); /*!< in: rollback segment memory object */
+/**********************************************************************//**
Assigns an undo log for a transaction. A new undo log is created or a cached
-undo log reused. */
+undo log reused.
+@return DB_SUCCESS if undo log assign successful, possible error codes
+are: DB_TOO_MANY_CONCURRENT_TRXS DB_OUT_OF_FILE_SPACE
+DB_OUT_OF_MEMORY */
UNIV_INTERN
ulint
trx_undo_assign_undo(
/*=================*/
- /* out: DB_SUCCESS if undo log assign
- successful, possible error codes are:
- DB_TOO_MANY_CONCURRENT_TRXS
- DB_OUT_OF_FILE_SPACE DB_OUT_OF_MEMORY*/
- trx_t* trx, /* in: transaction */
- ulint type); /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */
-/**********************************************************************
-Sets the state of the undo log segment at a transaction finish. */
+ trx_t* trx, /*!< in: transaction */
+ ulint type); /*!< in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */
+/******************************************************************//**
+Sets the state of the undo log segment at a transaction finish.
+@return undo log segment header page, x-latched */
UNIV_INTERN
page_t*
trx_undo_set_state_at_finish(
/*=========================*/
- /* out: undo log segment header page,
- x-latched */
- trx_rseg_t* rseg, /* in: rollback segment memory object */
- trx_t* trx, /* in: transaction */
- trx_undo_t* undo, /* in: undo log memory copy */
- mtr_t* mtr); /* in: mtr */
-/**********************************************************************
-Sets the state of the undo log segment at a transaction prepare. */
+ trx_rseg_t* rseg, /*!< in: rollback segment memory object */
+ trx_t* trx, /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log memory copy */
+ mtr_t* mtr); /*!< in: mtr */
+/******************************************************************//**
+Sets the state of the undo log segment at a transaction prepare.
+@return undo log segment header page, x-latched */
UNIV_INTERN
page_t*
trx_undo_set_state_at_prepare(
/*==========================*/
- /* out: undo log segment header page,
- x-latched */
- trx_t* trx, /* in: transaction */
- trx_undo_t* undo, /* in: undo log memory copy */
- mtr_t* mtr); /* in: mtr */
+ trx_t* trx, /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log memory copy */
+ mtr_t* mtr); /*!< in: mtr */
-/**************************************************************************
+/**********************************************************************//**
Adds the update undo log header as the first in the history list, and
frees the memory object, or puts it to the list of cached update undo log
segments. */
@@ -285,11 +285,11 @@ UNIV_INTERN
void
trx_undo_update_cleanup(
/*====================*/
- trx_t* trx, /* in: trx owning the update undo log */
- page_t* undo_page, /* in: update undo log header page,
+ trx_t* trx, /*!< in: trx owning the update undo log */
+ page_t* undo_page, /*!< in: update undo log header page,
x-latched */
- mtr_t* mtr); /* in: mtr */
-/**********************************************************************
+ mtr_t* mtr); /*!< in: mtr */
+/******************************************************************//**
Frees or caches an insert undo log after a transaction commit or rollback.
Knowledge of inserts is not needed after a commit or rollback, therefore
the data can be discarded. */
@@ -297,41 +297,42 @@ UNIV_INTERN
void
trx_undo_insert_cleanup(
/*====================*/
- trx_t* trx); /* in: transaction handle */
-/***************************************************************
-Parses the redo log entry of an undo log page initialization. */
+ trx_t* trx); /*!< in: transaction handle */
+#endif /* !UNIV_HOTBACKUP */
+/***********************************************************//**
+Parses the redo log entry of an undo log page initialization.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_page_init(
/*=====================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
-/***************************************************************
-Parses the redo log entry of an undo log page header create or reuse. */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+/***********************************************************//**
+Parses the redo log entry of an undo log page header create or reuse.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_page_header(
/*=======================*/
- /* out: end of log record or NULL */
- ulint type, /* in: MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
-/***************************************************************
-Parses the redo log entry of an undo log page header discard. */
+ ulint type, /*!< in: MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
+/***********************************************************//**
+Parses the redo log entry of an undo log page header discard.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_discard_latest(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr); /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr); /*!< in: mtr or NULL */
/* Types of an undo log segment */
#define TRX_UNDO_INSERT 1 /* contains undo entries for inserts */
@@ -350,18 +351,19 @@ trx_undo_parse_discard_latest(
#define TRX_UNDO_PREPARED 5 /* contains an undo log of an
prepared transaction */
-/* Transaction undo log memory object; this is protected by the undo_mutex
+#ifndef UNIV_HOTBACKUP
+/** Transaction undo log memory object; this is protected by the undo_mutex
in the corresponding transaction object */
struct trx_undo_struct{
/*-----------------------------*/
- ulint id; /* undo log slot number within the
+ ulint id; /*!< undo log slot number within the
rollback segment */
- ulint type; /* TRX_UNDO_INSERT or
+ ulint type; /*!< TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
- ulint state; /* state of the corresponding undo log
+ ulint state; /*!< state of the corresponding undo log
segment */
- ibool del_marks; /* relevant only in an update undo log:
+ ibool del_marks; /*!< relevant only in an update undo log:
this is TRUE if the transaction may
have delete marked records, because of
a delete of a row or an update of an
@@ -369,67 +371,72 @@ struct trx_undo_struct{
necessary; also TRUE if the transaction
has updated an externally stored
field */
- dulint trx_id; /* id of the trx assigned to the undo
+ trx_id_t trx_id; /*!< id of the trx assigned to the undo
log */
- XID xid; /* X/Open XA transaction
+ XID xid; /*!< X/Open XA transaction
identification */
- ibool dict_operation; /* TRUE if a dict operation trx */
- dulint table_id; /* if a dict operation, then the table
+ ibool dict_operation; /*!< TRUE if a dict operation trx */
+ dulint table_id; /*!< if a dict operation, then the table
id */
- trx_rseg_t* rseg; /* rseg where the undo log belongs */
+ trx_rseg_t* rseg; /*!< rseg where the undo log belongs */
/*-----------------------------*/
- ulint space; /* space id where the undo log
+ ulint space; /*!< space id where the undo log
placed */
- ulint zip_size; /* in: compressed page size of space
+ ulint zip_size; /*!< compressed page size of space
in bytes, or 0 for uncompressed */
- ulint hdr_page_no; /* page number of the header page in
+ ulint hdr_page_no; /*!< page number of the header page in
the undo log */
- ulint hdr_offset; /* header offset of the undo log on the
+ ulint hdr_offset; /*!< header offset of the undo log on the
page */
- ulint last_page_no; /* page number of the last page in the
+ ulint last_page_no; /*!< page number of the last page in the
undo log; this may differ from
top_page_no during a rollback */
- ulint size; /* current size in pages */
+ ulint size; /*!< current size in pages */
/*-----------------------------*/
- ulint empty; /* TRUE if the stack of undo log
+ ulint empty; /*!< TRUE if the stack of undo log
records is currently empty */
- ulint top_page_no; /* page number where the latest undo
+ ulint top_page_no; /*!< page number where the latest undo
log record was catenated; during
rollback the page from which the latest
undo record was chosen */
- ulint top_offset; /* offset of the latest undo record,
+ ulint top_offset; /*!< offset of the latest undo record,
i.e., the topmost element in the undo
log if we think of it as a stack */
- dulint top_undo_no; /* undo number of the latest record */
- buf_block_t* guess_block; /* guess for the buffer block where
+ undo_no_t top_undo_no; /*!< undo number of the latest record */
+ buf_block_t* guess_block; /*!< guess for the buffer block where
the top page might reside */
/*-----------------------------*/
UT_LIST_NODE_T(trx_undo_t) undo_list;
- /* undo log objects in the rollback
+ /*!< undo log objects in the rollback
segment are chained into lists */
};
+#endif /* !UNIV_HOTBACKUP */
-/* The offset of the undo log page header on pages of the undo log */
+/** The offset of the undo log page header on pages of the undo log */
#define TRX_UNDO_PAGE_HDR FSEG_PAGE_DATA
/*-------------------------------------------------------------*/
-/* Transaction undo log page header offsets */
-#define TRX_UNDO_PAGE_TYPE 0 /* TRX_UNDO_INSERT or
+/** Transaction undo log page header offsets */
+/* @{ */
+#define TRX_UNDO_PAGE_TYPE 0 /*!< TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
-#define TRX_UNDO_PAGE_START 2 /* Byte offset where the undo log
+#define TRX_UNDO_PAGE_START 2 /*!< Byte offset where the undo log
records for the LATEST transaction
start on this page (remember that
in an update undo log, the first page
can contain several undo logs) */
-#define TRX_UNDO_PAGE_FREE 4 /* On each page of the undo log this
+#define TRX_UNDO_PAGE_FREE 4 /*!< On each page of the undo log this
field contains the byte offset of the
first free byte on the page */
-#define TRX_UNDO_PAGE_NODE 6 /* The file list node in the chain
+#define TRX_UNDO_PAGE_NODE 6 /*!< The file list node in the chain
of undo log pages */
/*-------------------------------------------------------------*/
#define TRX_UNDO_PAGE_HDR_SIZE (6 + FLST_NODE_SIZE)
+ /*!< Size of the transaction undo
+ log page header, in bytes */
+/* @} */
-/* An update undo segment with just one page can be reused if it has
-< this number bytes used; we must leave space at least for one new undo
+/** An update undo segment with just one page can be reused if it has
+at most this many bytes used; we must leave space at least for one new undo
log header on the page */
#define TRX_UNDO_PAGE_REUSE_LIMIT (3 * UNIV_PAGE_SIZE / 4)
@@ -443,62 +450,67 @@ allowed to have zero undo records, but if the segment extends to several
pages, then all the rest of the pages must contain at least one undo log
record. */
-/* The offset of the undo log segment header on the first page of the undo
+/** The offset of the undo log segment header on the first page of the undo
log segment */
#define TRX_UNDO_SEG_HDR (TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE)
+/** Undo log segment header */
+/* @{ */
/*-------------------------------------------------------------*/
-#define TRX_UNDO_STATE 0 /* TRX_UNDO_ACTIVE, ... */
-#define TRX_UNDO_LAST_LOG 2 /* Offset of the last undo log header
+#define TRX_UNDO_STATE 0 /*!< TRX_UNDO_ACTIVE, ... */
+#define TRX_UNDO_LAST_LOG 2 /*!< Offset of the last undo log header
on the segment header page, 0 if
none */
-#define TRX_UNDO_FSEG_HEADER 4 /* Header for the file segment which
+#define TRX_UNDO_FSEG_HEADER 4 /*!< Header for the file segment which
the undo log segment occupies */
#define TRX_UNDO_PAGE_LIST (4 + FSEG_HEADER_SIZE)
- /* Base node for the list of pages in
+ /*!< Base node for the list of pages in
the undo log segment; defined only on
the undo log segment's first page */
/*-------------------------------------------------------------*/
-/* Size of the undo log segment header */
+/** Size of the undo log segment header */
#define TRX_UNDO_SEG_HDR_SIZE (4 + FSEG_HEADER_SIZE + FLST_BASE_NODE_SIZE)
+/* @} */
-/* The undo log header. There can be several undo log headers on the first
+/** The undo log header. There can be several undo log headers on the first
page of an update undo log segment. */
+/* @{ */
/*-------------------------------------------------------------*/
-#define TRX_UNDO_TRX_ID 0 /* Transaction id */
-#define TRX_UNDO_TRX_NO 8 /* Transaction number of the
+#define TRX_UNDO_TRX_ID 0 /*!< Transaction id */
+#define TRX_UNDO_TRX_NO 8 /*!< Transaction number of the
transaction; defined only if the log
is in a history list */
-#define TRX_UNDO_DEL_MARKS 16 /* Defined only in an update undo
+#define TRX_UNDO_DEL_MARKS 16 /*!< Defined only in an update undo
log: TRUE if the transaction may have
done delete markings of records, and
thus purge is necessary */
-#define TRX_UNDO_LOG_START 18 /* Offset of the first undo log record
+#define TRX_UNDO_LOG_START 18 /*!< Offset of the first undo log record
of this log on the header page; purge
may remove undo log record from the
log start, and therefore this is not
necessarily the same as this log
header end offset */
-#define TRX_UNDO_XID_EXISTS 20 /* TRUE if undo log header includes
+#define TRX_UNDO_XID_EXISTS 20 /*!< TRUE if undo log header includes
X/Open XA transaction identification
XID */
-#define TRX_UNDO_DICT_TRANS 21 /* TRUE if the transaction is a table
+#define TRX_UNDO_DICT_TRANS 21 /*!< TRUE if the transaction is a table
create, index create, or drop
transaction: in recovery
the transaction cannot be rolled back
in the usual way: a 'rollback' rather
means dropping the created or dropped
table, if it still exists */
-#define TRX_UNDO_TABLE_ID 22 /* Id of the table if the preceding
+#define TRX_UNDO_TABLE_ID 22 /*!< Id of the table if the preceding
field is TRUE */
-#define TRX_UNDO_NEXT_LOG 30 /* Offset of the next undo log header
+#define TRX_UNDO_NEXT_LOG 30 /*!< Offset of the next undo log header
on this page, 0 if none */
-#define TRX_UNDO_PREV_LOG 32 /* Offset of the previous undo log
+#define TRX_UNDO_PREV_LOG 32 /*!< Offset of the previous undo log
header on this page, 0 if none */
-#define TRX_UNDO_HISTORY_NODE 34 /* If the log is put to the history
+#define TRX_UNDO_HISTORY_NODE 34 /*!< If the log is put to the history
list, the file list node is here */
/*-------------------------------------------------------------*/
+/** Size of the undo log header without XID information */
#define TRX_UNDO_LOG_OLD_HDR_SIZE (34 + FLST_NODE_SIZE)
/* Note: the writing of the undo log old header is coded by a log record
@@ -509,15 +521,21 @@ is not needed by the user. The XID wastes about 150 bytes of space in every
undo log. In the history list we may have millions of undo logs, which means
quite a large overhead. */
-/* X/Open XA Transaction Identification (XID) */
-
+/** X/Open XA Transaction Identification (XID) */
+/* @{ */
+/** xid_t::formatID */
#define TRX_UNDO_XA_FORMAT (TRX_UNDO_LOG_OLD_HDR_SIZE)
+/** xid_t::gtrid_length */
#define TRX_UNDO_XA_TRID_LEN (TRX_UNDO_XA_FORMAT + 4)
+/** xid_t::bqual_length */
#define TRX_UNDO_XA_BQUAL_LEN (TRX_UNDO_XA_TRID_LEN + 4)
+/** Distributed transaction identifier data */
#define TRX_UNDO_XA_XID (TRX_UNDO_XA_BQUAL_LEN + 4)
/*--------------------------------------------------------------*/
#define TRX_UNDO_LOG_XA_HDR_SIZE (TRX_UNDO_XA_XID + XIDDATASIZE)
- /* Total size of the header with the XA XID */
+ /*!< Total size of the undo log header
+ with the XA XID */
+/* @} */
#ifndef UNIV_NONINL
#include "trx0undo.ic"
diff --git a/storage/xtradb/include/trx0undo.ic b/storage/xtradb/include/trx0undo.ic
index 0bd8b79414b..2d289b34ef1 100644
--- a/storage/xtradb/include/trx0undo.ic
+++ b/storage/xtradb/include/trx0undo.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/trx0undo.ic
Transaction undo log
Created 3/26/1996 Heikki Tuuri
@@ -25,17 +26,18 @@ Created 3/26/1996 Heikki Tuuri
#include "data0type.h"
#include "page0page.h"
-/***************************************************************************
-Builds a roll pointer dulint. */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
+Builds a roll pointer.
+@return roll pointer */
UNIV_INLINE
-dulint
+roll_ptr_t
trx_undo_build_roll_ptr(
/*====================*/
- /* out: roll pointer */
- ibool is_insert, /* in: TRUE if insert undo log */
- ulint rseg_id, /* in: rollback segment id */
- ulint page_no, /* in: page number */
- ulint offset) /* in: offset of the undo entry within page */
+ ibool is_insert, /*!< in: TRUE if insert undo log */
+ ulint rseg_id, /*!< in: rollback segment id */
+ ulint page_no, /*!< in: page number */
+ ulint offset) /*!< in: offset of the undo entry within page */
{
#if DATA_ROLL_PTR_LEN != 7
# error "DATA_ROLL_PTR_LEN != 7"
@@ -49,17 +51,18 @@ trx_undo_build_roll_ptr(
+ offset));
}
-/***************************************************************************
-Decodes a roll pointer dulint. */
+/***********************************************************************//**
+Decodes a roll pointer. */
UNIV_INLINE
void
trx_undo_decode_roll_ptr(
/*=====================*/
- dulint roll_ptr, /* in: roll pointer */
- ibool* is_insert, /* out: TRUE if insert undo log */
- ulint* rseg_id, /* out: rollback segment id */
- ulint* page_no, /* out: page number */
- ulint* offset) /* out: offset of the undo entry within page */
+ roll_ptr_t roll_ptr, /*!< in: roll pointer */
+ ibool* is_insert, /*!< out: TRUE if insert undo log */
+ ulint* rseg_id, /*!< out: rollback segment id */
+ ulint* page_no, /*!< out: page number */
+ ulint* offset) /*!< out: offset of the undo
+ entry within page */
{
ulint low;
ulint high;
@@ -81,14 +84,14 @@ trx_undo_decode_roll_ptr(
+ (low / 256) / 256;
}
-/***************************************************************************
-Returns TRUE if the roll pointer is of the insert type. */
+/***********************************************************************//**
+Returns TRUE if the roll pointer is of the insert type.
+@return TRUE if insert undo log */
UNIV_INLINE
ibool
trx_undo_roll_ptr_is_insert(
/*========================*/
- /* out: TRUE if insert undo log */
- dulint roll_ptr) /* in: roll pointer */
+ roll_ptr_t roll_ptr) /*!< in: roll pointer */
{
ulint high;
#if DATA_ROLL_PTR_LEN != 7
@@ -101,8 +104,9 @@ trx_undo_roll_ptr_is_insert(
return(high / (256 * 256 * 128));
}
+#endif /* !UNIV_HOTBACKUP */
-/*********************************************************************
+/*****************************************************************//**
Writes a roll ptr to an index page. In case that the size changes in
some future version, this function should be used instead of
mach_write_... */
@@ -110,8 +114,9 @@ UNIV_INLINE
void
trx_write_roll_ptr(
/*===============*/
- byte* ptr, /* in: pointer to memory where written */
- dulint roll_ptr) /* in: roll ptr */
+ byte* ptr, /*!< in: pointer to memory where
+ written */
+ roll_ptr_t roll_ptr) /*!< in: roll ptr */
{
#if DATA_ROLL_PTR_LEN != 7
# error "DATA_ROLL_PTR_LEN != 7"
@@ -119,16 +124,16 @@ trx_write_roll_ptr(
mach_write_to_7(ptr, roll_ptr);
}
-/*********************************************************************
+/*****************************************************************//**
Reads a roll ptr from an index page. In case that the roll ptr size
changes in some future version, this function should be used instead of
-mach_read_... */
+mach_read_...
+@return roll ptr */
UNIV_INLINE
-dulint
+roll_ptr_t
trx_read_roll_ptr(
/*==============*/
- /* out: roll ptr */
- const byte* ptr) /* in: pointer to memory from where to read */
+ const byte* ptr) /*!< in: pointer to memory from where to read */
{
#if DATA_ROLL_PTR_LEN != 7
# error "DATA_ROLL_PTR_LEN != 7"
@@ -136,18 +141,19 @@ trx_read_roll_ptr(
return(mach_read_from_7(ptr));
}
-/**********************************************************************
-Gets an undo log page and x-latches it. */
+#ifndef UNIV_HOTBACKUP
+/******************************************************************//**
+Gets an undo log page and x-latches it.
+@return pointer to page x-latched */
UNIV_INLINE
page_t*
trx_undo_page_get(
/*==============*/
- /* out: pointer to page x-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block = buf_page_get(space, zip_size, page_no,
RW_X_LATCH, mtr);
@@ -156,18 +162,18 @@ trx_undo_page_get(
return(buf_block_get_frame(block));
}
-/**********************************************************************
-Gets an undo log page and s-latches it. */
+/******************************************************************//**
+Gets an undo log page and s-latches it.
+@return pointer to page s-latched */
UNIV_INLINE
page_t*
trx_undo_page_get_s_latched(
/*========================*/
- /* out: pointer to page s-latched */
- ulint space, /* in: space where placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space where placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number */
+ mtr_t* mtr) /*!< in: mtr */
{
buf_block_t* block = buf_page_get(space, zip_size, page_no,
RW_S_LATCH, mtr);
@@ -176,17 +182,17 @@ trx_undo_page_get_s_latched(
return(buf_block_get_frame(block));
}
-/**********************************************************************
+/******************************************************************//**
Returns the start offset of the undo log records of the specified undo
-log on the page. */
+log on the page.
+@return start offset */
UNIV_INLINE
ulint
trx_undo_page_get_start(
/*====================*/
- /* out: start offset */
- page_t* undo_page,/* in: undo log page */
- ulint page_no,/* in: undo log header page number */
- ulint offset) /* in: undo log header offset on page */
+ page_t* undo_page,/*!< in: undo log page */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset) /*!< in: undo log header offset on page */
{
ulint start;
@@ -201,17 +207,17 @@ trx_undo_page_get_start(
return(start);
}
-/**********************************************************************
+/******************************************************************//**
Returns the end offset of the undo log records of the specified undo
-log on the page. */
+log on the page.
+@return end offset */
UNIV_INLINE
ulint
trx_undo_page_get_end(
/*==================*/
- /* out: end offset */
- page_t* undo_page,/* in: undo log page */
- ulint page_no,/* in: undo log header page number */
- ulint offset) /* in: undo log header offset on page */
+ page_t* undo_page,/*!< in: undo log page */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset) /*!< in: undo log header offset on page */
{
trx_ulogf_t* log_hdr;
ulint end;
@@ -234,17 +240,17 @@ trx_undo_page_get_end(
return(end);
}
-/**********************************************************************
+/******************************************************************//**
Returns the previous undo record on the page in the specified log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_prev_rec(
/*=======================*/
- /* out: pointer to record, NULL if none */
- trx_undo_rec_t* rec, /* in: undo log record */
- ulint page_no,/* in: undo log header page number */
- ulint offset) /* in: undo log header offset on page */
+ trx_undo_rec_t* rec, /*!< in: undo log record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset) /*!< in: undo log header offset on page */
{
page_t* undo_page;
ulint start;
@@ -261,17 +267,17 @@ trx_undo_page_get_prev_rec(
return(undo_page + mach_read_from_2(rec - 2));
}
-/**********************************************************************
+/******************************************************************//**
Returns the next undo log record on the page in the specified log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_next_rec(
/*=======================*/
- /* out: pointer to record, NULL if none */
- trx_undo_rec_t* rec, /* in: undo log record */
- ulint page_no,/* in: undo log header page number */
- ulint offset) /* in: undo log header offset on page */
+ trx_undo_rec_t* rec, /*!< in: undo log record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset) /*!< in: undo log header offset on page */
{
page_t* undo_page;
ulint end;
@@ -291,17 +297,17 @@ trx_undo_page_get_next_rec(
return(undo_page + next);
}
-/**********************************************************************
+/******************************************************************//**
Returns the last undo record on the page in the specified undo log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_last_rec(
/*=======================*/
- /* out: pointer to record, NULL if none */
- page_t* undo_page,/* in: undo log page */
- ulint page_no,/* in: undo log header page number */
- ulint offset) /* in: undo log header offset on page */
+ page_t* undo_page,/*!< in: undo log page */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset) /*!< in: undo log header offset on page */
{
ulint start;
ulint end;
@@ -317,17 +323,17 @@ trx_undo_page_get_last_rec(
return(undo_page + mach_read_from_2(undo_page + end - 2));
}
-/**********************************************************************
+/******************************************************************//**
Returns the first undo record on the page in the specified undo log, or
-NULL if none exists. */
+NULL if none exists.
+@return pointer to record, NULL if none */
UNIV_INLINE
trx_undo_rec_t*
trx_undo_page_get_first_rec(
/*========================*/
- /* out: pointer to record, NULL if none */
- page_t* undo_page,/* in: undo log page */
- ulint page_no,/* in: undo log header page number */
- ulint offset) /* in: undo log header offset on page */
+ page_t* undo_page,/*!< in: undo log page */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset) /*!< in: undo log header offset on page */
{
ulint start;
ulint end;
@@ -342,3 +348,4 @@ trx_undo_page_get_first_rec(
return(undo_page + start);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/trx0xa.h b/storage/xtradb/include/trx0xa.h
index 0e040b8d8e5..e0dd8a1af5b 100644
--- a/storage/xtradb/include/trx0xa.h
+++ b/storage/xtradb/include/trx0xa.h
@@ -29,32 +29,41 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef XIDDATASIZE
-#define XIDDATASIZE 128 /* size in bytes */
-#define MAXGTRIDSIZE 64 /* maximum size in bytes of gtrid */
-#define MAXBQUALSIZE 64 /* maximum size in bytes of bqual */
+/** Sizes of transaction identifier */
+#define XIDDATASIZE 128 /*!< maximum size of a transaction
+ identifier, in bytes */
+#define MAXGTRIDSIZE 64 /*!< maximum size in bytes of gtrid */
+#define MAXBQUALSIZE 64 /*!< maximum size in bytes of bqual */
+/** X/Open XA distributed transaction identifier */
struct xid_t {
- long formatID; /* format identifier; -1
+ long formatID; /*!< format identifier; -1
means that the XID is null */
- long gtrid_length; /* value from 1 through 64 */
- long bqual_length; /* value from 1 through 64 */
- char data[XIDDATASIZE];
+ long gtrid_length; /*!< value from 1 through 64 */
+ long bqual_length; /*!< value from 1 through 64 */
+ char data[XIDDATASIZE]; /*!< distributed transaction
+ identifier */
};
+/** X/Open XA distributed transaction identifier */
typedef struct xid_t XID;
#endif
-#define XA_OK 0 /* normal execution */
-#define XAER_ASYNC -2 /* asynchronous operation already
+/** X/Open XA distributed transaction status codes */
+/* @{ */
+#define XA_OK 0 /*!< normal execution */
+#define XAER_ASYNC -2 /*!< asynchronous operation already
outstanding */
-#define XAER_RMERR -3 /* a resource manager error occurred in
- the transaction branch */
-#define XAER_NOTA -4 /* the XID is not valid */
-#define XAER_INVAL -5 /* invalid arguments were given */
-#define XAER_PROTO -6 /* routine invoked in an improper
+#define XAER_RMERR -3 /*!< a resource manager error
+ occurred in the transaction
+ branch */
+#define XAER_NOTA -4 /*!< the XID is not valid */
+#define XAER_INVAL -5 /*!< invalid arguments were given */
+#define XAER_PROTO -6 /*!< routine invoked in an improper
context */
-#define XAER_RMFAIL -7 /* resource manager unavailable */
-#define XAER_DUPID -8 /* the XID already exists */
-#define XAER_OUTSIDE -9 /* resource manager doing work outside
- transaction */
+#define XAER_RMFAIL -7 /*!< resource manager unavailable */
+#define XAER_DUPID -8 /*!< the XID already exists */
+#define XAER_OUTSIDE -9 /*!< resource manager doing
+ work outside transaction */
+/* @} */
#endif /* ifndef XA_H */
/*
* End of xa.h header
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index 3fc12503031..5ccb7c39551 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -2,6 +2,7 @@
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
Copyright (c) 2008, Google Inc.
+Copyright (c) 2009, Sun Microsystems, Inc.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -9,6 +10,12 @@ briefly in the InnoDB documentation. The contributions by Google are
incorporated with their permission, and subject to the conditions contained in
the file COPYING.Google.
+Portions of this file contain modifications contributed and copyrighted by
+Sun Microsystems, Inc. Those modifications are gratefully acknowledged and
+are described briefly in the InnoDB documentation. The contributions by
+Sun Microsystems are incorporated with their permission, and subject to the
+conditions contained in the file COPYING.Sun_Microsystems.
+
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.
@@ -23,7 +30,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***************************************************************************
+/***********************************************************************//**
+@file include/univ.i
Version control for database, common definitions, and include files
Created 1/20/1994 Heikki Tuuri
@@ -32,10 +40,14 @@ Created 1/20/1994 Heikki Tuuri
#ifndef univ_i
#define univ_i
+#ifdef UNIV_HOTBACKUP
+#include "hb_univ.i"
+#endif /* UNIV_HOTBACKUP */
+
#define INNODB_VERSION_MAJOR 1
#define INNODB_VERSION_MINOR 0
-#define INNODB_VERSION_BUGFIX 3
-#define PERCONA_INNODB_VERSION 6a
+#define INNODB_VERSION_BUGFIX 4
+#define PERCONA_INNODB_VERSION 8
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
@@ -56,6 +68,8 @@ component, i.e. we show M.N.P as M.N */
INNODB_VERSION_BUGFIX, \
PERCONA_INNODB_VERSION)
+#define REFMAN "http://dev.mysql.com/doc/refman/5.1/en/"
+
#ifdef MYSQL_DYNAMIC_PLUGIN
/* In the dynamic plugin, redefine some externally visible symbols
in order not to conflict with the symbols of a builtin InnoDB. */
@@ -72,9 +86,10 @@ the virtual method table (vtable) in GCC 3. */
# include <windows.h>
-# if !defined(WIN64) && !defined(_WIN64)
-# define UNIV_CAN_USE_X86_ASSEMBLER
-# endif
+# if defined(HAVE_WINDOWS_ATOMICS)
+/* If atomics are defined we use them in InnoDB mutex implementation */
+# define HAVE_ATOMIC_BUILTINS
+# endif /* HAVE_WINDOWS_ATOMICS */
# ifdef _NT_
# define __NT__
@@ -87,8 +102,10 @@ the virtual method table (vtable) in GCC 3. */
in compiling more Posix-compatible. These headers also define __WIN__
if we are compiling on Windows. */
+#ifndef UNIV_HOTBACKUP
# include <my_global.h>
# include <my_pthread.h>
+#endif /* UNIV_HOTBACKUP */
/* Include <sys/stat.h> to get S_I... macros defined for os0file.c */
# include <sys/stat.h>
@@ -101,24 +118,26 @@ if we are compiling on Windows. */
/* Include the header file generated by GNU autoconf */
# ifndef __WIN__
-# include "config.h"
+#ifndef UNIV_HOTBACKUP
+# include "config.h"
+#endif /* UNIV_HOTBACKUP */
# endif
# ifdef HAVE_SCHED_H
# include <sched.h>
# endif
-/* When compiling for Itanium IA64, undefine the flag below to prevent use
-of the 32-bit x86 assembler in mutex operations. */
-
-# if defined(__WIN__) && !defined(WIN64) && !defined(_WIN64)
-# define UNIV_CAN_USE_X86_ASSEMBLER
-# endif
+# if defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_SOLARIS_ATOMICS) \
+ || defined(HAVE_WINDOWS_ATOMICS)
+/* If atomics are defined we use them in InnoDB mutex implementation */
+# define HAVE_ATOMIC_BUILTINS
+# endif /* (HAVE_GCC_ATOMIC_BUILTINS) || (HAVE_SOLARIS_ATOMICS)
+ || (HAVE_WINDOWS_ATOMICS) */
/* For InnoDB rw_locks to work with atomics we need the thread_id
to be no more than machine word wide. The following enables using
atomics for InnoDB rw_locks where these conditions are met. */
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
+#ifdef HAVE_ATOMIC_BUILTINS
/* if HAVE_ATOMIC_PTHREAD_T is defined at this point that means that
the code from plug.in has defined it and we do not need to include
ut0auxconf.h which would either define HAVE_ATOMIC_PTHREAD_T or will
@@ -131,12 +150,12 @@ from Makefile.in->ut0auxconf.h */
# ifdef HAVE_ATOMIC_PTHREAD_T
# define INNODB_RW_LOCKS_USE_ATOMICS
# endif /* HAVE_ATOMIC_PTHREAD_T */
-#endif /* HAVE_GCC_ATOMIC_BUILTINS */
+#endif /* HAVE_ATOMIC_BUILTINS */
-/* Enable explicit inlining of functions only for compilers known to
-support it. */
+/* We only try to do explicit inlining of functions with gcc and
+Sun Studio */
-# if !defined(__GNUC__) && !defined(__SUNPRO_C)
+# if !defined(__GNUC__) && !(defined(__SUNPRO_C) || defined(__SUNPRO_CC))
# undef UNIV_MUST_NOT_INLINE /* Remove compiler warning */
# define UNIV_MUST_NOT_INLINE
# endif
@@ -234,19 +253,21 @@ by one. */
/* Linkage specifier for non-static InnoDB symbols (variables and functions)
that are only referenced from within InnoDB, not from MySQL */
-#ifdef __WIN__
-# define UNIV_INTERN
-#else
+#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(UNIV_HOTBACKUP)
# define UNIV_INTERN __attribute__((visibility ("hidden")))
+#else
+# define UNIV_INTERN
#endif
#if (!defined(UNIV_DEBUG) && !defined(UNIV_MUST_NOT_INLINE))
/* Definition for inline version */
#ifdef __WIN__
-#define UNIV_INLINE __inline
+# define UNIV_INLINE __inline
+#elif defined(__SUNPRO_CC) || defined(__SUNPRO_C)
+# define UNIV_INLINE static inline
#else
-#define UNIV_INLINE static __inline__
+# define UNIV_INLINE static __inline__
#endif
#else
@@ -323,13 +344,15 @@ typedef long int lint;
#ifdef __WIN__
typedef __int64 ib_int64_t;
typedef unsigned __int64 ib_uint64_t;
-#else
+#elif !defined(UNIV_HOTBACKUP)
/* Note: longlong and ulonglong come from MySQL headers. */
typedef longlong ib_int64_t;
typedef ulonglong ib_uint64_t;
#endif
+#ifndef UNIV_HOTBACKUP
typedef unsigned long long int ullint;
+#endif /* UNIV_HOTBACKUP */
#ifndef __WIN__
#if SIZEOF_LONG != SIZEOF_VOIDP
@@ -387,6 +410,17 @@ it is read. */
/* Minimize cache-miss latency by moving data at addr into a cache before
it is read or written. */
# define UNIV_PREFETCH_RW(addr) __builtin_prefetch(addr, 1, 3)
+#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+# include <sun_prefetch.h>
+#if __SUNPRO_C >= 0x550
+# undef UNIV_INTERN
+# define UNIV_INTERN __hidden
+#endif /* __SUNPRO_C >= 0x550 */
+/* Use sun_prefetch when compile with Sun Studio */
+# define UNIV_EXPECT(expr,value) (expr)
+# define UNIV_LIKELY_NULL(expr) (expr)
+# define UNIV_PREFETCH_R(addr) sun_prefetch_read_many(addr)
+# define UNIV_PREFETCH_RW(addr) sun_prefetch_write_many(addr)
#else
/* Dummy versions of the macros */
# define UNIV_EXPECT(expr,value) (expr)
diff --git a/storage/xtradb/include/usr0sess.h b/storage/xtradb/include/usr0sess.h
index 08c6c70066f..7638a0c69e2 100644
--- a/storage/xtradb/include/usr0sess.h
+++ b/storage/xtradb/include/usr0sess.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/usr0sess.h
Sessions
Created 6/25/1996 Heikki Tuuri
@@ -35,33 +36,33 @@ Created 6/25/1996 Heikki Tuuri
#include "data0data.h"
#include "rem0rec.h"
-/*************************************************************************
-Opens a session. */
+/*********************************************************************//**
+Opens a session.
+@return own: session object */
UNIV_INTERN
sess_t*
sess_open(void);
/*============*/
- /* out, own: session object */
-/*************************************************************************
+/*********************************************************************//**
Closes a session, freeing the memory occupied by it, if it is in a state
-where it should be closed. */
+where it should be closed.
+@return TRUE if closed */
UNIV_INTERN
ibool
sess_try_close(
/*===========*/
- /* out: TRUE if closed */
- sess_t* sess); /* in, own: session object */
+ sess_t* sess); /*!< in, own: session object */
/* The session handle. All fields are protected by the kernel mutex */
struct sess_struct{
- ulint state; /* state of the session */
- trx_t* trx; /* transaction object permanently
+ ulint state; /*!< state of the session */
+ trx_t* trx; /*!< transaction object permanently
assigned for the session: the
transaction instance designated by the
trx id changes, but the memory
structure is preserved */
UT_LIST_BASE_NODE_T(que_t)
- graphs; /* query graphs belonging to this
+ graphs; /*!< query graphs belonging to this
session */
};
diff --git a/storage/xtradb/include/usr0sess.ic b/storage/xtradb/include/usr0sess.ic
index 5eefed382da..35a75d75acc 100644
--- a/storage/xtradb/include/usr0sess.ic
+++ b/storage/xtradb/include/usr0sess.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/usr0sess.ic
Sessions
Created 6/25/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/usr0types.h b/storage/xtradb/include/usr0types.h
index 7f7d12f7bf5..6cc6f015613 100644
--- a/storage/xtradb/include/usr0types.h
+++ b/storage/xtradb/include/usr0types.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file include/usr0types.h
Users and sessions global types
Created 6/25/1996 Heikki Tuuri
diff --git a/storage/xtradb/include/ut0auxconf.h b/storage/xtradb/include/ut0auxconf.h
index fb5fae9b399..88fb26f1863 100644
--- a/storage/xtradb/include/ut0auxconf.h
+++ b/storage/xtradb/include/ut0auxconf.h
@@ -2,7 +2,7 @@
This file is included in univ.i and will cause compilation failure
if not present.
A custom check has been added in the generated
-storage/innobase/Makefile.in that is shipped with with the InnoDB Plugin
+storage/innobase/Makefile.in that is shipped with the InnoDB Plugin
source archive. This check tries to compile a test program and if
successful then adds "#define HAVE_ATOMIC_PTHREAD_T" to this file.
This is a hack that has been developed in order to check for pthread_t
@@ -12,8 +12,3 @@ If by any chance Makefile.in and ./configure are regenerated and thus
the hack from Makefile.in wiped away then the "real" check from plug.in
will take over.
*/
-/* This is temprary fix for http://bugs.mysql.com/43740 */
-/* force to enable */
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
-#define HAVE_ATOMIC_PTHREAD_T
-#endif
diff --git a/storage/xtradb/include/ut0byte.h b/storage/xtradb/include/ut0byte.h
index 24aac1678b3..a2687e62f08 100644
--- a/storage/xtradb/include/ut0byte.h
+++ b/storage/xtradb/include/ut0byte.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/ut0byte.h
Utilities for byte operations
Created 1/20/1994 Heikki Tuuri
@@ -28,163 +29,162 @@ Created 1/20/1994 Heikki Tuuri
#include "univ.i"
-/* Type definition for a 64-bit unsigned integer, which works also
+/** Pair of ulint integers. */
+typedef struct dulint_struct dulint;
+/** Type definition for a 64-bit unsigned integer, which works also
in 32-bit machines. NOTE! Access the fields only with the accessor
functions. This definition appears here only for the compiler to
know the size of a dulint. */
-
-typedef struct dulint_struct dulint;
struct dulint_struct{
- ulint high; /* most significant 32 bits */
- ulint low; /* least significant 32 bits */
+ ulint high; /*!< most significant 32 bits */
+ ulint low; /*!< least significant 32 bits */
};
-/* Zero value for a dulint */
+/** Zero value for a dulint */
extern const dulint ut_dulint_zero;
-/* Maximum value for a dulint */
+/** Maximum value for a dulint */
extern const dulint ut_dulint_max;
-/***********************************************************
-Creates a 64-bit dulint out of two ulints. */
+/*******************************************************//**
+Creates a 64-bit dulint out of two ulints.
+@return created dulint */
UNIV_INLINE
dulint
ut_dulint_create(
/*=============*/
- /* out: created dulint */
- ulint high, /* in: high-order 32 bits */
- ulint low); /* in: low-order 32 bits */
-/***********************************************************
-Gets the high-order 32 bits of a dulint. */
+ ulint high, /*!< in: high-order 32 bits */
+ ulint low); /*!< in: low-order 32 bits */
+/*******************************************************//**
+Gets the high-order 32 bits of a dulint.
+@return 32 bits in ulint */
UNIV_INLINE
ulint
ut_dulint_get_high(
/*===============*/
- /* out: 32 bits in ulint */
- dulint d); /* in: dulint */
-/***********************************************************
-Gets the low-order 32 bits of a dulint. */
+ dulint d); /*!< in: dulint */
+/*******************************************************//**
+Gets the low-order 32 bits of a dulint.
+@return 32 bits in ulint */
UNIV_INLINE
ulint
ut_dulint_get_low(
/*==============*/
- /* out: 32 bits in ulint */
- dulint d); /* in: dulint */
-/***********************************************************
+ dulint d); /*!< in: dulint */
+/*******************************************************//**
Converts a dulint (a struct of 2 ulints) to ib_int64_t, which is a 64-bit
-integer type. */
+integer type.
+@return value in ib_int64_t type */
UNIV_INLINE
ib_int64_t
ut_conv_dulint_to_longlong(
/*=======================*/
- /* out: value in ib_int64_t type */
- dulint d); /* in: dulint */
-/***********************************************************
-Tests if a dulint is zero. */
+ dulint d); /*!< in: dulint */
+/*******************************************************//**
+Tests if a dulint is zero.
+@return TRUE if zero */
UNIV_INLINE
ibool
ut_dulint_is_zero(
/*==============*/
- /* out: TRUE if zero */
- dulint a); /* in: dulint */
-/***********************************************************
-Compares two dulints. */
+ dulint a); /*!< in: dulint */
+/*******************************************************//**
+Compares two dulints.
+@return -1 if a < b, 0 if a == b, 1 if a > b */
UNIV_INLINE
int
ut_dulint_cmp(
/*==========*/
- /* out: -1 if a < b, 0 if a == b,
- 1 if a > b */
- dulint a, /* in: dulint */
- dulint b); /* in: dulint */
-/***********************************************************
-Calculates the max of two dulints. */
+ dulint a, /*!< in: dulint */
+ dulint b); /*!< in: dulint */
+/*******************************************************//**
+Calculates the max of two dulints.
+@return max(a, b) */
UNIV_INLINE
dulint
ut_dulint_get_max(
/*==============*/
- /* out: max(a, b) */
- dulint a, /* in: dulint */
- dulint b); /* in: dulint */
-/***********************************************************
-Calculates the min of two dulints. */
+ dulint a, /*!< in: dulint */
+ dulint b); /*!< in: dulint */
+/*******************************************************//**
+Calculates the min of two dulints.
+@return min(a, b) */
UNIV_INLINE
dulint
ut_dulint_get_min(
/*==============*/
- /* out: min(a, b) */
- dulint a, /* in: dulint */
- dulint b); /* in: dulint */
-/***********************************************************
-Adds a ulint to a dulint. */
+ dulint a, /*!< in: dulint */
+ dulint b); /*!< in: dulint */
+/*******************************************************//**
+Adds a ulint to a dulint.
+@return sum a + b */
UNIV_INLINE
dulint
ut_dulint_add(
/*==========*/
- /* out: sum a + b */
- dulint a, /* in: dulint */
- ulint b); /* in: ulint */
-/***********************************************************
-Subtracts a ulint from a dulint. */
+ dulint a, /*!< in: dulint */
+ ulint b); /*!< in: ulint */
+/*******************************************************//**
+Subtracts a ulint from a dulint.
+@return a - b */
UNIV_INLINE
dulint
ut_dulint_subtract(
/*===============*/
- /* out: a - b */
- dulint a, /* in: dulint */
- ulint b); /* in: ulint, b <= a */
-/***********************************************************
+ dulint a, /*!< in: dulint */
+ ulint b); /*!< in: ulint, b <= a */
+/*******************************************************//**
Subtracts a dulint from another. NOTE that the difference must be positive
-and smaller that 4G. */
+and smaller that 4G.
+@return a - b */
UNIV_INLINE
ulint
ut_dulint_minus(
/*============*/
- /* out: a - b */
- dulint a, /* in: dulint; NOTE a must be >= b and at most
+ dulint a, /*!< in: dulint; NOTE a must be >= b and at most
2 to power 32 - 1 greater */
- dulint b); /* in: dulint */
-/************************************************************
-Rounds a dulint downward to a multiple of a power of 2. */
+ dulint b); /*!< in: dulint */
+/********************************************************//**
+Rounds a dulint downward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
dulint
ut_dulint_align_down(
/*=================*/
- /* out: rounded value */
- dulint n, /* in: number to be rounded */
- ulint align_no); /* in: align by this number which must be a
+ dulint n, /*!< in: number to be rounded */
+ ulint align_no); /*!< in: align by this number which must be a
power of 2 */
-/************************************************************
-Rounds a dulint upward to a multiple of a power of 2. */
+/********************************************************//**
+Rounds a dulint upward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
dulint
ut_dulint_align_up(
/*===============*/
- /* out: rounded value */
- dulint n, /* in: number to be rounded */
- ulint align_no); /* in: align by this number which must be a
+ dulint n, /*!< in: number to be rounded */
+ ulint align_no); /*!< in: align by this number which must be a
power of 2 */
-/************************************************************
-Rounds a dulint downward to a multiple of a power of 2. */
+/********************************************************//**
+Rounds a dulint downward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
ib_uint64_t
ut_uint64_align_down(
/*=================*/
- /* out: rounded value */
- ib_uint64_t n, /* in: number to be rounded */
- ulint align_no); /* in: align by this number
+ ib_uint64_t n, /*!< in: number to be rounded */
+ ulint align_no); /*!< in: align by this number
which must be a power of 2 */
-/************************************************************
-Rounds ib_uint64_t upward to a multiple of a power of 2. */
+/********************************************************//**
+Rounds ib_uint64_t upward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
ib_uint64_t
ut_uint64_align_up(
/*===============*/
- /* out: rounded value */
- ib_uint64_t n, /* in: number to be rounded */
- ulint align_no); /* in: align by this number
+ ib_uint64_t n, /*!< in: number to be rounded */
+ ulint align_no); /*!< in: align by this number
which must be a power of 2 */
-/***********************************************************
+/*******************************************************//**
Increments a dulint variable by 1. */
#define UT_DULINT_INC(D)\
{\
@@ -195,71 +195,73 @@ Increments a dulint variable by 1. */
(D).low = (D).low + 1;\
}\
}
-/***********************************************************
+/*******************************************************//**
Tests if two dulints are equal. */
#define UT_DULINT_EQ(D1, D2) (((D1).low == (D2).low)\
&& ((D1).high == (D2).high))
#ifdef notdefined
-/****************************************************************
+/************************************************************//**
Sort function for dulint arrays. */
UNIV_INTERN
void
-ut_dulint_sort(dulint* arr, dulint* aux_arr, ulint low, ulint high);
-/*===============================================================*/
+ut_dulint_sort(
+/*===========*/
+ dulint* arr, /*!< in/out: array to be sorted */
+ dulint* aux_arr,/*!< in/out: auxiliary array (same size as arr) */
+ ulint low, /*!< in: low bound of sort interval, inclusive */
+ ulint high); /*!< in: high bound of sort interval, noninclusive */
#endif /* notdefined */
-/*************************************************************
-The following function rounds up a pointer to the nearest aligned address. */
+/*********************************************************//**
+The following function rounds up a pointer to the nearest aligned address.
+@return aligned pointer */
UNIV_INLINE
void*
ut_align(
/*=====*/
- /* out: aligned pointer */
- void* ptr, /* in: pointer */
- ulint align_no); /* in: align by this number */
-/*************************************************************
+ void* ptr, /*!< in: pointer */
+ ulint align_no); /*!< in: align by this number */
+/*********************************************************//**
The following function rounds down a pointer to the nearest
-aligned address. */
+aligned address.
+@return aligned pointer */
UNIV_INLINE
void*
ut_align_down(
/*==========*/
- /* out: aligned pointer */
- const void* ptr, /* in: pointer */
- ulint align_no) /* in: align by this number */
+ const void* ptr, /*!< in: pointer */
+ ulint align_no) /*!< in: align by this number */
__attribute__((const));
-/*************************************************************
+/*********************************************************//**
The following function computes the offset of a pointer from the nearest
-aligned address. */
+aligned address.
+@return distance from aligned pointer */
UNIV_INLINE
ulint
ut_align_offset(
/*============*/
- /* out: distance from aligned
- pointer */
- const void* ptr, /* in: pointer */
- ulint align_no) /* in: align by this number */
+ const void* ptr, /*!< in: pointer */
+ ulint align_no) /*!< in: align by this number */
__attribute__((const));
-/*********************************************************************
-Gets the nth bit of a ulint. */
+/*****************************************************************//**
+Gets the nth bit of a ulint.
+@return TRUE if nth bit is 1; 0th bit is defined to be the least significant */
UNIV_INLINE
ibool
ut_bit_get_nth(
/*===========*/
- /* out: TRUE if nth bit is 1; 0th bit is defined to
- be the least significant */
- ulint a, /* in: ulint */
- ulint n); /* in: nth bit requested */
-/*********************************************************************
-Sets the nth bit of a ulint. */
+ ulint a, /*!< in: ulint */
+ ulint n); /*!< in: nth bit requested */
+/*****************************************************************//**
+Sets the nth bit of a ulint.
+@return the ulint with the bit set as requested */
UNIV_INLINE
ulint
ut_bit_set_nth(
/*===========*/
- /* out: the ulint with the bit set as requested */
- ulint a, /* in: ulint */
- ulint n, /* in: nth bit requested */
- ibool val); /* in: value for the bit to set */
+ ulint a, /*!< in: ulint */
+ ulint n, /*!< in: nth bit requested */
+ ibool val); /*!< in: value for the bit to set */
#ifndef UNIV_NONINL
#include "ut0byte.ic"
diff --git a/storage/xtradb/include/ut0byte.ic b/storage/xtradb/include/ut0byte.ic
index 021a3a15009..e3beed65138 100644
--- a/storage/xtradb/include/ut0byte.ic
+++ b/storage/xtradb/include/ut0byte.ic
@@ -16,21 +16,22 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************************
+/**************************************************************//**
+@file include/ut0byte.ic
Utilities for byte operations
Created 5/30/1994 Heikki Tuuri
*******************************************************************/
-/***********************************************************
-Creates a 64-bit dulint out of two ulints. */
+/*******************************************************//**
+Creates a 64-bit dulint out of two ulints.
+@return created dulint */
UNIV_INLINE
dulint
ut_dulint_create(
/*=============*/
- /* out: created dulint */
- ulint high, /* in: high-order 32 bits */
- ulint low) /* in: low-order 32 bits */
+ ulint high, /*!< in: high-order 32 bits */
+ ulint low) /*!< in: low-order 32 bits */
{
dulint res;
@@ -43,52 +44,52 @@ ut_dulint_create(
return(res);
}
-/***********************************************************
-Gets the high-order 32 bits of a dulint. */
+/*******************************************************//**
+Gets the high-order 32 bits of a dulint.
+@return 32 bits in ulint */
UNIV_INLINE
ulint
ut_dulint_get_high(
/*===============*/
- /* out: 32 bits in ulint */
- dulint d) /* in: dulint */
+ dulint d) /*!< in: dulint */
{
return(d.high);
}
-/***********************************************************
-Gets the low-order 32 bits of a dulint. */
+/*******************************************************//**
+Gets the low-order 32 bits of a dulint.
+@return 32 bits in ulint */
UNIV_INLINE
ulint
ut_dulint_get_low(
/*==============*/
- /* out: 32 bits in ulint */
- dulint d) /* in: dulint */
+ dulint d) /*!< in: dulint */
{
return(d.low);
}
-/***********************************************************
+/*******************************************************//**
Converts a dulint (a struct of 2 ulints) to ib_int64_t, which is a 64-bit
-integer type. */
+integer type.
+@return value in ib_int64_t type */
UNIV_INLINE
ib_int64_t
ut_conv_dulint_to_longlong(
/*=======================*/
- /* out: value in ib_int64_t type */
- dulint d) /* in: dulint */
+ dulint d) /*!< in: dulint */
{
return((ib_int64_t)d.low
+ (((ib_int64_t)d.high) << 32));
}
-/***********************************************************
-Tests if a dulint is zero. */
+/*******************************************************//**
+Tests if a dulint is zero.
+@return TRUE if zero */
UNIV_INLINE
ibool
ut_dulint_is_zero(
/*==============*/
- /* out: TRUE if zero */
- dulint a) /* in: dulint */
+ dulint a) /*!< in: dulint */
{
if ((a.low == 0) && (a.high == 0)) {
@@ -98,16 +99,15 @@ ut_dulint_is_zero(
return(FALSE);
}
-/***********************************************************
-Compares two dulints. */
+/*******************************************************//**
+Compares two dulints.
+@return -1 if a < b, 0 if a == b, 1 if a > b */
UNIV_INLINE
int
ut_dulint_cmp(
/*==========*/
- /* out: -1 if a < b, 0 if a == b,
- 1 if a > b */
- dulint a, /* in: dulint */
- dulint b) /* in: dulint */
+ dulint a, /*!< in: dulint */
+ dulint b) /*!< in: dulint */
{
if (a.high > b.high) {
return(1);
@@ -122,15 +122,15 @@ ut_dulint_cmp(
}
}
-/***********************************************************
-Calculates the max of two dulints. */
+/*******************************************************//**
+Calculates the max of two dulints.
+@return max(a, b) */
UNIV_INLINE
dulint
ut_dulint_get_max(
/*==============*/
- /* out: max(a, b) */
- dulint a, /* in: dulint */
- dulint b) /* in: dulint */
+ dulint a, /*!< in: dulint */
+ dulint b) /*!< in: dulint */
{
if (ut_dulint_cmp(a, b) > 0) {
@@ -140,15 +140,15 @@ ut_dulint_get_max(
return(b);
}
-/***********************************************************
-Calculates the min of two dulints. */
+/*******************************************************//**
+Calculates the min of two dulints.
+@return min(a, b) */
UNIV_INLINE
dulint
ut_dulint_get_min(
/*==============*/
- /* out: min(a, b) */
- dulint a, /* in: dulint */
- dulint b) /* in: dulint */
+ dulint a, /*!< in: dulint */
+ dulint b) /*!< in: dulint */
{
if (ut_dulint_cmp(a, b) > 0) {
@@ -158,15 +158,15 @@ ut_dulint_get_min(
return(a);
}
-/***********************************************************
-Adds a ulint to a dulint. */
+/*******************************************************//**
+Adds a ulint to a dulint.
+@return sum a + b */
UNIV_INLINE
dulint
ut_dulint_add(
/*==========*/
- /* out: sum a + b */
- dulint a, /* in: dulint */
- ulint b) /* in: ulint */
+ dulint a, /*!< in: dulint */
+ ulint b) /*!< in: ulint */
{
if (0xFFFFFFFFUL - b >= a.low) {
a.low += b;
@@ -181,15 +181,15 @@ ut_dulint_add(
return(a);
}
-/***********************************************************
-Subtracts a ulint from a dulint. */
+/*******************************************************//**
+Subtracts a ulint from a dulint.
+@return a - b */
UNIV_INLINE
dulint
ut_dulint_subtract(
/*===============*/
- /* out: a - b */
- dulint a, /* in: dulint */
- ulint b) /* in: ulint, b <= a */
+ dulint a, /*!< in: dulint */
+ ulint b) /*!< in: ulint, b <= a */
{
if (a.low >= b) {
a.low -= b;
@@ -208,17 +208,17 @@ ut_dulint_subtract(
return(a);
}
-/***********************************************************
+/*******************************************************//**
Subtracts a dulint from another. NOTE that the difference must be positive
-and smaller that 4G. */
+and smaller that 4G.
+@return a - b */
UNIV_INLINE
ulint
ut_dulint_minus(
/*============*/
- /* out: a - b */
- dulint a, /* in: dulint; NOTE a must be >= b and at most
+ dulint a, /*!< in: dulint; NOTE a must be >= b and at most
2 to power 32 - 1 greater */
- dulint b) /* in: dulint */
+ dulint b) /*!< in: dulint */
{
ulint diff;
@@ -238,15 +238,15 @@ ut_dulint_minus(
return(diff);
}
-/************************************************************
-Rounds a dulint downward to a multiple of a power of 2. */
+/********************************************************//**
+Rounds a dulint downward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
dulint
ut_dulint_align_down(
/*=================*/
- /* out: rounded value */
- dulint n, /* in: number to be rounded */
- ulint align_no) /* in: align by this number which must be a
+ dulint n, /*!< in: number to be rounded */
+ ulint align_no) /*!< in: align by this number which must be a
power of 2 */
{
ulint low, high;
@@ -262,29 +262,29 @@ ut_dulint_align_down(
return(ut_dulint_create(high, low));
}
-/************************************************************
-Rounds a dulint upward to a multiple of a power of 2. */
+/********************************************************//**
+Rounds a dulint upward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
dulint
ut_dulint_align_up(
/*===============*/
- /* out: rounded value */
- dulint n, /* in: number to be rounded */
- ulint align_no) /* in: align by this number which must be a
+ dulint n, /*!< in: number to be rounded */
+ ulint align_no) /*!< in: align by this number which must be a
power of 2 */
{
return(ut_dulint_align_down(ut_dulint_add(n, align_no - 1), align_no));
}
-/************************************************************
-Rounds ib_uint64_t downward to a multiple of a power of 2. */
+/********************************************************//**
+Rounds ib_uint64_t downward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
ib_uint64_t
ut_uint64_align_down(
/*=================*/
- /* out: rounded value */
- ib_uint64_t n, /* in: number to be rounded */
- ulint align_no) /* in: align by this number
+ ib_uint64_t n, /*!< in: number to be rounded */
+ ulint align_no) /*!< in: align by this number
which must be a power of 2 */
{
ut_ad(align_no > 0);
@@ -293,15 +293,15 @@ ut_uint64_align_down(
return(n & ~((ib_uint64_t) align_no - 1));
}
-/************************************************************
-Rounds ib_uint64_t upward to a multiple of a power of 2. */
+/********************************************************//**
+Rounds ib_uint64_t upward to a multiple of a power of 2.
+@return rounded value */
UNIV_INLINE
ib_uint64_t
ut_uint64_align_up(
/*===============*/
- /* out: rounded value */
- ib_uint64_t n, /* in: number to be rounded */
- ulint align_no) /* in: align by this number
+ ib_uint64_t n, /*!< in: number to be rounded */
+ ulint align_no) /*!< in: align by this number
which must be a power of 2 */
{
ib_uint64_t align_1 = (ib_uint64_t) align_no - 1;
@@ -312,15 +312,15 @@ ut_uint64_align_up(
return((n + align_1) & ~align_1);
}
-/*************************************************************
-The following function rounds up a pointer to the nearest aligned address. */
+/*********************************************************//**
+The following function rounds up a pointer to the nearest aligned address.
+@return aligned pointer */
UNIV_INLINE
void*
ut_align(
/*=====*/
- /* out: aligned pointer */
- void* ptr, /* in: pointer */
- ulint align_no) /* in: align by this number */
+ void* ptr, /*!< in: pointer */
+ ulint align_no) /*!< in: align by this number */
{
ut_ad(align_no > 0);
ut_ad(((align_no - 1) & align_no) == 0);
@@ -331,16 +331,16 @@ ut_align(
return((void*)((((ulint)ptr) + align_no - 1) & ~(align_no - 1)));
}
-/*************************************************************
+/*********************************************************//**
The following function rounds down a pointer to the nearest
-aligned address. */
+aligned address.
+@return aligned pointer */
UNIV_INLINE
void*
ut_align_down(
/*==========*/
- /* out: aligned pointer */
- const void* ptr, /* in: pointer */
- ulint align_no) /* in: align by this number */
+ const void* ptr, /*!< in: pointer */
+ ulint align_no) /*!< in: align by this number */
{
ut_ad(align_no > 0);
ut_ad(((align_no - 1) & align_no) == 0);
@@ -351,17 +351,16 @@ ut_align_down(
return((void*)((((ulint)ptr)) & ~(align_no - 1)));
}
-/*************************************************************
+/*********************************************************//**
The following function computes the offset of a pointer from the nearest
-aligned address. */
+aligned address.
+@return distance from aligned pointer */
UNIV_INLINE
ulint
ut_align_offset(
/*============*/
- /* out: distance from
- aligned pointer */
- const void* ptr, /* in: pointer */
- ulint align_no) /* in: align by this number */
+ const void* ptr, /*!< in: pointer */
+ ulint align_no) /*!< in: align by this number */
{
ut_ad(align_no > 0);
ut_ad(((align_no - 1) & align_no) == 0);
@@ -372,16 +371,15 @@ ut_align_offset(
return(((ulint)ptr) & (align_no - 1));
}
-/*********************************************************************
-Gets the nth bit of a ulint. */
+/*****************************************************************//**
+Gets the nth bit of a ulint.
+@return TRUE if nth bit is 1; 0th bit is defined to be the least significant */
UNIV_INLINE
ibool
ut_bit_get_nth(
/*===========*/
- /* out: TRUE if nth bit is 1; 0th bit is defined to
- be the least significant */
- ulint a, /* in: ulint */
- ulint n) /* in: nth bit requested */
+ ulint a, /*!< in: ulint */
+ ulint n) /*!< in: nth bit requested */
{
ut_ad(n < 8 * sizeof(ulint));
#if TRUE != 1
@@ -390,16 +388,16 @@ ut_bit_get_nth(
return(1 & (a >> n));
}
-/*********************************************************************
-Sets the nth bit of a ulint. */
+/*****************************************************************//**
+Sets the nth bit of a ulint.
+@return the ulint with the bit set as requested */
UNIV_INLINE
ulint
ut_bit_set_nth(
/*===========*/
- /* out: the ulint with the bit set as requested */
- ulint a, /* in: ulint */
- ulint n, /* in: nth bit requested */
- ibool val) /* in: value for the bit to set */
+ ulint a, /*!< in: ulint */
+ ulint n, /*!< in: nth bit requested */
+ ibool val) /*!< in: value for the bit to set */
{
ut_ad(n < 8 * sizeof(ulint));
#if TRUE != 1
diff --git a/storage/xtradb/include/ut0dbg.h b/storage/xtradb/include/ut0dbg.h
index a206789fd4c..78b525c38ab 100644
--- a/storage/xtradb/include/ut0dbg.h
+++ b/storage/xtradb/include/ut0dbg.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/*********************************************************************
+/*****************************************************************//**
+@file include/ut0dbg.h
Debug utilities for Innobase
Created 1/30/1994 Heikki Tuuri
@@ -30,26 +31,33 @@ Created 1/30/1994 Heikki Tuuri
#include "os0thread.h"
#if defined(__GNUC__) && (__GNUC__ > 2)
+/** Test if an assertion fails.
+@param EXPR assertion expression
+@return nonzero if EXPR holds, zero if not */
# define UT_DBG_FAIL(EXPR) UNIV_UNLIKELY(!((ulint)(EXPR)))
#else
-extern ulint ut_dbg_zero; /* This is used to eliminate
- compiler warnings */
+/** This is used to eliminate compiler warnings */
+extern ulint ut_dbg_zero;
+/** Test if an assertion fails.
+@param EXPR assertion expression
+@return nonzero if EXPR holds, zero if not */
# define UT_DBG_FAIL(EXPR) !((ulint)(EXPR) + ut_dbg_zero)
#endif
-/*****************************************************************
+/*************************************************************//**
Report a failed assertion. */
UNIV_INTERN
void
ut_dbg_assertion_failed(
/*====================*/
- const char* expr, /* in: the failed assertion */
- const char* file, /* in: source file containing the assertion */
- ulint line); /* in: line number of the assertion */
+ const char* expr, /*!< in: the failed assertion */
+ const char* file, /*!< in: source file containing the assertion */
+ ulint line); /*!< in: line number of the assertion */
#ifdef __NETWARE__
-/* Flag for ignoring further assertion failures.
-On NetWare, have a graceful exit rather than a segfault to avoid abends. */
+/** Flag for ignoring further assertion failures. This is set to TRUE
+when on NetWare there happens an InnoDB assertion failure or other
+fatal error condition that requires an immediate shutdown. */
extern ibool panic_shutdown;
/* Abort the execution. */
void ut_dbg_panic(void);
@@ -64,16 +72,16 @@ void ut_dbg_panic(void);
# endif
# ifndef UT_DBG_USE_ABORT
-/* A null pointer that will be dereferenced to trigger a memory trap */
+/** A null pointer that will be dereferenced to trigger a memory trap */
extern ulint* ut_dbg_null_ptr;
# endif
# if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
-/* Flag for indicating that all threads should stop. This will be set
-by ut_dbg_assertion_failed(). */
+/** If this is set to TRUE by ut_dbg_assertion_failed(), all threads
+will stop at the next ut_a() or ut_ad(). */
extern ibool ut_dbg_stop_threads;
-/*****************************************************************
+/*************************************************************//**
Stop a thread after assertion failure. */
UNIV_INTERN
void
@@ -84,15 +92,15 @@ ut_dbg_stop_thread(
# endif
# ifdef UT_DBG_USE_ABORT
-/* Abort the execution. */
+/** Abort the execution. */
# define UT_DBG_PANIC abort()
-/* Stop threads (null operation) */
+/** Stop threads (null operation) */
# define UT_DBG_STOP do {} while (0)
# else /* UT_DBG_USE_ABORT */
-/* Abort the execution. */
+/** Abort the execution. */
# define UT_DBG_PANIC \
if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL
-/* Stop threads in ut_a(). */
+/** Stop threads in ut_a(). */
# define UT_DBG_STOP do \
if (UNIV_UNLIKELY(ut_dbg_stop_threads)) { \
ut_dbg_stop_thread(__FILE__, (ulint) __LINE__); \
@@ -100,7 +108,8 @@ ut_dbg_stop_thread(
# endif /* UT_DBG_USE_ABORT */
#endif /* __NETWARE__ */
-/* Abort execution if EXPR does not evaluate to nonzero. */
+/** Abort execution if EXPR does not evaluate to nonzero.
+@param EXPR assertion expression that should hold */
#define ut_a(EXPR) do { \
if (UT_DBG_FAIL(EXPR)) { \
ut_dbg_assertion_failed(#EXPR, \
@@ -110,20 +119,26 @@ ut_dbg_stop_thread(
UT_DBG_STOP; \
} while (0)
-/* Abort execution. */
+/** Abort execution. */
#define ut_error do { \
ut_dbg_assertion_failed(0, __FILE__, (ulint) __LINE__); \
UT_DBG_PANIC; \
} while (0)
#ifdef UNIV_DEBUG
+/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
#define ut_ad(EXPR) ut_a(EXPR)
+/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
#define ut_d(EXPR) do {EXPR;} while (0)
#else
+/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
#define ut_ad(EXPR)
+/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
#define ut_d(EXPR)
#endif
+/** Silence warnings about an unused variable by doing a null assignment.
+@param A the unused variable */
#define UT_NOT_USED(A) A = A
#ifdef UNIV_COMPILE_TEST_FUNCS
@@ -132,28 +147,28 @@ ut_dbg_stop_thread(
#include <sys/time.h>
#include <sys/resource.h>
-/* structure used for recording usage statistics */
+/** structure used for recording usage statistics */
typedef struct speedo_struct {
- struct rusage ru;
- struct timeval tv;
+ struct rusage ru; /*!< getrusage() result */
+ struct timeval tv; /*!< gettimeofday() result */
} speedo_t;
-/***********************************************************************
+/*******************************************************************//**
Resets a speedo (records the current time in it). */
UNIV_INTERN
void
speedo_reset(
/*=========*/
- speedo_t* speedo); /* out: speedo */
+ speedo_t* speedo); /*!< out: speedo */
-/***********************************************************************
+/*******************************************************************//**
Shows the time elapsed and usage statistics since the last reset of a
speedo. */
UNIV_INTERN
void
speedo_show(
/*========*/
- const speedo_t* speedo); /* in: speedo */
+ const speedo_t* speedo); /*!< in: speedo */
#endif /* UNIV_COMPILE_TEST_FUNCS */
diff --git a/storage/xtradb/include/ut0list.h b/storage/xtradb/include/ut0list.h
index 034aa400af9..ec67f4e2a0f 100644
--- a/storage/xtradb/include/ut0list.h
+++ b/storage/xtradb/include/ut0list.h
@@ -16,7 +16,14 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file include/ut0list.h
+A double-linked list
+
+Created 4/26/2006 Osku Salerma
+************************************************************************/
+
+/*******************************************************************//**
A double-linked list. This differs from the one in ut0lst.h in that in this
one, each list node contains a pointer to the data, whereas the one in
ut0lst.h uses a strategy where the list pointers are embedded in the data
@@ -45,117 +52,117 @@ typedef struct ib_list_struct ib_list_t;
typedef struct ib_list_node_struct ib_list_node_t;
typedef struct ib_list_helper_struct ib_list_helper_t;
-/********************************************************************
+/****************************************************************//**
Create a new list using mem_alloc. Lists created with this function must be
-freed with ib_list_free. */
+freed with ib_list_free.
+@return list */
UNIV_INTERN
ib_list_t*
ib_list_create(void);
/*=================*/
- /* out: list */
-/********************************************************************
+/****************************************************************//**
Create a new list using the given heap. ib_list_free MUST NOT BE CALLED for
-lists created with this function. */
+lists created with this function.
+@return list */
UNIV_INTERN
ib_list_t*
ib_list_create_heap(
/*================*/
- /* out: list */
- mem_heap_t* heap); /* in: memory heap to use */
+ mem_heap_t* heap); /*!< in: memory heap to use */
-/********************************************************************
+/****************************************************************//**
Free a list. */
UNIV_INTERN
void
ib_list_free(
/*=========*/
- ib_list_t* list); /* in: list */
+ ib_list_t* list); /*!< in: list */
-/********************************************************************
-Add the data to the start of the list. */
+/****************************************************************//**
+Add the data to the start of the list.
+@return new list node */
UNIV_INTERN
ib_list_node_t*
ib_list_add_first(
/*==============*/
- /* out: new list node*/
- ib_list_t* list, /* in: list */
- void* data, /* in: data */
- mem_heap_t* heap); /* in: memory heap to use */
+ ib_list_t* list, /*!< in: list */
+ void* data, /*!< in: data */
+ mem_heap_t* heap); /*!< in: memory heap to use */
-/********************************************************************
-Add the data to the end of the list. */
+/****************************************************************//**
+Add the data to the end of the list.
+@return new list node */
UNIV_INTERN
ib_list_node_t*
ib_list_add_last(
/*=============*/
- /* out: new list node*/
- ib_list_t* list, /* in: list */
- void* data, /* in: data */
- mem_heap_t* heap); /* in: memory heap to use */
+ ib_list_t* list, /*!< in: list */
+ void* data, /*!< in: data */
+ mem_heap_t* heap); /*!< in: memory heap to use */
-/********************************************************************
-Add the data after the indicated node. */
+/****************************************************************//**
+Add the data after the indicated node.
+@return new list node */
UNIV_INTERN
ib_list_node_t*
ib_list_add_after(
/*==============*/
- /* out: new list node*/
- ib_list_t* list, /* in: list */
- ib_list_node_t* prev_node, /* in: node preceding new node (can
+ ib_list_t* list, /*!< in: list */
+ ib_list_node_t* prev_node, /*!< in: node preceding new node (can
be NULL) */
- void* data, /* in: data */
- mem_heap_t* heap); /* in: memory heap to use */
+ void* data, /*!< in: data */
+ mem_heap_t* heap); /*!< in: memory heap to use */
-/********************************************************************
+/****************************************************************//**
Remove the node from the list. */
UNIV_INTERN
void
ib_list_remove(
/*===========*/
- ib_list_t* list, /* in: list */
- ib_list_node_t* node); /* in: node to remove */
+ ib_list_t* list, /*!< in: list */
+ ib_list_node_t* node); /*!< in: node to remove */
-/********************************************************************
-Get the first node in the list. */
+/****************************************************************//**
+Get the first node in the list.
+@return first node, or NULL */
UNIV_INLINE
ib_list_node_t*
ib_list_get_first(
/*==============*/
- /* out: first node, or NULL */
- ib_list_t* list); /* in: list */
+ ib_list_t* list); /*!< in: list */
-/********************************************************************
-Get the last node in the list. */
+/****************************************************************//**
+Get the last node in the list.
+@return last node, or NULL */
UNIV_INLINE
ib_list_node_t*
ib_list_get_last(
/*=============*/
- /* out: last node, or NULL */
- ib_list_t* list); /* in: list */
+ ib_list_t* list); /*!< in: list */
/* List. */
struct ib_list_struct {
- ib_list_node_t* first; /* first node */
- ib_list_node_t* last; /* last node */
- ibool is_heap_list; /* TRUE if this list was
+ ib_list_node_t* first; /*!< first node */
+ ib_list_node_t* last; /*!< last node */
+ ibool is_heap_list; /*!< TRUE if this list was
allocated through a heap */
};
/* A list node. */
struct ib_list_node_struct {
- ib_list_node_t* prev; /* previous node */
- ib_list_node_t* next; /* next node */
- void* data; /* user data */
+ ib_list_node_t* prev; /*!< previous node */
+ ib_list_node_t* next; /*!< next node */
+ void* data; /*!< user data */
};
/* Quite often, the only additional piece of data you need is the per-item
memory heap, so we have this generic struct available to use in those
cases. */
struct ib_list_helper_struct {
- mem_heap_t* heap; /* memory heap */
- void* data; /* user data */
+ mem_heap_t* heap; /*!< memory heap */
+ void* data; /*!< user data */
};
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/ut0list.ic b/storage/xtradb/include/ut0list.ic
index c79a0cf18dc..eb5c62796e8 100644
--- a/storage/xtradb/include/ut0list.ic
+++ b/storage/xtradb/include/ut0list.ic
@@ -16,26 +16,33 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/********************************************************************
-Get the first node in the list. */
+/*******************************************************************//**
+@file include/ut0list.ic
+A double-linked list
+
+Created 4/26/2006 Osku Salerma
+************************************************************************/
+
+/****************************************************************//**
+Get the first node in the list.
+@return first node, or NULL */
UNIV_INLINE
ib_list_node_t*
ib_list_get_first(
/*==============*/
- /* out: first node, or NULL */
- ib_list_t* list) /* in: list */
+ ib_list_t* list) /*!< in: list */
{
return(list->first);
}
-/********************************************************************
-Get the last node in the list. */
+/****************************************************************//**
+Get the last node in the list.
+@return last node, or NULL */
UNIV_INLINE
ib_list_node_t*
ib_list_get_last(
/*=============*/
- /* out: last node, or NULL */
- ib_list_t* list) /* in: list */
+ ib_list_t* list) /*!< in: list */
{
return(list->last);
}
diff --git a/storage/xtradb/include/ut0lst.h b/storage/xtradb/include/ut0lst.h
index 46ee23a2538..261d33963dc 100644
--- a/storage/xtradb/include/ut0lst.h
+++ b/storage/xtradb/include/ut0lst.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/ut0lst.h
List utilities
Created 9/10/1995 Heikki Tuuri
@@ -32,45 +33,46 @@ if a list is used in the database. Note that a single struct may belong
to two or more lists, provided that the list are given different names.
An example of the usage of the lists can be found in fil0fil.c. */
-/***********************************************************************
+/*******************************************************************//**
This macro expands to the unnamed type definition of a struct which acts
as the two-way list base node. The base node contains pointers
to both ends of the list and a count of nodes in the list (excluding
-the base node from the count). TYPE should be the list node type name. */
-
+the base node from the count).
+@param TYPE the name of the list node data type */
#define UT_LIST_BASE_NODE_T(TYPE)\
struct {\
- ulint count; /* count of nodes in list */\
- TYPE * start; /* pointer to list start, NULL if empty */\
- TYPE * end; /* pointer to list end, NULL if empty */\
+ ulint count; /*!< count of nodes in list */\
+ TYPE * start; /*!< pointer to list start, NULL if empty */\
+ TYPE * end; /*!< pointer to list end, NULL if empty */\
}\
-/***********************************************************************
+/*******************************************************************//**
This macro expands to the unnamed type definition of a struct which
should be embedded in the nodes of the list, the node type must be a struct.
This struct contains the pointers to next and previous nodes in the list.
The name of the field in the node struct should be the name given
-to the list. TYPE should be the list node type name. Example of usage:
-
+to the list.
+@param TYPE the list node type name */
+/* Example:
typedef struct LRU_node_struct LRU_node_t;
struct LRU_node_struct {
UT_LIST_NODE_T(LRU_node_t) LRU_list;
...
}
The example implements an LRU list of name LRU_list. Its nodes are of type
-LRU_node_t.
-*/
+LRU_node_t. */
#define UT_LIST_NODE_T(TYPE)\
struct {\
- TYPE * prev; /* pointer to the previous node,\
+ TYPE * prev; /*!< pointer to the previous node,\
NULL if start of list */\
- TYPE * next; /* pointer to next node, NULL if end of list */\
+ TYPE * next; /*!< pointer to next node, NULL if end of list */\
}\
-/***********************************************************************
-Initializes the base node of a two-way list. */
-
+/*******************************************************************//**
+Initializes the base node of a two-way list.
+@param BASE the list base node
+*/
#define UT_LIST_INIT(BASE)\
{\
(BASE).count = 0;\
@@ -78,11 +80,12 @@ Initializes the base node of a two-way list. */
(BASE).end = NULL;\
}\
-/***********************************************************************
+/*******************************************************************//**
Adds the node as the first element in a two-way linked list.
-BASE has to be the base node (not a pointer to it). N has to be
-the pointer to the node to be added to the list. NAME is the list name. */
-
+@param NAME list name
+@param BASE the base node (not a pointer to it)
+@param N pointer to the node to be added to the list.
+*/
#define UT_LIST_ADD_FIRST(NAME, BASE, N)\
{\
ut_ad(N);\
@@ -99,11 +102,12 @@ the pointer to the node to be added to the list. NAME is the list name. */
}\
}\
-/***********************************************************************
+/*******************************************************************//**
Adds the node as the last element in a two-way linked list.
-BASE has to be the base node (not a pointer to it). N has to be
-the pointer to the node to be added to the list. NAME is the list name. */
-
+@param NAME list name
+@param BASE the base node (not a pointer to it)
+@param N pointer to the node to be added to the list
+*/
#define UT_LIST_ADD_LAST(NAME, BASE, N)\
{\
ut_ad(N);\
@@ -120,11 +124,13 @@ the pointer to the node to be added to the list. NAME is the list name. */
}\
}\
-/***********************************************************************
+/*******************************************************************//**
Inserts a NODE2 after NODE1 in a list.
-BASE has to be the base node (not a pointer to it). NAME is the list
-name, NODE1 and NODE2 are pointers to nodes. */
-
+@param NAME list name
+@param BASE the base node (not a pointer to it)
+@param NODE1 pointer to node after which NODE2 is inserted
+@param NODE2 pointer to node being inserted after NODE1
+*/
#define UT_LIST_INSERT_AFTER(NAME, BASE, NODE1, NODE2)\
{\
ut_ad(NODE1);\
@@ -142,19 +148,25 @@ name, NODE1 and NODE2 are pointers to nodes. */
}\
}\
-/* Invalidate the pointers in a list node. */
#ifdef UNIV_LIST_DEBUG
+/** Invalidate the pointers in a list node.
+@param NAME list name
+@param N pointer to the node that was removed */
# define UT_LIST_REMOVE_CLEAR(NAME, N) \
((N)->NAME.prev = (N)->NAME.next = (void*) -1)
#else
+/** Invalidate the pointers in a list node.
+@param NAME list name
+@param N pointer to the node that was removed */
# define UT_LIST_REMOVE_CLEAR(NAME, N) while (0)
#endif
-/***********************************************************************
-Removes a node from a two-way linked list. BASE has to be the base node
-(not a pointer to it). N has to be the pointer to the node to be removed
-from the list. NAME is the list name. */
-
+/*******************************************************************//**
+Removes a node from a two-way linked list.
+@param NAME list name
+@param BASE the base node (not a pointer to it)
+@param N pointer to the node to be removed from the list
+*/
#define UT_LIST_REMOVE(NAME, BASE, N) \
do { \
ut_ad(N); \
@@ -173,71 +185,77 @@ do { \
UT_LIST_REMOVE_CLEAR(NAME, N); \
} while (0)
-/************************************************************************
-Gets the next node in a two-way list. NAME is the name of the list
-and N is pointer to a node. */
-
+/********************************************************************//**
+Gets the next node in a two-way list.
+@param NAME list name
+@param N pointer to a node
+@return the successor of N in NAME, or NULL */
#define UT_LIST_GET_NEXT(NAME, N)\
(((N)->NAME).next)
-/************************************************************************
-Gets the previous node in a two-way list. NAME is the name of the list
-and N is pointer to a node. */
-
+/********************************************************************//**
+Gets the previous node in a two-way list.
+@param NAME list name
+@param N pointer to a node
+@return the predecessor of N in NAME, or NULL */
#define UT_LIST_GET_PREV(NAME, N)\
(((N)->NAME).prev)
-/************************************************************************
+/********************************************************************//**
Alternative macro to get the number of nodes in a two-way list, i.e.,
-its length. BASE is the base node (not a pointer to it). */
-
+its length.
+@param BASE the base node (not a pointer to it).
+@return the number of nodes in the list */
#define UT_LIST_GET_LEN(BASE)\
(BASE).count
-/************************************************************************
-Gets the first node in a two-way list, or returns NULL,
-if the list is empty. BASE is the base node (not a pointer to it). */
-
+/********************************************************************//**
+Gets the first node in a two-way list.
+@param BASE the base node (not a pointer to it)
+@return first node, or NULL if the list is empty */
#define UT_LIST_GET_FIRST(BASE)\
(BASE).start
-/************************************************************************
-Gets the last node in a two-way list, or returns NULL,
-if the list is empty. BASE is the base node (not a pointer to it). */
-
+/********************************************************************//**
+Gets the last node in a two-way list.
+@param BASE the base node (not a pointer to it)
+@return last node, or NULL if the list is empty */
#define UT_LIST_GET_LAST(BASE)\
(BASE).end
-/************************************************************************
-Checks the consistency of a two-way list. NAME is the name of the list,
-TYPE is the node type, and BASE is the base node (not a pointer to it). */
-
-#define UT_LIST_VALIDATE(NAME, TYPE, BASE)\
-{\
- ulint ut_list_i_313;\
- TYPE * ut_list_node_313;\
-\
- ut_list_node_313 = (BASE).start;\
-\
- for (ut_list_i_313 = 0; 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).next;\
- }\
-\
- ut_a(ut_list_node_313 == NULL);\
-\
- ut_list_node_313 = (BASE).end;\
-\
- for (ut_list_i_313 = 0; 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);\
-}\
-
+/********************************************************************//**
+Checks the consistency of a two-way list.
+@param NAME the name of the list
+@param TYPE node type
+@param BASE base node (not a pointer to it)
+@param ASSERTION a condition on ut_list_node_313 */
+#define UT_LIST_VALIDATE(NAME, TYPE, BASE, ASSERTION) \
+do { \
+ ulint ut_list_i_313; \
+ TYPE* ut_list_node_313; \
+ \
+ ut_list_node_313 = (BASE).start; \
+ \
+ for (ut_list_i_313 = (BASE).count; ut_list_i_313--; ) { \
+ ut_a(ut_list_node_313); \
+ ASSERTION; \
+ ut_ad((ut_list_node_313->NAME).next || !ut_list_i_313); \
+ 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); \
+ ASSERTION; \
+ ut_ad((ut_list_node_313->NAME).prev || !ut_list_i_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/include/ut0mem.h b/storage/xtradb/include/ut0mem.h
index f8dec99ed4a..cf41cba4643 100644
--- a/storage/xtradb/include/ut0mem.h
+++ b/storage/xtradb/include/ut0mem.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file include/ut0mem.h
Memory primitives
Created 5/30/1994 Heikki Tuuri
@@ -26,77 +27,100 @@ Created 5/30/1994 Heikki Tuuri
#define ut0mem_h
#include "univ.i"
-#include "os0sync.h"
#include <string.h>
+#ifndef UNIV_HOTBACKUP
+# include "os0sync.h"
-/* The total amount of memory currently allocated from the operating
+/** The total amount of memory currently allocated from the operating
system with os_mem_alloc_large() or malloc(). Does not count malloc()
if srv_use_sys_malloc is set. Protected by ut_list_mutex. */
extern ulint ut_total_allocated_memory;
-/* Mutex protecting ut_total_allocated_memory and ut_mem_block_list */
+/** Mutex protecting ut_total_allocated_memory and ut_mem_block_list */
extern os_fast_mutex_t ut_list_mutex;
-
+#endif /* !UNIV_HOTBACKUP */
+
+/** Wrapper for memcpy(3). Copy memory area when the source and
+target are not overlapping.
+* @param dest in: copy to
+* @param sour in: copy from
+* @param n in: number of bytes to copy
+* @return dest */
UNIV_INLINE
void*
ut_memcpy(void* dest, const void* sour, ulint n);
+/** Wrapper for memmove(3). Copy memory area when the source and
+target are overlapping.
+* @param dest in: copy to
+* @param sour in: copy from
+* @param n in: number of bytes to copy
+* @return dest */
UNIV_INLINE
void*
ut_memmove(void* dest, const void* sour, ulint n);
+/** Wrapper for memcmp(3). Compare memory areas.
+* @param str1 in: first memory block to compare
+* @param str2 in: second memory block to compare
+* @param n in: number of bytes to compare
+* @return negative, 0, or positive if str1 is smaller, equal,
+ or greater than str2, respectively. */
UNIV_INLINE
int
ut_memcmp(const void* str1, const void* str2, ulint n);
-/**************************************************************************
+/**********************************************************************//**
Initializes the mem block list at database startup. */
UNIV_INTERN
void
ut_mem_init(void);
/*=============*/
-/**************************************************************************
+/**********************************************************************//**
Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is
-defined and set_to_zero is TRUE. */
+defined and set_to_zero is TRUE.
+@return own: allocated memory */
UNIV_INTERN
void*
ut_malloc_low(
/*==========*/
- /* out, own: allocated memory */
- ulint n, /* in: number of bytes to allocate */
- ibool set_to_zero, /* in: TRUE if allocated memory
+ ulint n, /*!< in: number of bytes to allocate */
+ ibool set_to_zero, /*!< in: TRUE if allocated memory
should be set to zero if
UNIV_SET_MEM_TO_ZERO is defined */
- ibool assert_on_error); /* in: if TRUE, we crash mysqld if
+ ibool assert_on_error); /*!< in: if TRUE, we crash mysqld if
the memory cannot be allocated */
-/**************************************************************************
+/**********************************************************************//**
Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is
-defined. */
+defined.
+@return own: allocated memory */
UNIV_INTERN
void*
ut_malloc(
/*======*/
- /* out, own: allocated memory */
- ulint n); /* in: number of bytes to allocate */
-/**************************************************************************
+ ulint n); /*!< in: number of bytes to allocate */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Tests if malloc of n bytes would succeed. ut_malloc() asserts if memory runs
out. It cannot be used if we want to return an error message. Prints to
-stderr a message if fails. */
+stderr a message if fails.
+@return TRUE if succeeded */
UNIV_INTERN
ibool
ut_test_malloc(
/*===========*/
- /* out: TRUE if succeeded */
- ulint n); /* in: try to allocate this many bytes */
-/**************************************************************************
+ ulint n); /*!< in: try to allocate this many bytes */
+#endif /* !UNIV_HOTBACKUP */
+/**********************************************************************//**
Frees a memory block allocated with ut_malloc. */
UNIV_INTERN
void
ut_free(
/*====*/
- void* ptr); /* in, own: memory block */
-/**************************************************************************
+ void* ptr); /*!< in, own: memory block */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Implements realloc. This is needed by /pars/lexyy.c. Otherwise, you should not
use this function because the allocation functions in mem0mem.h are the
recommended ones in InnoDB.
@@ -119,149 +143,160 @@ RETURN VALUE
size was equal to 0, either NULL or a pointer suitable to
be passed to free() is returned. If realloc() fails the
original block is left untouched - it is not freed or
- moved. */
+ moved.
+@return own: pointer to new mem block or NULL */
UNIV_INTERN
void*
ut_realloc(
/*=======*/
- /* out, own: pointer to new mem block or NULL */
- void* ptr, /* in: pointer to old block or NULL */
- ulint size); /* in: desired size */
-/**************************************************************************
+ void* ptr, /*!< in: pointer to old block or NULL */
+ ulint size); /*!< in: desired size */
+/**********************************************************************//**
Frees in shutdown all allocated memory not freed yet. */
UNIV_INTERN
void
ut_free_all_mem(void);
/*=================*/
+#endif /* !UNIV_HOTBACKUP */
+/** Wrapper for strcpy(3). Copy a NUL-terminated string.
+* @param dest in: copy to
+* @param sour in: copy from
+* @return dest */
UNIV_INLINE
char*
ut_strcpy(char* dest, const char* sour);
+/** Wrapper for strlen(3). Determine the length of a NUL-terminated string.
+* @param str in: string
+* @return length of the string in bytes, excluding the terminating NUL */
UNIV_INLINE
ulint
ut_strlen(const char* str);
+/** Wrapper for strcmp(3). Compare NUL-terminated strings.
+* @param str1 in: first string to compare
+* @param str2 in: second string to compare
+* @return negative, 0, or positive if str1 is smaller, equal,
+ or greater than str2, respectively. */
UNIV_INLINE
int
ut_strcmp(const char* str1, const char* str2);
-/**************************************************************************
+/**********************************************************************//**
Copies up to size - 1 characters from the NUL-terminated string src to
dst, NUL-terminating the result. Returns strlen(src), so truncation
-occurred if the return value >= size. */
+occurred if the return value >= size.
+@return strlen(src) */
UNIV_INTERN
ulint
ut_strlcpy(
/*=======*/
- /* out: strlen(src) */
- char* dst, /* in: destination buffer */
- const char* src, /* in: source buffer */
- ulint size); /* in: size of destination buffer */
+ char* dst, /*!< in: destination buffer */
+ const char* src, /*!< in: source buffer */
+ ulint size); /*!< in: size of destination buffer */
-/**************************************************************************
+/**********************************************************************//**
Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last
-(size - 1) bytes of src, not the first. */
+(size - 1) bytes of src, not the first.
+@return strlen(src) */
UNIV_INTERN
ulint
ut_strlcpy_rev(
/*===========*/
- /* out: strlen(src) */
- char* dst, /* in: destination buffer */
- const char* src, /* in: source buffer */
- ulint size); /* in: size of destination buffer */
+ char* dst, /*!< in: destination buffer */
+ const char* src, /*!< in: source buffer */
+ ulint size); /*!< in: size of destination buffer */
-/**************************************************************************
-Compute strlen(ut_strcpyq(str, q)). */
+/**********************************************************************//**
+Compute strlen(ut_strcpyq(str, q)).
+@return length of the string when quoted */
UNIV_INLINE
ulint
ut_strlenq(
/*=======*/
- /* out: length of the string when quoted */
- const char* str, /* in: null-terminated string */
- char q); /* in: the quote character */
+ const char* str, /*!< in: null-terminated string */
+ char q); /*!< in: the quote character */
-/**************************************************************************
+/**********************************************************************//**
Make a quoted copy of a NUL-terminated string. Leading and trailing
quotes will not be included; only embedded quotes will be escaped.
-See also ut_strlenq() and ut_memcpyq(). */
+See also ut_strlenq() and ut_memcpyq().
+@return pointer to end of dest */
UNIV_INTERN
char*
ut_strcpyq(
/*=======*/
- /* out: pointer to end of dest */
- char* dest, /* in: output buffer */
- char q, /* in: the quote character */
- const char* src); /* in: null-terminated string */
+ char* dest, /*!< in: output buffer */
+ char q, /*!< in: the quote character */
+ const char* src); /*!< in: null-terminated string */
-/**************************************************************************
+/**********************************************************************//**
Make a quoted copy of a fixed-length string. Leading and trailing
quotes will not be included; only embedded quotes will be escaped.
-See also ut_strlenq() and ut_strcpyq(). */
+See also ut_strlenq() and ut_strcpyq().
+@return pointer to end of dest */
UNIV_INTERN
char*
ut_memcpyq(
/*=======*/
- /* out: pointer to end of dest */
- char* dest, /* in: output buffer */
- char q, /* in: the quote character */
- const char* src, /* in: string to be quoted */
- ulint len); /* in: length of src */
+ char* dest, /*!< in: output buffer */
+ char q, /*!< in: the quote character */
+ const char* src, /*!< in: string to be quoted */
+ ulint len); /*!< in: length of src */
-/**************************************************************************
+/**********************************************************************//**
Return the number of times s2 occurs in s1. Overlapping instances of s2
-are only counted once. */
+are only counted once.
+@return the number of times s2 occurs in s1 */
UNIV_INTERN
ulint
ut_strcount(
/*========*/
- /* out: the number of times s2 occurs in s1 */
- const char* s1, /* in: string to search in */
- const char* s2); /* in: string to search for */
+ const char* s1, /*!< in: string to search in */
+ const char* s2); /*!< in: string to search for */
-/**************************************************************************
+/**********************************************************************//**
Replace every occurrence of s1 in str with s2. Overlapping instances of s1
-are only replaced once. */
+are only replaced once.
+@return own: modified string, must be freed with mem_free() */
UNIV_INTERN
char*
ut_strreplace(
/*==========*/
- /* out, own: modified string, must be
- freed with mem_free() */
- const char* str, /* in: string to operate on */
- const char* s1, /* in: string to replace */
- const char* s2); /* in: string to replace s1 with */
-
-/**************************************************************************
-Converts a raw binary data to a '\0'-terminated hex string. The output is
+ const char* str, /*!< in: string to operate on */
+ const char* s1, /*!< in: string to replace */
+ const char* s2); /*!< in: string to replace s1 with */
+
+/**********************************************************************//**
+Converts a raw binary data to a NUL-terminated hex string. The output is
truncated if there is not enough space in "hex", make sure "hex_size" is at
least (2 * raw_size + 1) if you do not want this to happen. Returns the
-actual number of characters written to "hex" (including the '\0'). */
+actual number of characters written to "hex" (including the NUL).
+@return number of chars written */
UNIV_INLINE
ulint
ut_raw_to_hex(
/*==========*/
- /* out: number of chars written */
- const void* raw, /* in: raw data */
- ulint raw_size, /* in: "raw" length in bytes */
- char* hex, /* out: hex string */
- ulint hex_size); /* in: "hex" size in bytes */
+ const void* raw, /*!< in: raw data */
+ ulint raw_size, /*!< in: "raw" length in bytes */
+ char* hex, /*!< out: hex string */
+ ulint hex_size); /*!< in: "hex" size in bytes */
-/***********************************************************************
+/*******************************************************************//**
Adds single quotes to the start and end of string and escapes any quotes
by doubling them. Returns the number of bytes that were written to "buf"
-(including the terminating '\0'). If buf_size is too small then the
-trailing bytes from "str" are discarded. */
+(including the terminating NUL). If buf_size is too small then the
+trailing bytes from "str" are discarded.
+@return number of bytes that were written */
UNIV_INLINE
ulint
ut_str_sql_format(
/*==============*/
- /* out: number of bytes
- that were written */
- const char* str, /* in: string */
- ulint str_len, /* in: string length in bytes */
- char* buf, /* out: output buffer */
- ulint buf_size); /* in: output buffer size
+ const char* str, /*!< in: string */
+ ulint str_len, /*!< in: string length in bytes */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size); /*!< in: output buffer size
in bytes */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/ut0mem.ic b/storage/xtradb/include/ut0mem.ic
index 5078c721706..f36c28f1989 100644
--- a/storage/xtradb/include/ut0mem.ic
+++ b/storage/xtradb/include/ut0mem.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file include/ut0mem.ic
Memory primitives
Created 5/30/1994 Heikki Tuuri
@@ -25,6 +26,12 @@ Created 5/30/1994 Heikki Tuuri
#include "ut0byte.h"
#include "mach0data.h"
+/** Wrapper for memcpy(3). Copy memory area when the source and
+target are not overlapping.
+* @param dest in: copy to
+* @param sour in: copy from
+* @param n in: number of bytes to copy
+* @return dest */
UNIV_INLINE
void*
ut_memcpy(void* dest, const void* sour, ulint n)
@@ -32,6 +39,12 @@ ut_memcpy(void* dest, const void* sour, ulint n)
return(memcpy(dest, sour, n));
}
+/** Wrapper for memmove(3). Copy memory area when the source and
+target are overlapping.
+* @param dest in: copy to
+* @param sour in: copy from
+* @param n in: number of bytes to copy
+* @return dest */
UNIV_INLINE
void*
ut_memmove(void* dest, const void* sour, ulint n)
@@ -39,6 +52,12 @@ ut_memmove(void* dest, const void* sour, ulint n)
return(memmove(dest, sour, n));
}
+/** Wrapper for memcmp(3). Compare memory areas.
+* @param str1 in: first memory block to compare
+* @param str2 in: second memory block to compare
+* @param n in: number of bytes to compare
+* @return negative, 0, or positive if str1 is smaller, equal,
+ or greater than str2, respectively. */
UNIV_INLINE
int
ut_memcmp(const void* str1, const void* str2, ulint n)
@@ -46,6 +65,10 @@ ut_memcmp(const void* str1, const void* str2, ulint n)
return(memcmp(str1, str2, n));
}
+/** Wrapper for strcpy(3). Copy a NUL-terminated string.
+* @param dest in: copy to
+* @param sour in: copy from
+* @return dest */
UNIV_INLINE
char*
ut_strcpy(char* dest, const char* sour)
@@ -53,6 +76,9 @@ ut_strcpy(char* dest, const char* sour)
return(strcpy(dest, sour));
}
+/** Wrapper for strlen(3). Determine the length of a NUL-terminated string.
+* @param str in: string
+* @return length of the string in bytes, excluding the terminating NUL */
UNIV_INLINE
ulint
ut_strlen(const char* str)
@@ -60,6 +86,11 @@ ut_strlen(const char* str)
return(strlen(str));
}
+/** Wrapper for strcmp(3). Compare NUL-terminated strings.
+* @param str1 in: first string to compare
+* @param str2 in: second string to compare
+* @return negative, 0, or positive if str1 is smaller, equal,
+ or greater than str2, respectively. */
UNIV_INLINE
int
ut_strcmp(const char* str1, const char* str2)
@@ -67,15 +98,15 @@ ut_strcmp(const char* str1, const char* str2)
return(strcmp(str1, str2));
}
-/**************************************************************************
-Compute strlen(ut_strcpyq(str, q)). */
+/**********************************************************************//**
+Compute strlen(ut_strcpyq(str, q)).
+@return length of the string when quoted */
UNIV_INLINE
ulint
ut_strlenq(
/*=======*/
- /* out: length of the string when quoted */
- const char* str, /* in: null-terminated string */
- char q) /* in: the quote character */
+ const char* str, /*!< in: null-terminated string */
+ char q) /*!< in: the quote character */
{
ulint len;
@@ -88,20 +119,20 @@ ut_strlenq(
return(len);
}
-/**************************************************************************
-Converts a raw binary data to a '\0'-terminated hex string. The output is
+/**********************************************************************//**
+Converts a raw binary data to a NUL-terminated hex string. The output is
truncated if there is not enough space in "hex", make sure "hex_size" is at
least (2 * raw_size + 1) if you do not want this to happen. Returns the
-actual number of characters written to "hex" (including the '\0'). */
+actual number of characters written to "hex" (including the NUL).
+@return number of chars written */
UNIV_INLINE
ulint
ut_raw_to_hex(
/*==========*/
- /* out: number of chars written */
- const void* raw, /* in: raw data */
- ulint raw_size, /* in: "raw" length in bytes */
- char* hex, /* out: hex string */
- ulint hex_size) /* in: "hex" size in bytes */
+ const void* raw, /*!< in: raw data */
+ ulint raw_size, /*!< in: "raw" length in bytes */
+ char* hex, /*!< out: hex string */
+ ulint hex_size) /*!< in: "hex" size in bytes */
{
#ifdef WORDS_BIGENDIAN
@@ -208,21 +239,20 @@ ut_raw_to_hex(
return(write_bytes);
}
-/***********************************************************************
+/*******************************************************************//**
Adds single quotes to the start and end of string and escapes any quotes
by doubling them. Returns the number of bytes that were written to "buf"
-(including the terminating '\0'). If buf_size is too small then the
-trailing bytes from "str" are discarded. */
+(including the terminating NUL). If buf_size is too small then the
+trailing bytes from "str" are discarded.
+@return number of bytes that were written */
UNIV_INLINE
ulint
ut_str_sql_format(
/*==============*/
- /* out: number of bytes
- that were written */
- const char* str, /* in: string */
- ulint str_len, /* in: string length in bytes */
- char* buf, /* out: output buffer */
- ulint buf_size) /* in: output buffer size
+ const char* str, /*!< in: string */
+ ulint str_len, /*!< in: string length in bytes */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size) /*!< in: output buffer size
in bytes */
{
ulint str_i;
diff --git a/storage/xtradb/include/ut0rnd.h b/storage/xtradb/include/ut0rnd.h
index b9e23d7cd14..ce5152e942f 100644
--- a/storage/xtradb/include/ut0rnd.h
+++ b/storage/xtradb/include/ut0rnd.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/ut0rnd.h
Random numbers and hashing
Created 1/20/1994 Heikki Tuuri
@@ -29,109 +30,109 @@ Created 1/20/1994 Heikki Tuuri
#include "ut0byte.h"
-/* The 'character code' for end of field or string (used
+/** The 'character code' for end of field or string (used
in folding records */
#define UT_END_OF_FIELD 257
-/************************************************************
+/********************************************************//**
This is used to set the random number seed. */
UNIV_INLINE
void
ut_rnd_set_seed(
/*============*/
- ulint seed); /* in: seed */
-/************************************************************
-The following function generates a series of 'random' ulint integers. */
+ ulint seed); /*!< in: seed */
+/********************************************************//**
+The following function generates a series of 'random' ulint integers.
+@return the next 'random' number */
UNIV_INLINE
ulint
ut_rnd_gen_next_ulint(
/*==================*/
- /* out: the next 'random' number */
- ulint rnd); /* in: the previous random number value */
-/*************************************************************
+ ulint rnd); /*!< in: the previous random number value */
+/*********************************************************//**
The following function generates 'random' ulint integers which
enumerate the value space (let there be N of them) of ulint integers
in a pseudo-random fashion. Note that the same integer is repeated
-always after N calls to the generator. */
+always after N calls to the generator.
+@return the 'random' number */
UNIV_INLINE
ulint
ut_rnd_gen_ulint(void);
/*==================*/
- /* out: the 'random' number */
-/************************************************************
-Generates a random integer from a given interval. */
+/********************************************************//**
+Generates a random integer from a given interval.
+@return the 'random' number */
UNIV_INLINE
ulint
ut_rnd_interval(
/*============*/
- /* out: the 'random' number */
- ulint low, /* in: low limit; can generate also this value */
- ulint high); /* in: high limit; can generate also this value */
-/*************************************************************
-Generates a random iboolean value. */
+ ulint low, /*!< in: low limit; can generate also this value */
+ ulint high); /*!< in: high limit; can generate also this value */
+/*********************************************************//**
+Generates a random iboolean value.
+@return the random value */
UNIV_INLINE
ibool
ut_rnd_gen_ibool(void);
/*=================*/
- /* out: the random value */
-/***********************************************************
+/*******************************************************//**
The following function generates a hash value for a ulint integer
to a hash table of size table_size, which should be a prime or some
-random number to work reliably. */
+random number to work reliably.
+@return hash value */
UNIV_INLINE
ulint
ut_hash_ulint(
/*==========*/
- /* out: hash value */
- ulint key, /* in: value to be hashed */
- ulint table_size); /* in: hash table size */
-/*****************************************************************
-Folds a pair of ulints. */
+ ulint key, /*!< in: value to be hashed */
+ ulint table_size); /*!< in: hash table size */
+/*************************************************************//**
+Folds a pair of ulints.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_ulint_pair(
/*===============*/
- /* out: folded value */
- ulint n1, /* in: ulint */
- ulint n2) /* in: ulint */
+ ulint n1, /*!< in: ulint */
+ ulint n2) /*!< in: ulint */
__attribute__((const));
-/*****************************************************************
-Folds a dulint. */
+/*************************************************************//**
+Folds a dulint.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_dulint(
/*===========*/
- /* out: folded value */
- dulint d) /* in: dulint */
+ dulint d) /*!< in: dulint */
__attribute__((const));
-/*****************************************************************
-Folds a character string ending in the null character. */
+/*************************************************************//**
+Folds a character string ending in the null character.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_string(
/*===========*/
- /* out: folded value */
- const char* str) /* in: null-terminated string */
+ const char* str) /*!< in: null-terminated string */
__attribute__((pure));
-/*****************************************************************
-Folds a binary string. */
+/*************************************************************//**
+Folds a binary string.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_binary(
/*===========*/
- /* out: folded value */
- const byte* str, /* in: string of bytes */
- ulint len) /* in: length */
+ const byte* str, /*!< in: string of bytes */
+ ulint len) /*!< in: length */
__attribute__((pure));
-/***************************************************************
+/***********************************************************//**
Looks for a prime number slightly greater than the given argument.
-The prime is chosen so that it is not near any power of 2. */
+The prime is chosen so that it is not near any power of 2.
+@return prime */
UNIV_INTERN
ulint
ut_find_prime(
/*==========*/
- /* out: prime */
- ulint n) /* in: positive number > 100 */
+ ulint n) /*!< in: positive number > 100 */
__attribute__((const));
diff --git a/storage/xtradb/include/ut0rnd.ic b/storage/xtradb/include/ut0rnd.ic
index d72100d16a1..763469142ec 100644
--- a/storage/xtradb/include/ut0rnd.ic
+++ b/storage/xtradb/include/ut0rnd.ic
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************************
+/**************************************************************//**
+@file include/ut0rnd.ic
Random numbers and hashing
Created 5/30/1994 Heikki Tuuri
@@ -34,27 +35,28 @@ Created 5/30/1994 Heikki Tuuri
#define UT_XOR_RND1 187678878
#define UT_XOR_RND2 143537923
+/** Seed value of ut_rnd_gen_ulint() */
extern ulint ut_rnd_ulint_counter;
-/************************************************************
+/********************************************************//**
This is used to set the random number seed. */
UNIV_INLINE
void
ut_rnd_set_seed(
/*============*/
- ulint seed) /* in: seed */
+ ulint seed) /*!< in: seed */
{
ut_rnd_ulint_counter = seed;
}
-/************************************************************
-The following function generates a series of 'random' ulint integers. */
+/********************************************************//**
+The following function generates a series of 'random' ulint integers.
+@return the next 'random' number */
UNIV_INLINE
ulint
ut_rnd_gen_next_ulint(
/*==================*/
- /* out: the next 'random' number */
- ulint rnd) /* in: the previous random number value */
+ ulint rnd) /*!< in: the previous random number value */
{
ulint n_bits;
@@ -71,16 +73,16 @@ ut_rnd_gen_next_ulint(
return(rnd);
}
-/************************************************************
+/********************************************************//**
The following function generates 'random' ulint integers which
enumerate the value space of ulint integers in a pseudo random
fashion. Note that the same integer is repeated always after
-2 to power 32 calls to the generator (if ulint is 32-bit). */
+2 to power 32 calls to the generator (if ulint is 32-bit).
+@return the 'random' number */
UNIV_INLINE
ulint
ut_rnd_gen_ulint(void)
/*==================*/
- /* out: the 'random' number */
{
ulint rnd;
ulint n_bits;
@@ -94,15 +96,15 @@ ut_rnd_gen_ulint(void)
return(rnd);
}
-/************************************************************
-Generates a random integer from a given interval. */
+/********************************************************//**
+Generates a random integer from a given interval.
+@return the 'random' number */
UNIV_INLINE
ulint
ut_rnd_interval(
/*============*/
- /* out: the 'random' number */
- ulint low, /* in: low limit; can generate also this value */
- ulint high) /* in: high limit; can generate also this value */
+ ulint low, /*!< in: low limit; can generate also this value */
+ ulint high) /*!< in: high limit; can generate also this value */
{
ulint rnd;
@@ -118,13 +120,13 @@ ut_rnd_interval(
return(low + (rnd % (high - low + 1)));
}
-/*************************************************************
-Generates a random iboolean value. */
+/*********************************************************//**
+Generates a random iboolean value.
+@return the random value */
UNIV_INLINE
ibool
ut_rnd_gen_ibool(void)
/*=================*/
- /* out: the random value */
{
ulint x;
@@ -138,58 +140,58 @@ ut_rnd_gen_ibool(void)
return(FALSE);
}
-/***********************************************************
+/*******************************************************//**
The following function generates a hash value for a ulint integer
to a hash table of size table_size, which should be a prime
-or some random number for the hash table to work reliably. */
+or some random number for the hash table to work reliably.
+@return hash value */
UNIV_INLINE
ulint
ut_hash_ulint(
/*==========*/
- /* out: hash value */
- ulint key, /* in: value to be hashed */
- ulint table_size) /* in: hash table size */
+ ulint key, /*!< in: value to be hashed */
+ ulint table_size) /*!< in: hash table size */
{
key = key ^ UT_HASH_RANDOM_MASK2;
return(key % table_size);
}
-/*****************************************************************
-Folds a pair of ulints. */
+/*************************************************************//**
+Folds a pair of ulints.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_ulint_pair(
/*===============*/
- /* out: folded value */
- ulint n1, /* in: ulint */
- ulint n2) /* in: ulint */
+ ulint n1, /*!< in: ulint */
+ ulint n2) /*!< in: ulint */
{
return(((((n1 ^ n2 ^ UT_HASH_RANDOM_MASK2) << 8) + n1)
^ UT_HASH_RANDOM_MASK) + n2);
}
-/*****************************************************************
-Folds a dulint. */
+/*************************************************************//**
+Folds a dulint.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_dulint(
/*===========*/
- /* out: folded value */
- dulint d) /* in: dulint */
+ dulint d) /*!< in: dulint */
{
return(ut_fold_ulint_pair(ut_dulint_get_low(d),
ut_dulint_get_high(d)));
}
-/*****************************************************************
-Folds a character string ending in the null character. */
+/*************************************************************//**
+Folds a character string ending in the null character.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_string(
/*===========*/
- /* out: folded value */
- const char* str) /* in: null-terminated string */
+ const char* str) /*!< in: null-terminated string */
{
ulint fold = 0;
@@ -203,15 +205,15 @@ ut_fold_string(
return(fold);
}
-/*****************************************************************
-Folds a binary string. */
+/*************************************************************//**
+Folds a binary string.
+@return folded value */
UNIV_INLINE
ulint
ut_fold_binary(
/*===========*/
- /* out: folded value */
- const byte* str, /* in: string of bytes */
- ulint len) /* in: length */
+ const byte* str, /*!< in: string of bytes */
+ ulint len) /*!< in: length */
{
const byte* str_end = str + len;
ulint fold = 0;
diff --git a/storage/xtradb/include/ut0sort.h b/storage/xtradb/include/ut0sort.h
index 5fd5db54832..5c6647dda9e 100644
--- a/storage/xtradb/include/ut0sort.h
+++ b/storage/xtradb/include/ut0sort.h
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/ut0sort.h
Sort utility
Created 11/9/1995 Heikki Tuuri
@@ -34,7 +35,7 @@ the macro. The sort algorithm is mergesort which has logarithmic
worst case.
*/
-/***********************************************************************
+/*******************************************************************//**
This macro expands to the body of a standard sort function.
The sort function uses mergesort and must be defined separately
for each type of array.
diff --git a/storage/xtradb/include/ut0ut.h b/storage/xtradb/include/ut0ut.h
index 3ca14acd2ef..80094321041 100644
--- a/storage/xtradb/include/ut0ut.h
+++ b/storage/xtradb/include/ut0ut.h
@@ -1,6 +1,13 @@
/*****************************************************************************
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Sun Microsystems, Inc.
+
+Portions of this file contain modifications contributed and copyrighted by
+Sun Microsystems, Inc. Those modifications are gratefully acknowledged and
+are described briefly in the InnoDB documentation. The contributions by
+Sun Microsystems are incorporated with their permission, and subject to the
+conditions contained in the file COPYING.Sun_Microsystems.
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
@@ -16,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file include/ut0ut.h
Various utilities
Created 1/20/1994 Heikki Tuuri
@@ -31,15 +39,41 @@ Created 1/20/1994 Heikki Tuuri
#include <ctype.h>
#endif
-#define TEMP_INDEX_PREFIX '\377' /* Index name prefix in fast index
- creation */
+/** Index name prefix in fast index creation */
+#define TEMP_INDEX_PREFIX '\377'
+/** Index name prefix in fast index creation, as a string constant */
+#define TEMP_INDEX_PREFIX_STR "\377"
+/** Time stamp */
typedef time_t ib_time_t;
-/*************************************************************************
-Delays execution for at most max_wait_us microseconds or returns earlier
-if cond becomes true; cond is evaluated every 2 ms. */
+#if defined(IB_HAVE_PAUSE_INSTRUCTION)
+# ifdef WIN32
+ /* In the Win32 API, the x86 PAUSE instruction is executed by calling
+ the YieldProcessor macro defined in WinNT.h. It is a CPU architecture-
+ independent way by using YieldProcessor.*/
+# define UT_RELAX_CPU() YieldProcessor()
+# else
+ /* According to the gcc info page, asm volatile means that the
+ instruction has important side-effects and must not be removed.
+ Also asm volatile may trigger a memory barrier (spilling all registers
+ to memory). */
+# define UT_RELAX_CPU() __asm__ __volatile__ ("pause")
+# endif
+#elif defined(HAVE_ATOMIC_BUILTINS)
+# define UT_RELAX_CPU() do { \
+ volatile lint volatile_var; \
+ os_compare_and_swap_lint(&volatile_var, 0, 1); \
+ } while (0)
+#else
+# define UT_RELAX_CPU() ((void)0) /* avoid warning for an empty statement */
+#endif
+/*********************************************************************//**
+Delays execution for at most max_wait_us microseconds or returns earlier
+if cond becomes true.
+@param cond in: condition to wait for; evaluated every 2 ms
+@param max_wait_us in: maximum delay to wait, in microseconds */
#define UT_WAIT_FOR(cond, max_wait_us) \
do { \
ullint start_us; \
@@ -51,218 +85,237 @@ do { \
} \
} while (0)
-/************************************************************
+/********************************************************//**
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
but since there seem to be compiler bugs in both gcc and Visual C++,
-we do this by a special conversion. */
+we do this by a special conversion.
+@return a >> 32 */
UNIV_INTERN
ulint
ut_get_high32(
/*==========*/
- /* out: a >> 32 */
- ulint a); /* in: ulint */
-/**********************************************************
-Calculates the minimum of two ulints. */
+ ulint a); /*!< in: ulint */
+/******************************************************//**
+Calculates the minimum of two ulints.
+@return minimum */
UNIV_INLINE
ulint
ut_min(
/*===*/
- /* out: minimum */
- ulint n1, /* in: first number */
- ulint n2); /* in: second number */
-/**********************************************************
-Calculates the maximum of two ulints. */
+ ulint n1, /*!< in: first number */
+ ulint n2); /*!< in: second number */
+/******************************************************//**
+Calculates the maximum of two ulints.
+@return maximum */
UNIV_INLINE
ulint
ut_max(
/*===*/
- /* out: maximum */
- ulint n1, /* in: first number */
- ulint n2); /* in: second number */
-/********************************************************************
+ ulint n1, /*!< in: first number */
+ ulint n2); /*!< in: second number */
+/****************************************************************//**
Calculates minimum of two ulint-pairs. */
UNIV_INLINE
void
ut_pair_min(
/*========*/
- ulint* a, /* out: more significant part of minimum */
- ulint* b, /* out: less significant part of minimum */
- ulint a1, /* in: more significant part of first pair */
- ulint b1, /* in: less significant part of first pair */
- ulint a2, /* in: more significant part of second pair */
- ulint b2); /* in: less significant part of second pair */
-/**********************************************************
-Compares two ulints. */
+ ulint* a, /*!< out: more significant part of minimum */
+ ulint* b, /*!< out: less significant part of minimum */
+ ulint a1, /*!< in: more significant part of first pair */
+ ulint b1, /*!< in: less significant part of first pair */
+ ulint a2, /*!< in: more significant part of second pair */
+ ulint b2); /*!< in: less significant part of second pair */
+/******************************************************//**
+Compares two ulints.
+@return 1 if a > b, 0 if a == b, -1 if a < b */
UNIV_INLINE
int
ut_ulint_cmp(
/*=========*/
- /* out: 1 if a > b, 0 if a == b, -1 if a < b */
- ulint a, /* in: ulint */
- ulint b); /* in: ulint */
-/***********************************************************
-Compares two pairs of ulints. */
+ ulint a, /*!< in: ulint */
+ ulint b); /*!< in: ulint */
+/*******************************************************//**
+Compares two pairs of ulints.
+@return -1 if a < b, 0 if a == b, 1 if a > b */
UNIV_INLINE
int
ut_pair_cmp(
/*========*/
- /* out: -1 if a < b, 0 if a == b,
- 1 if a > b */
- ulint a1, /* in: more significant part of first pair */
- ulint a2, /* in: less significant part of first pair */
- ulint b1, /* in: more significant part of second pair */
- ulint b2); /* in: less significant part of second pair */
-/*****************************************************************
-Determines if a number is zero or a power of two. */
+ ulint a1, /*!< in: more significant part of first pair */
+ ulint a2, /*!< in: less significant part of first pair */
+ ulint b1, /*!< in: more significant part of second pair */
+ ulint b2); /*!< in: less significant part of second pair */
+/*************************************************************//**
+Determines if a number is zero or a power of two.
+@param n in: number
+@return nonzero if n is zero or a power of two; zero otherwise */
#define ut_is_2pow(n) UNIV_LIKELY(!((n) & ((n) - 1)))
-/*****************************************************************
-Calculates fast the remainder of n/m when m is a power of two. */
+/*************************************************************//**
+Calculates fast the remainder of n/m when m is a power of two.
+@param n in: numerator
+@param m in: denominator, must be a power of two
+@return the remainder of n/m */
#define ut_2pow_remainder(n, m) ((n) & ((m) - 1))
-/*****************************************************************
+/*************************************************************//**
Calculates the biggest multiple of m that is not bigger than n
-when m is a power of two. In other words, rounds n down to m * k. */
+when m is a power of two. In other words, rounds n down to m * k.
+@param n in: number to round down
+@param m in: alignment, must be a power of two
+@return n rounded down to the biggest possible integer multiple of m */
#define ut_2pow_round(n, m) ((n) & ~((m) - 1))
+/** Align a number down to a multiple of a power of two.
+@param n in: number to round down
+@param m in: alignment, must be a power of two
+@return n rounded down to the biggest possible integer multiple of m */
#define ut_calc_align_down(n, m) ut_2pow_round(n, m)
-/************************************************************
+/********************************************************//**
Calculates the smallest multiple of m that is not smaller than n
-when m is a power of two. In other words, rounds n up to m * k. */
+when m is a power of two. In other words, rounds n up to m * k.
+@param n in: number to round up
+@param m in: alignment, must be a power of two
+@return n rounded up to the smallest possible integer multiple of m */
#define ut_calc_align(n, m) (((n) + ((m) - 1)) & ~((m) - 1))
-/*****************************************************************
+/*************************************************************//**
Calculates fast the 2-logarithm of a number, rounded upward to an
-integer. */
+integer.
+@return logarithm in the base 2, rounded upward */
UNIV_INLINE
ulint
ut_2_log(
/*=====*/
- /* out: logarithm in the base 2, rounded upward */
- ulint n); /* in: number */
-/*****************************************************************
-Calculates 2 to power n. */
+ ulint n); /*!< in: number */
+/*************************************************************//**
+Calculates 2 to power n.
+@return 2 to power n */
UNIV_INLINE
ulint
ut_2_exp(
/*=====*/
- /* out: 2 to power n */
- ulint n); /* in: number */
-/*****************************************************************
-Calculates fast the number rounded up to the nearest power of 2. */
+ ulint n); /*!< in: number */
+/*************************************************************//**
+Calculates fast the number rounded up to the nearest power of 2.
+@return first power of 2 which is >= n */
UNIV_INTERN
ulint
ut_2_power_up(
/*==========*/
- /* out: first power of 2 which is >= n */
- ulint n) /* in: number != 0 */
+ ulint n) /*!< in: number != 0 */
__attribute__((const));
-/* Determine how many bytes (groups of 8 bits) are needed to
-store the given number of bits. */
+/** Determine how many bytes (groups of 8 bits) are needed to
+store the given number of bits.
+@param b in: bits
+@return number of bytes (octets) needed to represent b */
#define UT_BITS_IN_BYTES(b) (((b) + 7) / 8)
-/**************************************************************
+/**********************************************************//**
Returns system time. We do not specify the format of the time returned:
-the only way to manipulate it is to use the function ut_difftime. */
+the only way to manipulate it is to use the function ut_difftime.
+@return system time */
UNIV_INTERN
ib_time_t
ut_time(void);
/*=========*/
-/**************************************************************
+/**********************************************************//**
Returns system time.
Upon successful completion, the value 0 is returned; otherwise the
value -1 is returned and the global variable errno is set to indicate the
-error. */
+error.
+@return 0 on success, -1 otherwise */
UNIV_INTERN
int
ut_usectime(
/*========*/
- /* out: 0 on success, -1 otherwise */
- ulint* sec, /* out: seconds since the Epoch */
- ulint* ms); /* out: microseconds since the Epoch+*sec */
+ ulint* sec, /*!< out: seconds since the Epoch */
+ ulint* ms); /*!< out: microseconds since the Epoch+*sec */
-/**************************************************************
+/**********************************************************//**
Returns the number of microseconds since epoch. Similar to
time(3), the return value is also stored in *tloc, provided
-that tloc is non-NULL. */
+that tloc is non-NULL.
+@return us since epoch */
UNIV_INTERN
ullint
ut_time_us(
/*=======*/
- /* out: us since epoch */
- ullint* tloc); /* out: us since epoch, if non-NULL */
+ ullint* tloc); /*!< out: us since epoch, if non-NULL */
-/**************************************************************
-Returns the difference of two times in seconds. */
+/**********************************************************//**
+Returns the difference of two times in seconds.
+@return time2 - time1 expressed in seconds */
UNIV_INTERN
double
ut_difftime(
/*========*/
- /* out: time2 - time1 expressed in seconds */
- ib_time_t time2, /* in: time */
- ib_time_t time1); /* in: time */
-/**************************************************************
+ ib_time_t time2, /*!< in: time */
+ ib_time_t time1); /*!< in: time */
+/**********************************************************//**
Prints a timestamp to a file. */
UNIV_INTERN
void
ut_print_timestamp(
/*===============*/
- FILE* file); /* in: file where to print */
-/**************************************************************
+ FILE* file); /*!< in: file where to print */
+/**********************************************************//**
Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
UNIV_INTERN
void
ut_sprintf_timestamp(
/*=================*/
- char* buf); /* in: buffer where to sprintf */
+ char* buf); /*!< in: buffer where to sprintf */
#ifdef UNIV_HOTBACKUP
-/**************************************************************
+/**********************************************************//**
Sprintfs a timestamp to a buffer with no spaces and with ':' characters
replaced by '_'. */
UNIV_INTERN
void
ut_sprintf_timestamp_without_extra_chars(
/*=====================================*/
- char* buf); /* in: buffer where to sprintf */
-/**************************************************************
+ char* buf); /*!< in: buffer where to sprintf */
+/**********************************************************//**
Returns current year, month, day. */
UNIV_INTERN
void
ut_get_year_month_day(
/*==================*/
- ulint* year, /* out: current year */
- ulint* month, /* out: month */
- ulint* day); /* out: day */
-#endif /* UNIV_HOTBACKUP */
-/*****************************************************************
+ ulint* year, /*!< out: current year */
+ ulint* month, /*!< out: month */
+ ulint* day); /*!< out: day */
+#else /* UNIV_HOTBACKUP */
+/*************************************************************//**
Runs an idle loop on CPU. The argument gives the desired delay
-in microseconds on 100 MHz Pentium + Visual C++. */
+in microseconds on 100 MHz Pentium + Visual C++.
+@return dummy value */
UNIV_INTERN
ulint
ut_delay(
/*=====*/
- /* out: dummy value */
- ulint delay); /* in: delay in microseconds on 100 MHz Pentium */
-/*****************************************************************
+ ulint delay); /*!< in: delay in microseconds on 100 MHz Pentium */
+#endif /* UNIV_HOTBACKUP */
+/*************************************************************//**
Prints the contents of a memory buffer in hex and ascii. */
UNIV_INTERN
void
ut_print_buf(
/*=========*/
- FILE* file, /* in: file where to print */
- const void* buf, /* in: memory buffer */
- ulint len); /* in: length of the buffer */
+ FILE* file, /*!< in: file where to print */
+ const void* buf, /*!< in: memory buffer */
+ ulint len); /*!< in: length of the buffer */
-/**************************************************************************
+/**********************************************************************//**
Outputs a NUL-terminated file name, quoted with apostrophes. */
UNIV_INTERN
void
ut_print_filename(
/*==============*/
- FILE* f, /* in: output stream */
- const char* name); /* in: name to print */
+ FILE* f, /*!< in: output stream */
+ const char* name); /*!< in: name to print */
+#ifndef UNIV_HOTBACKUP
/* Forward declaration of transaction handle */
struct trx_struct;
-/**************************************************************************
+/**********************************************************************//**
Outputs a fixed-length string, quoted as an SQL identifier.
If the string contains a slash '/', the string will be
output as two identifiers separated by a period (.),
@@ -271,13 +324,13 @@ UNIV_INTERN
void
ut_print_name(
/*==========*/
- FILE* f, /* in: output stream */
- struct trx_struct*trx, /* in: transaction */
- ibool table_id,/* in: TRUE=print a table name,
+ FILE* f, /*!< in: output stream */
+ struct trx_struct*trx, /*!< in: transaction */
+ ibool table_id,/*!< in: TRUE=print a table name,
FALSE=print other identifier */
- const char* name); /* in: name to print */
+ const char* name); /*!< in: name to print */
-/**************************************************************************
+/**********************************************************************//**
Outputs a fixed-length string, quoted as an SQL identifier.
If the string contains a slash '/', the string will be
output as two identifiers separated by a period (.),
@@ -286,38 +339,42 @@ UNIV_INTERN
void
ut_print_namel(
/*===========*/
- FILE* f, /* in: output stream */
- struct trx_struct*trx, /* in: transaction (NULL=no quotes) */
- ibool table_id,/* in: TRUE=print a table name,
+ FILE* f, /*!< in: output stream */
+ struct trx_struct*trx, /*!< in: transaction (NULL=no quotes) */
+ ibool table_id,/*!< in: TRUE=print a table name,
FALSE=print other identifier */
- const char* name, /* in: name to print */
- ulint namelen);/* in: length of name */
+ const char* name, /*!< in: name to print */
+ ulint namelen);/*!< in: length of name */
-/**************************************************************************
+/**********************************************************************//**
Catenate files. */
UNIV_INTERN
void
ut_copy_file(
/*=========*/
- FILE* dest, /* in: output file */
- FILE* src); /* in: input file to be appended to output */
-
-/**************************************************************************
-snprintf(). */
+ FILE* dest, /*!< in: output file */
+ FILE* src); /*!< in: input file to be appended to output */
+#endif /* !UNIV_HOTBACKUP */
#ifdef __WIN__
+/**********************************************************************//**
+A substitute for snprintf(3), formatted output conversion into
+a limited buffer.
+@return number of characters that would have been printed if the size
+were unlimited, not including the terminating '\0'. */
+UNIV_INTERN
int
ut_snprintf(
- /* out: number of characters that would
- have been printed if the size were
- unlimited, not including the terminating
- '\0'. */
- char* str, /* out: string */
- size_t size, /* in: str size */
- const char* fmt, /* in: format */
- ...); /* in: format values */
+/*========*/
+ char* str, /*!< out: string */
+ size_t size, /*!< in: str size */
+ const char* fmt, /*!< in: format */
+ ...); /*!< in: format values */
#else
-#define ut_snprintf snprintf
+/**********************************************************************//**
+A wrapper for snprintf(3), formatted output conversion into
+a limited buffer. */
+# define ut_snprintf snprintf
#endif /* __WIN__ */
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/ut0ut.ic b/storage/xtradb/include/ut0ut.ic
index e4e0a2acce6..6f55c7e410e 100644
--- a/storage/xtradb/include/ut0ut.ic
+++ b/storage/xtradb/include/ut0ut.ic
@@ -16,50 +16,51 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************************
+/**************************************************************//**
+@file include/ut0ut.ic
Various utilities
Created 5/30/1994 Heikki Tuuri
*******************************************************************/
-/**********************************************************
-Calculates the minimum of two ulints. */
+/******************************************************//**
+Calculates the minimum of two ulints.
+@return minimum */
UNIV_INLINE
ulint
ut_min(
/*===*/
- /* out: minimum */
- ulint n1, /* in: first number */
- ulint n2) /* in: second number */
+ ulint n1, /*!< in: first number */
+ ulint n2) /*!< in: second number */
{
return((n1 <= n2) ? n1 : n2);
}
-/**********************************************************
-Calculates the maximum of two ulints. */
+/******************************************************//**
+Calculates the maximum of two ulints.
+@return maximum */
UNIV_INLINE
ulint
ut_max(
/*===*/
- /* out: maximum */
- ulint n1, /* in: first number */
- ulint n2) /* in: second number */
+ ulint n1, /*!< in: first number */
+ ulint n2) /*!< in: second number */
{
return((n1 <= n2) ? n2 : n1);
}
-/********************************************************************
+/****************************************************************//**
Calculates minimum of two ulint-pairs. */
UNIV_INLINE
void
ut_pair_min(
/*========*/
- ulint* a, /* out: more significant part of minimum */
- ulint* b, /* out: less significant part of minimum */
- ulint a1, /* in: more significant part of first pair */
- ulint b1, /* in: less significant part of first pair */
- ulint a2, /* in: more significant part of second pair */
- ulint b2) /* in: less significant part of second pair */
+ ulint* a, /*!< out: more significant part of minimum */
+ ulint* b, /*!< out: less significant part of minimum */
+ ulint a1, /*!< in: more significant part of first pair */
+ ulint b1, /*!< in: less significant part of first pair */
+ ulint a2, /*!< in: more significant part of second pair */
+ ulint b2) /*!< in: less significant part of second pair */
{
if (a1 == a2) {
*a = a1;
@@ -73,15 +74,15 @@ ut_pair_min(
}
}
-/**********************************************************
-Compares two ulints. */
+/******************************************************//**
+Compares two ulints.
+@return 1 if a > b, 0 if a == b, -1 if a < b */
UNIV_INLINE
int
ut_ulint_cmp(
/*=========*/
- /* out: 1 if a > b, 0 if a == b, -1 if a < b */
- ulint a, /* in: ulint */
- ulint b) /* in: ulint */
+ ulint a, /*!< in: ulint */
+ ulint b) /*!< in: ulint */
{
if (a < b) {
return(-1);
@@ -92,17 +93,17 @@ ut_ulint_cmp(
}
}
-/***********************************************************
-Compares two pairs of ulints. */
+/*******************************************************//**
+Compares two pairs of ulints.
+@return -1 if a < b, 0 if a == b, 1 if a > b */
UNIV_INLINE
int
ut_pair_cmp(
/*========*/
- /* out: -1 if a < b, 0 if a == b, 1 if a > b */
- ulint a1, /* in: more significant part of first pair */
- ulint a2, /* in: less significant part of first pair */
- ulint b1, /* in: more significant part of second pair */
- ulint b2) /* in: less significant part of second pair */
+ ulint a1, /*!< in: more significant part of first pair */
+ ulint a2, /*!< in: less significant part of first pair */
+ ulint b1, /*!< in: more significant part of second pair */
+ ulint b2) /*!< in: less significant part of second pair */
{
if (a1 > b1) {
return(1);
@@ -117,15 +118,15 @@ ut_pair_cmp(
}
}
-/*****************************************************************
+/*************************************************************//**
Calculates fast the 2-logarithm of a number, rounded upward to an
-integer. */
+integer.
+@return logarithm in the base 2, rounded upward */
UNIV_INLINE
ulint
ut_2_log(
/*=====*/
- /* out: logarithm in the base 2, rounded upward */
- ulint n) /* in: number != 0 */
+ ulint n) /*!< in: number != 0 */
{
ulint res;
@@ -148,14 +149,14 @@ ut_2_log(
return(res + 1);
}
-/*****************************************************************
-Calculates 2 to power n. */
+/*************************************************************//**
+Calculates 2 to power n.
+@return 2 to power n */
UNIV_INLINE
ulint
ut_2_exp(
/*=====*/
- /* out: 2 to power n */
- ulint n) /* in: number */
+ ulint n) /*!< in: number */
{
return((ulint) 1 << n);
}
diff --git a/storage/xtradb/include/ut0vec.h b/storage/xtradb/include/ut0vec.h
index aeb7e168dc6..a770f671cfc 100644
--- a/storage/xtradb/include/ut0vec.h
+++ b/storage/xtradb/include/ut0vec.h
@@ -16,12 +16,20 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/*******************************************************************//**
+@file include/ut0vec.h
+A vector of pointers to data items
+
+Created 4/6/2006 Osku Salerma
+************************************************************************/
+
#ifndef IB_VECTOR_H
#define IB_VECTOR_H
#include "univ.i"
#include "mem0mem.h"
+/** An automatically resizing vector data type. */
typedef struct ib_vector_struct ib_vector_t;
/* An automatically resizing vector datatype with the following properties:
@@ -38,76 +46,76 @@ typedef struct ib_vector_struct ib_vector_t;
relatively small or short-lived uses.
*/
-/********************************************************************
-Create a new vector with the given initial size. */
+/****************************************************************//**
+Create a new vector with the given initial size.
+@return vector */
UNIV_INTERN
ib_vector_t*
ib_vector_create(
/*=============*/
- /* out: vector */
- mem_heap_t* heap, /* in: heap */
- ulint size); /* in: initial size */
+ mem_heap_t* heap, /*!< in: heap */
+ ulint size); /*!< in: initial size */
-/********************************************************************
+/****************************************************************//**
Push a new element to the vector, increasing its size if necessary. */
UNIV_INTERN
void
ib_vector_push(
/*===========*/
- ib_vector_t* vec, /* in: vector */
- void* elem); /* in: data element */
+ ib_vector_t* vec, /*!< in: vector */
+ void* elem); /*!< in: data element */
-/********************************************************************
-Get the number of elements in the vector. */
+/****************************************************************//**
+Get the number of elements in the vector.
+@return number of elements in vector */
UNIV_INLINE
ulint
ib_vector_size(
/*===========*/
- /* out: number of elements in vector */
- const ib_vector_t* vec); /* in: vector */
+ const ib_vector_t* vec); /*!< in: vector */
-/********************************************************************
-Test whether a vector is empty or not. */
+/****************************************************************//**
+Test whether a vector is empty or not.
+@return TRUE if empty */
UNIV_INLINE
ibool
ib_vector_is_empty(
/*===============*/
- /* out: TRUE if empty */
- const ib_vector_t* vec); /* in: vector */
+ const ib_vector_t* vec); /*!< in: vector */
-/********************************************************************
-Get the n'th element. */
+/****************************************************************//**
+Get the n'th element.
+@return n'th element */
UNIV_INLINE
void*
ib_vector_get(
/*==========*/
- /* out: n'th element */
- ib_vector_t* vec, /* in: vector */
- ulint n); /* in: element index to get */
+ ib_vector_t* vec, /*!< in: vector */
+ ulint n); /*!< in: element index to get */
-/********************************************************************
+/****************************************************************//**
Remove the last element from the vector. */
UNIV_INLINE
void*
ib_vector_pop(
/*==========*/
- ib_vector_t* vec); /* in: vector */
+ ib_vector_t* vec); /*!< in: vector */
-/********************************************************************
+/****************************************************************//**
Free the underlying heap of the vector. Note that vec is invalid
after this call. */
UNIV_INLINE
void
ib_vector_free(
/*===========*/
- ib_vector_t* vec); /* in,own: vector */
+ ib_vector_t* vec); /*!< in,own: vector */
-/* See comment at beginning of file. */
+/** An automatically resizing vector data type. */
struct ib_vector_struct {
- mem_heap_t* heap; /* heap */
- void** data; /* data elements */
- ulint used; /* number of elements currently used */
- ulint total; /* number of elements allocated */
+ mem_heap_t* heap; /*!< heap */
+ void** data; /*!< data elements */
+ ulint used; /*!< number of elements currently used */
+ ulint total; /*!< number of elements allocated */
};
#ifndef UNIV_NONINL
diff --git a/storage/xtradb/include/ut0vec.ic b/storage/xtradb/include/ut0vec.ic
index b0e853717e3..02e881f9bca 100644
--- a/storage/xtradb/include/ut0vec.ic
+++ b/storage/xtradb/include/ut0vec.ic
@@ -16,41 +16,48 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/********************************************************************
-Get number of elements in vector. */
+/*******************************************************************//**
+@file include/ut0vec.ic
+A vector of pointers to data items
+
+Created 4/6/2006 Osku Salerma
+************************************************************************/
+
+/****************************************************************//**
+Get number of elements in vector.
+@return number of elements in vector */
UNIV_INLINE
ulint
ib_vector_size(
/*===========*/
- /* out: number of elements in vector */
- const ib_vector_t* vec) /* in: vector */
+ const ib_vector_t* vec) /*!< in: vector */
{
return(vec->used);
}
-/********************************************************************
-Get n'th element. */
+/****************************************************************//**
+Get n'th element.
+@return n'th element */
UNIV_INLINE
void*
ib_vector_get(
/*==========*/
- /* out: n'th element */
- ib_vector_t* vec, /* in: vector */
- ulint n) /* in: element index to get */
+ ib_vector_t* vec, /*!< in: vector */
+ ulint n) /*!< in: element index to get */
{
ut_a(n < vec->used);
return(vec->data[n]);
}
-/********************************************************************
-Remove the last element from the vector. */
+/****************************************************************//**
+Remove the last element from the vector.
+@return last vector element */
UNIV_INLINE
void*
ib_vector_pop(
/*==========*/
- /* out: last vector element */
- ib_vector_t* vec) /* in/out: vector */
+ ib_vector_t* vec) /*!< in/out: vector */
{
void* elem;
@@ -64,25 +71,26 @@ ib_vector_pop(
return(elem);
}
-/********************************************************************
+/****************************************************************//**
Free the underlying heap of the vector. Note that vec is invalid
after this call. */
UNIV_INLINE
void
ib_vector_free(
/*===========*/
- ib_vector_t* vec) /* in, own: vector */
+ ib_vector_t* vec) /*!< in, own: vector */
{
mem_heap_free(vec->heap);
}
-/********************************************************************
-Test whether a vector is empty or not. */
+/****************************************************************//**
+Test whether a vector is empty or not.
+@return TRUE if empty */
UNIV_INLINE
ibool
ib_vector_is_empty(
-/*===============*/ /* out: TRUE if empty else FALSE */
- const ib_vector_t* vec) /* in vector to test */
+/*===============*/
+ const ib_vector_t* vec) /*!< in: vector */
{
return(ib_vector_size(vec) == 0);
}
diff --git a/storage/xtradb/include/ut0wqueue.h b/storage/xtradb/include/ut0wqueue.h
index 6bb80dad532..2ec0f16ab05 100644
--- a/storage/xtradb/include/ut0wqueue.h
+++ b/storage/xtradb/include/ut0wqueue.h
@@ -16,7 +16,14 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file include/ut0wqueue.h
+A work queue
+
+Created 4/26/2006 Osku Salerma
+************************************************************************/
+
+/*******************************************************************//**
A Work queue. Threads can add work items to the queue and other threads can
wait for work items to be available and take them off the queue for
processing.
@@ -32,46 +39,47 @@ processing.
typedef struct ib_wqueue_struct ib_wqueue_t;
-/********************************************************************
-Create a new work queue. */
+/****************************************************************//**
+Create a new work queue.
+@return work queue */
UNIV_INTERN
ib_wqueue_t*
ib_wqueue_create(void);
/*===================*/
- /* out: work queue */
-/********************************************************************
+/****************************************************************//**
Free a work queue. */
UNIV_INTERN
void
ib_wqueue_free(
/*===========*/
- ib_wqueue_t* wq); /* in: work queue */
+ ib_wqueue_t* wq); /*!< in: work queue */
-/********************************************************************
+/****************************************************************//**
Add a work item to the queue. */
UNIV_INTERN
void
ib_wqueue_add(
/*==========*/
- ib_wqueue_t* wq, /* in: work queue */
- void* item, /* in: work item */
- mem_heap_t* heap); /* in: memory heap to use for allocating the
+ ib_wqueue_t* wq, /*!< in: work queue */
+ void* item, /*!< in: work item */
+ mem_heap_t* heap); /*!< in: memory heap to use for allocating the
list node */
-/********************************************************************
-Wait for a work item to appear in the queue. */
+/****************************************************************//**
+Wait for a work item to appear in the queue.
+@return work item */
UNIV_INTERN
void*
ib_wqueue_wait(
- /* out: work item */
- ib_wqueue_t* wq); /* in: work queue */
+/*===========*/
+ ib_wqueue_t* wq); /*!< in: work queue */
/* Work queue. */
struct ib_wqueue_struct {
- mutex_t mutex; /* mutex protecting everything */
- ib_list_t* items; /* work item list */
- os_event_t event; /* event we use to signal additions to list */
+ mutex_t mutex; /*!< mutex protecting everything */
+ ib_list_t* items; /*!< work item list */
+ os_event_t event; /*!< event we use to signal additions to list */
};
#endif
diff --git a/storage/xtradb/lock/lock0iter.c b/storage/xtradb/lock/lock0iter.c
index e7a128d0db3..51d1802ccde 100644
--- a/storage/xtradb/lock/lock0iter.c
+++ b/storage/xtradb/lock/lock0iter.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file lock/lock0iter.c
Lock queue iterator. Can iterate over table and record
lock queues.
@@ -35,7 +36,7 @@ Created July 16, 2007 Vasil Dimov
# include "srv0srv.h" /* kernel_mutex */
#endif /* UNIV_DEBUG */
-/***********************************************************************
+/*******************************************************************//**
Initialize lock queue iterator so that it starts to iterate from
"lock". bit_no specifies the record number within the heap where the
record is stored. It can be undefined (ULINT_UNDEFINED) in two cases:
@@ -48,9 +49,9 @@ UNIV_INTERN
void
lock_queue_iterator_reset(
/*======================*/
- lock_queue_iterator_t* iter, /* out: iterator */
- const lock_t* lock, /* in: lock to start from */
- ulint bit_no) /* in: record number in the
+ lock_queue_iterator_t* iter, /*!< out: iterator */
+ const lock_t* lock, /*!< in: lock to start from */
+ ulint bit_no) /*!< in: record number in the
heap */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -76,16 +77,16 @@ lock_queue_iterator_reset(
}
}
-/***********************************************************************
+/*******************************************************************//**
Gets the previous lock in the lock queue, returns NULL if there are no
more locks (i.e. the current lock is the first one). The iterator is
-receded (if not-NULL is returned). */
+receded (if not-NULL is returned).
+@return previous lock or NULL */
UNIV_INTERN
const lock_t*
lock_queue_iterator_get_prev(
/*=========================*/
- /* out: previous lock or NULL */
- lock_queue_iterator_t* iter) /* in/out: iterator */
+ lock_queue_iterator_t* iter) /*!< in/out: iterator */
{
const lock_t* prev_lock;
diff --git a/storage/xtradb/lock/lock0lock.c b/storage/xtradb/lock/lock0lock.c
index 9e90e099428..f76c27e093c 100644
--- a/storage/xtradb/lock/lock0lock.c
+++ b/storage/xtradb/lock/lock0lock.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file lock/lock0lock.c
The transaction lock system
Created 5/7/1996 Heikki Tuuri
@@ -343,23 +344,23 @@ equal to mode2. */
#ifdef UNIV_DEBUG
UNIV_INTERN ibool lock_print_waits = FALSE;
-/*************************************************************************
-Validates the lock system. */
+/*********************************************************************//**
+Validates the lock system.
+@return TRUE if ok */
static
ibool
lock_validate(void);
/*===============*/
- /* out: TRUE if ok */
-/*************************************************************************
-Validates the record lock queues on a page. */
+/*********************************************************************//**
+Validates the record lock queues on a page.
+@return TRUE if ok */
static
ibool
lock_rec_validate_page(
/*===================*/
- /* out: TRUE if ok */
- ulint space, /* in: space id */
- ulint page_no);/* in: page number */
+ ulint space, /*!< in: space id */
+ ulint page_no);/*!< in: page number */
/* Define the following in order to enable lock_rec_validate_page() checks. */
# undef UNIV_DEBUG_LOCK_VALIDATE
@@ -377,51 +378,47 @@ UNIV_INTERN FILE* lock_latest_err_file;
#define LOCK_VICTIM_IS_START 1
#define LOCK_VICTIM_IS_OTHER 2
-/************************************************************************
-Checks if a lock request results in a deadlock. */
+/********************************************************************//**
+Checks if a lock request results in a deadlock.
+@return TRUE if a deadlock was detected and we chose trx as a victim;
+FALSE if no deadlock, or there was a deadlock, but we chose other
+transaction(s) as victim(s) */
static
ibool
lock_deadlock_occurs(
/*=================*/
- /* out: TRUE if a deadlock was detected and we
- chose trx as a victim; FALSE if no deadlock, or
- there was a deadlock, but we chose other
- transaction(s) as victim(s) */
- lock_t* lock, /* in: lock the transaction is requesting */
- trx_t* trx); /* in: transaction */
-/************************************************************************
-Looks recursively for a deadlock. */
+ lock_t* lock, /*!< in: lock the transaction is requesting */
+ trx_t* trx); /*!< in: transaction */
+/********************************************************************//**
+Looks recursively for a deadlock.
+@return 0 if no deadlock found, LOCK_VICTIM_IS_START if there was a
+deadlock and we chose 'start' as the victim, LOCK_VICTIM_IS_OTHER if a
+deadlock was found and we chose some other trx as a victim: we must do
+the search again in this last case because there may be another
+deadlock! */
static
ulint
lock_deadlock_recursive(
/*====================*/
- /* out: 0 if no deadlock found,
- LOCK_VICTIM_IS_START if there was a deadlock
- and we chose 'start' as the victim,
- LOCK_VICTIM_IS_OTHER if a deadlock
- was found and we chose some other trx as a
- victim: we must do the search again in this
- last case because there may be another
- deadlock! */
- trx_t* start, /* in: recursion starting point */
- trx_t* trx, /* in: a transaction waiting for a lock */
- lock_t* wait_lock, /* in: the lock trx is waiting to be granted */
- ulint* cost, /* in/out: number of calculation steps thus
+ trx_t* start, /*!< in: recursion starting point */
+ trx_t* trx, /*!< in: a transaction waiting for a lock */
+ lock_t* wait_lock, /*!< in: the lock trx is waiting to be granted */
+ ulint* cost, /*!< in/out: number of calculation steps thus
far: if this exceeds LOCK_MAX_N_STEPS_...
we return LOCK_VICTIM_IS_START */
- ulint depth); /* in: recursion depth: if this exceeds
+ ulint depth); /*!< in: recursion depth: if this exceeds
LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we
return LOCK_VICTIM_IS_START */
-/*************************************************************************
-Gets the nth bit of a record lock. */
+/*********************************************************************//**
+Gets the nth bit of a record lock.
+@return TRUE if bit set */
UNIV_INLINE
ibool
lock_rec_get_nth_bit(
/*=================*/
- /* out: TRUE if bit set */
- const lock_t* lock, /* in: record lock */
- ulint i) /* in: index of the bit */
+ const lock_t* lock, /*!< in: record lock */
+ ulint i) /*!< in: index of the bit */
{
ulint byte_index;
ulint bit_index;
@@ -445,18 +442,18 @@ lock_rec_get_nth_bit(
#define lock_mutex_enter_kernel() mutex_enter(&kernel_mutex)
#define lock_mutex_exit_kernel() mutex_exit(&kernel_mutex)
-/*************************************************************************
-Checks that a transaction id is sensible, i.e., not in the future. */
+/*********************************************************************//**
+Checks that a transaction id is sensible, i.e., not in the future.
+@return TRUE if ok */
UNIV_INTERN
ibool
lock_check_trx_id_sanity(
/*=====================*/
- /* out: TRUE if ok */
- dulint trx_id, /* in: trx id */
- const rec_t* rec, /* in: user record */
- dict_index_t* index, /* in: index */
- const ulint* offsets, /* in: rec_get_offsets(rec, index) */
- ibool has_kernel_mutex)/* in: TRUE if the caller owns the
+ trx_id_t trx_id, /*!< in: trx id */
+ const rec_t* rec, /*!< in: user record */
+ dict_index_t* index, /*!< in: index */
+ const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */
+ ibool has_kernel_mutex)/*!< in: TRUE if the caller owns the
kernel mutex */
{
ibool is_ok = TRUE;
@@ -496,21 +493,21 @@ lock_check_trx_id_sanity(
return(is_ok);
}
-/*************************************************************************
-Checks that a record is seen in a consistent read. */
+/*********************************************************************//**
+Checks that a record is seen in a consistent read.
+@return TRUE if sees, or FALSE if an earlier version of the record
+should be retrieved */
UNIV_INTERN
ibool
lock_clust_rec_cons_read_sees(
/*==========================*/
- /* out: TRUE if sees, or FALSE if an earlier
- version of the record should be retrieved */
- const rec_t* rec, /* in: user record which should be read or
+ const rec_t* rec, /*!< in: user record which should be read or
passed over by a read cursor */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- read_view_t* view) /* in: consistent read view */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ read_view_t* view) /*!< in: consistent read view */
{
- dulint trx_id;
+ trx_id_t trx_id;
ut_ad(dict_index_is_clust(index));
ut_ad(page_rec_is_user_rec(rec));
@@ -525,31 +522,26 @@ lock_clust_rec_cons_read_sees(
return(read_view_sees_trx_id(view, trx_id));
}
-/*************************************************************************
-Checks that a non-clustered index record is seen in a consistent read. */
+/*********************************************************************//**
+Checks that a non-clustered index record is seen in a consistent read.
+
+NOTE that a non-clustered index page contains so little information on
+its modifications that also in the case FALSE, the present version of
+rec may be the right, but we must check this from the clustered index
+record.
+
+@return TRUE if certainly sees, or FALSE if an earlier version of the
+clustered index record might be needed */
UNIV_INTERN
ulint
lock_sec_rec_cons_read_sees(
/*========================*/
- /* out: TRUE if certainly
- sees, or FALSE if an earlier
- version of the clustered index
- record might be needed: NOTE
- that a non-clustered index
- page contains so little
- information on its
- modifications that also in the
- case FALSE, the present
- version of rec may be the
- right, but we must check this
- from the clustered index
- record */
- const rec_t* rec, /* in: user record which
+ const rec_t* rec, /*!< in: user record which
should be read or passed over
by a read cursor */
- const read_view_t* view) /* in: consistent read view */
+ const read_view_t* view) /*!< in: consistent read view */
{
- dulint max_trx_id;
+ trx_id_t max_trx_id;
ut_ad(page_rec_is_user_rec(rec));
@@ -563,17 +555,18 @@ lock_sec_rec_cons_read_sees(
}
max_trx_id = page_get_max_trx_id(page_align(rec));
+ ut_ad(!ut_dulint_is_zero(max_trx_id));
return(ut_dulint_cmp(max_trx_id, view->up_limit_id) < 0);
}
-/*************************************************************************
+/*********************************************************************//**
Creates the lock system at database start. */
UNIV_INTERN
void
lock_sys_create(
/*============*/
- ulint n_cells) /* in: number of slots in lock hash table */
+ ulint n_cells) /*!< in: number of slots in lock hash table */
{
lock_sys = mem_alloc(sizeof(lock_sys_t));
@@ -585,39 +578,39 @@ lock_sys_create(
ut_a(lock_latest_err_file);
}
-/*************************************************************************
-Gets the size of a lock struct. */
+/*********************************************************************//**
+Gets the size of a lock struct.
+@return size in bytes */
UNIV_INTERN
ulint
lock_get_size(void)
/*===============*/
- /* out: size in bytes */
{
return((ulint)sizeof(lock_t));
}
-/*************************************************************************
-Gets the mode of a lock. */
+/*********************************************************************//**
+Gets the mode of a lock.
+@return mode */
UNIV_INLINE
enum lock_mode
lock_get_mode(
/*==========*/
- /* out: mode */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ut_ad(lock);
return(lock->type_mode & LOCK_MODE_MASK);
}
-/*************************************************************************
-Gets the wait flag of a lock. */
+/*********************************************************************//**
+Gets the wait flag of a lock.
+@return TRUE if waiting */
UNIV_INLINE
ibool
lock_get_wait(
/*==========*/
- /* out: TRUE if waiting */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ut_ad(lock);
@@ -629,21 +622,20 @@ lock_get_wait(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Gets the source table of an ALTER TABLE transaction. The table must be
-covered by an IX or IS table lock. */
+covered by an IX or IS table lock.
+@return the source table of transaction, if it is covered by an IX or
+IS table lock; dest if there is no source table, and NULL if the
+transaction is locking more than two tables or an inconsistency is
+found */
UNIV_INTERN
dict_table_t*
lock_get_src_table(
/*===============*/
- /* out: the source table of transaction,
- if it is covered by an IX or IS table lock;
- dest if there is no source table, and
- NULL if the transaction is locking more than
- two tables or an inconsistency is found */
- trx_t* trx, /* in: transaction */
- dict_table_t* dest, /* in: destination of ALTER TABLE */
- enum lock_mode* mode) /* out: lock mode of the source table */
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* dest, /*!< in: destination of ALTER TABLE */
+ enum lock_mode* mode) /*!< out: lock mode of the source table */
{
dict_table_t* src;
lock_t* lock;
@@ -699,18 +691,18 @@ lock_get_src_table(
return(src);
}
-/*************************************************************************
+/*********************************************************************//**
Determine if the given table is exclusively "owned" by the given
transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
-on the table. */
+on the table.
+@return TRUE if table is only locked by trx, with LOCK_IX, and
+possibly LOCK_AUTO_INC */
UNIV_INTERN
ibool
lock_is_table_exclusive(
/*====================*/
- /* out: TRUE if table is only locked by trx,
- with LOCK_IX, and possibly LOCK_AUTO_INC */
- dict_table_t* table, /* in: table */
- trx_t* trx) /* in: transaction */
+ dict_table_t* table, /*!< in: table */
+ trx_t* trx) /*!< in: transaction */
{
const lock_t* lock;
ibool ok = FALSE;
@@ -756,14 +748,14 @@ func_exit:
return(ok);
}
-/*************************************************************************
+/*********************************************************************//**
Sets the wait flag of a lock and the back pointer in trx to lock. */
UNIV_INLINE
void
lock_set_lock_and_trx_wait(
/*=======================*/
- lock_t* lock, /* in: lock */
- trx_t* trx) /* in: trx */
+ lock_t* lock, /*!< in: lock */
+ trx_t* trx) /*!< in: trx */
{
ut_ad(lock);
ut_ad(trx->wait_lock == NULL);
@@ -772,14 +764,14 @@ lock_set_lock_and_trx_wait(
lock->type_mode |= LOCK_WAIT;
}
-/**************************************************************************
+/**********************************************************************//**
The back pointer to a waiting lock request in the transaction is set to NULL
and the wait bit in lock type_mode is reset. */
UNIV_INLINE
void
lock_reset_lock_and_trx_wait(
/*=========================*/
- lock_t* lock) /* in: record lock */
+ lock_t* lock) /*!< in: record lock */
{
ut_ad((lock->trx)->wait_lock == lock);
ut_ad(lock_get_wait(lock));
@@ -790,14 +782,14 @@ lock_reset_lock_and_trx_wait(
lock->type_mode &= ~LOCK_WAIT;
}
-/*************************************************************************
-Gets the gap flag of a record lock. */
+/*********************************************************************//**
+Gets the gap flag of a record lock.
+@return TRUE if gap flag set */
UNIV_INLINE
ibool
lock_rec_get_gap(
/*=============*/
- /* out: TRUE if gap flag set */
- const lock_t* lock) /* in: record lock */
+ const lock_t* lock) /*!< in: record lock */
{
ut_ad(lock);
ut_ad(lock_get_type_low(lock) == LOCK_REC);
@@ -810,14 +802,14 @@ lock_rec_get_gap(
return(FALSE);
}
-/*************************************************************************
-Gets the LOCK_REC_NOT_GAP flag of a record lock. */
+/*********************************************************************//**
+Gets the LOCK_REC_NOT_GAP flag of a record lock.
+@return TRUE if LOCK_REC_NOT_GAP flag set */
UNIV_INLINE
ibool
lock_rec_get_rec_not_gap(
/*=====================*/
- /* out: TRUE if LOCK_REC_NOT_GAP flag set */
- const lock_t* lock) /* in: record lock */
+ const lock_t* lock) /*!< in: record lock */
{
ut_ad(lock);
ut_ad(lock_get_type_low(lock) == LOCK_REC);
@@ -830,14 +822,14 @@ lock_rec_get_rec_not_gap(
return(FALSE);
}
-/*************************************************************************
-Gets the waiting insert flag of a record lock. */
+/*********************************************************************//**
+Gets the waiting insert flag of a record lock.
+@return TRUE if gap flag set */
UNIV_INLINE
ibool
lock_rec_get_insert_intention(
/*==========================*/
- /* out: TRUE if gap flag set */
- const lock_t* lock) /* in: record lock */
+ const lock_t* lock) /*!< in: record lock */
{
ut_ad(lock);
ut_ad(lock_get_type_low(lock) == LOCK_REC);
@@ -850,16 +842,15 @@ lock_rec_get_insert_intention(
return(FALSE);
}
-/*************************************************************************
-Calculates if lock mode 1 is stronger or equal to lock mode 2. */
+/*********************************************************************//**
+Calculates if lock mode 1 is stronger or equal to lock mode 2.
+@return nonzero if mode1 stronger or equal to mode2 */
UNIV_INLINE
ulint
lock_mode_stronger_or_eq(
/*=====================*/
- /* out: nonzero
- if mode1 stronger or equal to mode2 */
- enum lock_mode mode1, /* in: lock mode */
- enum lock_mode mode2) /* in: lock mode */
+ enum lock_mode mode1, /*!< in: lock mode */
+ enum lock_mode mode2) /*!< in: lock mode */
{
ut_ad(mode1 == LOCK_X || mode1 == LOCK_S || mode1 == LOCK_IX
|| mode1 == LOCK_IS || mode1 == LOCK_AUTO_INC);
@@ -869,15 +860,15 @@ lock_mode_stronger_or_eq(
return((LOCK_MODE_STRONGER_OR_EQ) & LK(mode1, mode2));
}
-/*************************************************************************
-Calculates if lock mode 1 is compatible with lock mode 2. */
+/*********************************************************************//**
+Calculates if lock mode 1 is compatible with lock mode 2.
+@return nonzero if mode1 compatible with mode2 */
UNIV_INLINE
ulint
lock_mode_compatible(
/*=================*/
- /* out: nonzero if mode1 compatible with mode2 */
- enum lock_mode mode1, /* in: lock mode */
- enum lock_mode mode2) /* in: lock mode */
+ enum lock_mode mode1, /*!< in: lock mode */
+ enum lock_mode mode2) /*!< in: lock mode */
{
ut_ad(mode1 == LOCK_X || mode1 == LOCK_S || mode1 == LOCK_IX
|| mode1 == LOCK_IS || mode1 == LOCK_AUTO_INC);
@@ -887,24 +878,23 @@ lock_mode_compatible(
return((LOCK_MODE_COMPATIBILITY) & LK(mode1, mode2));
}
-/*************************************************************************
-Checks if a lock request for a new lock has to wait for request lock2. */
+/*********************************************************************//**
+Checks if a lock request for a new lock has to wait for request lock2.
+@return TRUE if new lock has to wait for lock2 to be removed */
UNIV_INLINE
ibool
lock_rec_has_to_wait(
/*=================*/
- /* out: TRUE if new lock has to wait
- for lock2 to be removed */
- const trx_t* trx, /* in: trx of new lock */
- ulint type_mode,/* in: precise mode of the new lock
+ const trx_t* trx, /*!< in: trx of new lock */
+ ulint type_mode,/*!< in: precise mode of the new lock
to set: LOCK_S or LOCK_X, possibly
ORed to LOCK_GAP or LOCK_REC_NOT_GAP,
LOCK_INSERT_INTENTION */
- const lock_t* lock2, /* in: another record lock; NOTE that
+ const lock_t* lock2, /*!< in: another record lock; NOTE that
it is assumed that this has a lock bit
set on the same record as in the new
lock we are setting */
- ibool lock_is_on_supremum) /* in: TRUE if we are setting the
+ ibool lock_is_on_supremum) /*!< in: TRUE if we are setting the
lock on the 'supremum' record of an
index page: we know then that the lock
request is really for a 'gap' type lock */
@@ -970,16 +960,15 @@ lock_rec_has_to_wait(
return(FALSE);
}
-/*************************************************************************
-Checks if a lock request lock1 has to wait for request lock2. */
+/*********************************************************************//**
+Checks if a lock request lock1 has to wait for request lock2.
+@return TRUE if lock1 has to wait for lock2 to be removed */
UNIV_INTERN
ibool
lock_has_to_wait(
/*=============*/
- /* out: TRUE if lock1 has to wait for
- lock2 to be removed */
- const lock_t* lock1, /* in: waiting lock */
- const lock_t* lock2) /* in: another lock; NOTE that it is
+ const lock_t* lock1, /*!< in: waiting lock */
+ const lock_t* lock2) /*!< in: another lock; NOTE that it is
assumed that this has a lock bit set
on the same record as in lock1 if the
locks are record locks */
@@ -1009,26 +998,26 @@ lock_has_to_wait(
/*============== RECORD LOCK BASIC FUNCTIONS ============================*/
-/*************************************************************************
-Gets the number of bits in a record lock bitmap. */
+/*********************************************************************//**
+Gets the number of bits in a record lock bitmap.
+@return number of bits */
UNIV_INLINE
ulint
lock_rec_get_n_bits(
/*================*/
- /* out: number of bits */
- const lock_t* lock) /* in: record lock */
+ const lock_t* lock) /*!< in: record lock */
{
return(lock->un_member.rec_lock.n_bits);
}
-/**************************************************************************
+/**********************************************************************//**
Sets the nth bit of a record lock to TRUE. */
UNIV_INLINE
void
lock_rec_set_nth_bit(
/*=================*/
- lock_t* lock, /* in: record lock */
- ulint i) /* in: index of the bit */
+ lock_t* lock, /*!< in: record lock */
+ ulint i) /*!< in: index of the bit */
{
ulint byte_index;
ulint bit_index;
@@ -1043,16 +1032,16 @@ lock_rec_set_nth_bit(
((byte*) &lock[1])[byte_index] |= 1 << bit_index;
}
-/**************************************************************************
+/**********************************************************************//**
Looks for a set bit in a record lock bitmap. Returns ULINT_UNDEFINED,
-if none found. */
+if none found.
+@return bit index == heap number of the record, or ULINT_UNDEFINED if
+none found */
UNIV_INTERN
ulint
lock_rec_find_set_bit(
/*==================*/
- /* out: bit index == heap number of
- the record, or ULINT_UNDEFINED if none found */
- const lock_t* lock) /* in: record lock with at least one bit set */
+ const lock_t* lock) /*!< in: record lock with at least one bit set */
{
ulint i;
@@ -1067,14 +1056,14 @@ lock_rec_find_set_bit(
return(ULINT_UNDEFINED);
}
-/**************************************************************************
+/**********************************************************************//**
Resets the nth bit of a record lock. */
UNIV_INLINE
void
lock_rec_reset_nth_bit(
/*===================*/
- lock_t* lock, /* in: record lock */
- ulint i) /* in: index of the bit which must be set to TRUE
+ lock_t* lock, /*!< in: record lock */
+ ulint i) /*!< in: index of the bit which must be set to TRUE
when this function is called */
{
ulint byte_index;
@@ -1090,14 +1079,14 @@ lock_rec_reset_nth_bit(
((byte*) &lock[1])[byte_index] &= ~(1 << bit_index);
}
-/*************************************************************************
-Gets the first or next record lock on a page. */
+/*********************************************************************//**
+Gets the first or next record lock on a page.
+@return next lock, NULL if none exists */
UNIV_INLINE
lock_t*
lock_rec_get_next_on_page(
/*======================*/
- /* out: next lock, NULL if none exists */
- lock_t* lock) /* in: a record lock */
+ lock_t* lock) /*!< in: a record lock */
{
ulint space;
ulint page_no;
@@ -1126,16 +1115,16 @@ lock_rec_get_next_on_page(
return(lock);
}
-/*************************************************************************
+/*********************************************************************//**
Gets the first record lock on a page, where the page is identified by its
-file address. */
+file address.
+@return first lock, NULL if none exists */
UNIV_INLINE
lock_t*
lock_rec_get_first_on_page_addr(
/*============================*/
- /* out: first lock, NULL if none exists */
- ulint space, /* in: space */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no)/*!< in: page number */
{
lock_t* lock;
@@ -1156,16 +1145,15 @@ lock_rec_get_first_on_page_addr(
return(lock);
}
-/*************************************************************************
-Returns TRUE if there are explicit record locks on a page. */
+/*********************************************************************//**
+Returns TRUE if there are explicit record locks on a page.
+@return TRUE if there are explicit record locks on the page */
UNIV_INTERN
ibool
lock_rec_expl_exist_on_page(
/*========================*/
- /* out: TRUE if there are explicit record locks on
- the page */
- ulint space, /* in: space id */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space id */
+ ulint page_no)/*!< in: page number */
{
ibool ret;
@@ -1182,16 +1170,15 @@ lock_rec_expl_exist_on_page(
return(ret);
}
-/*************************************************************************
+/*********************************************************************//**
Gets the first record lock on a page, where the page is identified by a
-pointer to it. */
+pointer to it.
+@return first lock, NULL if none exists */
UNIV_INLINE
lock_t*
lock_rec_get_first_on_page(
/*=======================*/
- /* out: first lock, NULL if
- none exists */
- const buf_block_t* block) /* in: buffer block */
+ const buf_block_t* block) /*!< in: buffer block */
{
ulint hash;
lock_t* lock;
@@ -1217,15 +1204,15 @@ lock_rec_get_first_on_page(
return(lock);
}
-/*************************************************************************
-Gets the next explicit lock request on a record. */
+/*********************************************************************//**
+Gets the next explicit lock request on a record.
+@return next lock, NULL if none exists */
UNIV_INLINE
lock_t*
lock_rec_get_next(
/*==============*/
- /* out: next lock, NULL if none exists */
- ulint heap_no,/* in: heap number of the record */
- lock_t* lock) /* in: lock */
+ ulint heap_no,/*!< in: heap number of the record */
+ lock_t* lock) /*!< in: lock */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -1237,16 +1224,15 @@ lock_rec_get_next(
return(lock);
}
-/*************************************************************************
-Gets the first explicit lock request on a record. */
+/*********************************************************************//**
+Gets the first explicit lock request on a record.
+@return first lock, NULL if none exists */
UNIV_INLINE
lock_t*
lock_rec_get_first(
/*===============*/
- /* out: first lock, NULL if
- none exists */
- const buf_block_t* block, /* in: block containing the record */
- ulint heap_no)/* in: heap number of the record */
+ const buf_block_t* block, /*!< in: block containing the record */
+ ulint heap_no)/*!< in: heap number of the record */
{
lock_t* lock;
@@ -1262,7 +1248,7 @@ lock_rec_get_first(
return(lock);
}
-/*************************************************************************
+/*********************************************************************//**
Resets the record lock bitmap to zero. NOTE: does not touch the wait_lock
pointer in the transaction! This function is used in lock object creation
and resetting. */
@@ -1270,7 +1256,7 @@ static
void
lock_rec_bitmap_reset(
/*==================*/
- lock_t* lock) /* in: record lock */
+ lock_t* lock) /*!< in: record lock */
{
ulint n_bytes;
@@ -1286,15 +1272,15 @@ lock_rec_bitmap_reset(
memset(&lock[1], 0, n_bytes);
}
-/*************************************************************************
-Copies a record lock to heap. */
+/*********************************************************************//**
+Copies a record lock to heap.
+@return copy of lock */
static
lock_t*
lock_rec_copy(
/*==========*/
- /* out: copy of lock */
- const lock_t* lock, /* in: record lock */
- mem_heap_t* heap) /* in: memory heap */
+ const lock_t* lock, /*!< in: record lock */
+ mem_heap_t* heap) /*!< in: memory heap */
{
ulint size;
@@ -1305,16 +1291,15 @@ lock_rec_copy(
return(mem_heap_dup(heap, lock, size));
}
-/*************************************************************************
-Gets the previous record lock set on a record. */
+/*********************************************************************//**
+Gets the previous record lock set on a record.
+@return previous lock on the same record, NULL if none exists */
UNIV_INTERN
const lock_t*
lock_rec_get_prev(
/*==============*/
- /* out: previous lock on the same
- record, NULL if none exists */
- const lock_t* in_lock,/* in: record lock */
- ulint heap_no)/* in: heap number of the record */
+ const lock_t* in_lock,/*!< in: record lock */
+ ulint heap_no)/*!< in: heap number of the record */
{
lock_t* lock;
ulint space;
@@ -1348,16 +1333,16 @@ lock_rec_get_prev(
/*============= FUNCTIONS FOR ANALYZING TABLE LOCK QUEUE ================*/
-/*************************************************************************
-Checks if a transaction has the specified table lock, or stronger. */
+/*********************************************************************//**
+Checks if a transaction has the specified table lock, or stronger.
+@return lock or NULL */
UNIV_INLINE
lock_t*
lock_table_has(
/*===========*/
- /* out: lock or NULL */
- trx_t* trx, /* in: transaction */
- dict_table_t* table, /* in: table */
- enum lock_mode mode) /* in: lock mode */
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table, /*!< in: table */
+ enum lock_mode mode) /*!< in: lock mode */
{
lock_t* lock;
@@ -1388,23 +1373,23 @@ lock_table_has(
/*============= FUNCTIONS FOR ANALYZING RECORD LOCK QUEUE ================*/
-/*************************************************************************
+/*********************************************************************//**
Checks if a transaction has a GRANTED explicit lock on rec stronger or equal
-to precise_mode. */
+to precise_mode.
+@return lock or NULL */
UNIV_INLINE
lock_t*
lock_rec_has_expl(
/*==============*/
- /* out: lock or NULL */
- ulint precise_mode,/* in: LOCK_S or LOCK_X
+ ulint precise_mode,/*!< in: LOCK_S or LOCK_X
possibly ORed to LOCK_GAP or
LOCK_REC_NOT_GAP, for a
supremum record we regard this
always a gap type request */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of the record */
- trx_t* trx) /* in: transaction */
+ ulint heap_no,/*!< in: heap number of the record */
+ trx_t* trx) /*!< in: transaction */
{
lock_t* lock;
@@ -1438,25 +1423,24 @@ lock_rec_has_expl(
}
#ifdef UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
-/*************************************************************************
-Checks if some other transaction has a lock request in the queue. */
+/*********************************************************************//**
+Checks if some other transaction has a lock request in the queue.
+@return lock or NULL */
static
lock_t*
lock_rec_other_has_expl_req(
/*========================*/
- /* out: lock or NULL */
- enum lock_mode mode, /* in: LOCK_S or LOCK_X */
- ulint gap, /* in: LOCK_GAP if also gap
+ enum lock_mode mode, /*!< in: LOCK_S or LOCK_X */
+ ulint gap, /*!< in: LOCK_GAP if also gap
locks are taken into account,
or 0 if not */
- ulint wait, /* in: LOCK_WAIT if also
+ ulint wait, /*!< in: LOCK_WAIT if also
waiting locks are taken into
account, or 0 if not */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of the record */
- const trx_t* trx) /* in: transaction, or NULL if
+ ulint heap_no,/*!< in: heap number of the record */
+ const trx_t* trx) /*!< in: transaction, or NULL if
requests by all transactions
are taken into account */
{
@@ -1485,25 +1469,24 @@ lock_rec_other_has_expl_req(
return(NULL);
}
-# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG */
-/*************************************************************************
+/*********************************************************************//**
Checks if some other transaction has a conflicting explicit lock request
-in the queue, so that we have to wait. */
+in the queue, so that we have to wait.
+@return lock or NULL */
static
lock_t*
lock_rec_other_has_conflicting(
/*===========================*/
- /* out: lock or NULL */
- enum lock_mode mode, /* in: LOCK_S or LOCK_X,
+ enum lock_mode mode, /*!< in: LOCK_S or LOCK_X,
possibly ORed to LOCK_GAP or
LOC_REC_NOT_GAP,
LOCK_INSERT_INTENTION */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of the record */
- trx_t* trx) /* in: our transaction */
+ ulint heap_no,/*!< in: heap number of the record */
+ trx_t* trx) /*!< in: our transaction */
{
lock_t* lock;
@@ -1538,19 +1521,19 @@ lock_rec_other_has_conflicting(
return(NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Looks for a suitable type record lock struct by the same trx on the same page.
This can be used to save space when a new record lock should be set on a page:
-no new struct is needed, if a suitable old is found. */
+no new struct is needed, if a suitable old is found.
+@return lock or NULL */
UNIV_INLINE
lock_t*
lock_rec_find_similar_on_page(
/*==========================*/
- /* out: lock or NULL */
- ulint type_mode, /* in: lock type_mode field */
- ulint heap_no, /* in: heap number of the record */
- lock_t* lock, /* in: lock_rec_get_first_on_page() */
- const trx_t* trx) /* in: transaction */
+ ulint type_mode, /*!< in: lock type_mode field */
+ ulint heap_no, /*!< in: heap number of the record */
+ lock_t* lock, /*!< in: lock_rec_get_first_on_page() */
+ const trx_t* trx) /*!< in: transaction */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -1568,18 +1551,17 @@ lock_rec_find_similar_on_page(
return(NULL);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if some transaction has an implicit x-lock on a record in a secondary
-index. */
+index.
+@return transaction which has the x-lock, or NULL */
static
trx_t*
lock_sec_rec_some_has_impl_off_kernel(
/*==================================*/
- /* out: transaction which has the x-lock, or
- NULL */
- const rec_t* rec, /* in: user record */
- dict_index_t* index, /* in: secondary index */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ const rec_t* rec, /*!< in: user record */
+ dict_index_t* index, /*!< in: secondary index */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
const page_t* page = page_align(rec);
@@ -1616,7 +1598,7 @@ lock_sec_rec_some_has_impl_off_kernel(
return(row_vers_impl_x_locked_off_kernel(rec, index, offsets));
}
-/*************************************************************************
+/*********************************************************************//**
Return approximate number or record locks (bits set in the bitmap) for
this transaction. Since delete-marked records may be removed, the
record count will not be precise. */
@@ -1624,7 +1606,7 @@ UNIV_INTERN
ulint
lock_number_of_rows_locked(
/*=======================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
lock_t* lock;
ulint n_records = 0;
@@ -1652,22 +1634,22 @@ lock_number_of_rows_locked(
/*============== RECORD LOCK CREATION AND QUEUE MANAGEMENT =============*/
-/*************************************************************************
+/*********************************************************************//**
Creates a new record lock and inserts it to the lock queue. Does NOT check
-for deadlocks or lock compatibility! */
+for deadlocks or lock compatibility!
+@return created lock */
static
lock_t*
lock_rec_create(
/*============*/
- /* out: created lock */
- ulint type_mode,/* in: lock mode and wait
+ ulint type_mode,/*!< in: lock mode and wait
flag, type is ignored and
replaced by LOCK_REC */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of the record */
- dict_index_t* index, /* in: index of record */
- trx_t* trx) /* in: transaction */
+ ulint heap_no,/*!< in: heap number of the record */
+ dict_index_t* index, /*!< in: index of record */
+ trx_t* trx) /*!< in: transaction */
{
lock_t* lock;
ulint page_no;
@@ -1729,23 +1711,18 @@ lock_rec_create(
return(lock);
}
-/*************************************************************************
+/*********************************************************************//**
Enqueues a waiting request for a lock which cannot be granted immediately.
-Checks for deadlocks. */
+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 */
static
ulint
lock_rec_enqueue_waiting(
/*=====================*/
- /* out: 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 */
- ulint type_mode,/* in: lock mode this
+ ulint type_mode,/*!< in: lock mode this
transaction is requesting:
LOCK_S or LOCK_X, possibly
ORed with LOCK_GAP or
@@ -1754,11 +1731,11 @@ lock_rec_enqueue_waiting(
waiting lock request is set
when performing an insert of
an index record */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of the record */
- dict_index_t* index, /* in: index of record */
- que_thr_t* thr) /* in: query thread */
+ ulint heap_no,/*!< in: heap number of the record */
+ dict_index_t* index, /*!< in: index of record */
+ que_thr_t* thr) /*!< in: query thread */
{
lock_t* lock;
trx_t* trx;
@@ -1834,26 +1811,26 @@ lock_rec_enqueue_waiting(
return(DB_LOCK_WAIT);
}
-/*************************************************************************
+/*********************************************************************//**
Adds a record lock request in the record queue. The request is normally
added as the last in the queue, but if there are no waiting lock requests
on the record, and the request to be added is not a waiting request, we
can reuse a suitable record lock object already existing on the same page,
just setting the appropriate bit in its bitmap. This is a low-level function
-which does NOT check for deadlocks or lock compatibility! */
+which does NOT check for deadlocks or lock compatibility!
+@return lock where the bit was set */
static
lock_t*
lock_rec_add_to_queue(
/*==================*/
- /* out: lock where the bit was set */
- ulint type_mode,/* in: lock mode, wait, gap
+ ulint type_mode,/*!< in: lock mode, wait, gap
etc. flags; type is ignored
and replaced by LOCK_REC */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of the record */
- dict_index_t* index, /* in: index of record */
- trx_t* trx) /* in: transaction */
+ ulint heap_no,/*!< in: heap number of the record */
+ dict_index_t* index, /*!< in: index of record */
+ trx_t* trx) /*!< in: transaction */
{
lock_t* lock;
@@ -1930,30 +1907,30 @@ somebody_waits:
return(lock_rec_create(type_mode, block, heap_no, index, trx));
}
-/*************************************************************************
+/*********************************************************************//**
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
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. */
+a page supremum record, a gap type lock.
+@return TRUE if locking succeeded */
UNIV_INLINE
ibool
lock_rec_lock_fast(
/*===============*/
- /* out: TRUE if locking succeeded */
- ibool impl, /* in: if TRUE, no lock is set
+ ibool impl, /*!< in: if TRUE, no lock is set
if no wait is necessary: we
assume that the caller will
set an implicit lock */
- ulint mode, /* in: lock mode: LOCK_X or
+ ulint mode, /*!< in: lock mode: LOCK_X or
LOCK_S possibly ORed to either
LOCK_GAP or LOCK_REC_NOT_GAP */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of record */
- dict_index_t* index, /* in: index of record */
- que_thr_t* thr) /* in: query thread */
+ ulint heap_no,/*!< in: heap number of record */
+ dict_index_t* index, /*!< in: index of record */
+ que_thr_t* thr) /*!< in: query thread */
{
lock_t* lock;
trx_t* trx;
@@ -2005,29 +1982,28 @@ lock_rec_lock_fast(
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
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. */
+lock, or in the case of a page supremum record, a gap type lock.
+@return DB_SUCCESS, DB_LOCK_WAIT, or error code */
static
ulint
lock_rec_lock_slow(
/*===============*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, or error code */
- ibool impl, /* in: if TRUE, no lock is set
+ ibool impl, /*!< in: if TRUE, no lock is set
if no wait is necessary: we
assume that the caller will
set an implicit lock */
- ulint mode, /* in: lock mode: LOCK_X or
+ ulint mode, /*!< in: lock mode: LOCK_X or
LOCK_S possibly ORed to either
LOCK_GAP or LOCK_REC_NOT_GAP */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of record */
- dict_index_t* index, /* in: index of record */
- que_thr_t* thr) /* in: query thread */
+ ulint heap_no,/*!< in: heap number of record */
+ dict_index_t* index, /*!< in: index of record */
+ que_thr_t* thr) /*!< in: query thread */
{
trx_t* trx;
ulint err;
@@ -2072,30 +2048,29 @@ lock_rec_lock_slow(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Tries to lock the specified record in the mode requested. If not immediately
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. */
+of a page supremum record, a gap type lock.
+@return DB_SUCCESS, DB_LOCK_WAIT, or error code */
static
ulint
lock_rec_lock(
/*==========*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, or error code */
- ibool impl, /* in: if TRUE, no lock is set
+ ibool impl, /*!< in: if TRUE, no lock is set
if no wait is necessary: we
assume that the caller will
set an implicit lock */
- ulint mode, /* in: lock mode: LOCK_X or
+ ulint mode, /*!< in: lock mode: LOCK_X or
LOCK_S possibly ORed to either
LOCK_GAP or LOCK_REC_NOT_GAP */
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no,/* in: heap number of record */
- dict_index_t* index, /* in: index of record */
- que_thr_t* thr) /* in: query thread */
+ ulint heap_no,/*!< in: heap number of record */
+ dict_index_t* index, /*!< in: index of record */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
@@ -2124,14 +2099,14 @@ lock_rec_lock(
return(err);
}
-/*************************************************************************
-Checks if a waiting record lock request still has to wait in a queue. */
+/*********************************************************************//**
+Checks if a waiting record lock request still has to wait in a queue.
+@return TRUE if still has to wait */
static
ibool
lock_rec_has_to_wait_in_queue(
/*==========================*/
- /* out: TRUE if still has to wait */
- lock_t* wait_lock) /* in: waiting record lock */
+ lock_t* wait_lock) /*!< in: waiting record lock */
{
lock_t* lock;
ulint space;
@@ -2162,14 +2137,14 @@ lock_rec_has_to_wait_in_queue(
return(FALSE);
}
-/*****************************************************************
+/*************************************************************//**
Grants a lock to a waiting lock request and releases the waiting
transaction. */
static
void
lock_grant(
/*=======*/
- lock_t* lock) /* in/out: waiting lock request */
+ lock_t* lock) /*!< in/out: waiting lock request */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -2207,7 +2182,7 @@ lock_grant(
}
}
-/*****************************************************************
+/*************************************************************//**
Cancels a waiting record lock request and releases the waiting transaction
that requested it. NOTE: does NOT check if waiting lock requests behind this
one can now be granted! */
@@ -2215,7 +2190,7 @@ static
void
lock_rec_cancel(
/*============*/
- lock_t* lock) /* in: waiting record lock request */
+ lock_t* lock) /*!< in: waiting record lock request */
{
ut_ad(mutex_own(&kernel_mutex));
ut_ad(lock_get_type_low(lock) == LOCK_REC);
@@ -2232,7 +2207,7 @@ lock_rec_cancel(
trx_end_lock_wait(lock->trx);
}
-/*****************************************************************
+/*************************************************************//**
Removes a record lock request, waiting or granted, from the queue and
grants locks to other transactions in the queue if they now are entitled
to a lock. NOTE: all record locks contained in in_lock are removed. */
@@ -2240,7 +2215,7 @@ static
void
lock_rec_dequeue_from_page(
/*=======================*/
- lock_t* in_lock)/* in: record lock object: all record locks which
+ lock_t* in_lock)/*!< in: record lock object: all record locks which
are contained in this lock object are removed;
transactions waiting behind will get their lock
requests granted, if they are now qualified to it */
@@ -2280,13 +2255,13 @@ lock_rec_dequeue_from_page(
}
}
-/*****************************************************************
+/*************************************************************//**
Removes a record lock request, waiting or granted, from the queue. */
static
void
lock_rec_discard(
/*=============*/
- lock_t* in_lock)/* in: record lock object: all record locks which
+ lock_t* in_lock)/*!< in: record lock object: all record locks which
are contained in this lock object are removed */
{
ulint space;
@@ -2307,7 +2282,7 @@ lock_rec_discard(
UT_LIST_REMOVE(trx_locks, trx->trx_locks, in_lock);
}
-/*****************************************************************
+/*************************************************************//**
Removes record lock objects set on an index page which is discarded. This
function does not move locks, or check for waiting locks, therefore the
lock bitmaps must already be reset when this function is called. */
@@ -2315,7 +2290,7 @@ static
void
lock_rec_free_all_from_discard_page(
/*================================*/
- const buf_block_t* block) /* in: page to be discarded */
+ const buf_block_t* block) /*!< in: page to be discarded */
{
ulint space;
ulint page_no;
@@ -2343,16 +2318,16 @@ lock_rec_free_all_from_discard_page(
/*============= RECORD LOCK MOVING AND INHERITING ===================*/
-/*****************************************************************
+/*************************************************************//**
Resets the lock bits for a single record. Releases transactions waiting for
lock requests here. */
static
void
lock_rec_reset_and_release_wait(
/*============================*/
- const buf_block_t* block, /* in: buffer block containing
+ const buf_block_t* block, /*!< in: buffer block containing
the record */
- ulint heap_no)/* in: heap number of record */
+ ulint heap_no)/*!< in: heap number of record */
{
lock_t* lock;
@@ -2371,7 +2346,7 @@ lock_rec_reset_and_release_wait(
}
}
-/*****************************************************************
+/*************************************************************//**
Makes a record to inherit the locks (except LOCK_INSERT_INTENTION type)
of another record as gap type locks, but does not reset the lock bits of
the other record. Also waiting lock requests on rec are inherited as
@@ -2380,15 +2355,15 @@ static
void
lock_rec_inherit_to_gap(
/*====================*/
- const buf_block_t* heir_block, /* in: block containing the
+ const buf_block_t* heir_block, /*!< in: block containing the
record which inherits */
- const buf_block_t* block, /* in: block containing the
+ const buf_block_t* block, /*!< in: block containing the
record from which inherited;
does NOT reset the locks on
this record */
- ulint heir_heap_no, /* in: heap_no of the
+ ulint heir_heap_no, /*!< in: heap_no of the
inheriting record */
- ulint heap_no) /* in: heap_no of the
+ ulint heap_no) /*!< in: heap_no of the
donating record */
{
lock_t* lock;
@@ -2420,7 +2395,7 @@ lock_rec_inherit_to_gap(
}
}
-/*****************************************************************
+/*************************************************************//**
Makes a record to inherit the gap locks (except LOCK_INSERT_INTENTION type)
of another record as gap type locks, but does not reset the lock bits of the
other record. Also waiting lock requests are inherited as GRANTED gap locks. */
@@ -2428,10 +2403,10 @@ static
void
lock_rec_inherit_to_gap_if_gap_lock(
/*================================*/
- const buf_block_t* block, /* in: buffer block */
- ulint heir_heap_no, /* in: heap_no of
+ const buf_block_t* block, /*!< in: buffer block */
+ ulint heir_heap_no, /*!< in: heap_no of
record which inherits */
- ulint heap_no) /* in: heap_no of record
+ ulint heap_no) /*!< in: heap_no of record
from which inherited;
does NOT reset the locks
on this record */
@@ -2457,22 +2432,22 @@ lock_rec_inherit_to_gap_if_gap_lock(
}
}
-/*****************************************************************
+/*************************************************************//**
Moves the locks of a record to another record and resets the lock bits of
the donating record. */
static
void
lock_rec_move(
/*==========*/
- const buf_block_t* receiver, /* in: buffer block containing
+ const buf_block_t* receiver, /*!< in: buffer block containing
the receiving record */
- const buf_block_t* donator, /* in: buffer block containing
+ const buf_block_t* donator, /*!< in: buffer block containing
the donating record */
- ulint receiver_heap_no,/* in: heap_no of the record
+ ulint receiver_heap_no,/*!< in: heap_no of the record
which gets the locks; there
must be no lock requests
on it! */
- ulint donator_heap_no)/* in: heap_no of the record
+ ulint donator_heap_no)/*!< in: heap_no of the record
which gives the locks */
{
lock_t* lock;
@@ -2503,7 +2478,7 @@ lock_rec_move(
ut_ad(lock_rec_get_first(donator, donator_heap_no) == NULL);
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when we have reorganized a page. NOTE: we copy
also the locks set on the infimum of the page; the infimum may carry
locks if an update of a record is occurring on the page, and its locks
@@ -2512,9 +2487,9 @@ UNIV_INTERN
void
lock_move_reorganize_page(
/*======================*/
- const buf_block_t* block, /* in: old index page, now
+ const buf_block_t* block, /*!< in: old index page, now
reorganized */
- const buf_block_t* oblock) /* in: copy of the old, not
+ const buf_block_t* oblock) /*!< in: copy of the old, not
reorganized page */
{
lock_t* lock;
@@ -2651,16 +2626,16 @@ lock_move_reorganize_page(
#endif
}
-/*****************************************************************
+/*************************************************************//**
Moves the explicit locks on user records to another page if a record
list end is moved to another page. */
UNIV_INTERN
void
lock_move_rec_list_end(
/*===================*/
- const buf_block_t* new_block, /* in: index page to move to */
- const buf_block_t* block, /* in: index page */
- const rec_t* rec) /* in: record on page: this
+ const buf_block_t* new_block, /*!< in: index page to move to */
+ const buf_block_t* block, /*!< in: index page */
+ const rec_t* rec) /*!< in: record on page: this
is the first record moved */
{
lock_t* lock;
@@ -2742,19 +2717,19 @@ lock_move_rec_list_end(
#endif
}
-/*****************************************************************
+/*************************************************************//**
Moves the explicit locks on user records to another page if a record
list start is moved to another page. */
UNIV_INTERN
void
lock_move_rec_list_start(
/*=====================*/
- const buf_block_t* new_block, /* in: index page to move to */
- const buf_block_t* block, /* in: index page */
- const rec_t* rec, /* in: record on page:
+ const buf_block_t* new_block, /*!< in: index page to move to */
+ const buf_block_t* block, /*!< in: index page */
+ const rec_t* rec, /*!< in: record on page:
this is the first
record NOT copied */
- const rec_t* old_end) /* in: old
+ const rec_t* old_end) /*!< in: old
previous-to-last
record on new_page
before the records
@@ -2851,14 +2826,14 @@ lock_move_rec_list_start(
#endif
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is split to the right. */
UNIV_INTERN
void
lock_update_split_right(
/*====================*/
- const buf_block_t* right_block, /* in: right page */
- const buf_block_t* left_block) /* in: left page */
+ const buf_block_t* right_block, /*!< in: right page */
+ const buf_block_t* left_block) /*!< in: left page */
{
ulint heap_no = lock_get_min_heap_no(right_block);
@@ -2879,19 +2854,19 @@ lock_update_split_right(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is merged to the right. */
UNIV_INTERN
void
lock_update_merge_right(
/*====================*/
- const buf_block_t* right_block, /* in: right page to
+ const buf_block_t* right_block, /*!< in: right page to
which merged */
- const rec_t* orig_succ, /* in: original
+ const rec_t* orig_succ, /*!< in: original
successor of infimum
on the right page
before merge */
- const buf_block_t* left_block) /* in: merged index
+ const buf_block_t* left_block) /*!< in: merged index
page which will be
discarded */
{
@@ -2916,7 +2891,7 @@ lock_update_merge_right(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when the root page is copied to another in
btr_root_raise_and_insert. Note that we leave lock structs on the
root page, even though they do not make sense on other than leaf
@@ -2927,8 +2902,8 @@ UNIV_INTERN
void
lock_update_root_raise(
/*===================*/
- const buf_block_t* block, /* in: index page to which copied */
- const buf_block_t* root) /* in: root page */
+ const buf_block_t* block, /*!< in: index page to which copied */
+ const buf_block_t* root) /*!< in: root page */
{
lock_mutex_enter_kernel();
@@ -2940,16 +2915,16 @@ lock_update_root_raise(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is copied to another and the original page
is removed from the chain of leaf pages, except if page is the root! */
UNIV_INTERN
void
lock_update_copy_and_discard(
/*=========================*/
- const buf_block_t* new_block, /* in: index page to
+ const buf_block_t* new_block, /*!< in: index page to
which copied */
- const buf_block_t* block) /* in: index page;
+ const buf_block_t* block) /*!< in: index page;
NOT the root! */
{
lock_mutex_enter_kernel();
@@ -2964,14 +2939,14 @@ lock_update_copy_and_discard(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is split to the left. */
UNIV_INTERN
void
lock_update_split_left(
/*===================*/
- const buf_block_t* right_block, /* in: right page */
- const buf_block_t* left_block) /* in: left page */
+ const buf_block_t* right_block, /*!< in: right page */
+ const buf_block_t* left_block) /*!< in: left page */
{
ulint heap_no = lock_get_min_heap_no(right_block);
@@ -2986,18 +2961,18 @@ lock_update_split_left(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is merged to the left. */
UNIV_INTERN
void
lock_update_merge_left(
/*===================*/
- const buf_block_t* left_block, /* in: left page to
+ const buf_block_t* left_block, /*!< in: left page to
which merged */
- const rec_t* orig_pred, /* in: original predecessor
+ const rec_t* orig_pred, /*!< in: original predecessor
of supremum on the left page
before merge */
- const buf_block_t* right_block) /* in: merged index page
+ const buf_block_t* right_block) /*!< in: merged index page
which will be discarded */
{
const rec_t* left_next_rec;
@@ -3035,22 +3010,22 @@ lock_update_merge_left(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Resets the original locks on heir and replaces them with gap type locks
inherited from rec. */
UNIV_INTERN
void
lock_rec_reset_and_inherit_gap_locks(
/*=================================*/
- const buf_block_t* heir_block, /* in: block containing the
+ const buf_block_t* heir_block, /*!< in: block containing the
record which inherits */
- const buf_block_t* block, /* in: block containing the
+ const buf_block_t* block, /*!< in: block containing the
record from which inherited;
does NOT reset the locks on
this record */
- ulint heir_heap_no, /* in: heap_no of the
+ ulint heir_heap_no, /*!< in: heap_no of the
inheriting record */
- ulint heap_no) /* in: heap_no of the
+ ulint heap_no) /*!< in: heap_no of the
donating record */
{
mutex_enter(&kernel_mutex);
@@ -3062,17 +3037,17 @@ lock_rec_reset_and_inherit_gap_locks(
mutex_exit(&kernel_mutex);
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a page is discarded. */
UNIV_INTERN
void
lock_update_discard(
/*================*/
- const buf_block_t* heir_block, /* in: index page
+ const buf_block_t* heir_block, /*!< in: index page
which will inherit the locks */
- ulint heir_heap_no, /* in: heap_no of the record
+ ulint heir_heap_no, /*!< in: heap_no of the record
which will inherit the locks */
- const buf_block_t* block) /* in: index page
+ const buf_block_t* block) /*!< in: index page
which will be discarded */
{
const page_t* page = block->frame;
@@ -3125,14 +3100,14 @@ lock_update_discard(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a new user record is inserted. */
UNIV_INTERN
void
lock_update_insert(
/*===============*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec) /* in: the inserted record */
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec) /*!< in: the inserted record */
{
ulint receiver_heap_no;
ulint donator_heap_no;
@@ -3158,14 +3133,14 @@ lock_update_insert(
lock_mutex_exit_kernel();
}
-/*****************************************************************
+/*************************************************************//**
Updates the lock table when a record is removed. */
UNIV_INTERN
void
lock_update_delete(
/*===============*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec) /* in: the record to be removed */
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec) /*!< in: the record to be removed */
{
const page_t* page = block->frame;
ulint heap_no;
@@ -3198,7 +3173,7 @@ lock_update_delete(
lock_mutex_exit_kernel();
}
-/*************************************************************************
+/*********************************************************************//**
Stores on the page infimum record the explicit locks of another record.
This function is used to store the lock state of a record when it is
updated and the size of the record changes in the update. The record
@@ -3209,8 +3184,8 @@ UNIV_INTERN
void
lock_rec_store_on_page_infimum(
/*===========================*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec) /* in: record whose lock state
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec) /*!< in: record whose lock state
is stored on the infimum
record of the same page; lock
bits are reset on the
@@ -3227,17 +3202,17 @@ lock_rec_store_on_page_infimum(
lock_mutex_exit_kernel();
}
-/*************************************************************************
+/*********************************************************************//**
Restores the state of explicit lock requests on a single record, where the
state was stored on the infimum of the page. */
UNIV_INTERN
void
lock_rec_restore_from_page_infimum(
/*===============================*/
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec, /* in: record whose lock state
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec, /*!< in: record whose lock state
is restored */
- const buf_block_t* donator)/* in: page (rec is not
+ const buf_block_t* donator)/*!< in: page (rec is not
necessarily on this page)
whose infimum stored the lock
state; lock bits are reset on
@@ -3254,18 +3229,17 @@ lock_rec_restore_from_page_infimum(
/*=========== DEADLOCK CHECKING ======================================*/
-/************************************************************************
-Checks if a lock request results in a deadlock. */
+/********************************************************************//**
+Checks if a lock request results in a deadlock.
+@return TRUE if a deadlock was detected and we chose trx as a victim;
+FALSE if no deadlock, or there was a deadlock, but we chose other
+transaction(s) as victim(s) */
static
ibool
lock_deadlock_occurs(
/*=================*/
- /* out: TRUE if a deadlock was detected and we
- chose trx as a victim; FALSE if no deadlock, or
- there was a deadlock, but we chose other
- transaction(s) as victim(s) */
- lock_t* lock, /* in: lock the transaction is requesting */
- trx_t* trx) /* in: transaction */
+ lock_t* lock, /*!< in: lock the transaction is requesting */
+ trx_t* trx) /*!< in: transaction */
{
dict_table_t* table;
dict_index_t* index;
@@ -3317,27 +3291,24 @@ retry:
return(FALSE);
}
-/************************************************************************
-Looks recursively for a deadlock. */
+/********************************************************************//**
+Looks recursively for a deadlock.
+@return 0 if no deadlock found, LOCK_VICTIM_IS_START if there was a
+deadlock and we chose 'start' as the victim, LOCK_VICTIM_IS_OTHER if a
+deadlock was found and we chose some other trx as a victim: we must do
+the search again in this last case because there may be another
+deadlock! */
static
ulint
lock_deadlock_recursive(
/*====================*/
- /* out: 0 if no deadlock found,
- LOCK_VICTIM_IS_START if there was a deadlock
- and we chose 'start' as the victim,
- LOCK_VICTIM_IS_OTHER if a deadlock
- was found and we chose some other trx as a
- victim: we must do the search again in this
- last case because there may be another
- deadlock! */
- trx_t* start, /* in: recursion starting point */
- trx_t* trx, /* in: a transaction waiting for a lock */
- lock_t* wait_lock, /* in: the lock trx is waiting to be granted */
- ulint* cost, /* in/out: number of calculation steps thus
+ trx_t* start, /*!< in: recursion starting point */
+ trx_t* trx, /*!< in: a transaction waiting for a lock */
+ lock_t* wait_lock, /*!< in: the lock trx is waiting to be granted */
+ ulint* cost, /*!< in/out: number of calculation steps thus
far: if this exceeds LOCK_MAX_N_STEPS_...
we return LOCK_VICTIM_IS_START */
- ulint depth) /* in: recursion depth: if this exceeds
+ ulint depth) /*!< in: recursion depth: if this exceeds
LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we
return LOCK_VICTIM_IS_START */
{
@@ -3513,18 +3484,18 @@ lock_deadlock_recursive(
/*========================= TABLE LOCKS ==============================*/
-/*************************************************************************
+/*********************************************************************//**
Creates a table lock object and adds it as the last in the lock queue
-of the table. Does NOT check for deadlocks or lock compatibility. */
+of the table. Does NOT check for deadlocks or lock compatibility.
+@return own: new lock object */
UNIV_INLINE
lock_t*
lock_table_create(
/*==============*/
- /* out, own: new lock object */
- dict_table_t* table, /* in: database table in dictionary cache */
- ulint type_mode,/* in: lock mode possibly ORed with
+ dict_table_t* table, /*!< in: database table in dictionary cache */
+ ulint type_mode,/*!< in: lock mode possibly ORed with
LOCK_WAIT */
- trx_t* trx) /* in: trx */
+ trx_t* trx) /*!< in: trx */
{
lock_t* lock;
@@ -3566,7 +3537,7 @@ lock_table_create(
return(lock);
}
-/*****************************************************************
+/*************************************************************//**
Removes a table lock request from the queue and the trx list of locks;
this is a low-level function which does NOT check if waiting requests
can now be granted. */
@@ -3574,7 +3545,7 @@ UNIV_INLINE
void
lock_table_remove_low(
/*==================*/
- lock_t* lock) /* in: table lock */
+ lock_t* lock) /*!< in: table lock */
{
trx_t* trx;
dict_table_t* table;
@@ -3618,23 +3589,21 @@ lock_table_remove_low(
UT_LIST_REMOVE(un_member.tab_lock.locks, table->locks, lock);
}
-/*************************************************************************
+/*********************************************************************//**
Enqueues a waiting request for a table lock which cannot be granted
-immediately. Checks for deadlocks. */
+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 */
static
ulint
lock_table_enqueue_waiting(
/*=======================*/
- /* out: 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 */
- ulint mode, /* in: lock mode this transaction is
+ ulint mode, /*!< in: lock mode this transaction is
requesting */
- dict_table_t* table, /* in: table */
- que_thr_t* thr) /* in: query thread */
+ dict_table_t* table, /*!< in: table */
+ que_thr_t* thr) /*!< in: query thread */
{
lock_t* lock;
trx_t* trx;
@@ -3700,19 +3669,19 @@ lock_table_enqueue_waiting(
return(DB_LOCK_WAIT);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if other transactions have an incompatible mode lock request in
the lock queue. */
UNIV_INLINE
ibool
lock_table_other_has_incompatible(
/*==============================*/
- trx_t* trx, /* in: transaction, or NULL if all
+ trx_t* trx, /*!< in: transaction, or NULL if all
transactions should be included */
- ulint wait, /* in: LOCK_WAIT if also waiting locks are
+ ulint wait, /*!< in: LOCK_WAIT if also waiting locks are
taken into account, or 0 if not */
- dict_table_t* table, /* in: table */
- enum lock_mode mode) /* in: lock mode */
+ dict_table_t* table, /*!< in: table */
+ enum lock_mode mode) /*!< in: lock mode */
{
lock_t* lock;
@@ -3735,20 +3704,19 @@ lock_table_other_has_incompatible(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Locks the specified database table in the mode given. If the lock cannot
-be granted immediately, the query thread is put to wait. */
+be granted immediately, the query thread is put to wait.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_table(
/*=======*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is set,
does nothing */
- dict_table_t* table, /* in: database table in dictionary cache */
- enum lock_mode mode, /* in: lock mode */
- que_thr_t* thr) /* in: query thread */
+ dict_table_t* table, /*!< in: database table in dictionary cache */
+ enum lock_mode mode, /*!< in: lock mode */
+ que_thr_t* thr) /*!< in: query thread */
{
trx_t* trx;
ulint err;
@@ -3799,40 +3767,14 @@ lock_table(
return(DB_SUCCESS);
}
-/*************************************************************************
-Checks if there are any locks set on the table. */
-UNIV_INTERN
-ibool
-lock_is_on_table(
-/*=============*/
- /* out: TRUE if there are lock(s) */
- dict_table_t* table) /* in: database table in dictionary cache */
-{
- ibool ret;
-
- ut_ad(table);
-
- lock_mutex_enter_kernel();
-
- if (UT_LIST_GET_LAST(table->locks)) {
- ret = TRUE;
- } else {
- ret = FALSE;
- }
-
- lock_mutex_exit_kernel();
-
- return(ret);
-}
-
-/*************************************************************************
-Checks if a waiting table lock request still has to wait in a queue. */
+/*********************************************************************//**
+Checks if a waiting table lock request still has to wait in a queue.
+@return TRUE if still has to wait */
static
ibool
lock_table_has_to_wait_in_queue(
/*============================*/
- /* out: TRUE if still has to wait */
- lock_t* wait_lock) /* in: waiting table lock */
+ lock_t* wait_lock) /*!< in: waiting table lock */
{
dict_table_t* table;
lock_t* lock;
@@ -3857,7 +3799,7 @@ lock_table_has_to_wait_in_queue(
return(FALSE);
}
-/*****************************************************************
+/*************************************************************//**
Removes a table lock request, waiting or granted, from the queue and grants
locks to other transactions in the queue, if they now are entitled to a
lock. */
@@ -3865,7 +3807,7 @@ static
void
lock_table_dequeue(
/*===============*/
- lock_t* in_lock)/* in: table lock object; transactions waiting
+ lock_t* in_lock)/*!< in: table lock object; transactions waiting
behind will get their lock requests granted, if
they are now qualified to it */
{
@@ -3896,7 +3838,7 @@ lock_table_dequeue(
/*=========================== LOCK RELEASE ==============================*/
-/*****************************************************************
+/*************************************************************//**
Removes a granted record lock of a transaction from the queue and grants
locks to other transactions waiting in the queue if they now are entitled
to a lock. */
@@ -3904,11 +3846,11 @@ UNIV_INTERN
void
lock_rec_unlock(
/*============*/
- trx_t* trx, /* in: transaction that has
+ trx_t* trx, /*!< in: transaction that has
set a record lock */
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec, /* in: record */
- enum lock_mode lock_mode)/* in: LOCK_S or LOCK_X */
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec, /*!< in: record */
+ enum lock_mode lock_mode)/*!< in: LOCK_S or LOCK_X */
{
lock_t* lock;
lock_t* release_lock = NULL;
@@ -3968,30 +3910,14 @@ lock_rec_unlock(
mutex_exit(&kernel_mutex);
}
-/*************************************************************************
-Releases a table lock.
-Releases possible other transactions waiting for this lock. */
-UNIV_INTERN
-void
-lock_table_unlock(
-/*==============*/
- lock_t* lock) /* in: lock */
-{
- mutex_enter(&kernel_mutex);
-
- lock_table_dequeue(lock);
-
- mutex_exit(&kernel_mutex);
-}
-
-/*************************************************************************
+/*********************************************************************//**
Releases transaction locks, and releases possible other transactions waiting
because of these locks. */
UNIV_INTERN
void
lock_release_off_kernel(
/*====================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
dict_table_t* table;
ulint count;
@@ -4048,14 +3974,14 @@ lock_release_off_kernel(
mem_heap_empty(trx->lock_heap);
}
-/*************************************************************************
+/*********************************************************************//**
Cancels a waiting lock request and releases possible other transactions
waiting behind it. */
UNIV_INTERN
void
lock_cancel_waiting_and_release(
/*============================*/
- lock_t* lock) /* in: waiting lock request */
+ lock_t* lock) /*!< in: waiting lock request */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -4088,7 +4014,7 @@ lock_cancel_waiting_and_release(
|| lock_get_mode(lock) == LOCK_X)
-/*************************************************************************
+/*********************************************************************//**
Removes locks of a transaction on a table to be dropped.
If remove_also_table_sx_locks is TRUE then table-level S and X locks are
also removed in addition to other table-level and record-level locks.
@@ -4097,9 +4023,9 @@ static
void
lock_remove_all_on_table_for_trx(
/*=============================*/
- dict_table_t* table, /* in: table to be dropped */
- trx_t* trx, /* in: a transaction */
- ibool remove_also_table_sx_locks)/* in: also removes
+ dict_table_t* table, /*!< in: table to be dropped */
+ trx_t* trx, /*!< in: a transaction */
+ ibool remove_also_table_sx_locks)/*!< in: also removes
table S and X locks */
{
lock_t* lock;
@@ -4131,7 +4057,7 @@ lock_remove_all_on_table_for_trx(
}
}
-/*************************************************************************
+/*********************************************************************//**
Removes locks on a table to be dropped or truncated.
If remove_also_table_sx_locks is TRUE then table-level S and X locks are
also removed in addition to other table-level and record-level locks.
@@ -4140,9 +4066,9 @@ UNIV_INTERN
void
lock_remove_all_on_table(
/*=====================*/
- dict_table_t* table, /* in: table to be dropped
+ dict_table_t* table, /*!< in: table to be dropped
or truncated */
- ibool remove_also_table_sx_locks)/* in: also removes
+ ibool remove_also_table_sx_locks)/*!< in: also removes
table S and X locks */
{
lock_t* lock;
@@ -4198,14 +4124,14 @@ lock_remove_all_on_table(
/*===================== VALIDATION AND DEBUGGING ====================*/
-/*************************************************************************
+/*********************************************************************//**
Prints info of a table lock. */
UNIV_INTERN
void
lock_table_print(
/*=============*/
- FILE* file, /* in: file where to print */
- const lock_t* lock) /* in: table type lock */
+ FILE* file, /*!< in: file where to print */
+ const lock_t* lock) /*!< in: table type lock */
{
ut_ad(mutex_own(&kernel_mutex));
ut_a(lock_get_type_low(lock) == LOCK_TABLE);
@@ -4238,14 +4164,14 @@ lock_table_print(
putc('\n', file);
}
-/*************************************************************************
+/*********************************************************************//**
Prints info of a record lock. */
UNIV_INTERN
void
lock_rec_print(
/*===========*/
- FILE* file, /* in: file where to print */
- const lock_t* lock) /* in: record type lock */
+ FILE* file, /*!< in: file where to print */
+ const lock_t* lock) /*!< in: record type lock */
{
const buf_block_t* block;
ulint space;
@@ -4330,8 +4256,6 @@ lock_rec_print(
}
}
-#ifndef UNIV_HOTBACKUP
-
#ifdef UNIV_DEBUG
/* Print the number of lock structs from lock_print_info_summary() only
in non-production builds for performance reasons, see
@@ -4340,8 +4264,9 @@ http://bugs.mysql.com/36942 */
#endif /* UNIV_DEBUG */
#ifdef PRINT_NUM_OF_LOCK_STRUCTS
-/*************************************************************************
-Calculates the number of record lock structs in the record lock hash table. */
+/*********************************************************************//**
+Calculates the number of record lock structs in the record lock hash table.
+@return number of record locks */
static
ulint
lock_get_n_rec_locks(void)
@@ -4368,13 +4293,13 @@ lock_get_n_rec_locks(void)
}
#endif /* PRINT_NUM_OF_LOCK_STRUCTS */
-/*************************************************************************
+/*********************************************************************//**
Prints info of locks for all transactions. */
UNIV_INTERN
void
lock_print_info_summary(
/*====================*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
/* We must protect the MySQL thd->query field with a MySQL mutex, and
because the MySQL mutex must be reserved before the kernel_mutex of
@@ -4415,13 +4340,13 @@ lock_print_info_summary(
#endif /* PRINT_NUM_OF_LOCK_STRUCTS */
}
-/*************************************************************************
+/*********************************************************************//**
Prints info of locks for each transaction. */
UNIV_INTERN
void
lock_print_info_all_transactions(
/*=============================*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
lock_t* lock;
ibool load_page_first = TRUE;
@@ -4532,6 +4457,20 @@ loop:
ulint zip_size= fil_space_get_zip_size(space);
ulint page_no = lock->un_member.rec_lock.page_no;
+ if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
+
+ /* It is a single table tablespace and
+ the .ibd file is missing (TRUNCATE
+ TABLE probably stole the locks): just
+ print the lock without attempting to
+ load the page in the buffer pool. */
+
+ fprintf(file, "RECORD LOCKS on"
+ " non-existing space %lu\n",
+ (ulong) space);
+ goto print_rec;
+ }
+
lock_mutex_exit_kernel();
innobase_mysql_end_print_arbitrary_thd();
@@ -4550,6 +4489,7 @@ loop:
goto loop;
}
+print_rec:
lock_rec_print(file, lock);
} else {
ut_ad(lock_get_type_low(lock) & LOCK_TABLE);
@@ -4575,15 +4515,15 @@ loop:
goto loop;
}
-# ifdef UNIV_DEBUG
-/*************************************************************************
-Validates the lock queue on a table. */
+#ifdef UNIV_DEBUG
+/*********************************************************************//**
+Validates the lock queue on a table.
+@return TRUE if ok */
static
ibool
lock_table_queue_validate(
/*======================*/
- /* out: TRUE if ok */
- dict_table_t* table) /* in: table */
+ dict_table_t* table) /*!< in: table */
{
lock_t* lock;
@@ -4612,17 +4552,17 @@ lock_table_queue_validate(
return(TRUE);
}
-/*************************************************************************
-Validates the lock queue on a single record. */
+/*********************************************************************//**
+Validates the lock queue on a single record.
+@return TRUE if ok */
static
ibool
lock_rec_queue_validate(
/*====================*/
- /* out: TRUE if ok */
- const buf_block_t* block, /* in: buffer block containing rec */
- const rec_t* rec, /* in: record to look at */
- dict_index_t* index, /* in: index, or NULL if not known */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ const buf_block_t* block, /*!< in: buffer block containing rec */
+ const rec_t* rec, /*!< in: record to look at */
+ dict_index_t* index, /*!< in: index, or NULL if not known */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
trx_t* impl_trx;
lock_t* lock;
@@ -4736,15 +4676,15 @@ lock_rec_queue_validate(
return(TRUE);
}
-/*************************************************************************
-Validates the record lock queues on a page. */
+/*********************************************************************//**
+Validates the record lock queues on a page.
+@return TRUE if ok */
static
ibool
lock_rec_validate_page(
/*===================*/
- /* out: TRUE if ok */
- ulint space, /* in: space id */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space id */
+ ulint page_no)/*!< in: page number */
{
dict_index_t* index;
buf_block_t* block;
@@ -4754,6 +4694,7 @@ lock_rec_validate_page(
ulint nth_lock = 0;
ulint nth_bit = 0;
ulint i;
+ ulint zip_size;
mtr_t mtr;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
@@ -4764,8 +4705,9 @@ lock_rec_validate_page(
mtr_start(&mtr);
- block = buf_page_get(space, fil_space_get_zip_size(space),
- page_no, RW_X_LATCH, &mtr);
+ zip_size = fil_space_get_zip_size(space);
+ ut_ad(zip_size != ULINT_UNDEFINED);
+ block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, &mtr);
buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
page = block->frame;
@@ -4834,13 +4776,13 @@ function_exit:
return(TRUE);
}
-/*************************************************************************
-Validates the lock system. */
+/*********************************************************************//**
+Validates the lock system.
+@return TRUE if ok */
static
ibool
lock_validate(void)
/*===============*/
- /* out: TRUE if ok */
{
lock_t* lock;
trx_t* trx;
@@ -4910,29 +4852,28 @@ lock_validate(void)
return(TRUE);
}
-# endif /* UNIV_DEBUG */
-#endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG */
/*============ RECORD LOCK CHECKS FOR ROW OPERATIONS ====================*/
-/*************************************************************************
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate insert of
a record. If they do, first tests 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 gap x-lock to the lock queue. */
+for a gap x-lock to the lock queue.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_rec_insert_check_and_lock(
/*===========================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG bit is
set, does nothing */
- rec_t* rec, /* in: record after which to insert */
- buf_block_t* block, /* in/out: buffer block of rec */
- dict_index_t* index, /* in: index */
- que_thr_t* thr, /* in: query thread */
- ibool* inherit)/* out: set to TRUE if the new
+ const rec_t* rec, /*!< in: record after which to insert */
+ buf_block_t* block, /*!< in/out: buffer block of rec */
+ dict_index_t* index, /*!< in: index */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr, /*!< in/out: mini-transaction */
+ ibool* inherit)/*!< out: set to TRUE if the new
inserted record maybe should inherit
LOCK_GAP type locks from the successor
record */
@@ -4951,7 +4892,7 @@ lock_rec_insert_check_and_lock(
}
trx = thr_get_trx(thr);
- next_rec = page_rec_get_next(rec);
+ next_rec = page_rec_get_next((rec_t*) rec);
next_rec_heap_no = page_rec_get_heap_no(next_rec);
lock_mutex_enter_kernel();
@@ -4974,7 +4915,7 @@ lock_rec_insert_check_and_lock(
/* Update the page max trx id field */
page_update_max_trx_id(block,
buf_block_get_page_zip(block),
- trx->id);
+ trx->id, mtr);
}
*inherit = FALSE;
@@ -5013,7 +4954,7 @@ lock_rec_insert_check_and_lock(
/* Update the page max trx id field */
page_update_max_trx_id(block,
buf_block_get_page_zip(block),
- trx->id);
+ trx->id, mtr);
}
#ifdef UNIV_DEBUG
@@ -5036,7 +4977,7 @@ lock_rec_insert_check_and_lock(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
If a transaction has an implicit x-lock on a record, but no explicit x-lock
set on the record, sets one for it. NOTE that in the case of a secondary
index, the kernel mutex may get temporarily released. */
@@ -5044,10 +4985,10 @@ static
void
lock_rec_convert_impl_to_expl(
/*==========================*/
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: user record on page */
- dict_index_t* index, /* in: index of record */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: user record on page */
+ dict_index_t* index, /*!< in: index of record */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
trx_t* impl_trx;
@@ -5079,28 +5020,26 @@ lock_rec_convert_impl_to_expl(
}
}
-/*************************************************************************
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate modify (update,
delete mark, or delete unmark) of a clustered index record. If they do,
first tests 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 x-lock to the
-lock queue. */
+lock queue.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_clust_rec_modify_check_and_lock(
/*=================================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: record which should be
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: record which should be
modified */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- que_thr_t* thr) /* in: query thread */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
ulint heap_no;
@@ -5137,25 +5076,25 @@ lock_clust_rec_modify_check_and_lock(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate modify (delete
-mark or delete unmark) of a secondary index record. */
+mark or delete unmark) of a secondary index record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_sec_rec_modify_check_and_lock(
/*===============================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- buf_block_t* block, /* in/out: buffer block of rec */
- rec_t* rec, /* in: record which should be
+ buf_block_t* block, /*!< in/out: buffer block of rec */
+ const rec_t* rec, /*!< in: record which should be
modified; NOTE: as this is a secondary
index, we always have to modify the
clustered index record first: see the
comment below */
- dict_index_t* index, /* in: secondary index */
- que_thr_t* thr) /* in: query thread */
+ dict_index_t* index, /*!< in: secondary index */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
{
ulint err;
ulint heap_no;
@@ -5204,39 +5143,37 @@ lock_sec_rec_modify_check_and_lock(
/* Update the page max trx id field */
page_update_max_trx_id(block,
buf_block_get_page_zip(block),
- thr_get_trx(thr)->id);
+ thr_get_trx(thr)->id, mtr);
}
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Like the counterpart for a clustered index below, but now we read a
-secondary index record. */
+secondary index record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_sec_rec_read_check_and_lock(
/*=============================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: user record or page
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: user record or page
supremum record which should
be read or passed over by a
read cursor */
- dict_index_t* index, /* in: secondary index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- enum lock_mode mode, /* in: mode of the lock which
+ dict_index_t* index, /*!< in: secondary index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ enum lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
latter is possible in
SELECT FOR UPDATE */
- ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
ulint heap_no;
@@ -5283,37 +5220,35 @@ lock_sec_rec_read_check_and_lock(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate read, or passing
over by a read cursor, of a clustered index record. If they do, first tests
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. */
+lock on the record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_clust_rec_read_check_and_lock(
/*===============================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: user record or page
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: user record or page
supremum record which should
be read or passed over by a
read cursor */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- enum lock_mode mode, /* in: mode of the lock which
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ enum lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
latter is possible in
SELECT FOR UPDATE */
- ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
ulint heap_no;
@@ -5353,7 +5288,7 @@ lock_clust_rec_read_check_and_lock(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if locks of other transactions prevent an immediate read, or passing
over by a read cursor, of a clustered index record. If they do, first tests
if the query thread should anyway be suspended for some reason; if not, then
@@ -5361,30 +5296,28 @@ 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. This is an alternative version of
lock_clust_rec_read_check_and_lock() that does not require the parameter
-"offsets". */
+"offsets".
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
UNIV_INTERN
ulint
lock_clust_rec_read_check_and_lock_alt(
/*===================================*/
- /* out: DB_SUCCESS,
- DB_LOCK_WAIT, DB_DEADLOCK, or
- DB_QUE_THR_SUSPENDED */
- ulint flags, /* in: if BTR_NO_LOCKING_FLAG
+ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG
bit is set, does nothing */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: user record or page
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: user record or page
supremum record which should
be read or passed over by a
read cursor */
- dict_index_t* index, /* in: clustered index */
- enum lock_mode mode, /* in: mode of the lock which
+ dict_index_t* index, /*!< in: clustered index */
+ enum lock_mode mode, /*!< in: mode of the lock which
the read cursor should set on
records: LOCK_S or LOCK_X; the
latter is possible in
SELECT FOR UPDATE */
- ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
mem_heap_t* tmp_heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
@@ -5402,13 +5335,13 @@ lock_clust_rec_read_check_and_lock_alt(
return(ret);
}
-/***********************************************************************
+/*******************************************************************//**
Release the last lock from the transaction's autoinc locks. */
UNIV_INLINE
void
lock_release_autoinc_last_lock(
/*===========================*/
- ib_vector_t* autoinc_locks) /* in/out: vector of AUTOINC locks */
+ ib_vector_t* autoinc_locks) /*!< in/out: vector of AUTOINC locks */
{
ulint last;
lock_t* lock;
@@ -5430,13 +5363,13 @@ lock_release_autoinc_last_lock(
lock_table_dequeue(lock);
}
-/***********************************************************************
+/*******************************************************************//**
Release all the transaction's autoinc locks. */
UNIV_INTERN
void
lock_release_autoinc_locks(
/*=======================*/
- trx_t* trx) /* in/out: transaction */
+ trx_t* trx) /*!< in/out: transaction */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -5456,40 +5389,40 @@ lock_release_autoinc_locks(
ut_a(ib_vector_is_empty(trx->autoinc_locks));
}
-/***********************************************************************
+/*******************************************************************//**
Gets the type of a lock. Non-inline version for using outside of the
-lock module. */
+lock module.
+@return LOCK_TABLE or LOCK_REC */
UNIV_INTERN
ulint
lock_get_type(
/*==========*/
- /* out: LOCK_TABLE or LOCK_REC */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
return(lock_get_type_low(lock));
}
-/***********************************************************************
-Gets the id of the transaction owning a lock. */
+/*******************************************************************//**
+Gets the id of the transaction owning a lock.
+@return transaction id */
UNIV_INTERN
ullint
lock_get_trx_id(
/*============*/
- /* out: transaction id */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
return(trx_get_id(lock->trx));
}
-/***********************************************************************
+/*******************************************************************//**
Gets the mode of a lock in a human readable string.
-The string should not be free()'d or modified. */
+The string should not be free()'d or modified.
+@return lock mode */
UNIV_INTERN
const char*
lock_get_mode_str(
/*==============*/
- /* out: lock mode */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ibool is_gap_lock;
@@ -5528,15 +5461,15 @@ lock_get_mode_str(
}
}
-/***********************************************************************
+/*******************************************************************//**
Gets the type of a lock in a human readable string.
-The string should not be free()'d or modified. */
+The string should not be free()'d or modified.
+@return lock type */
UNIV_INTERN
const char*
lock_get_type_str(
/*==============*/
- /* out: lock type */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
switch (lock_get_type_low(lock)) {
case LOCK_REC:
@@ -5548,14 +5481,14 @@ lock_get_type_str(
}
}
-/***********************************************************************
-Gets the table on which the lock is. */
+/*******************************************************************//**
+Gets the table on which the lock is.
+@return table */
UNIV_INLINE
dict_table_t*
lock_get_table(
/*===========*/
- /* out: table */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
switch (lock_get_type_low(lock)) {
case LOCK_REC:
@@ -5568,14 +5501,14 @@ lock_get_table(
}
}
-/***********************************************************************
-Gets the id of the table on which the lock is. */
+/*******************************************************************//**
+Gets the id of the table on which the lock is.
+@return id of the table */
UNIV_INTERN
ullint
lock_get_table_id(
/*==============*/
- /* out: id of the table */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
dict_table_t* table;
@@ -5584,15 +5517,15 @@ lock_get_table_id(
return((ullint)ut_conv_dulint_to_longlong(table->id));
}
-/***********************************************************************
+/*******************************************************************//**
Gets the name of the table on which the lock is.
-The string should not be free()'d or modified. */
+The string should not be free()'d or modified.
+@return name of the table */
UNIV_INTERN
const char*
lock_get_table_name(
/*================*/
- /* out: name of the table */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
dict_table_t* table;
@@ -5601,57 +5534,57 @@ lock_get_table_name(
return(table->name);
}
-/***********************************************************************
-For a record lock, gets the index on which the lock is. */
+/*******************************************************************//**
+For a record lock, gets the index on which the lock is.
+@return index */
UNIV_INTERN
const dict_index_t*
lock_rec_get_index(
/*===============*/
- /* out: index */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ut_a(lock_get_type_low(lock) == LOCK_REC);
return(lock->index);
}
-/***********************************************************************
+/*******************************************************************//**
For a record lock, gets the name of the index on which the lock is.
-The string should not be free()'d or modified. */
+The string should not be free()'d or modified.
+@return name of the index */
UNIV_INTERN
const char*
lock_rec_get_index_name(
/*====================*/
- /* out: name of the index */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ut_a(lock_get_type_low(lock) == LOCK_REC);
return(lock->index->name);
}
-/***********************************************************************
-For a record lock, gets the tablespace number on which the lock is. */
+/*******************************************************************//**
+For a record lock, gets the tablespace number on which the lock is.
+@return tablespace number */
UNIV_INTERN
ulint
lock_rec_get_space_id(
/*==================*/
- /* out: tablespace number */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ut_a(lock_get_type_low(lock) == LOCK_REC);
return(lock->un_member.rec_lock.space);
}
-/***********************************************************************
-For a record lock, gets the page number on which the lock is. */
+/*******************************************************************//**
+For a record lock, gets the page number on which the lock is.
+@return page number */
UNIV_INTERN
ulint
lock_rec_get_page_no(
/*=================*/
- /* out: page number */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ut_a(lock_get_type_low(lock) == LOCK_REC);
diff --git a/storage/xtradb/log/log0log.c b/storage/xtradb/log/log0log.c
index a41b02c32fa..3a89f540b77 100644
--- a/storage/xtradb/log/log0log.c
+++ b/storage/xtradb/log/log0log.c
@@ -15,8 +15,33 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/*****************************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Google Inc.
-/******************************************************
+Portions of this file contain modifications contributed and copyrighted by
+Google, Inc. Those modifications are gratefully acknowledged and are described
+briefly in the InnoDB documentation. The contributions by Google are
+incorporated with their permission, and subject to the conditions contained in
+the file COPYING.Google.
+
+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
+
+*****************************************************************************/
+
+/**************************************************//**
+@file log/log0log.c
Database log
Created 12/9/1995 Heikki Tuuri
@@ -28,6 +53,7 @@ Created 12/9/1995 Heikki Tuuri
#include "log0log.ic"
#endif
+#ifndef UNIV_HOTBACKUP
#include "mem0mem.h"
#include "buf0buf.h"
#include "buf0flu.h"
@@ -75,8 +101,6 @@ UNIV_INTERN log_t* log_sys = NULL;
#ifdef UNIV_DEBUG
UNIV_INTERN ibool log_do_write = TRUE;
-
-UNIV_INTERN ibool log_debug_writes = FALSE;
#endif /* UNIV_DEBUG */
/* These control how often we print warnings if the last checkpoint is too
@@ -129,14 +153,14 @@ the previous */
#define LOG_ARCHIVE_READ 1
#define LOG_ARCHIVE_WRITE 2
-/**********************************************************
+/******************************************************//**
Completes a checkpoint write i/o to a log file. */
static
void
log_io_complete_checkpoint(void);
/*============================*/
#ifdef UNIV_LOG_ARCHIVE
-/**********************************************************
+/******************************************************//**
Completes an archiving i/o. */
static
void
@@ -144,7 +168,7 @@ log_io_complete_archive(void);
/*=========================*/
#endif /* UNIV_LOG_ARCHIVE */
-/********************************************************************
+/****************************************************************//**
Sets the global variable log_fsp_current_free_limit. Also makes a checkpoint,
so that we know that the limit has been written to a log checkpoint field
on disk. */
@@ -152,7 +176,7 @@ UNIV_INTERN
void
log_fsp_current_free_limit_set_and_checkpoint(
/*==========================================*/
- ulint limit) /* in: limit to set */
+ ulint limit) /*!< in: limit to set */
{
ibool success;
@@ -171,9 +195,10 @@ log_fsp_current_free_limit_set_and_checkpoint(
}
}
-/********************************************************************
+/****************************************************************//**
Returns the oldest modified block lsn in the pool, or log_sys->lsn if none
-exists. */
+exists.
+@return LSN of oldest modification */
static
ib_uint64_t
log_buf_pool_get_oldest_modification(void)
@@ -193,15 +218,15 @@ log_buf_pool_get_oldest_modification(void)
return(lsn);
}
-/****************************************************************
+/************************************************************//**
Opens the log for log_write_low. The log must be closed with log_close and
-released with log_release. */
+released with log_release.
+@return start lsn of the log record */
UNIV_INTERN
ib_uint64_t
log_reserve_and_open(
/*=================*/
- /* out: start lsn of the log record */
- ulint len) /* in: length of data to be catenated */
+ ulint len) /*!< in: length of data to be catenated */
{
log_t* log = log_sys;
ulint len_upper_limit;
@@ -267,15 +292,15 @@ loop:
return(log->lsn);
}
-/****************************************************************
+/************************************************************//**
Writes to the log the string given. It is assumed that the caller holds the
log mutex. */
UNIV_INTERN
void
log_write_low(
/*==========*/
- byte* str, /* in: string */
- ulint str_len) /* in: string length */
+ byte* str, /*!< in: string */
+ ulint str_len) /*!< in: string length */
{
log_t* log = log_sys;
ulint len;
@@ -336,13 +361,13 @@ part_loop:
srv_log_write_requests++;
}
-/****************************************************************
-Closes the log. */
+/************************************************************//**
+Closes the log.
+@return lsn */
UNIV_INTERN
ib_uint64_t
log_close(void)
/*===========*/
- /* out: lsn */
{
byte* log_block;
ulint first_rec_group;
@@ -428,7 +453,7 @@ function_exit:
}
#ifdef UNIV_LOG_ARCHIVE
-/**********************************************************
+/******************************************************//**
Pads the current log block full with dummy log records. Used in producing
consistent archived log files. */
static
@@ -461,47 +486,49 @@ log_pad_current_log_block(void)
}
#endif /* UNIV_LOG_ARCHIVE */
-/**********************************************************
+/******************************************************//**
Calculates the data capacity of a log group, when the log file headers are not
-included. */
+included.
+@return capacity in bytes */
UNIV_INTERN
ulint
log_group_get_capacity(
/*===================*/
- /* out: capacity in bytes */
- log_group_t* group) /* in: log group */
+ const log_group_t* group) /*!< in: log group */
{
ut_ad(mutex_own(&(log_sys->mutex)));
return((group->file_size - LOG_FILE_HDR_SIZE) * group->n_files);
}
-/**********************************************************
+/******************************************************//**
Calculates the offset within a log group, when the log file headers are not
-included. */
+included.
+@return size offset (<= offset) */
UNIV_INLINE
ulint
log_group_calc_size_offset(
/*=======================*/
- /* out: size offset (<= offset) */
- ulint offset, /* in: real offset within the log group */
- log_group_t* group) /* in: log group */
+ ulint offset, /*!< in: real offset within the
+ log group */
+ const log_group_t* group) /*!< in: log group */
{
ut_ad(mutex_own(&(log_sys->mutex)));
return(offset - LOG_FILE_HDR_SIZE * (1 + offset / group->file_size));
}
-/**********************************************************
+/******************************************************//**
Calculates the offset within a log group, when the log file headers are
-included. */
+included.
+@return real offset (>= offset) */
UNIV_INLINE
ulint
log_group_calc_real_offset(
/*=======================*/
- /* out: real offset (>= offset) */
- ulint offset, /* in: size offset within the log group */
- log_group_t* group) /* in: log group */
+ ulint offset, /*!< in: size offset within the
+ log group */
+ const log_group_t* group) /*!< in: log group */
{
ut_ad(mutex_own(&(log_sys->mutex)));
@@ -509,16 +536,16 @@ log_group_calc_real_offset(
* (1 + offset / (group->file_size - LOG_FILE_HDR_SIZE)));
}
-/**********************************************************
-Calculates the offset of an lsn within a log group. */
+/******************************************************//**
+Calculates the offset of an lsn within a log group.
+@return offset within the log group */
static
ulint
log_group_calc_lsn_offset(
/*======================*/
- /* out: offset within the log group */
- ib_uint64_t lsn, /* in: lsn, must be within 4 GB of
- group->lsn */
- log_group_t* group) /* in: log group */
+ ib_uint64_t lsn, /*!< in: lsn, must be within 4 GB of
+ group->lsn */
+ const log_group_t* group) /*!< in: log group */
{
ib_uint64_t gr_lsn;
ib_int64_t gr_lsn_size_offset;
@@ -560,23 +587,28 @@ log_group_calc_lsn_offset(
return(log_group_calc_real_offset((ulint)offset, group));
}
+#endif /* !UNIV_HOTBACKUP */
+
+#ifdef UNIV_DEBUG
+UNIV_INTERN ibool log_debug_writes = FALSE;
+#endif /* UNIV_DEBUG */
-/***********************************************************************
-Calculates where in log files we find a specified lsn. */
+/*******************************************************************//**
+Calculates where in log files we find a specified lsn.
+@return log file number */
UNIV_INTERN
ulint
log_calc_where_lsn_is(
/*==================*/
- /* out: log file number */
- ib_int64_t* log_file_offset, /* out: offset in that file
+ ib_int64_t* log_file_offset, /*!< out: offset in that file
(including the header) */
- ib_uint64_t first_header_lsn, /* in: first log file start
+ ib_uint64_t first_header_lsn, /*!< in: first log file start
lsn */
- ib_uint64_t lsn, /* in: lsn whose position to
+ ib_uint64_t lsn, /*!< in: lsn whose position to
determine */
- ulint n_log_files, /* in: total number of log
+ ulint n_log_files, /*!< in: total number of log
files */
- ib_int64_t log_file_size) /* in: log file size
+ ib_int64_t log_file_size) /*!< in: log file size
(including the header) */
{
ib_int64_t capacity = log_file_size - LOG_FILE_HDR_SIZE;
@@ -601,7 +633,8 @@ log_calc_where_lsn_is(
return(file_no);
}
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
Sets the field values in group to correspond to a given lsn. For this function
to work, the values must already be correctly initialized to correspond to
some lsn, for instance, a checkpoint lsn. */
@@ -609,24 +642,23 @@ UNIV_INTERN
void
log_group_set_fields(
/*=================*/
- log_group_t* group, /* in: group */
- ib_uint64_t lsn) /* in: lsn for which the values should be
+ log_group_t* group, /*!< in/out: group */
+ ib_uint64_t lsn) /*!< in: lsn for which the values should be
set */
{
group->lsn_offset = log_group_calc_lsn_offset(lsn, group);
group->lsn = lsn;
}
-/*********************************************************************
+/*****************************************************************//**
Calculates the recommended highest values for lsn - last_checkpoint_lsn,
-lsn - buf_get_oldest_modification(), and lsn - max_archive_lsn_age. */
+lsn - buf_get_oldest_modification(), and lsn - max_archive_lsn_age.
+@return error value FALSE if the smallest log group is too small to
+accommodate the number of OS threads in the database server */
static
ibool
log_calc_max_ages(void)
/*===================*/
- /* out: error value FALSE if the smallest log group is
- too small to accommodate the number of OS threads in
- the database server */
{
log_group_t* group;
ulint margin;
@@ -720,8 +752,7 @@ failure:
" After an ERROR-FREE shutdown\n"
"InnoDB: of mysqld you can adjust the size of"
" ib_logfiles, as explained in\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "adding-and-removing.html\n"
+ "InnoDB: " REFMAN "adding-and-removing.html\n"
"InnoDB: Cannot continue operation."
" Calling exit(1).\n",
(ulong)srv_thread_concurrency);
@@ -732,7 +763,7 @@ failure:
return(success);
}
-/**********************************************************
+/******************************************************//**
Initializes the log. */
UNIV_INTERN
void
@@ -842,7 +873,7 @@ log_init(void)
#ifdef UNIV_LOG_DEBUG
recv_sys_create();
- recv_sys_init(FALSE, buf_pool_get_curr_size());
+ recv_sys_init(buf_pool_get_curr_size());
recv_sys->parse_start_lsn = log_sys->lsn;
recv_sys->scanned_lsn = log_sys->lsn;
@@ -852,20 +883,20 @@ log_init(void)
#endif
}
-/**********************************************************************
+/******************************************************************//**
Inits a log group to the log system. */
UNIV_INTERN
void
log_group_init(
/*===========*/
- ulint id, /* in: group id */
- ulint n_files, /* in: number of log files */
- ulint file_size, /* in: log file size in bytes */
- ulint space_id, /* in: space id of the file space
+ ulint id, /*!< in: group id */
+ ulint n_files, /*!< in: number of log files */
+ ulint file_size, /*!< in: log file size in bytes */
+ ulint space_id, /*!< in: space id of the file space
which contains the log files of this
group */
ulint archive_space_id __attribute__((unused)))
- /* in: space id of the file space
+ /*!< in: space id of the file space
which contains some archived log
files for this group; currently, only
for the first log group this is
@@ -925,13 +956,13 @@ log_group_init(
ut_a(log_calc_max_ages());
}
-/**********************************************************************
+/******************************************************************//**
Does the unlockings needed in flush i/o completion. */
UNIV_INLINE
void
log_flush_do_unlocks(
/*=================*/
- ulint code) /* in: any ORed combination of LOG_UNLOCK_FLUSH_LOCK
+ ulint code) /*!< in: any ORed combination of LOG_UNLOCK_FLUSH_LOCK
and LOG_UNLOCK_NONE_FLUSHED_LOCK */
{
ut_ad(mutex_own(&(log_sys->mutex)));
@@ -956,15 +987,15 @@ log_flush_do_unlocks(
}
}
-/**********************************************************************
+/******************************************************************//**
Checks if a flush is completed for a log group and does the completion
-routine if yes. */
+routine if yes.
+@return LOG_UNLOCK_NONE_FLUSHED_LOCK or 0 */
UNIV_INLINE
ulint
log_group_check_flush_completion(
/*=============================*/
- /* out: LOG_UNLOCK_NONE_FLUSHED_LOCK or 0 */
- log_group_t* group) /* in: log group */
+ log_group_t* group) /*!< in: log group */
{
ut_ad(mutex_own(&(log_sys->mutex)));
@@ -992,13 +1023,13 @@ log_group_check_flush_completion(
return(0);
}
-/**********************************************************
-Checks if a flush is completed and does the completion routine if yes. */
+/******************************************************//**
+Checks if a flush is completed and does the completion routine if yes.
+@return LOG_UNLOCK_FLUSH_LOCK or 0 */
static
ulint
log_sys_check_flush_completion(void)
/*================================*/
- /* out: LOG_UNLOCK_FLUSH_LOCK or 0 */
{
ulint move_start;
ulint move_end;
@@ -1033,13 +1064,13 @@ log_sys_check_flush_completion(void)
return(0);
}
-/**********************************************************
+/******************************************************//**
Completes an i/o to a log file. */
UNIV_INTERN
void
log_io_complete(
/*============*/
- log_group_t* group) /* in: log group or a dummy pointer */
+ log_group_t* group) /*!< in: log group or a dummy pointer */
{
ulint unlock;
@@ -1075,7 +1106,7 @@ log_io_complete(
return;
}
- ut_error; /* We currently use synchronous writing of the
+ ut_error; /*!< We currently use synchronous writing of the
logs and cannot end up here! */
if (srv_unix_file_flush_method != SRV_UNIX_O_DSYNC
@@ -1101,16 +1132,16 @@ log_io_complete(
mutex_exit(&(log_sys->mutex));
}
-/**********************************************************
+/******************************************************//**
Writes a log file header to a log file space. */
static
void
log_group_file_header_flush(
/*========================*/
- log_group_t* group, /* in: log group */
- ulint nth_file, /* in: header to the nth file in the
+ log_group_t* group, /*!< in: log group */
+ ulint nth_file, /*!< in: header to the nth file in the
log file space */
- ib_uint64_t start_lsn) /* in: log file data starts at this
+ ib_uint64_t start_lsn) /*!< in: log file data starts at this
lsn */
{
byte* buf;
@@ -1151,7 +1182,7 @@ log_group_file_header_flush(
}
}
-/**********************************************************
+/******************************************************//**
Stores a 4-byte checksum to the trailer checksum field of a log block
before writing it to a log file. This checksum is used in recovery to
check the consistency of a log block. */
@@ -1159,25 +1190,25 @@ static
void
log_block_store_checksum(
/*=====================*/
- byte* block) /* in/out: pointer to a log block */
+ byte* block) /*!< in/out: pointer to a log block */
{
log_block_set_checksum(block, log_block_calc_checksum(block));
}
-/**********************************************************
+/******************************************************//**
Writes a buffer to a log file group. */
UNIV_INTERN
void
log_group_write_buf(
/*================*/
- log_group_t* group, /* in: log group */
- byte* buf, /* in: buffer */
- ulint len, /* in: buffer len; must be divisible
+ log_group_t* group, /*!< in: log group */
+ byte* buf, /*!< in: buffer */
+ ulint len, /*!< in: buffer len; must be divisible
by OS_FILE_LOG_BLOCK_SIZE */
- ib_uint64_t start_lsn, /* in: start lsn of the buffer; must
+ ib_uint64_t start_lsn, /*!< in: start lsn of the buffer; must
be divisible by
OS_FILE_LOG_BLOCK_SIZE */
- ulint new_data_offset)/* in: start offset of new data in
+ ulint new_data_offset)/*!< in: start offset of new data in
buf: this parameter is used to decide
if we have to write a new log file
header */
@@ -1281,7 +1312,7 @@ loop:
}
}
-/**********************************************************
+/******************************************************//**
This function is called, e.g., when a transaction wants to commit. It checks
that the log has been written to the log file up to the last log entry written
by the transaction. If there is a flush running, it waits and checks if the
@@ -1290,13 +1321,13 @@ UNIV_INTERN
void
log_write_up_to(
/*============*/
- ib_uint64_t lsn, /* in: log sequence number up to which
+ ib_uint64_t lsn, /*!< in: log sequence number up to which
the log should be written,
IB_ULONGLONG_MAX if not specified */
- ulint wait, /* in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
+ ulint wait, /*!< in: LOG_NO_WAIT, LOG_WAIT_ONE_GROUP,
or LOG_WAIT_ALL_GROUPS */
ibool flush_to_disk)
- /* in: TRUE if we want the written log
+ /*!< in: TRUE if we want the written log
also to be flushed to disk */
{
log_group_t* group;
@@ -1398,7 +1429,7 @@ loop:
log_sys->n_pending_writes++;
group = UT_LIST_GET_FIRST(log_sys->log_groups);
- group->n_pending_writes++; /* We assume here that we have only
+ group->n_pending_writes++; /*!< We assume here that we have only
one log group! */
os_event_reset(log_sys->no_flush_event);
@@ -1507,7 +1538,7 @@ do_waits:
}
}
-/********************************************************************
+/****************************************************************//**
Does a syncronous flush of the log buffer to disk. */
UNIV_INTERN
void
@@ -1525,13 +1556,16 @@ log_buffer_flush_to_disk(void)
log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS, TRUE);
}
-/********************************************************************
-Flush the log buffer. Force it to disk depending on the value of
-innodb_flush_log_at_trx_commit. */
+/****************************************************************//**
+This functions writes the log buffer to the log file and if 'flush'
+is set it forces a flush of the log file as well. This is meant to be
+called from background master thread only as it does not wait for
+the write (+ possible flush) to finish. */
UNIV_INTERN
void
-log_buffer_flush_maybe_sync(void)
-/*=============================*/
+log_buffer_sync_in_background(
+/*==========================*/
+ ibool flush) /*!< in: flush the logs to disk */
{
ib_uint64_t lsn;
@@ -1541,11 +1575,11 @@ log_buffer_flush_maybe_sync(void)
mutex_exit(&(log_sys->mutex));
- /* Force log buffer to disk when innodb_flush_log_at_trx_commit = 1. */
- log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS,
- srv_flush_log_at_trx_commit == 1 ? TRUE : FALSE);
+ log_write_up_to(lsn, LOG_NO_WAIT, flush);
}
+
/********************************************************************
+
Tries to establish a big enough margin of free space in the log buffer, such
that a new log entry can be catenated without an immediate need for a flush. */
static
@@ -1575,23 +1609,20 @@ log_flush_margin(void)
}
}
-/********************************************************************
+/****************************************************************//**
Advances the smallest lsn for which there are unflushed dirty blocks in the
buffer pool. NOTE: this function may only be called if the calling thread owns
-no synchronization objects! */
+no synchronization objects!
+@return FALSE if there was a flush batch of the same type running,
+which means that we could not start this flush batch */
UNIV_INTERN
ibool
log_preflush_pool_modified_pages(
/*=============================*/
- /* out: FALSE if there was a
- flush batch of the same type
- running, which means that we
- could not start this flush
- batch */
- ib_uint64_t new_oldest, /* in: try to advance
+ ib_uint64_t new_oldest, /*!< in: try to advance
oldest_modified_lsn at least
to this lsn */
- ibool sync) /* in: TRUE if synchronous
+ ibool sync) /*!< in: TRUE if synchronous
operation is desired */
{
ulint n_pages;
@@ -1623,7 +1654,7 @@ log_preflush_pool_modified_pages(
return(TRUE);
}
-/**********************************************************
+/******************************************************//**
Completes a checkpoint. */
static
void
@@ -1640,7 +1671,7 @@ log_complete_checkpoint(void)
rw_lock_x_unlock_gen(&(log_sys->checkpoint_lock), LOG_CHECKPOINT);
}
-/**********************************************************
+/******************************************************//**
Completes an asynchronous checkpoint info write i/o to a log file. */
static
void
@@ -1660,16 +1691,16 @@ log_io_complete_checkpoint(void)
mutex_exit(&(log_sys->mutex));
}
-/***********************************************************************
+/*******************************************************************//**
Writes info to a checkpoint about a log group. */
static
void
log_checkpoint_set_nth_group_info(
/*==============================*/
- byte* buf, /* in: buffer for checkpoint info */
- ulint n, /* in: nth slot */
- ulint file_no,/* in: archived file number */
- ulint offset) /* in: archived file offset */
+ byte* buf, /*!< in: buffer for checkpoint info */
+ ulint n, /*!< in: nth slot */
+ ulint file_no,/*!< in: archived file number */
+ ulint offset) /*!< in: archived file offset */
{
ut_ad(n < LOG_MAX_N_GROUPS);
@@ -1679,16 +1710,16 @@ log_checkpoint_set_nth_group_info(
+ 8 * n + LOG_CHECKPOINT_ARCHIVED_OFFSET, offset);
}
-/***********************************************************************
+/*******************************************************************//**
Gets info from a checkpoint about a log group. */
UNIV_INTERN
void
log_checkpoint_get_nth_group_info(
/*==============================*/
- byte* buf, /* in: buffer containing checkpoint info */
- ulint n, /* in: nth slot */
- ulint* file_no,/* out: archived file number */
- ulint* offset) /* out: archived file offset */
+ const byte* buf, /*!< in: buffer containing checkpoint info */
+ ulint n, /*!< in: nth slot */
+ ulint* file_no,/*!< out: archived file number */
+ ulint* offset) /*!< out: archived file offset */
{
ut_ad(n < LOG_MAX_N_GROUPS);
@@ -1698,13 +1729,13 @@ log_checkpoint_get_nth_group_info(
+ 8 * n + LOG_CHECKPOINT_ARCHIVED_OFFSET);
}
-/**********************************************************
+/******************************************************//**
Writes the checkpoint info to a log group header. */
static
void
log_group_checkpoint(
/*=================*/
- log_group_t* group) /* in: log group */
+ log_group_t* group) /*!< in: log group */
{
log_group_t* group2;
#ifdef UNIV_LOG_ARCHIVE
@@ -1817,18 +1848,19 @@ log_group_checkpoint(
ut_ad(((ulint)group & 0x1UL) == 0);
}
}
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_HOTBACKUP
-/**********************************************************
+/******************************************************//**
Writes info to a buffer of a log group when log files are created in
backup restoration. */
UNIV_INTERN
void
log_reset_first_header_and_checkpoint(
/*==================================*/
- byte* hdr_buf,/* in: buffer which will be written to the
+ byte* hdr_buf,/*!< in: buffer which will be written to the
start of the first log file */
- ib_uint64_t start) /* in: lsn of the start of the first log file;
+ ib_uint64_t start) /*!< in: lsn of the start of the first log file;
we pretend that there is a checkpoint at
start + LOG_BLOCK_HDR_SIZE */
{
@@ -1872,14 +1904,15 @@ log_reset_first_header_and_checkpoint(
}
#endif /* UNIV_HOTBACKUP */
-/**********************************************************
+#ifndef UNIV_HOTBACKUP
+/******************************************************//**
Reads a checkpoint info from a log group header to log_sys->checkpoint_buf. */
UNIV_INTERN
void
log_group_read_checkpoint_info(
/*===========================*/
- log_group_t* group, /* in: log group */
- ulint field) /* in: LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2 */
+ log_group_t* group, /*!< in: log group */
+ ulint field) /*!< in: LOG_CHECKPOINT_1 or LOG_CHECKPOINT_2 */
{
ut_ad(mutex_own(&(log_sys->mutex)));
@@ -1890,7 +1923,7 @@ log_group_read_checkpoint_info(
OS_FILE_LOG_BLOCK_SIZE, log_sys->checkpoint_buf, NULL);
}
-/**********************************************************
+/******************************************************//**
Writes checkpoint info to groups. */
UNIV_INTERN
void
@@ -1910,20 +1943,19 @@ log_groups_write_checkpoint_info(void)
}
}
-/**********************************************************
+/******************************************************//**
Makes a checkpoint. Note that this function does not flush dirty
blocks from the buffer pool: it only checks what is lsn of the oldest
modification in the pool, and writes information about the lsn in
-log files. Use log_make_checkpoint_at to flush also the pool. */
+log files. Use log_make_checkpoint_at to flush also the pool.
+@return TRUE if success, FALSE if a checkpoint write was already running */
UNIV_INTERN
ibool
log_checkpoint(
/*===========*/
- /* out: TRUE if success, FALSE if a checkpoint
- write was already running */
- ibool sync, /* in: TRUE if synchronous operation is
+ ibool sync, /*!< in: TRUE if synchronous operation is
desired */
- ibool write_always) /* in: the function normally checks if the
+ ibool write_always) /*!< in: the function normally checks if the
the new checkpoint would have a greater
lsn than the previous one: if not, then no
physical write is done; by setting this
@@ -2005,16 +2037,16 @@ log_checkpoint(
return(TRUE);
}
-/********************************************************************
+/****************************************************************//**
Makes a checkpoint at a given lsn or later. */
UNIV_INTERN
void
log_make_checkpoint_at(
/*===================*/
- ib_uint64_t lsn, /* in: make a checkpoint at this or a
+ ib_uint64_t lsn, /*!< in: make a checkpoint at this or a
later lsn, if IB_ULONGLONG_MAX, makes
a checkpoint at the latest lsn */
- ibool write_always) /* in: the function normally checks if
+ ibool write_always) /*!< in: the function normally checks if
the the new checkpoint would have a
greater lsn than the previous one: if
not, then no physical write is done;
@@ -2029,7 +2061,7 @@ log_make_checkpoint_at(
while (!log_checkpoint(TRUE, write_always));
}
-/********************************************************************
+/****************************************************************//**
Tries to establish a big enough margin of free space in the log groups, such
that a new log entry can be catenated without an immediate need for a
checkpoint. NOTE: this function may only be called if the calling thread
@@ -2131,17 +2163,17 @@ loop:
}
}
-/**********************************************************
+/******************************************************//**
Reads a specified log segment to a buffer. */
UNIV_INTERN
void
log_group_read_log_seg(
/*===================*/
- ulint type, /* in: LOG_ARCHIVE or LOG_RECOVER */
- byte* buf, /* in: buffer where to read */
- log_group_t* group, /* in: log group */
- ib_uint64_t start_lsn, /* in: read area start */
- ib_uint64_t end_lsn) /* in: read area end */
+ ulint type, /*!< in: LOG_ARCHIVE or LOG_RECOVER */
+ byte* buf, /*!< in: buffer where to read */
+ log_group_t* group, /*!< in: log group */
+ ib_uint64_t start_lsn, /*!< in: read area start */
+ ib_uint64_t end_lsn) /*!< in: read area end */
{
ulint len;
ulint source_offset;
@@ -2185,32 +2217,32 @@ loop:
}
#ifdef UNIV_LOG_ARCHIVE
-/**********************************************************
+/******************************************************//**
Generates an archived log file name. */
UNIV_INTERN
void
log_archived_file_name_gen(
/*=======================*/
- char* buf, /* in: buffer where to write */
+ char* buf, /*!< in: buffer where to write */
ulint id __attribute__((unused)),
- /* in: group id;
+ /*!< in: group id;
currently we only archive the first group */
- ulint file_no)/* in: file number */
+ ulint file_no)/*!< in: file number */
{
sprintf(buf, "%sib_arch_log_%010lu", srv_arch_dir, (ulong) file_no);
}
-/**********************************************************
+/******************************************************//**
Writes a log file header to a log file space. */
static
void
log_group_archive_file_header_write(
/*================================*/
- log_group_t* group, /* in: log group */
- ulint nth_file, /* in: header to the nth file in the
+ log_group_t* group, /*!< in: log group */
+ ulint nth_file, /*!< in: header to the nth file in the
archive log file space */
- ulint file_no, /* in: archived file number */
- ib_uint64_t start_lsn) /* in: log file data starts at this
+ ulint file_no, /*!< in: archived file number */
+ ib_uint64_t start_lsn) /*!< in: log file data starts at this
lsn */
{
byte* buf;
@@ -2239,16 +2271,16 @@ log_group_archive_file_header_write(
buf, &log_archive_io);
}
-/**********************************************************
+/******************************************************//**
Writes a log file header to a completed archived log file. */
static
void
log_group_archive_completed_header_write(
/*=====================================*/
- log_group_t* group, /* in: log group */
- ulint nth_file, /* in: header to the nth file in the
+ log_group_t* group, /*!< in: log group */
+ ulint nth_file, /*!< in: header to the nth file in the
archive log file space */
- ib_uint64_t end_lsn) /* in: end lsn of the file */
+ ib_uint64_t end_lsn) /*!< in: end lsn of the file */
{
byte* buf;
ulint dest_offset;
@@ -2273,13 +2305,13 @@ log_group_archive_completed_header_write(
&log_archive_io);
}
-/**********************************************************
+/******************************************************//**
Does the archive writes for a single log group. */
static
void
log_group_archive(
/*==============*/
- log_group_t* group) /* in: log group */
+ log_group_t* group) /*!< in: log group */
{
os_file_t file_handle;
ib_uint64_t start_lsn;
@@ -2414,7 +2446,7 @@ loop:
ut_a(group->next_archived_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
}
-/*********************************************************
+/*****************************************************//**
(Writes to the archive of each log group.) Currently, only the first
group is archived. */
static
@@ -2431,7 +2463,7 @@ log_archive_groups(void)
log_group_archive(group);
}
-/*********************************************************
+/*****************************************************//**
Completes the archiving write phase for (each log group), currently,
the first log group. */
static
@@ -2505,7 +2537,7 @@ log_archive_write_complete_groups(void)
#endif /* UNIV_DEBUG */
}
-/**********************************************************
+/******************************************************//**
Completes an archiving i/o. */
static
void
@@ -2541,7 +2573,7 @@ log_archive_check_completion_low(void)
}
}
-/**********************************************************
+/******************************************************//**
Completes an archiving i/o. */
static
void
@@ -2569,16 +2601,15 @@ log_io_complete_archive(void)
mutex_exit(&(log_sys->mutex));
}
-/************************************************************************
-Starts an archiving operation. */
+/********************************************************************//**
+Starts an archiving operation.
+@return TRUE if succeed, FALSE if an archiving operation was already running */
UNIV_INTERN
ibool
log_archive_do(
/*===========*/
- /* out: TRUE if succeed, FALSE if an archiving
- operation was already running */
- ibool sync, /* in: TRUE if synchronous operation is desired */
- ulint* n_bytes)/* out: archive log buffer size, 0 if nothing to
+ ibool sync, /*!< in: TRUE if synchronous operation is desired */
+ ulint* n_bytes)/*!< out: archive log buffer size, 0 if nothing to
archive */
{
ibool calc_new_limit;
@@ -2684,7 +2715,7 @@ arch_none:
return(TRUE);
}
-/********************************************************************
+/****************************************************************//**
Writes the log contents to the archive at least up to the lsn when this
function was called. */
static
@@ -2725,14 +2756,14 @@ log_archive_all(void)
}
}
-/*********************************************************
+/*****************************************************//**
Closes the possible open archive log file (for each group) the first group,
and if it was open, increments the group file count by 2, if desired. */
static
void
log_archive_close_groups(
/*=====================*/
- ibool increment_file_count) /* in: TRUE if we want to increment
+ ibool increment_file_count) /*!< in: TRUE if we want to increment
the file count */
{
log_group_t* group;
@@ -2777,16 +2808,16 @@ log_archive_close_groups(
}
}
-/********************************************************************
+/****************************************************************//**
Writes the log contents to the archive up to the lsn when this function was
called, and stops the archiving. When archiving is started again, the archived
log file numbers start from 2 higher, so that the archiving will not write
-again to the archived log files which exist when this function returns. */
+again to the archived log files which exist when this function returns.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_stop(void)
/*==================*/
- /* out: DB_SUCCESS or DB_ERROR */
{
ibool success;
@@ -2844,13 +2875,13 @@ log_archive_stop(void)
return(DB_SUCCESS);
}
-/********************************************************************
-Starts again archiving which has been stopped. */
+/****************************************************************//**
+Starts again archiving which has been stopped.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_start(void)
/*===================*/
- /* out: DB_SUCCESS or DB_ERROR */
{
mutex_enter(&(log_sys->mutex));
@@ -2870,13 +2901,13 @@ log_archive_start(void)
return(DB_SUCCESS);
}
-/********************************************************************
-Stop archiving the log so that a gap may occur in the archived log files. */
+/****************************************************************//**
+Stop archiving the log so that a gap may occur in the archived log files.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_noarchivelog(void)
/*==========================*/
- /* out: DB_SUCCESS or DB_ERROR */
{
loop:
mutex_enter(&(log_sys->mutex));
@@ -2902,13 +2933,13 @@ loop:
goto loop;
}
-/********************************************************************
-Start archiving the log so that a gap may occur in the archived log files. */
+/****************************************************************//**
+Start archiving the log so that a gap may occur in the archived log files.
+@return DB_SUCCESS or DB_ERROR */
UNIV_INTERN
ulint
log_archive_archivelog(void)
/*========================*/
- /* out: DB_SUCCESS or DB_ERROR */
{
mutex_enter(&(log_sys->mutex));
@@ -2929,7 +2960,7 @@ log_archive_archivelog(void)
return(DB_ERROR);
}
-/********************************************************************
+/****************************************************************//**
Tries to establish a big enough margin of free space in the log groups, such
that a new log entry can be catenated without an immediate need for
archiving. */
@@ -2984,7 +3015,7 @@ loop:
}
#endif /* UNIV_LOG_ARCHIVE */
-/************************************************************************
+/********************************************************************//**
Checks that there is enough free space in the log to start a new query step.
Flushes the log buffer or makes a new checkpoint if necessary. NOTE: this
function may only be called if the calling thread owns no synchronization
@@ -3015,7 +3046,7 @@ loop:
mutex_exit(&(log_sys->mutex));
}
-/********************************************************************
+/****************************************************************//**
Makes a checkpoint at the latest lsn and writes it to first page of each
data file in the database, so that we know that the file spaces contain
all modifications up to that lsn. This can only be called at database
@@ -3203,18 +3234,18 @@ loop:
ut_a(lsn == log_sys->lsn);
}
-/**********************************************************
+/******************************************************//**
Checks by parsing that the catenated log segment for a single mtr is
consistent. */
UNIV_INTERN
ibool
log_check_log_recs(
/*===============*/
- byte* buf, /* in: pointer to the start of
+ byte* buf, /*!< in: pointer to the start of
the log segment in the
log_sys->buf log buffer */
- ulint len, /* in: segment length in bytes */
- ib_uint64_t buf_start_lsn) /* in: buffer start lsn */
+ ulint len, /*!< in: segment length in bytes */
+ ib_uint64_t buf_start_lsn) /*!< in: buffer start lsn */
{
ib_uint64_t contiguous_lsn;
ib_uint64_t scanned_lsn;
@@ -3238,8 +3269,7 @@ log_check_log_recs(
ut_memcpy(scan_buf, start, end - start);
- recv_scan_log_recs(TRUE,
- (buf_pool->curr_size
+ recv_scan_log_recs((buf_pool->curr_size
- recv_n_pool_free_frames) * UNIV_PAGE_SIZE,
FALSE, scan_buf, end - start,
ut_uint64_align_down(buf_start_lsn,
@@ -3254,15 +3284,14 @@ log_check_log_recs(
return(TRUE);
}
-/**********************************************************
-Peeks the current lsn. */
+/******************************************************//**
+Peeks the current lsn.
+@return TRUE if success, FALSE if could not get the log system mutex */
UNIV_INTERN
ibool
log_peek_lsn(
/*=========*/
- /* out: TRUE if success, FALSE if
- could not get the log system mutex */
- ib_uint64_t* lsn) /* out: if returns TRUE, current lsn is here */
+ ib_uint64_t* lsn) /*!< out: if returns TRUE, current lsn is here */
{
if (0 == mutex_enter_nowait(&(log_sys->mutex))) {
*lsn = log_sys->lsn;
@@ -3275,13 +3304,13 @@ log_peek_lsn(
return(FALSE);
}
-/**********************************************************
+/******************************************************//**
Prints info of the log. */
UNIV_INTERN
void
log_print(
/*======*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
double time_elapsed;
time_t current_time;
@@ -3324,7 +3353,7 @@ log_print(
mutex_exit(&(log_sys->mutex));
}
-/**************************************************************************
+/**********************************************************************//**
Refreshes the statistics used to print per-second averages. */
UNIV_INTERN
void
@@ -3334,3 +3363,4 @@ log_refresh_stats(void)
log_sys->n_log_ios_old = log_sys->n_log_ios;
log_sys->last_printout_time = time(NULL);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/log/log0recv.c b/storage/xtradb/log/log0recv.c
index f0f5ae8d6cc..60ca47f1207 100644
--- a/storage/xtradb/log/log0recv.c
+++ b/storage/xtradb/log/log0recv.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file log/log0recv.c
Recovery
Created 9/20/1997 Heikki Tuuri
@@ -31,42 +32,59 @@ Created 9/20/1997 Heikki Tuuri
#include "mem0mem.h"
#include "buf0buf.h"
#include "buf0flu.h"
-#include "buf0rea.h"
-#include "srv0srv.h"
-#include "srv0start.h"
+#include "mtr0mtr.h"
#include "mtr0log.h"
#include "page0cur.h"
#include "page0zip.h"
+#include "btr0btr.h"
#include "btr0cur.h"
#include "ibuf0ibuf.h"
#include "trx0undo.h"
#include "trx0rec.h"
-#include "trx0roll.h"
-#include "row0merge.h"
-
-#ifdef UNIV_HOTBACKUP
-/* This is set to FALSE if the backup was originally taken with the
+#include "fil0fil.h"
+#ifndef UNIV_HOTBACKUP
+# include "buf0rea.h"
+# include "srv0srv.h"
+# include "srv0start.h"
+# include "trx0roll.h"
+# include "row0merge.h"
+# include "sync0sync.h"
+#else /* !UNIV_HOTBACKUP */
+
+/** This is set to FALSE if the backup was originally taken with the
ibbackup --include regexp option: then we do not want to create tables in
directories which were not included */
UNIV_INTERN ibool recv_replay_file_ops = TRUE;
-#endif /* UNIV_HOTBACKUP */
+#endif /* !UNIV_HOTBACKUP */
-/* Log records are stored in the hash table in chunks at most of this size;
+/** Log records are stored in the hash table in chunks at most of this size;
this must be less than UNIV_PAGE_SIZE as it is stored in the buffer pool */
#define RECV_DATA_BLOCK_SIZE (MEM_MAX_ALLOC_IN_BUF - sizeof(recv_data_t))
-/* Read-ahead area in applying log records to file pages */
+/** Read-ahead area in applying log records to file pages */
#define RECV_READ_AHEAD_AREA 32
+/** The recovery system */
UNIV_INTERN recv_sys_t* recv_sys = NULL;
+/** TRUE when applying redo log records during crash recovery; FALSE
+otherwise. Note that this is FALSE while a background thread is
+rolling back incomplete transactions. */
UNIV_INTERN ibool recv_recovery_on = FALSE;
+#ifdef UNIV_LOG_ARCHIVE
+/** TRUE when applying redo log records from an archived log file */
UNIV_INTERN ibool recv_recovery_from_backup_on = FALSE;
+#endif /* UNIV_LOG_ARCHIVE */
+#ifndef UNIV_HOTBACKUP
+/** TRUE when recv_init_crash_recovery() has been called. */
UNIV_INTERN ibool recv_needed_recovery = FALSE;
+/** TRUE if buf_page_is_corrupted() should check if the log sequence
+number (FIL_PAGE_LSN) is in the future. Initially FALSE, and set by
+recv_recovery_from_checkpoint_start_func(). */
UNIV_INTERN ibool recv_lsn_checks_on = FALSE;
-/* There are two conditions under which we scan the logs, the first
+/** There are two conditions under which we scan the logs, the first
is normal startup and the second is when we do a recovery from an
archive.
This flag is set if we are doing a scan from the last checkpoint during
@@ -74,61 +92,68 @@ startup. If we find log entries that were written after the last checkpoint
we know that the server was not cleanly shutdown. We must then initialize
the crash recovery environment before attempting to store these entries in
the log hash table. */
-UNIV_INTERN ibool recv_log_scan_is_startup_type = FALSE;
+static ibool recv_log_scan_is_startup_type = FALSE;
-/* If the following is TRUE, the buffer pool file pages must be invalidated
+/** If the following is TRUE, the buffer pool file pages must be invalidated
after recovery and no ibuf operations are allowed; this becomes TRUE if
the log record hash table becomes too full, and log records must be merged
to file pages already before the recovery is finished: in this case no
ibuf operations are allowed, as they could modify the pages read in the
-buffer pool before the pages have been recovered to the up-to-date state */
-
-/* Recovery is running and no operations on the log files are allowed
-yet: the variable name is misleading */
+buffer pool before the pages have been recovered to the up-to-date state.
+TRUE means that recovery is running and no operations on the log files
+are allowed yet: the variable name is misleading. */
UNIV_INTERN ibool recv_no_ibuf_operations = FALSE;
-
-/* The following counter is used to decide when to print info on
-log scan */
-UNIV_INTERN ulint recv_scan_print_counter = 0;
-
-UNIV_INTERN ibool recv_is_from_backup = FALSE;
-#ifdef UNIV_HOTBACKUP
+/** TRUE when the redo log is being backed up */
+# define recv_is_making_a_backup FALSE
+/** TRUE when recovering from a backed up redo log file */
+# define recv_is_from_backup FALSE
+#else /* !UNIV_HOTBACKUP */
+# define recv_needed_recovery FALSE
+/** TRUE when the redo log is being backed up */
UNIV_INTERN ibool recv_is_making_a_backup = FALSE;
-#else
-# define recv_is_making_a_backup FALSE
-#endif /* UNIV_HOTBACKUP */
+/** TRUE when recovering from a backed up redo log file */
+UNIV_INTERN ibool recv_is_from_backup = FALSE;
+# define buf_pool_get_curr_size() (5 * 1024 * 1024)
+#endif /* !UNIV_HOTBACKUP */
+/** The following counter is used to decide when to print info on
+log scan */
+static ulint recv_scan_print_counter = 0;
-UNIV_INTERN ulint recv_previous_parsed_rec_type = 999999;
-UNIV_INTERN ulint recv_previous_parsed_rec_offset = 0;
-UNIV_INTERN ulint recv_previous_parsed_rec_is_multi = 0;
+/** The type of the previous parsed redo log record */
+static ulint recv_previous_parsed_rec_type = 999999;
+/** The offset of the previous parsed redo log record */
+static ulint recv_previous_parsed_rec_offset = 0;
+/** The 'multi' flag of the previous parsed redo log record */
+static ulint recv_previous_parsed_rec_is_multi = 0;
+/** Maximum page number encountered in the redo log */
UNIV_INTERN ulint recv_max_parsed_page_no = 0;
-/* This many frames must be left free in the buffer pool when we scan
+/** This many frames must be left free in the buffer pool when we scan
the log and store the scanned log records in the buffer pool: we will
use these free frames to read in pages when we start applying the
log records to the database. */
-
UNIV_INTERN ulint recv_n_pool_free_frames = 1024;
-/* The maximum lsn we see for a page during the recovery process. If this
+/** The maximum lsn we see for a page during the recovery process. If this
is bigger than the lsn we are able to scan up to, that is an indication that
the recovery failed and the database may be corrupt. */
-
UNIV_INTERN ib_uint64_t recv_max_page_lsn;
/* prototypes */
-/***********************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************//**
Initialize crash recovery environment. Can be called iff
recv_needed_recovery == FALSE. */
static
void
recv_init_crash_recovery(void);
/*===========================*/
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************
+/********************************************************//**
Creates the recovery system. */
UNIV_INTERN
void
@@ -148,15 +173,13 @@ recv_sys_create(void)
recv_sys->addr_hash = NULL;
}
-/************************************************************
+/********************************************************//**
Inits the recovery system for a recovery operation. */
UNIV_INTERN
void
recv_sys_init(
/*==========*/
- ibool recover_from_backup, /* in: TRUE if this is called
- to recover from a hot backup */
- ulint available_memory) /* in: available memory in bytes */
+ ulint available_memory) /*!< in: available memory in bytes */
{
if (recv_sys->heap != NULL) {
@@ -165,12 +188,12 @@ recv_sys_init(
mutex_enter(&(recv_sys->mutex));
- if (!recover_from_backup) {
- recv_sys->heap = mem_heap_create_in_buffer(256);
- } else {
- recv_sys->heap = mem_heap_create(256);
- recv_is_from_backup = TRUE;
- }
+#ifndef UNIV_HOTBACKUP
+ recv_sys->heap = mem_heap_create_in_buffer(256);
+#else /* !UNIV_HOTBACKUP */
+ recv_sys->heap = mem_heap_create(256);
+ recv_is_from_backup = TRUE;
+#endif /* !UNIV_HOTBACKUP */
recv_sys->buf = ut_malloc(RECV_PARSING_BUF_SIZE);
recv_sys->len = 0;
@@ -193,7 +216,7 @@ recv_sys_init(
mutex_exit(&(recv_sys->mutex));
}
-/************************************************************
+/********************************************************//**
Empties the hash table when it has been fully processed. */
static
void
@@ -219,8 +242,9 @@ recv_sys_empty_hash(void)
recv_sys->addr_hash = hash_create(buf_pool_get_curr_size() / 256);
}
-#ifndef UNIV_LOG_DEBUG
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+# ifndef UNIV_LOG_DEBUG
+/********************************************************//**
Frees the recovery system. */
static
void
@@ -239,22 +263,22 @@ recv_sys_free(void)
mutex_exit(&(recv_sys->mutex));
}
-#endif /* UNIV_LOG_DEBUG */
+# endif /* UNIV_LOG_DEBUG */
-/************************************************************
+/********************************************************//**
Truncates possible corrupted or extra records from a log group. */
static
void
recv_truncate_group(
/*================*/
- log_group_t* group, /* in: log group */
- ib_uint64_t recovered_lsn, /* in: recovery succeeded up to this
+ log_group_t* group, /*!< in: log group */
+ ib_uint64_t recovered_lsn, /*!< in: recovery succeeded up to this
lsn */
- ib_uint64_t limit_lsn, /* in: this was the limit for
+ ib_uint64_t limit_lsn, /*!< in: this was the limit for
recovery */
- ib_uint64_t checkpoint_lsn, /* in: recovery was started from this
+ ib_uint64_t checkpoint_lsn, /*!< in: recovery was started from this
checkpoint */
- ib_uint64_t archived_lsn) /* in: the log has been archived up to
+ ib_uint64_t archived_lsn) /*!< in: the log has been archived up to
this lsn */
{
ib_uint64_t start_lsn;
@@ -341,18 +365,18 @@ recv_truncate_group(
}
}
-/************************************************************
+/********************************************************//**
Copies the log segment between group->recovered_lsn and recovered_lsn from the
most up-to-date log group to group, so that it contains the latest log data. */
static
void
recv_copy_group(
/*============*/
- log_group_t* up_to_date_group, /* in: the most up-to-date log
+ log_group_t* up_to_date_group, /*!< in: the most up-to-date log
group */
- log_group_t* group, /* in: copy to this log
+ log_group_t* group, /*!< in: copy to this log
group */
- ib_uint64_t recovered_lsn) /* in: recovery succeeded up
+ ib_uint64_t recovered_lsn) /*!< in: recovery succeeded up
to this lsn */
{
ib_uint64_t start_lsn;
@@ -392,7 +416,7 @@ recv_copy_group(
}
}
-/************************************************************
+/********************************************************//**
Copies a log segment from the most up-to-date log group to the other log
groups, so that they all contain the latest log data. Also writes the info
about the latest checkpoint to the groups, and inits the fields in the group
@@ -401,7 +425,7 @@ static
void
recv_synchronize_groups(
/*====================*/
- log_group_t* up_to_date_group) /* in: the most up-to-date
+ log_group_t* up_to_date_group) /*!< in: the most up-to-date
log group */
{
log_group_t* group;
@@ -459,15 +483,16 @@ recv_synchronize_groups(
mutex_enter(&(log_sys->mutex));
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************************
-Checks the consistency of the checkpoint info */
+/***********************************************************************//**
+Checks the consistency of the checkpoint info
+@return TRUE if ok */
static
ibool
recv_check_cp_is_consistent(
/*========================*/
- /* out: TRUE if ok */
- byte* buf) /* in: buffer containing checkpoint info */
+ const byte* buf) /*!< in: buffer containing checkpoint info */
{
ulint fold;
@@ -489,15 +514,16 @@ recv_check_cp_is_consistent(
return(TRUE);
}
-/************************************************************
-Looks for the maximum consistent checkpoint from the log groups. */
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
+Looks for the maximum consistent checkpoint from the log groups.
+@return error code or DB_SUCCESS */
static
ulint
recv_find_max_checkpoint(
/*=====================*/
- /* out: error code or DB_SUCCESS */
- log_group_t** max_group, /* out: max group */
- ulint* max_field) /* out: LOG_CHECKPOINT_1 or
+ log_group_t** max_group, /*!< out: max group */
+ ulint* max_field) /*!< out: LOG_CHECKPOINT_1 or
LOG_CHECKPOINT_2 */
{
log_group_t* group;
@@ -582,37 +608,35 @@ not_consistent:
"InnoDB: to create the InnoDB data files,"
" but log file creation failed.\n"
"InnoDB: If that is the case, please refer to\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "error-creating-innodb.html\n");
+ "InnoDB: " REFMAN "error-creating-innodb.html\n");
return(DB_ERROR);
}
return(DB_SUCCESS);
}
-
-#ifdef UNIV_HOTBACKUP
-/***********************************************************************
-Reads the checkpoint info needed in hot backup. */
+#else /* !UNIV_HOTBACKUP */
+/*******************************************************************//**
+Reads the checkpoint info needed in hot backup.
+@return TRUE if success */
UNIV_INTERN
ibool
recv_read_cp_info_for_backup(
/*=========================*/
- /* out: TRUE if success */
- byte* hdr, /* in: buffer containing the log group
+ const byte* hdr, /*!< in: buffer containing the log group
header */
- ib_uint64_t* lsn, /* out: checkpoint lsn */
- ulint* offset, /* out: checkpoint offset in the log group */
- ulint* fsp_limit,/* out: fsp limit of space 0,
+ ib_uint64_t* lsn, /*!< out: checkpoint lsn */
+ ulint* offset, /*!< out: checkpoint offset in the log group */
+ ulint* fsp_limit,/*!< out: fsp limit of space 0,
1000000000 if the database is running
with < version 3.23.50 of InnoDB */
- ib_uint64_t* cp_no, /* out: checkpoint number */
+ ib_uint64_t* cp_no, /*!< out: checkpoint number */
ib_uint64_t* first_header_lsn)
- /* out: lsn of of the start of the
+ /*!< out: lsn of of the start of the
first log file */
{
ulint max_cp = 0;
ib_uint64_t max_cp_no = 0;
- byte* cp_buf;
+ const byte* cp_buf;
cp_buf = hdr + LOG_CHECKPOINT_1;
@@ -661,19 +685,19 @@ recv_read_cp_info_for_backup(
return(TRUE);
}
-#endif /* UNIV_HOTBACKUP */
-
-/**********************************************************
-Checks the 4-byte checksum to the trailer checksum field of a log block.
-We also accept a log block in the old format < InnoDB-3.23.52 where the
-checksum field contains the log block number. */
+#endif /* !UNIV_HOTBACKUP */
+
+/******************************************************//**
+Checks the 4-byte checksum to the trailer checksum field of a log
+block. We also accept a log block in the old format before
+InnoDB-3.23.52 where the checksum field contains the log block number.
+@return TRUE if ok, or if the log block may be in the format of InnoDB
+version predating 3.23.52 */
static
ibool
log_block_checksum_is_ok_or_old_format(
/*===================================*/
- /* out: TRUE if ok, or if the log block may be in the
- format of InnoDB version < 3.23.52 */
- byte* block) /* in: pointer to a log block */
+ const byte* block) /*!< in: pointer to a log block */
{
#ifdef UNIV_LOG_DEBUG
return(TRUE);
@@ -700,22 +724,22 @@ log_block_checksum_is_ok_or_old_format(
}
#ifdef UNIV_HOTBACKUP
-/***********************************************************************
+/*******************************************************************//**
Scans the log segment and n_bytes_scanned is set to the length of valid
log scanned. */
UNIV_INTERN
void
recv_scan_log_seg_for_backup(
/*=========================*/
- byte* buf, /* in: buffer containing log data */
- ulint buf_len, /* in: data length in that buffer */
- ib_uint64_t* scanned_lsn, /* in/out: lsn of buffer start,
+ byte* buf, /*!< in: buffer containing log data */
+ ulint buf_len, /*!< in: data length in that buffer */
+ ib_uint64_t* scanned_lsn, /*!< in/out: lsn of buffer start,
we return scanned lsn */
ulint* scanned_checkpoint_no,
- /* in/out: 4 lowest bytes of the
+ /*!< in/out: 4 lowest bytes of the
highest scanned checkpoint number so
far */
- ulint* n_bytes_scanned)/* out: how much we were able to
+ ulint* n_bytes_scanned)/*!< out: how much we were able to
scan, smaller than buf_len if log
data ended here */
{
@@ -791,44 +815,124 @@ recv_scan_log_seg_for_backup(
}
#endif /* UNIV_HOTBACKUP */
-/***********************************************************************
+/*******************************************************************//**
Tries to parse a single log record body and also applies it to a page if
-specified. File ops are parsed, but not applied in this function. */
+specified. File ops are parsed, but not applied in this function.
+@return log record end, NULL if not a complete record */
static
byte*
recv_parse_or_apply_log_rec_body(
/*=============================*/
- /* out: log record end, NULL if not a
- complete record */
- byte type, /* in: type */
- byte* ptr, /* in: pointer to a buffer */
- byte* end_ptr,/* in: pointer to the buffer end */
- buf_block_t* block, /* in/out: buffer block or NULL; if
+ byte type, /*!< in: type */
+ byte* ptr, /*!< in: pointer to a buffer */
+ byte* end_ptr,/*!< in: pointer to the buffer end */
+ buf_block_t* block, /*!< in/out: buffer block or NULL; if
not NULL, then the log record is
applied to the page, and the log
record should be complete then */
- mtr_t* mtr) /* in: mtr or NULL; should be non-NULL
+ mtr_t* mtr) /*!< in: mtr or NULL; should be non-NULL
if and only if block is non-NULL */
{
dict_index_t* index = NULL;
page_t* page;
page_zip_des_t* page_zip;
+#ifdef UNIV_DEBUG
+ ulint page_type;
+#endif /* UNIV_DEBUG */
ut_ad(!block == !mtr);
if (block) {
page = block->frame;
page_zip = buf_block_get_page_zip(block);
+ ut_d(page_type = fil_page_get_type(page));
} else {
page = NULL;
page_zip = NULL;
+ ut_d(page_type = FIL_PAGE_TYPE_ALLOCATED);
}
switch (type) {
case MLOG_1BYTE: case MLOG_2BYTES: case MLOG_4BYTES: case MLOG_8BYTES:
+#ifdef UNIV_DEBUG
+ if (page && page_type == FIL_PAGE_TYPE_ALLOCATED
+ && end_ptr >= ptr + 2) {
+ /* It is OK to set FIL_PAGE_TYPE and certain
+ list node fields on an empty page. Any other
+ write is not OK. */
+
+ /* NOTE: There may be bogus assertion failures for
+ dict_hdr_create(), trx_rseg_header_create(),
+ trx_sys_create_doublewrite_buf(), and
+ trx_sysf_create().
+ These are only called during database creation. */
+ ulint offs = mach_read_from_2(ptr);
+
+ switch (type) {
+ default:
+ ut_error;
+ case MLOG_2BYTES:
+ /* Note that this can fail when the
+ redo log been written with something
+ older than InnoDB Plugin 1.0.4. */
+ ut_ad(offs == FIL_PAGE_TYPE
+ || offs == IBUF_TREE_SEG_HEADER
+ + IBUF_HEADER + FSEG_HDR_OFFSET
+ || offs == PAGE_BTR_IBUF_FREE_LIST
+ + PAGE_HEADER + FIL_ADDR_BYTE
+ || offs == PAGE_BTR_IBUF_FREE_LIST
+ + PAGE_HEADER + FIL_ADDR_BYTE
+ + FIL_ADDR_SIZE
+ || offs == PAGE_BTR_SEG_LEAF
+ + PAGE_HEADER + FSEG_HDR_OFFSET
+ || offs == PAGE_BTR_SEG_TOP
+ + PAGE_HEADER + FSEG_HDR_OFFSET
+ || offs == PAGE_BTR_IBUF_FREE_LIST_NODE
+ + PAGE_HEADER + FIL_ADDR_BYTE
+ + 0 /*FLST_PREV*/
+ || offs == PAGE_BTR_IBUF_FREE_LIST_NODE
+ + PAGE_HEADER + FIL_ADDR_BYTE
+ + FIL_ADDR_SIZE /*FLST_NEXT*/);
+ break;
+ case MLOG_4BYTES:
+ /* Note that this can fail when the
+ redo log been written with something
+ older than InnoDB Plugin 1.0.4. */
+ ut_ad(0
+ || offs == IBUF_TREE_SEG_HEADER
+ + IBUF_HEADER + FSEG_HDR_SPACE
+ || offs == IBUF_TREE_SEG_HEADER
+ + IBUF_HEADER + FSEG_HDR_PAGE_NO
+ || offs == PAGE_BTR_IBUF_FREE_LIST
+ + PAGE_HEADER/* flst_init */
+ || offs == PAGE_BTR_IBUF_FREE_LIST
+ + PAGE_HEADER + FIL_ADDR_PAGE
+ || offs == PAGE_BTR_IBUF_FREE_LIST
+ + PAGE_HEADER + FIL_ADDR_PAGE
+ + FIL_ADDR_SIZE
+ || offs == PAGE_BTR_SEG_LEAF
+ + PAGE_HEADER + FSEG_HDR_PAGE_NO
+ || offs == PAGE_BTR_SEG_LEAF
+ + PAGE_HEADER + FSEG_HDR_SPACE
+ || offs == PAGE_BTR_SEG_TOP
+ + PAGE_HEADER + FSEG_HDR_PAGE_NO
+ || offs == PAGE_BTR_SEG_TOP
+ + PAGE_HEADER + FSEG_HDR_SPACE
+ || offs == PAGE_BTR_IBUF_FREE_LIST_NODE
+ + PAGE_HEADER + FIL_ADDR_PAGE
+ + 0 /*FLST_PREV*/
+ || offs == PAGE_BTR_IBUF_FREE_LIST_NODE
+ + PAGE_HEADER + FIL_ADDR_PAGE
+ + FIL_ADDR_SIZE /*FLST_NEXT*/);
+ break;
+ }
+ }
+#endif /* UNIV_DEBUG */
ptr = mlog_parse_nbytes(type, ptr, end_ptr, page, page_zip);
break;
case MLOG_REC_INSERT: case MLOG_COMP_REC_INSERT:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
+
if (NULL != (ptr = mlog_parse_index(
ptr, end_ptr,
type == MLOG_COMP_REC_INSERT,
@@ -841,6 +945,8 @@ recv_parse_or_apply_log_rec_body(
}
break;
case MLOG_REC_CLUST_DELETE_MARK: case MLOG_COMP_REC_CLUST_DELETE_MARK:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
+
if (NULL != (ptr = mlog_parse_index(
ptr, end_ptr,
type == MLOG_COMP_REC_CLUST_DELETE_MARK,
@@ -853,6 +959,7 @@ recv_parse_or_apply_log_rec_body(
}
break;
case MLOG_COMP_REC_SEC_DELETE_MARK:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
/* This log record type is obsolete, but we process it for
backward compatibility with MySQL 5.0.3 and 5.0.4. */
ut_a(!page || page_is_comp(page));
@@ -863,10 +970,13 @@ recv_parse_or_apply_log_rec_body(
}
/* Fall through */
case MLOG_REC_SEC_DELETE_MARK:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
ptr = btr_cur_parse_del_mark_set_sec_rec(ptr, end_ptr,
page, page_zip);
break;
case MLOG_REC_UPDATE_IN_PLACE: case MLOG_COMP_REC_UPDATE_IN_PLACE:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
+
if (NULL != (ptr = mlog_parse_index(
ptr, end_ptr,
type == MLOG_COMP_REC_UPDATE_IN_PLACE,
@@ -880,6 +990,8 @@ recv_parse_or_apply_log_rec_body(
break;
case MLOG_LIST_END_DELETE: case MLOG_COMP_LIST_END_DELETE:
case MLOG_LIST_START_DELETE: case MLOG_COMP_LIST_START_DELETE:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
+
if (NULL != (ptr = mlog_parse_index(
ptr, end_ptr,
type == MLOG_COMP_LIST_END_DELETE
@@ -893,6 +1005,8 @@ recv_parse_or_apply_log_rec_body(
}
break;
case MLOG_LIST_END_COPY_CREATED: case MLOG_COMP_LIST_END_COPY_CREATED:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
+
if (NULL != (ptr = mlog_parse_index(
ptr, end_ptr,
type == MLOG_COMP_LIST_END_COPY_CREATED,
@@ -905,6 +1019,8 @@ recv_parse_or_apply_log_rec_body(
}
break;
case MLOG_PAGE_REORGANIZE: case MLOG_COMP_PAGE_REORGANIZE:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
+
if (NULL != (ptr = mlog_parse_index(
ptr, end_ptr,
type == MLOG_COMP_PAGE_REORGANIZE,
@@ -917,29 +1033,36 @@ recv_parse_or_apply_log_rec_body(
}
break;
case MLOG_PAGE_CREATE: case MLOG_COMP_PAGE_CREATE:
+ /* Allow anything in page_type when creating a page. */
ut_a(!page_zip);
ptr = page_parse_create(ptr, end_ptr,
type == MLOG_COMP_PAGE_CREATE,
block, mtr);
break;
case MLOG_UNDO_INSERT:
+ ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
ptr = trx_undo_parse_add_undo_rec(ptr, end_ptr, page);
break;
case MLOG_UNDO_ERASE_END:
+ ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
ptr = trx_undo_parse_erase_page_end(ptr, end_ptr, page, mtr);
break;
case MLOG_UNDO_INIT:
+ /* Allow anything in page_type when creating a page. */
ptr = trx_undo_parse_page_init(ptr, end_ptr, page, mtr);
break;
case MLOG_UNDO_HDR_DISCARD:
+ ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
ptr = trx_undo_parse_discard_latest(ptr, end_ptr, page, mtr);
break;
case MLOG_UNDO_HDR_CREATE:
case MLOG_UNDO_HDR_REUSE:
+ ut_ad(!page || page_type == FIL_PAGE_UNDO_LOG);
ptr = trx_undo_parse_page_header(type, ptr, end_ptr,
page, mtr);
break;
case MLOG_REC_MIN_MARK: case MLOG_COMP_REC_MIN_MARK:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
/* On a compressed page, MLOG_COMP_REC_MIN_MARK
will be followed by MLOG_COMP_REC_DELETE
or MLOG_ZIP_WRITE_HEADER(FIL_PAGE_PREV, FIL_NULL)
@@ -950,6 +1073,8 @@ recv_parse_or_apply_log_rec_body(
page, mtr);
break;
case MLOG_REC_DELETE: case MLOG_COMP_REC_DELETE:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
+
if (NULL != (ptr = mlog_parse_index(
ptr, end_ptr,
type == MLOG_COMP_REC_DELETE,
@@ -962,33 +1087,40 @@ recv_parse_or_apply_log_rec_body(
}
break;
case MLOG_IBUF_BITMAP_INIT:
+ /* Allow anything in page_type when creating a page. */
ptr = ibuf_parse_bitmap_init(ptr, end_ptr, block, mtr);
break;
case MLOG_INIT_FILE_PAGE:
+ /* Allow anything in page_type when creating a page. */
ptr = fsp_parse_init_file_page(ptr, end_ptr, block);
break;
case MLOG_WRITE_STRING:
+ ut_ad(!page || page_type != FIL_PAGE_TYPE_ALLOCATED);
ptr = mlog_parse_string(ptr, end_ptr, page, page_zip);
break;
case MLOG_FILE_CREATE:
case MLOG_FILE_RENAME:
case MLOG_FILE_DELETE:
case MLOG_FILE_CREATE2:
- ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0);
+ ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0, 0);
break;
case MLOG_ZIP_WRITE_NODE_PTR:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
ptr = page_zip_parse_write_node_ptr(ptr, end_ptr,
page, page_zip);
break;
case MLOG_ZIP_WRITE_BLOB_PTR:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
ptr = page_zip_parse_write_blob_ptr(ptr, end_ptr,
page, page_zip);
break;
case MLOG_ZIP_WRITE_HEADER:
+ ut_ad(!page || page_type == FIL_PAGE_INDEX);
ptr = page_zip_parse_write_header(ptr, end_ptr,
page, page_zip);
break;
case MLOG_ZIP_PAGE_COMPRESS:
+ /* Allow anything in page_type when creating a page. */
ptr = page_zip_parse_compress(ptr, end_ptr,
page, page_zip);
break;
@@ -1007,44 +1139,43 @@ recv_parse_or_apply_log_rec_body(
return(ptr);
}
-/*************************************************************************
+/*********************************************************************//**
Calculates the fold value of a page file address: used in inserting or
-searching for a log record in the hash table. */
+searching for a log record in the hash table.
+@return folded value */
UNIV_INLINE
ulint
recv_fold(
/*======*/
- /* out: folded value */
- ulint space, /* in: space */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no)/*!< in: page number */
{
return(ut_fold_ulint_pair(space, page_no));
}
-/*************************************************************************
+/*********************************************************************//**
Calculates the hash value of a page file address: used in inserting or
-searching for a log record in the hash table. */
+searching for a log record in the hash table.
+@return folded value */
UNIV_INLINE
ulint
recv_hash(
/*======*/
- /* out: folded value */
- ulint space, /* in: space */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint page_no)/*!< in: page number */
{
return(hash_calc_hash(recv_fold(space, page_no), recv_sys->addr_hash));
}
-/*************************************************************************
-Gets the hashed file address struct for a page. */
+/*********************************************************************//**
+Gets the hashed file address struct for a page.
+@return file address struct, NULL if not found from the hash table */
static
recv_addr_t*
recv_get_fil_addr_struct(
/*=====================*/
- /* out: file address struct, NULL if not found from
- the hash table */
- ulint space, /* in: space id */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space id */
+ ulint page_no)/*!< in: page number */
{
recv_addr_t* recv_addr;
@@ -1063,19 +1194,19 @@ recv_get_fil_addr_struct(
return(recv_addr);
}
-/***********************************************************************
+/*******************************************************************//**
Adds a new log record to the hash table of log records. */
static
void
recv_add_to_hash_table(
/*===================*/
- byte type, /* in: log record type */
- ulint space, /* in: space id */
- ulint page_no, /* in: page number */
- byte* body, /* in: log record body */
- byte* rec_end, /* in: log record end */
- ib_uint64_t start_lsn, /* in: start lsn of the mtr */
- ib_uint64_t end_lsn) /* in: end lsn of the mtr */
+ byte type, /*!< in: log record type */
+ ulint space, /*!< in: space id */
+ ulint page_no, /*!< in: page number */
+ byte* body, /*!< in: log record body */
+ byte* rec_end, /*!< in: log record end */
+ ib_uint64_t start_lsn, /*!< in: start lsn of the mtr */
+ ib_uint64_t end_lsn) /*!< in: end lsn of the mtr */
{
recv_t* recv;
ulint len;
@@ -1148,14 +1279,14 @@ recv_add_to_hash_table(
*prev_field = NULL;
}
-/*************************************************************************
+/*********************************************************************//**
Copies the log record body from recv to buf. */
static
void
recv_data_copy_to_buf(
/*==================*/
- byte* buf, /* in: buffer of length at least recv->len */
- recv_t* recv) /* in: log record */
+ byte* buf, /*!< in: buffer of length at least recv->len */
+ recv_t* recv) /*!< in: log record */
{
recv_data_t* recv_data;
ulint part_len;
@@ -1180,23 +1311,20 @@ recv_data_copy_to_buf(
}
}
-/****************************************************************************
+/************************************************************************//**
Applies the hashed log records to the page, if the page lsn is less than the
lsn of a log record. This can be called when a buffer page has just been
read in, or also for a page already in the buffer pool. */
UNIV_INTERN
void
-recv_recover_page(
-/*==============*/
- ibool recover_backup,
- /* in: TRUE if we are recovering a backup
- page: then we do not acquire any latches
- since the page was read in outside the
- buffer pool */
+recv_recover_page_func(
+/*===================*/
+#ifndef UNIV_HOTBACKUP
ibool just_read_in,
- /* in: TRUE if the i/o-handler calls this for
- a freshly read page */
- buf_block_t* block) /* in: buffer block */
+ /*!< in: TRUE if the i/o handler calls
+ this for a freshly read page */
+#endif /* !UNIV_HOTBACKUP */
+ buf_block_t* block) /*!< in/out: buffer block */
{
page_t* page;
recv_addr_t* recv_addr;
@@ -1207,7 +1335,9 @@ recv_recover_page(
ib_uint64_t page_lsn;
ib_uint64_t page_newest_lsn;
ibool modification_to_page;
+#ifndef UNIV_HOTBACKUP
ibool success;
+#endif /* !UNIV_HOTBACKUP */
mtr_t mtr;
mutex_enter(&(recv_sys->mutex));
@@ -1249,46 +1379,42 @@ recv_recover_page(
page = block->frame;
- if (!recover_backup) {
- if (just_read_in) {
- /* Move the ownership of the x-latch on the
- page to this OS thread, so that we can acquire
- a second x-latch on it. This is needed for the
- operations to the page to pass the debug
- checks. */
+#ifndef UNIV_HOTBACKUP
+ if (just_read_in) {
+ /* Move the ownership of the x-latch on the page to
+ this OS thread, so that we can acquire a second
+ x-latch on it. This is needed for the operations to
+ the page to pass the debug checks. */
- rw_lock_x_lock_move_ownership(&(block->lock));
- }
+ rw_lock_x_lock_move_ownership(&block->lock);
+ }
- success = buf_page_get_known_nowait(RW_X_LATCH, block,
- BUF_KEEP_OLD,
- __FILE__, __LINE__,
- &mtr);
- ut_a(success);
+ success = buf_page_get_known_nowait(RW_X_LATCH, block,
+ BUF_KEEP_OLD,
+ __FILE__, __LINE__,
+ &mtr);
+ ut_a(success);
- buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
- }
+ buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
+#endif /* !UNIV_HOTBACKUP */
/* Read the newest modification lsn from the page */
page_lsn = mach_read_ull(page + FIL_PAGE_LSN);
- if (!recover_backup) {
- /* It may be that the page has been modified in the buffer
- pool: read the newest modification lsn there */
-
- page_newest_lsn
- = buf_page_get_newest_modification(&block->page);
+#ifndef UNIV_HOTBACKUP
+ /* It may be that the page has been modified in the buffer
+ pool: read the newest modification lsn there */
- if (page_newest_lsn) {
+ page_newest_lsn = buf_page_get_newest_modification(&block->page);
- page_lsn = page_newest_lsn;
- }
- } else {
- /* In recovery from a backup we do not really use the buffer
- pool */
+ if (page_newest_lsn) {
- page_newest_lsn = 0;
+ page_lsn = page_newest_lsn;
}
+#else /* !UNIV_HOTBACKUP */
+ /* In recovery from a backup we do not really use the buffer pool */
+ page_newest_lsn = 0;
+#endif /* !UNIV_HOTBACKUP */
modification_to_page = FALSE;
start_lsn = end_lsn = 0;
@@ -1377,11 +1503,13 @@ recv_recover_page(
mutex_exit(&(recv_sys->mutex));
- if (!recover_backup && modification_to_page) {
+#ifndef UNIV_HOTBACKUP
+ if (modification_to_page) {
ut_a(block);
buf_flush_recv_note_modification(block, start_lsn, end_lsn);
}
+#endif /* !UNIV_HOTBACKUP */
/* Make sure that committing mtr does not change the modification
lsn values of page */
@@ -1391,17 +1519,18 @@ recv_recover_page(
mtr_commit(&mtr);
}
-/***********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************************//**
Reads in pages which have hashed log records, from an area around a given
-page number. */
+page number.
+@return number of pages found */
static
ulint
recv_read_in_area(
/*==============*/
- /* out: number of pages found */
- ulint space, /* in: space */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- ulint page_no)/* in: page number */
+ ulint space, /*!< in: space */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint page_no)/*!< in: page number */
{
recv_addr_t* recv_addr;
ulint page_nos[RECV_READ_AHEAD_AREA];
@@ -1439,14 +1568,14 @@ recv_read_in_area(
return(n);
}
-/***********************************************************************
+/*******************************************************************//**
Empties the hash table of stored log records, applying them to appropriate
pages. */
UNIV_INTERN
void
recv_apply_hashed_log_recs(
/*=======================*/
- ibool allow_ibuf) /* in: if TRUE, also ibuf operations are
+ ibool allow_ibuf) /*!< in: if TRUE, also ibuf operations are
allowed during the application; if FALSE,
no ibuf operations are allowed, and after
the application all file pages are flushed to
@@ -1515,7 +1644,7 @@ loop:
buf_block_dbg_add_level(
block, SYNC_NO_ORDER_CHECK);
- recv_recover_page(FALSE, FALSE, block);
+ recv_recover_page(FALSE, block);
mtr_commit(&mtr);
} else {
recv_read_in_area(space, zip_size,
@@ -1587,9 +1716,8 @@ loop:
mutex_exit(&(recv_sys->mutex));
}
-
-#ifdef UNIV_HOTBACKUP
-/***********************************************************************
+#else /* !UNIV_HOTBACKUP */
+/*******************************************************************//**
Applies log records in the hash table to a backup. */
UNIV_INTERN
void
@@ -1607,7 +1735,7 @@ recv_apply_log_recs_for_backup(void)
recv_sys->apply_log_recs = TRUE;
recv_sys->apply_batch_on = TRUE;
- block = buf_LRU_get_free_block(UNIV_PAGE_SIZE);
+ block = back_block1;
fputs("InnoDB: Starting an apply batch of log records"
" to the database...\n"
@@ -1675,6 +1803,10 @@ recv_apply_log_recs_for_backup(void)
recv_addr->space, zip_size,
recv_addr->page_no, 0, zip_size,
block->page.zip.data, NULL);
+ if (error == DB_SUCCESS
+ && !buf_zip_decompress(block, TRUE)) {
+ exit(1);
+ }
} else {
error = fil_io(OS_FILE_READ, TRUE,
recv_addr->space, 0,
@@ -1695,7 +1827,7 @@ recv_apply_log_recs_for_backup(void)
}
/* Apply the log records to this page */
- recv_recover_page(TRUE, FALSE, block);
+ recv_recover_page(FALSE, block);
/* Write the page back to the tablespace file using the
fil0fil.c routines */
@@ -1729,25 +1861,23 @@ skip_this_recv_addr:
}
}
- buf_block_free(block);
recv_sys_empty_hash();
}
-#endif /* UNIV_HOTBACKUP */
+#endif /* !UNIV_HOTBACKUP */
-/***********************************************************************
-Tries to parse a single log record and returns its length. */
+/*******************************************************************//**
+Tries to parse a single log record and returns its length.
+@return length of the record, or 0 if the record was not complete */
static
ulint
recv_parse_log_rec(
/*===============*/
- /* out: length of the record, or 0 if the record was
- not complete */
- byte* ptr, /* in: pointer to a buffer */
- byte* end_ptr,/* in: pointer to the buffer end */
- byte* type, /* out: type */
- ulint* space, /* out: space id */
- ulint* page_no,/* out: page number */
- byte** body) /* out: log record body start */
+ byte* ptr, /*!< in: pointer to a buffer */
+ byte* end_ptr,/*!< in: pointer to the buffer end */
+ byte* type, /*!< out: type */
+ ulint* space, /*!< out: space id */
+ ulint* page_no,/*!< out: page number */
+ byte** body) /*!< out: log record body start */
{
byte* new_ptr;
@@ -1805,14 +1935,14 @@ recv_parse_log_rec(
return(new_ptr - ptr);
}
-/***********************************************************
+/*******************************************************//**
Calculates the new value for lsn when more data is added to the log. */
static
ib_uint64_t
recv_calc_lsn_on_data_add(
/*======================*/
- ib_uint64_t lsn, /* in: old lsn */
- ib_uint64_t len) /* in: this many bytes of data is
+ ib_uint64_t lsn, /*!< in: old lsn */
+ ib_uint64_t len) /*!< in: this many bytes of data is
added, log block headers not included */
{
ulint frag_len;
@@ -1832,15 +1962,15 @@ recv_calc_lsn_on_data_add(
}
#ifdef UNIV_LOG_DEBUG
-/***********************************************************
+/*******************************************************//**
Checks that the parser recognizes incomplete initial segments of a log
record as incomplete. */
static
void
recv_check_incomplete_log_recs(
/*===========================*/
- byte* ptr, /* in: pointer to a complete log record */
- ulint len) /* in: length of the log record */
+ byte* ptr, /*!< in: pointer to a complete log record */
+ ulint len) /*!< in: length of the log record */
{
ulint i;
byte type;
@@ -1855,16 +1985,16 @@ recv_check_incomplete_log_recs(
}
#endif /* UNIV_LOG_DEBUG */
-/***********************************************************
+/*******************************************************//**
Prints diagnostic info of corrupt log. */
static
void
recv_report_corrupt_log(
/*====================*/
- byte* ptr, /* in: pointer to corrupt log record */
- byte type, /* in: type of the record */
- ulint space, /* in: space id, this may also be garbage */
- ulint page_no)/* in: page number, this may also be garbage */
+ byte* ptr, /*!< in: pointer to corrupt log record */
+ byte type, /*!< in: type of the record */
+ ulint space, /*!< in: space id, this may also be garbage */
+ ulint page_no)/*!< in: page number, this may also be garbage */
{
fprintf(stderr,
"InnoDB: ############### CORRUPT LOG RECORD FOUND\n"
@@ -1904,22 +2034,21 @@ recv_report_corrupt_log(
"InnoDB: far enough in recovery! Please run CHECK TABLE\n"
"InnoDB: on your InnoDB tables to check that they are ok!\n"
"InnoDB: If mysqld crashes after this recovery, look at\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "forcing-recovery.html\n"
+ "InnoDB: " REFMAN "forcing-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
fflush(stderr);
}
-/***********************************************************
+/*******************************************************//**
Parses log records from a buffer and stores them to a hash table to wait
-merging to file pages. */
+merging to file pages.
+@return currently always returns FALSE */
static
ibool
recv_parse_log_recs(
/*================*/
- /* out: currently always returns FALSE */
- ibool store_to_hash) /* in: TRUE if the records should be stored
+ ibool store_to_hash) /*!< in: TRUE if the records should be stored
to the hash table; this is set to FALSE if just
debug checking is needed */
{
@@ -2023,7 +2152,8 @@ loop:
point to the datadir we should use there */
if (NULL == fil_op_log_parse_or_replay(
- body, end_ptr, type, space)) {
+ body, end_ptr, type,
+ space, page_no)) {
fprintf(stderr,
"InnoDB: Error: file op"
" log record of type %lu"
@@ -2152,16 +2282,16 @@ loop:
goto loop;
}
-/***********************************************************
+/*******************************************************//**
Adds data from a new log block to the parsing buffer of recv_sys if
-recv_sys->parse_start_lsn is non-zero. */
+recv_sys->parse_start_lsn is non-zero.
+@return TRUE if more data added */
static
ibool
recv_sys_add_to_parsing_buf(
/*========================*/
- /* out: TRUE if more data added */
- byte* log_block, /* in: log block */
- ib_uint64_t scanned_lsn) /* in: lsn of how far we were able
+ const byte* log_block, /*!< in: log block */
+ ib_uint64_t scanned_lsn) /*!< in: lsn of how far we were able
to find data in this log block */
{
ulint more_len;
@@ -2227,7 +2357,7 @@ recv_sys_add_to_parsing_buf(
return(TRUE);
}
-/***********************************************************
+/*******************************************************//**
Moves the parsing buffer data left to the buffer start. */
static
void
@@ -2242,39 +2372,34 @@ recv_sys_justify_left_parsing_buf(void)
recv_sys->recovered_offset = 0;
}
-/***********************************************************
-Scans log from a buffer and stores new log data to the parsing buffer. Parses
-and hashes the log records if new data found. */
+/*******************************************************//**
+Scans log from a buffer and stores new log data to the parsing buffer.
+Parses and hashes the log records if new data found. Unless
+UNIV_HOTBACKUP is defined, this function will apply log records
+automatically when the hash table becomes full.
+@return TRUE if limit_lsn has been reached, or not able to scan any
+more in this log group */
UNIV_INTERN
ibool
recv_scan_log_recs(
/*===============*/
- /* out: TRUE if limit_lsn has been
- reached, or not able to scan any more
- in this log group */
- ibool apply_automatically,/* in: TRUE if we want this
- function to apply log records
- automatically when the hash table
- becomes full; in the hot backup tool
- the tool does the applying, not this
- function */
- ulint available_memory,/* in: we let the hash table of recs
+ ulint available_memory,/*!< in: we let the hash table of recs
to grow to this size, at the maximum */
- ibool store_to_hash, /* in: TRUE if the records should be
+ ibool store_to_hash, /*!< in: TRUE if the records should be
stored to the hash table; this is set
to FALSE if just debug checking is
needed */
- byte* buf, /* in: buffer containing a log segment
- or garbage */
- ulint len, /* in: buffer length */
- ib_uint64_t start_lsn, /* in: buffer start lsn */
- ib_uint64_t* contiguous_lsn, /* in/out: it is known that all log
+ const byte* buf, /*!< in: buffer containing a log
+ segment or garbage */
+ ulint len, /*!< in: buffer length */
+ ib_uint64_t start_lsn, /*!< in: buffer start lsn */
+ ib_uint64_t* contiguous_lsn, /*!< in/out: it is known that all log
groups contain contiguous log data up
to this lsn */
- ib_uint64_t* group_scanned_lsn)/* out: scanning succeeded up to
+ ib_uint64_t* group_scanned_lsn)/*!< out: scanning succeeded up to
this lsn */
{
- byte* log_block;
+ const byte* log_block;
ulint no;
ib_uint64_t scanned_lsn;
ibool finished;
@@ -2284,7 +2409,6 @@ recv_scan_log_recs(
ut_ad(start_lsn % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_ad(len % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_ad(len > 0);
- ut_a(apply_automatically <= TRUE);
ut_a(store_to_hash <= TRUE);
finished = FALSE;
@@ -2385,6 +2509,7 @@ recv_scan_log_recs(
of startup type, we must initiate crash recovery
environment before parsing these log records. */
+#ifndef UNIV_HOTBACKUP
if (recv_log_scan_is_startup_type
&& !recv_needed_recovery) {
@@ -2394,6 +2519,7 @@ recv_scan_log_recs(
recv_sys->scanned_lsn);
recv_init_crash_recovery();
}
+#endif /* !UNIV_HOTBACKUP */
/* We were able to find more log data: add it to the
parsing buffer if parse_start_lsn is already
@@ -2447,9 +2573,9 @@ recv_scan_log_recs(
recv_parse_log_recs(store_to_hash);
+#ifndef UNIV_HOTBACKUP
if (store_to_hash && mem_heap_get_size(recv_sys->heap)
- > available_memory
- && apply_automatically) {
+ > available_memory) {
/* Hash table of log records has grown too big:
empty it; FALSE means no ibuf operations
@@ -2459,6 +2585,7 @@ recv_scan_log_recs(
recv_apply_hashed_log_recs(FALSE);
}
+#endif /* !UNIV_HOTBACKUP */
if (recv_sys->recovered_offset > RECV_PARSING_BUF_SIZE / 4) {
/* Move parsing buffer data to the buffer start */
@@ -2470,18 +2597,19 @@ recv_scan_log_recs(
return(finished);
}
-/***********************************************************
+#ifndef UNIV_HOTBACKUP
+/*******************************************************//**
Scans log from a buffer and stores new log data to the parsing buffer. Parses
and hashes the log records if new data found. */
static
void
recv_group_scan_log_recs(
/*=====================*/
- log_group_t* group, /* in: log group */
- ib_uint64_t* contiguous_lsn, /* in/out: it is known that all log
+ log_group_t* group, /*!< in: log group */
+ ib_uint64_t* contiguous_lsn, /*!< in/out: it is known that all log
groups contain contiguous log data up
to this lsn */
- ib_uint64_t* group_scanned_lsn)/* out: scanning succeeded up to
+ ib_uint64_t* group_scanned_lsn)/*!< out: scanning succeeded up to
this lsn */
{
ibool finished;
@@ -2499,7 +2627,7 @@ recv_group_scan_log_recs(
group, start_lsn, end_lsn);
finished = recv_scan_log_recs(
- TRUE, (buf_pool->curr_size - recv_n_pool_free_frames)
+ (buf_pool->curr_size - recv_n_pool_free_frames)
* UNIV_PAGE_SIZE, TRUE, log_sys->buf, RECV_SCAN_SIZE,
start_lsn, contiguous_lsn, group_scanned_lsn);
start_lsn = end_lsn;
@@ -2516,7 +2644,7 @@ recv_group_scan_log_recs(
#endif /* UNIV_DEBUG */
}
-/***********************************************************
+/*******************************************************//**
Initialize crash recovery environment. Can be called iff
recv_needed_recovery == FALSE. */
static
@@ -2557,24 +2685,25 @@ recv_init_crash_recovery(void)
}
}
-/************************************************************
+/********************************************************//**
Recovers from a checkpoint. When this function returns, the database is able
to start processing of new user transactions, but the function
recv_recovery_from_checkpoint_finish should be called later to complete
-the recovery and free the resources used in it. */
+the recovery and free the resources used in it.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
recv_recovery_from_checkpoint_start_func(
/*=====================================*/
- /* out: error code or DB_SUCCESS */
#ifdef UNIV_LOG_ARCHIVE
- ulint type, /* in: LOG_CHECKPOINT or LOG_ARCHIVE */
- ib_uint64_t limit_lsn, /* in: recover up to this lsn
+ ulint type, /*!< in: LOG_CHECKPOINT or
+ LOG_ARCHIVE */
+ ib_uint64_t limit_lsn, /*!< in: recover up to this lsn
if possible */
#endif /* UNIV_LOG_ARCHIVE */
- ib_uint64_t min_flushed_lsn,/* in: min flushed lsn from
+ ib_uint64_t min_flushed_lsn,/*!< in: min flushed lsn from
data files */
- ib_uint64_t max_flushed_lsn)/* in: max flushed lsn from
+ ib_uint64_t max_flushed_lsn)/*!< in: max flushed lsn from
data files */
{
log_group_t* group;
@@ -2593,16 +2722,20 @@ recv_recovery_from_checkpoint_start_func(
#ifdef UNIV_LOG_ARCHIVE
ut_ad(type != LOG_CHECKPOINT || limit_lsn == IB_ULONGLONG_MAX);
+/** TRUE when recovering from a checkpoint */
# define TYPE_CHECKPOINT (type == LOG_CHECKPOINT)
+/** Recover up to this log sequence number */
# define LIMIT_LSN limit_lsn
#else /* UNIV_LOG_ARCHIVE */
+/** TRUE when recovering from a checkpoint */
# define TYPE_CHECKPOINT 1
+/** Recover up to this log sequence number */
# define LIMIT_LSN IB_ULONGLONG_MAX
#endif /* UNIV_LOG_ARCHIVE */
if (TYPE_CHECKPOINT) {
recv_sys_create();
- recv_sys_init(FALSE, buf_pool_get_curr_size());
+ recv_sys_init(buf_pool_get_curr_size());
}
if (srv_force_recovery >= SRV_FORCE_NO_LOG_REDO) {
@@ -2922,7 +3055,7 @@ recv_recovery_from_checkpoint_start_func(
#undef LIMIT_LSN
}
-/************************************************************
+/********************************************************//**
Completes recovery from a checkpoint. */
UNIV_INTERN
void
@@ -2994,21 +3127,21 @@ recv_recovery_from_checkpoint_finish(void)
}
}
-/**********************************************************
+/******************************************************//**
Resets the logs. The contents of log files will be lost! */
UNIV_INTERN
void
recv_reset_logs(
/*============*/
- ib_uint64_t lsn, /* in: reset to this lsn
+ ib_uint64_t lsn, /*!< in: reset to this lsn
rounded up to be divisible by
OS_FILE_LOG_BLOCK_SIZE, after
which we add
LOG_BLOCK_HDR_SIZE */
#ifdef UNIV_LOG_ARCHIVE
- ulint arch_log_no, /* in: next archived log file number */
+ ulint arch_log_no, /*!< in: next archived log file number */
#endif /* UNIV_LOG_ARCHIVE */
- ibool new_logs_created)/* in: TRUE if resetting logs
+ ibool new_logs_created)/*!< in: TRUE if resetting logs
is done at the log creation;
FALSE if it is done after
archive recovery */
@@ -3063,18 +3196,19 @@ recv_reset_logs(
mutex_enter(&(log_sys->mutex));
}
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_HOTBACKUP
-/**********************************************************
+/******************************************************//**
Creates new log files after a backup has been restored. */
UNIV_INTERN
void
recv_reset_log_files_for_backup(
/*============================*/
- const char* log_dir, /* in: log file directory path */
- ulint n_log_files, /* in: number of log files */
- ulint log_file_size, /* in: log file size */
- ib_uint64_t lsn) /* in: new start lsn, must be
+ const char* log_dir, /*!< in: log file directory path */
+ ulint n_log_files, /*!< in: number of log files */
+ ulint log_file_size, /*!< in: log file size */
+ ib_uint64_t lsn) /*!< in: new start lsn, must be
divisible by OS_FILE_LOG_BLOCK_SIZE */
{
os_file_t log_file;
@@ -3157,15 +3291,14 @@ recv_reset_log_files_for_backup(
#endif /* UNIV_HOTBACKUP */
#ifdef UNIV_LOG_ARCHIVE
-/**********************************************************
-Reads from the archive of a log group and performs recovery. */
+/******************************************************//**
+Reads from the archive of a log group and performs recovery.
+@return TRUE if no more complete consistent archive files */
static
ibool
log_group_recover_from_archive_file(
/*================================*/
- /* out: TRUE if no more complete
- consistent archive files */
- log_group_t* group) /* in: log group */
+ log_group_t* group) /*!< in: log group */
{
os_file_t file_handle;
ib_uint64_t start_lsn;
@@ -3322,7 +3455,7 @@ ask_again:
read_offset % UNIV_PAGE_SIZE, len, buf, NULL);
ret = recv_scan_log_recs(
- TRUE, (buf_pool->n_frames - recv_n_pool_free_frames)
+ (buf_pool->n_frames - recv_n_pool_free_frames)
* UNIV_PAGE_SIZE, TRUE, buf, len, start_lsn,
&dummy_lsn, &scanned_lsn);
@@ -3348,18 +3481,18 @@ ask_again:
return(FALSE);
}
-/************************************************************
-Recovers from archived log files, and also from log files, if they exist. */
+/********************************************************//**
+Recovers from archived log files, and also from log files, if they exist.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
recv_recovery_from_archive_start(
/*=============================*/
- /* out: error code or DB_SUCCESS */
- ib_uint64_t min_flushed_lsn,/* in: min flushed lsn field from the
+ ib_uint64_t min_flushed_lsn,/*!< in: min flushed lsn field from the
data files */
- ib_uint64_t limit_lsn, /* in: recover up to this lsn if
+ ib_uint64_t limit_lsn, /*!< in: recover up to this lsn if
possible */
- ulint first_log_no) /* in: number of the first archived
+ ulint first_log_no) /*!< in: number of the first archived
log file to use in the recovery; the
file will be searched from
INNOBASE_LOG_ARCH_DIR specified in
@@ -3374,7 +3507,7 @@ recv_recovery_from_archive_start(
ut_a(0);
recv_sys_create();
- recv_sys_init(FALSE, buf_pool_get_curr_size());
+ recv_sys_init(buf_pool_get_curr_size());
recv_recovery_on = TRUE;
recv_recovery_from_backup_on = TRUE;
@@ -3464,7 +3597,7 @@ recv_recovery_from_archive_start(
return(DB_SUCCESS);
}
-/************************************************************
+/********************************************************//**
Completes recovery from archive. */
UNIV_INTERN
void
diff --git a/storage/xtradb/mach/mach0data.c b/storage/xtradb/mach/mach0data.c
index 5deb475318d..e030ce9aadf 100644
--- a/storage/xtradb/mach/mach0data.c
+++ b/storage/xtradb/mach/mach0data.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/**********************************************************************
+/******************************************************************//**
+@file mach/mach0data.c
Utilities for converting data from the database file
to the machine format.
@@ -29,17 +30,16 @@ Created 11/28/1995 Heikki Tuuri
#include "mach0data.ic"
#endif
-/*************************************************************
-Reads a ulint in a compressed form if the log record fully contains it. */
+/*********************************************************//**
+Reads a ulint in a compressed form if the log record fully contains it.
+@return pointer to end of the stored field, NULL if not complete */
UNIV_INTERN
byte*
mach_parse_compressed(
/*==================*/
- /* out: pointer to end of the stored field, NULL if
- not complete */
- byte* ptr, /* in: pointer to buffer from where to read */
- byte* end_ptr,/* in: pointer to end of the buffer */
- ulint* val) /* out: read value (< 2^32) */
+ byte* ptr, /*!< in: pointer to buffer from where to read */
+ byte* end_ptr,/*!< in: pointer to end of the buffer */
+ ulint* val) /*!< out: read value (< 2^32) */
{
ulint flag;
@@ -93,17 +93,16 @@ mach_parse_compressed(
}
}
-/*************************************************************
-Reads a dulint in a compressed form if the log record fully contains it. */
+/*********************************************************//**
+Reads a dulint in a compressed form if the log record fully contains it.
+@return pointer to end of the stored field, NULL if not complete */
UNIV_INTERN
byte*
mach_dulint_parse_compressed(
/*=========================*/
- /* out: pointer to end of the stored field, NULL if
- not complete */
- byte* ptr, /* in: pointer to buffer from where to read */
- byte* end_ptr,/* in: pointer to end of the buffer */
- dulint* val) /* out: read value */
+ byte* ptr, /*!< in: pointer to buffer from where to read */
+ byte* end_ptr,/*!< in: pointer to end of the buffer */
+ dulint* val) /*!< out: read value */
{
ulint high;
ulint low;
diff --git a/storage/xtradb/mem/mem0dbg.c b/storage/xtradb/mem/mem0dbg.c
index a1647462922..a20eb2ad7d2 100644
--- a/storage/xtradb/mem/mem0dbg.c
+++ b/storage/xtradb/mem/mem0dbg.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file mem/mem0dbg.c
The memory management: the debug code. This is not a compilation module,
but is included in mem0mem.* !
@@ -24,10 +25,12 @@ Created 6/9/1994 Heikki Tuuri
*************************************************************************/
#ifdef UNIV_MEM_DEBUG
+# ifndef UNIV_HOTBACKUP
/* The mutex which protects in the debug version the hash table
containing the list of live memory heaps, and also the global
variables below. */
UNIV_INTERN mutex_t mem_hash_mutex;
+# endif /* !UNIV_HOTBACKUP */
/* The following variables contain information about the
extent of memory allocations. Only used in the debug version.
@@ -38,7 +41,10 @@ static ulint mem_n_allocations = 0;
static ulint mem_total_allocated_memory = 0;
UNIV_INTERN ulint mem_current_allocated_memory = 0;
static ulint mem_max_allocated_memory = 0;
+# ifndef UNIV_HOTBACKUP
static ulint mem_last_print_info = 0;
+static ibool mem_hash_initialized = FALSE;
+# endif /* !UNIV_HOTBACKUP */
/* Size of the hash table for memory management tracking */
#define MEM_HASH_SIZE 997
@@ -48,10 +54,10 @@ static ulint mem_last_print_info = 0;
typedef struct mem_hash_node_struct mem_hash_node_t;
struct mem_hash_node_struct {
UT_LIST_NODE_T(mem_hash_node_t)
- list; /* hash list node */
- mem_heap_t* heap; /* memory heap */
+ list; /*!< hash list node */
+ mem_heap_t* heap; /*!< memory heap */
const char* file_name;/* file where heap was created*/
- ulint line; /* file line of creation */
+ ulint line; /*!< file line of creation */
ulint nth_heap;/* this is the nth heap created */
UT_LIST_NODE_T(mem_hash_node_t)
all_list;/* list of all created heaps */
@@ -65,7 +71,6 @@ static mem_hash_cell_t mem_hash_table[MEM_HASH_SIZE];
/* The base node of the list of all allocated heaps */
static mem_hash_cell_t mem_all_list_base;
-static ibool mem_hash_initialized = FALSE;
UNIV_INLINE
@@ -128,13 +133,14 @@ mem_field_trailer_get_check(byte* field)
}
#endif /* UNIV_MEM_DEBUG */
-/**********************************************************************
+#ifndef UNIV_HOTBACKUP
+/******************************************************************//**
Initializes the memory system. */
UNIV_INTERN
void
mem_init(
/*=====*/
- ulint size) /* in: common pool size in bytes */
+ ulint size) /*!< in: common pool size in bytes */
{
#ifdef UNIV_MEM_DEBUG
@@ -164,16 +170,17 @@ mem_init(
mem_comm_pool = mem_pool_create(size);
}
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_MEM_DEBUG
-/**********************************************************************
+/******************************************************************//**
Initializes an allocated memory field in the debug version. */
UNIV_INTERN
void
mem_field_init(
/*===========*/
- byte* buf, /* in: memory field */
- ulint n) /* in: how many bytes the user requested */
+ byte* buf, /*!< in: memory field */
+ ulint n) /*!< in: how many bytes the user requested */
{
ulint rnd;
byte* usr_buf;
@@ -213,15 +220,15 @@ mem_field_init(
mem_init_buf(usr_buf, n);
}
-/**********************************************************************
+/******************************************************************//**
Erases an allocated memory field in the debug version. */
UNIV_INTERN
void
mem_field_erase(
/*============*/
- byte* buf, /* in: memory field */
+ byte* buf, /*!< in: memory field */
ulint n __attribute__((unused)))
- /* in: how many bytes the user requested */
+ /*!< in: how many bytes the user requested */
{
byte* usr_buf;
@@ -240,15 +247,15 @@ mem_field_erase(
mem_erase_buf(buf, MEM_SPACE_NEEDED(n));
}
-/*******************************************************************
+/***************************************************************//**
Initializes a buffer to a random combination of hex BA and BE.
Used to initialize allocated memory. */
UNIV_INTERN
void
mem_init_buf(
/*=========*/
- byte* buf, /* in: pointer to buffer */
- ulint n) /* in: length of buffer */
+ byte* buf, /*!< in: pointer to buffer */
+ ulint n) /*!< in: length of buffer */
{
byte* ptr;
@@ -266,15 +273,15 @@ mem_init_buf(
UNIV_MEM_INVALID(buf, n);
}
-/*******************************************************************
+/***************************************************************//**
Initializes a buffer to a random combination of hex DE and AD.
-Used to erase freed memory.*/
+Used to erase freed memory. */
UNIV_INTERN
void
mem_erase_buf(
/*==========*/
- byte* buf, /* in: pointer to buffer */
- ulint n) /* in: length of buffer */
+ byte* buf, /*!< in: pointer to buffer */
+ ulint n) /*!< in: length of buffer */
{
byte* ptr;
@@ -291,16 +298,16 @@ mem_erase_buf(
UNIV_MEM_FREE(buf, n);
}
-/*******************************************************************
+/***************************************************************//**
Inserts a created memory heap to the hash table of current allocated
memory heaps. */
UNIV_INTERN
void
mem_hash_insert(
/*============*/
- mem_heap_t* heap, /* in: the created heap */
- const char* file_name, /* in: file name of creation */
- ulint line) /* in: line where created */
+ mem_heap_t* heap, /*!< in: the created heap */
+ const char* file_name, /*!< in: file name of creation */
+ ulint line) /*!< in: line where created */
{
mem_hash_node_t* new_node;
ulint cell_no ;
@@ -329,7 +336,7 @@ mem_hash_insert(
mutex_exit(&mem_hash_mutex);
}
-/*******************************************************************
+/***************************************************************//**
Removes a memory heap (which is going to be freed by the caller)
from the list of live memory heaps. Returns the size of the heap
in terms of how much memory in bytes was allocated for the user of
@@ -341,9 +348,9 @@ UNIV_INTERN
void
mem_hash_remove(
/*============*/
- mem_heap_t* heap, /* in: the heap to be freed */
- const char* file_name, /* in: file name of freeing */
- ulint line) /* in: line where freed */
+ mem_heap_t* heap, /*!< in: the heap to be freed */
+ const char* file_name, /*!< in: file name of freeing */
+ ulint line) /*!< in: line where freed */
{
mem_hash_node_t* node;
ulint cell_no;
@@ -410,7 +417,7 @@ mem_hash_remove(
#endif /* UNIV_MEM_DEBUG */
#if defined UNIV_MEM_DEBUG || defined UNIV_DEBUG
-/*******************************************************************
+/***************************************************************//**
Checks a memory heap for consistency and prints the contents if requested.
Outputs the sum of sizes of buffers given to the user (only in
the debug version), the physical size of the heap and the number of
@@ -420,24 +427,24 @@ UNIV_INTERN
void
mem_heap_validate_or_print(
/*=======================*/
- mem_heap_t* heap, /* in: memory heap */
+ mem_heap_t* heap, /*!< in: memory heap */
byte* top __attribute__((unused)),
- /* in: calculate and validate only until
+ /*!< in: calculate and validate only until
this top pointer in the heap is reached,
if this pointer is NULL, ignored */
- ibool print, /* in: if TRUE, prints the contents
+ ibool print, /*!< in: if TRUE, prints the contents
of the heap; works only in
the debug version */
- ibool* error, /* out: TRUE if error */
- ulint* us_size,/* out: allocated memory
+ ibool* error, /*!< out: TRUE if error */
+ ulint* us_size,/*!< out: allocated memory
(for the user) in the heap,
if a NULL pointer is passed as this
argument, it is ignored; in the
non-debug version this is always -1 */
- ulint* ph_size,/* out: physical size of the heap,
+ ulint* ph_size,/*!< out: physical size of the heap,
if a NULL pointer is passed as this
argument, it is ignored */
- ulint* n_blocks) /* out: number of blocks in the heap,
+ ulint* n_blocks) /*!< out: number of blocks in the heap,
if a NULL pointer is passed as this
argument, it is ignored */
{
@@ -585,13 +592,13 @@ completed:
*error = FALSE;
}
-/******************************************************************
+/**************************************************************//**
Prints the contents of a memory heap. */
static
void
mem_heap_print(
/*===========*/
- mem_heap_t* heap) /* in: memory heap */
+ mem_heap_t* heap) /*!< in: memory heap */
{
ibool error;
ulint us_size;
@@ -610,14 +617,14 @@ mem_heap_print(
ut_a(!error);
}
-/******************************************************************
-Validates the contents of a memory heap. */
+/**************************************************************//**
+Validates the contents of a memory heap.
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_heap_validate(
/*==============*/
- /* out: TRUE if ok */
- mem_heap_t* heap) /* in: memory heap */
+ mem_heap_t* heap) /*!< in: memory heap */
{
ibool error;
ulint us_size;
@@ -639,14 +646,14 @@ mem_heap_validate(
#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
#ifdef UNIV_DEBUG
-/******************************************************************
-Checks that an object is a memory heap (or a block of it). */
+/**************************************************************//**
+Checks that an object is a memory heap (or a block of it).
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_heap_check(
/*===========*/
- /* out: TRUE if ok */
- mem_heap_t* heap) /* in: memory heap */
+ mem_heap_t* heap) /*!< in: memory heap */
{
ut_a(heap->magic_n == MEM_BLOCK_MAGIC_N);
@@ -655,13 +662,13 @@ mem_heap_check(
#endif /* UNIV_DEBUG */
#ifdef UNIV_MEM_DEBUG
-/*********************************************************************
-TRUE if no memory is currently allocated. */
+/*****************************************************************//**
+TRUE if no memory is currently allocated.
+@return TRUE if no heaps exist */
UNIV_INTERN
ibool
mem_all_freed(void)
/*===============*/
- /* out: TRUE if no heaps exist */
{
mem_hash_node_t* node;
ulint heap_count = 0;
@@ -683,8 +690,9 @@ mem_all_freed(void)
mutex_exit(&mem_hash_mutex);
if (heap_count == 0) {
-
+# ifndef UNIV_HOTBACKUP
ut_a(mem_pool_get_reserved(mem_comm_pool) == 0);
+# endif /* !UNIV_HOTBACKUP */
return(TRUE);
} else {
@@ -692,13 +700,13 @@ mem_all_freed(void)
}
}
-/*********************************************************************
-Validates the dynamic memory allocation system. */
+/*****************************************************************//**
+Validates the dynamic memory allocation system.
+@return TRUE if error */
UNIV_INTERN
ibool
mem_validate_no_assert(void)
/*========================*/
- /* out: TRUE if error */
{
mem_hash_node_t* node;
ulint n_heaps = 0;
@@ -709,7 +717,9 @@ mem_validate_no_assert(void)
ulint n_blocks;
ulint i;
+# ifndef UNIV_HOTBACKUP
mem_pool_validate(mem_comm_pool);
+# endif /* !UNIV_HOTBACKUP */
mutex_enter(&mem_hash_mutex);
@@ -765,13 +775,13 @@ mem_validate_no_assert(void)
return(error);
}
-/****************************************************************
-Validates the dynamic memory */
+/************************************************************//**
+Validates the dynamic memory
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_validate(void)
/*==============*/
- /* out: TRUE if ok */
{
ut_a(!mem_validate_no_assert());
@@ -779,14 +789,14 @@ mem_validate(void)
}
#endif /* UNIV_MEM_DEBUG */
-/****************************************************************
+/************************************************************//**
Tries to find neigboring memory allocation blocks and dumps to stderr
the neighborhood of a given pointer. */
UNIV_INTERN
void
mem_analyze_corruption(
/*===================*/
- void* ptr) /* in: pointer to place of possible corruption */
+ void* ptr) /*!< in: pointer to place of possible corruption */
{
byte* p;
ulint i;
@@ -887,14 +897,15 @@ mem_analyze_corruption(
}
}
-/*********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*****************************************************************//**
Prints information of dynamic memory usage and currently allocated
memory heaps or buffers. Can only be used in the debug version. */
static
void
mem_print_info_low(
/*===============*/
- ibool print_all) /* in: if TRUE, all heaps are printed,
+ ibool print_all) /*!< in: if TRUE, all heaps are printed,
else only the heaps allocated after the
previous call of this function */
{
@@ -991,7 +1002,7 @@ next_heap:
#endif
}
-/*********************************************************************
+/*****************************************************************//**
Prints information of dynamic memory usage and currently allocated memory
heaps or buffers. Can only be used in the debug version. */
UNIV_INTERN
@@ -1002,7 +1013,7 @@ mem_print_info(void)
mem_print_info_low(TRUE);
}
-/*********************************************************************
+/*****************************************************************//**
Prints information of dynamic memory usage and currently allocated memory
heaps or buffers since the last ..._print_info or..._print_new_info. */
UNIV_INTERN
@@ -1012,3 +1023,4 @@ mem_print_new_info(void)
{
mem_print_info_low(FALSE);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/mem/mem0mem.c b/storage/xtradb/mem/mem0mem.c
index b7345f5846b..e0dc8716f13 100644
--- a/storage/xtradb/mem/mem0mem.c
+++ b/storage/xtradb/mem/mem0mem.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file mem/mem0mem.c
The memory management
Created 6/9/1994 Heikki Tuuri
@@ -97,64 +98,43 @@ UT_LIST_BASE_NODE_T(mem_block_t) mem_block_list;
#endif
-/**************************************************************************
-Duplicates a NUL-terminated string, allocated from a memory heap. */
+/**********************************************************************//**
+Duplicates a NUL-terminated string, allocated from a memory heap.
+@return own: a copy of the string */
UNIV_INTERN
char*
mem_heap_strdup(
/*============*/
- /* out, own: a copy of the string */
- mem_heap_t* heap, /* in: memory heap where string is allocated */
- const char* str) /* in: string to be copied */
+ mem_heap_t* heap, /*!< in: memory heap where string is allocated */
+ const char* str) /*!< in: string to be copied */
{
return(mem_heap_dup(heap, str, strlen(str) + 1));
}
-/**************************************************************************
-Duplicate a block of data, allocated from a memory heap. */
+/**********************************************************************//**
+Duplicate a block of data, allocated from a memory heap.
+@return own: a copy of the data */
UNIV_INTERN
void*
mem_heap_dup(
/*=========*/
- /* out, own: a copy of the data */
- mem_heap_t* heap, /* in: memory heap where copy is allocated */
- const void* data, /* in: data to be copied */
- ulint len) /* in: length of data, in bytes */
+ mem_heap_t* heap, /*!< in: memory heap where copy is allocated */
+ const void* data, /*!< in: data to be copied */
+ ulint len) /*!< in: length of data, in bytes */
{
return(memcpy(mem_heap_alloc(heap, len), data, len));
}
-/**************************************************************************
-Concatenate two memory blocks and return the result, using a memory heap. */
-UNIV_INTERN
-void*
-mem_heap_cat(
-/*=========*/
- /* out, own: the result */
- mem_heap_t* heap, /* in: memory heap where result is allocated */
- const void* b1, /* in: block 1 */
- ulint len1, /* in: length of b1, in bytes */
- const void* b2, /* in: block 2 */
- ulint len2) /* in: length of b2, in bytes */
-{
- void* res = mem_heap_alloc(heap, len1 + len2);
-
- memcpy(res, b1, len1);
- memcpy((char*)res + len1, b2, len2);
-
- return(res);
-}
-
-/**************************************************************************
-Concatenate two strings and return the result, using a memory heap. */
+/**********************************************************************//**
+Concatenate two strings and return the result, using a memory heap.
+@return own: the result */
UNIV_INTERN
char*
mem_heap_strcat(
/*============*/
- /* out, own: the result */
- mem_heap_t* heap, /* in: memory heap where string is allocated */
- const char* s1, /* in: string 1 */
- const char* s2) /* in: string 2 */
+ mem_heap_t* heap, /*!< in: memory heap where string is allocated */
+ const char* s1, /*!< in: string 1 */
+ const char* s2) /*!< in: string 2 */
{
char* s;
ulint s1_len = strlen(s1);
@@ -171,18 +151,17 @@ mem_heap_strcat(
}
-/********************************************************************
-Helper function for mem_heap_printf. */
+/****************************************************************//**
+Helper function for mem_heap_printf.
+@return length of formatted string, including terminating NUL */
static
ulint
mem_heap_printf_low(
/*================*/
- /* out: length of formatted string,
- including terminating NUL */
- char* buf, /* in/out: buffer to store formatted string
+ char* buf, /*!< in/out: buffer to store formatted string
in, or NULL to just calculate length */
- const char* format, /* in: format string */
- va_list ap) /* in: arguments */
+ const char* format, /*!< in: format string */
+ va_list ap) /*!< in: arguments */
{
ulint len = 0;
@@ -281,18 +260,18 @@ mem_heap_printf_low(
return(len);
}
-/********************************************************************
+/****************************************************************//**
A simple (s)printf replacement that dynamically allocates the space for the
formatted string from the given heap. This supports a very limited set of
the printf syntax: types 's' and 'u' and length modifier 'l' (which is
-required for the 'u' type). */
+required for the 'u' type).
+@return heap-allocated formatted string */
UNIV_INTERN
char*
mem_heap_printf(
/*============*/
- /* out: heap-allocated formatted string */
- mem_heap_t* heap, /* in: memory heap */
- const char* format, /* in: format string */
+ mem_heap_t* heap, /*!< in: memory heap */
+ const char* format, /*!< in: format string */
...)
{
va_list ap;
@@ -314,24 +293,25 @@ mem_heap_printf(
return(str);
}
-/*******************************************************************
-Creates a memory heap block where data can be allocated. */
+/***************************************************************//**
+Creates a memory heap block where data can be allocated.
+@return own: memory heap block, NULL if did not succeed (only possible
+for MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INTERN
mem_block_t*
mem_heap_create_block(
/*==================*/
- /* out, own: memory heap block, NULL if
- did not succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps) */
- mem_heap_t* heap, /* in: memory heap or NULL if first block
+ mem_heap_t* heap, /*!< in: memory heap or NULL if first block
should be created */
- ulint n, /* in: number of bytes needed for user data */
- ulint type, /* in: type of heap: MEM_HEAP_DYNAMIC or
+ ulint n, /*!< in: number of bytes needed for user data */
+ ulint type, /*!< in: type of heap: MEM_HEAP_DYNAMIC or
MEM_HEAP_BUFFER */
- const char* file_name,/* in: file name where created */
- ulint line) /* in: line where created */
+ const char* file_name,/*!< in: file name where created */
+ ulint line) /*!< in: line where created */
{
+#ifndef UNIV_HOTBACKUP
buf_block_t* buf_block = NULL;
+#endif /* !UNIV_HOTBACKUP */
mem_block_t* block;
ulint len;
@@ -345,6 +325,7 @@ mem_heap_create_block(
/* In dynamic allocation, calculate the size: block header + data. */
len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n);
+#ifndef UNIV_HOTBACKUP
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
ut_ad(type == MEM_HEAP_DYNAMIC || n <= MEM_MAX_ALLOC_IN_BUF);
@@ -374,6 +355,13 @@ mem_heap_create_block(
ut_ad(block);
block->buf_block = buf_block;
+ block->free_block = NULL;
+#else /* !UNIV_HOTBACKUP */
+ len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n);
+ block = ut_malloc(len);
+ ut_ad(block);
+#endif /* !UNIV_HOTBACKUP */
+
block->magic_n = MEM_BLOCK_MAGIC_N;
ut_strlcpy_rev(block->file_name, file_name, sizeof(block->file_name));
block->line = line;
@@ -395,24 +383,21 @@ mem_heap_create_block(
mem_block_set_free(block, MEM_BLOCK_HEADER_SIZE);
mem_block_set_start(block, MEM_BLOCK_HEADER_SIZE);
- block->free_block = NULL;
-
ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len);
return(block);
}
-/*******************************************************************
-Adds a new block to a memory heap. */
+/***************************************************************//**
+Adds a new block to a memory heap.
+@return created block, NULL if did not succeed (only possible for
+MEM_HEAP_BTR_SEARCH type heaps) */
UNIV_INTERN
mem_block_t*
mem_heap_add_block(
/*===============*/
- /* out: created block, NULL if did not
- succeed (only possible for
- MEM_HEAP_BTR_SEARCH type heaps)*/
- mem_heap_t* heap, /* in: memory heap */
- ulint n) /* in: number of bytes user needs */
+ mem_heap_t* heap, /*!< in: memory heap */
+ ulint n) /*!< in: number of bytes user needs */
{
mem_block_t* block;
mem_block_t* new_block;
@@ -458,18 +443,20 @@ mem_heap_add_block(
return(new_block);
}
-/**********************************************************************
+/******************************************************************//**
Frees a block from a memory heap. */
UNIV_INTERN
void
mem_heap_block_free(
/*================*/
- mem_heap_t* heap, /* in: heap */
- mem_block_t* block) /* in: block to free */
+ mem_heap_t* heap, /*!< in: heap */
+ mem_block_t* block) /*!< in: block to free */
{
ulint type;
ulint len;
- buf_block_t* buf_block;
+#ifndef UNIV_HOTBACKUP
+ buf_block_t* buf_block = block->buf_block;
+#endif /* !UNIV_HOTBACKUP */
if (block->magic_n != MEM_BLOCK_MAGIC_N) {
mem_analyze_corruption(block);
@@ -486,7 +473,6 @@ mem_heap_block_free(
#endif
type = heap->type;
len = block->len;
- buf_block = block->buf_block;
block->magic_n = MEM_FREED_BLOCK_MAGIC_N;
#ifdef UNIV_MEM_DEBUG
@@ -498,6 +484,7 @@ mem_heap_block_free(
UNIV_MEM_ASSERT_AND_FREE(block, len);
#endif /* UNIV_MEM_DEBUG */
+#ifndef UNIV_HOTBACKUP
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
ut_ad(!buf_block);
@@ -507,15 +494,19 @@ mem_heap_block_free(
buf_block_free(buf_block);
}
+#else /* !UNIV_HOTBACKUP */
+ ut_free(block);
+#endif /* !UNIV_HOTBACKUP */
}
-/**********************************************************************
+#ifndef UNIV_HOTBACKUP
+/******************************************************************//**
Frees the free_block field from a memory heap. */
UNIV_INTERN
void
mem_heap_free_block_free(
/*=====================*/
- mem_heap_t* heap) /* in: heap */
+ mem_heap_t* heap) /*!< in: heap */
{
if (UNIV_LIKELY_NULL(heap->free_block)) {
@@ -524,9 +515,10 @@ mem_heap_free_block_free(
heap->free_block = NULL;
}
}
+#endif /* !UNIV_HOTBACKUP */
#ifdef MEM_PERIODIC_CHECK
-/**********************************************************************
+/******************************************************************//**
Goes through the list of all allocated mem blocks, checks their magic
numbers, and reports possible corruption. */
UNIV_INTERN
diff --git a/storage/xtradb/mem/mem0pool.c b/storage/xtradb/mem/mem0pool.c
index 34de6b2a706..c8fea97a6a3 100644
--- a/storage/xtradb/mem/mem0pool.c
+++ b/storage/xtradb/mem/mem0pool.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file mem/mem0pool.c
The lowest-level memory management
Created 5/12/1997 Heikki Tuuri
@@ -89,28 +90,28 @@ and for the adaptive index. Thus, for each individual transaction, its locks
can occupy at most about the size of the buffer frame of memory in the common
pool, and after that its locks will grow into the buffer pool. */
-/* Mask used to extract the free bit from area->size */
+/** Mask used to extract the free bit from area->size */
#define MEM_AREA_FREE 1
-/* The smallest memory area total size */
+/** The smallest memory area total size */
#define MEM_AREA_MIN_SIZE (2 * MEM_AREA_EXTRA_SIZE)
-/* Data structure for a memory pool. The space is allocated using the buddy
+/** Data structure for a memory pool. The space is allocated using the buddy
algorithm, where free list i contains areas of size 2 to power i. */
struct mem_pool_struct{
- byte* buf; /* memory pool */
- ulint size; /* memory common pool size */
- ulint reserved; /* amount of currently allocated
+ byte* buf; /*!< memory pool */
+ ulint size; /*!< memory common pool size */
+ ulint reserved; /*!< amount of currently allocated
memory */
- mutex_t mutex; /* mutex protecting this struct */
+ mutex_t mutex; /*!< mutex protecting this struct */
UT_LIST_BASE_NODE_T(mem_area_t)
- free_list[64]; /* lists of free memory areas: an
+ free_list[64]; /*!< lists of free memory areas: an
area is put to the list whose number
is the 2-logarithm of the area size */
};
-/* The common memory pool */
+/** The common memory pool */
UNIV_INTERN mem_pool_t* mem_comm_pool = NULL;
/* We use this counter to check that the mem pool mutex does not leak;
@@ -119,7 +120,7 @@ mysql@lists.mysql.com */
UNIV_INTERN ulint mem_n_threads_inside = 0;
-/************************************************************************
+/********************************************************************//**
Reserves the mem pool mutex. */
UNIV_INTERN
void
@@ -129,7 +130,7 @@ mem_pool_mutex_enter(void)
mutex_enter(&(mem_comm_pool->mutex));
}
-/************************************************************************
+/********************************************************************//**
Releases the mem pool mutex. */
UNIV_INTERN
void
@@ -139,39 +140,39 @@ mem_pool_mutex_exit(void)
mutex_exit(&(mem_comm_pool->mutex));
}
-/************************************************************************
-Returns memory area size. */
+/********************************************************************//**
+Returns memory area size.
+@return size */
UNIV_INLINE
ulint
mem_area_get_size(
/*==============*/
- /* out: size */
- mem_area_t* area) /* in: area */
+ mem_area_t* area) /*!< in: area */
{
return(area->size_and_free & ~MEM_AREA_FREE);
}
-/************************************************************************
+/********************************************************************//**
Sets memory area size. */
UNIV_INLINE
void
mem_area_set_size(
/*==============*/
- mem_area_t* area, /* in: area */
- ulint size) /* in: size */
+ mem_area_t* area, /*!< in: area */
+ ulint size) /*!< in: size */
{
area->size_and_free = (area->size_and_free & MEM_AREA_FREE)
| size;
}
-/************************************************************************
-Returns memory area free bit. */
+/********************************************************************//**
+Returns memory area free bit.
+@return TRUE if free */
UNIV_INLINE
ibool
mem_area_get_free(
/*==============*/
- /* out: TRUE if free */
- mem_area_t* area) /* in: area */
+ mem_area_t* area) /*!< in: area */
{
#if TRUE != MEM_AREA_FREE
# error "TRUE != MEM_AREA_FREE"
@@ -179,14 +180,14 @@ mem_area_get_free(
return(area->size_and_free & MEM_AREA_FREE);
}
-/************************************************************************
+/********************************************************************//**
Sets memory area free bit. */
UNIV_INLINE
void
mem_area_set_free(
/*==============*/
- mem_area_t* area, /* in: area */
- ibool free) /* in: free bit value */
+ mem_area_t* area, /*!< in: area */
+ ibool free) /*!< in: free bit value */
{
#if TRUE != MEM_AREA_FREE
# error "TRUE != MEM_AREA_FREE"
@@ -195,14 +196,14 @@ mem_area_set_free(
| free;
}
-/************************************************************************
-Creates a memory pool. */
+/********************************************************************//**
+Creates a memory pool.
+@return memory pool */
UNIV_INTERN
mem_pool_t*
mem_pool_create(
/*============*/
- /* out: memory pool */
- ulint size) /* in: pool size in bytes */
+ ulint size) /*!< in: pool size in bytes */
{
mem_pool_t* pool;
mem_area_t* area;
@@ -259,16 +260,15 @@ mem_pool_create(
return(pool);
}
-/************************************************************************
-Fills the specified free list. */
+/********************************************************************//**
+Fills the specified free list.
+@return TRUE if we were able to insert a block to the free list */
static
ibool
mem_pool_fill_free_list(
/*====================*/
- /* out: TRUE if we were able to insert a
- block to the free list */
- ulint i, /* in: free list index */
- mem_pool_t* pool) /* in: memory pool */
+ ulint i, /*!< in: free list index */
+ mem_pool_t* pool) /*!< in: memory pool */
{
mem_area_t* area;
mem_area_t* area2;
@@ -331,20 +331,20 @@ mem_pool_fill_free_list(
return(TRUE);
}
-/************************************************************************
+/********************************************************************//**
Allocates memory from a pool. NOTE: This low-level function should only be
-used in mem0mem.*! */
+used in mem0mem.*!
+@return own: allocated memory buffer */
UNIV_INTERN
void*
mem_area_alloc(
/*===========*/
- /* out, own: allocated memory buffer */
- ulint* psize, /* in: requested size in bytes; for optimum
+ ulint* psize, /*!< in: requested size in bytes; for optimum
space usage, the size should be a power of 2
minus MEM_AREA_EXTRA_SIZE;
out: allocated size in bytes (greater than
or equal to the requested size) */
- mem_pool_t* pool) /* in: memory pool */
+ mem_pool_t* pool) /*!< in: memory pool */
{
mem_area_t* area;
ulint size;
@@ -435,16 +435,16 @@ mem_area_alloc(
return((void*)(MEM_AREA_EXTRA_SIZE + ((byte*)area)));
}
-/************************************************************************
-Gets the buddy of an area, if it exists in pool. */
+/********************************************************************//**
+Gets the buddy of an area, if it exists in pool.
+@return the buddy, NULL if no buddy in pool */
UNIV_INLINE
mem_area_t*
mem_area_get_buddy(
/*===============*/
- /* out: the buddy, NULL if no buddy in pool */
- mem_area_t* area, /* in: memory area */
- ulint size, /* in: memory area size */
- mem_pool_t* pool) /* in: memory pool */
+ mem_area_t* area, /*!< in: memory area */
+ ulint size, /*!< in: memory area size */
+ mem_pool_t* pool) /*!< in: memory pool */
{
mem_area_t* buddy;
@@ -475,15 +475,15 @@ mem_area_get_buddy(
return(buddy);
}
-/************************************************************************
+/********************************************************************//**
Frees memory to a pool. */
UNIV_INTERN
void
mem_area_free(
/*==========*/
- void* ptr, /* in, own: pointer to allocated memory
+ void* ptr, /*!< in, own: pointer to allocated memory
buffer */
- mem_pool_t* pool) /* in: memory pool */
+ mem_pool_t* pool) /*!< in: memory pool */
{
mem_area_t* area;
mem_area_t* buddy;
@@ -604,14 +604,14 @@ mem_area_free(
ut_ad(mem_pool_validate(pool));
}
-/************************************************************************
-Validates a memory pool. */
+/********************************************************************//**
+Validates a memory pool.
+@return TRUE if ok */
UNIV_INTERN
ibool
mem_pool_validate(
/*==============*/
- /* out: TRUE if ok */
- mem_pool_t* pool) /* in: memory pool */
+ mem_pool_t* pool) /*!< in: memory pool */
{
mem_area_t* area;
mem_area_t* buddy;
@@ -624,7 +624,8 @@ mem_pool_validate(
for (i = 0; i < 64; i++) {
- UT_LIST_VALIDATE(free_list, mem_area_t, pool->free_list[i]);
+ UT_LIST_VALIDATE(free_list, mem_area_t, pool->free_list[i],
+ (void) 0);
area = UT_LIST_GET_FIRST(pool->free_list[i]);
@@ -650,14 +651,14 @@ mem_pool_validate(
return(TRUE);
}
-/************************************************************************
+/********************************************************************//**
Prints info of a memory pool. */
UNIV_INTERN
void
mem_pool_print_info(
/*================*/
- FILE* outfile,/* in: output file to write to */
- mem_pool_t* pool) /* in: memory pool */
+ FILE* outfile,/*!< in: output file to write to */
+ mem_pool_t* pool) /*!< in: memory pool */
{
ulint i;
@@ -683,14 +684,14 @@ mem_pool_print_info(
mutex_exit(&(pool->mutex));
}
-/************************************************************************
-Returns the amount of reserved memory. */
+/********************************************************************//**
+Returns the amount of reserved memory.
+@return reserved memory in bytes */
UNIV_INTERN
ulint
mem_pool_get_reserved(
/*==================*/
- /* out: reserved memory in bytes */
- mem_pool_t* pool) /* in: memory pool */
+ mem_pool_t* pool) /*!< in: memory pool */
{
ulint reserved;
diff --git a/storage/xtradb/mtr/mtr0log.c b/storage/xtradb/mtr/mtr0log.c
index 0fe66d08c05..3f3dab36b76 100644
--- a/storage/xtradb/mtr/mtr0log.c
+++ b/storage/xtradb/mtr/mtr0log.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file mtr/mtr0log.c
Mini-transaction log routines
Created 12/7/1995 Heikki Tuuri
@@ -29,19 +30,22 @@ Created 12/7/1995 Heikki Tuuri
#endif
#include "buf0buf.h"
-#include "dict0boot.h"
+#include "dict0dict.h"
#include "log0recv.h"
#include "page0page.h"
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+# include "dict0boot.h"
+
+/********************************************************//**
Catenates n bytes to the mtr log. */
UNIV_INTERN
void
mlog_catenate_string(
/*=================*/
- mtr_t* mtr, /* in: mtr */
- const byte* str, /* in: string to write */
- ulint len) /* in: string length */
+ mtr_t* mtr, /*!< in: mtr */
+ const byte* str, /*!< in: string to write */
+ ulint len) /*!< in: string length */
{
dyn_array_t* mlog;
@@ -55,7 +59,7 @@ mlog_catenate_string(
dyn_push_string(mlog, str, len);
}
-/************************************************************
+/********************************************************//**
Writes the initial part of a log record consisting of one-byte item
type and four-byte space and page numbers. Also pushes info
to the mtr memo that a buffer page has been modified. */
@@ -63,11 +67,11 @@ UNIV_INTERN
void
mlog_write_initial_log_record(
/*==========================*/
- const byte* ptr, /* in: pointer to (inside) a buffer
+ const byte* ptr, /*!< in: pointer to (inside) a buffer
frame holding the file page where
modification is made */
- byte type, /* in: log item type: MLOG_1BYTE, ... */
- mtr_t* mtr) /* in: mini-transaction handle */
+ byte type, /*!< in: log item type: MLOG_1BYTE, ... */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
byte* log_ptr;
@@ -86,20 +90,20 @@ mlog_write_initial_log_record(
mlog_close(mtr, log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************
-Parses an initial log record written by mlog_write_initial_log_record. */
+/********************************************************//**
+Parses an initial log record written by mlog_write_initial_log_record.
+@return parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_initial_log_record(
/*==========================*/
- /* out: parsed record end, NULL if not a complete
- record */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- byte* type, /* out: log record type: MLOG_1BYTE, ... */
- ulint* space, /* out: space id */
- ulint* page_no)/* out: page number */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ byte* type, /*!< out: log record type: MLOG_1BYTE, ... */
+ ulint* space, /*!< out: space id */
+ ulint* page_no)/*!< out: page number */
{
if (end_ptr < ptr + 1) {
@@ -128,19 +132,18 @@ mlog_parse_initial_log_record(
return(ptr);
}
-/************************************************************
-Parses a log record written by mlog_write_ulint or mlog_write_dulint. */
+/********************************************************//**
+Parses a log record written by mlog_write_ulint or mlog_write_dulint.
+@return parsed record end, NULL if not a complete record or a corrupt record */
UNIV_INTERN
byte*
mlog_parse_nbytes(
/*==============*/
- /* out: parsed record end, NULL if not a complete
- record or a corrupt record */
- ulint type, /* in: log record type: MLOG_1BYTE, ... */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- byte* page, /* in: page where to apply the log record, or NULL */
- void* page_zip)/* in/out: compressed page, or NULL */
+ ulint type, /*!< in: log record type: MLOG_1BYTE, ... */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ byte* page, /*!< in: page where to apply the log record, or NULL */
+ void* page_zip)/*!< in/out: compressed page, or NULL */
{
ulint offset;
ulint val;
@@ -236,17 +239,17 @@ mlog_parse_nbytes(
return(ptr);
}
-/************************************************************
+/********************************************************//**
Writes 1 - 4 bytes to a file page buffered in the buffer pool.
Writes the corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_write_ulint(
/*=============*/
- byte* ptr, /* in: pointer where to write */
- ulint val, /* in: value to write */
- byte type, /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
- mtr_t* mtr) /* in: mini-transaction handle */
+ byte* ptr, /*!< in: pointer where to write */
+ ulint val, /*!< in: value to write */
+ byte type, /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
byte* log_ptr;
@@ -282,16 +285,16 @@ mlog_write_ulint(
mlog_close(mtr, log_ptr);
}
-/************************************************************
+/********************************************************//**
Writes 8 bytes to a file page buffered in the buffer pool.
Writes the corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_write_dulint(
/*==============*/
- byte* ptr, /* in: pointer where to write */
- dulint val, /* in: value to write */
- mtr_t* mtr) /* in: mini-transaction handle */
+ byte* ptr, /*!< in: pointer where to write */
+ dulint val, /*!< in: value to write */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
byte* log_ptr;
@@ -318,17 +321,18 @@ mlog_write_dulint(
mlog_close(mtr, log_ptr);
}
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
Writes a string to a file page buffered in the buffer pool. Writes the
corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_write_string(
/*==============*/
- byte* ptr, /* in: pointer where to write */
- const byte* str, /* in: string to write */
- ulint len, /* in: string length */
- mtr_t* mtr) /* in: mini-transaction handle */
+ byte* ptr, /*!< in: pointer where to write */
+ const byte* str, /*!< in: string to write */
+ ulint len, /*!< in: string length */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ut_ad(ptr && mtr);
ut_a(len < UNIV_PAGE_SIZE);
@@ -338,16 +342,16 @@ mlog_write_string(
mlog_log_string(ptr, len, mtr);
}
-/************************************************************
+/********************************************************//**
Logs a write of a string to a file page buffered in the buffer pool.
Writes the corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
mlog_log_string(
/*============*/
- byte* ptr, /* in: pointer written to */
- ulint len, /* in: string length */
- mtr_t* mtr) /* in: mini-transaction handle */
+ byte* ptr, /*!< in: pointer written to */
+ ulint len, /*!< in: string length */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
byte* log_ptr;
@@ -374,19 +378,19 @@ mlog_log_string(
mlog_catenate_string(mtr, ptr, len);
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************
-Parses a log record written by mlog_write_string. */
+/********************************************************//**
+Parses a log record written by mlog_write_string.
+@return parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_string(
/*==============*/
- /* out: parsed record end, NULL if not a complete
- record */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- byte* page, /* in: page where to apply the log record, or NULL */
- void* page_zip)/* in/out: compressed page, or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ byte* page, /*!< in: page where to apply the log record, or NULL */
+ void* page_zip)/*!< in/out: compressed page, or NULL */
{
ulint offset;
ulint len;
@@ -426,20 +430,20 @@ mlog_parse_string(
return(ptr + len);
}
-/************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************//**
Opens a buffer for mlog, writes the initial log record and,
-if needed, the field lengths of an index. */
+if needed, the field lengths of an index.
+@return buffer, NULL if log mode MTR_LOG_NONE */
UNIV_INTERN
byte*
mlog_open_and_write_index(
/*======================*/
- /* out: buffer, NULL if log mode
- MTR_LOG_NONE */
- mtr_t* mtr, /* in: mtr */
- byte* rec, /* in: index record or page */
- dict_index_t* index, /* in: record descriptor */
- byte type, /* in: log item type */
- ulint size) /* in: requested buffer size in bytes
+ mtr_t* mtr, /*!< in: mtr */
+ const byte* rec, /*!< in: index record or page */
+ dict_index_t* index, /*!< in: record descriptor */
+ byte type, /*!< in: log item type */
+ ulint size) /*!< in: requested buffer size in bytes
(if 0, calls mlog_close() and returns NULL) */
{
byte* log_ptr;
@@ -523,20 +527,19 @@ mlog_open_and_write_index(
}
return(log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************
-Parses a log record written by mlog_open_and_write_index. */
+/********************************************************//**
+Parses a log record written by mlog_open_and_write_index.
+@return parsed record end, NULL if not a complete record */
UNIV_INTERN
byte*
mlog_parse_index(
/*=============*/
- /* out: parsed record end,
- NULL if not a complete record */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- /* out: new value of log_ptr */
- ibool comp, /* in: TRUE=compact record format */
- dict_index_t** index) /* out, own: dummy index */
+ byte* ptr, /*!< in: buffer */
+ const byte* end_ptr,/*!< in: buffer end */
+ ibool comp, /*!< in: TRUE=compact record format */
+ dict_index_t** index) /*!< out, own: dummy index */
{
ulint i, n, n_uniq;
dict_table_t* table;
diff --git a/storage/xtradb/mtr/mtr0mtr.c b/storage/xtradb/mtr/mtr0mtr.c
index 1f811a6eea3..183e575fadd 100644
--- a/storage/xtradb/mtr/mtr0mtr.c
+++ b/storage/xtradb/mtr/mtr0mtr.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file mtr/mtr0mtr.c
Mini-transaction buffer
Created 11/26/1995 Heikki Tuuri
@@ -34,14 +35,15 @@ Created 11/26/1995 Heikki Tuuri
#include "log0log.h"
#include "buf0flu.h"
-/*********************************************************************
+#ifndef UNIV_HOTBACKUP
+/*****************************************************************//**
Releases the item in the slot given. */
UNIV_INLINE
void
mtr_memo_slot_release(
/*==================*/
- mtr_t* mtr, /* in: mtr */
- mtr_memo_slot_t* slot) /* in: memo slot */
+ mtr_t* mtr, /*!< in: mtr */
+ mtr_memo_slot_t* slot) /*!< in: memo slot */
{
void* object;
ulint type;
@@ -70,7 +72,7 @@ mtr_memo_slot_release(
slot->object = NULL;
}
-/**************************************************************
+/**********************************************************//**
Releases the mlocks and other objects stored in an mtr memo. They are released
in the order opposite to which they were pushed to the memo. NOTE! It is
essential that the x-rw-lock on a modified buffer page is not released before
@@ -81,7 +83,7 @@ UNIV_INLINE
void
mtr_memo_pop_all(
/*=============*/
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
@@ -135,13 +137,13 @@ mtr_memo_note_modification_all(
}
}
-/****************************************************************
+/************************************************************//**
Writes the contents of a mini-transaction log, if any, to the database log. */
static
void
mtr_log_reserve_and_write(
/*======================*/
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dyn_array_t* mlog;
dyn_block_t* block;
@@ -193,22 +195,26 @@ mtr_log_reserve_and_write(
mtr->end_lsn = log_close();
}
+#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
Commits a mini-transaction. */
UNIV_INTERN
void
mtr_commit(
/*=======*/
- mtr_t* mtr) /* in: mini-transaction */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
+#ifndef UNIV_HOTBACKUP
ibool write_log;
+#endif /* !UNIV_HOTBACKUP */
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE);
ut_d(mtr->state = MTR_COMMITTING);
+#ifndef UNIV_HOTBACKUP
write_log = mtr->modifications && mtr->n_log_recs;
if (write_log) {
@@ -232,12 +238,15 @@ mtr_commit(
/* All unlocking has been moved here, after log_sys mutex release. */
mtr_memo_pop_all(mtr);
+#endif /* !UNIV_HOTBACKUP */
+
ut_d(mtr->state = MTR_COMMITTED);
dyn_array_free(&(mtr->memo));
dyn_array_free(&(mtr->log));
}
-/**************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
Releases the latches stored in an mtr memo down to a savepoint.
NOTE! The mtr must not have made changes to buffer pages after the
savepoint, as these can be handled only by mtr_commit. */
@@ -245,8 +254,8 @@ UNIV_INTERN
void
mtr_rollback_to_savepoint(
/*======================*/
- mtr_t* mtr, /* in: mtr */
- ulint savepoint) /* in: savepoint */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint savepoint) /*!< in: savepoint */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
@@ -271,15 +280,15 @@ mtr_rollback_to_savepoint(
}
}
-/*******************************************************
+/***************************************************//**
Releases an object in the memo stack. */
UNIV_INTERN
void
mtr_memo_release(
/*=============*/
- mtr_t* mtr, /* in: mtr */
- void* object, /* in: object */
- ulint type) /* in: object type: MTR_MEMO_S_LOCK, ... */
+ mtr_t* mtr, /*!< in: mtr */
+ void* object, /*!< in: object */
+ ulint type) /*!< in: object type: MTR_MEMO_S_LOCK, ... */
{
mtr_memo_slot_t* slot;
dyn_array_t* memo;
@@ -312,18 +321,19 @@ mtr_memo_release(
}
}
}
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************
-Reads 1 - 4 bytes from a file page buffered in the buffer pool. */
+/********************************************************//**
+Reads 1 - 4 bytes from a file page buffered in the buffer pool.
+@return value read */
UNIV_INTERN
ulint
mtr_read_ulint(
/*===========*/
- /* out: value read */
- const byte* ptr, /* in: pointer from where to read */
- ulint type, /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
+ const byte* ptr, /*!< in: pointer from where to read */
+ ulint type, /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
mtr_t* mtr __attribute__((unused)))
- /* in: mini-transaction handle */
+ /*!< in: mini-transaction handle */
{
ut_ad(mtr->state == MTR_ACTIVE);
ut_ad(mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_S_FIX)
@@ -338,16 +348,16 @@ mtr_read_ulint(
}
}
-/************************************************************
-Reads 8 bytes from a file page buffered in the buffer pool. */
+/********************************************************//**
+Reads 8 bytes from a file page buffered in the buffer pool.
+@return value read */
UNIV_INTERN
dulint
mtr_read_dulint(
/*============*/
- /* out: value read */
- const byte* ptr, /* in: pointer from where to read */
+ const byte* ptr, /*!< in: pointer from where to read */
mtr_t* mtr __attribute__((unused)))
- /* in: mini-transaction handle */
+ /*!< in: mini-transaction handle */
{
ut_ad(mtr->state == MTR_ACTIVE);
ut_ad(mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_S_FIX)
@@ -356,27 +366,28 @@ mtr_read_dulint(
}
#ifdef UNIV_DEBUG
-/**************************************************************
-Checks if memo contains the given page. */
+# ifndef UNIV_HOTBACKUP
+/**********************************************************//**
+Checks if memo contains the given page.
+@return TRUE if contains */
UNIV_INTERN
ibool
mtr_memo_contains_page(
/*===================*/
- /* out: TRUE if contains */
- mtr_t* mtr, /* in: mtr */
- const byte* ptr, /* in: pointer to buffer frame */
- ulint type) /* in: type of object */
+ mtr_t* mtr, /*!< in: mtr */
+ const byte* ptr, /*!< in: pointer to buffer frame */
+ ulint type) /*!< in: type of object */
{
return(mtr_memo_contains(mtr, buf_block_align(ptr), type));
}
-/*************************************************************
+/*********************************************************//**
Prints info of an mtr handle. */
UNIV_INTERN
void
mtr_print(
/*======*/
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
fprintf(stderr,
"Mini-transaction handle: memo size %lu bytes"
@@ -384,4 +395,5 @@ mtr_print(
(ulong) dyn_array_get_data_size(&(mtr->memo)),
(ulong) dyn_array_get_data_size(&(mtr->log)));
}
+# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG */
diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c
index efef608b88f..f961ea2adb2 100644
--- a/storage/xtradb/os/os0file.c
+++ b/storage/xtradb/os/os0file.c
@@ -15,37 +15,68 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+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
+
+***********************************************************************/
+
+/**************************************************//**
+@file os/os0file.c
The interface to the operating system file i/o primitives
Created 10/21/1995 Heikki Tuuri
*******************************************************/
#include "os0file.h"
-#include "os0sync.h"
-#include "os0thread.h"
#include "ut0mem.h"
#include "srv0srv.h"
#include "srv0start.h"
#include "fil0fil.h"
#include "buf0buf.h"
-
-#if defined(UNIV_HOTBACKUP) && defined(__WIN__)
+#ifndef UNIV_HOTBACKUP
+# include "os0sync.h"
+# include "os0thread.h"
+#else /* !UNIV_HOTBACKUP */
+# ifdef __WIN__
/* Add includes for the _stat() call to compile on Windows */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#endif /* UNIV_HOTBACKUP */
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <errno.h>
+# endif /* __WIN__ */
+#endif /* !UNIV_HOTBACKUP */
/* This specifies the file permissions InnoDB uses when it creates files in
Unix; the value of os_innodb_umask is initialized in ha_innodb.cc to
my_umask */
#ifndef __WIN__
+/** Umask for creating files */
UNIV_INTERN ulint os_innodb_umask
= S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
#else
+/** Umask for creating files */
UNIV_INTERN ulint os_innodb_umask = 0;
#endif
@@ -57,6 +88,7 @@ UNIV_INTERN ibool os_do_not_call_flush_at_each_write = FALSE;
/* We do not call os_file_flush in every os_file_write. */
#endif /* UNIV_DO_FLUSH */
+#ifndef UNIV_HOTBACKUP
/* We use these mutexes to protect lseek + file i/o operation, if the
OS does not provide an atomic pread or pwrite, or similar */
#define OS_FILE_N_SEEK_MUTEXES 16
@@ -65,12 +97,13 @@ UNIV_INTERN os_mutex_t os_file_seek_mutexes[OS_FILE_N_SEEK_MUTEXES];
/* In simulated aio, merge at most this many consecutive i/os */
#define OS_AIO_MERGE_N_CONSECUTIVE 64
-/* If this flag is TRUE, then we will use the native aio of the
+/** If this flag is TRUE, then we will use the native aio of the
OS (provided we compiled Innobase with it in), otherwise we will
use simulated aio we build below with threads */
UNIV_INTERN ibool os_aio_use_native_aio = FALSE;
+/** Flag: enable debug printout for asynchronous i/o */
UNIV_INTERN ibool os_aio_print_debug = FALSE;
/* State for the state of an IO request in simulated AIO.
@@ -95,74 +128,83 @@ typedef enum {
OS_AIO_CLAIMED /* Result being returned to client. */
} os_aio_status;
-/* The aio array slot structure */
+/** The asynchronous i/o array slot structure */
typedef struct os_aio_slot_struct os_aio_slot_t;
+/** The asynchronous i/o array slot structure */
struct os_aio_slot_struct{
- ibool is_read; /* TRUE if a read operation */
- ulint pos; /* index of the slot in the aio
+ ibool is_read; /*!< TRUE if a read operation */
+ ulint pos; /*!< index of the slot in the aio
array */
- ibool reserved; /* TRUE if this slot is reserved */
+ ibool reserved; /*!< TRUE if this slot is reserved */
os_aio_status status; /* Status for current request. Valid when reserved
is TRUE. Used only in simulated aio. */
- time_t reservation_time;/* time when reserved */
- ulint len; /* length of the block to read or
+ time_t reservation_time;/*!< time when reserved */
+ ulint len; /*!< length of the block to read or
write */
- byte* buf; /* buffer used in i/o */
- ulint type; /* OS_FILE_READ or OS_FILE_WRITE */
- ulint offset; /* 32 low bits of file offset in
+ byte* buf; /*!< buffer used in i/o */
+ ulint type; /*!< OS_FILE_READ or OS_FILE_WRITE */
+ ulint offset; /*!< 32 low bits of file offset in
bytes */
- ulint offset_high; /* 32 high bits of file offset */
- os_file_t file; /* file where to read or write */
- const char* name; /* file name or path */
-// ibool io_already_done;/* used only in simulated aio:
+ ulint offset_high; /*!< 32 high bits of file offset */
+ os_file_t file; /*!< file where to read or write */
+ const char* name; /*!< file name or path */
+// ibool io_already_done;/*!< used only in simulated aio:
// TRUE if the physical i/o already
// made and only the slot message
// needs to be passed to the caller
// of os_aio_simulated_handle */
- fil_node_t* message1; /* message which is given by the */
- void* message2; /* the requester of an aio operation
+ fil_node_t* message1; /*!< message which is given by the */
+ void* message2; /*!< the requester of an aio operation
and which can be used to identify
which pending aio operation was
completed */
#ifdef WIN_ASYNC_IO
- os_event_t event; /* event object we need in the
+ os_event_t event; /*!< event object we need in the
OVERLAPPED struct */
- OVERLAPPED control; /* Windows control block for the
+ OVERLAPPED control; /*!< Windows control block for the
aio request */
#endif
};
-/* The aio array structure */
+/** The asynchronous i/o array structure */
typedef struct os_aio_array_struct os_aio_array_t;
+/** The asynchronous i/o array structure */
struct os_aio_array_struct{
- os_mutex_t mutex; /* the mutex protecting the aio array */
- os_event_t not_full; /* The event which is set to the signaled
- state when there is space in the aio
- outside the ibuf segment */
- os_event_t is_empty; /* The event which is set to the signaled
- state when there are no pending i/os
- in this array */
- ulint n_slots; /* Total number of slots in the aio array.
- This must be divisible by n_threads. */
- ulint n_segments;/* Number of segments in the aio array of
- pending aio requests. A thread can wait
- separately for any one of the segments. */
- ulint n_reserved;/* Number of reserved slots in the
- aio array outside the ibuf segment */
- os_aio_slot_t* slots; /* Pointer to the slots in the array */
+ os_mutex_t mutex; /*!< the mutex protecting the aio array */
+ os_event_t not_full;
+ /*!< The event which is set to the
+ signaled state when there is space in
+ the aio outside the ibuf segment */
+ os_event_t is_empty;
+ /*!< The event which is set to the
+ signaled state when there are no
+ pending i/os in this array */
+ ulint n_slots;/*!< Total number of slots in the aio
+ array. This must be divisible by
+ n_threads. */
+ ulint n_segments;
+ /*!< Number of segments in the aio
+ array of pending aio requests. A
+ thread can wait separately for any one
+ of the segments. */
+ ulint n_reserved;
+ /*!< Number of reserved slots in the
+ aio array outside the ibuf segment */
+ os_aio_slot_t* slots; /*!< Pointer to the slots in the array */
#ifdef __WIN__
os_native_event_t* native_events;
- /* Pointer to an array of OS native event
- handles where we copied the handles from
- slots, in the same order. This can be used
- in WaitForMultipleObjects; used only in
- Windows */
+ /*!< Pointer to an array of OS native
+ event handles where we copied the
+ handles from slots, in the same
+ order. This can be used in
+ WaitForMultipleObjects; used only in
+ Windows */
#endif
};
-/* Array of events used in simulated aio */
+/** Array of events used in simulated aio */
static os_event_t* os_aio_segment_wait_events = NULL;
/* Number for the first global segment for reading. */
@@ -172,13 +214,14 @@ const ulint os_aio_first_read_segment = 2;
2 + os_aio_read_write_threads. */
ulint os_aio_first_write_segment = 0;
-/* The aio arrays for non-ibuf i/o and ibuf i/o, as well as sync aio. These
-are NULL when the module has not yet been initialized. */
-static os_aio_array_t* os_aio_read_array = NULL;
-static os_aio_array_t* os_aio_write_array = NULL;
-static os_aio_array_t* os_aio_ibuf_array = NULL;
-static os_aio_array_t* os_aio_log_array = NULL;
-static os_aio_array_t* os_aio_sync_array = NULL;
+/** The aio arrays for non-ibuf i/o and ibuf i/o, as well as sync aio. These
+are NULL when the module has not yet been initialized. @{ */
+static os_aio_array_t* os_aio_read_array = NULL; /*!< Reads */
+static os_aio_array_t* os_aio_write_array = NULL; /*!< Writes */
+static os_aio_array_t* os_aio_ibuf_array = NULL; /*!< Insert buffer */
+static os_aio_array_t* os_aio_log_array = NULL; /*!< Redo log */
+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
@@ -186,11 +229,13 @@ for each request. */
static char* 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(). */
static ulint os_aio_n_segments = ULINT_UNDEFINED;
-/* If the following is TRUE, read i/o handler threads try to
+/** If the following is TRUE, read i/o handler threads try to
wait until a batch of new read requests have been posted */
static volatile ibool os_aio_recommend_sleep_for_read_threads = FALSE;
+#endif /* !UNIV_HOTBACKUP */
UNIV_INTERN ulint os_n_file_reads = 0;
UNIV_INTERN ulint os_bytes_read_since_printout = 0;
@@ -203,20 +248,26 @@ UNIV_INTERN time_t os_last_printout;
UNIV_INTERN ibool os_has_said_disk_full = FALSE;
-/* The mutex protecting the following counts of pending I/O operations */
+#ifndef UNIV_HOTBACKUP
+/** The mutex protecting the following counts of pending I/O operations */
static os_mutex_t os_file_count_mutex;
+#endif /* !UNIV_HOTBACKUP */
+/** Number of pending os_file_pread() operations */
UNIV_INTERN ulint os_file_n_pending_preads = 0;
+/** Number of pending os_file_pwrite() operations */
UNIV_INTERN ulint os_file_n_pending_pwrites = 0;
+/** Number of pending write operations */
UNIV_INTERN ulint os_n_pending_writes = 0;
+/** Number of pending read operations */
UNIV_INTERN ulint os_n_pending_reads = 0;
-/***************************************************************************
-Gets the operating system version. Currently works only on Windows. */
+/***********************************************************************//**
+Gets the operating system version. Currently works only on Windows.
+@return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000 */
UNIV_INTERN
ulint
os_get_os_version(void)
/*===================*/
- /* out: OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000 */
{
#ifdef __WIN__
OSVERSIONINFO os_info;
@@ -246,18 +297,17 @@ os_get_os_version(void)
#endif
}
-/***************************************************************************
+/***********************************************************************//**
Retrieves the last error number if an error occurs in a file io function.
The number should be retrieved before any other OS calls (because they may
overwrite the error number). If the number is not known to this program,
-the OS error number + 100 is returned. */
+the OS error number + 100 is returned.
+@return error number, or OS error number + 100 */
UNIV_INTERN
ulint
os_file_get_last_error(
/*===================*/
- /* out: error number, or OS error
- number + 100 */
- ibool report_all_errors) /* in: TRUE if we want an error message
+ ibool report_all_errors) /*!< in: TRUE if we want an error message
printed of all errors */
{
ulint err;
@@ -307,7 +357,7 @@ os_file_get_last_error(
"InnoDB: Some operating system error numbers"
" are described at\n"
"InnoDB: "
- "http://dev.mysql.com/doc/refman/5.1/en/"
+ REFMAN
"operating-system-error-codes.html\n");
}
}
@@ -366,7 +416,7 @@ os_file_get_last_error(
"InnoDB: Some operating system"
" error numbers are described at\n"
"InnoDB: "
- "http://dev.mysql.com/doc/refman/5.1/en/"
+ REFMAN
"operating-system-error-codes.html\n");
}
}
@@ -387,19 +437,18 @@ os_file_get_last_error(
#endif
}
-/********************************************************************
+/****************************************************************//**
Does error handling when a file operation fails.
Conditionally exits (calling exit(3)) based on should_exit value and the
-error type */
+error type
+@return TRUE if we should retry the operation */
static
ibool
os_file_handle_error_cond_exit(
/*===========================*/
- /* out: TRUE if we should retry the
- operation */
- const char* name, /* in: name of a file or NULL */
- const char* operation, /* in: operation */
- ibool should_exit) /* in: call exit(3) if unknown error
+ const char* name, /*!< in: name of a file or NULL */
+ const char* operation, /*!< in: operation */
+ ibool should_exit) /*!< in: call exit(3) if unknown error
and this parameter is TRUE */
{
ulint err;
@@ -462,31 +511,29 @@ os_file_handle_error_cond_exit(
return(FALSE);
}
-/********************************************************************
-Does error handling when a file operation fails. */
+/****************************************************************//**
+Does error handling when a file operation fails.
+@return TRUE if we should retry the operation */
static
ibool
os_file_handle_error(
/*=================*/
- /* out: TRUE if we should retry the
- operation */
- const char* name, /* in: name of a file or NULL */
- const char* operation)/* in: operation */
+ const char* name, /*!< in: name of a file or NULL */
+ const char* operation)/*!< in: operation */
{
/* exit in case of unknown error */
return(os_file_handle_error_cond_exit(name, operation, TRUE));
}
-/********************************************************************
-Does error handling when a file operation fails. */
+/****************************************************************//**
+Does error handling when a file operation fails.
+@return TRUE if we should retry the operation */
static
ibool
os_file_handle_error_no_exit(
/*=========================*/
- /* out: TRUE if we should retry the
- operation */
- const char* name, /* in: name of a file or NULL */
- const char* operation)/* in: operation */
+ const char* name, /*!< in: name of a file or NULL */
+ const char* operation)/*!< in: operation */
{
/* don't exit in case of unknown error */
return(os_file_handle_error_cond_exit(name, operation, FALSE));
@@ -501,15 +548,15 @@ os_file_handle_error_no_exit(
# undef USE_FILE_LOCK
#endif
#ifdef USE_FILE_LOCK
-/********************************************************************
-Obtain an exclusive lock on a file. */
+/****************************************************************//**
+Obtain an exclusive lock on a file.
+@return 0 on success */
static
int
os_file_lock(
/*=========*/
- /* out: 0 on success */
- int fd, /* in: file descriptor */
- const char* name) /* in: file name */
+ int fd, /*!< in: file descriptor */
+ const char* name) /*!< in: file name */
{
struct flock lk;
lk.l_type = F_WRLCK;
@@ -534,7 +581,8 @@ os_file_lock(
}
#endif /* USE_FILE_LOCK */
-/********************************************************************
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
Creates the seek mutexes used in positioned reads and writes. */
UNIV_INTERN
void
@@ -550,63 +598,57 @@ os_io_init_simple(void)
}
}
-/***************************************************************************
+/***********************************************************************//**
Creates a temporary file. This function is like tmpfile(3), but
the temporary file is created in the MySQL temporary directory.
On Netware, this function is like tmpfile(3), because the C run-time
-library of Netware does not expose the delete-on-close flag. */
+library of Netware does not expose the delete-on-close flag.
+@return temporary file handle, or NULL on error */
UNIV_INTERN
FILE*
os_file_create_tmpfile(void)
/*========================*/
- /* out: temporary file handle, or NULL on error */
{
-#ifdef UNIV_HOTBACKUP
- ut_error;
-
- return(NULL);
-#else
-# ifdef __NETWARE__
+#ifdef __NETWARE__
FILE* file = tmpfile();
-# else /* __NETWARE__ */
+#else /* __NETWARE__ */
FILE* file = NULL;
int fd = innobase_mysql_tmpfile();
if (fd >= 0) {
file = fdopen(fd, "w+b");
}
-# endif /* __NETWARE__ */
+#endif /* __NETWARE__ */
if (!file) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error: unable to create temporary file;"
" errno: %d\n", errno);
-# ifndef __NETWARE__
+#ifndef __NETWARE__
if (fd >= 0) {
close(fd);
}
-# endif /* !__NETWARE__ */
+#endif /* !__NETWARE__ */
}
return(file);
-#endif /* UNIV_HOTBACKUP */
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************************
+/***********************************************************************//**
The os_file_opendir() function opens a directory stream corresponding to the
directory named by the dirname argument. The directory stream is positioned
at the first entry. In both Unix and Windows we automatically skip the '.'
-and '..' items at the start of the directory listing. */
+and '..' items at the start of the directory listing.
+@return directory stream, NULL if error */
UNIV_INTERN
os_file_dir_t
os_file_opendir(
/*============*/
- /* out: directory stream, NULL if
- error */
- const char* dirname, /* in: directory name; it must not
+ const char* dirname, /*!< in: directory name; it must not
contain a trailing '\' or '/' */
- ibool error_is_fatal) /* in: TRUE if we should treat an
+ ibool error_is_fatal) /*!< in: TRUE if we should treat an
error as a fatal error; if we try to
open symlinks then we do not wish a
fatal error if it happens not to be
@@ -653,14 +695,14 @@ os_file_opendir(
#endif
}
-/***************************************************************************
-Closes a directory stream. */
+/***********************************************************************//**
+Closes a directory stream.
+@return 0 if success, -1 if failure */
UNIV_INTERN
int
os_file_closedir(
/*=============*/
- /* out: 0 if success, -1 if failure */
- os_file_dir_t dir) /* in: directory stream */
+ os_file_dir_t dir) /*!< in: directory stream */
{
#ifdef __WIN__
BOOL ret;
@@ -687,18 +729,17 @@ os_file_closedir(
#endif
}
-/***************************************************************************
+/***********************************************************************//**
This function returns information of the next file in the directory. We jump
-over the '.' and '..' entries in the directory. */
+over the '.' and '..' entries in the directory.
+@return 0 if ok, -1 if error, 1 if at the end of the directory */
UNIV_INTERN
int
os_file_readdir_next_file(
/*======================*/
- /* out: 0 if ok, -1 if error, 1 if at the end
- of the directory */
- const char* dirname,/* in: directory name or path */
- os_file_dir_t dir, /* in: directory stream */
- os_file_stat_t* info) /* in/out: buffer where the info is returned */
+ const char* dirname,/*!< in: directory name or path */
+ os_file_dir_t dir, /*!< in: directory stream */
+ os_file_stat_t* info) /*!< in/out: buffer where the info is returned */
{
#ifdef __WIN__
LPWIN32_FIND_DATA lpFindFileData;
@@ -730,8 +771,7 @@ next_file:
/* TODO: MySQL has apparently its own symlink
implementation in Windows, dbname.sym can
redirect a database directory:
- http://dev.mysql.com/doc/refman/5.1/en/
- windows-symbolic-links.html */
+ REFMAN "windows-symbolic-links.html" */
info->type = OS_FILE_TYPE_LINK;
} else if (lpFindFileData->dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY) {
@@ -839,20 +879,19 @@ next_file:
#endif
}
-/*********************************************************************
+/*****************************************************************//**
This function attempts to create a directory named pathname. The new directory
gets default permissions. On Unix the permissions are (0770 & ~umask). If the
directory exists already, nothing is done and the call succeeds, unless the
-fail_if_exists arguments is true. */
+fail_if_exists arguments is true.
+@return TRUE if call succeeds, FALSE on error */
UNIV_INTERN
ibool
os_file_create_directory(
/*=====================*/
- /* out: TRUE if call succeeds,
- FALSE on error */
- const char* pathname, /* in: directory name as
+ const char* pathname, /*!< in: directory name as
null-terminated string */
- ibool fail_if_exists) /* in: if TRUE, pre-existing directory
+ ibool fail_if_exists) /*!< in: if TRUE, pre-existing directory
is treated as an error. */
{
#ifdef __WIN__
@@ -885,27 +924,26 @@ os_file_create_directory(
#endif
}
-/********************************************************************
-A simple function to open or create a file. */
+/****************************************************************//**
+A simple function to open or create a file.
+@return own: handle to the file, not defined if error, error number
+can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
os_file_create_simple(
/*==================*/
- /* out, own: handle to the file, not defined
- if error, error number can be retrieved with
- os_file_get_last_error */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- ulint create_mode,/* in: OS_FILE_OPEN if an existing file is
+ ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file is
opened (if does not exist, error), or
OS_FILE_CREATE if a new file is created
(if exists, error), or
OS_FILE_CREATE_PATH if new file
(if exists, error) and subdirectories along
its path are created (if needed)*/
- ulint access_type,/* in: OS_FILE_READ_ONLY or
+ ulint access_type,/*!< in: OS_FILE_READ_ONLY or
OS_FILE_READ_WRITE */
- ibool* success)/* out: TRUE if succeed, FALSE if error */
+ ibool* success)/*!< out: TRUE if succeed, FALSE if error */
{
#ifdef __WIN__
os_file_t file;
@@ -951,7 +989,7 @@ try_again:
NULL, /* default security attributes */
create_flag,
attributes,
- NULL); /* no template file */
+ NULL); /*!< no template file */
if (file == INVALID_HANDLE_VALUE) {
*success = FALSE;
@@ -1027,26 +1065,25 @@ try_again:
#endif /* __WIN__ */
}
-/********************************************************************
-A simple function to open or create a file. */
+/****************************************************************//**
+A simple function to open or create a file.
+@return own: handle to the file, not defined if error, error number
+can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
os_file_create_simple_no_error_handling(
/*====================================*/
- /* out, own: handle to the file, not defined
- if error, error number can be retrieved with
- os_file_get_last_error */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- ulint create_mode,/* in: OS_FILE_OPEN if an existing file
+ ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file
is opened (if does not exist, error), or
OS_FILE_CREATE if a new file is created
(if exists, error) */
- ulint access_type,/* in: OS_FILE_READ_ONLY,
+ ulint access_type,/*!< in: OS_FILE_READ_ONLY,
OS_FILE_READ_WRITE, or
OS_FILE_READ_ALLOW_DELETE; the last option is
used by a backup program reading the file */
- ibool* success)/* out: TRUE if succeed, FALSE if error */
+ ibool* success)/*!< out: TRUE if succeed, FALSE if error */
{
#ifdef __WIN__
os_file_t file;
@@ -1073,7 +1110,7 @@ os_file_create_simple_no_error_handling(
} else if (access_type == OS_FILE_READ_ALLOW_DELETE) {
access = GENERIC_READ;
share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ
- | FILE_SHARE_WRITE; /* A backup program has to give
+ | FILE_SHARE_WRITE; /*!< A backup program has to give
mysqld the maximum freedom to
do what it likes with the
file */
@@ -1088,7 +1125,7 @@ os_file_create_simple_no_error_handling(
NULL, /* default security attributes */
create_flag,
attributes,
- NULL); /* no template file */
+ NULL); /*!< no template file */
if (file == INVALID_HANDLE_VALUE) {
*success = FALSE;
@@ -1140,16 +1177,16 @@ os_file_create_simple_no_error_handling(
#endif /* __WIN__ */
}
-/********************************************************************
+/****************************************************************//**
Tries to disable OS caching on an opened file descriptor. */
UNIV_INTERN
void
os_file_set_nocache(
/*================*/
- int fd, /* in: file descriptor to alter */
- const char* file_name, /* in: file name, used in the
+ int fd, /*!< in: file descriptor to alter */
+ const char* file_name, /*!< in: file name, used in the
diagnostic message */
- const char* operation_name) /* in: "open" or "create"; used in the
+ const char* operation_name) /*!< in: "open" or "create"; used in the
diagnostic message */
{
/* some versions of Solaris may not have DIRECTIO_ON */
@@ -1183,18 +1220,17 @@ os_file_set_nocache(
#endif
}
-/********************************************************************
-Opens an existing file or creates a new. */
+/****************************************************************//**
+Opens an existing file or creates a new.
+@return own: handle to the file, not defined if error, error number
+can be retrieved with os_file_get_last_error */
UNIV_INTERN
os_file_t
os_file_create(
/*===========*/
- /* out, own: handle to the file, not defined
- if error, error number can be retrieved with
- os_file_get_last_error */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- ulint create_mode,/* in: OS_FILE_OPEN if an existing file
+ ulint create_mode,/*!< in: OS_FILE_OPEN if an existing file
is opened (if does not exist, error), or
OS_FILE_CREATE if a new file is created
(if exists, error),
@@ -1202,15 +1238,15 @@ os_file_create(
or an old overwritten;
OS_FILE_OPEN_RAW, if a raw device or disk
partition should be opened */
- ulint purpose,/* in: OS_FILE_AIO, if asynchronous,
+ ulint purpose,/*!< in: OS_FILE_AIO, if asynchronous,
non-buffered i/o is desired,
OS_FILE_NORMAL, if any normal file;
NOTE that it also depends on type, os_aio_..
and srv_.. variables whether we really use
async i/o or unbuffered i/o: look in the
function source code for the exact rules */
- ulint type, /* in: OS_DATA_FILE or OS_LOG_FILE */
- ibool* success)/* out: TRUE if succeed, FALSE if error */
+ ulint type, /*!< in: OS_DATA_FILE or OS_LOG_FILE */
+ ibool* success)/*!< out: TRUE if succeed, FALSE if error */
{
#ifdef __WIN__
os_file_t file;
@@ -1289,7 +1325,7 @@ try_again:
NULL, /* default security attributes */
create_flag,
attributes,
- NULL); /* no template file */
+ NULL); /*!< no template file */
if (file == INVALID_HANDLE_VALUE) {
*success = FALSE;
@@ -1442,14 +1478,14 @@ try_again:
#endif /* __WIN__ */
}
-/***************************************************************************
-Deletes a file if it exists. The file has to be closed before calling this. */
+/***********************************************************************//**
+Deletes a file if it exists. The file has to be closed before calling this.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_delete_if_exists(
/*=====================*/
- /* out: TRUE if success */
- const char* name) /* in: file path as a null-terminated string */
+ const char* name) /*!< in: file path as a null-terminated string */
{
#ifdef __WIN__
BOOL ret;
@@ -1504,14 +1540,14 @@ loop:
#endif
}
-/***************************************************************************
-Deletes a file. The file has to be closed before calling this. */
+/***********************************************************************//**
+Deletes a file. The file has to be closed before calling this.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_delete(
/*===========*/
- /* out: TRUE if success */
- const char* name) /* in: file path as a null-terminated string */
+ const char* name) /*!< in: file path as a null-terminated string */
{
#ifdef __WIN__
BOOL ret;
@@ -1567,17 +1603,17 @@ loop:
#endif
}
-/***************************************************************************
+/***********************************************************************//**
Renames a file (can also move it to another directory). It is safest that the
-file is closed before calling this function. */
+file is closed before calling this function.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_rename(
/*===========*/
- /* out: TRUE if success */
- const char* oldpath,/* in: old file path as a null-terminated
+ const char* oldpath,/*!< in: old file path as a null-terminated
string */
- const char* newpath)/* in: new file path */
+ const char* newpath)/*!< in: new file path */
{
#ifdef __WIN__
BOOL ret;
@@ -1606,15 +1642,15 @@ os_file_rename(
#endif
}
-/***************************************************************************
+/***********************************************************************//**
Closes a file handle. In case of error, error number can be retrieved with
-os_file_get_last_error. */
+os_file_get_last_error.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_close(
/*==========*/
- /* out: TRUE if success */
- os_file_t file) /* in, own: handle to a file */
+ os_file_t file) /*!< in, own: handle to a file */
{
#ifdef __WIN__
BOOL ret;
@@ -1645,14 +1681,15 @@ os_file_close(
#endif
}
-/***************************************************************************
-Closes a file handle. */
+#ifdef UNIV_HOTBACKUP
+/***********************************************************************//**
+Closes a file handle.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_close_no_error_handling(
/*============================*/
- /* out: TRUE if success */
- os_file_t file) /* in, own: handle to a file */
+ os_file_t file) /*!< in, own: handle to a file */
{
#ifdef __WIN__
BOOL ret;
@@ -1679,18 +1716,19 @@ os_file_close_no_error_handling(
return(TRUE);
#endif
}
+#endif /* UNIV_HOTBACKUP */
-/***************************************************************************
-Gets a file size. */
+/***********************************************************************//**
+Gets a file size.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_get_size(
/*=============*/
- /* out: TRUE if success */
- os_file_t file, /* in: handle to a file */
- ulint* size, /* out: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ ulint* size, /*!< out: least significant 32 bits of file
size */
- ulint* size_high)/* out: most significant 32 bits of size */
+ ulint* size_high)/*!< out: most significant 32 bits of size */
{
#ifdef __WIN__
DWORD high;
@@ -1728,14 +1766,14 @@ os_file_get_size(
#endif
}
-/***************************************************************************
-Gets file size as a 64-bit integer ib_int64_t. */
+/***********************************************************************//**
+Gets file size as a 64-bit integer ib_int64_t.
+@return size in bytes, -1 if error */
UNIV_INTERN
ib_int64_t
os_file_get_size_as_iblonglong(
/*===========================*/
- /* out: size in bytes, -1 if error */
- os_file_t file) /* in: handle to a file */
+ os_file_t file) /*!< in: handle to a file */
{
ulint size;
ulint size_high;
@@ -1751,19 +1789,19 @@ os_file_get_size_as_iblonglong(
return((((ib_int64_t)size_high) << 32) + (ib_int64_t)size);
}
-/***************************************************************************
-Write the specified number of zeros to a newly created file. */
+/***********************************************************************//**
+Write the specified number of zeros to a newly created file.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_set_size(
/*=============*/
- /* out: TRUE if success */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /* in: handle to a file */
- ulint size, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ ulint size, /*!< in: least significant 32 bits of file
size */
- ulint size_high)/* in: most significant 32 bits of size */
+ ulint size_high)/*!< in: most significant 32 bits of size */
{
ib_int64_t current_size;
ib_int64_t desired_size;
@@ -1840,14 +1878,14 @@ error_handling:
return(FALSE);
}
-/***************************************************************************
-Truncates a file at its current position. */
+/***********************************************************************//**
+Truncates a file at its current position.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_set_eof(
/*============*/
- /* out: TRUE if success */
- FILE* file) /* in: file to be truncated */
+ FILE* file) /*!< in: file to be truncated */
{
#ifdef __WIN__
HANDLE h = (HANDLE) _get_osfhandle(fileno(file));
@@ -1858,17 +1896,17 @@ os_file_set_eof(
}
#ifndef __WIN__
-/***************************************************************************
+/***********************************************************************//**
Wrapper to fsync(2) that retries the call on some errors.
Returns the value 0 if successful; otherwise the value -1 is returned and
-the global variable errno is set to indicate the error. */
+the global variable errno is set to indicate the error.
+@return 0 if success, -1 otherwise */
static
int
os_file_fsync(
/*==========*/
- /* out: 0 if success, -1 otherwise */
- os_file_t file) /* in: handle to a file */
+ os_file_t file) /*!< in: handle to a file */
{
int ret;
int failures;
@@ -1906,14 +1944,14 @@ os_file_fsync(
}
#endif /* !__WIN__ */
-/***************************************************************************
-Flushes the write buffers of a given file to the disk. */
+/***********************************************************************//**
+Flushes the write buffers of a given file to the disk.
+@return TRUE if success */
UNIV_INTERN
ibool
os_file_flush(
/*==========*/
- /* out: TRUE if success */
- os_file_t file) /* in, own: handle to a file */
+ os_file_t file) /*!< in, own: handle to a file */
{
#ifdef __WIN__
BOOL ret;
@@ -2005,19 +2043,19 @@ os_file_flush(
}
#ifndef __WIN__
-/***********************************************************************
-Does a synchronous read operation in Posix. */
+/*******************************************************************//**
+Does a synchronous read operation in Posix.
+@return number of bytes read, -1 if error */
static
ssize_t
os_file_pread(
/*==========*/
- /* out: number of bytes read, -1 if error */
- os_file_t file, /* in: handle to a file */
- void* buf, /* in: buffer where to read */
- ulint n, /* in: number of bytes to read */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ void* buf, /*!< in: buffer where to read */
+ ulint n, /*!< in: number of bytes to read */
+ ulint offset, /*!< in: least significant 32 bits of file
offset from where to read */
- ulint offset_high) /* in: most significant 32 bits of
+ ulint offset_high) /*!< in: most significant 32 bits of
offset */
{
off_t offs;
@@ -2090,19 +2128,19 @@ os_file_pread(
#endif
}
-/***********************************************************************
-Does a synchronous write operation in Posix. */
+/*******************************************************************//**
+Does a synchronous write operation in Posix.
+@return number of bytes written, -1 if error */
static
ssize_t
os_file_pwrite(
/*===========*/
- /* out: number of bytes written, -1 if error */
- os_file_t file, /* in: handle to a file */
- const void* buf, /* in: buffer from where to write */
- ulint n, /* in: number of bytes to write */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ const void* buf, /*!< in: buffer from where to write */
+ ulint n, /*!< in: number of bytes to write */
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to write */
- ulint offset_high) /* in: most significant 32 bits of
+ ulint offset_high) /*!< in: most significant 32 bits of
offset */
{
ssize_t ret;
@@ -2204,21 +2242,20 @@ func_exit:
}
#endif
-/***********************************************************************
-Requests a synchronous positioned read operation. */
+/*******************************************************************//**
+Requests a synchronous positioned read operation.
+@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
ibool
os_file_read(
/*=========*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- os_file_t file, /* in: handle to a file */
- void* buf, /* in: buffer where to read */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ void* buf, /*!< in: buffer where to read */
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to read */
- ulint offset_high, /* in: most significant 32 bits of
+ ulint offset_high, /*!< in: most significant 32 bits of
offset */
- ulint n) /* in: number of bytes to read */
+ ulint n) /*!< in: number of bytes to read */
{
#ifdef __WIN__
BOOL ret;
@@ -2320,22 +2357,21 @@ error_handling:
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Requests a synchronous positioned read operation. This function does not do
-any error handling. In case of error it returns FALSE. */
+any error handling. In case of error it returns FALSE.
+@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
ibool
os_file_read_no_error_handling(
/*===========================*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- os_file_t file, /* in: handle to a file */
- void* buf, /* in: buffer where to read */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ void* buf, /*!< in: buffer where to read */
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to read */
- ulint offset_high, /* in: most significant 32 bits of
+ ulint offset_high, /*!< in: most significant 32 bits of
offset */
- ulint n) /* in: number of bytes to read */
+ ulint n) /*!< in: number of bytes to read */
{
#ifdef __WIN__
BOOL ret;
@@ -2418,7 +2454,7 @@ error_handling:
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Rewind file to its start, read at most size - 1 bytes from it to str, and
NUL-terminate str. All errors are silently ignored. This function is
mostly meant to be used with temporary files. */
@@ -2426,9 +2462,9 @@ UNIV_INTERN
void
os_file_read_string(
/*================*/
- FILE* file, /* in: file to read from */
- char* str, /* in: buffer where to read */
- ulint size) /* in: size of buffer */
+ FILE* file, /*!< in: file to read from */
+ char* str, /*!< in: buffer where to read */
+ ulint size) /*!< in: size of buffer */
{
size_t flen;
@@ -2441,23 +2477,22 @@ os_file_read_string(
str[flen] = '\0';
}
-/***********************************************************************
-Requests a synchronous write operation. */
+/*******************************************************************//**
+Requests a synchronous write operation.
+@return TRUE if request was successful, FALSE if fail */
UNIV_INTERN
ibool
os_file_write(
/*==========*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /* in: handle to a file */
- const void* buf, /* in: buffer from which to write */
- ulint offset, /* in: least significant 32 bits of file
+ os_file_t file, /*!< in: handle to a file */
+ const void* buf, /*!< in: buffer from which to write */
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to write */
- ulint offset_high, /* in: most significant 32 bits of
+ ulint offset_high, /*!< in: most significant 32 bits of
offset */
- ulint n) /* in: number of bytes to write */
+ ulint n) /*!< in: number of bytes to write */
{
#ifdef __WIN__
BOOL ret;
@@ -2509,8 +2544,7 @@ retry:
"InnoDB: Some operating system error numbers"
" are described at\n"
"InnoDB: "
- "http://dev.mysql.com/doc/refman/5.1/en/"
- "operating-system-error-codes.html\n",
+ REFMAN "operating-system-error-codes.html\n",
name, (ulong) offset_high, (ulong) offset,
(ulong) GetLastError());
@@ -2581,8 +2615,7 @@ retry:
"InnoDB: Some operating system error numbers"
" are described at\n"
"InnoDB: "
- "http://dev.mysql.com/doc/refman/5.1/en/"
- "operating-system-error-codes.html\n");
+ REFMAN "operating-system-error-codes.html\n");
os_has_said_disk_full = TRUE;
}
@@ -2624,8 +2657,7 @@ retry:
"InnoDB: Some operating system error numbers"
" are described at\n"
"InnoDB: "
- "http://dev.mysql.com/doc/refman/5.1/en/"
- "operating-system-error-codes.html\n");
+ REFMAN "operating-system-error-codes.html\n");
os_has_said_disk_full = TRUE;
}
@@ -2634,16 +2666,16 @@ retry:
#endif
}
-/***********************************************************************
-Check the existence and type of the given file. */
+/*******************************************************************//**
+Check the existence and type of the given file.
+@return TRUE if call succeeded */
UNIV_INTERN
ibool
os_file_status(
/*===========*/
- /* out: TRUE if call succeeded */
- const char* path, /* in: pathname of the file */
- ibool* exists, /* out: TRUE if file exists */
- os_file_type_t* type) /* out: type of the file (if it exists) */
+ const char* path, /*!< in: pathname of the file */
+ ibool* exists, /*!< out: TRUE if file exists */
+ os_file_type_t* type) /*!< out: type of the file (if it exists) */
{
#ifdef __WIN__
int ret;
@@ -2706,16 +2738,15 @@ os_file_status(
#endif
}
-/***********************************************************************
-This function returns information about the specified file */
+/*******************************************************************//**
+This function returns information about the specified file
+@return TRUE if stat information found */
UNIV_INTERN
ibool
os_file_get_status(
/*===============*/
- /* out: TRUE if stat
- information found */
- const char* path, /* in: pathname of the file */
- os_file_stat_t* stat_info) /* information of a file in a
+ const char* path, /*!< in: pathname of the file */
+ os_file_stat_t* stat_info) /*!< information of a file in a
directory */
{
#ifdef __WIN__
@@ -2792,7 +2823,7 @@ os_file_get_status(
# define OS_FILE_PATH_SEPARATOR '/'
#endif
-/********************************************************************
+/****************************************************************//**
The function os_file_dirname returns a directory component of a
null-terminated pathname string. In the usual case, dirname returns
the string up to, but not including, the final '/', and basename
@@ -2818,14 +2849,13 @@ returned by dirname and basename for different paths:
"/" "/" "/"
"." "." "."
".." "." ".."
-*/
+
+@return own: directory component of the pathname */
UNIV_INTERN
char*
os_file_dirname(
/*============*/
- /* out, own: directory component of the
- pathname */
- const char* path) /* in: pathname */
+ const char* path) /*!< in: pathname */
{
/* Find the offset of the last slash */
const char* last_slash = strrchr(path, OS_FILE_PATH_SEPARATOR);
@@ -2848,15 +2878,14 @@ os_file_dirname(
return(mem_strdupl(path, last_slash - path));
}
-/********************************************************************
-Creates all missing subdirectories along the given path. */
+/****************************************************************//**
+Creates all missing subdirectories along the given path.
+@return TRUE if call succeeded FALSE otherwise */
UNIV_INTERN
ibool
os_file_create_subdirs_if_needed(
/*=============================*/
- /* out: TRUE if call succeeded
- FALSE otherwise */
- const char* path) /* in: path name */
+ const char* path) /*!< in: path name */
{
char* subdir;
ibool success, subdir_exists;
@@ -2889,31 +2918,32 @@ os_file_create_subdirs_if_needed(
return(success);
}
-/********************************************************************
-Returns a pointer to the nth slot in the aio array. */
+#ifndef UNIV_HOTBACKUP
+/****************************************************************//**
+Returns a pointer to the nth slot in the aio array.
+@return pointer to slot */
static
os_aio_slot_t*
os_aio_array_get_nth_slot(
/*======================*/
- /* out: pointer to slot */
- os_aio_array_t* array, /* in: aio array */
- ulint index) /* in: index of the slot */
+ os_aio_array_t* array, /*!< in: aio array */
+ ulint index) /*!< in: index of the slot */
{
ut_a(index < array->n_slots);
return((array->slots) + index);
}
-/****************************************************************************
-Creates an aio wait array. */
+/************************************************************************//**
+Creates an aio wait array.
+@return own: aio array */
static
os_aio_array_t*
os_aio_array_create(
/*================*/
- /* out, own: aio array */
- ulint n, /* in: maximum number of pending aio operations
+ ulint n, /*!< in: maximum number of pending aio operations
allowed; n must be divisible by n_segments */
- ulint n_segments) /* in: number of segments in the aio array */
+ ulint n_segments) /*!< in: number of segments in the aio array */
{
os_aio_array_t* array;
ulint i;
@@ -2958,35 +2988,27 @@ os_aio_array_create(
return(array);
}
-/****************************************************************************
-Initializes the asynchronous io system. Calls also os_io_init_simple.
-Creates a separate aio array for
-non-ibuf read and write, a third aio array for the ibuf i/o, with just one
-segment, two aio arrays for log reads and writes with one segment, and a
-synchronous aio array of the specified size. The combined number of segments
-in the three first aio arrays is the parameter n_segments given to the
-function. The caller must create an i/o handler thread for each segment in
-the four first arrays, but not for the sync aio array. */
+/***********************************************************************
+Initializes the asynchronous io system. Creates one array each for ibuf
+and log i/o. Also creates one array each for read and write where each
+array is divided logically into n_read_segs and n_write_segs
+respectively. The caller must create an i/o handler thread for each
+segment in these arrays. This function also creates the sync array.
+No i/o handler thread needs to be created for that */
UNIV_INTERN
void
os_aio_init(
/*========*/
- ulint n, /* in: maximum number of pending aio operations
- allowed; n must be divisible by n_segments */
-// ulint n_segments, /* in: combined number of segments in the four
-// first aio arrays; must be >= 4 */
- ulint n_read_threads, /* n_segments == 2 + n_read_threads + n_write_threads*/
- ulint n_write_threads, /**/
- ulint n_slots_sync) /* in: number of slots in the sync aio array */
+ ulint n_per_seg, /*<! in: maximum number of pending aio
+ operations allowed per segment */
+ ulint n_read_segs, /*<! in: number of reader threads */
+ ulint n_write_segs, /*<! in: number of writer threads */
+ ulint n_slots_sync) /*<! in: number of slots in the sync aio
+ array */
{
- ulint n_read_segs;
- ulint n_write_segs;
- ulint n_per_seg;
ulint i;
+ ulint n_segments = 2 + n_read_segs + n_write_segs;
- ulint n_segments = 2 + n_read_threads + n_write_threads;
-
- ut_ad(n % n_segments == 0);
ut_ad(n_segments >= 4);
os_io_init_simple();
@@ -2997,13 +3019,10 @@ os_aio_init(
os_aio_thread_buffer_size[i] = 0;
}
- n_per_seg = n / n_segments;
- n_write_segs = n_write_threads;
- n_read_segs = n_read_threads;
/* fprintf(stderr, "Array n per seg %lu\n", n_per_seg); */
- os_aio_first_write_segment = os_aio_first_read_segment + n_read_threads;
+ os_aio_first_write_segment = os_aio_first_read_segment + n_read_segs;
os_aio_ibuf_array = os_aio_array_create(n_per_seg, 1);
srv_io_thread_function[0] = "insert buffer thread";
@@ -3043,14 +3062,14 @@ os_aio_init(
}
#ifdef WIN_ASYNC_IO
-/****************************************************************************
+/************************************************************************//**
Wakes up all async i/o threads in the array in Windows async i/o at
shutdown. */
static
void
os_aio_array_wake_win_aio_at_shutdown(
/*==================================*/
- os_aio_array_t* array) /* in: aio array */
+ os_aio_array_t* array) /*!< in: aio array */
{
ulint i;
@@ -3061,7 +3080,7 @@ os_aio_array_wake_win_aio_at_shutdown(
}
#endif
-/****************************************************************************
+/************************************************************************//**
Wakes up all async i/o threads so that they know to exit themselves in
shutdown. */
UNIV_INTERN
@@ -3086,7 +3105,7 @@ os_aio_wake_all_threads_at_shutdown(void)
}
}
-/****************************************************************************
+/************************************************************************//**
Waits until there are no pending writes in os_aio_write_array. There can
be other, synchronous, pending writes. */
UNIV_INTERN
@@ -3097,16 +3116,16 @@ os_aio_wait_until_no_pending_writes(void)
os_event_wait(os_aio_write_array->is_empty);
}
-/**************************************************************************
-Calculates segment number for a slot. */
+/**********************************************************************//**
+Calculates segment number for a slot.
+@return segment number (which is the number used by, for example,
+i/o-handler threads) */
static
ulint
os_aio_get_segment_no_from_slot(
/*============================*/
- /* out: segment number (which is the number
- used by, for example, i/o-handler threads) */
- os_aio_array_t* array, /* in: aio wait array */
- os_aio_slot_t* slot) /* in: slot in this array */
+ os_aio_array_t* array, /*!< in: aio wait array */
+ os_aio_slot_t* slot) /*!< in: slot in this array */
{
ulint segment;
ulint seg_len;
@@ -3134,16 +3153,15 @@ os_aio_get_segment_no_from_slot(
return(segment);
}
-/**************************************************************************
-Calculates local segment number and aio array from global segment number. */
+/**********************************************************************//**
+Calculates local segment number and aio array from global segment number.
+@return local segment number within the aio array */
static
ulint
os_aio_get_array_and_local_segment(
/*===============================*/
- /* out: local segment number within
- the aio array */
- os_aio_array_t** array, /* out: aio wait array */
- ulint global_segment)/* in: global segment number */
+ os_aio_array_t** array, /*!< out: aio wait array */
+ ulint global_segment)/*!< in: global segment number */
{
ulint segment;
@@ -3170,42 +3188,47 @@ os_aio_get_array_and_local_segment(
return(segment);
}
-/***********************************************************************
+/*******************************************************************//**
Requests for a slot in the aio array. If no slot is available, waits until
-not_full-event becomes signaled. */
+not_full-event becomes signaled.
+@return pointer to slot */
static
os_aio_slot_t*
os_aio_array_reserve_slot(
/*======================*/
- /* out: pointer to slot */
- ulint type, /* in: OS_FILE_READ or OS_FILE_WRITE */
- os_aio_array_t* array, /* in: aio array */
- fil_node_t* message1,/* in: message to be passed along with
+ ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE */
+ os_aio_array_t* array, /*!< in: aio array */
+ fil_node_t* message1,/*!< in: message to be passed along with
the aio operation */
- void* message2,/* in: message to be passed along with
+ void* message2,/*!< in: message to be passed along with
the aio operation */
- os_file_t file, /* in: file handle */
- const char* name, /* in: name of the file or path as a
+ os_file_t file, /*!< in: file handle */
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- void* buf, /* in: buffer where to read or from which
+ void* buf, /*!< in: buffer where to read or from which
to write */
- ulint offset, /* in: least significant 32 bits of file
+ ulint offset, /*!< in: least significant 32 bits of file
offset */
- ulint offset_high, /* in: most significant 32 bits of
+ ulint offset_high, /*!< in: most significant 32 bits of
offset */
- ulint len) /* in: length of the block to read or write */
+ ulint len) /*!< in: length of the block to read or write */
{
os_aio_slot_t* slot;
#ifdef WIN_ASYNC_IO
OVERLAPPED* control;
#endif
ulint i;
- ulint prim_segment;
- ulint n;
+ ulint slots_per_seg;
+ ulint local_seg;
- n = array->n_slots / array->n_segments;
- /* 64 blocks' striping ( aligning max(BUF_READ_AHEAD_AREA) ) */
- prim_segment = ( offset >> (UNIV_PAGE_SIZE_SHIFT + 6) ) % (array->n_segments);
+ /* No need of a mutex. Only reading constant fields */
+ slots_per_seg = array->n_slots / array->n_segments;
+
+ /* We attempt to keep adjacent blocks in the same local
+ segment. This can help in merging IO requests when we are
+ doing simulated AIO */
+ local_seg = (offset >> (UNIV_PAGE_SIZE_SHIFT + 6))
+ % array->n_segments;
loop:
os_mutex_enter(array->mutex);
@@ -3225,25 +3248,26 @@ loop:
goto loop;
}
- for (i = prim_segment * n; i < array->n_slots; i++) {
+ /* First try to find a slot in the preferred local segment */
+ for (i = local_seg * slots_per_seg; i < array->n_slots; i++) {
slot = os_aio_array_get_nth_slot(array, i);
if (slot->reserved == FALSE) {
- break;
+ goto found;
}
}
- if (slot->reserved == TRUE){
- /* Not found after the intended segment. So we should search before. */
+ /* Fall back to a full scan. We are guaranteed to find a slot */
for (i = 0;; i++) {
slot = os_aio_array_get_nth_slot(array, i);
if (slot->reserved == FALSE) {
- break;
+ goto found;
}
}
- }
+found:
+ ut_a(slot->reserved == FALSE);
array->n_reserved++;
if (array->n_reserved == 1) {
@@ -3280,14 +3304,14 @@ loop:
return(slot);
}
-/***********************************************************************
+/*******************************************************************//**
Frees a slot in the aio array. */
static
void
os_aio_array_free_slot(
/*===================*/
- os_aio_array_t* array, /* in: aio array */
- os_aio_slot_t* slot) /* in: pointer to slot */
+ os_aio_array_t* array, /*!< in: aio array */
+ os_aio_slot_t* slot) /*!< in: pointer to slot */
{
ut_ad(array);
ut_ad(slot);
@@ -3315,13 +3339,13 @@ os_aio_array_free_slot(
os_mutex_exit(array->mutex);
}
-/**************************************************************************
+/**********************************************************************//**
Wakes up a simulated aio i/o-handler thread if it has something to do. */
static
void
os_aio_simulated_wake_handler_thread(
/*=================================*/
- ulint global_segment) /* in: the number of the segment in the aio
+ ulint global_segment) /*!< in: the number of the segment in the aio
arrays */
{
os_aio_array_t* array;
@@ -3377,7 +3401,7 @@ os_aio_simulated_wake_handler_thread(
}
}
-/**************************************************************************
+/**********************************************************************//**
Wakes up simulated aio i/o-handler threads if they have something to do. */
UNIV_INTERN
void
@@ -3398,7 +3422,7 @@ os_aio_simulated_wake_handler_threads(void)
os_aio_simulated_wake_handler_thread(os_aio_first_write_segment);
}
-/**************************************************************************
+/**********************************************************************//**
This function can be called if one wants to post a batch of reads and
prefers an i/o-handler thread to handle them all at once later. You must
call os_aio_simulated_wake_handler_threads later to ensure the threads
@@ -3423,16 +3447,15 @@ os_aio_simulated_put_read_threads_to_sleep(void)
}
}
-/***********************************************************************
-Requests an asynchronous i/o operation. */
+/*******************************************************************//**
+Requests an asynchronous i/o operation.
+@return TRUE if request was queued successfully, FALSE if fail */
UNIV_INTERN
ibool
os_aio(
/*===*/
- /* out: TRUE if request was queued
- successfully, FALSE if fail */
- ulint type, /* in: OS_FILE_READ or OS_FILE_WRITE */
- ulint mode, /* in: OS_AIO_NORMAL, ..., possibly ORed
+ ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE */
+ ulint mode, /*!< in: OS_AIO_NORMAL, ..., possibly ORed
to OS_AIO_SIMULATED_WAKE_LATER: the
last flag advises this function not to wake
i/o-handler threads, but the caller will
@@ -3445,21 +3468,24 @@ os_aio(
because i/os are not actually handled until
all have been posted: use with great
caution! */
- const char* name, /* in: name of the file or path as a
+ const char* name, /*!< in: name of the file or path as a
null-terminated string */
- os_file_t file, /* in: handle to a file */
- void* buf, /* in: buffer where to read or from which
+ os_file_t file, /*!< in: handle to a file */
+ void* buf, /*!< in: buffer where to read or from which
to write */
- ulint offset, /* in: least significant 32 bits of file
+ ulint offset, /*!< in: least significant 32 bits of file
offset where to read or write */
- ulint offset_high, /* in: most significant 32 bits of
+ ulint offset_high, /*!< in: most significant 32 bits of
offset */
- ulint n, /* in: number of bytes to read or write */
- fil_node_t* message1,/* in: messages for the aio handler (these
- can be used to identify a completed aio
- operation); if mode is OS_AIO_SYNC, these
- are ignored */
- void* message2)
+ ulint n, /*!< in: number of bytes to read or write */
+ fil_node_t* message1,/*!< in: message for the aio handler
+ (can be used to identify a completed
+ aio operation); ignored if mode is
+ OS_AIO_SYNC */
+ void* message2)/*!< in: message for the aio handler
+ (can be used to identify a completed
+ aio operation); ignored if mode is
+ OS_AIO_SYNC */
{
os_aio_array_t* array;
os_aio_slot_t* slot;
@@ -3615,19 +3641,19 @@ try_again:
}
#ifdef WIN_ASYNC_IO
-/**************************************************************************
+/**********************************************************************//**
This function is only used in Windows asynchronous i/o.
Waits for an aio operation to complete. This function is used to wait the
for completed requests. The aio array of pending requests is divided
into segments. The thread specifies which segment or slot it wants to wait
for. NOTE: this function will also take care of freeing the aio slot,
-therefore no other thread is allowed to do the freeing! */
+therefore no other thread is allowed to do the freeing!
+@return TRUE if the aio operation succeeded */
UNIV_INTERN
ibool
os_aio_windows_handle(
/*==================*/
- /* out: TRUE if the aio operation succeeded */
- ulint segment, /* in: the number of the segment in the aio
+ ulint segment, /*!< in: the number of the segment in the aio
arrays to wait for; segment 0 is the ibuf
i/o thread, segment 1 the log i/o thread,
then follow the non-ibuf read threads, and as
@@ -3635,15 +3661,15 @@ os_aio_windows_handle(
this is ULINT_UNDEFINED, then it means that
sync aio is used, and this parameter is
ignored */
- ulint pos, /* this parameter is used only in sync aio:
+ ulint pos, /*!< this parameter is used only in sync aio:
wait for the aio slot at this position */
- fil_node_t**message1, /* out: the messages passed with the aio
+ fil_node_t**message1, /*!< out: the messages passed with the aio
request; note that also in the case where
the aio operation failed, these output
parameters are valid and can be used to
restart the operation, for example */
void** message2,
- ulint* type) /* out: OS_FILE_WRITE or ..._READ */
+ ulint* type) /*!< out: OS_FILE_WRITE or ..._READ */
{
ulint orig_seg = segment;
os_aio_array_t* array;
@@ -3720,26 +3746,26 @@ os_aio_windows_handle(
}
#endif
-/**************************************************************************
+/**********************************************************************//**
Does simulated aio. This function should be called by an i/o-handler
-thread. */
+thread.
+@return TRUE if the aio operation succeeded */
UNIV_INTERN
ibool
os_aio_simulated_handle(
/*====================*/
- /* out: TRUE if the aio operation succeeded */
- ulint global_segment, /* in: the number of the segment in the aio
+ ulint global_segment, /*!< in: the number of the segment in the aio
arrays to wait for; segment 0 is the ibuf
i/o thread, segment 1 the log i/o thread,
then follow the non-ibuf read threads, and as
the last are the non-ibuf write threads */
- fil_node_t**message1, /* out: the messages passed with the aio
+ fil_node_t**message1, /*!< out: the messages passed with the aio
request; note that also in the case where
the aio operation failed, these output
parameters are valid and can be used to
restart the operation, for example */
void** message2,
- ulint* type) /* out: OS_FILE_WRITE or ..._READ */
+ ulint* type) /*!< out: OS_FILE_WRITE or ..._READ */
{
os_aio_array_t* array;
ulint segment;
@@ -3760,7 +3786,7 @@ os_aio_simulated_handle(
ibool ret;
ulint n;
ulint i;
- time_t now;
+ time_t now;
segment = os_aio_get_array_and_local_segment(&array, global_segment);
@@ -4047,14 +4073,14 @@ recommended_sleep:
goto restart;
}
-/**************************************************************************
-Validates the consistency of an aio array. */
+/**********************************************************************//**
+Validates the consistency of an aio array.
+@return TRUE if ok */
static
ibool
os_aio_array_validate(
/*==================*/
- /* out: TRUE if ok */
- os_aio_array_t* array) /* in: aio wait array */
+ os_aio_array_t* array) /*!< in: aio wait array */
{
os_aio_slot_t* slot;
ulint n_reserved = 0;
@@ -4083,13 +4109,13 @@ os_aio_array_validate(
return(TRUE);
}
-/**************************************************************************
-Validates the consistency the aio system. */
+/**********************************************************************//**
+Validates the consistency the aio system.
+@return TRUE if ok */
UNIV_INTERN
ibool
os_aio_validate(void)
/*=================*/
- /* out: TRUE if ok */
{
os_aio_array_validate(os_aio_read_array);
os_aio_array_validate(os_aio_write_array);
@@ -4100,13 +4126,13 @@ os_aio_validate(void)
return(TRUE);
}
-/**************************************************************************
+/**********************************************************************//**
Prints info of the aio arrays. */
UNIV_INTERN
void
os_aio_print(
/*=========*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
os_aio_array_t* array;
os_aio_slot_t* slot;
@@ -4237,7 +4263,7 @@ loop:
os_last_printout = current_time;
}
-/**************************************************************************
+/**********************************************************************//**
Refreshes the statistics used to print per-second averages. */
UNIV_INTERN
void
@@ -4253,14 +4279,14 @@ os_aio_refresh_stats(void)
}
#ifdef UNIV_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Checks that all slots in the system have been freed, that is, there are
-no pending io operations. */
+no pending io operations.
+@return TRUE if all free */
UNIV_INTERN
ibool
os_aio_all_slots_free(void)
/*=======================*/
- /* out: TRUE if all free */
{
os_aio_array_t* array;
ulint n_res = 0;
@@ -4313,3 +4339,5 @@ os_aio_all_slots_free(void)
return(FALSE);
}
#endif /* UNIV_DEBUG */
+
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/os/os0proc.c b/storage/xtradb/os/os0proc.c
index 8d4a71f8c4e..a0ea9a1b258 100644
--- a/storage/xtradb/os/os0proc.c
+++ b/storage/xtradb/os/os0proc.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file os/os0proc.c
The interface to the operating system
process control primitives
@@ -43,11 +44,12 @@ UNIV_INTERN ibool os_use_large_pages;
/* Large page size. This may be a boot-time option on some platforms */
UNIV_INTERN ulint os_large_page_size;
-/********************************************************************
+/****************************************************************//**
Converts the current process id to a number. It is not guaranteed that the
number is unique. In Linux returns the 'process number' of the current
thread. That number is the same as one sees in 'top', for example. In Linux
-the thread id is not the same as one sees in 'top'. */
+the thread id is not the same as one sees in 'top'.
+@return process id as a number */
UNIV_INTERN
ulint
os_proc_get_number(void)
@@ -60,14 +62,14 @@ os_proc_get_number(void)
#endif
}
-/********************************************************************
-Allocates large pages memory. */
+/****************************************************************//**
+Allocates large pages memory.
+@return allocated memory */
UNIV_INTERN
void*
os_mem_alloc_large(
/*===============*/
- /* out: allocated memory */
- ulint* n) /* in/out: number of bytes */
+ ulint* n) /*!< in/out: number of bytes */
{
void* ptr;
ulint size;
@@ -171,15 +173,15 @@ skip:
return(ptr);
}
-/********************************************************************
+/****************************************************************//**
Frees large pages memory. */
UNIV_INTERN
void
os_mem_free_large(
/*==============*/
- void *ptr, /* in: pointer returned by
+ void *ptr, /*!< in: pointer returned by
os_mem_alloc_large() */
- ulint size) /* in: size returned by
+ ulint size) /*!< in: size returned by
os_mem_alloc_large() */
{
os_fast_mutex_lock(&ut_list_mutex);
@@ -226,37 +228,3 @@ os_mem_free_large(
}
#endif
}
-
-/********************************************************************
-Sets the priority boost for threads released from waiting within the current
-process. */
-UNIV_INTERN
-void
-os_process_set_priority_boost(
-/*==========================*/
- ibool do_boost) /* in: TRUE if priority boost should be done,
- FALSE if not */
-{
-#ifdef __WIN__
- ibool no_boost;
-
- if (do_boost) {
- no_boost = FALSE;
- } else {
- no_boost = TRUE;
- }
-
-#if TRUE != 1
-# error "TRUE != 1"
-#endif
-
- /* Does not do anything currently!
- SetProcessPriorityBoost(GetCurrentProcess(), no_boost);
- */
- fputs("Warning: process priority boost setting"
- " currently not functional!\n",
- stderr);
-#else
- UT_NOT_USED(do_boost);
-#endif
-}
diff --git a/storage/xtradb/os/os0sync.c b/storage/xtradb/os/os0sync.c
index 78ff74059f8..4ec340b72b5 100644
--- a/storage/xtradb/os/os0sync.c
+++ b/storage/xtradb/os/os0sync.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file os/os0sync.c
The interface to the operating system
synchronization primitives.
@@ -37,9 +38,9 @@ Created 9/6/1995 Heikki Tuuri
/* Type definition for an operating system mutex struct */
struct os_mutex_struct{
- os_event_t event; /* Used by sync0arr.c for queing threads */
- void* handle; /* OS handle to mutex */
- ulint count; /* we use this counter to check
+ os_event_t event; /*!< Used by sync0arr.c for queing threads */
+ void* handle; /*!< OS handle to mutex */
+ ulint count; /*!< we use this counter to check
that the same thread does not
recursively lock the mutex: we
do not assume that the OS mutex
@@ -49,19 +50,21 @@ struct os_mutex_struct{
/* list of all 'slow' OS mutexes created */
};
-/* Mutex protecting counts and the lists of OS mutexes and events */
+/** Mutex protecting counts and the lists of OS mutexes and events */
UNIV_INTERN os_mutex_t os_sync_mutex;
+/** TRUE if os_sync_mutex has been initialized */
static ibool os_sync_mutex_inited = FALSE;
+/** TRUE when os_sync_free() is being executed */
static ibool os_sync_free_called = FALSE;
-/* This is incremented by 1 in os_thread_create and decremented by 1 in
+/** This is incremented by 1 in os_thread_create and decremented by 1 in
os_thread_exit */
UNIV_INTERN ulint os_thread_count = 0;
-/* The list of all events created */
+/** The list of all events created */
static UT_LIST_BASE_NODE_T(os_event_struct_t) os_event_list;
-/* The list of all OS 'slow' mutexes */
+/** The list of all OS 'slow' mutexes */
static UT_LIST_BASE_NODE_T(os_mutex_str_t) os_mutex_list;
UNIV_INTERN ulint os_event_count = 0;
@@ -73,7 +76,7 @@ event embedded inside a mutex, on free, this generates a recursive call.
This version of the free event function doesn't acquire the global lock */
static void os_event_free_internal(os_event_t event);
-/*************************************************************
+/*********************************************************//**
Initializes global event and OS 'slow' mutex lists. */
UNIV_INTERN
void
@@ -88,7 +91,7 @@ os_sync_init(void)
os_sync_mutex_inited = TRUE;
}
-/*************************************************************
+/*********************************************************//**
Frees created events and OS 'slow' mutexes. */
UNIV_INTERN
void
@@ -125,16 +128,16 @@ os_sync_free(void)
os_sync_free_called = FALSE;
}
-/*************************************************************
+/*********************************************************//**
Creates an event semaphore, i.e., a semaphore which may just have two
states: signaled and nonsignaled. The created event is manual reset: it
-must be reset explicitly by calling sync_os_reset_event. */
+must be reset explicitly by calling sync_os_reset_event.
+@return the event handle */
UNIV_INTERN
os_event_t
os_event_create(
/*============*/
- /* out: the event handle */
- const char* name) /* in: the name of the event, if NULL
+ const char* name) /*!< in: the name of the event, if NULL
the event is created without a name */
{
#ifdef __WIN__
@@ -161,12 +164,8 @@ os_event_create(
os_fast_mutex_init(&(event->os_mutex));
-#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
- ut_a(0 == pthread_cond_init(&(event->cond_var),
- pthread_condattr_default));
-#else
ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));
-#endif
+
event->is_set = FALSE;
/* We return this value in os_event_reset(), which can then be
@@ -197,55 +196,14 @@ os_event_create(
return(event);
}
-#ifdef __WIN__
-/*************************************************************
-Creates an auto-reset event semaphore, i.e., an event which is automatically
-reset when a single thread is released. Works only in Windows. */
-UNIV_INTERN
-os_event_t
-os_event_create_auto(
-/*=================*/
- /* out: the event handle */
- const char* name) /* in: the name of the event, if NULL
- the event is created without a name */
-{
- os_event_t event;
-
- event = ut_malloc(sizeof(struct os_event_struct));
-
- event->handle = CreateEvent(NULL, /* No security attributes */
- FALSE, /* Auto-reset */
- FALSE, /* Initial state nonsignaled */
- (LPCTSTR) name);
-
- if (!event->handle) {
- fprintf(stderr,
- "InnoDB: Could not create a Windows auto"
- " event semaphore; Windows error %lu\n",
- (ulong) GetLastError());
- }
-
- /* Put to the list of events */
- os_mutex_enter(os_sync_mutex);
-
- UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);
-
- os_event_count++;
-
- os_mutex_exit(os_sync_mutex);
-
- return(event);
-}
-#endif
-
-/**************************************************************
+/**********************************************************//**
Sets an event semaphore to the signaled state: lets waiting threads
proceed. */
UNIV_INTERN
void
os_event_set(
/*=========*/
- os_event_t event) /* in: event to set */
+ os_event_t event) /*!< in: event to set */
{
#ifdef __WIN__
ut_a(event);
@@ -267,19 +225,19 @@ os_event_set(
#endif
}
-/**************************************************************
+/**********************************************************//**
Resets an event semaphore to the nonsignaled state. Waiting threads will
stop to wait for the event.
The return value should be passed to os_even_wait_low() if it is desired
that this thread should not wait in case of an intervening call to
os_event_set() between this os_event_reset() and the
-os_event_wait_low() call. See comments for os_event_wait_low(). */
+os_event_wait_low() call. See comments for os_event_wait_low().
+@return current signal_count. */
UNIV_INTERN
ib_int64_t
os_event_reset(
/*===========*/
- /* out: current signal_count. */
- os_event_t event) /* in: event to reset */
+ os_event_t event) /*!< in: event to reset */
{
ib_int64_t ret = 0;
@@ -304,13 +262,13 @@ os_event_reset(
return(ret);
}
-/**************************************************************
+/**********************************************************//**
Frees an event object, without acquiring the global lock. */
static
void
os_event_free_internal(
/*===================*/
- os_event_t event) /* in: event to free */
+ os_event_t event) /*!< in: event to free */
{
#ifdef __WIN__
ut_a(event);
@@ -333,13 +291,13 @@ os_event_free_internal(
ut_free(event);
}
-/**************************************************************
+/**********************************************************//**
Frees an event object. */
UNIV_INTERN
void
os_event_free(
/*==========*/
- os_event_t event) /* in: event to free */
+ os_event_t event) /*!< in: event to free */
{
#ifdef __WIN__
@@ -365,7 +323,7 @@ os_event_free(
ut_free(event);
}
-/**************************************************************
+/**********************************************************//**
Waits for an event object until it is in the signaled state. If
srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
waiting thread when the event becomes signaled (or immediately if the
@@ -389,8 +347,8 @@ UNIV_INTERN
void
os_event_wait_low(
/*==============*/
- os_event_t event, /* in: event to wait */
- ib_int64_t reset_sig_count)/* in: zero or the value
+ os_event_t event, /*!< in: event to wait */
+ ib_int64_t reset_sig_count)/*!< in: zero or the value
returned by previous call of
os_event_reset(). */
{
@@ -444,17 +402,16 @@ os_event_wait_low(
#endif
}
-/**************************************************************
+/**********************************************************//**
Waits for an event object until it is in the signaled state or
-a timeout is exceeded. In Unix the timeout is always infinite. */
+a timeout is exceeded. In Unix the timeout is always infinite.
+@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
UNIV_INTERN
ulint
os_event_wait_time(
/*===============*/
- /* out: 0 if success, OS_SYNC_TIME_EXCEEDED if
- timeout was exceeded */
- os_event_t event, /* in: event to wait */
- ulint time) /* in: timeout in microseconds, or
+ os_event_t event, /*!< in: event to wait */
+ ulint time) /*!< in: timeout in microseconds, or
OS_SYNC_INFINITE_TIME */
{
#ifdef __WIN__
@@ -490,19 +447,18 @@ os_event_wait_time(
}
#ifdef __WIN__
-/**************************************************************
+/**********************************************************//**
Waits for any event in an OS native event array. Returns if even a single
-one is signaled or becomes signaled. */
+one is signaled or becomes signaled.
+@return index of the event which was signaled */
UNIV_INTERN
ulint
os_event_wait_multiple(
/*===================*/
- /* out: index of the event
- which was signaled */
- ulint n, /* in: number of events in the
+ ulint n, /*!< in: number of events in the
array */
os_native_event_t* native_event_array)
- /* in: pointer to an array of event
+ /*!< in: pointer to an array of event
handles */
{
DWORD index;
@@ -514,7 +470,7 @@ os_event_wait_multiple(
FALSE, /* Wait for any 1 event */
INFINITE); /* Infinite wait time
limit */
- ut_a(index >= WAIT_OBJECT_0); /* NOTE: Pointless comparision */
+ ut_a(index >= WAIT_OBJECT_0); /* NOTE: Pointless comparison */
ut_a(index < WAIT_OBJECT_0 + n);
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
@@ -525,15 +481,15 @@ os_event_wait_multiple(
}
#endif
-/*************************************************************
+/*********************************************************//**
Creates an operating system mutex semaphore. Because these are slow, the
-mutex semaphore of InnoDB itself (mutex_t) should be used where possible. */
+mutex semaphore of InnoDB itself (mutex_t) should be used where possible.
+@return the mutex handle */
UNIV_INTERN
os_mutex_t
os_mutex_create(
/*============*/
- /* out: the mutex handle */
- const char* name) /* in: the name of the mutex, if NULL
+ const char* name) /*!< in: the name of the mutex, if NULL
the mutex is created without a name */
{
#ifdef __WIN__
@@ -576,13 +532,13 @@ os_mutex_create(
return(mutex_str);
}
-/**************************************************************
+/**********************************************************//**
Acquires ownership of a mutex semaphore. */
UNIV_INTERN
void
os_mutex_enter(
/*===========*/
- os_mutex_t mutex) /* in: mutex to acquire */
+ os_mutex_t mutex) /*!< in: mutex to acquire */
{
#ifdef __WIN__
DWORD err;
@@ -605,13 +561,13 @@ os_mutex_enter(
#endif
}
-/**************************************************************
+/**********************************************************//**
Releases ownership of a mutex. */
UNIV_INTERN
void
os_mutex_exit(
/*==========*/
- os_mutex_t mutex) /* in: mutex to release */
+ os_mutex_t mutex) /*!< in: mutex to release */
{
ut_a(mutex);
@@ -625,13 +581,13 @@ os_mutex_exit(
#endif
}
-/**************************************************************
+/**********************************************************//**
Frees a mutex object. */
UNIV_INTERN
void
os_mutex_free(
/*==========*/
- os_mutex_t mutex) /* in: mutex to free */
+ os_mutex_t mutex) /*!< in: mutex to free */
{
ut_a(mutex);
@@ -662,25 +618,21 @@ os_mutex_free(
#endif
}
-/*************************************************************
+/*********************************************************//**
Initializes an operating system fast mutex semaphore. */
UNIV_INTERN
void
os_fast_mutex_init(
/*===============*/
- os_fast_mutex_t* fast_mutex) /* in: fast mutex */
+ os_fast_mutex_t* fast_mutex) /*!< in: fast mutex */
{
#ifdef __WIN__
ut_a(fast_mutex);
InitializeCriticalSection((LPCRITICAL_SECTION) fast_mutex);
#else
-#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
- ut_a(0 == pthread_mutex_init(fast_mutex, pthread_mutexattr_default));
-#else
ut_a(0 == pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST));
#endif
-#endif
if (UNIV_LIKELY(os_sync_mutex_inited)) {
/* When creating os_sync_mutex itself (in Unix) we cannot
reserve it */
@@ -695,13 +647,13 @@ os_fast_mutex_init(
}
}
-/**************************************************************
+/**********************************************************//**
Acquires ownership of a fast mutex. */
UNIV_INTERN
void
os_fast_mutex_lock(
/*===============*/
- os_fast_mutex_t* fast_mutex) /* in: mutex to acquire */
+ os_fast_mutex_t* fast_mutex) /*!< in: mutex to acquire */
{
#ifdef __WIN__
EnterCriticalSection((LPCRITICAL_SECTION) fast_mutex);
@@ -710,13 +662,13 @@ os_fast_mutex_lock(
#endif
}
-/**************************************************************
+/**********************************************************//**
Releases ownership of a fast mutex. */
UNIV_INTERN
void
os_fast_mutex_unlock(
/*=================*/
- os_fast_mutex_t* fast_mutex) /* in: mutex to release */
+ os_fast_mutex_t* fast_mutex) /*!< in: mutex to release */
{
#ifdef __WIN__
LeaveCriticalSection(fast_mutex);
@@ -725,13 +677,13 @@ os_fast_mutex_unlock(
#endif
}
-/**************************************************************
+/**********************************************************//**
Frees a mutex object. */
UNIV_INTERN
void
os_fast_mutex_free(
/*===============*/
- os_fast_mutex_t* fast_mutex) /* in: mutex to free */
+ os_fast_mutex_t* fast_mutex) /*!< in: mutex to free */
{
#ifdef __WIN__
ut_a(fast_mutex);
diff --git a/storage/xtradb/os/os0thread.c b/storage/xtradb/os/os0thread.c
index 7d0a57ae17c..9a2d95cb166 100644
--- a/storage/xtradb/os/os0thread.c
+++ b/storage/xtradb/os/os0thread.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file os/os0thread.c
The interface to the operating system thread control primitives
Created 9/8/1995 Heikki Tuuri
@@ -31,18 +32,19 @@ Created 9/8/1995 Heikki Tuuri
#include <windows.h>
#endif
+#ifndef UNIV_HOTBACKUP
#include "srv0srv.h"
#include "os0sync.h"
-/*******************************************************************
-Compares two thread ids for equality. */
+/***************************************************************//**
+Compares two thread ids for equality.
+@return TRUE if equal */
UNIV_INTERN
ibool
os_thread_eq(
/*=========*/
- /* out: TRUE if equal */
- os_thread_id_t a, /* in: OS thread or thread id */
- os_thread_id_t b) /* in: OS thread or thread id */
+ os_thread_id_t a, /*!< in: OS thread or thread id */
+ os_thread_id_t b) /*!< in: OS thread or thread id */
{
#ifdef __WIN__
if (a == b) {
@@ -59,14 +61,15 @@ os_thread_eq(
#endif
}
-/********************************************************************
+/****************************************************************//**
Converts an OS thread id to a ulint. It is NOT guaranteed that the ulint is
-unique for the thread though! */
+unique for the thread though!
+@return thread identifier as a number */
UNIV_INTERN
ulint
os_thread_pf(
/*=========*/
- os_thread_id_t a)
+ os_thread_id_t a) /*!< in: OS thread identifier */
{
#ifdef UNIV_HPUX10
/* In HP-UX-10.20 a pthread_t is a struct of 3 fields: field1, field2,
@@ -78,10 +81,11 @@ os_thread_pf(
#endif
}
-/*********************************************************************
+/*****************************************************************//**
Returns the thread identifier of current thread. Currently the thread
identifier in Unix is the thread handle itself. Note that in HP-UX
-pthread_t is a struct of 3 fields. */
+pthread_t is a struct of 3 fields.
+@return current thread identifier */
UNIV_INTERN
os_thread_id_t
os_thread_get_curr_id(void)
@@ -94,24 +98,24 @@ os_thread_get_curr_id(void)
#endif
}
-/********************************************************************
+/****************************************************************//**
Creates a new thread of execution. The execution starts from
the function given. The start function takes a void* parameter
-and returns an ulint. */
+and returns an ulint.
+@return handle to the thread */
UNIV_INTERN
os_thread_t
os_thread_create(
/*=============*/
- /* out: handle to the thread */
#ifndef __WIN__
os_posix_f_t start_f,
#else
- ulint (*start_f)(void*), /* in: pointer to function
+ ulint (*start_f)(void*), /*!< in: pointer to function
from which to start */
#endif
- void* arg, /* in: argument to start
+ void* arg, /*!< in: argument to start
function */
- os_thread_id_t* thread_id) /* out: id of the created
+ os_thread_id_t* thread_id) /*!< out: id of the created
thread, or NULL */
{
#ifdef __WIN__
@@ -148,7 +152,7 @@ os_thread_create(
os_thread_t pthread;
pthread_attr_t attr;
-#if !(defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10))
+#ifndef UNIV_HPUX10
pthread_attr_init(&attr);
#endif
@@ -182,7 +186,7 @@ os_thread_create(
os_thread_count++;
os_mutex_exit(os_sync_mutex);
-#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
+#ifdef UNIV_HPUX10
ret = pthread_create(&pthread, pthread_attr_default, start_f, arg);
#else
ret = pthread_create(&pthread, &attr, start_f, arg);
@@ -193,7 +197,7 @@ os_thread_create(
exit(1);
}
-#if !(defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10))
+#ifndef UNIV_HPUX10
pthread_attr_destroy(&attr);
#endif
if (srv_set_thread_priorities) {
@@ -209,13 +213,13 @@ os_thread_create(
#endif
}
-/*********************************************************************
+/*****************************************************************//**
Exits the current thread. */
UNIV_INTERN
void
os_thread_exit(
/*===========*/
- void* exit_value) /* in: exit value; in Windows this void*
+ void* exit_value) /*!< in: exit value; in Windows this void*
is cast as a DWORD */
{
#ifdef UNIV_DEBUG_THREAD_CREATION
@@ -233,8 +237,9 @@ os_thread_exit(
#endif
}
-/*********************************************************************
-Returns handle to the current thread. */
+/*****************************************************************//**
+Returns handle to the current thread.
+@return current thread handle */
UNIV_INTERN
os_thread_t
os_thread_get_curr(void)
@@ -247,7 +252,7 @@ os_thread_get_curr(void)
#endif
}
-/*********************************************************************
+/*****************************************************************//**
Advises the os to give up remainder of the thread's time slice. */
UNIV_INTERN
void
@@ -266,14 +271,15 @@ os_thread_yield(void)
os_thread_sleep(0);
#endif
}
+#endif /* !UNIV_HOTBACKUP */
-/*********************************************************************
+/*****************************************************************//**
The thread sleeps at least the time given in microseconds. */
UNIV_INTERN
void
os_thread_sleep(
/*============*/
- ulint tm) /* in: time in microseconds */
+ ulint tm) /*!< in: time in microseconds */
{
#ifdef __WIN__
Sleep((DWORD) tm / 1000);
@@ -289,14 +295,15 @@ os_thread_sleep(
#endif
}
-/**********************************************************************
+#ifndef UNIV_HOTBACKUP
+/******************************************************************//**
Sets a thread priority. */
UNIV_INTERN
void
os_thread_set_priority(
/*===================*/
- os_thread_t handle, /* in: OS handle to the thread */
- ulint pri) /* in: priority */
+ os_thread_t handle, /*!< in: OS handle to the thread */
+ ulint pri) /*!< in: priority */
{
#ifdef __WIN__
int os_pri;
@@ -318,15 +325,15 @@ os_thread_set_priority(
#endif
}
-/**********************************************************************
-Gets a thread priority. */
+/******************************************************************//**
+Gets a thread priority.
+@return priority */
UNIV_INTERN
ulint
os_thread_get_priority(
/*===================*/
- /* out: priority */
os_thread_t handle __attribute__((unused)))
- /* in: OS handle to the thread */
+ /*!< in: OS handle to the thread */
{
#ifdef __WIN__
int os_pri;
@@ -350,8 +357,9 @@ os_thread_get_priority(
#endif
}
-/**********************************************************************
-Gets the last operating system error code for the calling thread. */
+/******************************************************************//**
+Gets the last operating system error code for the calling thread.
+@return last error on Windows, 0 otherwise */
UNIV_INTERN
ulint
os_thread_get_last_error(void)
@@ -363,3 +371,4 @@ os_thread_get_last_error(void)
return(0);
#endif
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/page/page0cur.c b/storage/xtradb/page/page0cur.c
index e810756c1e4..65f3ba67439 100644
--- a/storage/xtradb/page/page0cur.c
+++ b/storage/xtradb/page/page0cur.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file page/page0cur.c
The page cursor
Created 10/4/1994 Heikki Tuuri
@@ -30,40 +31,74 @@ Created 10/4/1994 Heikki Tuuri
#include "page0zip.h"
#include "mtr0log.h"
#include "log0recv.h"
+#include "ut0ut.h"
+#ifndef UNIV_HOTBACKUP
#include "rem0cmp.h"
-static ulint page_rnd = 976722341;
-
#ifdef PAGE_CUR_ADAPT
# ifdef UNIV_SEARCH_PERF_STAT
static ulint page_cur_short_succ = 0;
# endif /* UNIV_SEARCH_PERF_STAT */
-/********************************************************************
-Tries a search shortcut based on the last insert. */
+/*******************************************************************//**
+This is a linear congruential generator PRNG. Returns a pseudo random
+number between 0 and 2^64-1 inclusive. The formula and the constants
+being used are:
+X[n+1] = (a * X[n] + c) mod m
+where:
+X[0] = ut_time_us(NULL)
+a = 1103515245 (3^5 * 5 * 7 * 129749)
+c = 12345 (3 * 5 * 823)
+m = 18446744073709551616 (2^64)
+
+@return number between 0 and 2^64-1 */
+static
+ib_uint64_t
+page_cur_lcg_prng(void)
+/*===================*/
+{
+#define LCG_a 1103515245
+#define LCG_c 12345
+ static ib_uint64_t lcg_current = 0;
+ static ibool initialized = FALSE;
+
+ if (!initialized) {
+ lcg_current = (ib_uint64_t) ut_time_us(NULL);
+ initialized = TRUE;
+ }
+
+ /* no need to "% 2^64" explicitly because lcg_current is
+ 64 bit and this will be done anyway */
+ lcg_current = LCG_a * lcg_current + LCG_c;
+
+ return(lcg_current);
+}
+
+/****************************************************************//**
+Tries a search shortcut based on the last insert.
+@return TRUE on success */
UNIV_INLINE
ibool
page_cur_try_search_shortcut(
/*=========================*/
- /* out: TRUE on success */
- const buf_block_t* block, /* in: index page */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* tuple, /* in: data tuple */
+ const buf_block_t* block, /*!< in: index page */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* tuple, /*!< in: data tuple */
ulint* iup_matched_fields,
- /* in/out: already matched
+ /*!< in/out: already matched
fields in upper limit record */
ulint* iup_matched_bytes,
- /* in/out: already matched
+ /*!< in/out: already matched
bytes in a field not yet
completely matched */
ulint* ilow_matched_fields,
- /* in/out: already matched
+ /*!< in/out: already matched
fields in lower limit record */
ulint* ilow_matched_bytes,
- /* in/out: already matched
+ /*!< in/out: already matched
bytes in a field not yet
completely matched */
- page_cur_t* cursor) /* out: page cursor */
+ page_cur_t* cursor) /*!< out: page cursor */
{
const rec_t* rec;
const rec_t* next_rec;
@@ -154,20 +189,19 @@ exit_func:
#endif
#ifdef PAGE_CUR_LE_OR_EXTENDS
-/********************************************************************
+/****************************************************************//**
Checks if the nth field in a record is a character type field which extends
the nth field in tuple, i.e., the field is longer or equal in length and has
-common first characters. */
+common first characters.
+@return TRUE if rec field extends tuple field */
static
ibool
page_cur_rec_field_extends(
/*=======================*/
- /* out: TRUE if rec field
- extends tuple field */
- const dtuple_t* tuple, /* in: data tuple */
- const rec_t* rec, /* in: record */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint n) /* in: compare nth field */
+ const dtuple_t* tuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: record */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint n) /*!< in: compare nth field */
{
const dtype_t* type;
const dfield_t* dfield;
@@ -205,33 +239,33 @@ page_cur_rec_field_extends(
}
#endif /* PAGE_CUR_LE_OR_EXTENDS */
-/********************************************************************
+/****************************************************************//**
Searches the right position for a page cursor. */
UNIV_INTERN
void
page_cur_search_with_match(
/*=======================*/
- const buf_block_t* block, /* in: buffer block */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* tuple, /* in: data tuple */
- ulint mode, /* in: PAGE_CUR_L,
+ const buf_block_t* block, /*!< in: buffer block */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* tuple, /*!< in: data tuple */
+ ulint mode, /*!< in: PAGE_CUR_L,
PAGE_CUR_LE, PAGE_CUR_G, or
PAGE_CUR_GE */
ulint* iup_matched_fields,
- /* in/out: already matched
+ /*!< in/out: already matched
fields in upper limit record */
ulint* iup_matched_bytes,
- /* in/out: already matched
+ /*!< in/out: already matched
bytes in a field not yet
completely matched */
ulint* ilow_matched_fields,
- /* in/out: already matched
+ /*!< in/out: already matched
fields in lower limit record */
ulint* ilow_matched_bytes,
- /* in/out: already matched
+ /*!< in/out: already matched
bytes in a field not yet
completely matched */
- page_cur_t* cursor) /* out: page cursor */
+ page_cur_t* cursor) /*!< out: page cursor */
{
ulint up;
ulint low;
@@ -503,15 +537,15 @@ up_rec_match:
}
}
-/***************************************************************
+/***********************************************************//**
Positions a page cursor on a randomly chosen user record on a page. If there
are no user records, sets the cursor on the infimum record. */
UNIV_INTERN
void
page_cur_open_on_rnd_user_rec(
/*==========================*/
- buf_block_t* block, /* in: page */
- page_cur_t* cursor) /* out: page cursor */
+ buf_block_t* block, /*!< in: page */
+ page_cur_t* cursor) /*!< out: page cursor */
{
ulint rnd;
ulint n_recs = page_get_n_recs(buf_block_get_frame(block));
@@ -523,27 +557,25 @@ page_cur_open_on_rnd_user_rec(
return;
}
- page_rnd += 87584577;
-
- rnd = page_rnd % n_recs;
+ rnd = (ulint) (page_cur_lcg_prng() % n_recs);
do {
page_cur_move_to_next(cursor);
} while (rnd--);
}
-/***************************************************************
+/***********************************************************//**
Writes the log record of a record insert on a page. */
static
void
page_cur_insert_rec_write_log(
/*==========================*/
- rec_t* insert_rec, /* in: inserted physical record */
- ulint rec_size, /* in: insert_rec size */
- rec_t* cursor_rec, /* in: record the
+ rec_t* insert_rec, /*!< in: inserted physical record */
+ ulint rec_size, /*!< in: insert_rec size */
+ rec_t* cursor_rec, /*!< in: record the
cursor is pointing to */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mini-transaction handle */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
ulint cur_rec_size;
ulint extra_size;
@@ -713,20 +745,23 @@ need_extra_info:
mlog_catenate_string(mtr, ins_ptr, rec_size);
}
}
+#else /* !UNIV_HOTBACKUP */
+# define page_cur_insert_rec_write_log(ins_rec,size,cur,index,mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses a log record of a record insert on a page. */
+/***********************************************************//**
+Parses a log record of a record insert on a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_cur_parse_insert_rec(
/*======================*/
- /* out: end of log record or NULL */
- ibool is_short,/* in: TRUE if short inserts */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in: page or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr or NULL */
+ ibool is_short,/*!< in: TRUE if short inserts */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in: page or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ulint origin_offset;
ulint end_seg_len;
@@ -905,32 +940,31 @@ page_cur_parse_insert_rec(
return(ptr + end_seg_len);
}
-/***************************************************************
+/***********************************************************//**
Inserts a record next to page cursor on an uncompressed page.
Returns pointer to inserted record if succeed, i.e., enough
-space available, NULL otherwise. The cursor stays at the same position. */
+space available, NULL otherwise. The cursor stays at the same position.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INTERN
rec_t*
page_cur_insert_rec_low(
/*====================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- rec_t* current_rec,/* in: pointer to current record after
+ rec_t* current_rec,/*!< in: pointer to current record after
which the new record is inserted */
- dict_index_t* index, /* in: record descriptor */
- const rec_t* rec, /* in: pointer to a physical record */
- ulint* offsets,/* in/out: rec_get_offsets(rec, index) */
- mtr_t* mtr) /* in: mini-transaction handle, or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ const rec_t* rec, /*!< in: pointer to a physical record */
+ ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
+ mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
{
byte* insert_buf;
ulint rec_size;
- page_t* page; /* the relevant page */
- rec_t* last_insert; /* cursor position at previous
+ page_t* page; /*!< the relevant page */
+ rec_t* last_insert; /*!< cursor position at previous
insert */
- rec_t* free_rec; /* a free record that was reused,
+ rec_t* free_rec; /*!< a free record that was reused,
or NULL */
- rec_t* insert_rec; /* inserted record */
- ulint heap_no; /* heap number of the inserted
+ rec_t* insert_rec; /*!< inserted record */
+ ulint heap_no; /*!< heap number of the inserted
record */
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -1118,21 +1152,21 @@ use_heap:
return(insert_rec);
}
-/***************************************************************
-Compresses or reorganizes a page after an optimistic insert. */
+/***********************************************************//**
+Compresses or reorganizes a page after an optimistic insert.
+@return rec if succeed, NULL otherwise */
static
rec_t*
page_cur_insert_rec_zip_reorg(
/*==========================*/
- /* out: rec if succeed, NULL otherwise */
- rec_t** current_rec,/* in/out: pointer to current record after
+ rec_t** current_rec,/*!< in/out: pointer to current record after
which the new record is inserted */
- buf_block_t* block, /* in: buffer block */
- dict_index_t* index, /* in: record descriptor */
- rec_t* rec, /* in: inserted record */
- page_t* page, /* in: uncompressed page */
- page_zip_des_t* page_zip,/* in: compressed page */
- mtr_t* mtr) /* in: mini-transaction, or NULL */
+ buf_block_t* block, /*!< in: buffer block */
+ dict_index_t* index, /*!< in: record descriptor */
+ rec_t* rec, /*!< in: inserted record */
+ page_t* page, /*!< in: uncompressed page */
+ page_zip_des_t* page_zip,/*!< in: compressed page */
+ mtr_t* mtr) /*!< in: mini-transaction, or NULL */
{
ulint pos;
@@ -1168,34 +1202,33 @@ page_cur_insert_rec_zip_reorg(
return(NULL);
}
-/***************************************************************
+/***********************************************************//**
Inserts a record next to page cursor on a compressed and uncompressed
page. Returns pointer to inserted record if succeed, i.e.,
enough space available, NULL otherwise.
-The cursor stays at the same position. */
+The cursor stays at the same position.
+@return pointer to record if succeed, NULL otherwise */
UNIV_INTERN
rec_t*
page_cur_insert_rec_zip(
/*====================*/
- /* out: pointer to record if succeed, NULL
- otherwise */
- rec_t** current_rec,/* in/out: pointer to current record after
+ rec_t** current_rec,/*!< in/out: pointer to current record after
which the new record is inserted */
- buf_block_t* block, /* in: buffer block of *current_rec */
- dict_index_t* index, /* in: record descriptor */
- const rec_t* rec, /* in: pointer to a physical record */
- ulint* offsets,/* in/out: rec_get_offsets(rec, index) */
- mtr_t* mtr) /* in: mini-transaction handle, or NULL */
+ buf_block_t* block, /*!< in: buffer block of *current_rec */
+ dict_index_t* index, /*!< in: record descriptor */
+ const rec_t* rec, /*!< in: pointer to a physical record */
+ ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */
+ mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
{
byte* insert_buf;
ulint rec_size;
- page_t* page; /* the relevant page */
- rec_t* last_insert; /* cursor position at previous
+ page_t* page; /*!< the relevant page */
+ rec_t* last_insert; /*!< cursor position at previous
insert */
- rec_t* free_rec; /* a free record that was reused,
+ rec_t* free_rec; /*!< a free record that was reused,
or NULL */
- rec_t* insert_rec; /* inserted record */
- ulint heap_no; /* heap number of the inserted
+ rec_t* insert_rec; /*!< inserted record */
+ ulint heap_no; /*!< heap number of the inserted
record */
page_zip_des_t* page_zip;
@@ -1466,18 +1499,18 @@ use_heap:
return(insert_rec);
}
-/**************************************************************
-Writes a log record of copying a record list end to a new created page. */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
+Writes a log record of copying a record list end to a new created page.
+@return 4-byte field where to write the log data length, or NULL if
+logging is disabled */
UNIV_INLINE
byte*
page_copy_rec_list_to_created_page_write_log(
/*=========================================*/
- /* out: 4-byte field where to
- write the log data length,
- or NULL if logging is disabled */
- page_t* page, /* in: index page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ page_t* page, /*!< in: index page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* log_ptr;
@@ -1493,19 +1526,20 @@ page_copy_rec_list_to_created_page_write_log(
return(log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************
-Parses a log record of copying a record list end to a new created page. */
+/**********************************************************//**
+Parses a log record of copying a record list end to a new created page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_parse_copy_rec_list_to_created_page(
/*=====================================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in: page or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in: page or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
byte* rec_end;
ulint log_data_len;
@@ -1550,17 +1584,18 @@ page_parse_copy_rec_list_to_created_page(
return(rec_end);
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Copies records from page to a newly created page, from a given record onward,
including that record. Infimum and supremum records are not copied. */
UNIV_INTERN
void
page_copy_rec_list_end_to_created_page(
/*===================================*/
- page_t* new_page, /* in/out: index page to copy to */
- rec_t* rec, /* in: first record to copy */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ page_t* new_page, /*!< in/out: index page to copy to */
+ rec_t* rec, /*!< in: first record to copy */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_dir_slot_t* slot = 0; /* remove warning */
byte* heap_top;
@@ -1723,15 +1758,15 @@ page_copy_rec_list_end_to_created_page(
mtr_set_log_mode(mtr, log_mode);
}
-/***************************************************************
+/***********************************************************//**
Writes log record of a record delete on a page. */
UNIV_INLINE
void
page_cur_delete_rec_write_log(
/*==========================*/
- rec_t* rec, /* in: record to be deleted */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mini-transaction handle */
+ rec_t* rec, /*!< in: record to be deleted */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
byte* log_ptr;
@@ -1753,19 +1788,22 @@ page_cur_delete_rec_write_log(
mlog_close(mtr, log_ptr + 2);
}
+#else /* !UNIV_HOTBACKUP */
+# define page_cur_delete_rec_write_log(rec,index,mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses log record of a record delete on a page. */
+/***********************************************************//**
+Parses log record of a record delete on a page.
+@return pointer to record end or NULL */
UNIV_INTERN
byte*
page_cur_parse_delete_rec(
/*======================*/
- /* out: pointer to record end or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in: page or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in: page or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ulint offset;
page_cur_t cursor;
@@ -1803,17 +1841,17 @@ page_cur_parse_delete_rec(
return(ptr);
}
-/***************************************************************
+/***********************************************************//**
Deletes a record at the page cursor. The cursor is moved to the next
record after the deleted one. */
UNIV_INTERN
void
page_cur_delete_rec(
/*================*/
- page_cur_t* cursor, /* in/out: a page cursor */
- dict_index_t* index, /* in: record descriptor */
- const ulint* offsets,/* in: rec_get_offsets(cursor->rec, index) */
- mtr_t* mtr) /* in: mini-transaction handle */
+ page_cur_t* cursor, /*!< in/out: a page cursor */
+ dict_index_t* index, /*!< in: record descriptor */
+ const ulint* offsets,/*!< in: rec_get_offsets(cursor->rec, index) */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
page_dir_slot_t* cur_dir_slot;
page_dir_slot_t* prev_slot;
@@ -1920,3 +1958,30 @@ page_cur_delete_rec(
ut_a(!page_zip || page_zip_validate(page_zip, page));
#endif /* UNIV_ZIP_DEBUG */
}
+
+#ifdef UNIV_COMPILE_TEST_FUNCS
+
+/*******************************************************************//**
+Print the first n numbers, generated by page_cur_lcg_prng() to make sure
+(visually) that it works properly. */
+void
+test_page_cur_lcg_prng(
+/*===================*/
+ int n) /*!< in: print first n numbers */
+{
+ int i;
+ unsigned long long rnd;
+
+ for (i = 0; i < n; i++) {
+ rnd = page_cur_lcg_prng();
+ printf("%llu\t%%2=%llu %%3=%llu %%5=%llu %%7=%llu %%11=%llu\n",
+ rnd,
+ rnd % 2,
+ rnd % 3,
+ rnd % 5,
+ rnd % 7,
+ rnd % 11);
+ }
+}
+
+#endif /* UNIV_COMPILE_TEST_FUNCS */
diff --git a/storage/xtradb/page/page0page.c b/storage/xtradb/page/page0page.c
index 0ce532068ce..f056ef77bdc 100644
--- a/storage/xtradb/page/page0page.c
+++ b/storage/xtradb/page/page0page.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file page/page0page.c
Index page routines
Created 2/2/1994 Heikki Tuuri
@@ -31,12 +32,14 @@ Created 2/2/1994 Heikki Tuuri
#include "page0cur.h"
#include "page0zip.h"
-#include "lock0lock.h"
-#include "fut0lst.h"
-#include "btr0sea.h"
#include "buf0buf.h"
-#include "srv0srv.h"
#include "btr0btr.h"
+#ifndef UNIV_HOTBACKUP
+# include "srv0srv.h"
+# include "lock0lock.h"
+# include "fut0lst.h"
+# include "btr0sea.h"
+#endif /* !UNIV_HOTBACKUP */
/* THE INDEX PAGE
==============
@@ -80,14 +83,14 @@ Assuming a page size of 8 kB, a typical index page of a secondary
index contains 300 index entries, and the size of the page directory
is 50 x 4 bytes = 200 bytes. */
-/*******************************************************************
-Looks for the directory slot which owns the given record. */
+/***************************************************************//**
+Looks for the directory slot which owns the given record.
+@return the directory slot number */
UNIV_INTERN
ulint
page_dir_find_owner_slot(
/*=====================*/
- /* out: the directory slot number */
- const rec_t* rec) /* in: the physical record */
+ const rec_t* rec) /*!< in: the physical record */
{
const page_t* page;
register uint16 rec_offs_bytes;
@@ -156,14 +159,14 @@ page_dir_find_owner_slot(
return(((ulint) (first_slot - slot)) / PAGE_DIR_SLOT_SIZE);
}
-/******************************************************************
-Used to check the consistency of a directory slot. */
+/**************************************************************//**
+Used to check the consistency of a directory slot.
+@return TRUE if succeed */
static
ibool
page_dir_slot_check(
/*================*/
- /* out: TRUE if succeed */
- page_dir_slot_t* slot) /* in: slot */
+ page_dir_slot_t* slot) /*!< in: slot */
{
page_t* page;
ulint n_slots;
@@ -199,53 +202,66 @@ page_dir_slot_check(
return(TRUE);
}
-/*****************************************************************
+/*************************************************************//**
Sets the max trx id field value. */
UNIV_INTERN
void
page_set_max_trx_id(
/*================*/
- buf_block_t* block, /* in/out: page */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- dulint trx_id) /* in: transaction id */
+ buf_block_t* block, /*!< in/out: page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr) /*!< in/out: mini-transaction, or NULL */
{
- const ibool is_hashed = block->is_hashed;
page_t* page = buf_block_get_frame(block);
+#ifndef UNIV_HOTBACKUP
+ const ibool is_hashed = block->is_hashed;
if (is_hashed) {
rw_lock_x_lock(&btr_search_latch);
}
+ ut_ad(!mtr || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
+#endif /* !UNIV_HOTBACKUP */
+
/* It is not necessary to write this change to the redo log, as
during a database recovery we assume that the max trx id of every
page is the maximum trx id assigned before the crash. */
- mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id);
if (UNIV_LIKELY_NULL(page_zip)) {
+ mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id);
page_zip_write_header(page_zip,
page + (PAGE_HEADER + PAGE_MAX_TRX_ID),
- 8, NULL);
+ 8, mtr);
+#ifndef UNIV_HOTBACKUP
+ } else if (mtr) {
+ mlog_write_dulint(page + (PAGE_HEADER + PAGE_MAX_TRX_ID),
+ trx_id, mtr);
+#endif /* !UNIV_HOTBACKUP */
+ } else {
+ mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id);
}
+#ifndef UNIV_HOTBACKUP
if (is_hashed) {
rw_lock_x_unlock(&btr_search_latch);
}
+#endif /* !UNIV_HOTBACKUP */
}
-/****************************************************************
-Allocates a block of memory from the heap of an index page. */
+/************************************************************//**
+Allocates a block of memory from the heap of an index page.
+@return pointer to start of allocated buffer, or NULL if allocation fails */
UNIV_INTERN
byte*
page_mem_alloc_heap(
/*================*/
- /* out: pointer to start of allocated
- buffer, or NULL if allocation fails */
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page with enough
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
space available for inserting the record,
or NULL */
- ulint need, /* in: total number of bytes needed */
- ulint* heap_no)/* out: this contains the heap number
+ ulint need, /*!< in: total number of bytes needed */
+ ulint* heap_no)/*!< out: this contains the heap number
of the allocated record
if allocation succeeds */
{
@@ -271,34 +287,38 @@ page_mem_alloc_heap(
return(NULL);
}
-/**************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
Writes a log record of page creation. */
UNIV_INLINE
void
page_create_write_log(
/*==================*/
- buf_frame_t* frame, /* in: a buffer frame where the page is
+ buf_frame_t* frame, /*!< in: a buffer frame where the page is
created */
- mtr_t* mtr, /* in: mini-transaction handle */
- ibool comp) /* in: TRUE=compact page format */
+ mtr_t* mtr, /*!< in: mini-transaction handle */
+ ibool comp) /*!< in: TRUE=compact page format */
{
mlog_write_initial_log_record(frame, comp
? MLOG_COMP_PAGE_CREATE
: MLOG_PAGE_CREATE, mtr);
}
+#else /* !UNIV_HOTBACKUP */
+# define page_create_write_log(frame,mtr,comp) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses a redo log record of creating a page. */
+/***********************************************************//**
+Parses a redo log record of creating a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_parse_create(
/*==============*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr __attribute__((unused)), /* in: buffer end */
- ulint comp, /* in: nonzero=compact page format */
- buf_block_t* block, /* in: block or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr __attribute__((unused)), /*!< in: buffer end */
+ ulint comp, /*!< in: nonzero=compact page format */
+ buf_block_t* block, /*!< in: block or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ut_ad(ptr && end_ptr);
@@ -311,16 +331,16 @@ page_parse_create(
return(ptr);
}
-/**************************************************************
-The index page creation function. */
+/**********************************************************//**
+The index page creation function.
+@return pointer to the page */
static
page_t*
page_create_low(
/*============*/
- /* out: pointer to the page */
- buf_block_t* block, /* in: a buffer block where the
+ buf_block_t* block, /*!< in: a buffer block where the
page is created */
- ulint comp) /* in: nonzero=compact page format */
+ ulint comp) /*!< in: nonzero=compact page format */
{
page_dir_slot_t* slot;
mem_heap_t* heap;
@@ -343,9 +363,9 @@ page_create_low(
/* The infimum and supremum records use a dummy index. */
if (UNIV_LIKELY(comp)) {
- index = srv_sys->dummy_ind2;
+ index = dict_ind_compact;
} else {
- index = srv_sys->dummy_ind1;
+ index = dict_ind_redundant;
}
/* 1. INCREMENT MODIFY CLOCK */
@@ -437,7 +457,7 @@ page_create_low(
page_header_set_field(page, NULL, PAGE_DIRECTION, PAGE_NO_DIRECTION);
page_header_set_field(page, NULL, PAGE_N_DIRECTION, 0);
page_header_set_field(page, NULL, PAGE_N_RECS, 0);
- page_set_max_trx_id(block, NULL, ut_dulint_zero);
+ page_set_max_trx_id(block, NULL, ut_dulint_zero, NULL);
memset(heap_top, 0, UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START
- page_offset(heap_top));
@@ -464,34 +484,34 @@ page_create_low(
return(page);
}
-/**************************************************************
-Create an uncompressed B-tree index page. */
+/**********************************************************//**
+Create an uncompressed B-tree index page.
+@return pointer to the page */
UNIV_INTERN
page_t*
page_create(
/*========*/
- /* out: pointer to the page */
- buf_block_t* block, /* in: a buffer block where the
+ buf_block_t* block, /*!< in: a buffer block where the
page is created */
- mtr_t* mtr, /* in: mini-transaction handle */
- ulint comp) /* in: nonzero=compact page format */
+ mtr_t* mtr, /*!< in: mini-transaction handle */
+ ulint comp) /*!< in: nonzero=compact page format */
{
page_create_write_log(buf_block_get_frame(block), mtr, comp);
return(page_create_low(block, comp));
}
-/**************************************************************
-Create a compressed B-tree index page. */
+/**********************************************************//**
+Create a compressed B-tree index page.
+@return pointer to the page */
UNIV_INTERN
page_t*
page_create_zip(
/*============*/
- /* out: pointer to the page */
- buf_block_t* block, /* in/out: a buffer frame where the
+ buf_block_t* block, /*!< in/out: a buffer frame where the
page is created */
- dict_index_t* index, /* in: the index of the page */
- ulint level, /* in: the B-tree level of the page */
- mtr_t* mtr) /* in: mini-transaction handle */
+ dict_index_t* index, /*!< in: the index of the page */
+ ulint level, /*!< in: the B-tree level of the page */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
page_t* page;
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
@@ -513,18 +533,18 @@ page_create_zip(
return(page);
}
-/*****************************************************************
+/*************************************************************//**
Differs from page_copy_rec_list_end, because this function does not
touch the lock table and max trx id on page or compress the page. */
UNIV_INTERN
void
page_copy_rec_list_end_no_locks(
/*============================*/
- buf_block_t* new_block, /* in: index page to copy to */
- buf_block_t* block, /* in: index page of rec */
- rec_t* rec, /* in: record on page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in: index page to copy to */
+ buf_block_t* block, /*!< in: index page of rec */
+ rec_t* rec, /*!< in: record on page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* new_page = buf_block_get_frame(new_block);
page_cur_t cur1;
@@ -584,23 +604,22 @@ page_copy_rec_list_end_no_locks(
}
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Copies records from page to new_page, from a given record onward,
including that record. Infimum and supremum records are not copied.
-The records are copied to the start of the record list on new_page. */
+The records are copied to the start of the record list on new_page.
+@return pointer to the original successor of the infimum record on
+new_page, or NULL on zip overflow (new_block will be decompressed) */
UNIV_INTERN
rec_t*
page_copy_rec_list_end(
/*===================*/
- /* out: pointer to the original
- successor of the infimum record
- on new_page, or NULL on zip overflow
- (new_block will be decompressed) */
- buf_block_t* new_block, /* in/out: index page to copy to */
- buf_block_t* block, /* in: index page containing rec */
- rec_t* rec, /* in: record on page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page to copy to */
+ buf_block_t* block, /*!< in: index page containing rec */
+ rec_t* rec, /*!< in: record on page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* new_page = buf_block_get_frame(new_block);
page_zip_des_t* new_page_zip = buf_block_get_page_zip(new_block);
@@ -681,31 +700,31 @@ page_copy_rec_list_end(
lock_move_rec_list_end(new_block, block, rec);
- page_update_max_trx_id(new_block, new_page_zip,
- page_get_max_trx_id(page));
+ if (dict_index_is_sec_or_ibuf(index) && page_is_leaf(page)) {
+ page_update_max_trx_id(new_block, new_page_zip,
+ page_get_max_trx_id(page), mtr);
+ }
btr_search_move_or_delete_hash_entries(new_block, block, index);
return(ret);
}
-/*****************************************************************
+/*************************************************************//**
Copies records from page to new_page, up to the given record,
NOT including that record. Infimum and supremum records are not copied.
-The records are copied to the end of the record list on new_page. */
+The records are copied to the end of the record list on new_page.
+@return pointer to the original predecessor of the supremum record on
+new_page, or NULL on zip overflow (new_block will be decompressed) */
UNIV_INTERN
rec_t*
page_copy_rec_list_start(
/*=====================*/
- /* out: pointer to the original
- predecessor of the supremum record
- on new_page, or NULL on zip overflow
- (new_block will be decompressed) */
- buf_block_t* new_block, /* in/out: index page to copy to */
- buf_block_t* block, /* in: index page containing rec */
- rec_t* rec, /* in: record on page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page to copy to */
+ buf_block_t* block, /*!< in: index page containing rec */
+ rec_t* rec, /*!< in: record on page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* new_page = buf_block_get_frame(new_block);
page_zip_des_t* new_page_zip = buf_block_get_page_zip(new_block);
@@ -792,8 +811,12 @@ page_copy_rec_list_start(
/* Update MAX_TRX_ID, the lock table, and possible hash index */
- page_update_max_trx_id(new_block, new_page_zip,
- page_get_max_trx_id(page_align(rec)));
+ if (dict_index_is_sec_or_ibuf(index)
+ && page_is_leaf(page_align(rec))) {
+ page_update_max_trx_id(new_block, new_page_zip,
+ page_get_max_trx_id(page_align(rec)),
+ mtr);
+ }
lock_move_rec_list_start(new_block, block, rec, ret);
@@ -802,17 +825,17 @@ page_copy_rec_list_start(
return(ret);
}
-/**************************************************************
+/**********************************************************//**
Writes a log record of a record list end or start deletion. */
UNIV_INLINE
void
page_delete_rec_list_write_log(
/*===========================*/
- rec_t* rec, /* in: record on page */
- dict_index_t* index, /* in: record descriptor */
- byte type, /* in: operation type:
+ rec_t* rec, /*!< in: record on page */
+ dict_index_t* index, /*!< in: record descriptor */
+ byte type, /*!< in: operation type:
MLOG_LIST_END_DELETE, ... */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* log_ptr;
ut_ad(type == MLOG_LIST_END_DELETE
@@ -827,23 +850,26 @@ page_delete_rec_list_write_log(
mlog_close(mtr, log_ptr + 2);
}
}
+#else /* !UNIV_HOTBACKUP */
+# define page_delete_rec_list_write_log(rec,index,type,mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************
-Parses a log record of a record list end or start deletion. */
+/**********************************************************//**
+Parses a log record of a record list end or start deletion.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_parse_delete_rec_list(
/*=======================*/
- /* out: end of log record or NULL */
- byte type, /* in: MLOG_LIST_END_DELETE,
+ byte type, /*!< in: MLOG_LIST_END_DELETE,
MLOG_LIST_START_DELETE,
MLOG_COMP_LIST_END_DELETE or
MLOG_COMP_LIST_START_DELETE */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- buf_block_t* block, /* in/out: buffer block or NULL */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ buf_block_t* block, /*!< in/out: buffer block or NULL */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
page_t* page;
ulint offset;
@@ -884,22 +910,22 @@ page_parse_delete_rec_list(
return(ptr);
}
-/*****************************************************************
+/*************************************************************//**
Deletes records from a page from a given record onward, including that record.
The infimum and supremum records are not deleted. */
UNIV_INTERN
void
page_delete_rec_list_end(
/*=====================*/
- rec_t* rec, /* in: pointer to record on page */
- buf_block_t* block, /* in: buffer block of the page */
- dict_index_t* index, /* in: record descriptor */
- ulint n_recs, /* in: number of records to delete,
+ rec_t* rec, /*!< in: pointer to record on page */
+ buf_block_t* block, /*!< in: buffer block of the page */
+ dict_index_t* index, /*!< in: record descriptor */
+ ulint n_recs, /*!< in: number of records to delete,
or ULINT_UNDEFINED if not known */
- ulint size, /* in: the sum of the sizes of the
+ ulint size, /*!< in: the sum of the sizes of the
records in the end of the chain to
delete, or ULINT_UNDEFINED if not known */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
page_dir_slot_t*slot;
ulint slot_index;
@@ -1060,17 +1086,17 @@ page_delete_rec_list_end(
(ulint)(page_get_n_recs(page) - n_recs));
}
-/*****************************************************************
+/*************************************************************//**
Deletes records from page, up to the given record, NOT including
that record. Infimum and supremum records are not deleted. */
UNIV_INTERN
void
page_delete_rec_list_start(
/*=======================*/
- rec_t* rec, /* in: record on page */
- buf_block_t* block, /* in: buffer block of the page */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ rec_t* rec, /*!< in: record on page */
+ buf_block_t* block, /*!< in: buffer block of the page */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_cur_t cur1;
ulint log_mode;
@@ -1132,21 +1158,21 @@ page_delete_rec_list_start(
mtr_set_log_mode(mtr, log_mode);
}
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Moves record list end to another page. Moved records include
-split_rec. */
+split_rec.
+@return TRUE on success; FALSE on compression failure (new_block will
+be decompressed) */
UNIV_INTERN
ibool
page_move_rec_list_end(
/*===================*/
- /* out: TRUE on success; FALSE on
- compression failure
- (new_block will be decompressed) */
- buf_block_t* new_block, /* in/out: index page where to move */
- buf_block_t* block, /* in: index page from where to move */
- rec_t* split_rec, /* in: first record to move */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page where to move */
+ buf_block_t* block, /*!< in: index page from where to move */
+ rec_t* split_rec, /*!< in: first record to move */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* new_page = buf_block_get_frame(new_block);
ulint old_data_size;
@@ -1187,20 +1213,19 @@ page_move_rec_list_end(
return(TRUE);
}
-/*****************************************************************
+/*************************************************************//**
Moves record list start to another page. Moved records do not include
-split_rec. */
+split_rec.
+@return TRUE on success; FALSE on compression failure */
UNIV_INTERN
ibool
page_move_rec_list_start(
/*=====================*/
- /* out: TRUE on success; FALSE on
- compression failure */
- buf_block_t* new_block, /* in/out: index page where to move */
- buf_block_t* block, /* in/out: page containing split_rec */
- rec_t* split_rec, /* in: first record not to move */
- dict_index_t* index, /* in: record descriptor */
- mtr_t* mtr) /* in: mtr */
+ buf_block_t* new_block, /*!< in/out: index page where to move */
+ buf_block_t* block, /*!< in/out: page containing split_rec */
+ rec_t* split_rec, /*!< in: first record not to move */
+ dict_index_t* index, /*!< in: record descriptor */
+ mtr_t* mtr) /*!< in: mtr */
{
if (UNIV_UNLIKELY(!page_copy_rec_list_start(new_block, block,
split_rec, index, mtr))) {
@@ -1212,17 +1237,17 @@ page_move_rec_list_start(
return(TRUE);
}
-/***************************************************************************
+/***********************************************************************//**
This is a low-level operation which is used in a database index creation
to update the page number of a created B-tree to a data dictionary record. */
UNIV_INTERN
void
page_rec_write_index_page_no(
/*=========================*/
- rec_t* rec, /* in: record to update */
- ulint i, /* in: index of the field to update */
- ulint page_no,/* in: value to write */
- mtr_t* mtr) /* in: mtr */
+ rec_t* rec, /*!< in: record to update */
+ ulint i, /*!< in: index of the field to update */
+ ulint page_no,/*!< in: value to write */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* data;
ulint len;
@@ -1233,8 +1258,9 @@ page_rec_write_index_page_no(
mlog_write_ulint(data, page_no, MLOG_4BYTES, mtr);
}
+#endif /* !UNIV_HOTBACKUP */
-/******************************************************************
+/**************************************************************//**
Used to delete n slots from the directory. This function updates
also n_owned fields in the records, so that the first slot after
the deleted ones inherits the records of the deleted slots. */
@@ -1242,9 +1268,9 @@ UNIV_INLINE
void
page_dir_delete_slot(
/*=================*/
- page_t* page, /* in/out: the index page */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint slot_no)/* in: slot to be deleted */
+ page_t* page, /*!< in/out: the index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint slot_no)/*!< in: slot to be deleted */
{
page_dir_slot_t* slot;
ulint n_owned;
@@ -1283,7 +1309,7 @@ page_dir_delete_slot(
page_header_set_field(page, page_zip, PAGE_N_DIR_SLOTS, n_slots - 1);
}
-/******************************************************************
+/**************************************************************//**
Used to add n slots to the directory. Does not set the record pointers
in the added slots or update n_owned values: this is the responsibility
of the caller. */
@@ -1291,9 +1317,9 @@ UNIV_INLINE
void
page_dir_add_slot(
/*==============*/
- page_t* page, /* in/out: the index page */
- page_zip_des_t* page_zip,/* in/out: comprssed page, or NULL */
- ulint start) /* in: the slot above which the new slots
+ page_t* page, /*!< in/out: the index page */
+ page_zip_des_t* page_zip,/*!< in/out: comprssed page, or NULL */
+ ulint start) /*!< in: the slot above which the new slots
are added */
{
page_dir_slot_t* slot;
@@ -1312,16 +1338,16 @@ page_dir_add_slot(
(n_slots - 1 - start) * PAGE_DIR_SLOT_SIZE);
}
-/********************************************************************
+/****************************************************************//**
Splits a directory slot which owns too many records. */
UNIV_INTERN
void
page_dir_split_slot(
/*================*/
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page whose
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be written, or NULL */
- ulint slot_no)/* in: the directory slot */
+ ulint slot_no)/*!< in: the directory slot */
{
rec_t* rec;
page_dir_slot_t* new_slot;
@@ -1373,7 +1399,7 @@ page_dir_split_slot(
page_dir_slot_set_n_owned(slot, page_zip, n_owned - (n_owned / 2));
}
-/*****************************************************************
+/*************************************************************//**
Tries to balance the given directory slot with too few records with the upper
neighbor, so that there are at least the minimum number of records owned by
the slot; this may result in the merging of two slots. */
@@ -1381,9 +1407,9 @@ UNIV_INTERN
void
page_dir_balance_slot(
/*==================*/
- page_t* page, /* in/out: index page */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- ulint slot_no)/* in: the directory slot */
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ ulint slot_no)/*!< in: the directory slot */
{
page_dir_slot_t* slot;
page_dir_slot_t* up_slot;
@@ -1444,15 +1470,16 @@ page_dir_balance_slot(
}
}
-/****************************************************************
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
Returns the middle record of the record list. If there are an even number
-of records in the list, returns the first record of the upper half-list. */
+of records in the list, returns the first record of the upper half-list.
+@return middle record */
UNIV_INTERN
rec_t*
page_get_middle_rec(
/*================*/
- /* out: middle record */
- page_t* page) /* in: page */
+ page_t* page) /*!< in: page */
{
page_dir_slot_t* slot;
ulint middle;
@@ -1491,16 +1518,17 @@ page_get_middle_rec(
return(rec);
}
+#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
Returns the number of records before the given record in chain.
-The number includes infimum and supremum records. */
+The number includes infimum and supremum records.
+@return number of records */
UNIV_INTERN
ulint
page_rec_get_n_recs_before(
/*=======================*/
- /* out: number of records */
- const rec_t* rec) /* in: the physical record */
+ const rec_t* rec) /*!< in: the physical record */
{
const page_dir_slot_t* slot;
const rec_t* slot_rec;
@@ -1556,15 +1584,16 @@ page_rec_get_n_recs_before(
return((ulint) n);
}
-/****************************************************************
+#ifndef UNIV_HOTBACKUP
+/************************************************************//**
Prints record contents including the data relevant only in
the index page context. */
UNIV_INTERN
void
page_rec_print(
/*===========*/
- const rec_t* rec, /* in: physical record */
- const ulint* offsets)/* in: record descriptor */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: record descriptor */
{
ut_a(!page_rec_is_comp(rec) == !rec_offs_comp(offsets));
rec_print_new(stderr, rec, offsets);
@@ -1586,15 +1615,15 @@ page_rec_print(
rec_validate(rec, offsets);
}
-/*******************************************************************
+/***************************************************************//**
This is used to print the contents of the directory for
debugging purposes. */
UNIV_INTERN
void
page_dir_print(
/*===========*/
- page_t* page, /* in: index page */
- ulint pr_n) /* in: print n first and n last entries */
+ page_t* page, /*!< in: index page */
+ ulint pr_n) /*!< in: print n first and n last entries */
{
ulint n;
ulint i;
@@ -1628,16 +1657,16 @@ page_dir_print(
(ulong) (PAGE_HEAP_NO_USER_LOW + page_get_n_recs(page)));
}
-/*******************************************************************
+/***************************************************************//**
This is used to print the contents of the page record list for
debugging purposes. */
UNIV_INTERN
void
page_print_list(
/*============*/
- buf_block_t* block, /* in: index page */
- dict_index_t* index, /* in: dictionary index of the page */
- ulint pr_n) /* in: print n first and n last entries */
+ buf_block_t* block, /*!< in: index page */
+ dict_index_t* index, /*!< in: dictionary index of the page */
+ ulint pr_n) /*!< in: print n first and n last entries */
{
page_t* page = block->frame;
page_cur_t cur;
@@ -1699,7 +1728,7 @@ page_print_list(
}
}
-/*******************************************************************
+/***************************************************************//**
Prints the info in a page header. */
UNIV_INTERN
void
@@ -1726,18 +1755,18 @@ page_header_print(
(ulong) page_header_get_field(page, PAGE_N_DIRECTION));
}
-/*******************************************************************
+/***************************************************************//**
This is used to print the contents of the page for
debugging purposes. */
UNIV_INTERN
void
page_print(
/*=======*/
- buf_block_t* block, /* in: index page */
- dict_index_t* index, /* in: dictionary index of the page */
- ulint dn, /* in: print dn first and last entries
+ buf_block_t* block, /*!< in: index page */
+ dict_index_t* index, /*!< in: dictionary index of the page */
+ ulint dn, /*!< in: print dn first and last entries
in directory */
- ulint rn) /* in: print rn first and last records
+ ulint rn) /*!< in: print rn first and last records
in directory */
{
page_t* page = block->frame;
@@ -1746,18 +1775,19 @@ page_print(
page_dir_print(page, dn);
page_print_list(block, index, rn);
}
+#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
The following is used to validate a record on a page. This function
differs from rec_validate as it can also check the n_owned field and
-the heap_no field. */
+the heap_no field.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_rec_validate(
/*==============*/
- /* out: TRUE if ok */
- rec_t* rec, /* in: physical record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n_owned;
ulint heap_no;
@@ -1795,7 +1825,8 @@ page_rec_validate(
return(TRUE);
}
-/*******************************************************************
+#ifndef UNIV_HOTBACKUP
+/***************************************************************//**
Checks that the first directory slot points to the infimum record and
the last to the supremum. This function is intended to track if the
bug fixed in 4.0.14 has caused corruption to users' databases. */
@@ -1803,7 +1834,7 @@ UNIV_INTERN
void
page_check_dir(
/*===========*/
- const page_t* page) /* in: index page */
+ const page_t* page) /*!< in: index page */
{
ulint n_slots;
ulint infimum_offs;
@@ -1830,17 +1861,18 @@ page_check_dir(
buf_page_print(page, 0);
}
}
+#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
This function checks the consistency of an index page when we do not
know the index. This is also resilient so that this should never crash
-even if the page is total garbage. */
+even if the page is total garbage.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_simple_validate_old(
/*=====================*/
- /* out: TRUE if ok */
- page_t* page) /* in: old-style index page */
+ page_t* page) /*!< in: old-style index page */
{
page_dir_slot_t* slot;
ulint slot_no;
@@ -2041,16 +2073,16 @@ func_exit:
return(ret);
}
-/*******************************************************************
+/***************************************************************//**
This function checks the consistency of an index page when we do not
know the index. This is also resilient so that this should never crash
-even if the page is total garbage. */
+even if the page is total garbage.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_simple_validate_new(
/*=====================*/
- /* out: TRUE if ok */
- page_t* page) /* in: new-style index page */
+ page_t* page) /*!< in: new-style index page */
{
page_dir_slot_t* slot;
ulint slot_no;
@@ -2252,15 +2284,15 @@ func_exit:
return(ret);
}
-/*******************************************************************
-This function checks the consistency of an index page. */
+/***************************************************************//**
+This function checks the consistency of an index page.
+@return TRUE if ok */
UNIV_INTERN
ibool
page_validate(
/*==========*/
- /* out: TRUE if ok */
- page_t* page, /* in: index page */
- dict_index_t* index) /* in: data dictionary index containing
+ page_t* page, /*!< in: index page */
+ dict_index_t* index) /*!< in: data dictionary index containing
the page record type definition */
{
page_dir_slot_t*slot;
@@ -2310,10 +2342,11 @@ page_validate(
if (UNIV_UNLIKELY(!(page_header_get_ptr(page, PAGE_HEAP_TOP)
<= page_dir_get_nth_slot(page, n_slots - 1)))) {
- fputs("InnoDB: Record heap and dir overlap on a page ",
- stderr);
- dict_index_name_print(stderr, NULL, index);
- fprintf(stderr, ", %p, %p\n",
+ fprintf(stderr,
+ "InnoDB: Record heap and dir overlap"
+ " on space %lu page %lu index %s, %p, %p\n",
+ (ulong) page_get_space_id(page),
+ (ulong) page_get_page_no(page), index->name,
page_header_get_ptr(page, PAGE_HEAP_TOP),
page_dir_get_nth_slot(page, n_slots - 1));
@@ -2345,17 +2378,19 @@ page_validate(
goto func_exit;
}
+#ifndef UNIV_HOTBACKUP
/* Check that the records are in the ascending order */
if (UNIV_LIKELY(count >= PAGE_HEAP_NO_USER_LOW)
&& !page_rec_is_supremum(rec)) {
if (UNIV_UNLIKELY
(1 != cmp_rec_rec(rec, old_rec,
offsets, old_offsets, index))) {
- fprintf(stderr,
+ fprintf(stderr,
"InnoDB: Records in wrong order"
- " on page %lu ",
- (ulong) page_get_page_no(page));
- dict_index_name_print(stderr, NULL, index);
+ " on space %lu page %lu index %s\n",
+ (ulong) page_get_space_id(page),
+ (ulong) page_get_page_no(page),
+ index->name);
fputs("\nInnoDB: previous record ", stderr);
rec_print_new(stderr, old_rec, old_offsets);
fputs("\nInnoDB: record ", stderr);
@@ -2365,6 +2400,7 @@ page_validate(
goto func_exit;
}
}
+#endif /* !UNIV_HOTBACKUP */
if (page_rec_is_user_rec(rec)) {
@@ -2510,25 +2546,28 @@ func_exit:
if (UNIV_UNLIKELY(ret == FALSE)) {
func_exit2:
- fprintf(stderr, "InnoDB: Apparent corruption in page %lu in ",
- (ulong) page_get_page_no(page));
- dict_index_name_print(stderr, NULL, index);
- putc('\n', stderr);
+ fprintf(stderr,
+ "InnoDB: Apparent corruption"
+ " in space %lu page %lu index %s\n",
+ (ulong) page_get_space_id(page),
+ (ulong) page_get_page_no(page),
+ index->name);
buf_page_print(page, 0);
}
return(ret);
}
-/*******************************************************************
-Looks in the page record list for a record with the given heap number. */
+#ifndef UNIV_HOTBACKUP
+/***************************************************************//**
+Looks in the page record list for a record with the given heap number.
+@return record, NULL if not found */
UNIV_INTERN
const rec_t*
page_find_rec_with_heap_no(
/*=======================*/
- /* out: record, NULL if not found */
- const page_t* page, /* in: index page */
- ulint heap_no)/* in: heap number */
+ const page_t* page, /*!< in: index page */
+ ulint heap_no)/*!< in: heap number */
{
const rec_t* rec;
@@ -2566,3 +2605,4 @@ page_find_rec_with_heap_no(
}
}
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/page/page0zip.c b/storage/xtradb/page/page0zip.c
index 56189ce3bad..92ba0ec768a 100644
--- a/storage/xtradb/page/page0zip.c
+++ b/storage/xtradb/page/page0zip.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file page/page0zip.c
Compressed page interface
Created June 2005 by Marko Makela
@@ -31,15 +32,20 @@ Created June 2005 by Marko Makela
#include "page0page.h"
#include "mtr0log.h"
#include "ut0sort.h"
-#include "dict0boot.h"
#include "dict0dict.h"
-#include "btr0sea.h"
#include "btr0cur.h"
#include "page0types.h"
-#include "lock0lock.h"
#include "log0recv.h"
#include "zlib.h"
-#include "buf0lru.h"
+#ifndef UNIV_HOTBACKUP
+# include "buf0lru.h"
+# include "btr0sea.h"
+# include "dict0boot.h"
+# include "lock0lock.h"
+#else /* !UNIV_HOTBACKUP */
+# define lock_move_reorganize_page(block, temp_block) ((void) 0)
+# define buf_LRU_stat_inc_unzip() ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
/** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */
UNIV_INTERN page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
@@ -50,15 +56,18 @@ compressed page format. */
/* The infimum and supremum records are omitted from the compressed page.
On compress, we compare that the records are there, and on uncompress we
restore the records. */
+/** Extra bytes of an infimum record */
static const byte infimum_extra[] = {
0x01, /* info_bits=0, n_owned=1 */
0x00, 0x02 /* heap_no=0, status=2 */
/* ?, ? */ /* next=(first user rec, or supremum) */
};
+/** Data bytes of an infimum record */
static const byte infimum_data[] = {
0x69, 0x6e, 0x66, 0x69,
0x6d, 0x75, 0x6d, 0x00 /* "infimum\0" */
};
+/** Extra bytes and data bytes of a supremum record */
static const byte supremum_extra_data[] = {
/* 0x0?, */ /* info_bits=0, n_owned=1..8 */
0x00, 0x0b, /* heap_no=1, status=3 */
@@ -68,10 +77,13 @@ static const byte supremum_extra_data[] = {
};
/** Assert that a block of memory is filled with zero bytes.
-Compare at most sizeof(field_ref_zero) bytes. */
+Compare at most sizeof(field_ref_zero) bytes.
+@param b in: memory block
+@param s in: size of the memory block, in bytes */
#define ASSERT_ZERO(b, s) \
ut_ad(!memcmp(b, field_ref_zero, ut_min(s, sizeof field_ref_zero)))
-/** Assert that a BLOB pointer is filled with zero bytes. */
+/** Assert that a BLOB pointer is filled with zero bytes.
+@param b in: BLOB pointer */
#define ASSERT_ZERO_BLOB(b) \
ut_ad(!memcmp(b, field_ref_zero, sizeof field_ref_zero))
@@ -80,15 +92,15 @@ independently of any UNIV_ debugging conditions. */
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
# include <stdarg.h>
__attribute__((format (printf, 1, 2)))
-/**************************************************************************
-Report a failure to decompress or compress. */
+/**********************************************************************//**
+Report a failure to decompress or compress.
+@return number of characters printed */
static
int
page_zip_fail_func(
/*===============*/
- /* out: number of characters printed */
- const char* fmt, /* in: printf(3) format string */
- ...) /* in: arguments corresponding to fmt */
+ const char* fmt, /*!< in: printf(3) format string */
+ ...) /*!< in: arguments corresponding to fmt */
{
int res;
va_list ap;
@@ -101,20 +113,25 @@ page_zip_fail_func(
return(res);
}
+/** Wrapper for page_zip_fail_func()
+@param fmt_args in: printf(3) format string and arguments */
# define page_zip_fail(fmt_args) page_zip_fail_func fmt_args
#else /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
+/** Dummy wrapper for page_zip_fail_func()
+@param fmt_args ignored: printf(3) format string and arguments */
# define page_zip_fail(fmt_args) /* empty */
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
-/**************************************************************************
-Determine the guaranteed free space on an empty page. */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
+Determine the guaranteed free space on an empty page.
+@return minimum payload size on the page */
UNIV_INTERN
ulint
page_zip_empty_size(
/*================*/
- /* out: minimum payload size on the page */
- ulint n_fields, /* in: number of columns in the index */
- ulint zip_size) /* in: compressed page size in bytes */
+ ulint n_fields, /*!< in: number of columns in the index */
+ ulint zip_size) /*!< in: compressed page size in bytes */
{
lint size = zip_size
/* subtract the page header and the longest
@@ -129,17 +146,17 @@ page_zip_empty_size(
- compressBound(2 * (n_fields + 1));
return(size > 0 ? (ulint) size : 0);
}
+#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+/*************************************************************//**
Gets the size of the compressed page trailer (the dense page directory),
-including deleted records (the free list). */
+including deleted records (the free list).
+@return length of dense page directory, in bytes */
UNIV_INLINE
ulint
page_zip_dir_size(
/*==============*/
- /* out: length of dense page
- directory, in bytes */
- const page_zip_des_t* page_zip) /* in: compressed page */
+ const page_zip_des_t* page_zip) /*!< in: compressed page */
{
/* Exclude the page infimum and supremum from the record count. */
ulint size = PAGE_ZIP_DIR_SLOT_SIZE
@@ -148,17 +165,15 @@ page_zip_dir_size(
return(size);
}
-/*****************************************************************
+/*************************************************************//**
Gets the size of the compressed page trailer (the dense page directory),
-only including user records (excluding the free list). */
+only including user records (excluding the free list).
+@return length of dense page directory comprising existing records, in bytes */
UNIV_INLINE
ulint
page_zip_dir_user_size(
/*===================*/
- /* out: length of dense page
- directory comprising existing
- records, in bytes */
- const page_zip_des_t* page_zip) /* in: compressed page */
+ const page_zip_des_t* page_zip) /*!< in: compressed page */
{
ulint size = PAGE_ZIP_DIR_SLOT_SIZE
* page_get_n_recs(page_zip->data);
@@ -166,17 +181,16 @@ page_zip_dir_user_size(
return(size);
}
-/*****************************************************************
-Find the slot of the given record in the dense page directory. */
+/*************************************************************//**
+Find the slot of the given record in the dense page directory.
+@return dense directory slot, or NULL if record not found */
UNIV_INLINE
byte*
page_zip_dir_find_low(
/*==================*/
- /* out: dense directory slot,
- or NULL if record not found */
- byte* slot, /* in: start of records */
- byte* end, /* in: end of records */
- ulint offset) /* in: offset of user record */
+ byte* slot, /*!< in: start of records */
+ byte* end, /*!< in: end of records */
+ ulint offset) /*!< in: offset of user record */
{
ut_ad(slot <= end);
@@ -190,16 +204,15 @@ page_zip_dir_find_low(
return(NULL);
}
-/*****************************************************************
-Find the slot of the given non-free record in the dense page directory. */
+/*************************************************************//**
+Find the slot of the given non-free record in the dense page directory.
+@return dense directory slot, or NULL if record not found */
UNIV_INLINE
byte*
page_zip_dir_find(
/*==============*/
- /* out: dense directory slot,
- or NULL if record not found */
- page_zip_des_t* page_zip, /* in: compressed page */
- ulint offset) /* in: offset of user record */
+ page_zip_des_t* page_zip, /*!< in: compressed page */
+ ulint offset) /*!< in: offset of user record */
{
byte* end = page_zip->data + page_zip_get_size(page_zip);
@@ -210,16 +223,15 @@ page_zip_dir_find(
offset));
}
-/*****************************************************************
-Find the slot of the given free record in the dense page directory. */
+/*************************************************************//**
+Find the slot of the given free record in the dense page directory.
+@return dense directory slot, or NULL if record not found */
UNIV_INLINE
byte*
page_zip_dir_find_free(
/*===================*/
- /* out: dense directory slot,
- or NULL if record not found */
- page_zip_des_t* page_zip, /* in: compressed page */
- ulint offset) /* in: offset of user record */
+ page_zip_des_t* page_zip, /*!< in: compressed page */
+ ulint offset) /*!< in: offset of user record */
{
byte* end = page_zip->data + page_zip_get_size(page_zip);
@@ -230,19 +242,16 @@ page_zip_dir_find_free(
offset));
}
-/*****************************************************************
-Read a given slot in the dense page directory. */
+/*************************************************************//**
+Read a given slot in the dense page directory.
+@return record offset on the uncompressed page, possibly ORed with
+PAGE_ZIP_DIR_SLOT_DEL or PAGE_ZIP_DIR_SLOT_OWNED */
UNIV_INLINE
ulint
page_zip_dir_get(
/*=============*/
- /* out: record offset
- on the uncompressed page,
- possibly ORed with
- PAGE_ZIP_DIR_SLOT_DEL or
- PAGE_ZIP_DIR_SLOT_OWNED */
- const page_zip_des_t* page_zip, /* in: compressed page */
- ulint slot) /* in: slot
+ const page_zip_des_t* page_zip, /*!< in: compressed page */
+ ulint slot) /*!< in: slot
(0=first user record) */
{
ut_ad(page_zip_simple_validate(page_zip));
@@ -251,20 +260,23 @@ page_zip_dir_get(
- PAGE_ZIP_DIR_SLOT_SIZE * (slot + 1)));
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Write a log record of compressing an index page. */
static
void
page_zip_compress_write_log(
/*========================*/
- const page_zip_des_t* page_zip,/* in: compressed page */
- const page_t* page, /* in: uncompressed page */
- dict_index_t* index, /* in: index of the B-tree node */
- mtr_t* mtr) /* in: mini-transaction */
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ const page_t* page, /*!< in: uncompressed page */
+ dict_index_t* index, /*!< in: index of the B-tree node */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
byte* log_ptr;
ulint trailer_size;
+ ut_ad(!dict_index_is_ibuf(index));
+
log_ptr = mlog_open(mtr, 11 + 2 + 2);
if (!log_ptr) {
@@ -312,19 +324,20 @@ page_zip_compress_write_log(
mlog_catenate_string(mtr, page_zip->data + page_zip_get_size(page_zip)
- trailer_size, trailer_size);
}
+#endif /* !UNIV_HOTBACKUP */
-/**********************************************************
+/******************************************************//**
Determine how many externally stored columns are contained
in existing records with smaller heap_no than rec. */
static
ulint
page_zip_get_n_prev_extern(
/*=======================*/
- const page_zip_des_t* page_zip,/* in: dense page directory on
+ const page_zip_des_t* page_zip,/*!< in: dense page directory on
compressed page */
- const rec_t* rec, /* in: compact physical record
+ const rec_t* rec, /*!< in: compact physical record
on a B-tree leaf page */
- dict_index_t* index) /* in: record descriptor */
+ dict_index_t* index) /*!< in: record descriptor */
{
const page_t* page = page_align(rec);
ulint n_ext = 0;
@@ -337,6 +350,7 @@ page_zip_get_n_prev_extern(
ut_ad(page_is_comp(page));
ut_ad(dict_table_is_comp(index->table));
ut_ad(dict_index_is_clust(index));
+ ut_ad(!dict_index_is_ibuf(index));
heap_no = rec_get_heap_no_new(rec);
ut_ad(heap_no >= PAGE_HEAP_NO_USER_LOW);
@@ -361,15 +375,15 @@ page_zip_get_n_prev_extern(
return(n_ext);
}
-/**************************************************************************
-Encode the length of a fixed-length column. */
+/**********************************************************************//**
+Encode the length of a fixed-length column.
+@return buf + length of encoded val */
static
byte*
page_zip_fixed_field_encode(
/*========================*/
- /* out: buf + length of encoded val */
- byte* buf, /* in: pointer to buffer where to write */
- ulint val) /* in: value to write */
+ byte* buf, /*!< in: pointer to buffer where to write */
+ ulint val) /*!< in: value to write */
{
ut_ad(val >= 2);
@@ -389,19 +403,19 @@ page_zip_fixed_field_encode(
return(buf);
}
-/**************************************************************************
-Write the index information for the compressed page. */
+/**********************************************************************//**
+Write the index information for the compressed page.
+@return used size of buf */
static
ulint
page_zip_fields_encode(
/*===================*/
- /* out: used size of buf */
- ulint n, /* in: number of fields to compress */
- dict_index_t* index, /* in: index comprising at least n fields */
- ulint trx_id_pos,/* in: position of the trx_id column
+ ulint n, /*!< in: number of fields to compress */
+ dict_index_t* index, /*!< in: index comprising at least n fields */
+ ulint trx_id_pos,/*!< in: position of the trx_id column
in the index, or ULINT_UNDEFINED if
this is a non-leaf page */
- byte* buf) /* out: buffer of (n + 1) * 2 bytes */
+ byte* buf) /*!< out: buffer of (n + 1) * 2 bytes */
{
const byte* buf_start = buf;
ulint i;
@@ -517,16 +531,16 @@ page_zip_fields_encode(
return((ulint) (buf - buf_start));
}
-/**************************************************************************
+/**********************************************************************//**
Populate the dense page directory from the sparse directory. */
static
void
page_zip_dir_encode(
/*================*/
- const page_t* page, /* in: compact page */
- byte* buf, /* in: pointer to dense page directory[-1];
+ const page_t* page, /*!< in: compact page */
+ byte* buf, /*!< in: pointer to dense page directory[-1];
out: dense directory on compressed page */
- const rec_t** recs) /* in: pointer to an array of 0, or NULL;
+ const rec_t** recs) /*!< in: pointer to an array of 0, or NULL;
out: dense page directory sorted by ascending
address (and heap_no) */
{
@@ -633,38 +647,38 @@ page_zip_dir_encode(
ut_a(i + PAGE_HEAP_NO_USER_LOW == n_heap);
}
-/**************************************************************************
+/**********************************************************************//**
Allocate memory for zlib. */
static
void*
page_zip_malloc(
/*============*/
- void* opaque,
- uInt items,
- uInt size)
+ void* opaque, /*!< in/out: memory heap */
+ uInt items, /*!< in: number of items to allocate */
+ uInt size) /*!< in: size of an item in bytes */
{
return(mem_heap_alloc(opaque, items * size));
}
-/**************************************************************************
+/**********************************************************************//**
Deallocate memory for zlib. */
static
void
page_zip_free(
/*==========*/
- void* opaque __attribute__((unused)),
- void* address __attribute__((unused)))
+ void* opaque __attribute__((unused)), /*!< in: memory heap */
+ void* address __attribute__((unused)))/*!< in: object to free */
{
}
-/**************************************************************************
+/**********************************************************************//**
Configure the zlib allocator to use the given memory heap. */
UNIV_INTERN
void
page_zip_set_alloc(
/*===============*/
- void* stream, /* in/out: zlib stream */
- mem_heap_t* heap) /* in: memory heap to use */
+ void* stream, /*!< in/out: zlib stream */
+ mem_heap_t* heap) /*!< in: memory heap to use */
{
z_stream* strm = stream;
@@ -674,28 +688,30 @@ page_zip_set_alloc(
}
#if 0 || defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
+/** Symbol for enabling compression and decompression diagnostics */
# define PAGE_ZIP_COMPRESS_DBG
#endif
#ifdef PAGE_ZIP_COMPRESS_DBG
-/* Set this variable in a debugger to enable
+/** Set this variable in a debugger to enable
excessive logging in page_zip_compress(). */
UNIV_INTERN ibool page_zip_compress_dbg;
-/* Set this variable in a debugger to enable
+/** Set this variable in a debugger to enable
binary logging of the data passed to deflate().
When this variable is nonzero, it will act
as a log file name generator. */
UNIV_INTERN unsigned page_zip_compress_log;
-/**************************************************************************
-Wrapper for deflate(). Log the operation if page_zip_compress_dbg is set. */
+/**********************************************************************//**
+Wrapper for deflate(). Log the operation if page_zip_compress_dbg is set.
+@return deflate() status: Z_OK, Z_BUF_ERROR, ... */
static
-ibool
+int
page_zip_compress_deflate(
/*======================*/
- FILE* logfile,/* in: log file, or NULL */
- z_streamp strm, /* in/out: compressed stream for deflate() */
- int flush) /* in: deflate() flushing method */
+ FILE* logfile,/*!< in: log file, or NULL */
+ z_streamp strm, /*!< in/out: compressed stream for deflate() */
+ int flush) /*!< in: deflate() flushing method */
{
int status;
if (UNIV_UNLIKELY(page_zip_compress_dbg)) {
@@ -713,29 +729,38 @@ page_zip_compress_deflate(
/* Redefine deflate(). */
# undef deflate
+/** Debug wrapper for the zlib compression routine deflate().
+Log the operation if page_zip_compress_dbg is set.
+@param strm in/out: compressed stream
+@param flush in: flushing method
+@return deflate() status: Z_OK, Z_BUF_ERROR, ... */
# define deflate(strm, flush) page_zip_compress_deflate(logfile, strm, flush)
+/** Declaration of the logfile parameter */
# define FILE_LOGFILE FILE* logfile,
+/** The logfile parameter */
# define LOGFILE logfile,
#else /* PAGE_ZIP_COMPRESS_DBG */
+/** Empty declaration of the logfile parameter */
# define FILE_LOGFILE
+/** Missing logfile parameter */
# define LOGFILE
#endif /* PAGE_ZIP_COMPRESS_DBG */
-/**************************************************************************
-Compress the records of a node pointer page. */
+/**********************************************************************//**
+Compress the records of a node pointer page.
+@return Z_OK, or a zlib error code */
static
int
page_zip_compress_node_ptrs(
/*========================*/
- /* out: Z_OK, or a zlib error code */
FILE_LOGFILE
- z_stream* c_stream, /* in/out: compressed page stream */
- const rec_t** recs, /* in: dense page directory
+ z_stream* c_stream, /*!< in/out: compressed page stream */
+ const rec_t** recs, /*!< in: dense page directory
sorted by address */
- ulint n_dense, /* in: size of recs[] */
- dict_index_t* index, /* in: the index of the page */
- byte* storage, /* in: end of dense page directory */
- mem_heap_t* heap) /* in: temporary memory heap */
+ ulint n_dense, /*!< in: size of recs[] */
+ dict_index_t* index, /*!< in: the index of the page */
+ byte* storage, /*!< in: end of dense page directory */
+ mem_heap_t* heap) /*!< in: temporary memory heap */
{
int err = Z_OK;
ulint* offsets = NULL;
@@ -786,18 +811,18 @@ page_zip_compress_node_ptrs(
return(err);
}
-/**************************************************************************
-Compress the records of a leaf node of a secondary index. */
+/**********************************************************************//**
+Compress the records of a leaf node of a secondary index.
+@return Z_OK, or a zlib error code */
static
int
page_zip_compress_sec(
/*==================*/
- /* out: Z_OK, or a zlib error code */
FILE_LOGFILE
- z_stream* c_stream, /* in/out: compressed page stream */
- const rec_t** recs, /* in: dense page directory
+ z_stream* c_stream, /*!< in/out: compressed page stream */
+ const rec_t** recs, /*!< in: dense page directory
sorted by address */
- ulint n_dense) /* in: size of recs[] */
+ ulint n_dense) /*!< in: size of recs[] */
{
int err = Z_OK;
@@ -830,25 +855,25 @@ page_zip_compress_sec(
return(err);
}
-/**************************************************************************
+/**********************************************************************//**
Compress a record of a leaf node of a clustered index that contains
-externally stored columns. */
+externally stored columns.
+@return Z_OK, or a zlib error code */
static
int
page_zip_compress_clust_ext(
/*========================*/
- /* out: Z_OK, or a zlib error code */
FILE_LOGFILE
- z_stream* c_stream, /* in/out: compressed page stream */
- const rec_t* rec, /* in: record */
- const ulint* offsets, /* in: rec_get_offsets(rec) */
- ulint trx_id_col, /* in: position of of DB_TRX_ID */
- byte* deleted, /* in: dense directory entry pointing
+ z_stream* c_stream, /*!< in/out: compressed page stream */
+ const rec_t* rec, /*!< in: record */
+ const ulint* offsets, /*!< in: rec_get_offsets(rec) */
+ ulint trx_id_col, /*!< in: position of of DB_TRX_ID */
+ byte* deleted, /*!< in: dense directory entry pointing
to the head of the free list */
- byte* storage, /* in: end of dense page directory */
- byte** externs, /* in/out: pointer to the next
+ byte* storage, /*!< in: end of dense page directory */
+ byte** externs, /*!< in/out: pointer to the next
available BLOB pointer */
- ulint* n_blobs) /* in/out: number of
+ ulint* n_blobs) /*!< in/out: number of
externally stored columns */
{
int err;
@@ -958,26 +983,26 @@ page_zip_compress_clust_ext(
return(Z_OK);
}
-/**************************************************************************
-Compress the records of a leaf node of a clustered index. */
+/**********************************************************************//**
+Compress the records of a leaf node of a clustered index.
+@return Z_OK, or a zlib error code */
static
int
page_zip_compress_clust(
/*====================*/
- /* out: Z_OK, or a zlib error code */
FILE_LOGFILE
- z_stream* c_stream, /* in/out: compressed page stream */
- const rec_t** recs, /* in: dense page directory
+ z_stream* c_stream, /*!< in/out: compressed page stream */
+ const rec_t** recs, /*!< in: dense page directory
sorted by address */
- ulint n_dense, /* in: size of recs[] */
- dict_index_t* index, /* in: the index of the page */
- ulint* n_blobs, /* in: 0; out: number of
+ ulint n_dense, /*!< in: size of recs[] */
+ dict_index_t* index, /*!< in: the index of the page */
+ ulint* n_blobs, /*!< in: 0; out: number of
externally stored columns */
- ulint trx_id_col, /* index of the trx_id column */
- byte* deleted, /* in: dense directory entry pointing
+ ulint trx_id_col, /*!< index of the trx_id column */
+ byte* deleted, /*!< in: dense directory entry pointing
to the head of the free list */
- byte* storage, /* in: end of dense page directory */
- mem_heap_t* heap) /* in: temporary memory heap */
+ byte* storage, /*!< in: end of dense page directory */
+ mem_heap_t* heap) /*!< in: temporary memory heap */
{
int err = Z_OK;
ulint* offsets = NULL;
@@ -1091,29 +1116,29 @@ func_exit:
return(err);
}
-/**************************************************************************
-Compress a page. */
+/**********************************************************************//**
+Compress a page.
+@return TRUE on success, FALSE on failure; page_zip will be left
+intact on failure. */
UNIV_INTERN
ibool
page_zip_compress(
/*==============*/
- /* out: TRUE on success, FALSE on failure;
- page_zip will be left intact on failure. */
- page_zip_des_t* page_zip,/* in: size; out: data, n_blobs,
+ page_zip_des_t* page_zip,/*!< in: size; out: data, n_blobs,
m_start, m_end, m_nonempty */
- 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 */
+ 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 */
{
z_stream c_stream;
int err;
ulint n_fields;/* number of index fields needed */
- byte* fields; /* index field information */
- byte* buf; /* compressed payload of the page */
+ byte* fields; /*!< index field information */
+ byte* buf; /*!< compressed payload of the page */
byte* buf_end;/* end of buf */
ulint n_dense;
ulint slot_size;/* amount of uncompressed bytes per record */
- const rec_t** recs; /* dense page directory, sorted by address */
+ const rec_t** recs; /*!< dense page directory, sorted by address */
mem_heap_t* heap;
ulint trx_id_col;
ulint* offsets = NULL;
@@ -1128,6 +1153,8 @@ page_zip_compress(
ut_a(fil_page_get_type(page) == FIL_PAGE_INDEX);
ut_ad(page_simple_validate_new((page_t*) page));
ut_ad(page_zip_simple_validate(page_zip));
+ ut_ad(dict_table_is_comp(index->table));
+ ut_ad(!dict_index_is_ibuf(index));
UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
@@ -1360,7 +1387,9 @@ err_exit:
#endif /* UNIV_ZIP_DEBUG */
if (mtr) {
+#ifndef UNIV_HOTBACKUP
page_zip_compress_write_log(page_zip, page, index, mtr);
+#endif /* !UNIV_HOTBACKUP */
}
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
@@ -1385,41 +1414,41 @@ err_exit:
return(TRUE);
}
-/**************************************************************************
-Compare two page directory entries. */
+/**********************************************************************//**
+Compare two page directory entries.
+@return positive if rec1 > rec2 */
UNIV_INLINE
ibool
page_zip_dir_cmp(
/*=============*/
- /* out: positive if rec1 > rec2 */
- const rec_t* rec1, /* in: rec1 */
- const rec_t* rec2) /* in: rec2 */
+ const rec_t* rec1, /*!< in: rec1 */
+ const rec_t* rec2) /*!< in: rec2 */
{
return(rec1 > rec2);
}
-/**************************************************************************
+/**********************************************************************//**
Sort the dense page directory by address (heap_no). */
static
void
page_zip_dir_sort(
/*==============*/
- rec_t** arr, /* in/out: dense page directory */
- rec_t** aux_arr,/* in/out: work area */
- ulint low, /* in: lower bound of the sorting area, inclusive */
- ulint high) /* in: upper bound of the sorting area, exclusive */
+ rec_t** arr, /*!< in/out: dense page directory */
+ rec_t** aux_arr,/*!< in/out: work area */
+ ulint low, /*!< in: lower bound of the sorting area, inclusive */
+ ulint high) /*!< in: upper bound of the sorting area, exclusive */
{
UT_SORT_FUNCTION_BODY(page_zip_dir_sort, arr, aux_arr, low, high,
page_zip_dir_cmp);
}
-/**************************************************************************
+/**********************************************************************//**
Deallocate the index information initialized by page_zip_fields_decode(). */
static
void
page_zip_fields_free(
/*=================*/
- dict_index_t* index) /* in: dummy index to be freed */
+ dict_index_t* index) /*!< in: dummy index to be freed */
{
if (index) {
dict_table_t* table = index->table;
@@ -1429,17 +1458,16 @@ page_zip_fields_free(
}
}
-/**************************************************************************
-Read the index information for the compressed page. */
+/**********************************************************************//**
+Read the index information for the compressed page.
+@return own: dummy index describing the page, or NULL on error */
static
dict_index_t*
page_zip_fields_decode(
/*===================*/
- /* out,own: dummy index describing the page,
- or NULL on error */
- const byte* buf, /* in: index information */
- const byte* end, /* in: end of buf */
- ulint* trx_id_col)/* in: NULL for non-leaf pages;
+ const byte* buf, /*!< in: index information */
+ const byte* end, /*!< in: end of buf */
+ ulint* trx_id_col)/*!< in: NULL for non-leaf pages;
for leaf pages, pointer to where to store
the position of the trx_id column */
{
@@ -1546,23 +1574,22 @@ page_zip_fields_decode(
return(index);
}
-/**************************************************************************
-Populate the sparse page directory from the dense directory. */
+/**********************************************************************//**
+Populate the sparse page directory from the dense directory.
+@return TRUE on success, FALSE on failure */
static
ibool
page_zip_dir_decode(
/*================*/
- /* out: TRUE on success,
- FALSE on failure */
- const page_zip_des_t* page_zip,/* in: dense page directory on
+ const page_zip_des_t* page_zip,/*!< in: dense page directory on
compressed page */
- page_t* page, /* in: compact page with valid header;
+ page_t* page, /*!< in: compact page with valid header;
out: trailer and sparse page directory
filled in */
- rec_t** recs, /* out: dense page directory sorted by
+ rec_t** recs, /*!< out: dense page directory sorted by
ascending address (and heap_no) */
- rec_t** recs_aux,/* in/out: scratch area */
- ulint n_dense)/* in: number of user records, and
+ rec_t** recs_aux,/*!< in/out: scratch area */
+ ulint n_dense)/*!< in: number of user records, and
size of recs[] and recs_aux[] */
{
ulint i;
@@ -1644,17 +1671,16 @@ page_zip_dir_decode(
return(TRUE);
}
-/**************************************************************************
-Initialize the REC_N_NEW_EXTRA_BYTES of each record. */
+/**********************************************************************//**
+Initialize the REC_N_NEW_EXTRA_BYTES of each record.
+@return TRUE on success, FALSE on failure */
static
ibool
page_zip_set_extra_bytes(
/*=====================*/
- /* out: TRUE on success,
- FALSE on failure */
- const page_zip_des_t* page_zip,/* in: compressed page */
- page_t* page, /* in/out: uncompressed page */
- ulint info_bits)/* in: REC_INFO_MIN_REC_FLAG or 0 */
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ page_t* page, /*!< in/out: uncompressed page */
+ ulint info_bits)/*!< in: REC_INFO_MIN_REC_FLAG or 0 */
{
ulint n;
ulint i;
@@ -1742,20 +1768,19 @@ page_zip_set_extra_bytes(
return(TRUE);
}
-/**************************************************************************
+/**********************************************************************//**
Apply the modification log to a record containing externally stored
-columns. Do not copy the fields that are stored separately. */
+columns. Do not copy the fields that are stored separately.
+@return pointer to modification log, or NULL on failure */
static
const byte*
page_zip_apply_log_ext(
/*===================*/
- /* out: pointer to modification log,
- or NULL on failure */
- rec_t* rec, /* in/out: record */
- const ulint* offsets, /* in: rec_get_offsets(rec) */
- ulint trx_id_col, /* in: position of of DB_TRX_ID */
- const byte* data, /* in: modification log */
- const byte* end) /* in: end of modification log */
+ rec_t* rec, /*!< in/out: record */
+ const ulint* offsets, /*!< in: rec_get_offsets(rec) */
+ ulint trx_id_col, /*!< in: position of of DB_TRX_ID */
+ const byte* data, /*!< in: modification log */
+ const byte* end) /*!< in: end of modification log */
{
ulint i;
ulint len;
@@ -1832,28 +1857,27 @@ page_zip_apply_log_ext(
return(data);
}
-/**************************************************************************
+/**********************************************************************//**
Apply the modification log to an uncompressed page.
-Do not copy the fields that are stored separately. */
+Do not copy the fields that are stored separately.
+@return pointer to end of modification log, or NULL on failure */
static
const byte*
page_zip_apply_log(
/*===============*/
- /* out: pointer to end of modification log,
- or NULL on failure */
- const byte* data, /* in: modification log */
- ulint size, /* in: maximum length of the log, in bytes */
- rec_t** recs, /* in: dense page directory,
+ const byte* data, /*!< in: modification log */
+ ulint size, /*!< in: maximum length of the log, in bytes */
+ rec_t** recs, /*!< in: dense page directory,
sorted by address (indexed by
heap_no - PAGE_HEAP_NO_USER_LOW) */
- ulint n_dense,/* in: size of recs[] */
- ulint trx_id_col,/* in: column number of trx_id in the index,
+ ulint n_dense,/*!< in: size of recs[] */
+ ulint trx_id_col,/*!< in: column number of trx_id in the index,
or ULINT_UNDEFINED if none */
ulint heap_status,
- /* in: heap_no and status bits for
+ /*!< in: heap_no and status bits for
the next record to uncompress */
- dict_index_t* index, /* in: index of the page */
- ulint* offsets)/* in/out: work area for
+ dict_index_t* index, /*!< in: index of the page */
+ ulint* offsets)/*!< in/out: work area for
rec_get_offsets_reverse() */
{
const byte* const end = data + size;
@@ -2034,22 +2058,21 @@ page_zip_apply_log(
}
}
-/**************************************************************************
-Decompress the records of a node pointer page. */
+/**********************************************************************//**
+Decompress the records of a node pointer page.
+@return TRUE on success, FALSE on failure */
static
ibool
page_zip_decompress_node_ptrs(
/*==========================*/
- /* out: TRUE on success,
- FALSE on failure */
- page_zip_des_t* page_zip, /* in/out: compressed page */
- z_stream* d_stream, /* in/out: compressed page stream */
- rec_t** recs, /* in: dense page directory
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ z_stream* d_stream, /*!< in/out: compressed page stream */
+ rec_t** recs, /*!< in: dense page directory
sorted by address */
- ulint n_dense, /* in: size of recs[] */
- dict_index_t* index, /* in: the index of the page */
- ulint* offsets, /* in/out: temporary offsets */
- mem_heap_t* heap) /* in: temporary memory heap */
+ ulint n_dense, /*!< in: size of recs[] */
+ dict_index_t* index, /*!< in: the index of the page */
+ ulint* offsets, /*!< in/out: temporary offsets */
+ mem_heap_t* heap) /*!< in: temporary memory heap */
{
ulint heap_status = REC_STATUS_NODE_PTR
| PAGE_HEAP_NO_USER_LOW << REC_HEAP_NO_SHIFT;
@@ -2228,21 +2251,20 @@ zlib_done:
return(TRUE);
}
-/**************************************************************************
-Decompress the records of a leaf node of a secondary index. */
+/**********************************************************************//**
+Decompress the records of a leaf node of a secondary index.
+@return TRUE on success, FALSE on failure */
static
ibool
page_zip_decompress_sec(
/*====================*/
- /* out: TRUE on success,
- FALSE on failure */
- page_zip_des_t* page_zip, /* in/out: compressed page */
- z_stream* d_stream, /* in/out: compressed page stream */
- rec_t** recs, /* in: dense page directory
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ z_stream* d_stream, /*!< in/out: compressed page stream */
+ rec_t** recs, /*!< in: dense page directory
sorted by address */
- ulint n_dense, /* in: size of recs[] */
- dict_index_t* index, /* in: the index of the page */
- ulint* offsets) /* in/out: temporary offsets */
+ ulint n_dense, /*!< in: size of recs[] */
+ dict_index_t* index, /*!< in: the index of the page */
+ ulint* offsets) /*!< in/out: temporary offsets */
{
ulint heap_status = REC_STATUS_ORDINARY
| PAGE_HEAP_NO_USER_LOW << REC_HEAP_NO_SHIFT;
@@ -2370,18 +2392,18 @@ zlib_done:
return(TRUE);
}
-/**************************************************************************
+/**********************************************************************//**
Decompress a record of a leaf node of a clustered index that contains
-externally stored columns. */
+externally stored columns.
+@return TRUE on success */
static
ibool
page_zip_decompress_clust_ext(
/*==========================*/
- /* out: TRUE on success */
- z_stream* d_stream, /* in/out: compressed page stream */
- rec_t* rec, /* in/out: record */
- const ulint* offsets, /* in: rec_get_offsets(rec) */
- ulint trx_id_col) /* in: position of of DB_TRX_ID */
+ z_stream* d_stream, /*!< in/out: compressed page stream */
+ rec_t* rec, /*!< in/out: record */
+ const ulint* offsets, /*!< in: rec_get_offsets(rec) */
+ ulint trx_id_col) /*!< in: position of of DB_TRX_ID */
{
ulint i;
@@ -2479,23 +2501,22 @@ page_zip_decompress_clust_ext(
return(TRUE);
}
-/**************************************************************************
-Compress the records of a leaf node of a clustered index. */
+/**********************************************************************//**
+Compress the records of a leaf node of a clustered index.
+@return TRUE on success, FALSE on failure */
static
ibool
page_zip_decompress_clust(
/*======================*/
- /* out: TRUE on success,
- FALSE on failure */
- page_zip_des_t* page_zip, /* in/out: compressed page */
- z_stream* d_stream, /* in/out: compressed page stream */
- rec_t** recs, /* in: dense page directory
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ z_stream* d_stream, /*!< in/out: compressed page stream */
+ rec_t** recs, /*!< in: dense page directory
sorted by address */
- ulint n_dense, /* in: size of recs[] */
- dict_index_t* index, /* in: the index of the page */
- ulint trx_id_col, /* index of the trx_id column */
- ulint* offsets, /* in/out: temporary offsets */
- mem_heap_t* heap) /* in: temporary memory heap */
+ ulint n_dense, /*!< in: size of recs[] */
+ dict_index_t* index, /*!< in: the index of the page */
+ ulint trx_id_col, /*!< index of the trx_id column */
+ ulint* offsets, /*!< in/out: temporary offsets */
+ mem_heap_t* heap) /*!< in: temporary memory heap */
{
int err;
ulint slot;
@@ -2779,22 +2800,22 @@ zlib_done:
return(TRUE);
}
-/**************************************************************************
+/**********************************************************************//**
Decompress a page. This function should tolerate errors on the compressed
page. Instead of letting assertions fail, it will return FALSE if an
-inconsistency is detected. */
+inconsistency is detected.
+@return TRUE on success, FALSE on failure */
UNIV_INTERN
ibool
page_zip_decompress(
/*================*/
- /* out: TRUE on success, FALSE on failure */
- page_zip_des_t* page_zip,/* in: data, ssize;
+ page_zip_des_t* page_zip,/*!< in: data, ssize;
out: m_start, m_end, m_nonempty, n_blobs */
- page_t* page) /* out: uncompressed page, may be trashed */
+ page_t* page) /*!< out: uncompressed page, may be trashed */
{
z_stream d_stream;
dict_index_t* index = NULL;
- rec_t** recs; /* dense page directory, sorted by address */
+ rec_t** recs; /*!< dense page directory, sorted by address */
ulint n_dense;/* number of user records on the page */
ulint trx_id_col = ULINT_UNDEFINED;
mem_heap_t* heap;
@@ -2969,15 +2990,15 @@ err_exit:
}
#ifdef UNIV_ZIP_DEBUG
-/**************************************************************************
+/**********************************************************************//**
Dump a block of memory on the standard error stream. */
static
void
page_zip_hexdump_func(
/*==================*/
- const char* name, /* in: name of the data structure */
- const void* buf, /* in: data */
- ulint size) /* in: length of the data, in bytes */
+ const char* name, /*!< in: name of the data structure */
+ const void* buf, /*!< in: data */
+ ulint size) /*!< in: length of the data, in bytes */
{
const byte* s = buf;
ulint addr;
@@ -3000,21 +3021,24 @@ page_zip_hexdump_func(
}
}
+/** Dump a block of memory on the standard error stream.
+@param buf in: data
+@param size in: length of the data, in bytes */
#define page_zip_hexdump(buf, size) page_zip_hexdump_func(#buf, buf, size)
-/* Flag: make page_zip_validate() compare page headers only */
+/** Flag: make page_zip_validate() compare page headers only */
UNIV_INTERN ibool page_zip_validate_header_only = FALSE;
-/**************************************************************************
-Check that the compressed and decompressed pages match. */
+/**********************************************************************//**
+Check that the compressed and decompressed pages match.
+@return TRUE if valid, FALSE if not */
UNIV_INTERN
ibool
page_zip_validate_low(
/*==================*/
- /* out: TRUE if valid, FALSE if not */
- const page_zip_des_t* page_zip,/* in: compressed page */
- const page_t* page, /* in: uncompressed page */
- ibool sloppy) /* in: FALSE=strict,
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ const page_t* page, /*!< in: uncompressed page */
+ ibool sloppy) /*!< in: FALSE=strict,
TRUE=ignore the MIN_REC_FLAG */
{
page_zip_des_t temp_page_zip;
@@ -3142,15 +3166,15 @@ func_exit:
return(valid);
}
-/**************************************************************************
-Check that the compressed and decompressed pages match. */
+/**********************************************************************//**
+Check that the compressed and decompressed pages match.
+@return TRUE if valid, FALSE if not */
UNIV_INTERN
ibool
page_zip_validate(
/*==============*/
- /* out: TRUE if valid, FALSE if not */
- const page_zip_des_t* page_zip,/* in: compressed page */
- const page_t* page) /* in: uncompressed page */
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ const page_t* page) /*!< in: uncompressed page */
{
return(page_zip_validate_low(page_zip, page,
recv_recovery_is_on()));
@@ -3158,13 +3182,15 @@ page_zip_validate(
#endif /* UNIV_ZIP_DEBUG */
#ifdef UNIV_DEBUG
+/**********************************************************************//**
+Assert that the compressed and decompressed page headers match.
+@return TRUE */
static
ibool
page_zip_header_cmp(
/*================*/
- /* out: TRUE */
- const page_zip_des_t* page_zip,/* in: compressed page */
- const byte* page) /* in: uncompressed page */
+ const page_zip_des_t* page_zip,/*!< in: compressed page */
+ const byte* page) /*!< in: uncompressed page */
{
ut_ad(!memcmp(page_zip->data + FIL_PAGE_PREV, page + FIL_PAGE_PREV,
FIL_PAGE_LSN - FIL_PAGE_PREV));
@@ -3177,24 +3203,24 @@ page_zip_header_cmp(
}
#endif /* UNIV_DEBUG */
-/**************************************************************************
+/**********************************************************************//**
Write a record on the compressed page that contains externally stored
-columns. The data must already have been written to the uncompressed page. */
+columns. The data must already have been written to the uncompressed page.
+@return end of modification log */
static
byte*
page_zip_write_rec_ext(
/*===================*/
- /* out: end of modification log */
- page_zip_des_t* page_zip, /* in/out: compressed page */
- const page_t* page, /* in: page containing rec */
- const byte* rec, /* in: record being written */
- dict_index_t* index, /* in: record descriptor */
- const ulint* offsets, /* in: rec_get_offsets(rec, index) */
- ulint create, /* in: nonzero=insert, zero=update */
- ulint trx_id_col, /* in: position of DB_TRX_ID */
- ulint heap_no, /* in: heap number of rec */
- byte* storage, /* in: end of dense page directory */
- byte* data) /* in: end of modification log */
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ const page_t* page, /*!< in: page containing rec */
+ const byte* rec, /*!< in: record being written */
+ dict_index_t* index, /*!< in: record descriptor */
+ const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */
+ ulint create, /*!< in: nonzero=insert, zero=update */
+ ulint trx_id_col, /*!< in: position of DB_TRX_ID */
+ ulint heap_no, /*!< in: heap number of rec */
+ byte* storage, /*!< in: end of dense page directory */
+ byte* data) /*!< in: end of modification log */
{
const byte* start = rec;
ulint i;
@@ -3299,18 +3325,18 @@ page_zip_write_rec_ext(
return(data);
}
-/**************************************************************************
+/**********************************************************************//**
Write an entire record on the compressed page. The data must already
have been written to the uncompressed page. */
UNIV_INTERN
void
page_zip_write_rec(
/*===============*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in: record being written */
- dict_index_t* index, /* in: the index the record belongs to */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- ulint create) /* in: nonzero=insert, zero=update */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in: record being written */
+ dict_index_t* index, /*!< in: the index the record belongs to */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ ulint create) /*!< in: nonzero=insert, zero=update */
{
const page_t* page;
byte* data;
@@ -3318,7 +3344,7 @@ page_zip_write_rec(
ulint heap_no;
byte* slot;
- ut_ad(buf_frame_get_page_zip(rec) == page_zip);
+ ut_ad(PAGE_ZIP_MATCH(rec, page_zip));
ut_ad(page_zip_simple_validate(page_zip));
ut_ad(page_zip_get_size(page_zip)
> PAGE_DATA + page_zip_dir_size(page_zip));
@@ -3487,17 +3513,17 @@ page_zip_write_rec(
#endif /* UNIV_ZIP_DEBUG */
}
-/***************************************************************
-Parses a log record of writing a BLOB pointer of a record. */
+/***********************************************************//**
+Parses a log record of writing a BLOB pointer of a record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_write_blob_ptr(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: redo log buffer */
- byte* end_ptr,/* in: redo log buffer end */
- page_t* page, /* in/out: uncompressed page */
- page_zip_des_t* page_zip)/* in/out: compressed page */
+ byte* ptr, /*!< in: redo log buffer */
+ byte* end_ptr,/*!< in: redo log buffer end */
+ page_t* page, /*!< in/out: uncompressed page */
+ page_zip_des_t* page_zip)/*!< in/out: compressed page */
{
ulint offset;
ulint z_offset;
@@ -3546,20 +3572,20 @@ corrupt:
return(ptr + (2 + 2 + BTR_EXTERN_FIELD_REF_SIZE));
}
-/**************************************************************************
+/**********************************************************************//**
Write a BLOB pointer of a record on the leaf page of a clustered index.
The information must already have been updated on the uncompressed page. */
UNIV_INTERN
void
page_zip_write_blob_ptr(
/*====================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in/out: record whose data is being
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in/out: record whose data is being
written */
- dict_index_t* index, /* in: index of the page */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- ulint n, /* in: column index */
- mtr_t* mtr) /* in: mini-transaction handle,
+ dict_index_t* index, /*!< in: index of the page */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ ulint n, /*!< in: column index */
+ mtr_t* mtr) /*!< in: mini-transaction handle,
or NULL if no logging is needed */
{
const byte* field;
@@ -3568,7 +3594,7 @@ page_zip_write_blob_ptr(
ulint blob_no;
ulint len;
- ut_ad(buf_frame_get_page_zip(rec) == page_zip);
+ ut_ad(PAGE_ZIP_MATCH(rec, page_zip));
ut_ad(page_simple_validate_new((page_t*) page));
ut_ad(page_zip_simple_validate(page_zip));
ut_ad(page_zip_get_size(page_zip)
@@ -3610,6 +3636,7 @@ page_zip_write_blob_ptr(
#endif /* UNIV_ZIP_DEBUG */
if (mtr) {
+#ifndef UNIV_HOTBACKUP
byte* log_ptr = mlog_open(
mtr, 11 + 2 + 2 + BTR_EXTERN_FIELD_REF_SIZE);
if (UNIV_UNLIKELY(!log_ptr)) {
@@ -3625,20 +3652,21 @@ page_zip_write_blob_ptr(
memcpy(log_ptr, externs, BTR_EXTERN_FIELD_REF_SIZE);
log_ptr += BTR_EXTERN_FIELD_REF_SIZE;
mlog_close(mtr, log_ptr);
+#endif /* !UNIV_HOTBACKUP */
}
}
-/***************************************************************
-Parses a log record of writing the node pointer of a record. */
+/***********************************************************//**
+Parses a log record of writing the node pointer of a record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_write_node_ptr(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: redo log buffer */
- byte* end_ptr,/* in: redo log buffer end */
- page_t* page, /* in/out: uncompressed page */
- page_zip_des_t* page_zip)/* in/out: compressed page */
+ byte* ptr, /*!< in: redo log buffer */
+ byte* end_ptr,/*!< in: redo log buffer end */
+ page_t* page, /*!< in/out: uncompressed page */
+ page_zip_des_t* page_zip)/*!< in/out: compressed page */
{
ulint offset;
ulint z_offset;
@@ -3705,23 +3733,23 @@ corrupt:
return(ptr + (2 + 2 + REC_NODE_PTR_SIZE));
}
-/**************************************************************************
+/**********************************************************************//**
Write the node pointer of a record on a non-leaf compressed page. */
UNIV_INTERN
void
page_zip_write_node_ptr(
/*====================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- byte* rec, /* in/out: record */
- ulint size, /* in: data size of rec */
- ulint ptr, /* in: node pointer */
- mtr_t* mtr) /* in: mini-transaction, or NULL */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ byte* rec, /*!< in/out: record */
+ ulint size, /*!< in: data size of rec */
+ ulint ptr, /*!< in: node pointer */
+ mtr_t* mtr) /*!< in: mini-transaction, or NULL */
{
byte* field;
byte* storage;
page_t* page = page_align(rec);
- ut_ad(buf_frame_get_page_zip(rec) == page_zip);
+ ut_ad(PAGE_ZIP_MATCH(rec, page_zip));
ut_ad(page_simple_validate_new(page));
ut_ad(page_zip_simple_validate(page_zip));
ut_ad(page_zip_get_size(page_zip)
@@ -3752,6 +3780,7 @@ page_zip_write_node_ptr(
memcpy(storage, field, REC_NODE_PTR_SIZE);
if (mtr) {
+#ifndef UNIV_HOTBACKUP
byte* log_ptr = mlog_open(mtr,
11 + 2 + 2 + REC_NODE_PTR_SIZE);
if (UNIV_UNLIKELY(!log_ptr)) {
@@ -3767,28 +3796,29 @@ page_zip_write_node_ptr(
memcpy(log_ptr, field, REC_NODE_PTR_SIZE);
log_ptr += REC_NODE_PTR_SIZE;
mlog_close(mtr, log_ptr);
+#endif /* !UNIV_HOTBACKUP */
}
}
-/**************************************************************************
+/**********************************************************************//**
Write the trx_id and roll_ptr of a record on a B-tree leaf node page. */
UNIV_INTERN
void
page_zip_write_trx_id_and_roll_ptr(
/*===============================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- byte* rec, /* in/out: record */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- ulint trx_id_col,/* in: column number of TRX_ID in rec */
- dulint trx_id, /* in: transaction identifier */
- dulint roll_ptr)/* in: roll_ptr */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ byte* rec, /*!< in/out: record */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ ulint trx_id_col,/*!< in: column number of TRX_ID in rec */
+ trx_id_t trx_id, /*!< in: transaction identifier */
+ roll_ptr_t roll_ptr)/*!< in: roll_ptr */
{
byte* field;
byte* storage;
page_t* page = page_align(rec);
ulint len;
- ut_ad(buf_frame_get_page_zip(rec) == page_zip);
+ ut_ad(PAGE_ZIP_MATCH(rec, page_zip));
ut_ad(page_simple_validate_new(page));
ut_ad(page_zip_simple_validate(page_zip));
ut_ad(page_zip_get_size(page_zip)
@@ -3837,7 +3867,7 @@ page_zip_write_trx_id_and_roll_ptr(
}
#ifdef UNIV_ZIP_DEBUG
-/* Set this variable in a debugger to disable page_zip_clear_rec().
+/** Set this variable in a debugger to disable page_zip_clear_rec().
The only observable effect should be the compression ratio due to
deleted records not being zeroed out. In rare cases, there can be
page_zip_validate() failures on the node_ptr, trx_id and roll_ptr
@@ -3845,16 +3875,16 @@ columns if the space is reallocated for a smaller record. */
UNIV_INTERN ibool page_zip_clear_rec_disable;
#endif /* UNIV_ZIP_DEBUG */
-/**************************************************************************
+/**********************************************************************//**
Clear an area on the uncompressed and compressed page, if possible. */
static
void
page_zip_clear_rec(
/*===============*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- byte* rec, /* in: record to clear */
- dict_index_t* index, /* in: index of rec */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ byte* rec, /*!< in: record to clear */
+ dict_index_t* index, /*!< in: index of rec */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
ulint heap_no;
page_t* page = page_align(rec);
@@ -3951,16 +3981,16 @@ page_zip_clear_rec(
#endif /* UNIV_ZIP_DEBUG */
}
-/**************************************************************************
+/**********************************************************************//**
Write the "deleted" flag of a record on a compressed page. The flag must
already have been written on the uncompressed page. */
UNIV_INTERN
void
page_zip_rec_set_deleted(
/*=====================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in: record on the uncompressed page */
- ulint flag) /* in: the deleted flag (nonzero=TRUE) */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in: record on the uncompressed page */
+ ulint flag) /*!< in: the deleted flag (nonzero=TRUE) */
{
byte* slot = page_zip_dir_find(page_zip, page_offset(rec));
ut_a(slot);
@@ -3975,16 +4005,16 @@ page_zip_rec_set_deleted(
#endif /* UNIV_ZIP_DEBUG */
}
-/**************************************************************************
+/**********************************************************************//**
Write the "owned" flag of a record on a compressed page. The n_owned field
must already have been written on the uncompressed page. */
UNIV_INTERN
void
page_zip_rec_set_owned(
/*===================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* rec, /* in: record on the uncompressed page */
- ulint flag) /* in: the owned flag (nonzero=TRUE) */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* rec, /*!< in: record on the uncompressed page */
+ ulint flag) /*!< in: the owned flag (nonzero=TRUE) */
{
byte* slot = page_zip_dir_find(page_zip, page_offset(rec));
ut_a(slot);
@@ -3996,17 +4026,17 @@ page_zip_rec_set_owned(
}
}
-/**************************************************************************
+/**********************************************************************//**
Insert a record to the dense page directory. */
UNIV_INTERN
void
page_zip_dir_insert(
/*================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- const byte* prev_rec,/* in: record after which to insert */
- const byte* free_rec,/* in: record from which rec was
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ const byte* prev_rec,/*!< in: record after which to insert */
+ const byte* free_rec,/*!< in: record from which rec was
allocated, or NULL */
- byte* rec) /* in: record to insert */
+ byte* rec) /*!< in: record to insert */
{
ulint n_dense;
byte* slot_rec;
@@ -4074,18 +4104,18 @@ page_zip_dir_insert(
mach_write_to_2(slot_rec - PAGE_ZIP_DIR_SLOT_SIZE, page_offset(rec));
}
-/**************************************************************************
+/**********************************************************************//**
Shift the dense page directory and the array of BLOB pointers
when a record is deleted. */
UNIV_INTERN
void
page_zip_dir_delete(
/*================*/
- page_zip_des_t* page_zip,/* in/out: compressed page */
- byte* rec, /* in: record to delete */
- dict_index_t* index, /* in: index of rec */
- const ulint* offsets,/* in: rec_get_offsets(rec) */
- const byte* free) /* in: previous start of the free list */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page */
+ byte* rec, /*!< in: record to delete */
+ dict_index_t* index, /*!< in: index of rec */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec) */
+ const byte* free) /*!< in: previous start of the free list */
{
byte* slot_rec;
byte* slot_free;
@@ -4172,14 +4202,14 @@ skip_blobs:
page_zip_clear_rec(page_zip, rec, index, offsets);
}
-/**************************************************************************
+/**********************************************************************//**
Add a slot to the dense page directory. */
UNIV_INTERN
void
page_zip_dir_add_slot(
/*==================*/
- page_zip_des_t* page_zip, /* in/out: compressed page */
- ulint is_clustered) /* in: nonzero for clustered index,
+ page_zip_des_t* page_zip, /*!< in/out: compressed page */
+ ulint is_clustered) /*!< in: nonzero for clustered index,
zero for others */
{
ulint n_dense;
@@ -4228,17 +4258,17 @@ page_zip_dir_add_slot(
memmove(stored - PAGE_ZIP_DIR_SLOT_SIZE, stored, dir - stored);
}
-/***************************************************************
-Parses a log record of writing to the header of a page. */
+/***********************************************************//**
+Parses a log record of writing to the header of a page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_write_header(
/*========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: redo log buffer */
- byte* end_ptr,/* in: redo log buffer end */
- page_t* page, /* in/out: uncompressed page */
- page_zip_des_t* page_zip)/* in/out: compressed page */
+ byte* ptr, /*!< in: redo log buffer */
+ byte* end_ptr,/*!< in: redo log buffer end */
+ page_t* page, /*!< in/out: uncompressed page */
+ page_zip_des_t* page_zip)/*!< in/out: compressed page */
{
ulint offset;
ulint len;
@@ -4286,15 +4316,16 @@ corrupt:
return(ptr + len);
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Write a log record of writing to the uncompressed header portion of a page. */
UNIV_INTERN
void
page_zip_write_header_log(
/*======================*/
- const byte* data, /* in: data on the uncompressed page */
- ulint length, /* in: length of the data */
- mtr_t* mtr) /* in: mini-transaction */
+ const byte* data, /*!< in: data on the uncompressed page */
+ ulint length, /*!< in: length of the data */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
byte* log_ptr = mlog_open(mtr, 11 + 1 + 1);
ulint offset = page_offset(data);
@@ -4320,8 +4351,9 @@ page_zip_write_header_log(
mlog_catenate_string(mtr, data, length);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Reorganize and compress a page. This is a low-level operation for
compressed pages, to be used when page_zip_compress() fails.
On success, a redo log entry MLOG_ZIP_PAGE_COMPRESS will be written.
@@ -4329,20 +4361,19 @@ The function btr_page_reorganize() should be preferred whenever possible.
IMPORTANT: if page_zip_reorganize() is invoked on a leaf page of a
non-clustered index, the caller must update the insert buffer free
bits in the same mini-transaction in such a way that the modification
-will be redo-logged. */
+will be redo-logged.
+@return TRUE on success, FALSE on failure; page and page_zip will be
+left intact on failure. */
UNIV_INTERN
ibool
page_zip_reorganize(
/*================*/
- /* out: TRUE on success, FALSE on failure;
- page and page_zip will be left intact
- on failure. */
- buf_block_t* block, /* in/out: page with compressed page;
+ buf_block_t* block, /*!< in/out: page with compressed page;
on the compressed page, in: size;
out: data, n_blobs,
m_start, m_end, m_nonempty */
- dict_index_t* index, /* in: index of the B-tree node */
- mtr_t* mtr) /* in: mini-transaction */
+ dict_index_t* index, /*!< in: index of the B-tree node */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
page_t* page = buf_block_get_frame(block);
@@ -4352,6 +4383,7 @@ page_zip_reorganize(
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
ut_ad(page_is_comp(page));
+ ut_ad(!dict_index_is_ibuf(index));
/* Note that page_zip_validate(page_zip, page) may fail here. */
UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
@@ -4359,10 +4391,15 @@ page_zip_reorganize(
/* Disable logging */
log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
+#ifndef UNIV_HOTBACKUP
temp_block = buf_block_alloc(0);
- temp_page = temp_block->frame;
-
btr_search_drop_page_hash_index(block);
+ block->check_index_page_at_flush = TRUE;
+#else /* !UNIV_HOTBACKUP */
+ ut_ad(block == back_block1);
+ temp_block = back_block2;
+#endif /* !UNIV_HOTBACKUP */
+ temp_page = temp_block->frame;
/* Copy the old page to temporary space */
buf_frame_copy(temp_page, page);
@@ -4371,7 +4408,6 @@ page_zip_reorganize(
segment headers, next page-field, etc.) is preserved intact */
page_create(block, mtr, TRUE);
- block->check_index_page_at_flush = TRUE;
/* Copy the records from the temporary space to the recreated page;
do not copy the lock bits yet */
@@ -4379,8 +4415,13 @@ page_zip_reorganize(
page_copy_rec_list_end_no_locks(block, temp_block,
page_get_infimum_rec(temp_page),
index, mtr);
- /* Copy max trx id to recreated page */
- page_set_max_trx_id(block, NULL, page_get_max_trx_id(temp_page));
+
+ if (!dict_index_is_clust(index) && page_is_leaf(temp_page)) {
+ /* Copy max trx id to recreated page */
+ trx_id_t max_trx_id = page_get_max_trx_id(temp_page);
+ page_set_max_trx_id(block, NULL, max_trx_id, NULL);
+ ut_ad(!ut_dulint_is_zero(max_trx_id));
+ }
/* Restore logging. */
mtr_set_log_mode(mtr, log_mode);
@@ -4390,17 +4431,22 @@ page_zip_reorganize(
/* Restore the old page and exit. */
buf_frame_copy(page, temp_page);
+#ifndef UNIV_HOTBACKUP
buf_block_free(temp_block);
+#endif /* !UNIV_HOTBACKUP */
return(FALSE);
}
lock_move_reorganize_page(block, temp_block);
+#ifndef UNIV_HOTBACKUP
buf_block_free(temp_block);
+#endif /* !UNIV_HOTBACKUP */
return(TRUE);
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Copy the records of a page byte for byte. Do not copy the page header
or trailer, except those B-tree header fields that are directly
related to the storage of records. Also copy PAGE_MAX_TRX_ID.
@@ -4409,17 +4455,18 @@ UNIV_INTERN
void
page_zip_copy_recs(
/*===============*/
- page_zip_des_t* page_zip, /* out: copy of src_zip
+ page_zip_des_t* page_zip, /*!< out: copy of src_zip
(n_blobs, m_start, m_end,
m_nonempty, data[0..size-1]) */
- page_t* page, /* out: copy of src */
- const page_zip_des_t* src_zip, /* in: compressed page */
- const page_t* src, /* in: page */
- dict_index_t* index, /* in: index of the B-tree */
- mtr_t* mtr) /* in: mini-transaction */
+ page_t* page, /*!< out: copy of src */
+ const page_zip_des_t* src_zip, /*!< in: compressed page */
+ const page_t* src, /*!< in: page */
+ dict_index_t* index, /*!< in: index of the B-tree */
+ mtr_t* mtr) /*!< in: mini-transaction */
{
ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
ut_ad(mtr_memo_contains_page(mtr, (page_t*) src, MTR_MEMO_PAGE_X_FIX));
+ ut_ad(!dict_index_is_ibuf(index));
#ifdef UNIV_ZIP_DEBUG
/* The B-tree operations that call this function may set
FIL_PAGE_PREV or PAGE_LEVEL, causing a temporary min_rec_flag
@@ -4433,6 +4480,11 @@ page_zip_copy_recs(
ut_a(dict_index_is_clust(index));
}
+ /* The PAGE_MAX_TRX_ID must be set on leaf pages of secondary
+ indexes. It does not matter on other pages. */
+ ut_a(dict_index_is_clust(index) || !page_is_leaf(src)
+ || !ut_dulint_is_zero(page_get_max_trx_id(src)));
+
UNIV_MEM_ASSERT_W(page, UNIV_PAGE_SIZE);
UNIV_MEM_ASSERT_W(page_zip->data, page_zip_get_size(page_zip));
UNIV_MEM_ASSERT_RW(src, UNIV_PAGE_SIZE);
@@ -4486,18 +4538,19 @@ page_zip_copy_recs(
page_zip_compress_write_log(page_zip, page, index, mtr);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
-Parses a log record of compressing an index page. */
+/**********************************************************************//**
+Parses a log record of compressing an index page.
+@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_compress(
/*====================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* out: uncompressed page */
- page_zip_des_t* page_zip)/* out: compressed page */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< out: uncompressed page */
+ page_zip_des_t* page_zip)/*!< out: compressed page */
{
ulint size;
ulint trailer_size;
@@ -4547,15 +4600,15 @@ corrupt:
return(ptr + 8 + size + trailer_size);
}
-/**************************************************************************
-Calculate the compressed page checksum. */
+/**********************************************************************//**
+Calculate the compressed page checksum.
+@return page checksum */
UNIV_INTERN
ulint
page_zip_calc_checksum(
/*===================*/
- /* out: page checksum */
- const void* data, /* in: compressed page */
- ulint size) /* in: size of compressed page */
+ const void* data, /*!< in: compressed page */
+ ulint size) /*!< in: size of compressed page */
{
/* Exclude FIL_PAGE_SPACE_OR_CHKSUM, FIL_PAGE_LSN,
and FIL_PAGE_FILE_FLUSH_LSN from the checksum. */
diff --git a/storage/xtradb/pars/lexyy.c b/storage/xtradb/pars/lexyy.c
index 489752a1900..37d892e51e3 100644
--- a/storage/xtradb/pars/lexyy.c
+++ b/storage/xtradb/pars/lexyy.c
@@ -703,7 +703,7 @@ static int yy_flex_debug = 0;
#define YY_RESTORE_YY_MORE_OFFSET
static char *yytext;
#line 1 "pars0lex.l"
-/******************************************************
+/**************************************************//**
SQL parser lexical analyzer: input file for the GNU Flex lexer generator
(c) 1997 Innobase Oy
@@ -747,13 +747,13 @@ Linux.
static ulint stringbuf_len_alloc = 0; /* Allocated length */
static ulint stringbuf_len = 0; /* Current length */
static char* stringbuf; /* Start of buffer */
-/* Appends a string to the buffer. */
+/** Appends a string to the buffer. */
static
void
string_append(
/*==========*/
- const char* str, /* in: string to be appended */
- ulint len) /* in: length of the string */
+ const char* str, /*!< in: string to be appended */
+ ulint len) /*!< in: length of the string */
{
if (stringbuf == NULL) {
stringbuf = malloc(1);
diff --git a/storage/xtradb/pars/pars0lex.l b/storage/xtradb/pars/pars0lex.l
index 38cb744bd44..4abff65e98b 100644
--- a/storage/xtradb/pars/pars0lex.l
+++ b/storage/xtradb/pars/pars0lex.l
@@ -70,13 +70,13 @@ Created 12/14/1997 Heikki Tuuri
static ulint stringbuf_len_alloc = 0; /* Allocated length */
static ulint stringbuf_len = 0; /* Current length */
static char* stringbuf; /* Start of buffer */
-/* Appends a string to the buffer. */
+/** Appends a string to the buffer. */
static
void
string_append(
/*==========*/
- const char* str, /* in: string to be appended */
- ulint len) /* in: length of the string */
+ const char* str, /*!< in: string to be appended */
+ ulint len) /*!< in: length of the string */
{
if (stringbuf == NULL) {
stringbuf = malloc(1);
diff --git a/storage/xtradb/pars/pars0opt.c b/storage/xtradb/pars/pars0opt.c
index 34246929c53..2e392ba4836 100644
--- a/storage/xtradb/pars/pars0opt.c
+++ b/storage/xtradb/pars/pars0opt.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file pars/pars0opt.c
Simple SQL optimizer
Created 12/21/1997 Heikki Tuuri
@@ -47,15 +48,14 @@ Created 12/21/1997 Heikki Tuuri
#define OPT_SCROLL_COND 4
-/***********************************************************************
-Inverts a comparison operator. */
+/*******************************************************************//**
+Inverts a comparison operator.
+@return the equivalent operator when the order of the arguments is switched */
static
int
opt_invert_cmp_op(
/*==============*/
- /* out: the equivalent operator when the order of
- the arguments is switched */
- int op) /* in: operator */
+ int op) /*!< in: operator */
{
if (op == '<') {
return('>');
@@ -74,18 +74,18 @@ opt_invert_cmp_op(
return(0);
}
-/***********************************************************************
+/*******************************************************************//**
Checks if the value of an expression can be calculated BEFORE the nth table
in a join is accessed. If this is the case, it can possibly be used in an
-index search for the nth table. */
+index search for the nth table.
+@return TRUE if already determined */
static
ibool
opt_check_exp_determined_before(
/*============================*/
- /* out: TRUE if already determined */
- que_node_t* exp, /* in: expression */
- sel_node_t* sel_node, /* in: select node */
- ulint nth_table) /* in: nth table will be accessed */
+ que_node_t* exp, /*!< in: expression */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint nth_table) /*!< in: nth table will be accessed */
{
func_node_t* func_node;
sym_node_t* sym_node;
@@ -134,24 +134,22 @@ opt_check_exp_determined_before(
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Looks in a comparison condition if a column value is already restricted by
-it BEFORE the nth table is accessed. */
+it BEFORE the nth table is accessed.
+@return expression restricting the value of the column, or NULL if not known */
static
que_node_t*
opt_look_for_col_in_comparison_before(
/*==================================*/
- /* out: expression restricting the
- value of the column, or NULL if not
- known */
- ulint cmp_type, /* in: OPT_EQUAL, OPT_COMPARISON */
- ulint col_no, /* in: column number */
- func_node_t* search_cond, /* in: comparison condition */
- sel_node_t* sel_node, /* in: select node */
- ulint nth_table, /* in: nth table in a join (a query
+ ulint cmp_type, /*!< in: OPT_EQUAL, OPT_COMPARISON */
+ ulint col_no, /*!< in: column number */
+ func_node_t* search_cond, /*!< in: comparison condition */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint nth_table, /*!< in: nth table in a join (a query
from a single table is considered a
join of 1 table) */
- ulint* op) /* out: comparison operator ('=',
+ ulint* op) /*!< out: comparison operator ('=',
PARS_GE_TOKEN, ... ); this is inverted
if the column appears on the right
side */
@@ -231,26 +229,24 @@ opt_look_for_col_in_comparison_before(
return(NULL);
}
-/***********************************************************************
+/*******************************************************************//**
Looks in a search condition if a column value is already restricted by the
search condition BEFORE the nth table is accessed. Takes into account that
if we will fetch in an ascending order, we cannot utilize an upper limit for
-a column value; in a descending order, respectively, a lower limit. */
+a column value; in a descending order, respectively, a lower limit.
+@return expression restricting the value of the column, or NULL if not known */
static
que_node_t*
opt_look_for_col_in_cond_before(
/*============================*/
- /* out: expression restricting the
- value of the column, or NULL if not
- known */
- ulint cmp_type, /* in: OPT_EQUAL, OPT_COMPARISON */
- ulint col_no, /* in: column number */
- func_node_t* search_cond, /* in: search condition or NULL */
- sel_node_t* sel_node, /* in: select node */
- ulint nth_table, /* in: nth table in a join (a query
+ ulint cmp_type, /*!< in: OPT_EQUAL, OPT_COMPARISON */
+ ulint col_no, /*!< in: column number */
+ func_node_t* search_cond, /*!< in: search condition or NULL */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint nth_table, /*!< in: nth table in a join (a query
from a single table is considered a
join of 1 table) */
- ulint* op) /* out: comparison operator ('=',
+ ulint* op) /*!< out: comparison operator ('=',
PARS_GE_TOKEN, ... ) */
{
func_node_t* new_cond;
@@ -309,24 +305,24 @@ opt_look_for_col_in_cond_before(
return(exp);
}
-/***********************************************************************
+/*******************************************************************//**
Calculates the goodness for an index according to a select node. The
goodness is 4 times the number of first fields in index whose values we
already know exactly in the query. If we have a comparison condition for
an additional field, 2 point are added. If the index is unique, and we know
all the unique fields for the index we add 1024 points. For a clustered index
-we add 1 point. */
+we add 1 point.
+@return goodness */
static
ulint
opt_calc_index_goodness(
/*====================*/
- /* out: goodness */
- dict_index_t* index, /* in: index */
- sel_node_t* sel_node, /* in: parsed select node */
- ulint nth_table, /* in: nth table in a join */
- que_node_t** index_plan, /* in/out: comparison expressions for
+ dict_index_t* index, /*!< in: index */
+ sel_node_t* sel_node, /*!< in: parsed select node */
+ ulint nth_table, /*!< in: nth table in a join */
+ que_node_t** index_plan, /*!< in/out: comparison expressions for
this index */
- ulint* last_op) /* out: last comparison operator, if
+ ulint* last_op) /*!< out: last comparison operator, if
goodness > 1 */
{
que_node_t* exp;
@@ -393,30 +389,29 @@ opt_calc_index_goodness(
return(goodness);
}
-/***********************************************************************
-Calculates the number of matched fields based on an index goodness. */
+/*******************************************************************//**
+Calculates the number of matched fields based on an index goodness.
+@return number of excatly or partially matched fields */
UNIV_INLINE
ulint
opt_calc_n_fields_from_goodness(
/*============================*/
- /* out: number of excatly or partially matched
- fields */
- ulint goodness) /* in: goodness */
+ ulint goodness) /*!< in: goodness */
{
return(((goodness % 1024) + 2) / 4);
}
-/***********************************************************************
+/*******************************************************************//**
Converts a comparison operator to the corresponding search mode PAGE_CUR_GE,
-... */
+...
+@return search mode */
UNIV_INLINE
ulint
opt_op_to_search_mode(
/*==================*/
- /* out: search mode */
- ibool asc, /* in: TRUE if the rows should be fetched in an
+ ibool asc, /*!< in: TRUE if the rows should be fetched in an
ascending order */
- ulint op) /* in: operator '=', PARS_GE_TOKEN, ... */
+ ulint op) /*!< in: operator '=', PARS_GE_TOKEN, ... */
{
if (op == '=') {
if (asc) {
@@ -443,15 +438,15 @@ opt_op_to_search_mode(
return(0);
}
-/***********************************************************************
-Determines if a node is an argument node of a function node. */
+/*******************************************************************//**
+Determines if a node is an argument node of a function node.
+@return TRUE if is an argument */
static
ibool
opt_is_arg(
/*=======*/
- /* out: TRUE if is an argument */
- que_node_t* arg_node, /* in: possible argument node */
- func_node_t* func_node) /* in: function node */
+ que_node_t* arg_node, /*!< in: possible argument node */
+ func_node_t* func_node) /*!< in: function node */
{
que_node_t* arg;
@@ -469,7 +464,7 @@ opt_is_arg(
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Decides if the fetching of rows should be made in a descending order, and
also checks that the chosen query plan produces a result which satisfies
the order-by. */
@@ -477,7 +472,7 @@ static
void
opt_check_order_by(
/*===============*/
- sel_node_t* sel_node) /* in: select node; asserts an error
+ sel_node_t* sel_node) /*!< in: select node; asserts an error
if the plan does not agree with the
order-by */
{
@@ -521,7 +516,7 @@ opt_check_order_by(
}
}
-/***********************************************************************
+/*******************************************************************//**
Optimizes a select. Decides which indexes to tables to use. The tables
are accessed in the order that they were written to the FROM part in the
select statement. */
@@ -529,9 +524,9 @@ static
void
opt_search_plan_for_table(
/*======================*/
- sel_node_t* sel_node, /* in: parsed select node */
- ulint i, /* in: this is the ith table */
- dict_table_t* table) /* in: table */
+ sel_node_t* sel_node, /*!< in: parsed select node */
+ ulint i, /*!< in: this is the ith table */
+ dict_table_t* table) /*!< in: table */
{
plan_t* plan;
dict_index_t* index;
@@ -617,22 +612,19 @@ opt_search_plan_for_table(
btr_pcur_init(&(plan->clust_pcur));
}
-/***********************************************************************
+/*******************************************************************//**
Looks at a comparison condition and decides if it can, and need, be tested for
-a table AFTER the table has been accessed. */
+a table AFTER the table has been accessed.
+@return OPT_NOT_COND if not for this table, else OPT_END_COND,
+OPT_TEST_COND, or OPT_SCROLL_COND, where the last means that the
+condition need not be tested, except when scroll cursors are used */
static
ulint
opt_classify_comparison(
/*====================*/
- /* out: OPT_NOT_COND if not for this
- table, else OPT_END_COND,
- OPT_TEST_COND, or OPT_SCROLL_COND,
- where the last means that the
- condition need not be tested, except
- when scroll cursors are used */
- sel_node_t* sel_node, /* in: select node */
- ulint i, /* in: ith table in the join */
- func_node_t* cond) /* in: comparison condition */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint i, /*!< in: ith table in the join */
+ func_node_t* cond) /*!< in: comparison condition */
{
plan_t* plan;
ulint n_fields;
@@ -713,15 +705,15 @@ opt_classify_comparison(
return(OPT_TEST_COND);
}
-/***********************************************************************
+/*******************************************************************//**
Recursively looks for test conditions for a table in a join. */
static
void
opt_find_test_conds(
/*================*/
- sel_node_t* sel_node, /* in: select node */
- ulint i, /* in: ith table in the join */
- func_node_t* cond) /* in: conjunction of search
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint i, /*!< in: ith table in the join */
+ func_node_t* cond) /*!< in: conjunction of search
conditions or NULL */
{
func_node_t* new_cond;
@@ -758,7 +750,7 @@ opt_find_test_conds(
}
}
-/***********************************************************************
+/*******************************************************************//**
Normalizes a list of comparison conditions so that a column of the table
appears on the left side of the comparison if possible. This is accomplished
by switching the arguments of the operator. */
@@ -766,9 +758,9 @@ static
void
opt_normalize_cmp_conds(
/*====================*/
- func_node_t* cond, /* in: first in a list of comparison
+ func_node_t* cond, /*!< in: first in a list of comparison
conditions, or NULL */
- dict_table_t* table) /* in: table */
+ dict_table_t* table) /*!< in: table */
{
que_node_t* arg1;
que_node_t* arg2;
@@ -800,7 +792,7 @@ opt_normalize_cmp_conds(
}
}
-/***********************************************************************
+/*******************************************************************//**
Finds out the search condition conjuncts we can, and need, to test as the ith
table in a join is accessed. The search tuple can eliminate the need to test
some conjuncts. */
@@ -808,8 +800,8 @@ static
void
opt_determine_and_normalize_test_conds(
/*===================================*/
- sel_node_t* sel_node, /* in: select node */
- ulint i) /* in: ith table in the join */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint i) /*!< in: ith table in the join */
{
plan_t* plan;
@@ -828,7 +820,7 @@ opt_determine_and_normalize_test_conds(
ut_a(UT_LIST_GET_LEN(plan->end_conds) >= plan->n_exact_match);
}
-/***********************************************************************
+/*******************************************************************//**
Looks for occurrences of the columns of the table in the query subgraph and
adds them to the list of columns if an occurrence of the same column does not
already exist in the list. If the column is already in the list, puts a value
@@ -839,13 +831,13 @@ UNIV_INTERN
void
opt_find_all_cols(
/*==============*/
- ibool copy_val, /* in: if TRUE, new found columns are
+ ibool copy_val, /*!< in: if TRUE, new found columns are
added as columns to copy */
- dict_index_t* index, /* in: index of the table to use */
- sym_node_list_t* col_list, /* in: base node of a list where
+ dict_index_t* index, /*!< in: index of the table to use */
+ sym_node_list_t* col_list, /*!< in: base node of a list where
to add new found columns */
- plan_t* plan, /* in: plan or NULL */
- que_node_t* exp) /* in: expression or condition or
+ plan_t* plan, /*!< in: plan or NULL */
+ que_node_t* exp) /*!< in: expression or condition or
NULL */
{
func_node_t* func_node;
@@ -937,7 +929,7 @@ opt_find_all_cols(
}
}
-/***********************************************************************
+/*******************************************************************//**
Looks for occurrences of the columns of the table in conditions which are
not yet determined AFTER the join operation has fetched a row in the ith
table. The values for these column must be copied to dynamic memory for
@@ -946,9 +938,9 @@ static
void
opt_find_copy_cols(
/*===============*/
- sel_node_t* sel_node, /* in: select node */
- ulint i, /* in: ith table in the join */
- func_node_t* search_cond) /* in: search condition or NULL */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint i, /*!< in: ith table in the join */
+ func_node_t* search_cond) /*!< in: search condition or NULL */
{
func_node_t* new_cond;
plan_t* plan;
@@ -985,7 +977,7 @@ opt_find_copy_cols(
}
}
-/***********************************************************************
+/*******************************************************************//**
Classifies the table columns according to whether we use the column only while
holding the latch on the page, or whether we have to copy the column value to
dynamic memory. Puts the first occurrence of a column to either list in the
@@ -994,8 +986,8 @@ static
void
opt_classify_cols(
/*==============*/
- sel_node_t* sel_node, /* in: select node */
- ulint i) /* in: ith table in the join */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint i) /*!< in: ith table in the join */
{
plan_t* plan;
que_node_t* exp;
@@ -1029,15 +1021,15 @@ opt_classify_cols(
sel_node->search_cond);
}
-/***********************************************************************
+/*******************************************************************//**
Fills in the info in plan which is used in accessing a clustered index
record. The columns must already be classified for the plan node. */
static
void
opt_clust_access(
/*=============*/
- sel_node_t* sel_node, /* in: select node */
- ulint n) /* in: nth table in select */
+ sel_node_t* sel_node, /*!< in: select node */
+ ulint n) /*!< in: nth table in select */
{
plan_t* plan;
dict_table_t* table;
@@ -1101,7 +1093,7 @@ opt_clust_access(
}
}
-/***********************************************************************
+/*******************************************************************//**
Optimizes a select. Decides which indexes to tables to use. The tables
are accessed in the order that they were written to the FROM part in the
select statement. */
@@ -1109,7 +1101,7 @@ UNIV_INTERN
void
opt_search_plan(
/*============*/
- sel_node_t* sel_node) /* in: parsed select node */
+ sel_node_t* sel_node) /*!< in: parsed select node */
{
sym_node_t* table_node;
dict_table_t* table;
@@ -1176,13 +1168,13 @@ opt_search_plan(
#endif
}
-/************************************************************************
+/********************************************************************//**
Prints info of a query plan. */
UNIV_INTERN
void
opt_print_query_plan(
/*=================*/
- sel_node_t* sel_node) /* in: select node */
+ sel_node_t* sel_node) /*!< in: select node */
{
plan_t* plan;
ulint n_fields;
diff --git a/storage/xtradb/pars/pars0pars.c b/storage/xtradb/pars/pars0pars.c
index 62ae3b3d09b..9faf36d00a8 100644
--- a/storage/xtradb/pars/pars0pars.c
+++ b/storage/xtradb/pars/pars0pars.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file pars/pars0pars.c
SQL parser
Created 11/19/1996 Heikki Tuuri
@@ -48,10 +49,9 @@ on 1/27/1998 */
#include "eval0eval.h"
#ifdef UNIV_SQL_DEBUG
-/* If the following is set TRUE, the lexer will print the SQL string
+/** If the following is set TRUE, the lexer will print the SQL string
as it tokenizes it */
-
-ibool pars_print_lexed = FALSE;
+UNIV_INTERN ibool pars_print_lexed = FALSE;
#endif /* UNIV_SQL_DEBUG */
/* Global variable used while parsing a single procedure or query : the code is
@@ -92,19 +92,18 @@ UNIV_INTERN pars_res_word_t pars_share_token = {PARS_SHARE_TOKEN};
UNIV_INTERN pars_res_word_t pars_unique_token = {PARS_UNIQUE_TOKEN};
UNIV_INTERN pars_res_word_t pars_clustered_token = {PARS_CLUSTERED_TOKEN};
-/* Global variable used to denote the '*' in SELECT * FROM.. */
-#define PARS_STAR_DENOTER 12345678
-UNIV_INTERN ulint pars_star_denoter = PARS_STAR_DENOTER;
+/** Global variable used to denote the '*' in SELECT * FROM.. */
+UNIV_INTERN ulint pars_star_denoter = 12345678;
-/*************************************************************************
-Determines the class of a function code. */
+/*********************************************************************//**
+Determines the class of a function code.
+@return function class: PARS_FUNC_ARITH, ... */
static
ulint
pars_func_get_class(
/*================*/
- /* out: function class: PARS_FUNC_ARITH, ... */
- int func) /* in: function code: '=', PARS_GE_TOKEN, ... */
+ int func) /*!< in: function code: '=', PARS_GE_TOKEN, ... */
{
switch (func) {
case '+': case '-': case '*': case '/':
@@ -142,15 +141,15 @@ pars_func_get_class(
}
}
-/*************************************************************************
-Parses an operator or predefined function expression. */
+/*********************************************************************//**
+Parses an operator or predefined function expression.
+@return own: function node in a query tree */
static
func_node_t*
pars_func_low(
/*==========*/
- /* out, own: function node in a query tree */
- int func, /* in: function token code */
- que_node_t* arg) /* in: first argument in the argument list */
+ int func, /*!< in: function token code */
+ que_node_t* arg) /*!< in: first argument in the argument list */
{
func_node_t* node;
@@ -171,29 +170,29 @@ pars_func_low(
return(node);
}
-/*************************************************************************
-Parses a function expression. */
+/*********************************************************************//**
+Parses a function expression.
+@return own: function node in a query tree */
UNIV_INTERN
func_node_t*
pars_func(
/*======*/
- /* out, own: function node in a query tree */
- que_node_t* res_word,/* in: function name reserved word */
- que_node_t* arg) /* in: first argument in the argument list */
+ que_node_t* res_word,/*!< in: function name reserved word */
+ que_node_t* arg) /*!< in: first argument in the argument list */
{
return(pars_func_low(((pars_res_word_t*)res_word)->code, arg));
}
-/*************************************************************************
-Parses an operator expression. */
+/*********************************************************************//**
+Parses an operator expression.
+@return own: function node in a query tree */
UNIV_INTERN
func_node_t*
pars_op(
/*====*/
- /* out, own: function node in a query tree */
- int func, /* in: operator token code */
- que_node_t* arg1, /* in: first argument */
- que_node_t* arg2) /* in: second argument or NULL for an unary
+ int func, /*!< in: operator token code */
+ que_node_t* arg1, /*!< in: first argument */
+ que_node_t* arg2) /*!< in: second argument or NULL for an unary
operator */
{
que_node_list_add_last(NULL, arg1);
@@ -205,15 +204,15 @@ pars_op(
return(pars_func_low(func, arg1));
}
-/*************************************************************************
-Parses an ORDER BY clause. Order by a single column only is supported. */
+/*********************************************************************//**
+Parses an ORDER BY clause. Order by a single column only is supported.
+@return own: order-by node in a query tree */
UNIV_INTERN
order_node_t*
pars_order_by(
/*==========*/
- /* out, own: order-by node in a query tree */
- sym_node_t* column, /* in: column name */
- pars_res_word_t* asc) /* in: &pars_asc_token or pars_desc_token */
+ sym_node_t* column, /*!< in: column name */
+ pars_res_word_t* asc) /*!< in: &pars_asc_token or pars_desc_token */
{
order_node_t* node;
@@ -233,15 +232,15 @@ pars_order_by(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Determine if a data type is a built-in string data type of the InnoDB
-SQL parser. */
+SQL parser.
+@return TRUE if string data type */
static
ibool
pars_is_string_type(
/*================*/
- /* out: TRUE if string data type */
- ulint mtype) /* in: main data type */
+ ulint mtype) /*!< in: main data type */
{
switch (mtype) {
case DATA_VARCHAR: case DATA_CHAR:
@@ -252,14 +251,14 @@ pars_is_string_type(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Resolves the data type of a function in an expression. The argument data
types must already be resolved. */
static
void
pars_resolve_func_data_type(
/*========================*/
- func_node_t* node) /* in: function node */
+ func_node_t* node) /*!< in: function node */
{
que_node_t* arg;
@@ -345,18 +344,18 @@ pars_resolve_func_data_type(
}
}
-/*************************************************************************
+/*********************************************************************//**
Resolves the meaning of variables in an expression and the data types of
functions. It is an error if some identifier cannot be resolved here. */
static
void
pars_resolve_exp_variables_and_types(
/*=================================*/
- sel_node_t* select_node, /* in: select node or NULL; if
+ sel_node_t* select_node, /*!< in: select node or NULL; if
this is not NULL then the variable
sym nodes are added to the
copy_variables list of select_node */
- que_node_t* exp_node) /* in: expression */
+ que_node_t* exp_node) /*!< in: expression */
{
func_node_t* func_node;
que_node_t* arg;
@@ -435,7 +434,7 @@ pars_resolve_exp_variables_and_types(
que_node_get_data_type(node));
}
-/*************************************************************************
+/*********************************************************************//**
Resolves the meaning of variables in an expression list. It is an error if
some identifier cannot be resolved here. Resolves also the data types of
functions. */
@@ -443,8 +442,8 @@ static
void
pars_resolve_exp_list_variables_and_types(
/*======================================*/
- sel_node_t* select_node, /* in: select node or NULL */
- que_node_t* exp_node) /* in: expression list first node, or
+ sel_node_t* select_node, /*!< in: select node or NULL */
+ que_node_t* exp_node) /*!< in: expression list first node, or
NULL */
{
while (exp_node) {
@@ -454,14 +453,14 @@ pars_resolve_exp_list_variables_and_types(
}
}
-/*************************************************************************
+/*********************************************************************//**
Resolves the columns in an expression. */
static
void
pars_resolve_exp_columns(
/*=====================*/
- sym_node_t* table_node, /* in: first node in a table list */
- que_node_t* exp_node) /* in: expression */
+ sym_node_t* table_node, /*!< in: first node in a table list */
+ que_node_t* exp_node) /*!< in: expression */
{
func_node_t* func_node;
que_node_t* arg;
@@ -535,14 +534,14 @@ pars_resolve_exp_columns(
}
}
-/*************************************************************************
+/*********************************************************************//**
Resolves the meaning of columns in an expression list. */
static
void
pars_resolve_exp_list_columns(
/*==========================*/
- sym_node_t* table_node, /* in: first node in a table list */
- que_node_t* exp_node) /* in: expression list first node, or
+ sym_node_t* table_node, /*!< in: first node in a table list */
+ que_node_t* exp_node) /*!< in: expression list first node, or
NULL */
{
while (exp_node) {
@@ -552,13 +551,13 @@ pars_resolve_exp_list_columns(
}
}
-/*************************************************************************
+/*********************************************************************//**
Retrieves the table definition for a table name id. */
static
void
pars_retrieve_table_def(
/*====================*/
- sym_node_t* sym_node) /* in: table node */
+ sym_node_t* sym_node) /*!< in: table node */
{
const char* table_name;
@@ -575,14 +574,14 @@ pars_retrieve_table_def(
ut_a(sym_node->table);
}
-/*************************************************************************
-Retrieves the table definitions for a list of table name ids. */
+/*********************************************************************//**
+Retrieves the table definitions for a list of table name ids.
+@return number of tables */
static
ulint
pars_retrieve_table_list_defs(
/*==========================*/
- /* out: number of tables */
- sym_node_t* sym_node) /* in: first table node in list */
+ sym_node_t* sym_node) /*!< in: first table node in list */
{
ulint count = 0;
@@ -602,13 +601,13 @@ pars_retrieve_table_list_defs(
return(count);
}
-/*************************************************************************
+/*********************************************************************//**
Adds all columns to the select list if the query is SELECT * FROM ... */
static
void
pars_select_all_columns(
/*====================*/
- sel_node_t* select_node) /* in: select node already containing
+ sel_node_t* select_node) /*!< in: select node already containing
the table list */
{
sym_node_t* col_node;
@@ -639,17 +638,16 @@ pars_select_all_columns(
}
}
-/*************************************************************************
+/*********************************************************************//**
Parses a select list; creates a query graph node for the whole SELECT
-statement. */
+statement.
+@return own: select node in a query tree */
UNIV_INTERN
sel_node_t*
pars_select_list(
/*=============*/
- /* out, own: select node in a query
- tree */
- que_node_t* select_list, /* in: select list */
- sym_node_t* into_list) /* in: variables list or NULL */
+ que_node_t* select_list, /*!< in: select list */
+ sym_node_t* into_list) /*!< in: variables list or NULL */
{
sel_node_t* node;
@@ -663,14 +661,14 @@ pars_select_list(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if the query is an aggregate query, in which case the selct list must
contain only aggregate function items. */
static
void
pars_check_aggregate(
/*=================*/
- sel_node_t* select_node) /* in: select node already containing
+ sel_node_t* select_node) /*!< in: select node already containing
the select list */
{
que_node_t* exp_node;
@@ -706,21 +704,20 @@ pars_check_aggregate(
}
}
-/*************************************************************************
-Parses a select statement. */
+/*********************************************************************//**
+Parses a select statement.
+@return own: select node in a query tree */
UNIV_INTERN
sel_node_t*
pars_select_statement(
/*==================*/
- /* out, own: select node in a query
- tree */
- sel_node_t* select_node, /* in: select node already containing
+ sel_node_t* select_node, /*!< in: select node already containing
the select list */
- sym_node_t* table_list, /* in: table list */
- que_node_t* search_cond, /* in: search condition or NULL */
- pars_res_word_t* for_update, /* in: NULL or &pars_update_token */
- pars_res_word_t* lock_shared, /* in: NULL or &pars_share_token */
- order_node_t* order_by) /* in: NULL or an order-by node */
+ sym_node_t* table_list, /*!< in: table list */
+ que_node_t* search_cond, /*!< in: search condition or NULL */
+ pars_res_word_t* for_update, /*!< in: NULL or &pars_update_token */
+ pars_res_word_t* lock_shared, /*!< in: NULL or &pars_share_token */
+ order_node_t* order_by) /*!< in: NULL or an order-by node */
{
select_node->state = SEL_NODE_OPEN;
@@ -790,16 +787,16 @@ pars_select_statement(
return(select_node);
}
-/*************************************************************************
-Parses a cursor declaration. */
+/*********************************************************************//**
+Parses a cursor declaration.
+@return sym_node */
UNIV_INTERN
que_node_t*
pars_cursor_declaration(
/*====================*/
- /* out: sym_node */
- sym_node_t* sym_node, /* in: cursor id node in the symbol
+ sym_node_t* sym_node, /*!< in: cursor id node in the symbol
table */
- sel_node_t* select_node) /* in: select node */
+ sel_node_t* select_node) /*!< in: select node */
{
sym_node->resolved = TRUE;
sym_node->token_type = SYM_CURSOR;
@@ -811,14 +808,14 @@ pars_cursor_declaration(
return(sym_node);
}
-/*************************************************************************
-Parses a function declaration. */
+/*********************************************************************//**
+Parses a function declaration.
+@return sym_node */
UNIV_INTERN
que_node_t*
pars_function_declaration(
/*======================*/
- /* out: sym_node */
- sym_node_t* sym_node) /* in: function id node in the symbol
+ sym_node_t* sym_node) /*!< in: function id node in the symbol
table */
{
sym_node->resolved = TRUE;
@@ -831,17 +828,16 @@ pars_function_declaration(
return(sym_node);
}
-/*************************************************************************
-Parses a delete or update statement start. */
+/*********************************************************************//**
+Parses a delete or update statement start.
+@return own: update node in a query tree */
UNIV_INTERN
upd_node_t*
pars_update_statement_start(
/*========================*/
- /* out, own: update node in a query
- tree */
- ibool is_delete, /* in: TRUE if delete */
- sym_node_t* table_sym, /* in: table name node */
- col_assign_node_t* col_assign_list)/* in: column assignment list, NULL
+ ibool is_delete, /*!< in: TRUE if delete */
+ sym_node_t* table_sym, /*!< in: table name node */
+ col_assign_node_t* col_assign_list)/*!< in: column assignment list, NULL
if delete */
{
upd_node_t* node;
@@ -856,15 +852,15 @@ pars_update_statement_start(
return(node);
}
-/*************************************************************************
-Parses a column assignment in an update. */
+/*********************************************************************//**
+Parses a column assignment in an update.
+@return column assignment node */
UNIV_INTERN
col_assign_node_t*
pars_column_assignment(
/*===================*/
- /* out: column assignment node */
- sym_node_t* column, /* in: column to assign */
- que_node_t* exp) /* in: value to assign */
+ sym_node_t* column, /*!< in: column to assign */
+ que_node_t* exp) /*!< in: value to assign */
{
col_assign_node_t* node;
@@ -878,13 +874,13 @@ pars_column_assignment(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Processes an update node assignment list. */
static
void
pars_process_assign_list(
/*=====================*/
- upd_node_t* node) /* in: update node */
+ upd_node_t* node) /*!< in: update node */
{
col_assign_node_t* col_assign_list;
sym_node_t* table_sym;
@@ -945,7 +941,8 @@ pars_process_assign_list(
if (!dict_col_get_fixed_size(
dict_index_get_nth_col(clust_index,
- upd_field->field_no))) {
+ upd_field->field_no),
+ dict_table_is_comp(node->table))) {
changes_field_size = 0;
}
@@ -964,18 +961,17 @@ pars_process_assign_list(
node->cmpl_info = changes_ord_field | changes_field_size;
}
-/*************************************************************************
-Parses an update or delete statement. */
+/*********************************************************************//**
+Parses an update or delete statement.
+@return own: update node in a query tree */
UNIV_INTERN
upd_node_t*
pars_update_statement(
/*==================*/
- /* out, own: update node in a query
- tree */
- upd_node_t* node, /* in: update node */
- sym_node_t* cursor_sym, /* in: pointer to a cursor entry in
+ upd_node_t* node, /*!< in: update node */
+ sym_node_t* cursor_sym, /*!< in: pointer to a cursor entry in
the symbol table or NULL */
- que_node_t* search_cond) /* in: search condition or NULL */
+ que_node_t* search_cond) /*!< in: search condition or NULL */
{
sym_node_t* table_sym;
sel_node_t* sel_node;
@@ -1051,17 +1047,16 @@ pars_update_statement(
return(node);
}
-/*************************************************************************
-Parses an insert statement. */
+/*********************************************************************//**
+Parses an insert statement.
+@return own: update node in a query tree */
UNIV_INTERN
ins_node_t*
pars_insert_statement(
/*==================*/
- /* out, own: update node in a query
- tree */
- sym_node_t* table_sym, /* in: table name node */
- que_node_t* values_list, /* in: value expression list or NULL */
- sel_node_t* select) /* in: select condition or NULL */
+ sym_node_t* table_sym, /*!< in: table name node */
+ que_node_t* values_list, /*!< in: value expression list or NULL */
+ sel_node_t* select) /*!< in: select condition or NULL */
{
ins_node_t* node;
dtuple_t* row;
@@ -1109,19 +1104,19 @@ pars_insert_statement(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Set the type of a dfield. */
static
void
pars_set_dfield_type(
/*=================*/
- dfield_t* dfield, /* in: dfield */
- pars_res_word_t* type, /* in: pointer to a type
+ dfield_t* dfield, /*!< in: dfield */
+ pars_res_word_t* type, /*!< in: pointer to a type
token */
- ulint len, /* in: length, or 0 */
- ibool is_unsigned, /* in: if TRUE, column is
+ ulint len, /*!< in: length, or 0 */
+ ibool is_unsigned, /*!< in: if TRUE, column is
UNSIGNED. */
- ibool is_not_null) /* in: if TRUE, column is
+ ibool is_not_null) /*!< in: if TRUE, column is
NOT NULL. */
{
ulint flags = 0;
@@ -1159,17 +1154,16 @@ pars_set_dfield_type(
}
}
-/*************************************************************************
-Parses a variable declaration. */
+/*********************************************************************//**
+Parses a variable declaration.
+@return own: symbol table node of type SYM_VAR */
UNIV_INTERN
sym_node_t*
pars_variable_declaration(
/*======================*/
- /* out, own: symbol table node of type
- SYM_VAR */
- sym_node_t* node, /* in: symbol table node allocated for the
+ sym_node_t* node, /*!< in: symbol table node allocated for the
id of the variable */
- pars_res_word_t* type) /* in: pointer to a type token */
+ pars_res_word_t* type) /*!< in: pointer to a type token */
{
node->resolved = TRUE;
node->token_type = SYM_VAR;
@@ -1181,19 +1175,18 @@ pars_variable_declaration(
return(node);
}
-/*************************************************************************
-Parses a procedure parameter declaration. */
+/*********************************************************************//**
+Parses a procedure parameter declaration.
+@return own: symbol table node of type SYM_VAR */
UNIV_INTERN
sym_node_t*
pars_parameter_declaration(
/*=======================*/
- /* out, own: symbol table node of type
- SYM_VAR */
- sym_node_t* node, /* in: symbol table node allocated for the
+ sym_node_t* node, /*!< in: symbol table node allocated for the
id of the parameter */
ulint param_type,
- /* in: PARS_INPUT or PARS_OUTPUT */
- pars_res_word_t* type) /* in: pointer to a type token */
+ /*!< in: PARS_INPUT or PARS_OUTPUT */
+ pars_res_word_t* type) /*!< in: pointer to a type token */
{
ut_a((param_type == PARS_INPUT) || (param_type == PARS_OUTPUT));
@@ -1204,14 +1197,14 @@ pars_parameter_declaration(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Sets the parent field in a query node list. */
static
void
pars_set_parent_in_list(
/*====================*/
- que_node_t* node_list, /* in: first node in a list */
- que_node_t* parent) /* in: parent value to set in all
+ que_node_t* node_list, /*!< in: first node in a list */
+ que_node_t* parent) /*!< in: parent value to set in all
nodes of the list */
{
que_common_t* common;
@@ -1225,15 +1218,15 @@ pars_set_parent_in_list(
}
}
-/*************************************************************************
-Parses an elsif element. */
+/*********************************************************************//**
+Parses an elsif element.
+@return elsif node */
UNIV_INTERN
elsif_node_t*
pars_elsif_element(
/*===============*/
- /* out: elsif node */
- que_node_t* cond, /* in: if-condition */
- que_node_t* stat_list) /* in: statement list */
+ que_node_t* cond, /*!< in: if-condition */
+ que_node_t* stat_list) /*!< in: statement list */
{
elsif_node_t* node;
@@ -1250,16 +1243,16 @@ pars_elsif_element(
return(node);
}
-/*************************************************************************
-Parses an if-statement. */
+/*********************************************************************//**
+Parses an if-statement.
+@return if-statement node */
UNIV_INTERN
if_node_t*
pars_if_statement(
/*==============*/
- /* out: if-statement node */
- que_node_t* cond, /* in: if-condition */
- que_node_t* stat_list, /* in: statement list */
- que_node_t* else_part) /* in: else-part statement list
+ que_node_t* cond, /*!< in: if-condition */
+ que_node_t* stat_list, /*!< in: statement list */
+ que_node_t* else_part) /*!< in: else-part statement list
or elsif element list */
{
if_node_t* node;
@@ -1301,15 +1294,15 @@ pars_if_statement(
return(node);
}
-/*************************************************************************
-Parses a while-statement. */
+/*********************************************************************//**
+Parses a while-statement.
+@return while-statement node */
UNIV_INTERN
while_node_t*
pars_while_statement(
/*=================*/
- /* out: while-statement node */
- que_node_t* cond, /* in: while-condition */
- que_node_t* stat_list) /* in: statement list */
+ que_node_t* cond, /*!< in: while-condition */
+ que_node_t* stat_list) /*!< in: statement list */
{
while_node_t* node;
@@ -1328,17 +1321,17 @@ pars_while_statement(
return(node);
}
-/*************************************************************************
-Parses a for-loop-statement. */
+/*********************************************************************//**
+Parses a for-loop-statement.
+@return for-statement node */
UNIV_INTERN
for_node_t*
pars_for_statement(
/*===============*/
- /* out: for-statement node */
- sym_node_t* loop_var, /* in: loop variable */
- que_node_t* loop_start_limit,/* in: loop start expression */
- que_node_t* loop_end_limit, /* in: loop end expression */
- que_node_t* stat_list) /* in: statement list */
+ sym_node_t* loop_var, /*!< in: loop variable */
+ que_node_t* loop_start_limit,/*!< in: loop start expression */
+ que_node_t* loop_end_limit, /*!< in: loop end expression */
+ que_node_t* stat_list) /*!< in: statement list */
{
for_node_t* node;
@@ -1364,13 +1357,13 @@ pars_for_statement(
return(node);
}
-/*************************************************************************
-Parses an exit statement. */
+/*********************************************************************//**
+Parses an exit statement.
+@return exit statement node */
UNIV_INTERN
exit_node_t*
pars_exit_statement(void)
/*=====================*/
- /* out: exit statement node */
{
exit_node_t* node;
@@ -1380,13 +1373,13 @@ pars_exit_statement(void)
return(node);
}
-/*************************************************************************
-Parses a return-statement. */
+/*********************************************************************//**
+Parses a return-statement.
+@return return-statement node */
UNIV_INTERN
return_node_t*
pars_return_statement(void)
/*=======================*/
- /* out: return-statement node */
{
return_node_t* node;
@@ -1397,15 +1390,15 @@ pars_return_statement(void)
return(node);
}
-/*************************************************************************
-Parses an assignment statement. */
+/*********************************************************************//**
+Parses an assignment statement.
+@return assignment statement node */
UNIV_INTERN
assign_node_t*
pars_assignment_statement(
/*======================*/
- /* out: assignment statement node */
- sym_node_t* var, /* in: variable to assign */
- que_node_t* val) /* in: value to assign */
+ sym_node_t* var, /*!< in: variable to assign */
+ que_node_t* val) /*!< in: value to assign */
{
assign_node_t* node;
@@ -1425,15 +1418,15 @@ pars_assignment_statement(
return(node);
}
-/*************************************************************************
-Parses a procedure call. */
+/*********************************************************************//**
+Parses a procedure call.
+@return function node */
UNIV_INTERN
func_node_t*
pars_procedure_call(
/*================*/
- /* out: function node */
- que_node_t* res_word,/* in: procedure name reserved word */
- que_node_t* args) /* in: argument list */
+ que_node_t* res_word,/*!< in: procedure name reserved word */
+ que_node_t* args) /*!< in: argument list */
{
func_node_t* node;
@@ -1444,17 +1437,17 @@ pars_procedure_call(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Parses a fetch statement. into_list or user_func (but not both) must be
-non-NULL. */
+non-NULL.
+@return fetch statement node */
UNIV_INTERN
fetch_node_t*
pars_fetch_statement(
/*=================*/
- /* out: fetch statement node */
- sym_node_t* cursor, /* in: cursor node */
- sym_node_t* into_list, /* in: variables to set, or NULL */
- sym_node_t* user_func) /* in: user function name, or NULL */
+ sym_node_t* cursor, /*!< in: cursor node */
+ sym_node_t* into_list, /*!< in: variables to set, or NULL */
+ sym_node_t* user_func) /*!< in: user function name, or NULL */
{
sym_node_t* cursor_decl;
fetch_node_t* node;
@@ -1496,16 +1489,16 @@ pars_fetch_statement(
return(node);
}
-/*************************************************************************
-Parses an open or close cursor statement. */
+/*********************************************************************//**
+Parses an open or close cursor statement.
+@return fetch statement node */
UNIV_INTERN
open_node_t*
pars_open_statement(
/*================*/
- /* out: fetch statement node */
- ulint type, /* in: ROW_SEL_OPEN_CURSOR
+ ulint type, /*!< in: ROW_SEL_OPEN_CURSOR
or ROW_SEL_CLOSE_CURSOR */
- sym_node_t* cursor) /* in: cursor node */
+ sym_node_t* cursor) /*!< in: cursor node */
{
sym_node_t* cursor_decl;
open_node_t* node;
@@ -1526,14 +1519,14 @@ pars_open_statement(
return(node);
}
-/*************************************************************************
-Parses a row_printf-statement. */
+/*********************************************************************//**
+Parses a row_printf-statement.
+@return row_printf-statement node */
UNIV_INTERN
row_printf_node_t*
pars_row_printf_statement(
/*======================*/
- /* out: row_printf-statement node */
- sel_node_t* sel_node) /* in: select node */
+ sel_node_t* sel_node) /*!< in: select node */
{
row_printf_node_t* node;
@@ -1548,8 +1541,9 @@ pars_row_printf_statement(
return(node);
}
-/*************************************************************************
-Parses a commit statement. */
+/*********************************************************************//**
+Parses a commit statement.
+@return own: commit node struct */
UNIV_INTERN
commit_node_t*
pars_commit_statement(void)
@@ -1558,8 +1552,9 @@ pars_commit_statement(void)
return(commit_node_create(pars_sym_tab_global->heap));
}
-/*************************************************************************
-Parses a rollback statement. */
+/*********************************************************************//**
+Parses a rollback statement.
+@return own: rollback node struct */
UNIV_INTERN
roll_node_t*
pars_rollback_statement(void)
@@ -1568,22 +1563,21 @@ pars_rollback_statement(void)
return(roll_node_create(pars_sym_tab_global->heap));
}
-/*************************************************************************
-Parses a column definition at a table creation. */
+/*********************************************************************//**
+Parses a column definition at a table creation.
+@return column sym table node */
UNIV_INTERN
sym_node_t*
pars_column_def(
/*============*/
- /* out: column sym table
- node */
- sym_node_t* sym_node, /* in: column node in the
+ sym_node_t* sym_node, /*!< in: column node in the
symbol table */
- pars_res_word_t* type, /* in: data type */
- sym_node_t* len, /* in: length of column, or
+ pars_res_word_t* type, /*!< in: data type */
+ sym_node_t* len, /*!< in: length of column, or
NULL */
- void* is_unsigned, /* in: if not NULL, column
+ void* is_unsigned, /*!< in: if not NULL, column
is of type UNSIGNED. */
- void* is_not_null) /* in: if not NULL, column
+ void* is_not_null) /*!< in: if not NULL, column
is of type NOT NULL. */
{
ulint len2;
@@ -1600,18 +1594,18 @@ pars_column_def(
return(sym_node);
}
-/*************************************************************************
-Parses a table creation operation. */
+/*********************************************************************//**
+Parses a table creation operation.
+@return table create subgraph */
UNIV_INTERN
tab_node_t*
pars_create_table(
/*==============*/
- /* out: table create subgraph */
- sym_node_t* table_sym, /* in: table name node in the symbol
+ sym_node_t* table_sym, /*!< in: table name node in the symbol
table */
- sym_node_t* column_defs, /* in: list of column names */
+ sym_node_t* column_defs, /*!< in: list of column names */
void* not_fit_in_memory __attribute__((unused)))
- /* in: a non-NULL pointer means that
+ /*!< in: a non-NULL pointer means that
this is a table which in simulations
should be simulated as not fitting
in memory; thread is put to sleep
@@ -1662,20 +1656,20 @@ pars_create_table(
return(node);
}
-/*************************************************************************
-Parses an index creation operation. */
+/*********************************************************************//**
+Parses an index creation operation.
+@return index create subgraph */
UNIV_INTERN
ind_node_t*
pars_create_index(
/*==============*/
- /* out: index create subgraph */
- pars_res_word_t* unique_def, /* in: not NULL if a unique index */
- pars_res_word_t* clustered_def, /* in: not NULL if a clustered index */
- sym_node_t* index_sym, /* in: index name node in the symbol
+ pars_res_word_t* unique_def, /*!< in: not NULL if a unique index */
+ pars_res_word_t* clustered_def, /*!< in: not NULL if a clustered index */
+ sym_node_t* index_sym, /*!< in: index name node in the symbol
table */
- sym_node_t* table_sym, /* in: table name node in the symbol
+ sym_node_t* table_sym, /*!< in: table name node in the symbol
table */
- sym_node_t* column_list) /* in: list of column names */
+ sym_node_t* column_list) /*!< in: list of column names */
{
dict_index_t* index;
sym_node_t* column;
@@ -1719,17 +1713,17 @@ pars_create_index(
return(node);
}
-/*************************************************************************
-Parses a procedure definition. */
+/*********************************************************************//**
+Parses a procedure definition.
+@return query fork node */
UNIV_INTERN
que_fork_t*
pars_procedure_definition(
/*======================*/
- /* out: query fork node */
- sym_node_t* sym_node, /* in: procedure id node in the symbol
+ sym_node_t* sym_node, /*!< in: procedure id node in the symbol
table */
- sym_node_t* param_list, /* in: parameter declaration list */
- que_node_t* stat_list) /* in: statement list */
+ sym_node_t* param_list, /*!< in: parameter declaration list */
+ que_node_t* stat_list) /*!< in: statement list */
{
proc_node_t* node;
que_fork_t* fork;
@@ -1766,32 +1760,32 @@ pars_procedure_definition(
return(fork);
}
-/*****************************************************************
+/*************************************************************//**
Parses a stored procedure call, when this is not within another stored
procedure, that is, the client issues a procedure call directly.
In MySQL/InnoDB, stored InnoDB procedures are invoked via the
-parsed procedure tree, not via InnoDB SQL, so this function is not used. */
+parsed procedure tree, not via InnoDB SQL, so this function is not used.
+@return query graph */
UNIV_INTERN
que_fork_t*
pars_stored_procedure_call(
/*=======================*/
- /* out: query graph */
sym_node_t* sym_node __attribute__((unused)))
- /* in: stored procedure name */
+ /*!< in: stored procedure name */
{
ut_error;
return(NULL);
}
-/*****************************************************************
+/*************************************************************//**
Retrieves characters to the lexical analyzer. */
UNIV_INTERN
void
pars_get_lex_chars(
/*===============*/
- char* buf, /* in/out: buffer where to copy */
- int* result, /* out: number of characters copied or EOF */
- int max_size) /* in: maximum number of characters which fit
+ char* buf, /*!< in/out: buffer where to copy */
+ int* result, /*!< out: number of characters copied or EOF */
+ int max_size) /*!< in: maximum number of characters which fit
in the buffer */
{
int len;
@@ -1831,14 +1825,14 @@ pars_get_lex_chars(
pars_sym_tab_global->next_char_pos += len;
}
-/*****************************************************************
+/*************************************************************//**
Called by yyparse on error. */
UNIV_INTERN
void
yyerror(
/*====*/
const char* s __attribute__((unused)))
- /* in: error message string */
+ /*!< in: error message string */
{
ut_ad(s);
@@ -1847,15 +1841,15 @@ yyerror(
ut_error;
}
-/*****************************************************************
-Parses an SQL string returning the query graph. */
+/*************************************************************//**
+Parses an SQL string returning the query graph.
+@return own: the query graph */
UNIV_INTERN
que_t*
pars_sql(
/*=====*/
- /* out, own: the query graph */
- pars_info_t* info, /* in: extra information, or NULL */
- const char* str) /* in: SQL string */
+ pars_info_t* info, /*!< in: extra information, or NULL */
+ const char* str) /*!< in: SQL string */
{
sym_node_t* sym_node;
mem_heap_t* heap;
@@ -1896,19 +1890,19 @@ pars_sql(
return(graph);
}
-/**********************************************************************
+/******************************************************************//**
Completes a query graph by adding query thread and fork nodes
above it and prepares the graph for running. The fork created is of
-type QUE_FORK_MYSQL_INTERFACE. */
+type QUE_FORK_MYSQL_INTERFACE.
+@return query thread node to run */
UNIV_INTERN
que_thr_t*
pars_complete_graph_for_exec(
/*=========================*/
- /* out: query thread node to run */
- que_node_t* node, /* in: root node for an incomplete
+ que_node_t* node, /*!< in: root node for an incomplete
query graph */
- trx_t* trx, /* in: transaction handle */
- mem_heap_t* heap) /* in: memory heap from which allocated */
+ trx_t* trx, /*!< in: transaction handle */
+ mem_heap_t* heap) /*!< in: memory heap from which allocated */
{
que_fork_t* fork;
que_thr_t* thr;
@@ -1927,13 +1921,13 @@ pars_complete_graph_for_exec(
return(thr);
}
-/********************************************************************
-Create parser info struct.*/
+/****************************************************************//**
+Create parser info struct.
+@return own: info struct */
UNIV_INTERN
pars_info_t*
pars_info_create(void)
/*==================*/
- /* out, own: info struct */
{
pars_info_t* info;
mem_heap_t* heap;
@@ -1951,29 +1945,29 @@ pars_info_create(void)
return(info);
}
-/********************************************************************
-Free info struct and everything it contains.*/
+/****************************************************************//**
+Free info struct and everything it contains. */
UNIV_INTERN
void
pars_info_free(
/*===========*/
- pars_info_t* info) /* in: info struct */
+ pars_info_t* info) /*!< in, own: info struct */
{
mem_heap_free(info->heap);
}
-/********************************************************************
+/****************************************************************//**
Add bound literal. */
UNIV_INTERN
void
pars_info_add_literal(
/*==================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- const void* address, /* in: address */
- ulint length, /* in: length of data */
- ulint type, /* in: type, e.g. DATA_FIXBINARY */
- ulint prtype) /* in: precise type, e.g.
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ const void* address, /*!< in: address */
+ ulint length, /*!< in: length of data */
+ ulint type, /*!< in: type, e.g. DATA_FIXBINARY */
+ ulint prtype) /*!< in: precise type, e.g.
DATA_UNSIGNED */
{
pars_bound_lit_t* pbl;
@@ -1995,22 +1989,22 @@ pars_info_add_literal(
ib_vector_push(info->bound_lits, pbl);
}
-/********************************************************************
+/****************************************************************//**
Equivalent to pars_info_add_literal(info, name, str, strlen(str),
DATA_VARCHAR, DATA_ENGLISH). */
UNIV_INTERN
void
pars_info_add_str_literal(
/*======================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- const char* str) /* in: string */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ const char* str) /*!< in: string */
{
pars_info_add_literal(info, name, str, strlen(str),
DATA_VARCHAR, DATA_ENGLISH);
}
-/********************************************************************
+/****************************************************************//**
Equivalent to:
char buf[4];
@@ -2023,9 +2017,9 @@ UNIV_INTERN
void
pars_info_add_int4_literal(
/*=======================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- lint val) /* in: value */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ lint val) /*!< in: value */
{
byte* buf = mem_heap_alloc(info->heap, 4);
@@ -2033,7 +2027,7 @@ pars_info_add_int4_literal(
pars_info_add_literal(info, name, buf, 4, DATA_INT, 0);
}
-/********************************************************************
+/****************************************************************//**
Equivalent to:
char buf[8];
@@ -2046,9 +2040,9 @@ UNIV_INTERN
void
pars_info_add_dulint_literal(
/*=========================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- dulint val) /* in: value */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ dulint val) /*!< in: value */
{
byte* buf = mem_heap_alloc(info->heap, 8);
@@ -2057,16 +2051,16 @@ pars_info_add_dulint_literal(
pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0);
}
-/********************************************************************
+/****************************************************************//**
Add user function. */
UNIV_INTERN
void
pars_info_add_function(
/*===================*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: function name */
- pars_user_func_cb_t func, /* in: function address */
- void* arg) /* in: user-supplied argument */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: function name */
+ pars_user_func_cb_t func, /*!< in: function address */
+ void* arg) /*!< in: user-supplied argument */
{
pars_user_func_t* puf;
@@ -2085,15 +2079,15 @@ pars_info_add_function(
ib_vector_push(info->funcs, puf);
}
-/********************************************************************
+/****************************************************************//**
Add bound id. */
UNIV_INTERN
void
pars_info_add_id(
/*=============*/
- pars_info_t* info, /* in: info struct */
- const char* name, /* in: name */
- const char* id) /* in: id */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name, /*!< in: name */
+ const char* id) /*!< in: id */
{
pars_bound_id_t* bid;
@@ -2111,16 +2105,15 @@ pars_info_add_id(
ib_vector_push(info->bound_ids, bid);
}
-/********************************************************************
-Get user function with the given name.*/
+/****************************************************************//**
+Get user function with the given name.
+@return user func, or NULL if not found */
UNIV_INTERN
pars_user_func_t*
pars_info_get_user_func(
/*====================*/
- /* out: user func, or NULL if not
- found */
- pars_info_t* info, /* in: info struct */
- const char* name) /* in: function name to find*/
+ pars_info_t* info, /*!< in: info struct */
+ const char* name) /*!< in: function name to find*/
{
ulint i;
ib_vector_t* vec;
@@ -2142,16 +2135,15 @@ pars_info_get_user_func(
return(NULL);
}
-/********************************************************************
-Get bound literal with the given name.*/
+/****************************************************************//**
+Get bound literal with the given name.
+@return bound literal, or NULL if not found */
UNIV_INTERN
pars_bound_lit_t*
pars_info_get_bound_lit(
/*====================*/
- /* out: bound literal, or NULL if
- not found */
- pars_info_t* info, /* in: info struct */
- const char* name) /* in: bound literal name to find */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name) /*!< in: bound literal name to find */
{
ulint i;
ib_vector_t* vec;
@@ -2173,16 +2165,15 @@ pars_info_get_bound_lit(
return(NULL);
}
-/********************************************************************
-Get bound id with the given name.*/
+/****************************************************************//**
+Get bound id with the given name.
+@return bound id, or NULL if not found */
UNIV_INTERN
pars_bound_id_t*
pars_info_get_bound_id(
/*===================*/
- /* out: bound id, or NULL if not
- found */
- pars_info_t* info, /* in: info struct */
- const char* name) /* in: bound id name to find */
+ pars_info_t* info, /*!< in: info struct */
+ const char* name) /*!< in: bound id name to find */
{
ulint i;
ib_vector_t* vec;
diff --git a/storage/xtradb/pars/pars0sym.c b/storage/xtradb/pars/pars0sym.c
index fb23547e767..b56350116bb 100644
--- a/storage/xtradb/pars/pars0sym.c
+++ b/storage/xtradb/pars/pars0sym.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file pars/pars0sym.c
SQL parser symbol table
Created 12/15/1997 Heikki Tuuri
@@ -37,14 +38,14 @@ Created 12/15/1997 Heikki Tuuri
#include "eval0eval.h"
#include "row0sel.h"
-/**********************************************************************
-Creates a symbol table for a single stored procedure or query. */
+/******************************************************************//**
+Creates a symbol table for a single stored procedure or query.
+@return own: symbol table */
UNIV_INTERN
sym_tab_t*
sym_tab_create(
/*===========*/
- /* out, own: symbol table */
- mem_heap_t* heap) /* in: memory heap where to create */
+ mem_heap_t* heap) /*!< in: memory heap where to create */
{
sym_tab_t* sym_tab;
@@ -58,7 +59,7 @@ sym_tab_create(
return(sym_tab);
}
-/**********************************************************************
+/******************************************************************//**
Frees the memory allocated dynamically AFTER parsing phase for variables
etc. in the symbol table. Does not free the mem heap where the table was
originally created. Frees also SQL explicit cursor definitions. */
@@ -66,7 +67,7 @@ UNIV_INTERN
void
sym_tab_free_private(
/*=================*/
- sym_tab_t* sym_tab) /* in, own: symbol table */
+ sym_tab_t* sym_tab) /*!< in, own: symbol table */
{
sym_node_t* sym;
func_node_t* func;
@@ -96,15 +97,15 @@ sym_tab_free_private(
}
}
-/**********************************************************************
-Adds an integer literal to a symbol table. */
+/******************************************************************//**
+Adds an integer literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_int_lit(
/*================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- ulint val) /* in: integer value */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ ulint val) /*!< in: integer value */
{
sym_node_t* node;
byte* data;
@@ -136,17 +137,17 @@ sym_tab_add_int_lit(
return(node);
}
-/**********************************************************************
-Adds a string literal to a symbol table. */
+/******************************************************************//**
+Adds a string literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_str_lit(
/*================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- byte* str, /* in: string with no quotes around
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ byte* str, /*!< in: string with no quotes around
it */
- ulint len) /* in: string length */
+ ulint len) /*!< in: string length */
{
sym_node_t* node;
byte* data;
@@ -183,16 +184,16 @@ sym_tab_add_str_lit(
return(node);
}
-/**********************************************************************
-Add a bound literal to a symbol table. */
+/******************************************************************//**
+Add a bound literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_bound_lit(
/*==================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- const char* name, /* in: name of bound literal */
- ulint* lit_type) /* out: type of literal (PARS_*_LIT) */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ const char* name, /*!< in: name of bound literal */
+ ulint* lit_type) /*!< out: type of literal (PARS_*_LIT) */
{
sym_node_t* node;
pars_bound_lit_t* blit;
@@ -259,14 +260,14 @@ sym_tab_add_bound_lit(
return(node);
}
-/**********************************************************************
-Adds an SQL null literal to a symbol table. */
+/******************************************************************//**
+Adds an SQL null literal to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_null_lit(
/*=================*/
- /* out: symbol table node */
- sym_tab_t* sym_tab) /* in: symbol table */
+ sym_tab_t* sym_tab) /*!< in: symbol table */
{
sym_node_t* node;
@@ -294,16 +295,16 @@ sym_tab_add_null_lit(
return(node);
}
-/**********************************************************************
-Adds an identifier to a symbol table. */
+/******************************************************************//**
+Adds an identifier to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_id(
/*===========*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- byte* name, /* in: identifier name */
- ulint len) /* in: identifier length */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ byte* name, /*!< in: identifier name */
+ ulint len) /*!< in: identifier length */
{
sym_node_t* node;
@@ -330,15 +331,15 @@ sym_tab_add_id(
return(node);
}
-/**********************************************************************
-Add a bound identifier to a symbol table. */
+/******************************************************************//**
+Add a bound identifier to a symbol table.
+@return symbol table node */
UNIV_INTERN
sym_node_t*
sym_tab_add_bound_id(
/*===========*/
- /* out: symbol table node */
- sym_tab_t* sym_tab, /* in: symbol table */
- const char* name) /* in: name of bound id */
+ sym_tab_t* sym_tab, /*!< in: symbol table */
+ const char* name) /*!< in: name of bound id */
{
sym_node_t* node;
pars_bound_id_t* bid;
diff --git a/storage/xtradb/plug.in b/storage/xtradb/plug.in
index 35c0ac750b0..ed9555bb512 100644
--- a/storage/xtradb/plug.in
+++ b/storage/xtradb/plug.in
@@ -40,6 +40,16 @@ MYSQL_PLUGIN_ACTIONS(innobase, [
irix*|osf*|sysv5uw7*|openbsd*)
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";;
*solaris*|*SunOS*)
+ # Begin Solaris atomic function checks
+ AC_CHECK_FUNCS(atomic_cas_ulong atomic_cas_32 \
+ atomic_cas_64 atomic_add_long,
+ AC_DEFINE(
+ [HAVE_SOLARIS_ATOMICS],
+ [1],
+ [Define to 1 if Solaris supports \
+ atomic functions.]))
+ ### End Solaris atomic function checks
+
CFLAGS="$CFLAGS -DUNIV_SOLARIS";;
esac
INNODB_DYNAMIC_CFLAGS="-DMYSQL_DYNAMIC_PLUGIN"
@@ -57,12 +67,17 @@ MYSQL_PLUGIN_ACTIONS(innobase, [
AC_TRY_RUN(
[
#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);
@@ -77,6 +92,65 @@ MYSQL_PLUGIN_ACTIONS(innobase, [
AC_MSG_RESULT(no)
]
)
+
+ # Try using solaris atomics on SunOS if GCC atomics are not available
+ AC_CHECK_DECLS(
+ [HAVE_ATOMIC_PTHREAD_T],
+ [
+ AC_MSG_NOTICE(no need to check pthread_t size)
+ ],
+ [
+ AC_CHECK_DECLS(
+ [HAVE_SOLARIS_ATOMICS],
+ [
+ AC_MSG_CHECKING(checking if pthread_t size is integral)
+ AC_TRY_RUN(
+ [
+ #include <pthread.h>
+ int main()
+ {
+ pthread_t x = 0;
+ return(0);
+ }
+ ],
+ [
+ AC_DEFINE([HAVE_ATOMIC_PTHREAD_T], [1],
+ [pthread_t can be used by solaris atomics])
+ AC_MSG_RESULT(yes)
+ # size of pthread_t is needed for typed solaris atomics
+ AC_CHECK_SIZEOF([pthread_t], [], [#include <pthread.h>])
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ])
+ ])
+ ])
+ # Check for x86 PAUSE instruction
+ AC_MSG_CHECKING(for x86 PAUSE instruction)
+ # We have to actually try running the test program, because of a bug
+ # in Solaris on x86_64, where it wrongly reports that PAUSE is not
+ # supported when trying to run an application. See
+ # http://bugs.opensolaris.org/bugdatabase/printableBug.do?bug_id=6478684
+ # We use ib_ prefix to avoid collisoins if this code is added to
+ # mysql's configure.in.
+ AC_TRY_RUN(
+ [
+ int main() {
+ __asm__ __volatile__ ("pause");
+ return(0);
+ }
+ ],
+ [
+ AC_DEFINE([IB_HAVE_PAUSE_INSTRUCTION], [1], [Does x86 PAUSE instruction exist])
+ AC_MSG_RESULT(yes)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ]
+ )
])
# vim: set ft=config:
diff --git a/storage/xtradb/que/que0que.c b/storage/xtradb/que/que0que.c
index 91a9d30ec4c..54b1e7535fa 100644
--- a/storage/xtradb/que/que0que.c
+++ b/storage/xtradb/que/que0que.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file que/que0que.c
Query graph
Created 5/27/1996 Heikki Tuuri
@@ -123,7 +124,7 @@ When the execution of the graph completes, it is like returning
from a subprocedure: the query thread which requested the operation
starts running again. */
-/**************************************************************************
+/**********************************************************************//**
Moves a thread from another state to the QUE_THR_RUNNING state. Increments
the n_active_thrs counters of the query graph and transaction.
***NOTE***: This is the only function in which such a transition is allowed
@@ -132,35 +133,35 @@ static
void
que_thr_move_to_run_state(
/*======================*/
- que_thr_t* thr); /* in: an query thread */
+ que_thr_t* thr); /*!< in: an query thread */
-/***************************************************************************
+/***********************************************************************//**
Adds a query graph to the session's list of graphs. */
UNIV_INTERN
void
que_graph_publish(
/*==============*/
- que_t* graph, /* in: graph */
- sess_t* sess) /* in: session */
+ que_t* graph, /*!< in: graph */
+ sess_t* sess) /*!< in: session */
{
ut_ad(mutex_own(&kernel_mutex));
UT_LIST_ADD_LAST(graphs, sess->graphs, graph);
}
-/***************************************************************************
-Creates a query graph fork node. */
+/***********************************************************************//**
+Creates a query graph fork node.
+@return own: fork node */
UNIV_INTERN
que_fork_t*
que_fork_create(
/*============*/
- /* out, own: fork node */
- que_t* graph, /* in: graph, if NULL then this
+ que_t* graph, /*!< in: graph, if NULL then this
fork node is assumed to be the
graph root */
- que_node_t* parent, /* in: parent node */
- ulint fork_type, /* in: fork type */
- mem_heap_t* heap) /* in: memory heap where created */
+ que_node_t* parent, /*!< in: parent node */
+ ulint fork_type, /*!< in: fork type */
+ mem_heap_t* heap) /*!< in: memory heap where created */
{
que_fork_t* fork;
@@ -194,15 +195,15 @@ que_fork_create(
return(fork);
}
-/***************************************************************************
-Creates a query graph thread node. */
+/***********************************************************************//**
+Creates a query graph thread node.
+@return own: query thread node */
UNIV_INTERN
que_thr_t*
que_thr_create(
/*===========*/
- /* out, own: query thread node */
- que_fork_t* parent, /* in: parent node, i.e., a fork node */
- mem_heap_t* heap) /* in: memory heap where created */
+ que_fork_t* parent, /*!< in: parent node, i.e., a fork node */
+ mem_heap_t* heap) /*!< in: memory heap where created */
{
que_thr_t* thr;
@@ -230,7 +231,7 @@ que_thr_create(
return(thr);
}
-/**************************************************************************
+/**********************************************************************//**
Moves a suspended query thread to the QUE_THR_RUNNING state and may release
a single worker thread to execute it. This function should be used to end
the wait state of a query thread waiting for a lock or a stored procedure
@@ -239,11 +240,11 @@ UNIV_INTERN
void
que_thr_end_wait(
/*=============*/
- que_thr_t* thr, /* in: query thread in the
+ que_thr_t* thr, /*!< in: query thread in the
QUE_THR_LOCK_WAIT,
or QUE_THR_PROCEDURE_WAIT, or
QUE_THR_SIG_REPLY_WAIT state */
- que_thr_t** next_thr) /* in/out: next query thread to run;
+ que_thr_t** next_thr) /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -278,13 +279,13 @@ que_thr_end_wait(
}
}
-/**************************************************************************
+/**********************************************************************//**
Same as que_thr_end_wait, but no parameter next_thr available. */
UNIV_INTERN
void
que_thr_end_wait_no_next_thr(
/*=========================*/
- que_thr_t* thr) /* in: query thread in the QUE_THR_LOCK_WAIT,
+ que_thr_t* thr) /*!< in: query thread in the QUE_THR_LOCK_WAIT,
or QUE_THR_PROCEDURE_WAIT, or
QUE_THR_SIG_REPLY_WAIT state */
{
@@ -315,13 +316,13 @@ que_thr_end_wait_no_next_thr(
/* srv_que_task_enqueue_low(thr); */
}
-/**************************************************************************
+/**********************************************************************//**
Inits a query thread for a command. */
UNIV_INLINE
void
que_thr_init_command(
/*=================*/
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
thr->run_node = thr;
thr->prev_node = thr->common.parent;
@@ -329,20 +330,19 @@ que_thr_init_command(
que_thr_move_to_run_state(thr);
}
-/**************************************************************************
+/**********************************************************************//**
Starts execution of a command in a query fork. Picks a query thread which
is not in the QUE_THR_RUNNING state and moves it to that state. If none
can be chosen, a situation which may arise in parallelized fetches, NULL
-is returned. */
+is returned.
+@return a query thread of the graph moved to QUE_THR_RUNNING state, or
+NULL; the query thread should be executed by que_run_threads by the
+caller */
UNIV_INTERN
que_thr_t*
que_fork_start_command(
/*===================*/
- /* out: a query thread of the graph moved to
- QUE_THR_RUNNING state, or NULL; the query
- thread should be executed by que_run_threads
- by the caller */
- que_fork_t* fork) /* in: a query fork */
+ que_fork_t* fork) /*!< in: a query fork */
{
que_thr_t* thr;
que_thr_t* suspended_thr = NULL;
@@ -418,7 +418,7 @@ que_fork_start_command(
return(thr);
}
-/**************************************************************************
+/**********************************************************************//**
After signal handling is finished, returns control to a query graph error
handling routine. (Currently, just returns the control to the root of the
graph so that the graph can communicate an error message to the client.) */
@@ -426,8 +426,8 @@ UNIV_INTERN
void
que_fork_error_handle(
/*==================*/
- trx_t* trx __attribute__((unused)), /* in: trx */
- que_t* fork) /* in: query graph which was run before signal
+ trx_t* trx __attribute__((unused)), /*!< in: trx */
+ que_t* fork) /*!< in: query graph which was run before signal
handling started, NULL not allowed */
{
que_thr_t* thr;
@@ -459,16 +459,16 @@ que_fork_error_handle(
srv_que_task_enqueue_low(thr);
}
-/********************************************************************
-Tests if all the query threads in the same fork have a given state. */
+/****************************************************************//**
+Tests if all the query threads in the same fork have a given state.
+@return TRUE if all the query threads in the same fork were in the
+given state */
UNIV_INLINE
ibool
que_fork_all_thrs_in_state(
/*=======================*/
- /* out: TRUE if all the query threads in the
- same fork were in the given state */
- que_fork_t* fork, /* in: query fork */
- ulint state) /* in: state */
+ que_fork_t* fork, /*!< in: query fork */
+ ulint state) /*!< in: state */
{
que_thr_t* thr_node;
@@ -486,13 +486,13 @@ que_fork_all_thrs_in_state(
return(TRUE);
}
-/**************************************************************************
+/**********************************************************************//**
Calls que_graph_free_recursive for statements in a statement list. */
static
void
que_graph_free_stat_list(
/*=====================*/
- que_node_t* node) /* in: first query graph node in the list */
+ que_node_t* node) /*!< in: first query graph node in the list */
{
while (node) {
que_graph_free_recursive(node);
@@ -501,14 +501,14 @@ que_graph_free_stat_list(
}
}
-/**************************************************************************
+/**********************************************************************//**
Frees a query graph, but not the heap where it was created. Does not free
explicit cursor declarations, they are freed in que_graph_free. */
UNIV_INTERN
void
que_graph_free_recursive(
/*=====================*/
- que_node_t* node) /* in: query graph node */
+ que_node_t* node) /*!< in: query graph node */
{
que_fork_t* fork;
que_thr_t* thr;
@@ -665,13 +665,13 @@ que_graph_free_recursive(
}
}
-/**************************************************************************
+/**********************************************************************//**
Frees a query graph. */
UNIV_INTERN
void
que_graph_free(
/*===========*/
- que_t* graph) /* in: query graph; we assume that the memory
+ que_t* graph) /*!< in: query graph; we assume that the memory
heap where this graph was created is private
to this graph: if not, then use
que_graph_free_recursive and free the heap
@@ -696,46 +696,14 @@ que_graph_free(
mem_heap_free(graph->heap);
}
-/**************************************************************************
-Checks if the query graph is in a state where it should be freed, and
-frees it in that case. If the session is in a state where it should be
-closed, also this is done. */
-UNIV_INTERN
-ibool
-que_graph_try_free(
-/*===============*/
- /* out: TRUE if freed */
- que_t* graph) /* in: query graph */
-{
- sess_t* sess;
-
- ut_ad(mutex_own(&kernel_mutex));
-
- sess = (graph->trx)->sess;
-
- if ((graph->state == QUE_FORK_BEING_FREED)
- && (graph->n_active_thrs == 0)) {
-
- UT_LIST_REMOVE(graphs, sess->graphs, graph);
- que_graph_free(graph);
-
- sess_try_close(sess);
-
- return(TRUE);
- }
-
- return(FALSE);
-}
-
-/********************************************************************
-Performs an execution step on a thr node. */
+/****************************************************************//**
+Performs an execution step on a thr node.
+@return query thread to run next, or NULL if none */
static
que_thr_t*
que_thr_node_step(
/*==============*/
- /* out: query thread to run next, or NULL
- if none */
- que_thr_t* thr) /* in: query thread where run_node must
+ que_thr_t* thr) /*!< in: query thread where run_node must
be the thread node itself */
{
ut_ad(thr->run_node == thr);
@@ -767,7 +735,7 @@ que_thr_node_step(
return(NULL);
}
-/**************************************************************************
+/**********************************************************************//**
Moves a thread from another state to the QUE_THR_RUNNING state. Increments
the n_active_thrs counters of the query graph and transaction if thr was
not active.
@@ -777,7 +745,7 @@ static
void
que_thr_move_to_run_state(
/*======================*/
- que_thr_t* thr) /* in: an query thread */
+ que_thr_t* thr) /*!< in: an query thread */
{
trx_t* trx;
@@ -800,7 +768,7 @@ que_thr_move_to_run_state(
thr->state = QUE_THR_RUNNING;
}
-/**************************************************************************
+/**********************************************************************//**
Decrements the query thread reference counts in the query graph and the
transaction. May start signal handling, e.g., a rollback.
*** NOTE ***:
@@ -812,8 +780,8 @@ static
void
que_thr_dec_refer_count(
/*====================*/
- que_thr_t* thr, /* in: query thread */
- que_thr_t** next_thr) /* in/out: next query thread to run;
+ que_thr_t* thr, /*!< in: query thread */
+ que_thr_t** next_thr) /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -902,7 +870,7 @@ que_thr_dec_refer_count(
break;
default:
- ut_error; /* not used in MySQL */
+ ut_error; /*!< not used in MySQL */
}
}
@@ -923,16 +891,16 @@ que_thr_dec_refer_count(
mutex_exit(&kernel_mutex);
}
-/**************************************************************************
+/**********************************************************************//**
Stops a query thread if graph or trx is in a state requiring it. The
conditions are tested in the order (1) graph, (2) trx. The kernel mutex has
-to be reserved. */
+to be reserved.
+@return TRUE if stopped */
UNIV_INTERN
ibool
que_thr_stop(
/*=========*/
- /* out: TRUE if stopped */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
trx_t* trx;
que_t* graph;
@@ -970,7 +938,7 @@ que_thr_stop(
return(ret);
}
-/**************************************************************************
+/**********************************************************************//**
A patch for MySQL used to 'stop' a dummy query thread used in MySQL. The
query thread is stopped and made inactive, except in the case where
it was put to the lock wait state in lock0lock.c, but the lock has already
@@ -979,7 +947,7 @@ UNIV_INTERN
void
que_thr_stop_for_mysql(
/*===================*/
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
trx_t* trx;
@@ -1017,7 +985,7 @@ que_thr_stop_for_mysql(
mutex_exit(&kernel_mutex);
}
-/**************************************************************************
+/**********************************************************************//**
Moves a thread from another state to the QUE_THR_RUNNING state. Increments
the n_active_thrs counters of the query graph and transaction if thr was
not active. */
@@ -1025,8 +993,8 @@ UNIV_INTERN
void
que_thr_move_to_run_state_for_mysql(
/*================================*/
- que_thr_t* thr, /* in: an query thread */
- trx_t* trx) /* in: transaction */
+ que_thr_t* thr, /*!< in: an query thread */
+ trx_t* trx) /*!< in: transaction */
{
if (thr->magic_n != QUE_THR_MAGIC_N) {
fprintf(stderr,
@@ -1050,15 +1018,15 @@ que_thr_move_to_run_state_for_mysql(
thr->state = QUE_THR_RUNNING;
}
-/**************************************************************************
+/**********************************************************************//**
A patch for MySQL used to 'stop' a dummy query thread used in MySQL
select, when there is no error or lock wait. */
UNIV_INTERN
void
que_thr_stop_for_mysql_no_error(
/*============================*/
- que_thr_t* thr, /* in: query thread */
- trx_t* trx) /* in: transaction */
+ que_thr_t* thr, /*!< in: query thread */
+ trx_t* trx) /*!< in: transaction */
{
ut_ad(thr->state == QUE_THR_RUNNING);
ut_ad(thr->is_active == TRUE);
@@ -1083,15 +1051,15 @@ que_thr_stop_for_mysql_no_error(
trx->n_active_thrs--;
}
-/********************************************************************
+/****************************************************************//**
Get the first containing loop node (e.g. while_node_t or for_node_t) for the
-given node, or NULL if the node is not within a loop. */
+given node, or NULL if the node is not within a loop.
+@return containing loop node, or NULL. */
UNIV_INTERN
que_node_t*
que_node_get_containing_loop_node(
/*==============================*/
- /* out: containing loop node, or NULL. */
- que_node_t* node) /* in: node */
+ que_node_t* node) /*!< in: node */
{
ut_ad(node);
@@ -1114,13 +1082,13 @@ que_node_get_containing_loop_node(
return(node);
}
-/**************************************************************************
+/**********************************************************************//**
Prints info of an SQL query graph node. */
UNIV_INTERN
void
que_node_print_info(
/*================*/
- que_node_t* node) /* in: query graph node */
+ que_node_t* node) /*!< in: query graph node */
{
ulint type;
const char* str;
@@ -1177,16 +1145,15 @@ que_node_print_info(
(ulong) type, str, (void*) node);
}
-/**************************************************************************
-Performs an execution step on a query thread. */
+/**********************************************************************//**
+Performs an execution step on a query thread.
+@return query thread to run next: it may differ from the input
+parameter if, e.g., a subprocedure call is made */
UNIV_INLINE
que_thr_t*
que_thr_step(
/*=========*/
- /* out: query thread to run next: it may
- differ from the input parameter if, e.g., a
- subprocedure call is made */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
que_node_t* node;
que_thr_t* old_thr;
@@ -1300,13 +1267,13 @@ que_thr_step(
return(thr);
}
-/**************************************************************************
+/**********************************************************************//**
Run a query thread until it finishes or encounters e.g. a lock wait. */
static
void
que_run_threads_low(
/*================*/
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
que_thr_t* next_thr;
ulint cumul_resource;
@@ -1360,13 +1327,13 @@ loop:
goto loop;
}
-/**************************************************************************
+/**********************************************************************//**
Run a query thread. Handles lock waits. */
UNIV_INTERN
void
que_run_threads(
/*============*/
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
loop:
ut_a(thr_get_trx(thr)->error_state == DB_SUCCESS);
@@ -1415,19 +1382,19 @@ loop:
mutex_exit(&kernel_mutex);
}
-/*************************************************************************
-Evaluate the given SQL. */
+/*********************************************************************//**
+Evaluate the given SQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
que_eval_sql(
/*=========*/
- /* out: error code or DB_SUCCESS */
- pars_info_t* info, /* in: info struct, or NULL */
- const char* sql, /* in: SQL string */
+ pars_info_t* info, /*!< in: info struct, or NULL */
+ const char* sql, /*!< in: SQL string */
ibool reserve_dict_mutex,
- /* in: if TRUE, acquire/release
+ /*!< in: if TRUE, acquire/release
dict_sys->mutex around call to pars_sql. */
- trx_t* trx) /* in: trx */
+ trx_t* trx) /*!< in: trx */
{
que_thr_t* thr;
que_t* graph;
diff --git a/storage/xtradb/read/read0read.c b/storage/xtradb/read/read0read.c
index e3e5ee5d623..85adae4ddff 100644
--- a/storage/xtradb/read/read0read.c
+++ b/storage/xtradb/read/read0read.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file read/read0read.c
Cursor read
Created 2/16/1997 Heikki Tuuri
@@ -136,39 +137,40 @@ TODO: proof this
*/
-/*************************************************************************
-Creates a read view object. */
+/*********************************************************************//**
+Creates a read view object.
+@return own: read view struct */
UNIV_INLINE
read_view_t*
read_view_create_low(
/*=================*/
- /* out, own: read view struct */
- ulint n, /* in: number of cells in the trx_ids array */
- mem_heap_t* heap) /* in: memory heap from which allocated */
+ ulint n, /*!< in: number of cells in the trx_ids array */
+ mem_heap_t* heap) /*!< in: memory heap from which allocated */
{
read_view_t* view;
view = mem_heap_alloc(heap, sizeof(read_view_t));
view->n_trx_ids = n;
- view->trx_ids = mem_heap_alloc(heap, n * sizeof(dulint));
+ view->trx_ids = mem_heap_alloc(heap, n * sizeof *view->trx_ids);
return(view);
}
-/*************************************************************************
+/*********************************************************************//**
Makes a copy of the oldest existing read view, with the exception that also
the creating trx of the oldest view is set as not visible in the 'copied'
view. Opens a new view if no views currently exist. The view must be closed
-with ..._close. This is used in purge. */
+with ..._close. This is used in purge.
+@return own: read view struct */
UNIV_INTERN
read_view_t*
read_view_oldest_copy_or_open_new(
/*==============================*/
- /* out, own: read view struct */
- dulint cr_trx_id, /* in: trx_id of creating
- transaction, or (0, 0) used in purge*/
- mem_heap_t* heap) /* in: memory heap from which
+ trx_id_t cr_trx_id, /*!< in: trx_id of creating
+ transaction, or ut_dulint_zero
+ used in purge */
+ mem_heap_t* heap) /*!< in: memory heap from which
allocated */
{
read_view_t* old_view;
@@ -241,18 +243,18 @@ read_view_oldest_copy_or_open_new(
return(view_copy);
}
-/*************************************************************************
+/*********************************************************************//**
Opens a read view where exactly the transactions serialized before this
-point in time are seen in the view. */
+point in time are seen in the view.
+@return own: read view struct */
UNIV_INTERN
read_view_t*
read_view_open_now(
/*===============*/
- /* out, own: read view struct */
- dulint cr_trx_id, /* in: trx_id of creating
- transaction, or (0, 0) used in
- purge */
- mem_heap_t* heap) /* in: memory heap from which
+ trx_id_t cr_trx_id, /*!< in: trx_id of creating
+ transaction, or ut_dulint_zero
+ used in purge */
+ mem_heap_t* heap) /*!< in: memory heap from which
allocated */
{
read_view_t* view;
@@ -316,27 +318,27 @@ read_view_open_now(
return(view);
}
-/*************************************************************************
+/*********************************************************************//**
Closes a read view. */
UNIV_INTERN
void
read_view_close(
/*============*/
- read_view_t* view) /* in: read view */
+ read_view_t* view) /*!< in: read view */
{
ut_ad(mutex_own(&kernel_mutex));
UT_LIST_REMOVE(view_list, trx_sys->view_list, view);
}
-/*************************************************************************
+/*********************************************************************//**
Closes a consistent read view for MySQL. This function is called at an SQL
statement end if the trx isolation level is <= TRX_ISO_READ_COMMITTED. */
UNIV_INTERN
void
read_view_close_for_mysql(
/*======================*/
- trx_t* trx) /* in: trx which has a read view */
+ trx_t* trx) /*!< in: trx which has a read view */
{
ut_a(trx->global_read_view);
@@ -352,13 +354,13 @@ read_view_close_for_mysql(
mutex_exit(&kernel_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
Prints a read view to stderr. */
UNIV_INTERN
void
read_view_print(
/*============*/
- read_view_t* view) /* in: read view */
+ const read_view_t* view) /*!< in: read view */
{
ulint n_ids;
ulint i;
@@ -393,7 +395,7 @@ read_view_print(
}
}
-/*************************************************************************
+/*********************************************************************//**
Create a high-granularity consistent cursor view for mysql to be used
in cursors. In this consistent read view modifications done by the
creating transaction after the cursor is created or future transactions
@@ -402,7 +404,7 @@ UNIV_INTERN
cursor_view_t*
read_cursor_view_create_for_mysql(
/*==============================*/
- trx_t* cr_trx) /* in: trx where cursor view is created */
+ trx_t* cr_trx) /*!< in: trx where cursor view is created */
{
cursor_view_t* curview;
read_view_t* view;
@@ -485,15 +487,15 @@ read_cursor_view_create_for_mysql(
return(curview);
}
-/*************************************************************************
+/*********************************************************************//**
Close a given consistent cursor view for mysql and restore global read view
back to a transaction read view. */
UNIV_INTERN
void
read_cursor_view_close_for_mysql(
/*=============================*/
- trx_t* trx, /* in: trx */
- cursor_view_t* curview)/* in: cursor view to be closed */
+ trx_t* trx, /*!< in: trx */
+ cursor_view_t* curview)/*!< in: cursor view to be closed */
{
ut_a(curview);
ut_a(curview->read_view);
@@ -513,7 +515,7 @@ read_cursor_view_close_for_mysql(
mem_heap_free(curview->heap);
}
-/*************************************************************************
+/*********************************************************************//**
This function sets a given consistent cursor view to a transaction
read view if given consistent cursor view is not NULL. Otherwise, function
restores a global read view to a transaction read view. */
@@ -521,8 +523,8 @@ UNIV_INTERN
void
read_cursor_set_for_mysql(
/*======================*/
- trx_t* trx, /* in: transaction where cursor is set */
- cursor_view_t* curview)/* in: consistent cursor view to be set */
+ trx_t* trx, /*!< in: transaction where cursor is set */
+ cursor_view_t* curview)/*!< in: consistent cursor view to be set */
{
ut_a(trx);
diff --git a/storage/xtradb/rem/rem0cmp.c b/storage/xtradb/rem/rem0cmp.c
index f8e5a6b88ff..3924ed69b82 100644
--- a/storage/xtradb/rem/rem0cmp.c
+++ b/storage/xtradb/rem/rem0cmp.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/***********************************************************************
+/*******************************************************************//**
+@file rem/rem0cmp.c
Comparison services for records
Created 7/1/1994 Heikki Tuuri
@@ -50,75 +51,70 @@ where two records disagree only in the way that one
has more fields than the other. */
#ifdef UNIV_DEBUG
-/*****************************************************************
+/*************************************************************//**
Used in debug checking of cmp_dtuple_... .
This function is used to compare a data tuple to a physical record. If
dtuple has n fields then rec must have either m >= n fields, or it must
-differ from dtuple in some of the m fields rec has. */
+differ from dtuple in some of the m fields rec has.
+@return 1, 0, -1, if dtuple is greater, equal, less than rec,
+respectively, when only the common first fields are compared */
static
int
cmp_debug_dtuple_rec_with_match(
/*============================*/
- /* out: 1, 0, -1, if dtuple is greater, equal,
- less than rec, respectively, when only the
- common first fields are compared */
- const dtuple_t* dtuple, /* in: data tuple */
- const rec_t* rec, /* in: physical record which differs from
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record which differs from
dtuple in some of the common fields, or which
has an equal number or more fields than
dtuple */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint* matched_fields);/* in/out: number of already
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint* matched_fields);/*!< in/out: number of already
completely matched fields; when function
returns, contains the value for current
comparison */
#endif /* UNIV_DEBUG */
-#ifndef UNIV_HOTBACKUP
-/*****************************************************************
+/*************************************************************//**
This function is used to compare two data fields for which the data type
is such that we must use MySQL code to compare them. The prototype here
-must be a copy of the the one in ha_innobase.cc! */
+must be a copy of the the one in ha_innobase.cc!
+@return 1, 0, -1, if a is greater, equal, less than b, respectively */
extern
int
innobase_mysql_cmp(
/*===============*/
- /* out: 1, 0, -1, if a is greater,
- equal, less than b, respectively */
- int mysql_type, /* in: MySQL type */
- uint charset_number, /* in: number of the charset */
- const unsigned char* a, /* in: data field */
- unsigned int a_length, /* in: data field length,
+ int mysql_type, /*!< in: MySQL type */
+ uint charset_number, /*!< in: number of the charset */
+ const unsigned char* a, /*!< in: data field */
+ unsigned int a_length, /*!< in: data field length,
not UNIV_SQL_NULL */
- const unsigned char* b, /* in: data field */
- unsigned int b_length); /* in: data field length,
+ const unsigned char* b, /*!< in: data field */
+ unsigned int b_length); /*!< in: data field length,
not UNIV_SQL_NULL */
-#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
+/*********************************************************************//**
Transforms the character code so that it is ordered appropriately for the
language. This is only used for the latin1 char set. MySQL does the
-comparisons for other char sets. */
+comparisons for other char sets.
+@return collation order position */
UNIV_INLINE
ulint
cmp_collate(
/*========*/
- /* out: collation order position */
- ulint code) /* in: code of a character stored in database record */
+ ulint code) /*!< in: code of a character stored in database record */
{
return((ulint) srv_latin1_ordering[code]);
}
-/*****************************************************************
-Returns TRUE if two columns are equal for comparison purposes. */
+/*************************************************************//**
+Returns TRUE if two columns are equal for comparison purposes.
+@return TRUE if the columns are considered equal in comparisons */
UNIV_INTERN
ibool
cmp_cols_are_equal(
/*===============*/
- /* out: TRUE if the columns are
- considered equal in comparisons */
- const dict_col_t* col1, /* in: column 1 */
- const dict_col_t* col2, /* in: column 2 */
+ const dict_col_t* col1, /*!< in: column 1 */
+ const dict_col_t* col2, /*!< in: column 2 */
ibool check_charsets)
- /* in: whether to check charsets */
+ /*!< in: whether to check charsets */
{
if (dtype_is_non_binary_string_type(col1->mtype, col1->prtype)
&& dtype_is_non_binary_string_type(col2->mtype, col2->prtype)) {
@@ -161,23 +157,21 @@ cmp_cols_are_equal(
return(col1->mtype != DATA_INT || col1->len == col2->len);
}
-#ifndef UNIV_HOTBACKUP
-/*****************************************************************
+/*************************************************************//**
Innobase uses this function to compare two data fields for which the data type
-is such that we must compare whole fields or call MySQL to do the comparison */
+is such that we must compare whole fields or call MySQL to do the comparison
+@return 1, 0, -1, if a is greater, equal, less than b, respectively */
static
int
cmp_whole_field(
/*============*/
- /* out: 1, 0, -1, if a is greater,
- equal, less than b, respectively */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- const byte* a, /* in: data field */
- unsigned int a_length, /* in: data field length,
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ const byte* a, /*!< in: data field */
+ unsigned int a_length, /*!< in: data field length,
not UNIV_SQL_NULL */
- const byte* b, /* in: data field */
- unsigned int b_length) /* in: data field length,
+ const byte* b, /*!< in: data field */
+ unsigned int b_length) /*!< in: data field length,
not UNIV_SQL_NULL */
{
float f_1;
@@ -288,27 +282,24 @@ cmp_whole_field(
return(0);
}
-#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+/*************************************************************//**
This function is used to compare two data fields for which we know the
-data type. */
+data type.
+@return 1, 0, -1, if data1 is greater, equal, less than data2, respectively */
UNIV_INTERN
int
cmp_data_data_slow(
/*===============*/
- /* out: 1, 0, -1, if data1 is greater, equal,
- less than data2, respectively */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- const byte* data1, /* in: data field (== a pointer to a memory
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ const byte* data1, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len1, /* in: data field length or UNIV_SQL_NULL */
- const byte* data2, /* in: data field (== a pointer to a memory
+ ulint len1, /*!< in: data field length or UNIV_SQL_NULL */
+ const byte* data2, /*!< in: data field (== a pointer to a memory
buffer) */
- ulint len2) /* in: data field length or UNIV_SQL_NULL */
+ ulint len2) /*!< in: data field length or UNIV_SQL_NULL */
{
-#ifndef UNIV_HOTBACKUP
ulint data1_byte;
ulint data2_byte;
ulint cur_bytes;
@@ -401,48 +392,39 @@ next_byte:
data1++;
data2++;
}
-#else /* !UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
-#endif /* !UNIV_HOTBACKUP */
return(0); /* Not reached */
}
-/*****************************************************************
+/*************************************************************//**
This function is used to compare a data tuple to a physical record.
Only dtuple->n_fields_cmp first fields are taken into account for
the the data tuple! If we denote by n = n_fields_cmp, then rec must
have either m >= n fields, or it must differ from dtuple in some of
the m fields rec has. If rec has an externally stored field we do not
compare it but return with value 0 if such a comparison should be
-made. */
+made.
+@return 1, 0, -1, if dtuple is greater, equal, less than rec,
+respectively, when only the common first fields are compared, or until
+the first externally stored field in rec */
UNIV_INTERN
int
cmp_dtuple_rec_with_match(
/*======================*/
- /* out: 1, 0, -1, if dtuple is greater, equal,
- less than rec, respectively, when only the
- common first fields are compared, or
- until the first externally stored field in
- rec */
- const dtuple_t* dtuple, /* in: data tuple */
- const rec_t* rec, /* in: physical record which differs from
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record which differs from
dtuple in some of the common fields, or which
has an equal number or more fields than
dtuple */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint* matched_fields, /* in/out: number of already completely
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint* matched_fields, /*!< in/out: number of already completely
matched fields; when function returns,
contains the value for current comparison */
- ulint* matched_bytes) /* in/out: number of already matched
+ ulint* matched_bytes) /*!< in/out: number of already matched
bytes within the first field not completely
matched; when function returns, contains the
value for current comparison */
{
-#ifndef UNIV_HOTBACKUP
const dfield_t* dtuple_field; /* current field in logical record */
ulint dtuple_f_len; /* the length of the current field
in the logical record */
@@ -650,27 +632,19 @@ order_resolved:
*matched_bytes = cur_bytes;
return(ret);
-#else /* !UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
- return(0);
-#endif /* !UNIV_HOTBACKUP */
}
-/******************************************************************
-Compares a data tuple to a physical record. */
+/**************************************************************//**
+Compares a data tuple to a physical record.
+@see cmp_dtuple_rec_with_match
+@return 1, 0, -1, if dtuple is greater, equal, less than rec, respectively */
UNIV_INTERN
int
cmp_dtuple_rec(
/*===========*/
- /* out: 1, 0, -1, if dtuple is greater, equal,
- less than rec, respectively; see the comments
- for cmp_dtuple_rec_with_match */
- const dtuple_t* dtuple, /* in: data tuple */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint matched_fields = 0;
ulint matched_bytes = 0;
@@ -680,17 +654,17 @@ cmp_dtuple_rec(
&matched_fields, &matched_bytes));
}
-/******************************************************************
+/**************************************************************//**
Checks if a dtuple is a prefix of a record. The last field in dtuple
-is allowed to be a prefix of the corresponding field in the record. */
+is allowed to be a prefix of the corresponding field in the record.
+@return TRUE if prefix */
UNIV_INTERN
ibool
cmp_dtuple_is_prefix_of_rec(
/*========================*/
- /* out: TRUE if prefix */
- const dtuple_t* dtuple, /* in: data tuple */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n_fields;
ulint matched_fields = 0;
@@ -720,33 +694,31 @@ cmp_dtuple_is_prefix_of_rec(
return(FALSE);
}
-#ifndef UNIV_HOTBACKUP
-/*****************************************************************
+/*************************************************************//**
Compare two physical records that contain the same number of columns,
-none of which are stored externally. */
+none of which are stored externally.
+@return 1, 0, -1 if rec1 is greater, equal, less, respectively, than rec2 */
UNIV_INTERN
int
cmp_rec_rec_simple(
/*===============*/
- /* out: 1, 0 , -1 if rec1 is greater,
- equal, less, respectively, than rec2 */
- const rec_t* rec1, /* in: physical record */
- const rec_t* rec2, /* in: physical record */
- const ulint* offsets1,/* in: rec_get_offsets(rec1, index) */
- const ulint* offsets2,/* in: rec_get_offsets(rec2, index) */
- const dict_index_t* index) /* in: data dictionary index */
+ const rec_t* rec1, /*!< in: physical record */
+ 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 */
{
- ulint rec1_f_len; /* length of current field in rec1 */
- const byte* rec1_b_ptr; /* pointer to the current byte
+ ulint rec1_f_len; /*!< length of current field in rec1 */
+ const byte* rec1_b_ptr; /*!< pointer to the current byte
in rec1 field */
- ulint rec1_byte; /* value of current byte to be
+ ulint rec1_byte; /*!< value of current byte to be
compared in rec1 */
- ulint rec2_f_len; /* length of current field in rec2 */
- const byte* rec2_b_ptr; /* pointer to the current byte
+ ulint rec2_f_len; /*!< length of current field in rec2 */
+ const byte* rec2_b_ptr; /*!< pointer to the current byte
in rec2 field */
- ulint rec2_byte; /* value of current byte to be
+ ulint rec2_byte; /*!< value of current byte to be
compared in rec2 */
- ulint cur_field; /* current field number */
+ ulint cur_field; /*!< current field number */
ulint n_uniq;
n_uniq = dict_index_get_n_unique(index);
@@ -870,35 +842,31 @@ next_field:
/* If we ran out of fields, rec1 was equal to rec2. */
return(0);
}
-#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+/*************************************************************//**
This function is used to compare two physical records. Only the common
first fields are compared, and if an externally stored field is
-encountered, then 0 is returned. */
+encountered, then 0 is returned.
+@return 1, 0, -1 if rec1 is greater, equal, less, respectively */
UNIV_INTERN
int
cmp_rec_rec_with_match(
/*===================*/
- /* out: 1, 0 , -1 if rec1 is greater, equal,
- less, respectively, than rec2; only the common
- first fields are compared */
- const rec_t* rec1, /* in: physical record */
- const rec_t* rec2, /* in: physical record */
- const ulint* offsets1,/* in: rec_get_offsets(rec1, index) */
- const ulint* offsets2,/* in: rec_get_offsets(rec2, index) */
- dict_index_t* index, /* in: data dictionary index */
- ulint* matched_fields, /* in/out: number of already completely
+ const rec_t* rec1, /*!< in: physical record */
+ const rec_t* rec2, /*!< in: physical record */
+ const ulint* offsets1,/*!< in: rec_get_offsets(rec1, index) */
+ const ulint* offsets2,/*!< in: rec_get_offsets(rec2, index) */
+ dict_index_t* index, /*!< in: data dictionary index */
+ ulint* matched_fields, /*!< in/out: number of already completely
matched fields; when the function returns,
contains the value the for current
comparison */
- ulint* matched_bytes, /* in/out: number of already matched
+ ulint* matched_bytes, /*!< in/out: number of already matched
bytes within the first field not completely
matched; when the function returns, contains
the value for the current comparison */
ulint stats_method)
{
-#ifndef UNIV_HOTBACKUP
ulint rec1_n_fields; /* the number of fields in rec */
ulint rec1_f_len; /* length of current field in rec */
const byte* rec1_b_ptr; /* pointer to the current byte
@@ -1116,36 +1084,28 @@ order_resolved:
*matched_bytes = cur_bytes;
return(ret);
-#else /* !UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
- return(0);
-#endif /* !UNIV_HOTBACKUP */
}
#ifdef UNIV_DEBUG
-/*****************************************************************
+/*************************************************************//**
Used in debug checking of cmp_dtuple_... .
This function is used to compare a data tuple to a physical record. If
dtuple has n fields then rec must have either m >= n fields, or it must
differ from dtuple in some of the m fields rec has. If encounters an
-externally stored field, returns 0. */
+externally stored field, returns 0.
+@return 1, 0, -1, if dtuple is greater, equal, less than rec,
+respectively, when only the common first fields are compared */
static
int
cmp_debug_dtuple_rec_with_match(
/*============================*/
- /* out: 1, 0, -1, if dtuple is greater, equal,
- less than rec, respectively, when only the
- common first fields are compared */
- const dtuple_t* dtuple, /* in: data tuple */
- const rec_t* rec, /* in: physical record which differs from
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ const rec_t* rec, /*!< in: physical record which differs from
dtuple in some of the common fields, or which
has an equal number or more fields than
dtuple */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint* matched_fields) /* in/out: number of already
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint* matched_fields) /*!< in/out: number of already
completely matched fields; when function
returns, contains the value for current
comparison */
diff --git a/storage/xtradb/rem/rem0rec.c b/storage/xtradb/rem/rem0rec.c
index d6899c810e3..1c8b3fd8c1e 100644
--- a/storage/xtradb/rem/rem0rec.c
+++ b/storage/xtradb/rem/rem0rec.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file rem/rem0rec.c
Record manager
Created 5/30/1994 Heikki Tuuri
@@ -143,26 +144,26 @@ the corresponding canonical strings have the same property. */
/* this is used to fool compiler in rec_validate */
UNIV_INTERN ulint rec_dummy;
-/*******************************************************************
-Validates the consistency of an old-style physical record. */
+/***************************************************************//**
+Validates the consistency of an old-style physical record.
+@return TRUE if ok */
static
ibool
rec_validate_old(
/*=============*/
- /* out: TRUE if ok */
- const rec_t* rec); /* in: physical record */
+ const rec_t* rec); /*!< in: physical record */
-/**********************************************************
+/******************************************************//**
Determine how many of the first n columns in a compact
-physical record are stored externally. */
+physical record are stored externally.
+@return number of externally stored columns */
UNIV_INTERN
ulint
rec_get_n_extern_new(
/*=================*/
- /* out: number of externally stored columns */
- const rec_t* rec, /* in: compact physical record */
- dict_index_t* index, /* in: record descriptor */
- ulint n) /* in: number of columns to scan */
+ const rec_t* rec, /*!< in: compact physical record */
+ dict_index_t* index, /*!< in: record descriptor */
+ ulint n) /*!< in: number of columns to scan */
{
const byte* nulls;
const byte* lens;
@@ -227,7 +228,7 @@ rec_get_n_extern_new(
return(n_extern);
}
-/**********************************************************
+/******************************************************//**
Determine the offset to each field in a leaf-page record
in ROW_FORMAT=COMPACT. This is a special case of
rec_init_offsets() and rec_get_offsets_func(). */
@@ -235,14 +236,14 @@ UNIV_INTERN
void
rec_init_offsets_comp_ordinary(
/*===========================*/
- const rec_t* rec, /* in: physical record in
+ const rec_t* rec, /*!< in: physical record in
ROW_FORMAT=COMPACT */
- ulint extra, /* in: number of bytes to reserve
+ ulint extra, /*!< in: number of bytes to reserve
between the record header and
the data payload
(usually REC_N_NEW_EXTRA_BYTES) */
- const dict_index_t* index, /* in: record descriptor */
- ulint* offsets)/* in/out: array of offsets;
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets)/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
{
ulint i = 0;
@@ -329,7 +330,7 @@ resolved:
= (rec - (lens + 1)) | REC_OFFS_COMPACT | any_ext;
}
-/**********************************************************
+/******************************************************//**
The following function determines the offsets to each field in the
record. The offsets are written to a previously allocated array of
ulint, where rec_offs_n_fields(offsets) has been initialized to the
@@ -347,9 +348,9 @@ static
void
rec_init_offsets(
/*=============*/
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index, /* in: record descriptor */
- ulint* offsets)/* in/out: array of offsets;
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets)/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
{
ulint i = 0;
@@ -491,26 +492,26 @@ resolved:
}
}
-/**********************************************************
+/******************************************************//**
The following function determines the offsets to each field
-in the record. It can reuse a previously returned array. */
+in the record. It can reuse a previously returned array.
+@return the new offsets */
UNIV_INTERN
ulint*
rec_get_offsets_func(
/*=================*/
- /* out: the new offsets */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index, /* in: record descriptor */
- ulint* offsets,/* in/out: array consisting of
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets,/*!< in/out: array consisting of
offsets[0] allocated elements,
or an array from rec_get_offsets(),
or NULL */
- ulint n_fields,/* in: maximum number of
+ ulint n_fields,/*!< in: maximum number of
initialized fields
(ULINT_UNDEFINED if all fields) */
- mem_heap_t** heap, /* in/out: memory heap */
- const char* file, /* in: file name where called */
- ulint line) /* in: line number where called */
+ mem_heap_t** heap, /*!< in/out: memory heap */
+ const char* file, /*!< in: file name where called */
+ ulint line) /*!< in: line number where called */
{
ulint n;
ulint size;
@@ -563,21 +564,21 @@ rec_get_offsets_func(
return(offsets);
}
-/**********************************************************
+/******************************************************//**
The following function determines the offsets to each field
in the record. It can reuse a previously allocated array. */
UNIV_INTERN
void
rec_get_offsets_reverse(
/*====================*/
- const byte* extra, /* in: the extra bytes of a
+ const byte* extra, /*!< in: the extra bytes of a
compact record in reverse order,
excluding the fixed-size
REC_N_NEW_EXTRA_BYTES */
- const dict_index_t* index, /* in: record descriptor */
- ulint node_ptr,/* in: nonzero=node pointer,
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint node_ptr,/*!< in: nonzero=node pointer,
0=leaf node */
- ulint* offsets)/* in/out: array consisting of
+ ulint* offsets)/*!< in/out: array consisting of
offsets[0] allocated elements */
{
ulint n;
@@ -678,17 +679,17 @@ resolved:
| REC_OFFS_COMPACT | any_ext;
}
-/****************************************************************
+/************************************************************//**
The following function is used to get the offset to the nth
-data field in an old-style record. */
+data field in an old-style record.
+@return offset to the field */
UNIV_INTERN
ulint
rec_get_nth_field_offs_old(
/*=======================*/
- /* out: offset to the field */
- const rec_t* rec, /* in: record */
- ulint n, /* in: index of the field */
- ulint* len) /* out: length of the field;
+ const rec_t* rec, /*!< in: record */
+ ulint n, /*!< in: index of the field */
+ ulint* len) /*!< out: length of the field;
UNIV_SQL_NULL if SQL null */
{
ulint os;
@@ -742,20 +743,20 @@ rec_get_nth_field_offs_old(
return(os);
}
-/**************************************************************
-Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT. */
+/**********************************************************//**
+Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
+@return total size */
UNIV_INTERN
ulint
rec_get_converted_size_comp_prefix(
/*===============================*/
- /* out: total size */
- const dict_index_t* index, /* in: record descriptor;
+ const dict_index_t* index, /*!< in: record descriptor;
dict_table_is_comp() is
assumed to hold, even if
it does not */
- const dfield_t* fields, /* in: array of data fields */
- ulint n_fields,/* in: number of data fields */
- ulint* extra) /* out: extra size */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint* extra) /*!< out: extra size */
{
ulint extra_size;
ulint data_size;
@@ -817,21 +818,21 @@ rec_get_converted_size_comp_prefix(
return(extra_size + data_size);
}
-/**************************************************************
-Determines the size of a data tuple in ROW_FORMAT=COMPACT. */
+/**********************************************************//**
+Determines the size of a data tuple in ROW_FORMAT=COMPACT.
+@return total size */
UNIV_INTERN
ulint
rec_get_converted_size_comp(
/*========================*/
- /* out: total size */
- const dict_index_t* index, /* in: record descriptor;
+ const dict_index_t* index, /*!< in: record descriptor;
dict_table_is_comp() is
assumed to hold, even if
it does not */
- ulint status, /* in: status bits of the record */
- const dfield_t* fields, /* in: array of data fields */
- ulint n_fields,/* in: number of data fields */
- ulint* extra) /* out: extra size */
+ ulint status, /*!< in: status bits of the record */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint* extra) /*!< out: extra size */
{
ulint size;
ut_ad(index);
@@ -865,15 +866,15 @@ rec_get_converted_size_comp(
n_fields, extra));
}
-/***************************************************************
+/***********************************************************//**
Sets the value of the ith field SQL null bit of an old-style record. */
UNIV_INTERN
void
rec_set_nth_field_null_bit(
/*=======================*/
- rec_t* rec, /* in: record */
- ulint i, /* in: ith field */
- ibool val) /* in: value to set */
+ rec_t* rec, /*!< in: record */
+ ulint i, /*!< in: ith field */
+ ibool val) /*!< in: value to set */
{
ulint info;
@@ -903,15 +904,15 @@ rec_set_nth_field_null_bit(
rec_2_set_field_end_info(rec, i, info);
}
-/***************************************************************
+/***********************************************************//**
Sets an old-style record field to SQL null.
The physical size of the field is not changed. */
UNIV_INTERN
void
rec_set_nth_field_sql_null(
/*=======================*/
- rec_t* rec, /* in: record */
- ulint n) /* in: index of the field */
+ rec_t* rec, /*!< in: record */
+ ulint n) /*!< in: index of the field */
{
ulint offset;
@@ -922,18 +923,17 @@ rec_set_nth_field_sql_null(
rec_set_nth_field_null_bit(rec, n, TRUE);
}
-/*************************************************************
+/*********************************************************//**
Builds an old-style physical record out of a data tuple and
-stores it beginning from the start of the given buffer. */
+stores it beginning from the start of the given buffer.
+@return pointer to the origin of physical record */
static
rec_t*
rec_convert_dtuple_to_rec_old(
/*==========================*/
- /* out: pointer to the origin of
- physical record */
- byte* buf, /* in: start address of the physical record */
- const dtuple_t* dtuple, /* in: data tuple */
- ulint n_ext) /* in: number of externally stored columns */
+ byte* buf, /*!< in: start address of the physical record */
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ ulint n_ext) /*!< in: number of externally stored columns */
{
const dfield_t* field;
ulint n_fields;
@@ -949,7 +949,7 @@ rec_convert_dtuple_to_rec_old(
ut_ad(dtuple_check_typed(dtuple));
n_fields = dtuple_get_n_fields(dtuple);
- data_size = dtuple_get_data_size(dtuple);
+ data_size = dtuple_get_data_size(dtuple, 0);
ut_ad(n_fields > 0);
@@ -982,7 +982,7 @@ rec_convert_dtuple_to_rec_old(
if (dfield_is_null(field)) {
len = dtype_get_sql_null_size(
- dfield_get_type(field));
+ dfield_get_type(field), 0);
data_write_sql_null(rec + end_offset, len);
end_offset += len;
@@ -1010,7 +1010,7 @@ rec_convert_dtuple_to_rec_old(
if (dfield_is_null(field)) {
len = dtype_get_sql_null_size(
- dfield_get_type(field));
+ dfield_get_type(field), 0);
data_write_sql_null(rec + end_offset, len);
end_offset += len;
@@ -1038,21 +1038,21 @@ rec_convert_dtuple_to_rec_old(
return(rec);
}
-/*************************************************************
+/*********************************************************//**
Builds a ROW_FORMAT=COMPACT record out of a data tuple. */
UNIV_INTERN
void
rec_convert_dtuple_to_rec_comp(
/*===========================*/
- rec_t* rec, /* in: origin of record */
- ulint extra, /* in: number of bytes to
+ rec_t* rec, /*!< in: origin of record */
+ ulint extra, /*!< in: number of bytes to
reserve between the record
header and the data payload
(normally REC_N_NEW_EXTRA_BYTES) */
- const dict_index_t* index, /* in: record descriptor */
- ulint status, /* in: status bits of the record */
- const dfield_t* fields, /* in: array of data fields */
- ulint n_fields)/* in: number of data fields */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint status, /*!< in: status bits of the record */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields)/*!< in: number of data fields */
{
const dfield_t* field;
const dtype_t* type;
@@ -1160,19 +1160,18 @@ rec_convert_dtuple_to_rec_comp(
}
}
-/*************************************************************
+/*********************************************************//**
Builds a new-style physical record out of a data tuple and
-stores it beginning from the start of the given buffer. */
+stores it beginning from the start of the given buffer.
+@return pointer to the origin of physical record */
static
rec_t*
rec_convert_dtuple_to_rec_new(
/*==========================*/
- /* out: pointer to the origin
- of physical record */
- byte* buf, /* in: start address of
+ byte* buf, /*!< in: start address of
the physical record */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* dtuple) /* in: data tuple */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* dtuple) /*!< in: data tuple */
{
ulint extra_size;
ulint status;
@@ -1194,20 +1193,19 @@ rec_convert_dtuple_to_rec_new(
return(rec);
}
-/*************************************************************
+/*********************************************************//**
Builds a physical record out of a data tuple and
-stores it beginning from the start of the given buffer. */
+stores it beginning from the start of the given buffer.
+@return pointer to the origin of physical record */
UNIV_INTERN
rec_t*
rec_convert_dtuple_to_rec(
/*======================*/
- /* out: pointer to the origin
- of physical record */
- byte* buf, /* in: start address of the
+ byte* buf, /*!< in: start address of the
physical record */
- const dict_index_t* index, /* in: record descriptor */
- const dtuple_t* dtuple, /* in: data tuple */
- ulint n_ext) /* in: number of
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dtuple_t* dtuple, /*!< in: data tuple */
+ ulint n_ext) /*!< in: number of
externally stored columns */
{
rec_t* rec;
@@ -1240,19 +1238,19 @@ rec_convert_dtuple_to_rec(
return(rec);
}
-/******************************************************************
+/**************************************************************//**
Copies the first n fields of a physical record to a data tuple. The fields
are copied to the memory heap. */
UNIV_INTERN
void
rec_copy_prefix_to_dtuple(
/*======================*/
- dtuple_t* tuple, /* out: data tuple */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index, /* in: record descriptor */
- ulint n_fields, /* in: number of fields
+ dtuple_t* tuple, /*!< out: data tuple */
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint n_fields, /*!< in: number of fields
to copy */
- mem_heap_t* heap) /* in: memory heap */
+ mem_heap_t* heap) /*!< in: memory heap */
{
ulint i;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
@@ -1285,20 +1283,20 @@ rec_copy_prefix_to_dtuple(
}
}
-/******************************************************************
+/**************************************************************//**
Copies the first n fields of an old-style physical record
-to a new physical record in a buffer. */
+to a new physical record in a buffer.
+@return own: copied record */
static
rec_t*
rec_copy_prefix_to_buf_old(
/*=======================*/
- /* out, own: copied record */
- const rec_t* rec, /* in: physical record */
- ulint n_fields, /* in: number of fields to copy */
- ulint area_end, /* in: end of the prefix data */
- byte** buf, /* in/out: memory buffer for
+ const rec_t* rec, /*!< in: physical record */
+ ulint n_fields, /*!< in: number of fields to copy */
+ ulint area_end, /*!< in: end of the prefix data */
+ byte** buf, /*!< in/out: memory buffer for
the copied prefix, or NULL */
- ulint* buf_size) /* in/out: buffer size */
+ ulint* buf_size) /*!< in/out: buffer size */
{
rec_t* copy_rec;
ulint area_start;
@@ -1329,22 +1327,22 @@ rec_copy_prefix_to_buf_old(
return(copy_rec);
}
-/******************************************************************
+/**************************************************************//**
Copies the first n fields of a physical record to a new physical record in
-a buffer. */
+a buffer.
+@return own: copied record */
UNIV_INTERN
rec_t*
rec_copy_prefix_to_buf(
/*===================*/
- /* out, own: copied record */
- const rec_t* rec, /* in: physical record */
- const dict_index_t* index, /* in: record descriptor */
- ulint n_fields, /* in: number of fields
+ const rec_t* rec, /*!< in: physical record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint n_fields, /*!< in: number of fields
to copy */
- byte** buf, /* in/out: memory buffer
+ byte** buf, /*!< in/out: memory buffer
for the copied prefix,
or NULL */
- ulint* buf_size) /* in/out: buffer size */
+ ulint* buf_size) /*!< in/out: buffer size */
{
const byte* nulls;
const byte* lens;
@@ -1444,14 +1442,14 @@ rec_copy_prefix_to_buf(
return(*buf + (rec - (lens + 1)));
}
-/*******************************************************************
-Validates the consistency of an old-style physical record. */
+/***************************************************************//**
+Validates the consistency of an old-style physical record.
+@return TRUE if ok */
static
ibool
rec_validate_old(
/*=============*/
- /* out: TRUE if ok */
- const rec_t* rec) /* in: physical record */
+ const rec_t* rec) /*!< in: physical record */
{
const byte* data;
ulint len;
@@ -1504,15 +1502,15 @@ rec_validate_old(
return(TRUE);
}
-/*******************************************************************
-Validates the consistency of a physical record. */
+/***************************************************************//**
+Validates the consistency of a physical record.
+@return TRUE if ok */
UNIV_INTERN
ibool
rec_validate(
/*=========*/
- /* out: TRUE if ok */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
const byte* data;
ulint len;
@@ -1571,14 +1569,14 @@ rec_validate(
return(TRUE);
}
-/*******************************************************************
+/***************************************************************//**
Prints an old-style physical record. */
UNIV_INTERN
void
rec_print_old(
/*==========*/
- FILE* file, /* in: file where to print */
- const rec_t* rec) /* in: physical record */
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec) /*!< in: physical record */
{
const byte* data;
ulint len;
@@ -1623,16 +1621,17 @@ rec_print_old(
rec_validate_old(rec);
}
-/*******************************************************************
+#ifndef UNIV_HOTBACKUP
+/***************************************************************//**
Prints a physical record in ROW_FORMAT=COMPACT. Ignores the
record header. */
UNIV_INTERN
void
rec_print_comp(
/*===========*/
- FILE* file, /* in: file where to print */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint i;
@@ -1662,15 +1661,15 @@ rec_print_comp(
}
}
-/*******************************************************************
+/***************************************************************//**
Prints a physical record. */
UNIV_INTERN
void
rec_print_new(
/*==========*/
- FILE* file, /* in: file where to print */
- const rec_t* rec, /* in: physical record */
- const ulint* offsets)/* in: array returned by rec_get_offsets() */
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec, /*!< in: physical record */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec);
ut_ad(offsets);
@@ -1690,15 +1689,15 @@ rec_print_new(
rec_validate(rec, offsets);
}
-/*******************************************************************
+/***************************************************************//**
Prints a physical record. */
UNIV_INTERN
void
rec_print(
/*======*/
- FILE* file, /* in: file where to print */
- const rec_t* rec, /* in: physical record */
- dict_index_t* index) /* in: record descriptor */
+ FILE* file, /*!< in: file where to print */
+ const rec_t* rec, /*!< in: physical record */
+ dict_index_t* index) /*!< in: record descriptor */
{
ut_ad(index);
@@ -1718,3 +1717,4 @@ rec_print(
}
}
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/row/row0ext.c b/storage/xtradb/row/row0ext.c
index 83dfa024ffc..7320f5b1dca 100644
--- a/storage/xtradb/row/row0ext.c
+++ b/storage/xtradb/row/row0ext.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0ext.c
Caching of externally stored column prefixes
Created September 2006 Marko Makela
@@ -30,16 +31,16 @@ Created September 2006 Marko Makela
#include "btr0cur.h"
-/************************************************************************
+/********************************************************************//**
Fills the column prefix cache of an externally stored column. */
static
void
row_ext_cache_fill(
/*===============*/
- row_ext_t* ext, /* in/out: column prefix cache */
- ulint i, /* in: index of ext->ext[] */
- ulint zip_size,/* compressed page size in bytes, or 0 */
- const dfield_t* dfield) /* in: data field */
+ row_ext_t* ext, /*!< in/out: column prefix cache */
+ ulint i, /*!< in: index of ext->ext[] */
+ ulint zip_size,/*!< compressed page size in bytes, or 0 */
+ const dfield_t* dfield) /*!< in: data field */
{
const byte* field = dfield_get_data(dfield);
ulint f_len = dfield_get_len(dfield);
@@ -66,26 +67,26 @@ row_ext_cache_fill(
}
}
-/************************************************************************
-Creates a cache of column prefixes of externally stored columns. */
+/********************************************************************//**
+Creates a cache of column prefixes of externally stored columns.
+@return own: column prefix cache */
UNIV_INTERN
row_ext_t*
row_ext_create(
/*===========*/
- /* out,own: column prefix cache */
- ulint n_ext, /* in: number of externally stored columns */
- const ulint* ext, /* in: col_no's of externally stored columns
+ ulint n_ext, /*!< in: number of externally stored columns */
+ const ulint* ext, /*!< in: col_no's of externally stored columns
in the InnoDB table object, as reported by
dict_col_get_no(); NOT relative to the records
in the clustered index */
- const dtuple_t* tuple, /* in: data tuple containing the field
+ const dtuple_t* tuple, /*!< in: data tuple containing the field
references of the externally stored
columns; must be indexed by col_no;
the clustered index record must be
covered by a lock or a page latch
to prevent deletion (rollback or purge). */
- ulint zip_size,/* compressed page size in bytes, or 0 */
- mem_heap_t* heap) /* in: heap where created */
+ ulint zip_size,/*!< compressed page size in bytes, or 0 */
+ mem_heap_t* heap) /*!< in: heap where created */
{
ulint i;
row_ext_t* ret = mem_heap_alloc(heap, (sizeof *ret)
diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c
index ceb0f7d75a2..930c9ec1fc7 100644
--- a/storage/xtradb/row/row0ins.c
+++ b/storage/xtradb/row/row0ins.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0ins.c
Insert into a table
Created 4/20/1996 Heikki Tuuri
@@ -28,6 +29,7 @@ Created 4/20/1996 Heikki Tuuri
#include "row0ins.ic"
#endif
+#include "ha_prototypes.h"
#include "dict0dict.h"
#include "dict0boot.h"
#include "trx0undo.h"
@@ -50,33 +52,16 @@ Created 4/20/1996 Heikki Tuuri
#define ROW_INS_NEXT 2
-/*********************************************************************
-This prototype is copied from /mysql/sql/ha_innodb.cc.
-Invalidates the MySQL query cache for the table.
-NOTE that the exact prototype of this function has to be in
-/xtradb/row/row0ins.c! */
-extern
-void
-innobase_invalidate_query_cache(
-/*============================*/
- trx_t* trx, /* in: transaction which modifies the table */
- char* full_name, /* in: concatenation of database name, null
- char '\0', table name, null char'\0';
- NOTE that in Windows this is always
- in LOWER CASE! */
- ulint full_name_len); /* in: full name length where also the null
- chars count */
-
-/*************************************************************************
-Creates an insert node struct. */
+/*********************************************************************//**
+Creates an insert node struct.
+@return own: insert node struct */
UNIV_INTERN
ins_node_t*
ins_node_create(
/*============*/
- /* out, own: insert node struct */
- ulint ins_type, /* in: INS_VALUES, ... */
- dict_table_t* table, /* in: table where to insert */
- mem_heap_t* heap) /* in: mem heap where created */
+ ulint ins_type, /*!< in: INS_VALUES, ... */
+ dict_table_t* table, /*!< in: table where to insert */
+ mem_heap_t* heap) /*!< in: mem heap where created */
{
ins_node_t* node;
@@ -102,13 +87,13 @@ ins_node_create(
return(node);
}
-/***************************************************************
+/***********************************************************//**
Creates an entry template for each index of a table. */
UNIV_INTERN
void
ins_node_create_entry_list(
/*=======================*/
- ins_node_t* node) /* in: row insert node */
+ ins_node_t* node) /*!< in: row insert node */
{
dict_index_t* index;
dtuple_t* entry;
@@ -128,13 +113,13 @@ ins_node_create_entry_list(
}
}
-/*********************************************************************
+/*****************************************************************//**
Adds system field buffers to a row. */
static
void
row_ins_alloc_sys_fields(
/*=====================*/
- ins_node_t* node) /* in: insert node */
+ ins_node_t* node) /*!< in: insert node */
{
dtuple_t* row;
dict_table_t* table;
@@ -183,7 +168,7 @@ row_ins_alloc_sys_fields(
dfield_set_data(dfield, ptr, DATA_ROLL_PTR_LEN);
}
-/*************************************************************************
+/*********************************************************************//**
Sets a new row to insert for an INS_DIRECT node. This function is only used
if we have constructed the row separately, which is a rare case; this
function is quite slow. */
@@ -191,8 +176,8 @@ UNIV_INTERN
void
ins_node_set_new_row(
/*=================*/
- ins_node_t* node, /* in: insert node */
- dtuple_t* row) /* in: new row (or first row) for the node */
+ ins_node_t* node, /*!< in: insert node */
+ dtuple_t* row) /*!< in: new row (or first row) for the node */
{
node->state = INS_NODE_SET_IX_LOCK;
node->index = NULL;
@@ -216,22 +201,22 @@ ins_node_set_new_row(
node->trx_id = ut_dulint_zero;
}
-/***********************************************************************
+/*******************************************************************//**
Does an insert operation by updating a delete-marked existing record
in the index. This situation can occur if the delete-marked record is
-kept in the index for consistent reads. */
+kept in the index for consistent reads.
+@return DB_SUCCESS or error code */
static
ulint
row_ins_sec_index_entry_by_modify(
/*==============================*/
- /* out: DB_SUCCESS or error code */
- ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
+ ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
depending on whether mtr holds just a leaf
latch or also a tree latch */
- btr_cur_t* cursor, /* in: B-tree cursor */
- const dtuple_t* entry, /* in: index entry to insert */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr; must be committed before
+ btr_cur_t* cursor, /*!< in: B-tree cursor */
+ const dtuple_t* entry, /*!< in: index entry to insert */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr; must be committed before
latching any further pages */
{
big_rec_t* dummy_big_rec;
@@ -287,26 +272,26 @@ func_exit:
return(err);
}
-/***********************************************************************
+/*******************************************************************//**
Does an insert operation by delete unmarking and updating a delete marked
existing record in the index. This situation can occur if the delete marked
-record is kept in the index for consistent reads. */
+record is kept in the index for consistent reads.
+@return DB_SUCCESS, DB_FAIL, or error code */
static
ulint
row_ins_clust_index_entry_by_modify(
/*================================*/
- /* out: DB_SUCCESS, DB_FAIL, or error code */
- ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
+ ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
depending on whether mtr holds just a leaf
latch or also a tree latch */
- btr_cur_t* cursor, /* in: B-tree cursor */
- mem_heap_t** heap, /* in/out: pointer to memory heap, or NULL */
- big_rec_t** big_rec,/* out: possible big rec vector of fields
+ btr_cur_t* cursor, /*!< in: B-tree cursor */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
+ big_rec_t** big_rec,/*!< out: possible big rec vector of fields
which have to be stored externally by the
caller */
- const dtuple_t* entry, /* in: index entry to insert */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr; must be committed before
+ const dtuple_t* entry, /*!< in: index entry to insert */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr; must be committed before
latching any further pages */
{
rec_t* rec;
@@ -359,16 +344,16 @@ row_ins_clust_index_entry_by_modify(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Returns TRUE if in a cascaded update/delete an ancestor node of node
-updates (not DELETE, but UPDATE) table. */
+updates (not DELETE, but UPDATE) table.
+@return TRUE if an ancestor updates table */
static
ibool
row_ins_cascade_ancestor_updates_table(
/*===================================*/
- /* out: TRUE if an ancestor updates table */
- que_node_t* node, /* in: node in a query graph */
- dict_table_t* table) /* in: table */
+ que_node_t* node, /*!< in: node in a query graph */
+ dict_table_t* table) /*!< in: table */
{
que_node_t* parent;
upd_node_t* upd_node;
@@ -392,15 +377,15 @@ row_ins_cascade_ancestor_updates_table(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Returns the number of ancestor UPDATE or DELETE nodes of a
-cascaded update/delete node. */
+cascaded update/delete node.
+@return number of ancestors */
static
ulint
row_ins_cascade_n_ancestors(
/*========================*/
- /* out: number of ancestors */
- que_node_t* node) /* in: node in a query graph */
+ que_node_t* node) /*!< in: node in a query graph */
{
que_node_t* parent;
ulint n_ancestors = 0;
@@ -418,26 +403,22 @@ row_ins_cascade_n_ancestors(
return(n_ancestors);
}
-/**********************************************************************
+/******************************************************************//**
Calculates the update vector node->cascade->update for a child table in
-a cascaded update. */
+a cascaded update.
+@return number of fields in the calculated update vector; the value
+can also be 0 if no foreign key fields changed; the returned value is
+ULINT_UNDEFINED if the column type in the child table is too short to
+fit the new value in the parent table: that means the update fails */
static
ulint
row_ins_cascade_calc_update_vec(
/*============================*/
- /* out: number of fields in the
- calculated update vector; the value
- can also be 0 if no foreign key
- fields changed; the returned value
- is ULINT_UNDEFINED if the column
- type in the child table is too short
- to fit the new value in the parent
- table: that means the update fails */
- upd_node_t* node, /* in: update node of the parent
+ upd_node_t* node, /*!< in: update node of the parent
table */
- dict_foreign_t* foreign, /* in: foreign key constraint whose
+ dict_foreign_t* foreign, /*!< in: foreign key constraint whose
type is != 0 */
- mem_heap_t* heap) /* in: memory heap to use as
+ mem_heap_t* heap) /*!< in: memory heap to use as
temporary storage */
{
upd_node_t* cascade = node->cascade_node;
@@ -606,15 +587,15 @@ row_ins_cascade_calc_update_vec(
return(n_fields_updated);
}
-/*************************************************************************
+/*********************************************************************//**
Set detailed error message associated with foreign key errors for
the given transaction. */
static
void
row_ins_set_detailed(
/*=================*/
- trx_t* trx, /* in: transaction */
- dict_foreign_t* foreign) /* in: foreign key constraint */
+ trx_t* trx, /*!< in: transaction */
+ dict_foreign_t* foreign) /*!< in: foreign key constraint */
{
mutex_enter(&srv_misc_tmpfile_mutex);
rewind(srv_misc_tmpfile);
@@ -632,21 +613,21 @@ row_ins_set_detailed(
mutex_exit(&srv_misc_tmpfile_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
Reports a foreign key error associated with an update or a delete of a
parent table index entry. */
static
void
row_ins_foreign_report_err(
/*=======================*/
- const char* errstr, /* in: error string from the viewpoint
+ const char* errstr, /*!< in: error string from the viewpoint
of the parent table */
- que_thr_t* thr, /* in: query thread whose run_node
+ que_thr_t* thr, /*!< in: query thread whose run_node
is an update node */
- dict_foreign_t* foreign, /* in: foreign key constraint */
- const rec_t* rec, /* in: a matching index record in the
+ dict_foreign_t* foreign, /*!< in: foreign key constraint */
+ const rec_t* rec, /*!< in: a matching index record in the
child table */
- const dtuple_t* entry) /* in: index entry in the parent
+ const dtuple_t* entry) /*!< in: index entry in the parent
table */
{
FILE* ef = dict_foreign_err_file;
@@ -688,7 +669,7 @@ row_ins_foreign_report_err(
mutex_exit(&dict_foreign_err_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
Reports a foreign key error to dict_foreign_err_file when we are trying
to add an index entry to a child table. Note that the adding may be the result
of an update, too. */
@@ -696,12 +677,12 @@ static
void
row_ins_foreign_report_add_err(
/*===========================*/
- trx_t* trx, /* in: transaction */
- dict_foreign_t* foreign, /* in: foreign key constraint */
- const rec_t* rec, /* in: a record in the parent table:
+ trx_t* trx, /*!< in: transaction */
+ dict_foreign_t* foreign, /*!< in: foreign key constraint */
+ const rec_t* rec, /*!< in: a record in the parent table:
it does not match entry because we
have an error! */
- const dtuple_t* entry) /* in: index entry to insert in the
+ const dtuple_t* entry) /*!< in: index entry to insert in the
child table */
{
FILE* ef = dict_foreign_err_file;
@@ -746,15 +727,15 @@ row_ins_foreign_report_add_err(
mutex_exit(&dict_foreign_err_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
Invalidate the query cache for the given table. */
static
void
row_ins_invalidate_query_cache(
/*===========================*/
- que_thr_t* thr, /* in: query thread whose run_node
+ que_thr_t* thr, /*!< in: query thread whose run_node
is an update node */
- const char* name) /* in: table name prefixed with
+ const char* name) /*!< in: table name prefixed with
database name and a '/' character */
{
char* buf;
@@ -767,32 +748,28 @@ row_ins_invalidate_query_cache(
ut_a(ptr);
*ptr = '\0';
- /* We call a function in ha_innodb.cc */
-#ifndef UNIV_HOTBACKUP
innobase_invalidate_query_cache(thr_get_trx(thr), buf, len);
-#endif
mem_free(buf);
}
-/*************************************************************************
+/*********************************************************************//**
Perform referential actions or checks when a parent row is deleted or updated
and the constraint had an ON DELETE or ON UPDATE condition which was not
-RESTRICT. */
+RESTRICT.
+@return DB_SUCCESS, DB_LOCK_WAIT, or error code */
static
ulint
row_ins_foreign_check_on_constraint(
/*================================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- or error code */
- que_thr_t* thr, /* in: query thread whose run_node
+ que_thr_t* thr, /*!< in: query thread whose run_node
is an update node */
- dict_foreign_t* foreign, /* in: foreign key constraint whose
+ dict_foreign_t* foreign, /*!< in: foreign key constraint whose
type is != 0 */
- btr_pcur_t* pcur, /* in: cursor placed on a matching
+ btr_pcur_t* pcur, /*!< in: cursor placed on a matching
index record in the child table */
- dtuple_t* entry, /* in: index entry in the parent
+ dtuple_t* entry, /*!< in: index entry in the parent
table */
- mtr_t* mtr) /* in: mtr holding the latch of pcur
+ mtr_t* mtr) /*!< in: mtr holding the latch of pcur
page */
{
upd_node_t* node;
@@ -1141,21 +1118,21 @@ nonstandard_exit_func:
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Sets a shared lock on a record. Used in locking possible duplicate key
-records and also in checking foreign key constraints. */
+records and also in checking foreign key constraints.
+@return DB_SUCCESS or error code */
static
ulint
row_ins_set_shared_rec_lock(
/*========================*/
- /* out: DB_SUCCESS or error code */
- ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP type lock */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: record */
- dict_index_t* index, /* in: index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- que_thr_t* thr) /* in: query thread */
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
@@ -1172,22 +1149,21 @@ row_ins_set_shared_rec_lock(
return(err);
}
-#ifndef UNIV_HOTBACKUP
-/*************************************************************************
+/*********************************************************************//**
Sets a exclusive lock on a record. Used in locking possible duplicate key
-records */
+records
+@return DB_SUCCESS or error code */
static
ulint
row_ins_set_exclusive_rec_lock(
/*===========================*/
- /* out: DB_SUCCESS or error code */
- ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or
+ ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP type lock */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: record */
- dict_index_t* index, /* in: index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- que_thr_t* thr) /* in: query thread */
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
@@ -1203,29 +1179,26 @@ row_ins_set_exclusive_rec_lock(
return(err);
}
-#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
Checks if foreign key constraint fails for an index entry. Sets shared locks
which lock either the success or the failure of the constraint. NOTE that
-the caller must have a shared latch on dict_operation_lock. */
+the caller must have a shared latch on dict_operation_lock.
+@return DB_SUCCESS, DB_NO_REFERENCED_ROW, or DB_ROW_IS_REFERENCED */
UNIV_INTERN
ulint
row_ins_check_foreign_constraint(
/*=============================*/
- /* out: DB_SUCCESS,
- DB_NO_REFERENCED_ROW,
- or DB_ROW_IS_REFERENCED */
- ibool check_ref,/* in: TRUE if we want to check that
+ ibool check_ref,/*!< in: TRUE if we want to check that
the referenced table is ok, FALSE if we
want to to check the foreign key table */
- dict_foreign_t* foreign,/* in: foreign constraint; NOTE that the
+ dict_foreign_t* foreign,/*!< in: foreign constraint; NOTE that the
tables mentioned in it must be in the
dictionary cache if they exist at all */
- dict_table_t* table, /* in: if check_ref is TRUE, then the foreign
+ dict_table_t* table, /*!< in: if check_ref is TRUE, then the foreign
table, else the referenced table */
- dtuple_t* entry, /* in: index entry for index */
- que_thr_t* thr) /* in: query thread */
+ dtuple_t* entry, /*!< in: index entry for index */
+ que_thr_t* thr) /*!< in: query thread */
{
upd_node_t* upd_node;
dict_table_t* check_table;
@@ -1529,21 +1502,21 @@ exit_func:
return(err);
}
-/*******************************************************************
+/***************************************************************//**
Checks if foreign key constraints fail for an index entry. If index
is not mentioned in any constraint, this function does nothing,
Otherwise does searches to the indexes of referenced tables and
sets shared locks which lock either the success or the failure of
-a constraint. */
+a constraint.
+@return DB_SUCCESS or error code */
static
ulint
row_ins_check_foreign_constraints(
/*==============================*/
- /* out: DB_SUCCESS or error code */
- dict_table_t* table, /* in: table */
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in: index entry for index */
- que_thr_t* thr) /* in: query thread */
+ dict_table_t* table, /*!< in: table */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in: index entry for index */
+ que_thr_t* thr) /*!< in: query thread */
{
dict_foreign_t* foreign;
ulint err;
@@ -1611,21 +1584,20 @@ row_ins_check_foreign_constraints(
return(DB_SUCCESS);
}
-#ifndef UNIV_HOTBACKUP
-/*******************************************************************
+/***************************************************************//**
Checks if a unique key violation to rec would occur at the index entry
-insert. */
+insert.
+@return TRUE if error */
static
ibool
row_ins_dupl_error_with_rec(
/*========================*/
- /* out: TRUE if error */
- const rec_t* rec, /* in: user record; NOTE that we assume
+ const rec_t* rec, /*!< in: user record; NOTE that we assume
that the caller already has a record lock on
the record! */
- const dtuple_t* entry, /* in: entry to insert */
- dict_index_t* index, /* in: index */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ const dtuple_t* entry, /*!< in: entry to insert */
+ dict_index_t* index, /*!< in: index */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
ulint matched_fields;
ulint matched_bytes;
@@ -1663,23 +1635,20 @@ row_ins_dupl_error_with_rec(
return(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
}
-#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
Scans a unique non-clustered index at a given index entry to determine
whether a uniqueness violation has occurred for the key value of the entry.
-Set shared locks on possible duplicate records. */
+Set shared locks on possible duplicate records.
+@return DB_SUCCESS, DB_DUPLICATE_KEY, or DB_LOCK_WAIT */
static
ulint
row_ins_scan_sec_index_for_duplicate(
/*=================================*/
- /* out: DB_SUCCESS, DB_DUPLICATE_KEY, or
- DB_LOCK_WAIT */
- dict_index_t* index, /* in: non-clustered unique index */
- dtuple_t* entry, /* in: index entry */
- que_thr_t* thr) /* in: query thread */
+ dict_index_t* index, /*!< in: non-clustered unique index */
+ dtuple_t* entry, /*!< in: index entry */
+ que_thr_t* thr) /*!< in: query thread */
{
-#ifndef UNIV_HOTBACKUP
ulint n_unique;
ulint i;
int cmp;
@@ -1789,33 +1758,24 @@ row_ins_scan_sec_index_for_duplicate(
dtuple_set_n_fields_cmp(entry, n_fields_cmp);
return(err);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
- return(DB_FAIL);
-#endif /* UNIV_HOTBACKUP */
}
-/*******************************************************************
+/***************************************************************//**
Checks if a unique key violation error would occur at an index entry
insert. Sets shared locks on possible duplicate records. Works only
-for a clustered index! */
+for a clustered index!
+@return DB_SUCCESS if no error, DB_DUPLICATE_KEY if error,
+DB_LOCK_WAIT if we have to wait for a lock on a possible duplicate
+record */
static
ulint
row_ins_duplicate_error_in_clust(
/*=============================*/
- /* out: DB_SUCCESS if no error,
- DB_DUPLICATE_KEY if error, DB_LOCK_WAIT if we
- have to wait for a lock on a possible
- duplicate record */
- btr_cur_t* cursor, /* in: B-tree cursor */
- dtuple_t* entry, /* in: entry to insert */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr */
+ btr_cur_t* cursor, /*!< in: B-tree cursor */
+ dtuple_t* entry, /*!< in: entry to insert */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr */
{
-#ifndef UNIV_HOTBACKUP
ulint err;
rec_t* rec;
ulint n_unique;
@@ -1939,31 +1899,22 @@ func_exit:
mem_heap_free(heap);
}
return(err);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
- return(DB_FAIL);
-#endif /* UNIV_HOTBACKUP */
}
-/*******************************************************************
+/***************************************************************//**
Checks if an index entry has long enough common prefix with an existing
record so that the intended insert of the entry must be changed to a modify of
the existing record. In the case of a clustered index, the prefix must be
n_unique fields long, and in the case of a secondary index, all fields must be
-equal. */
+equal.
+@return 0 if no update, ROW_INS_PREV if previous should be updated;
+currently we do the search so that only the low_match record can match
+enough to the search tuple, not the next record */
UNIV_INLINE
ulint
row_ins_must_modify(
/*================*/
- /* out: 0 if no update, ROW_INS_PREV if
- previous should be updated; currently we
- do the search so that only the low_match
- record can match enough to the search tuple,
- not the next record */
- btr_cur_t* cursor) /* in: B-tree cursor */
+ btr_cur_t* cursor) /*!< in: B-tree cursor */
{
ulint enough_match;
rec_t* rec;
@@ -1990,7 +1941,7 @@ row_ins_must_modify(
return(0);
}
-/*******************************************************************
+/***************************************************************//**
Tries to insert an index entry to an index. If the index is clustered
and a record with the same unique key is found, the other record is
necessarily marked deleted by a committed transaction, or a unique key
@@ -1998,20 +1949,20 @@ violation error occurs. The delete marked record is then updated to an
existing record, and we must write an undo log record on the delete
marked record. If the index is secondary, and a record with exactly the
same fields is found, the other record is necessarily marked deleted.
-It is then unmarked. Otherwise, the entry is just inserted to the index. */
+It is then unmarked. Otherwise, the entry is just inserted to the index.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_FAIL if pessimistic retry needed,
+or error code */
static
ulint
row_ins_index_entry_low(
/*====================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT, DB_FAIL
- if pessimistic retry needed, or error code */
- ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
+ ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
depending on whether we wish optimistic or
pessimistic descent down the index tree */
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in: index entry to insert */
- ulint n_ext, /* in: number of externally stored columns */
- que_thr_t* thr) /* in: query thread */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in: index entry to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ que_thr_t* thr) /*!< in: query thread */
{
btr_cur_t cursor;
ulint ignore_sec_unique = 0;
@@ -2177,22 +2128,21 @@ function_exit:
return(err);
}
-/*******************************************************************
+/***************************************************************//**
Inserts an index entry to index. Tries first optimistic, then pessimistic
descent down the tree. If the entry matches enough to a delete marked record,
performs the insert by updating or delete unmarking the delete marked
-record. */
+record.
+@return DB_SUCCESS, DB_LOCK_WAIT, DB_DUPLICATE_KEY, or some other error code */
UNIV_INTERN
ulint
row_ins_index_entry(
/*================*/
- /* out: DB_SUCCESS, DB_LOCK_WAIT,
- DB_DUPLICATE_KEY, or some other error code */
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in: index entry to insert */
- ulint n_ext, /* in: number of externally stored columns */
- ibool foreign,/* in: TRUE=check foreign key constraints */
- que_thr_t* thr) /* in: query thread */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in: index entry to insert */
+ ulint n_ext, /*!< in: number of externally stored columns */
+ ibool foreign,/*!< in: TRUE=check foreign key constraints */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
@@ -2221,16 +2171,16 @@ row_ins_index_entry(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Sets the values of the dtuple fields in entry from the values of appropriate
columns in row. */
static
void
row_ins_index_entry_set_vals(
/*=========================*/
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in: index entry to make */
- const dtuple_t* row) /* in: row */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in: index entry to make */
+ const dtuple_t* row) /*!< in: row */
{
ulint n_fields;
ulint i;
@@ -2273,16 +2223,16 @@ row_ins_index_entry_set_vals(
}
}
-/***************************************************************
-Inserts a single index entry to the table. */
+/***********************************************************//**
+Inserts a single index entry to the table.
+@return DB_SUCCESS if operation successfully completed, else error
+code or DB_LOCK_WAIT */
static
ulint
row_ins_index_entry_step(
/*=====================*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code or DB_LOCK_WAIT */
- ins_node_t* node, /* in: row insert node */
- que_thr_t* thr) /* in: query thread */
+ ins_node_t* node, /*!< in: row insert node */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
@@ -2297,13 +2247,13 @@ row_ins_index_entry_step(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Allocates a row id for row and inits the node->index field. */
UNIV_INLINE
void
row_ins_alloc_row_id_step(
/*======================*/
- ins_node_t* node) /* in: row insert node */
+ ins_node_t* node) /*!< in: row insert node */
{
dulint row_id;
@@ -2323,13 +2273,13 @@ row_ins_alloc_row_id_step(
dict_sys_write_row_id(node->row_id_buf, row_id);
}
-/***************************************************************
+/***********************************************************//**
Gets a row to insert from the values list. */
UNIV_INLINE
void
row_ins_get_row_from_values(
/*========================*/
- ins_node_t* node) /* in: row insert node */
+ ins_node_t* node) /*!< in: row insert node */
{
que_node_t* list_node;
dfield_t* dfield;
@@ -2356,13 +2306,13 @@ row_ins_get_row_from_values(
}
}
-/***************************************************************
+/***********************************************************//**
Gets a row to insert from the select list. */
UNIV_INLINE
void
row_ins_get_row_from_select(
/*========================*/
- ins_node_t* node) /* in: row insert node */
+ ins_node_t* node) /*!< in: row insert node */
{
que_node_t* list_node;
dfield_t* dfield;
@@ -2387,16 +2337,16 @@ row_ins_get_row_from_select(
}
}
-/***************************************************************
-Inserts a row to a table. */
+/***********************************************************//**
+Inserts a row to a table.
+@return DB_SUCCESS if operation successfully completed, else error
+code or DB_LOCK_WAIT */
static
ulint
row_ins(
/*====*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code or DB_LOCK_WAIT */
- ins_node_t* node, /* in: row insert node */
- que_thr_t* thr) /* in: query thread */
+ ins_node_t* node, /*!< in: row insert node */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
@@ -2442,15 +2392,15 @@ row_ins(
return(DB_SUCCESS);
}
-/***************************************************************
+/***********************************************************//**
Inserts a row to a table. This is a high-level function used in SQL execution
-graphs. */
+graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_ins_step(
/*=========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ins_node_t* node;
que_node_t* parent;
diff --git a/storage/xtradb/row/row0merge.c b/storage/xtradb/row/row0merge.c
index efed3d26e5b..05a45dc647c 100644
--- a/storage/xtradb/row/row0merge.c
+++ b/storage/xtradb/row/row0merge.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0merge.c
New index creation routines using a merge sort
Created 12/4/2005 Jan Lindstrom
@@ -57,69 +58,74 @@ Completed by Sunny Bains and Marko Makela
#include "handler0alter.h"
#ifdef UNIV_DEBUG
-/* Set these in order ot enable debug printout. */
+/** Set these in order ot enable debug printout. */
+/* @{ */
static ibool row_merge_print_cmp;
static ibool row_merge_print_read;
static ibool row_merge_print_write;
+/* @} */
#endif /* UNIV_DEBUG */
-/* Block size for I/O operations in merge sort. The minimum is
-UNIV_PAGE_SIZE, or page_get_free_space_of_empty() rounded to a power of 2.
+/** @brief Block size for I/O operations in merge sort.
+
+The minimum is UNIV_PAGE_SIZE, or page_get_free_space_of_empty()
+rounded to a power of 2.
When not creating a PRIMARY KEY that contains column prefixes, this
can be set as small as UNIV_PAGE_SIZE / 2. See the comment above
ut_ad(data_size < sizeof(row_merge_block_t)). */
-
typedef byte row_merge_block_t[1048576];
-/* Secondary buffer for I/O operations of merge records. This buffer
-is used for writing or reading a record that spans two row_merge_block_t.
-Thus, it must be able to hold one merge record, whose maximum size is
-the same as the minimum size of row_merge_block_t. */
+/** @brief Secondary buffer for I/O operations of merge records.
+This buffer is used for writing or reading a record that spans two
+row_merge_block_t. Thus, it must be able to hold one merge record,
+whose maximum size is the same as the minimum size of
+row_merge_block_t. */
typedef byte mrec_buf_t[UNIV_PAGE_SIZE];
-/* Merge record in row_merge_block_t. The format is the same as a
-record in ROW_FORMAT=COMPACT with the exception that the
-REC_N_NEW_EXTRA_BYTES are omitted. */
+/** @brief Merge record in row_merge_block_t.
+
+The format is the same as a record in ROW_FORMAT=COMPACT with the
+exception that the REC_N_NEW_EXTRA_BYTES are omitted. */
typedef byte mrec_t;
-/* Buffer for sorting in main memory. */
+/** Buffer for sorting in main memory. */
struct row_merge_buf_struct {
- mem_heap_t* heap; /* memory heap where allocated */
- dict_index_t* index; /* the index the tuples belong to */
- ulint total_size; /* total amount of data bytes */
- ulint n_tuples; /* number of data tuples */
- ulint max_tuples; /* maximum number of data tuples */
- const dfield_t**tuples; /* array of pointers to
+ mem_heap_t* heap; /*!< memory heap where allocated */
+ dict_index_t* index; /*!< the index the tuples belong to */
+ ulint total_size; /*!< total amount of data bytes */
+ ulint n_tuples; /*!< number of data tuples */
+ ulint max_tuples; /*!< maximum number of data tuples */
+ const dfield_t**tuples; /*!< array of pointers to
arrays of fields that form
the data tuples */
- const dfield_t**tmp_tuples; /* temporary copy of tuples,
+ const dfield_t**tmp_tuples; /*!< temporary copy of tuples,
for sorting */
};
+/** Buffer for sorting in main memory. */
typedef struct row_merge_buf_struct row_merge_buf_t;
-/* Information about temporary files used in merge sort are stored
-to this structure */
-
+/** Information about temporary files used in merge sort */
struct merge_file_struct {
- int fd; /* File descriptor */
- ulint offset; /* File offset */
+ int fd; /*!< file descriptor */
+ ulint offset; /*!< file offset */
};
+/** Information about temporary files used in merge sort */
typedef struct merge_file_struct merge_file_t;
#ifdef UNIV_DEBUG
-/**********************************************************
+/******************************************************//**
Display a merge tuple. */
static
void
row_merge_tuple_print(
/*==================*/
- FILE* f, /* in: output stream */
- const dfield_t* entry, /* in: tuple to print */
- ulint n_fields)/* in: number of fields in the tuple */
+ FILE* f, /*!< in: output stream */
+ const dfield_t* entry, /*!< in: tuple to print */
+ ulint n_fields)/*!< in: number of fields in the tuple */
{
ulint j;
@@ -146,17 +152,17 @@ row_merge_tuple_print(
}
#endif /* UNIV_DEBUG */
-/**********************************************************
-Allocate a sort buffer. */
+/******************************************************//**
+Allocate a sort buffer.
+@return own: sort buffer */
static
row_merge_buf_t*
row_merge_buf_create_low(
/*=====================*/
- /* out,own: sort buffer */
- mem_heap_t* heap, /* in: heap where allocated */
- dict_index_t* index, /* in: secondary index */
- ulint max_tuples, /* in: maximum number of data tuples */
- ulint buf_size) /* in: size of the buffer, in bytes */
+ mem_heap_t* heap, /*!< in: heap where allocated */
+ dict_index_t* index, /*!< in: secondary index */
+ ulint max_tuples, /*!< in: maximum number of data tuples */
+ ulint buf_size) /*!< in: size of the buffer, in bytes */
{
row_merge_buf_t* buf;
@@ -175,14 +181,14 @@ row_merge_buf_create_low(
return(buf);
}
-/**********************************************************
-Allocate a sort buffer. */
+/******************************************************//**
+Allocate a sort buffer.
+@return own: sort buffer */
static
row_merge_buf_t*
row_merge_buf_create(
/*=================*/
- /* out,own: sort buffer */
- dict_index_t* index) /* in: secondary index */
+ dict_index_t* index) /*!< in: secondary index */
{
row_merge_buf_t* buf;
ulint max_tuples;
@@ -201,14 +207,14 @@ row_merge_buf_create(
return(buf);
}
-/**********************************************************
-Empty a sort buffer. */
+/******************************************************//**
+Empty a sort buffer.
+@return sort buffer */
static
row_merge_buf_t*
row_merge_buf_empty(
/*================*/
- /* out: sort buffer */
- row_merge_buf_t* buf) /* in,own: sort buffer */
+ row_merge_buf_t* buf) /*!< in,own: sort buffer */
{
ulint buf_size;
ulint max_tuples = buf->max_tuples;
@@ -222,28 +228,27 @@ row_merge_buf_empty(
return(row_merge_buf_create_low(heap, index, max_tuples, buf_size));
}
-/**********************************************************
+/******************************************************//**
Deallocate a sort buffer. */
static
void
row_merge_buf_free(
/*===============*/
- row_merge_buf_t* buf) /* in,own: sort buffer, to be freed */
+ row_merge_buf_t* buf) /*!< in,own: sort buffer, to be freed */
{
mem_heap_free(buf->heap);
}
-/**********************************************************
-Insert a data tuple into a sort buffer. */
+/******************************************************//**
+Insert a data tuple into a sort buffer.
+@return TRUE if added, FALSE if out of space */
static
ibool
row_merge_buf_add(
/*==============*/
- /* out: TRUE if added,
- FALSE if out of space */
- row_merge_buf_t* buf, /* in/out: sort buffer */
- const dtuple_t* row, /* in: row in clustered index */
- const row_ext_t* ext) /* in: cache of externally stored
+ row_merge_buf_t* buf, /*!< in/out: sort buffer */
+ const dtuple_t* row, /*!< in: row in clustered index */
+ const row_ext_t* ext) /*!< in: cache of externally stored
column prefixes, or NULL */
{
ulint i;
@@ -389,23 +394,24 @@ row_merge_buf_add(
return(TRUE);
}
-/* Structure for reporting duplicate records. */
+/** Structure for reporting duplicate records. */
struct row_merge_dup_struct {
- const dict_index_t* index; /* index being sorted */
- TABLE* table; /* MySQL table object */
- ulint n_dup; /* number of duplicates */
+ const dict_index_t* index; /*!< index being sorted */
+ TABLE* table; /*!< MySQL table object */
+ ulint n_dup; /*!< number of duplicates */
};
+/** Structure for reporting duplicate records. */
typedef struct row_merge_dup_struct row_merge_dup_t;
-/*****************************************************************
+/*************************************************************//**
Report a duplicate key. */
static
void
row_merge_dup_report(
/*=================*/
- row_merge_dup_t* dup, /* in/out: for reporting duplicates */
- const dfield_t* entry) /* in: duplicate index entry */
+ row_merge_dup_t* dup, /*!< in/out: for reporting duplicates */
+ const dfield_t* entry) /*!< in: duplicate index entry */
{
mrec_buf_t buf;
const dtuple_t* tuple;
@@ -442,18 +448,17 @@ row_merge_dup_report(
}
}
-/*****************************************************************
-Compare two tuples. */
+/*************************************************************//**
+Compare two tuples.
+@return 1, 0, -1 if a is greater, equal, less, respectively, than b */
static
int
row_merge_tuple_cmp(
/*================*/
- /* out: 1, 0, -1 if a is greater,
- equal, less, respectively, than b */
- ulint n_field,/* in: number of fields */
- const dfield_t* a, /* in: first tuple to be compared */
- const dfield_t* b, /* in: second tuple to be compared */
- row_merge_dup_t* dup) /* in/out: for reporting duplicates */
+ ulint n_field,/*!< in: number of fields */
+ const dfield_t* a, /*!< in: first tuple to be compared */
+ const dfield_t* b, /*!< in: second tuple to be compared */
+ row_merge_dup_t* dup) /*!< in/out: for reporting duplicates */
{
int cmp;
const dfield_t* field = a;
@@ -484,53 +489,64 @@ func_exit:
return(cmp);
}
-/**************************************************************************
+/** Wrapper for row_merge_tuple_sort() to inject some more context to
+UT_SORT_FUNCTION_BODY().
+@param a array of tuples that being sorted
+@param b aux (work area), same size as tuples[]
+@param c lower bound of the sorting area, inclusive
+@param d upper bound of the sorting area, inclusive */
+#define row_merge_tuple_sort_ctx(a,b,c,d) \
+ row_merge_tuple_sort(n_field, dup, a, b, c, d)
+/** Wrapper for row_merge_tuple_cmp() to inject some more context to
+UT_SORT_FUNCTION_BODY().
+@param a first tuple to be compared
+@param b second tuple to be compared
+@return 1, 0, -1 if a is greater, equal, less, respectively, than b */
+#define row_merge_tuple_cmp_ctx(a,b) row_merge_tuple_cmp(n_field, a, b, dup)
+
+/**********************************************************************//**
Merge sort the tuple buffer in main memory. */
static
void
row_merge_tuple_sort(
/*=================*/
- ulint n_field,/* in: number of fields */
- row_merge_dup_t* dup, /* in/out: for reporting duplicates */
- const dfield_t** tuples, /* in/out: tuples */
- const dfield_t** aux, /* in/out: work area */
- ulint low, /* in: lower bound of the
+ ulint n_field,/*!< in: number of fields */
+ row_merge_dup_t* dup, /*!< in/out: for reporting duplicates */
+ const dfield_t** tuples, /*!< in/out: tuples */
+ const dfield_t** aux, /*!< in/out: work area */
+ ulint low, /*!< in: lower bound of the
sorting area, inclusive */
- ulint high) /* in: upper bound of the
+ ulint high) /*!< in: upper bound of the
sorting area, exclusive */
{
-#define row_merge_tuple_sort_ctx(a,b,c,d) \
- row_merge_tuple_sort(n_field, dup, a, b, c, d)
-#define row_merge_tuple_cmp_ctx(a,b) row_merge_tuple_cmp(n_field, a, b, dup)
-
UT_SORT_FUNCTION_BODY(row_merge_tuple_sort_ctx,
tuples, aux, low, high, row_merge_tuple_cmp_ctx);
}
-/**********************************************************
+/******************************************************//**
Sort a buffer. */
static
void
row_merge_buf_sort(
/*===============*/
- row_merge_buf_t* buf, /* in/out: sort buffer */
- row_merge_dup_t* dup) /* in/out: for reporting duplicates */
+ row_merge_buf_t* buf, /*!< in/out: sort buffer */
+ row_merge_dup_t* dup) /*!< in/out: for reporting duplicates */
{
row_merge_tuple_sort(dict_index_get_n_unique(buf->index), dup,
buf->tuples, buf->tmp_tuples, 0, buf->n_tuples);
}
-/**********************************************************
+/******************************************************//**
Write a buffer to a block. */
static
void
row_merge_buf_write(
/*================*/
- const row_merge_buf_t* buf, /* in: sorted buffer */
+ const row_merge_buf_t* buf, /*!< in: sorted buffer */
#ifdef UNIV_DEBUG
- const merge_file_t* of, /* in: output file */
+ const merge_file_t* of, /*!< in: output file */
#endif /* UNIV_DEBUG */
- row_merge_block_t* block) /* out: buffer for writing to file */
+ row_merge_block_t* block) /*!< out: buffer for writing to file */
#ifndef UNIV_DEBUG
# define row_merge_buf_write(buf, of, block) row_merge_buf_write(buf, block)
#endif /* !UNIV_DEBUG */
@@ -599,16 +615,16 @@ row_merge_buf_write(
#endif /* UNIV_DEBUG */
}
-/**********************************************************
-Create a memory heap and allocate space for row_merge_rec_offsets(). */
+/******************************************************//**
+Create a memory heap and allocate space for row_merge_rec_offsets().
+@return memory heap */
static
mem_heap_t*
row_merge_heap_create(
/*==================*/
- /* out: memory heap */
- const dict_index_t* index, /* in: record descriptor */
- ulint** offsets1, /* out: offsets */
- ulint** offsets2) /* out: offsets */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint** offsets1, /*!< out: offsets */
+ ulint** offsets2) /*!< out: offsets */
{
ulint i = 1 + REC_OFFS_HEADER_SIZE
+ dict_index_get_n_fields(index);
@@ -623,17 +639,16 @@ row_merge_heap_create(
return(heap);
}
-/**************************************************************************
+/**********************************************************************//**
Search an index object by name and column names. If several indexes match,
-return the index with the max id. */
+return the index with the max id.
+@return matching index, NULL if not found */
static
dict_index_t*
row_merge_dict_table_get_index(
/*===========================*/
- /* out: matching index,
- NULL if not found */
- dict_table_t* table, /* in: table */
- const merge_index_def_t*index_def) /* in: index definition */
+ dict_table_t* table, /*!< in: table */
+ const merge_index_def_t*index_def) /*!< in: index definition */
{
ulint i;
dict_index_t* index;
@@ -653,17 +668,16 @@ row_merge_dict_table_get_index(
return(index);
}
-/************************************************************************
-Read a merge block from the file system. */
+/********************************************************************//**
+Read a merge block from the file system.
+@return TRUE if request was successful, FALSE if fail */
static
ibool
row_merge_read(
/*===========*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- int fd, /* in: file descriptor */
- ulint offset, /* in: offset where to read */
- row_merge_block_t* buf) /* out: data */
+ int fd, /*!< in: file descriptor */
+ ulint offset, /*!< in: offset where to read */
+ row_merge_block_t* buf) /*!< out: data */
{
ib_uint64_t ofs = ((ib_uint64_t) offset) * sizeof *buf;
ibool success;
@@ -681,17 +695,16 @@ row_merge_read(
return(UNIV_LIKELY(success));
}
-/************************************************************************
-Read a merge block from the file system. */
+/********************************************************************//**
+Read a merge block from the file system.
+@return TRUE if request was successful, FALSE if fail */
static
ibool
row_merge_write(
/*============*/
- /* out: TRUE if request was
- successful, FALSE if fail */
- int fd, /* in: file descriptor */
- ulint offset, /* in: offset where to write */
- const void* buf) /* in: data */
+ int fd, /*!< in: file descriptor */
+ ulint offset, /*!< in: offset where to write */
+ const void* buf) /*!< in: data */
{
ib_uint64_t ofs = ((ib_uint64_t) offset)
* sizeof(row_merge_block_t);
@@ -702,25 +715,23 @@ row_merge_write(
sizeof(row_merge_block_t))));
}
-/************************************************************************
-Read a merge record. */
+/********************************************************************//**
+Read a merge record.
+@return pointer to next record, or NULL on I/O error or end of list */
static
const byte*
row_merge_read_rec(
/*===============*/
- /* out: pointer to next record,
- or NULL on I/O error
- or end of list */
- row_merge_block_t* block, /* in/out: file buffer */
- mrec_buf_t* buf, /* in/out: secondary buffer */
- const byte* b, /* in: pointer to record */
- const dict_index_t* index, /* in: index of the record */
- int fd, /* in: file descriptor */
- ulint* foffs, /* in/out: file offset */
- const mrec_t** mrec, /* out: pointer to merge record,
+ row_merge_block_t* block, /*!< in/out: file buffer */
+ mrec_buf_t* buf, /*!< in/out: secondary buffer */
+ const byte* b, /*!< in: pointer to record */
+ const dict_index_t* index, /*!< in: index of the record */
+ int fd, /*!< in: file descriptor */
+ ulint* foffs, /*!< in/out: file offset */
+ const mrec_t** mrec, /*!< out: pointer to merge record,
or NULL on end of list
(non-NULL on I/O error) */
- ulint* offsets)/* out: offsets of mrec */
+ ulint* offsets)/*!< out: offsets of mrec */
{
ulint extra_size;
ulint data_size;
@@ -838,7 +849,14 @@ err_exit:
avail_size = block[1] - b;
memcpy(*buf, b, avail_size);
*mrec = *buf + extra_size;
- rec_offs_make_valid(*mrec, index, offsets);
+#ifdef UNIV_DEBUG
+ /* We cannot invoke rec_offs_make_valid() here, because there
+ are no REC_N_NEW_EXTRA_BYTES between extra_size and data_size.
+ Similarly, rec_offs_validate() would fail, because it invokes
+ rec_get_status(). */
+ offsets[2] = (ulint) *mrec;
+ offsets[3] = (ulint) index;
+#endif /* UNIV_DEBUG */
if (!row_merge_read(fd, ++(*foffs), block)) {
@@ -866,21 +884,21 @@ func_exit:
return(b);
}
-/************************************************************************
+/********************************************************************//**
Write a merge record. */
static
void
row_merge_write_rec_low(
/*====================*/
- byte* b, /* out: buffer */
- ulint e, /* in: encoded extra_size */
+ byte* b, /*!< out: buffer */
+ ulint e, /*!< in: encoded extra_size */
#ifdef UNIV_DEBUG
- ulint size, /* in: total size to write */
- int fd, /* in: file descriptor */
- ulint foffs, /* in: file offset */
+ ulint size, /*!< in: total size to write */
+ int fd, /*!< in: file descriptor */
+ ulint foffs, /*!< in: file offset */
#endif /* UNIV_DEBUG */
- const mrec_t* mrec, /* in: record to write */
- const ulint* offsets)/* in: offsets of mrec */
+ const mrec_t* mrec, /*!< in: record to write */
+ const ulint* offsets)/*!< in: offsets of mrec */
#ifndef UNIV_DEBUG
# define row_merge_write_rec_low(b, e, size, fd, foffs, mrec, offsets) \
row_merge_write_rec_low(b, e, mrec, offsets)
@@ -909,21 +927,20 @@ row_merge_write_rec_low(
ut_ad(b + rec_offs_size(offsets) == end);
}
-/************************************************************************
-Write a merge record. */
+/********************************************************************//**
+Write a merge record.
+@return pointer to end of block, or NULL on error */
static
byte*
row_merge_write_rec(
/*================*/
- /* out: pointer to end of block,
- or NULL on error */
- row_merge_block_t* block, /* in/out: file buffer */
- mrec_buf_t* buf, /* in/out: secondary buffer */
- byte* b, /* in: pointer to end of block */
- int fd, /* in: file descriptor */
- ulint* foffs, /* in/out: file offset */
- const mrec_t* mrec, /* in: record to write */
- const ulint* offsets)/* in: offsets of mrec */
+ row_merge_block_t* block, /*!< in/out: file buffer */
+ mrec_buf_t* buf, /*!< in/out: secondary buffer */
+ byte* b, /*!< in: pointer to end of block */
+ int fd, /*!< in: file descriptor */
+ ulint* foffs, /*!< in/out: file offset */
+ const mrec_t* mrec, /*!< in: record to write */
+ const ulint* offsets)/*!< in: offsets of mrec */
{
ulint extra_size;
ulint size;
@@ -977,18 +994,17 @@ row_merge_write_rec(
return(b);
}
-/************************************************************************
-Write an end-of-list marker. */
+/********************************************************************//**
+Write an end-of-list marker.
+@return pointer to end of block, or NULL on error */
static
byte*
row_merge_write_eof(
/*================*/
- /* out: pointer to end of block,
- or NULL on error */
- row_merge_block_t* block, /* in/out: file buffer */
- byte* b, /* in: pointer to end of block */
- int fd, /* in: file descriptor */
- ulint* foffs) /* in/out: file offset */
+ row_merge_block_t* block, /*!< in/out: file buffer */
+ byte* b, /*!< in: pointer to end of block */
+ int fd, /*!< in: file descriptor */
+ ulint* foffs) /*!< in/out: file offset */
{
ut_ad(block);
ut_ad(b >= block[0]);
@@ -1018,22 +1034,20 @@ row_merge_write_eof(
return(block[0]);
}
-/*****************************************************************
-Compare two merge records. */
+/*************************************************************//**
+Compare two merge records.
+@return 1, 0, -1 if mrec1 is greater, equal, less, respectively, than mrec2 */
static
int
row_merge_cmp(
/*==========*/
- /* out: 1, 0, -1 if
- mrec1 is greater, equal, less,
- respectively, than mrec2 */
- const mrec_t* mrec1, /* in: first merge
+ const mrec_t* mrec1, /*!< in: first merge
record to be compared */
- const mrec_t* mrec2, /* in: second merge
+ const mrec_t* mrec2, /*!< in: second merge
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 ulint* offsets1, /*!< in: first record offsets */
+ const ulint* offsets2, /*!< in: second record offsets */
+ const dict_index_t* index) /*!< in: index */
{
int cmp;
@@ -1052,26 +1066,26 @@ row_merge_cmp(
return(cmp);
}
-/************************************************************************
+/********************************************************************//**
Reads clustered index of the table and create temporary files
-containing the index entries for the indexes to be built. */
+containing the index entries for the indexes to be built.
+@return DB_SUCCESS or error */
static
ulint
row_merge_read_clustered_index(
/*===========================*/
- /* out: DB_SUCCESS or error */
- trx_t* trx, /* in: transaction */
- TABLE* table, /* in/out: MySQL table object,
+ trx_t* trx, /*!< in: transaction */
+ TABLE* table, /*!< in/out: MySQL table object,
for reporting erroneous records */
- const dict_table_t* old_table,/* in: table where rows are
+ const dict_table_t* old_table,/*!< in: table where rows are
read from */
- const dict_table_t* new_table,/* in: table where indexes are
+ const dict_table_t* new_table,/*!< in: table where indexes are
created; identical to old_table
unless creating a PRIMARY KEY */
- dict_index_t** index, /* in: indexes to be created */
- merge_file_t* files, /* in: temporary files */
- ulint n_index,/* in: number of indexes to create */
- row_merge_block_t* block) /* in/out: file buffer */
+ dict_index_t** index, /*!< in: indexes to be created */
+ merge_file_t* files, /*!< in: temporary files */
+ ulint n_index,/*!< in: number of indexes to create */
+ row_merge_block_t* block) /*!< in/out: file buffer */
{
dict_index_t* clust_index; /* Clustered index */
mem_heap_t* row_heap; /* Heap memory to create
@@ -1298,41 +1312,9 @@ func_exit:
return(err);
}
-/*****************************************************************
-Merge two blocks of linked lists on disk and write a bigger block. */
-static
-ulint
-row_merge_blocks(
-/*=============*/
- /* out: DB_SUCCESS or error code */
- const dict_index_t* index, /* in: index being created */
- merge_file_t* file, /* in/out: file containing
- index entries */
- row_merge_block_t* block, /* in/out: 3 buffers */
- ulint* foffs0, /* in/out: offset of first
- source list in the file */
- ulint* foffs1, /* in/out: offset of second
- source list in the file */
- merge_file_t* of, /* in/out: output file */
- TABLE* table) /* in/out: MySQL table, for
- reporting erroneous key value
- if applicable */
-{
- mem_heap_t* heap; /* memory heap for offsets0, offsets1 */
-
- mrec_buf_t buf[3]; /* buffer for handling split mrec in block[] */
- const byte* b0; /* pointer to block[0] */
- const byte* b1; /* pointer to block[1] */
- byte* b2; /* pointer to block[2] */
- const mrec_t* mrec0; /* merge rec, points to block[0] or buf[0] */
- const mrec_t* mrec1; /* merge rec, points to block[1] or buf[1] */
- ulint* offsets0;/* offsets of mrec0 */
- ulint* offsets1;/* offsets of mrec1 */
-
- heap = row_merge_heap_create(index, &offsets0, &offsets1);
-
- /* Write a record and read the next record. Split the output
- file in two halves, which can be merged on the following pass. */
+/** Write a record via buffer 2 and read the next record to buffer N.
+@param N number of the buffer (0 or 1)
+@param AT_END statement to execute at end of input */
#define ROW_MERGE_WRITE_GET_NEXT(N, AT_END) \
do { \
b2 = row_merge_write_rec(&block[2], &buf[2], b2, \
@@ -1353,6 +1335,42 @@ row_merge_blocks(
} \
} while (0)
+/*************************************************************//**
+Merge two blocks of linked lists on disk and write a bigger block.
+@return DB_SUCCESS or error code */
+static
+ulint
+row_merge_blocks(
+/*=============*/
+ const dict_index_t* index, /*!< in: index being created */
+ merge_file_t* file, /*!< in/out: file containing
+ index entries */
+ row_merge_block_t* block, /*!< in/out: 3 buffers */
+ ulint* foffs0, /*!< in/out: offset of first
+ source list in the file */
+ ulint* foffs1, /*!< in/out: offset of second
+ source list in the file */
+ merge_file_t* of, /*!< in/out: output file */
+ TABLE* table) /*!< in/out: MySQL table, for
+ reporting erroneous key value
+ if applicable */
+{
+ mem_heap_t* heap; /*!< memory heap for offsets0, offsets1 */
+
+ mrec_buf_t buf[3]; /*!< buffer for handling split mrec in block[] */
+ const byte* b0; /*!< pointer to block[0] */
+ const byte* b1; /*!< pointer to block[1] */
+ byte* b2; /*!< pointer to block[2] */
+ const mrec_t* mrec0; /*!< merge rec, points to block[0] or buf[0] */
+ const mrec_t* mrec1; /*!< merge rec, points to block[1] or buf[1] */
+ ulint* offsets0;/* offsets of mrec0 */
+ ulint* offsets1;/* offsets of mrec1 */
+
+ heap = row_merge_heap_create(index, &offsets0, &offsets1);
+
+ /* Write a record and read the next record. Split the output
+ file in two halves, which can be merged on the following pass. */
+
if (!row_merge_read(file->fd, *foffs0, &block[0])
|| !row_merge_read(file->fd, *foffs1, &block[1])) {
corrupt:
@@ -1419,27 +1437,27 @@ done1:
return(b2 ? DB_SUCCESS : DB_CORRUPTION);
}
-/*****************************************************************
-Merge disk files. */
+/*************************************************************//**
+Merge disk files.
+@return DB_SUCCESS or error code */
static
ulint
row_merge(
/*======*/
- /* out: DB_SUCCESS or error code */
- const dict_index_t* index, /* in: index being created */
- merge_file_t* file, /* in/out: file containing
+ const dict_index_t* index, /*!< in: index being created */
+ merge_file_t* file, /*!< in/out: file containing
index entries */
- ulint half, /* in: 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
+ ulint half, /*!< in: 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
reporting erroneous key value
if applicable */
{
- ulint foffs0; /* first input offset */
- ulint foffs1; /* second input offset */
- ulint error; /* error code */
- merge_file_t of; /* output file */
+ ulint foffs0; /*!< first input offset */
+ ulint foffs1; /*!< second input offset */
+ ulint error; /*!< error code */
+ merge_file_t of; /*!< output file */
UNIV_MEM_ASSERT_W(block[0], 3 * sizeof block[0]);
ut_ad(half > 0);
@@ -1483,23 +1501,23 @@ row_merge(
return(DB_SUCCESS);
}
-/*****************************************************************
-Merge disk files. */
+/*************************************************************//**
+Merge disk files.
+@return DB_SUCCESS or error code */
static
ulint
row_merge_sort(
/*===========*/
- /* out: DB_SUCCESS or error code */
- const dict_index_t* index, /* in: index being created */
- merge_file_t* file, /* in/out: file containing
+ const dict_index_t* index, /*!< in: index being created */
+ merge_file_t* file, /*!< in/out: file containing
index entries */
- row_merge_block_t* block, /* in/out: 3 buffers */
- int* tmpfd, /* in/out: temporary file handle */
- TABLE* table) /* in/out: MySQL table, for
+ row_merge_block_t* block, /*!< in/out: 3 buffers */
+ int* tmpfd, /*!< in/out: temporary file handle */
+ TABLE* table) /*!< in/out: MySQL table, for
reporting erroneous key value
if applicable */
{
- ulint blksz; /* block size */
+ ulint blksz; /*!< block size */
for (blksz = 1; blksz < file->offset; blksz *= 2) {
ulint half;
@@ -1517,17 +1535,17 @@ row_merge_sort(
return(DB_SUCCESS);
}
-/*****************************************************************
+/*************************************************************//**
Copy externally stored columns to the data tuple. */
static
void
row_merge_copy_blobs(
/*=================*/
- const mrec_t* mrec, /* in: merge record */
- const ulint* offsets,/* in: offsets of mrec */
- ulint zip_size,/* in: compressed page size in bytes, or 0 */
- dtuple_t* tuple, /* in/out: data tuple */
- mem_heap_t* heap) /* in/out: memory heap */
+ const mrec_t* mrec, /*!< in: merge record */
+ const ulint* offsets,/*!< in: offsets of mrec */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ dtuple_t* tuple, /*!< in/out: data tuple */
+ mem_heap_t* heap) /*!< in/out: memory heap */
{
ulint i;
ulint n_fields = dtuple_get_n_fields(tuple);
@@ -1555,21 +1573,21 @@ row_merge_copy_blobs(
}
}
-/************************************************************************
+/********************************************************************//**
Read sorted file containing index data tuples and insert these data
-tuples to the index */
+tuples to the index
+@return DB_SUCCESS or error number */
static
ulint
row_merge_insert_index_tuples(
/*==========================*/
- /* out: DB_SUCCESS or error number */
- trx_t* trx, /* in: transaction */
- dict_index_t* index, /* in: index */
- dict_table_t* table, /* in: new table */
- ulint zip_size,/* in: compressed page size of
+ trx_t* trx, /*!< in: transaction */
+ dict_index_t* index, /*!< in: index */
+ dict_table_t* table, /*!< in: new table */
+ ulint zip_size,/*!< in: compressed page size of
the old table, or 0 if uncompressed */
- int fd, /* in: file descriptor */
- row_merge_block_t* block) /* in/out: file buffer */
+ int fd, /*!< in: file descriptor */
+ row_merge_block_t* block) /*!< in/out: file buffer */
{
mrec_buf_t buf;
const byte* b;
@@ -1677,16 +1695,16 @@ err_exit:
return(error);
}
-/*************************************************************************
-Sets an exclusive lock on a table, for the duration of creating indexes. */
+/*********************************************************************//**
+Sets an exclusive lock on a table, for the duration of creating indexes.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_merge_lock_table(
/*=================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in/out: transaction */
- dict_table_t* table, /* in: table to lock */
- enum lock_mode mode) /* in: LOCK_X or LOCK_S */
+ trx_t* trx, /*!< in/out: transaction */
+ dict_table_t* table, /*!< in: table to lock */
+ enum lock_mode mode) /*!< in: LOCK_X or LOCK_S */
{
mem_heap_t* heap;
que_thr_t* thr;
@@ -1756,7 +1774,7 @@ run_again:
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Drop an index from the InnoDB system tables. The data dictionary must
have been locked exclusively by the caller, because the transaction
will not be committed. */
@@ -1764,9 +1782,9 @@ UNIV_INTERN
void
row_merge_drop_index(
/*=================*/
- dict_index_t* index, /* in: index to be removed */
- dict_table_t* table, /* in: table */
- trx_t* trx) /* in: transaction handle */
+ dict_index_t* index, /*!< in: index to be removed */
+ dict_table_t* table, /*!< in: table */
+ trx_t* trx) /*!< in: transaction handle */
{
ulint err;
pars_info_t* info = pars_info_create();
@@ -1807,7 +1825,7 @@ row_merge_drop_index(
trx->op_info = "";
}
-/*************************************************************************
+/*********************************************************************//**
Drop those indexes which were created before an error occurred when
building an index. The data dictionary must have been locked
exclusively by the caller, because the transaction will not be
@@ -1816,10 +1834,10 @@ UNIV_INTERN
void
row_merge_drop_indexes(
/*===================*/
- trx_t* trx, /* in: transaction */
- dict_table_t* table, /* in: table containing the indexes */
- dict_index_t** index, /* in: indexes to drop */
- ulint num_created) /* in: number of elements in index[] */
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table, /*!< in: table containing the indexes */
+ dict_index_t** index, /*!< in: indexes to drop */
+ ulint num_created) /*!< in: number of elements in index[] */
{
ulint key_num;
@@ -1828,7 +1846,7 @@ row_merge_drop_indexes(
}
}
-/*************************************************************************
+/*********************************************************************//**
Drop all partially created indexes during crash recovery. */
UNIV_INTERN
void
@@ -1842,14 +1860,11 @@ row_merge_drop_temp_indexes(void)
query graphs needed in deleting the dictionary data from system
tables in Innobase. Deleting a row from SYS_INDEXES table also
frees the file segments of the B-tree associated with the index. */
-#if TEMP_INDEX_PREFIX != '\377'
-# error "TEMP_INDEX_PREFIX != '\377'"
-#endif
static const char drop_temp_indexes[] =
"PROCEDURE DROP_TEMP_INDEXES_PROC () IS\n"
"indexid CHAR;\n"
"DECLARE CURSOR c IS SELECT ID FROM SYS_INDEXES\n"
- "WHERE SUBSTR(NAME,0,1)='\377';\n"
+ "WHERE SUBSTR(NAME,0,1)='" TEMP_INDEX_PREFIX_STR "';\n"
"BEGIN\n"
"\tOPEN c;\n"
"\tWHILE 1=1 LOOP\n"
@@ -1884,25 +1899,25 @@ row_merge_drop_temp_indexes(void)
trx_free_for_background(trx);
}
-/*************************************************************************
+/*********************************************************************//**
Create a merge file. */
static
void
row_merge_file_create(
/*==================*/
- merge_file_t* merge_file) /* out: merge file structure */
+ merge_file_t* merge_file) /*!< out: merge file structure */
{
merge_file->fd = innobase_mysql_tmpfile();
merge_file->offset = 0;
}
-/*************************************************************************
+/*********************************************************************//**
Destroy a merge file. */
static
void
row_merge_file_destroy(
/*===================*/
- merge_file_t* merge_file) /* out: merge file structure */
+ merge_file_t* merge_file) /*!< out: merge file structure */
{
if (merge_file->fd != -1) {
close(merge_file->fd);
@@ -1910,18 +1925,17 @@ row_merge_file_destroy(
}
}
-/*************************************************************************
+/*********************************************************************//**
Determine the precise type of a column that is added to a tem
-if a column must be constrained NOT NULL. */
+if a column must be constrained NOT NULL.
+@return col->prtype, possibly ORed with DATA_NOT_NULL */
UNIV_INLINE
ulint
row_merge_col_prtype(
/*=================*/
- /* out: col->prtype, possibly
- ORed with DATA_NOT_NULL */
- const dict_col_t* col, /* in: column */
- const char* col_name, /* in: name of the column */
- const merge_index_def_t*index_def) /* in: the index definition
+ const dict_col_t* col, /*!< in: column */
+ const char* col_name, /*!< in: name of the column */
+ const merge_index_def_t*index_def) /*!< in: the index definition
of the primary key */
{
ulint prtype = col->prtype;
@@ -1946,20 +1960,19 @@ row_merge_col_prtype(
return(prtype);
}
-/*************************************************************************
+/*********************************************************************//**
Create a temporary table for creating a primary key, using the definition
-of an existing table. */
+of an existing table.
+@return table, or NULL on error */
UNIV_INTERN
dict_table_t*
row_merge_create_temporary_table(
/*=============================*/
- /* out: table,
- or NULL on error */
- const char* table_name, /* in: new table name */
- const merge_index_def_t*index_def, /* in: the index definition
+ const char* table_name, /*!< in: new table name */
+ const merge_index_def_t*index_def, /*!< in: the index definition
of the primary key */
- const dict_table_t* table, /* in: old table definition */
- trx_t* trx) /* in/out: transaction
+ const dict_table_t* table, /*!< in: old table definition */
+ trx_t* trx) /*!< in/out: transaction
(sets error_state) */
{
ulint i;
@@ -1999,17 +2012,17 @@ row_merge_create_temporary_table(
return(new_table);
}
-/*************************************************************************
+/*********************************************************************//**
Rename the temporary indexes in the dictionary to permanent ones. The
data dictionary must have been locked exclusively by the caller,
-because the transaction will not be committed. */
+because the transaction will not be committed.
+@return DB_SUCCESS if all OK */
UNIV_INTERN
ulint
row_merge_rename_indexes(
/*=====================*/
- /* out: DB_SUCCESS if all OK */
- trx_t* trx, /* in/out: transaction */
- dict_table_t* table) /* in/out: table with new indexes */
+ trx_t* trx, /*!< in/out: transaction */
+ dict_table_t* table) /*!< in/out: table with new indexes */
{
ulint err = DB_SUCCESS;
pars_info_t* info = pars_info_create();
@@ -2017,15 +2030,12 @@ row_merge_rename_indexes(
/* We use the private SQL parser of Innobase to generate the
query graphs needed in renaming indexes. */
-#if TEMP_INDEX_PREFIX != '\377'
-# error "TEMP_INDEX_PREFIX != '\377'"
-#endif
-
static const char rename_indexes[] =
"PROCEDURE RENAME_INDEXES_PROC () IS\n"
"BEGIN\n"
"UPDATE SYS_INDEXES SET NAME=SUBSTR(NAME,1,LENGTH(NAME)-1)\n"
- "WHERE TABLE_ID = :tableid AND SUBSTR(NAME,0,1)='\377';\n"
+ "WHERE TABLE_ID = :tableid AND SUBSTR(NAME,0,1)='"
+ TEMP_INDEX_PREFIX_STR "';\n"
"END;\n";
ut_ad(table);
@@ -2053,21 +2063,21 @@ row_merge_rename_indexes(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Rename the tables in the data dictionary. The data dictionary must
have been locked exclusively by the caller, because the transaction
-will not be committed. */
+will not be committed.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_merge_rename_tables(
/*====================*/
- /* out: error code or DB_SUCCESS */
- dict_table_t* old_table, /* in/out: old table, renamed to
+ dict_table_t* old_table, /*!< in/out: old table, renamed to
tmp_name */
- dict_table_t* new_table, /* in/out: new table, renamed to
+ dict_table_t* new_table, /*!< in/out: new table, renamed to
old_table->name */
- const char* tmp_name, /* in: new name for old_table */
- trx_t* trx) /* in: transaction handle */
+ const char* tmp_name, /*!< in: new name for old_table */
+ trx_t* trx) /*!< in: transaction handle */
{
ulint err = DB_ERROR;
pars_info_t* info;
@@ -2128,20 +2138,20 @@ err_exit:
return(err);
}
-/*************************************************************************
-Create and execute a query graph for creating an index. */
+/*********************************************************************//**
+Create and execute a query graph for creating an index.
+@return DB_SUCCESS or error code */
static
ulint
row_merge_create_index_graph(
/*=========================*/
- /* out: DB_SUCCESS or error code */
- trx_t* trx, /* in: trx */
- dict_table_t* table, /* in: table */
- dict_index_t* index) /* in: index */
+ trx_t* trx, /*!< in: trx */
+ dict_table_t* table, /*!< in: table */
+ dict_index_t* index) /*!< in: index */
{
- ind_node_t* node; /* Index creation node */
- mem_heap_t* heap; /* Memory heap */
- que_thr_t* thr; /* Query thread */
+ ind_node_t* node; /*!< Index creation node */
+ mem_heap_t* heap; /*!< Memory heap */
+ que_thr_t* thr; /*!< Query thread */
ulint err;
ut_ad(trx);
@@ -2165,17 +2175,17 @@ row_merge_create_index_graph(
return(err);
}
-/*************************************************************************
-Create the index and load in to the dictionary. */
+/*********************************************************************//**
+Create the index and load in to the dictionary.
+@return index, or NULL on error */
UNIV_INTERN
dict_index_t*
row_merge_create_index(
/*===================*/
- /* out: index, or NULL on error */
- trx_t* trx, /* in/out: trx (sets error_state) */
- dict_table_t* table, /* in: the index is on this table */
- const merge_index_def_t* /* in: the index definition */
- index_def)
+ trx_t* trx, /*!< in/out: trx (sets error_state) */
+ dict_table_t* table, /*!< in: the index is on this table */
+ const merge_index_def_t*index_def)
+ /*!< in: the index definition */
{
dict_index_t* index;
ulint err;
@@ -2208,12 +2218,11 @@ row_merge_create_index(
ut_a(index);
-#ifdef ROW_MERGE_IS_INDEX_USABLE
/* Note the id of the transaction that created this
index, we use it to restrict readers from accessing
this index, to ensure read consistency. */
- index->trx_id = trx->id;
-#endif /* ROW_MERGE_IS_INDEX_USABLE */
+ index->trx_id = (ib_uint64_t)
+ ut_conv_dulint_to_longlong(trx->id);
} else {
index = NULL;
}
@@ -2221,33 +2230,30 @@ row_merge_create_index(
return(index);
}
-#ifdef ROW_MERGE_IS_INDEX_USABLE
-/*************************************************************************
+/*********************************************************************//**
Check if a transaction can use an index. */
UNIV_INTERN
ibool
row_merge_is_index_usable(
/*======================*/
- const trx_t* trx, /* in: transaction */
- const dict_index_t* index) /* in: index to check */
+ const trx_t* trx, /*!< in: transaction */
+ const dict_index_t* index) /*!< in: index to check */
{
- if (!trx->read_view) {
- return(TRUE);
- }
-
- return(ut_dulint_cmp(index->trx_id, trx->read_view->low_limit_id) < 0);
+ return(!trx->read_view || read_view_sees_trx_id(
+ trx->read_view,
+ ut_dulint_create((ulint) (index->trx_id >> 32),
+ (ulint) index->trx_id & 0xFFFFFFFF)));
}
-#endif /* ROW_MERGE_IS_INDEX_USABLE */
-/*************************************************************************
-Drop the old table. */
+/*********************************************************************//**
+Drop the old table.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
row_merge_drop_table(
/*=================*/
- /* out: DB_SUCCESS or error code */
- trx_t* trx, /* in: transaction */
- dict_table_t* table) /* in: table to drop */
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* table) /*!< in: table to drop */
{
/* There must be no open transactions on the table. */
ut_a(table->n_mysql_handles_opened == 0);
@@ -2255,24 +2261,24 @@ row_merge_drop_table(
return(row_drop_table_for_mysql(table->name, trx, FALSE));
}
-/*************************************************************************
+/*********************************************************************//**
Build indexes on a table by reading a clustered index,
creating a temporary file containing index entries, merge sorting
-these index entries and inserting sorted index entries to indexes. */
+these index entries and inserting sorted index entries to indexes.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
row_merge_build_indexes(
/*====================*/
- /* out: DB_SUCCESS or error code */
- trx_t* trx, /* in: transaction */
- dict_table_t* old_table, /* in: table where rows are
+ trx_t* trx, /*!< in: transaction */
+ dict_table_t* old_table, /*!< in: table where rows are
read from */
- dict_table_t* new_table, /* in: table where indexes are
+ dict_table_t* new_table, /*!< in: table where indexes are
created; identical to old_table
unless creating a PRIMARY KEY */
- dict_index_t** indexes, /* in: indexes to be created */
- ulint n_indexes, /* in: size of indexes[] */
- TABLE* table) /* in/out: MySQL table, for
+ dict_index_t** indexes, /*!< in: indexes to be created */
+ ulint n_indexes, /*!< in: size of indexes[] */
+ TABLE* table) /*!< in/out: MySQL table, for
reporting erroneous key value
if applicable */
{
diff --git a/storage/xtradb/row/row0mysql.c b/storage/xtradb/row/row0mysql.c
index 3a9e1de0125..25946399fb6 100644
--- a/storage/xtradb/row/row0mysql.c
+++ b/storage/xtradb/row/row0mysql.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0mysql.c
Interface between Innobase row operations and MySQL.
Contains also create table and other data dictionary operations.
@@ -30,6 +31,7 @@ Created 9/17/2000 Heikki Tuuri
#endif
#include "row0ins.h"
+#include "row0merge.h"
#include "row0sel.h"
#include "row0upd.h"
#include "row0row.h"
@@ -50,43 +52,54 @@ Created 9/17/2000 Heikki Tuuri
#include "fil0fil.h"
#include "ibuf0ibuf.h"
-/* Provide optional 4.x backwards compatibility for 5.0 and above */
+/** Provide optional 4.x backwards compatibility for 5.0 and above */
UNIV_INTERN ibool row_rollback_on_timeout = FALSE;
-/* List of tables we should drop in background. ALTER TABLE in MySQL requires
-that the table handler can drop the table in background when there are no
-queries to it any more. Protected by the kernel mutex. */
+/** Chain node of the list of tables to drop in the background. */
typedef struct row_mysql_drop_struct row_mysql_drop_t;
+
+/** Chain node of the list of tables to drop in the background. */
struct row_mysql_drop_struct{
- char* table_name;
- UT_LIST_NODE_T(row_mysql_drop_t) row_mysql_drop_list;
+ char* table_name; /*!< table name */
+ UT_LIST_NODE_T(row_mysql_drop_t)row_mysql_drop_list;
+ /*!< list chain node */
};
+/** @brief List of tables we should drop in background.
+
+ALTER TABLE in MySQL requires that the table handler can drop the
+table in background when there are no queries to it any
+more. Protected by kernel_mutex. */
static UT_LIST_BASE_NODE_T(row_mysql_drop_t) row_mysql_drop_list;
+/** Flag: has row_mysql_drop_list been initialized? */
static ibool row_mysql_drop_list_inited = FALSE;
-/* Magic table names for invoking various monitor threads */
+/** Magic table names for invoking various monitor threads */
+/* @{ */
static const char S_innodb_monitor[] = "innodb_monitor";
static const char S_innodb_lock_monitor[] = "innodb_lock_monitor";
static const char S_innodb_tablespace_monitor[] = "innodb_tablespace_monitor";
static const char S_innodb_table_monitor[] = "innodb_table_monitor";
static const char S_innodb_mem_validate[] = "innodb_mem_validate";
-
-/* Evaluates to true if str1 equals str2_onstack, used for comparing
-the above strings. */
+/* @} */
+
+/** Evaluates to true if str1 equals str2_onstack, used for comparing
+the magic table names.
+@param str1 in: string to compare
+@param str1_len in: length of str1, in bytes, including terminating NUL
+@param str2_onstack in: char[] array containing a NUL terminated string
+@return TRUE if str1 equals str2_onstack */
#define STR_EQ(str1, str1_len, str2_onstack) \
((str1_len) == sizeof(str2_onstack) \
&& memcmp(str1, str2_onstack, sizeof(str2_onstack)) == 0)
-#ifndef UNIV_HOTBACKUP
-/***********************************************************************
-Determine if the given name is a name reserved for MySQL system tables. */
+/*******************************************************************//**
+Determine if the given name is a name reserved for MySQL system tables.
+@return TRUE if name is a MySQL system table name */
static
ibool
row_mysql_is_system_table(
/*======================*/
- /* out: TRUE if name is a MySQL
- system table name */
const char* name)
{
if (strncmp(name, "mysql/", 6) != 0) {
@@ -98,23 +111,21 @@ row_mysql_is_system_table(
|| 0 == strcmp(name + 6, "user")
|| 0 == strcmp(name + 6, "db"));
}
-#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
+/*********************************************************************//**
If a table is not yet in the drop list, adds the table to the list of tables
which the master thread drops in background. We need this on Unix because in
ALTER TABLE MySQL may call drop table even if the table has running queries on
it. Also, if there are running foreign key checks on the table, we drop the
-table lazily. */
+table lazily.
+@return TRUE if the table was not yet in the drop list, and was added there */
static
ibool
row_add_table_to_background_drop_list(
/*==================================*/
- /* out: TRUE if the table was not yet in the
- drop list, and was added there */
- const char* name); /* in: table name */
+ const char* name); /*!< in: table name */
-/***********************************************************************
+/*******************************************************************//**
Delays an INSERT, DELETE or UPDATE operation if the purge is lagging. */
static
void
@@ -126,31 +137,31 @@ row_mysql_delay_if_needed(void)
}
}
-/***********************************************************************
+/*******************************************************************//**
Frees the blob heap in prebuilt when no longer needed. */
UNIV_INTERN
void
row_mysql_prebuilt_free_blob_heap(
/*==============================*/
- row_prebuilt_t* prebuilt) /* in: prebuilt struct of a
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct of a
ha_innobase:: table handle */
{
mem_heap_free(prebuilt->blob_heap);
prebuilt->blob_heap = NULL;
}
-/***********************************************************************
+/*******************************************************************//**
Stores a >= 5.0.3 format true VARCHAR length to dest, in the MySQL row
-format. */
+format.
+@return pointer to the data, we skip the 1 or 2 bytes at the start
+that are used to store the len */
UNIV_INTERN
byte*
row_mysql_store_true_var_len(
/*=========================*/
- /* out: pointer to the data, we skip the 1 or 2 bytes
- at the start that are used to store the len */
- byte* dest, /* in: where to store */
- ulint len, /* in: length, must fit in two bytes */
- ulint lenlen) /* in: storage length of len: either 1 or 2 bytes */
+ byte* dest, /*!< in: where to store */
+ ulint len, /*!< in: length, must fit in two bytes */
+ ulint lenlen) /*!< in: storage length of len: either 1 or 2 bytes */
{
if (lenlen == 2) {
ut_a(len < 256 * 256);
@@ -168,19 +179,18 @@ row_mysql_store_true_var_len(
return(dest + 1);
}
-/***********************************************************************
+/*******************************************************************//**
Reads a >= 5.0.3 format true VARCHAR length, in the MySQL row format, and
-returns a pointer to the data. */
+returns a pointer to the data.
+@return pointer to the data, we skip the 1 or 2 bytes at the start
+that are used to store the len */
UNIV_INTERN
const byte*
row_mysql_read_true_varchar(
/*========================*/
- /* out: pointer to the data, we skip
- the 1 or 2 bytes at the start that are
- used to store the len */
- ulint* len, /* out: variable-length field length */
- const byte* field, /* in: field in the MySQL format */
- ulint lenlen) /* in: storage length of len: either 1
+ ulint* len, /*!< out: variable-length field length */
+ const byte* field, /*!< in: field in the MySQL format */
+ ulint lenlen) /*!< in: storage length of len: either 1
or 2 bytes */
{
if (lenlen == 2) {
@@ -196,20 +206,20 @@ row_mysql_read_true_varchar(
return(field + 1);
}
-/***********************************************************************
+/*******************************************************************//**
Stores a reference to a BLOB in the MySQL format. */
UNIV_INTERN
void
row_mysql_store_blob_ref(
/*=====================*/
- byte* dest, /* in: where to store */
- ulint col_len,/* in: dest buffer size: determines into
+ byte* dest, /*!< in: where to store */
+ ulint col_len,/*!< in: dest buffer size: determines into
how many bytes the BLOB length is stored,
the space for the length may vary from 1
to 4 bytes */
- const void* data, /* in: BLOB data; if the value to store
+ const void* data, /*!< in: BLOB data; if the value to store
is SQL NULL this should be NULL pointer */
- ulint len) /* in: BLOB length; if the value to store
+ ulint len) /*!< in: BLOB length; if the value to store
is SQL NULL this should be 0; remember
also to set the NULL bit in the MySQL record
header! */
@@ -233,17 +243,17 @@ row_mysql_store_blob_ref(
memcpy(dest + col_len - 8, &data, sizeof data);
}
-/***********************************************************************
-Reads a reference to a BLOB in the MySQL format. */
+/*******************************************************************//**
+Reads a reference to a BLOB in the MySQL format.
+@return pointer to BLOB data */
UNIV_INTERN
const byte*
row_mysql_read_blob_ref(
/*====================*/
- /* out: pointer to BLOB data */
- ulint* len, /* out: BLOB length */
- const byte* ref, /* in: BLOB reference in the
+ ulint* len, /*!< out: BLOB length */
+ const byte* ref, /*!< in: BLOB reference in the
MySQL format */
- ulint col_len) /* in: BLOB reference length
+ ulint col_len) /*!< in: BLOB reference length
(not BLOB length) */
{
byte* data;
@@ -255,41 +265,40 @@ row_mysql_read_blob_ref(
return(data);
}
-/******************************************************************
+/**************************************************************//**
Stores a non-SQL-NULL field given in the MySQL format in the InnoDB format.
The counterpart of this function is row_sel_field_store_in_mysql_format() in
-row0sel.c. */
+row0sel.c.
+@return up to which byte we used buf in the conversion */
UNIV_INTERN
byte*
row_mysql_store_col_in_innobase_format(
/*===================================*/
- /* out: up to which byte we used
- buf in the conversion */
- dfield_t* dfield, /* in/out: dfield where dtype
+ dfield_t* dfield, /*!< in/out: dfield where dtype
information must be already set when
this function is called! */
- byte* buf, /* in/out: buffer for a converted
+ byte* buf, /*!< in/out: buffer for a converted
integer value; this must be at least
col_len long then! */
- ibool row_format_col, /* TRUE if the mysql_data is from
+ ibool row_format_col, /*!< TRUE if the mysql_data is from
a MySQL row, FALSE if from a MySQL
key value;
in MySQL, a true VARCHAR storage
format differs in a row and in a
key value: in a key value the length
is always stored in 2 bytes! */
- const byte* mysql_data, /* in: MySQL column value, not
+ const byte* mysql_data, /*!< in: MySQL column value, not
SQL NULL; NOTE that dfield may also
get a pointer to mysql_data,
therefore do not discard this as long
as dfield is used! */
- ulint col_len, /* in: MySQL column length; NOTE that
+ ulint col_len, /*!< in: MySQL column length; NOTE that
this is the storage length of the
column in the MySQL format row, not
necessarily the length of the actual
payload data; if the column is a true
VARCHAR then this is irrelevant */
- ulint comp) /* in: nonzero=compact format */
+ ulint comp) /*!< in: nonzero=compact format */
{
const byte* ptr = mysql_data;
const dtype_t* dtype;
@@ -417,7 +426,7 @@ row_mysql_store_col_in_innobase_format(
return(buf);
}
-/******************************************************************
+/**************************************************************//**
Convert a row in the MySQL format to a row in the Innobase format. Note that
the function to convert a MySQL format key value to an InnoDB dtuple is
row_sel_convert_mysql_key_to_innobase() in row0sel.c. */
@@ -425,12 +434,12 @@ static
void
row_mysql_convert_row_to_innobase(
/*==============================*/
- dtuple_t* row, /* in/out: Innobase row where the
+ dtuple_t* row, /*!< in/out: Innobase row where the
field type information is already
copied there! */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct where template
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct where template
must be of type ROW_MYSQL_WHOLE_ROW */
- byte* mysql_rec) /* in: row in the MySQL format;
+ byte* mysql_rec) /*!< in: row in the MySQL format;
NOTE: do not discard as long as
row is used, as row may contain
pointers to this record! */
@@ -473,23 +482,22 @@ next_column:
}
}
-/********************************************************************
-Handles user errors and lock waits detected by the database engine. */
+/****************************************************************//**
+Handles user errors and lock waits detected by the database engine.
+@return TRUE if it was a lock wait and we should continue running the
+query thread */
UNIV_INTERN
ibool
row_mysql_handle_errors(
/*====================*/
- /* out: TRUE if it was a lock wait and
- we should continue running the query thread */
- ulint* new_err,/* out: possible new error encountered in
+ ulint* new_err,/*!< out: possible new error encountered in
lock wait, or if no new error, the value
of trx->error_state at the entry of this
function */
- trx_t* trx, /* in: transaction */
- que_thr_t* thr, /* in: query thread */
- trx_savept_t* savept) /* in: savepoint or NULL */
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t* thr, /*!< in: query thread */
+ trx_savept_t* savept) /*!< in: savepoint or NULL */
{
-#ifndef UNIV_HOTBACKUP
ulint err;
handle_new_error:
@@ -564,8 +572,7 @@ handle_new_error:
"InnoDB: If the mysqld server crashes"
" after the startup or when\n"
"InnoDB: you dump the tables, look at\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "forcing-recovery.html"
+ "InnoDB: " REFMAN "forcing-recovery.html"
" for help.\n", stderr);
break;
default:
@@ -583,23 +590,16 @@ handle_new_error:
trx->error_state = DB_SUCCESS;
return(FALSE);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
- return(FALSE);
-#endif /* UNIV_HOTBACKUP */
}
-/************************************************************************
-Create a prebuilt struct for a MySQL table handle. */
+/********************************************************************//**
+Create a prebuilt struct for a MySQL table handle.
+@return own: a prebuilt struct */
UNIV_INTERN
row_prebuilt_t*
row_create_prebuilt(
/*================*/
- /* out, own: a prebuilt struct */
- dict_table_t* table) /* in: Innobase table handle */
+ dict_table_t* table) /*!< in: Innobase table handle */
{
row_prebuilt_t* prebuilt;
mem_heap_t* heap;
@@ -653,14 +653,14 @@ row_create_prebuilt(
return(prebuilt);
}
-/************************************************************************
+/********************************************************************//**
Free a prebuilt struct for a MySQL table handle. */
UNIV_INTERN
void
row_prebuilt_free(
/*==============*/
- row_prebuilt_t* prebuilt, /* in, own: prebuilt struct */
- ibool dict_locked) /* in: TRUE=data dictionary locked */
+ row_prebuilt_t* prebuilt, /*!< in, own: prebuilt struct */
+ ibool dict_locked) /*!< in: TRUE=data dictionary locked */
{
ulint i;
@@ -738,17 +738,16 @@ row_prebuilt_free(
mem_heap_free(prebuilt->heap);
}
-/*************************************************************************
+/*********************************************************************//**
Updates the transaction pointers in query graphs stored in the prebuilt
struct. */
UNIV_INTERN
void
row_update_prebuilt_trx(
/*====================*/
- /* out: prebuilt dtuple */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL
- handle */
- trx_t* trx) /* in: transaction handle */
+ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct
+ in MySQL handle */
+ trx_t* trx) /*!< in: transaction handle */
{
if (trx->magic_n != TRX_MAGIC_N) {
fprintf(stderr,
@@ -789,17 +788,16 @@ row_update_prebuilt_trx(
}
}
-/*************************************************************************
+/*********************************************************************//**
Gets pointer to a prebuilt dtuple used in insertions. If the insert graph
has not yet been built in the prebuilt struct, then this function first
-builds it. */
+builds it.
+@return prebuilt dtuple; the column type information is also set in it */
static
dtuple_t*
row_get_prebuilt_insert_row(
/*========================*/
- /* out: prebuilt dtuple; the column
- type information is also set in it */
- row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
handle */
{
ins_node_t* node;
@@ -839,14 +837,14 @@ row_get_prebuilt_insert_row(
return(prebuilt->ins_node->row);
}
-/*************************************************************************
+/*********************************************************************//**
Updates the table modification counter and calculates new estimates
for table and index statistics if necessary. */
UNIV_INLINE
void
row_update_statistics_if_needed(
/*============================*/
- dict_table_t* table) /* in: table */
+ dict_table_t* table) /*!< in: table */
{
ulint counter;
@@ -870,13 +868,13 @@ row_update_statistics_if_needed(
}
}
-/*************************************************************************
+/*********************************************************************//**
Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
UNIV_INTERN
void
row_unlock_table_autoinc_for_mysql(
/*===============================*/
- trx_t* trx) /* in/out: transaction */
+ trx_t* trx) /*!< in/out: transaction */
{
mutex_enter(&kernel_mutex);
@@ -885,18 +883,18 @@ row_unlock_table_autoinc_for_mysql(
mutex_exit(&kernel_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
Sets an AUTO_INC type lock on the table mentioned in prebuilt. The
AUTO_INC lock gives exclusive access to the auto-inc counter of the
table. The lock is reserved only for the duration of an SQL statement.
It is not compatible with another AUTO_INC or exclusive lock on the
-table. */
+table.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_lock_table_autoinc_for_mysql(
/*=============================*/
- /* out: error code or DB_SUCCESS */
- row_prebuilt_t* prebuilt) /* in: prebuilt struct in the MySQL
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in the MySQL
table handle */
{
trx_t* trx = prebuilt->trx;
@@ -965,20 +963,20 @@ run_again:
return((int) err);
}
-/*************************************************************************
-Sets a table lock on the table mentioned in prebuilt. */
+/*********************************************************************//**
+Sets a table lock on the table mentioned in prebuilt.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_lock_table_for_mysql(
/*=====================*/
- /* out: error code or DB_SUCCESS */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct in the MySQL
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in the MySQL
table handle */
- dict_table_t* table, /* in: table to lock, or NULL
+ dict_table_t* table, /*!< in: table to lock, or NULL
if prebuilt->table should be
locked as
prebuilt->select_lock_type */
- ulint mode) /* in: lock mode of table
+ ulint mode) /*!< in: lock mode of table
(ignored if table==NULL) */
{
trx_t* trx = prebuilt->trx;
@@ -1042,15 +1040,15 @@ run_again:
return((int) err);
}
-/*************************************************************************
-Does an insert for MySQL. */
+/*********************************************************************//**
+Does an insert for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_insert_for_mysql(
/*=================*/
- /* out: error code or DB_SUCCESS */
- byte* mysql_rec, /* in: row in the MySQL format */
- row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
+ byte* mysql_rec, /*!< in: row in the MySQL format */
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
handle */
{
trx_savept_t savept;
@@ -1074,8 +1072,7 @@ row_insert_for_mysql(
"InnoDB: the MySQL datadir, or have you"
" used DISCARD TABLESPACE?\n"
"InnoDB: Look from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
"InnoDB: how you can resolve the problem.\n",
prebuilt->table->name);
return(DB_ERROR);
@@ -1175,13 +1172,13 @@ run_again:
return((int) err);
}
-/*************************************************************************
+/*********************************************************************//**
Builds a dummy query graph used in selects. */
UNIV_INTERN
void
row_prebuild_sel_graph(
/*===================*/
- row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
handle */
{
sel_node_t* node;
@@ -1201,16 +1198,16 @@ row_prebuild_sel_graph(
}
}
-/*************************************************************************
+/*********************************************************************//**
Creates an query graph node of 'update' type to be used in the MySQL
-interface. */
+interface.
+@return own: update node */
UNIV_INTERN
upd_node_t*
row_create_update_node_for_mysql(
/*=============================*/
- /* out, own: update node */
- dict_table_t* table, /* in: table to update */
- mem_heap_t* heap) /* in: mem heap from which allocated */
+ dict_table_t* table, /*!< in: table to update */
+ mem_heap_t* heap) /*!< in: mem heap from which allocated */
{
upd_node_t* node;
@@ -1237,16 +1234,16 @@ row_create_update_node_for_mysql(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Gets pointer to a prebuilt update vector used in updates. If the update
graph has not yet been built in the prebuilt struct, then this function
-first builds it. */
+first builds it.
+@return prebuilt update vector */
UNIV_INTERN
upd_t*
row_get_prebuilt_update_vector(
/*===========================*/
- /* out: prebuilt update vector */
- row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
handle */
{
dict_table_t* table = prebuilt->table;
@@ -1273,16 +1270,16 @@ row_get_prebuilt_update_vector(
return(prebuilt->upd_node->update);
}
-/*************************************************************************
-Does an update or delete of a row for MySQL. */
+/*********************************************************************//**
+Does an update or delete of a row for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_update_for_mysql(
/*=================*/
- /* out: error code or DB_SUCCESS */
- byte* mysql_rec, /* in: the row to be updated, in
+ byte* mysql_rec, /*!< in: the row to be updated, in
the MySQL format */
- row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
handle */
{
trx_savept_t savept;
@@ -1310,8 +1307,7 @@ row_update_for_mysql(
"InnoDB: the MySQL datadir, or have you"
" used DISCARD TABLESPACE?\n"
"InnoDB: Look from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
"InnoDB: how you can resolve the problem.\n",
prebuilt->table->name);
return(DB_ERROR);
@@ -1429,7 +1425,7 @@ run_again:
return((int) err);
}
-/*************************************************************************
+/*********************************************************************//**
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
@@ -1439,15 +1435,15 @@ 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. */
+locks we set.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_unlock_for_mysql(
/*=================*/
- /* out: error code or DB_SUCCESS */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL
handle */
- ibool has_latches_on_recs)/* TRUE if called so that we have
+ 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. */
@@ -1476,9 +1472,9 @@ row_unlock_for_mysql(
if (prebuilt->new_rec_locks >= 1) {
- rec_t* rec;
+ const rec_t* rec;
dict_index_t* index;
- dulint rec_trx_id;
+ trx_id_t rec_trx_id;
mtr_t mtr;
mtr_start(&mtr);
@@ -1505,7 +1501,7 @@ row_unlock_for_mysql(
index = btr_pcur_get_btr_cur(clust_pcur)->index;
}
- if (UNIV_UNLIKELY(!(dict_index_is_clust(index)))) {
+ if (UNIV_UNLIKELY(!dict_index_is_clust(index))) {
/* This is not a clustered index record. We
do not know how to unlock the record. */
goto no_unlock;
@@ -1522,7 +1518,7 @@ row_unlock_for_mysql(
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
- *offsets_ = (sizeof offsets_) / sizeof *offsets_;
+ rec_offs_init(offsets_);
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
@@ -1546,11 +1542,12 @@ row_unlock_for_mysql(
rec = btr_pcur_get_rec(clust_pcur);
index = btr_pcur_get_btr_cur(clust_pcur)->index;
- lock_rec_unlock(trx, btr_pcur_get_block(clust_pcur),
- rec, prebuilt->select_lock_type);
+ lock_rec_unlock(trx,
+ btr_pcur_get_block(clust_pcur),
+ rec,
+ prebuilt->select_lock_type);
}
}
-
no_unlock:
mtr_commit(&mtr);
}
@@ -1560,17 +1557,17 @@ no_unlock:
return(DB_SUCCESS);
}
-/**************************************************************************
-Does a cascaded delete or set null in a foreign key operation. */
+/**********************************************************************//**
+Does a cascaded delete or set null in a foreign key operation.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_update_cascade_for_mysql(
/*=========================*/
- /* out: error code or DB_SUCCESS */
- que_thr_t* thr, /* in: query thread */
- upd_node_t* node, /* in: update node used in the cascade
+ que_thr_t* thr, /*!< in: query thread */
+ upd_node_t* node, /*!< in: update node used in the cascade
or set null operation */
- dict_table_t* table) /* in: table where we do the operation */
+ dict_table_t* table) /*!< in: table where we do the operation */
{
ulint err;
trx_t* trx;
@@ -1629,14 +1626,15 @@ run_again:
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if a table is such that we automatically created a clustered
-index on it (on row id). */
+index on it (on row id).
+@return TRUE if the clustered index was generated automatically */
UNIV_INTERN
ibool
row_table_got_default_clust_index(
/*==============================*/
- const dict_table_t* table)
+ const dict_table_t* table) /*!< in: table */
{
const dict_index_t* clust_index;
@@ -1645,14 +1643,15 @@ row_table_got_default_clust_index(
return(dict_index_get_nth_col(clust_index, 0)->mtype == DATA_SYS);
}
-/*************************************************************************
+/*********************************************************************//**
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 */
+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)
+ const dict_index_t* index) /*!< in: index */
{
const dict_index_t* ind;
ulint i;
@@ -1675,16 +1674,16 @@ row_get_mysql_key_number_for_index(
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
void
row_mysql_freeze_data_dictionary_func(
/*==================================*/
- trx_t* trx, /* in/out: transaction */
- const char* file, /* in: file name */
- ulint line) /* in: line number */
+ trx_t* trx, /*!< in/out: transaction */
+ const char* file, /*!< in: file name */
+ ulint line) /*!< in: line number */
{
ut_a(trx->dict_operation_lock_mode == 0);
@@ -1693,13 +1692,13 @@ row_mysql_freeze_data_dictionary_func(
trx->dict_operation_lock_mode = RW_S_LATCH;
}
-/*************************************************************************
+/*********************************************************************//**
Unlocks the data dictionary shared lock. */
UNIV_INTERN
void
row_mysql_unfreeze_data_dictionary(
/*===============================*/
- trx_t* trx) /* in/out: transaction */
+ trx_t* trx) /*!< in/out: transaction */
{
ut_a(trx->dict_operation_lock_mode == RW_S_LATCH);
@@ -1708,16 +1707,16 @@ row_mysql_unfreeze_data_dictionary(
trx->dict_operation_lock_mode = 0;
}
-/*************************************************************************
+/*********************************************************************//**
Locks the data dictionary exclusively for performing a table create or other
data dictionary modification operation. */
UNIV_INTERN
void
row_mysql_lock_data_dictionary_func(
/*================================*/
- trx_t* trx, /* in/out: transaction */
- const char* file, /* in: file name */
- ulint line) /* in: line number */
+ trx_t* trx, /*!< in/out: transaction */
+ const char* file, /*!< in: file name */
+ ulint line) /*!< in: line number */
{
ut_a(trx->dict_operation_lock_mode == 0
|| trx->dict_operation_lock_mode == RW_X_LATCH);
@@ -1731,13 +1730,13 @@ row_mysql_lock_data_dictionary_func(
mutex_enter(&(dict_sys->mutex));
}
-/*************************************************************************
+/*********************************************************************//**
Unlocks the data dictionary exclusive lock. */
UNIV_INTERN
void
row_mysql_unlock_data_dictionary(
/*=============================*/
- trx_t* trx) /* in/out: transaction */
+ trx_t* trx) /*!< in/out: transaction */
{
ut_a(trx->dict_operation_lock_mode == RW_X_LATCH);
@@ -1750,21 +1749,20 @@ row_mysql_unlock_data_dictionary(
trx->dict_operation_lock_mode = 0;
}
-#ifndef UNIV_HOTBACKUP
-/*************************************************************************
+/*********************************************************************//**
Creates a table for MySQL. If the name of the table ends in
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
"innodb_table_monitor", then this will also start the printing of monitor
output by the master thread. If the table name ends in "innodb_mem_validate",
-InnoDB will try to invoke mem_validate(). */
+InnoDB will try to invoke mem_validate().
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_create_table_for_mysql(
/*=======================*/
- /* out: error code or DB_SUCCESS */
- dict_table_t* table, /* in, own: table definition
+ dict_table_t* table, /*!< in, own: table definition
(will be freed) */
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx) /*!< in: transaction handle */
{
tab_node_t* node;
mem_heap_t* heap;
@@ -1931,9 +1929,8 @@ err_exit:
" and DROP TABLE will\n"
"InnoDB: succeed.\n"
"InnoDB: You can look for further help from\n"
- "InnoDB: "
- "http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n", stderr);
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n",
+ stderr);
/* We may also get err == DB_ERROR if the .ibd file for the
table already exists */
@@ -1948,19 +1945,19 @@ err_exit:
return((int) err);
}
-/*************************************************************************
+/*********************************************************************//**
Does an index creation operation for MySQL. TODO: currently failure
to create an index results in dropping the whole table! This is no problem
-currently as all indexes must be created at the same time as the table. */
+currently as all indexes must be created at the same time as the table.
+@return error number or DB_SUCCESS */
UNIV_INTERN
int
row_create_index_for_mysql(
/*=======================*/
- /* out: error number or DB_SUCCESS */
- dict_index_t* index, /* in, own: index definition
+ dict_index_t* index, /*!< in, own: index definition
(will be freed) */
- trx_t* trx, /* in: transaction handle */
- const ulint* field_lengths) /* in: if not NULL, must contain
+ trx_t* trx, /*!< in: transaction handle */
+ const ulint* field_lengths) /*!< in: if not NULL, must contain
dict_index_get_n_fields(index)
actual field lengths for the
index columns, which are
@@ -2075,29 +2072,29 @@ error_handling:
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.
Each foreign key constraint must be accompanied with indexes in
bot participating tables. The indexes are allowed to contain more
fields than mentioned in the constraint. Check also that foreign key
-constraints which reference this table are ok. */
+constraints which reference this table are ok.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_table_add_foreign_constraints(
/*==============================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in: transaction */
- const char* sql_string, /* in: table create statement where
+ trx_t* trx, /*!< in: transaction */
+ const char* sql_string, /*!< in: table create statement where
foreign keys are declared like:
FOREIGN KEY (a, b) REFERENCES table2(c, d),
table2 can be written also with the
database name before it: test.table2 */
- const char* name, /* in: table full name in the
+ const char* name, /*!< in: table full name in the
normalized form
database_name/table_name */
- ibool reject_fks) /* in: if TRUE, fail with error
+ ibool reject_fks) /*!< in: if TRUE, fail with error
code DB_CANNOT_ADD_CONSTRAINT if
any foreign keys are found. */
{
@@ -2117,12 +2114,11 @@ row_table_add_foreign_constraints(
err = dict_create_foreign_constraints(trx, sql_string, name,
reject_fks);
-#ifndef UNIV_HOTBACKUP
if (err == DB_SUCCESS) {
/* Check that also referencing constraints are ok */
err = dict_load_foreigns(name, TRUE);
}
-#endif /* !UNIV_HOTBACKUP */
+
if (err != DB_SUCCESS) {
/* We have special error handling here */
@@ -2140,19 +2136,19 @@ row_table_add_foreign_constraints(
return((int) err);
}
-/*************************************************************************
+/*********************************************************************//**
Drops a table for MySQL as a background operation. MySQL relies on Unix
in ALTER TABLE to the fact that the table handler does not remove the
table before all handles to it has been removed. Furhermore, the MySQL's
call to drop table must be non-blocking. Therefore we do the drop table
as a background operation, which is taken care of by the master thread
-in srv0srv.c. */
+in srv0srv.c.
+@return error code or DB_SUCCESS */
static
int
row_drop_table_for_mysql_in_background(
/*===================================*/
- /* out: error code or DB_SUCCESS */
- const char* name) /* in: table name */
+ const char* name) /*!< in: table name */
{
ulint error;
trx_t* trx;
@@ -2186,16 +2182,15 @@ row_drop_table_for_mysql_in_background(
return((int) error);
}
-/*************************************************************************
+/*********************************************************************//**
The master thread in srv0srv.c calls this regularly to drop tables which
we must drop in background after queries to them have ended. Such lazy
-dropping of tables is needed in ALTER TABLE on Unix. */
+dropping of tables is needed in ALTER TABLE on Unix.
+@return how many tables dropped + remaining tables in list */
UNIV_INTERN
ulint
row_drop_tables_for_mysql_in_background(void)
/*=========================================*/
- /* out: how many tables dropped
- + remaining tables in list */
{
row_mysql_drop_t* drop;
dict_table_t* table;
@@ -2262,14 +2257,14 @@ already_dropped:
goto loop;
}
-/*************************************************************************
+/*********************************************************************//**
Get the background drop list length. NOTE: the caller must own the kernel
-mutex! */
+mutex!
+@return how many tables in list */
UNIV_INTERN
ulint
row_get_background_drop_list_len_low(void)
/*======================================*/
- /* out: how many tables in list */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -2282,19 +2277,18 @@ row_get_background_drop_list_len_low(void)
return(UT_LIST_GET_LEN(row_mysql_drop_list));
}
-/*************************************************************************
+/*********************************************************************//**
If a table is not yet in the drop list, adds the table to the list of tables
which the master thread drops in background. We need this on Unix because in
ALTER TABLE MySQL may call drop table even if the table has running queries on
it. Also, if there are running foreign key checks on the table, we drop the
-table lazily. */
+table lazily.
+@return TRUE if the table was not yet in the drop list, and was added there */
static
ibool
row_add_table_to_background_drop_list(
/*==================================*/
- /* out: TRUE if the table was not yet in the
- drop list, and was added there */
- const char* name) /* in: table name */
+ const char* name) /*!< in: table name */
{
row_mysql_drop_t* drop;
@@ -2336,17 +2330,17 @@ row_add_table_to_background_drop_list(
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
Discards the tablespace of a table which stored in an .ibd file. Discarding
means that this function deletes the .ibd file and assigns a new table id for
-the table. Also the flag table->ibd_file_missing is set TRUE. */
+the table. Also the flag table->ibd_file_missing is set TRUE.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_discard_tablespace_for_mysql(
/*=============================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: table name */
- trx_t* trx) /* in: transaction handle */
+ const char* name, /*!< in: table name */
+ trx_t* trx) /*!< in: transaction handle */
{
dict_foreign_t* foreign;
dulint new_id;
@@ -2528,16 +2522,16 @@ funct_exit:
return((int) err);
}
-/*********************************************************************
+/*****************************************************************//**
Imports a tablespace. The space id in the .ibd file must match the space id
-of the table in the data dictionary. */
+of the table in the data dictionary.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_import_tablespace_for_mysql(
/*============================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: table name */
- trx_t* trx) /* in: transaction handle */
+ const char* name, /*!< in: table name */
+ trx_t* trx) /*!< in: transaction handle */
{
dict_table_t* table;
ibool success;
@@ -2666,15 +2660,15 @@ funct_exit:
return((int) err);
}
-/*************************************************************************
-Truncates a table for MySQL. */
+/*********************************************************************//**
+Truncates a table for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_truncate_table_for_mysql(
/*=========================*/
- /* out: error code or DB_SUCCESS */
- dict_table_t* table, /* in: table handle */
- trx_t* trx) /* in: transaction handle */
+ dict_table_t* table, /*!< in: table handle */
+ trx_t* trx) /*!< in: transaction handle */
{
dict_foreign_t* foreign;
ulint err;
@@ -2992,21 +2986,21 @@ funct_exit:
return((int) err);
}
-/*************************************************************************
+/*********************************************************************//**
Drops a table for MySQL. If the name of the dropped table ends in
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
"innodb_table_monitor", then this will also stop the printing of monitor
output by the master thread. If the data dictionary was not already locked
by the transaction, the transaction will be committed. Otherwise, the
-data dictionary will remain locked. */
+data dictionary will remain locked.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_drop_table_for_mysql(
/*=====================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: table name */
- trx_t* trx, /* in: transaction handle */
- ibool drop_db)/* in: TRUE=dropping whole database */
+ const char* name, /*!< in: table name */
+ trx_t* trx, /*!< in: transaction handle */
+ ibool drop_db)/*!< in: TRUE=dropping whole database */
{
dict_foreign_t* foreign;
dict_table_t* table;
@@ -3101,8 +3095,7 @@ row_drop_table_for_mysql(
"InnoDB: MySQL database directory"
" from another database?\n"
"InnoDB: You can look for further help from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n",
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n",
stderr);
goto funct_exit;
}
@@ -3382,23 +3375,21 @@ funct_exit:
trx->op_info = "";
-#ifndef UNIV_HOTBACKUP
srv_wake_master_thread();
-#endif /* !UNIV_HOTBACKUP */
return((int) err);
}
-/***********************************************************************
+/*******************************************************************//**
Drop all foreign keys in a database, see Bug#18942.
-Called at the end of row_drop_database_for_mysql(). */
+Called at the end of row_drop_database_for_mysql().
+@return error code or DB_SUCCESS */
static
ulint
drop_all_foreign_keys_in_db(
/*========================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: database name which ends to '/' */
- trx_t* trx) /* in: transaction handle */
+ const char* name, /*!< in: database name which ends to '/' */
+ trx_t* trx) /*!< in: transaction handle */
{
pars_info_t* pinfo;
ulint err;
@@ -3409,7 +3400,7 @@ drop_all_foreign_keys_in_db(
pars_info_add_str_literal(pinfo, "dbname", name);
-/* true if for_name is not prefixed with dbname */
+/** true if for_name is not prefixed with dbname */
#define TABLE_NOT_IN_THIS_DB \
"SUBSTR(for_name, 0, LENGTH(:dbname)) <> :dbname"
@@ -3449,15 +3440,15 @@ drop_all_foreign_keys_in_db(
return(err);
}
-/*************************************************************************
-Drops a database for MySQL. */
+/*********************************************************************//**
+Drops a database for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
row_drop_database_for_mysql(
/*========================*/
- /* out: error code or DB_SUCCESS */
- const char* name, /* in: database name which ends to '/' */
- trx_t* trx) /* in: transaction handle */
+ const char* name, /*!< in: database name which ends to '/' */
+ trx_t* trx) /*!< in: transaction handle */
{
dict_table_t* table;
char* table_name;
@@ -3543,30 +3534,30 @@ loop:
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if a table name contains the string "/#sql" which denotes temporary
-tables in MySQL. */
+tables in MySQL.
+@return TRUE if temporary table */
static
ibool
row_is_mysql_tmp_table_name(
/*========================*/
- /* out: TRUE if temporary table */
- const char* name) /* in: table name in the form
+ const char* name) /*!< in: table name in the form
'database/tablename' */
{
return(strstr(name, "/#sql") != NULL);
/* return(strstr(name, "/@0023sql") != NULL); */
}
-/********************************************************************
-Delete a single constraint. */
+/****************************************************************//**
+Delete a single constraint.
+@return error code or DB_SUCCESS */
static
int
row_delete_constraint_low(
/*======================*/
- /* out: error code or DB_SUCCESS */
- const char* id, /* in: constraint id */
- trx_t* trx) /* in: transaction handle */
+ const char* id, /*!< in: constraint id */
+ trx_t* trx) /*!< in: transaction handle */
{
pars_info_t* info = pars_info_create();
@@ -3581,18 +3572,18 @@ row_delete_constraint_low(
, FALSE, trx));
}
-/********************************************************************
-Delete a single constraint. */
+/****************************************************************//**
+Delete a single constraint.
+@return error code or DB_SUCCESS */
static
int
row_delete_constraint(
/*==================*/
- /* out: error code or DB_SUCCESS */
- const char* id, /* in: constraint id */
- const char* database_name, /* in: database name, with the
+ const char* id, /*!< in: constraint id */
+ const char* database_name, /*!< in: database name, with the
trailing '/' */
- mem_heap_t* heap, /* in: memory heap */
- trx_t* trx) /* in: transaction handle */
+ mem_heap_t* heap, /*!< in: memory heap */
+ trx_t* trx) /*!< in: transaction handle */
{
ulint err;
@@ -3614,17 +3605,17 @@ row_delete_constraint(
return((int) err);
}
-/*************************************************************************
-Renames a table for MySQL. */
+/*********************************************************************//**
+Renames a table for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
ulint
row_rename_table_for_mysql(
/*=======================*/
- /* out: error code or DB_SUCCESS */
- const char* old_name, /* in: old table name */
- const char* new_name, /* in: new table name */
- trx_t* trx, /* in: transaction handle */
- ibool commit) /* in: if TRUE then commit trx */
+ const char* old_name, /*!< in: old table name */
+ const char* new_name, /*!< in: new table name */
+ trx_t* trx, /*!< in: transaction handle */
+ ibool commit) /*!< in: if TRUE then commit trx */
{
dict_table_t* table;
ulint err = DB_ERROR;
@@ -3682,8 +3673,7 @@ row_rename_table_for_mysql(
"InnoDB: MySQL database directory"
" from another database?\n"
"InnoDB: You can look for further help from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n",
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n",
stderr);
goto funct_exit;
} else if (table->ibd_file_missing) {
@@ -3695,8 +3685,7 @@ row_rename_table_for_mysql(
fputs(" does not have an .ibd file"
" in the database directory.\n"
"InnoDB: You can look for further help from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n",
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n",
stderr);
goto funct_exit;
} else if (new_is_tmp) {
@@ -3848,8 +3837,7 @@ end:
"InnoDB: Have you deleted the .frm file"
" and not used DROP TABLE?\n"
"InnoDB: You can look for further help from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
"InnoDB: If table ", stderr);
ut_print_name(stderr, trx, TRUE, new_name);
fputs(" is a temporary table #sql..., then"
@@ -3938,18 +3926,18 @@ funct_exit:
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Checks that the index contains entries in an ascending order, unique
constraint is not broken, and calculates the number of index entries
-in the read view of the current transaction. */
+in the read view of the current transaction.
+@return TRUE if ok */
static
ibool
row_scan_and_check_index(
/*=====================*/
- /* out: TRUE if ok */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL */
- dict_index_t* index, /* in: index */
- ulint* n_rows) /* out: number of entries seen in the
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL */
+ dict_index_t* index, /*!< in: index */
+ ulint* n_rows) /*!< out: number of entries seen in the
current consistent read */
{
dtuple_t* prev_entry = NULL;
@@ -3971,6 +3959,14 @@ row_scan_and_check_index(
*n_rows = 0;
+ if (!row_merge_is_index_usable(prebuilt->trx, index)) {
+ /* A newly created index may lack some delete-marked
+ records that may exist in the read view of
+ prebuilt->trx. Thus, such indexes must not be
+ accessed by consistent read. */
+ return(is_ok);
+ }
+
buf = mem_alloc(UNIV_PAGE_SIZE);
heap = mem_heap_create(100);
@@ -3978,6 +3974,8 @@ row_scan_and_check_index(
in scanning the index entries */
prebuilt->index = index;
+ /* row_merge_is_index_usable() was already checked above. */
+ prebuilt->index_usable = TRUE;
prebuilt->sql_stat_start = TRUE;
prebuilt->template_type = ROW_MYSQL_DUMMY_TEMPLATE;
prebuilt->n_template = 0;
@@ -3997,7 +3995,17 @@ loop:
}
cnt = 1000;
}
- if (ret != DB_SUCCESS) {
+
+ switch (ret) {
+ case DB_SUCCESS:
+ break;
+ default:
+ ut_print_timestamp(stderr);
+ fputs(" InnoDB: Warning: CHECK TABLE on ", stderr);
+ dict_index_name_print(stderr, prebuilt->trx, index);
+ fprintf(stderr, " returned %lu\n", ret);
+ /* fall through (this error is ignored by CHECK TABLE) */
+ case DB_END_OF_INDEX:
func_exit:
mem_free(buf);
mem_heap_free(heap);
@@ -4093,14 +4101,14 @@ not_ok:
goto loop;
}
-/*************************************************************************
-Checks a table for corruption. */
+/*********************************************************************//**
+Checks a table for corruption.
+@return DB_ERROR or DB_SUCCESS */
UNIV_INTERN
ulint
row_check_table_for_mysql(
/*======================*/
- /* out: DB_ERROR or DB_SUCCESS */
- row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
handle */
{
dict_table_t* table = prebuilt->table;
@@ -4121,8 +4129,7 @@ row_check_table_for_mysql(
"InnoDB: the MySQL datadir, or have you"
" used DISCARD TABLESPACE?\n"
"InnoDB: Look from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
"InnoDB: how you can resolve the problem.\n",
table->name);
return(DB_ERROR);
@@ -4205,16 +4212,15 @@ row_check_table_for_mysql(
return(ret);
}
-#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
-Determines if a table is a magic monitor table. */
+/*********************************************************************//**
+Determines if a table is a magic monitor table.
+@return TRUE if monitor table */
UNIV_INTERN
ibool
row_is_magic_monitor_table(
/*=======================*/
- /* out: TRUE if monitor table */
- const char* table_name) /* in: name of the table, in the
+ const char* table_name) /*!< in: name of the table, in the
form database/table_name */
{
const char* name; /* table_name without database/ */
diff --git a/storage/xtradb/row/row0purge.c b/storage/xtradb/row/row0purge.c
index 8c3f9b993ba..500ebe571ab 100644
--- a/storage/xtradb/row/row0purge.c
+++ b/storage/xtradb/row/row0purge.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0purge.c
Purge obsolete records
Created 3/14/1997 Heikki Tuuri
@@ -43,15 +44,15 @@ Created 3/14/1997 Heikki Tuuri
#include "row0mysql.h"
#include "log0log.h"
-/************************************************************************
-Creates a purge node to a query graph. */
+/********************************************************************//**
+Creates a purge node to a query graph.
+@return own: purge node */
UNIV_INTERN
purge_node_t*
row_purge_node_create(
/*==================*/
- /* out, own: purge node */
- que_thr_t* parent, /* in: parent node, i.e., a thr node */
- mem_heap_t* heap) /* in: memory heap where created */
+ que_thr_t* parent, /*!< in: parent node, i.e., a thr node */
+ mem_heap_t* heap) /*!< in: memory heap where created */
{
purge_node_t* node;
@@ -67,17 +68,17 @@ row_purge_node_create(
return(node);
}
-/***************************************************************
+/***********************************************************//**
Repositions the pcur in the purge node on the clustered index record,
-if found. */
+if found.
+@return TRUE if the record was found */
static
ibool
row_purge_reposition_pcur(
/*======================*/
- /* out: TRUE if the record was found */
- ulint mode, /* in: latching mode */
- purge_node_t* node, /* in: row purge node */
- mtr_t* mtr) /* in: mtr */
+ ulint mode, /*!< in: latching mode */
+ purge_node_t* node, /*!< in: row purge node */
+ mtr_t* mtr) /*!< in: mtr */
{
ibool found;
@@ -98,16 +99,16 @@ row_purge_reposition_pcur(
return(found);
}
-/***************************************************************
-Removes a delete marked clustered index record if possible. */
+/***********************************************************//**
+Removes a delete marked clustered index record if possible.
+@return TRUE if success, or if not found, or if modified after the
+delete marking */
static
ibool
row_purge_remove_clust_if_poss_low(
/*===============================*/
- /* out: TRUE if success, or if not found, or
- if modified after the delete marking */
- purge_node_t* node, /* in: row purge node */
- ulint mode) /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
+ purge_node_t* node, /*!< in: row purge node */
+ ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
{
dict_index_t* index;
btr_pcur_t* pcur;
@@ -177,14 +178,14 @@ row_purge_remove_clust_if_poss_low(
return(success);
}
-/***************************************************************
+/***********************************************************//**
Removes a clustered index record if it has not been modified after the delete
marking. */
static
void
row_purge_remove_clust_if_poss(
/*===========================*/
- purge_node_t* node) /* in: row purge node */
+ purge_node_t* node) /*!< in: row purge node */
{
ibool success;
ulint n_tries = 0;
@@ -213,17 +214,17 @@ retry:
ut_a(success);
}
-/***************************************************************
-Removes a secondary index entry if possible. */
+/***********************************************************//**
+Removes a secondary index entry if possible.
+@return TRUE if success or if not found */
static
ibool
row_purge_remove_sec_if_poss_low(
/*=============================*/
- /* out: TRUE if success or if not found */
- purge_node_t* node, /* in: row purge node */
- dict_index_t* index, /* in: index */
- const dtuple_t* entry, /* in: index entry */
- ulint mode) /* in: latch mode BTR_MODIFY_LEAF or
+ purge_node_t* node, /*!< in: row purge node */
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* entry, /*!< in: index entry */
+ ulint mode) /*!< in: latch mode BTR_MODIFY_LEAF or
BTR_MODIFY_TREE */
{
btr_pcur_t pcur;
@@ -298,15 +299,15 @@ row_purge_remove_sec_if_poss_low(
return(success);
}
-/***************************************************************
+/***********************************************************//**
Removes a secondary index entry if possible. */
UNIV_INLINE
void
row_purge_remove_sec_if_poss(
/*=========================*/
- purge_node_t* node, /* in: row purge node */
- dict_index_t* index, /* in: index */
- dtuple_t* entry) /* in: index entry */
+ purge_node_t* node, /*!< in: row purge node */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry) /*!< in: index entry */
{
ibool success;
ulint n_tries = 0;
@@ -338,13 +339,13 @@ retry:
ut_a(success);
}
-/***************************************************************
+/***********************************************************//**
Purges a delete marking of a record. */
static
void
row_purge_del_mark(
/*===============*/
- purge_node_t* node) /* in: row purge node */
+ purge_node_t* node) /*!< in: row purge node */
{
mem_heap_t* heap;
dtuple_t* entry;
@@ -370,14 +371,14 @@ row_purge_del_mark(
row_purge_remove_clust_if_poss(node);
}
-/***************************************************************
+/***********************************************************//**
Purges an update of an existing record. Also purges an update of a delete
marked record if that record contained an externally stored field. */
static
void
row_purge_upd_exist_or_extern(
/*==========================*/
- purge_node_t* node) /* in: row purge node */
+ purge_node_t* node) /*!< in: row purge node */
{
mem_heap_t* heap;
dtuple_t* entry;
@@ -484,28 +485,27 @@ skip_secondaries:
}
}
-/***************************************************************
-Parses the row reference and other info in a modify undo log record. */
+/***********************************************************//**
+Parses the row reference and other info in a modify undo log record.
+@return TRUE if purge operation required: NOTE that then the CALLER
+must unfreeze data dictionary! */
static
ibool
row_purge_parse_undo_rec(
/*=====================*/
- /* out: TRUE if purge operation required:
- NOTE that then the CALLER must unfreeze
- data dictionary! */
- purge_node_t* node, /* in: row undo node */
+ purge_node_t* node, /*!< in: row undo node */
ibool* updated_extern,
- /* out: TRUE if an externally stored field
+ /*!< out: TRUE if an externally stored field
was updated */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
dict_index_t* clust_index;
byte* ptr;
trx_t* trx;
- dulint undo_no;
+ undo_no_t undo_no;
dulint table_id;
- dulint trx_id;
- dulint roll_ptr;
+ trx_id_t trx_id;
+ roll_ptr_t roll_ptr;
ulint info_bits;
ulint type;
ulint cmpl_info;
@@ -588,23 +588,22 @@ err_exit:
return(TRUE);
}
-/***************************************************************
+/***********************************************************//**
Fetches an undo log record and does the purge for the recorded operation.
If none left, or the current purge completed, returns the control to the
-parent node, which is always a query thread node. */
+parent node, which is always a query thread node.
+@return DB_SUCCESS if operation successfully completed, else error code */
static
ulint
row_purge(
/*======*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code */
- purge_node_t* node, /* in: row purge node */
- que_thr_t* thr) /* in: query thread */
+ purge_node_t* node, /*!< in: row purge node */
+ que_thr_t* thr) /*!< in: query thread */
{
- dulint roll_ptr;
- ibool purge_needed;
- ibool updated_extern;
- trx_t* trx;
+ roll_ptr_t roll_ptr;
+ ibool purge_needed;
+ ibool updated_extern;
+ trx_t* trx;
ut_ad(node && thr);
@@ -663,15 +662,15 @@ row_purge(
return(DB_SUCCESS);
}
-/***************************************************************
+/***********************************************************//**
Does the purge operation for a single undo log record. This is a high-level
-function used in an SQL execution graph. */
+function used in an SQL execution graph.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_purge_step(
/*===========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
purge_node_t* node;
ulint err;
diff --git a/storage/xtradb/row/row0row.c b/storage/xtradb/row/row0row.c
index 4343ee2b009..128ac3ba3e8 100644
--- a/storage/xtradb/row/row0row.c
+++ b/storage/xtradb/row/row0row.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0row.c
General row routines
Created 4/20/1996 Heikki Tuuri
@@ -46,18 +47,18 @@ Created 4/20/1996 Heikki Tuuri
#include "read0read.h"
#include "ut0mem.h"
-/*************************************************************************
+/*********************************************************************//**
Gets the offset of trx id field, in bytes relative to the origin of
-a clustered index record. */
+a clustered index record.
+@return offset of DATA_TRX_ID */
UNIV_INTERN
ulint
row_get_trx_id_offset(
/*==================*/
- /* out: offset of DATA_TRX_ID */
const rec_t* rec __attribute__((unused)),
- /* in: record */
- dict_index_t* index, /* in: clustered index */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ /*!< in: record */
+ dict_index_t* index, /*!< in: clustered index */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
ulint pos;
ulint offset;
@@ -75,24 +76,22 @@ row_get_trx_id_offset(
return(offset);
}
-/*********************************************************************
+/*****************************************************************//**
When an insert or purge to a table is performed, this function builds
-the entry to be inserted into or purged from an index on the table. */
+the entry to be inserted into or purged from an index on the table.
+@return index entry which should be inserted or purged, or NULL if the
+externally stored columns in the clustered index record are
+unavailable and ext != NULL */
UNIV_INTERN
dtuple_t*
row_build_index_entry(
/*==================*/
- /* out: index entry which should be
- inserted or purged, or NULL if the
- externally stored columns in the
- clustered index record are unavailable
- and ext != NULL */
- const dtuple_t* row, /* in: row which should be
+ const dtuple_t* row, /*!< in: row which should be
inserted or purged */
- row_ext_t* ext, /* in: externally stored column prefixes,
+ row_ext_t* ext, /*!< in: externally stored column prefixes,
or NULL */
- dict_index_t* index, /* in: index on the table */
- mem_heap_t* heap) /* in: memory heap from which the memory for
+ dict_index_t* index, /*!< in: index on the table */
+ mem_heap_t* heap) /*!< in: memory heap from which the memory for
the index entry is allocated */
{
dtuple_t* entry;
@@ -167,24 +166,23 @@ row_build_index_entry(
return(entry);
}
-/***********************************************************************
+/*******************************************************************//**
An inverse function to row_build_index_entry. Builds a row from a
-record in a clustered index. */
+record in a clustered index.
+@return own: row built; see the NOTE below! */
UNIV_INTERN
dtuple_t*
row_build(
/*======*/
- /* out, own: row built;
- see the NOTE below! */
- ulint type, /* in: ROW_COPY_POINTERS or
+ ulint type, /*!< in: ROW_COPY_POINTERS or
ROW_COPY_DATA; the latter
copies also the data fields to
heap while the first only
places pointers to data fields
on the index page, and thus is
more efficient */
- const dict_index_t* index, /* in: clustered index */
- const rec_t* rec, /* in: record in the clustered
+ const dict_index_t* index, /*!< in: clustered index */
+ const rec_t* rec, /*!< in: record in the clustered
index; NOTE: in the case
ROW_COPY_POINTERS the data
fields in the row will point
@@ -193,20 +191,20 @@ row_build(
this record must be at least
s-latched and the latch held
as long as the row dtuple is used! */
- const ulint* offsets,/* in: rec_get_offsets(rec,index)
+ const ulint* offsets,/*!< in: rec_get_offsets(rec,index)
or NULL, in which case this function
will invoke rec_get_offsets() */
const dict_table_t* col_table,
- /* in: table, to check which
+ /*!< in: table, to check which
externally stored columns
occur in the ordering columns
of an index, or NULL if
index->table should be
consulted instead */
- row_ext_t** ext, /* out, own: cache of
+ row_ext_t** ext, /*!< out, own: cache of
externally stored column
prefixes, or NULL */
- mem_heap_t* heap) /* in: memory heap from which
+ mem_heap_t* heap) /*!< in: memory heap from which
the memory needed is allocated */
{
dtuple_t* row;
@@ -311,21 +309,20 @@ row_build(
return(row);
}
-/***********************************************************************
-Converts an index record to a typed data tuple. */
+/*******************************************************************//**
+Converts an index record to a typed data tuple.
+@return index entry built; does not set info_bits, and the data fields
+in the entry will point directly to rec */
UNIV_INTERN
dtuple_t*
row_rec_to_index_entry_low(
/*=======================*/
- /* out: index entry built; does not
- set info_bits, and the data fields in
- the entry will point directly to rec */
- const rec_t* rec, /* in: record in the index */
- const dict_index_t* index, /* in: index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- ulint* n_ext, /* out: number of externally
+ const rec_t* rec, /*!< in: record in the index */
+ const dict_index_t* index, /*!< in: index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ ulint* n_ext, /*!< out: number of externally
stored columns */
- mem_heap_t* heap) /* in: memory heap from which
+ mem_heap_t* heap) /*!< in: memory heap from which
the memory needed is allocated */
{
dtuple_t* entry;
@@ -370,22 +367,21 @@ row_rec_to_index_entry_low(
return(entry);
}
-/***********************************************************************
+/*******************************************************************//**
Converts an index record to a typed data tuple. NOTE that externally
-stored (often big) fields are NOT copied to heap. */
+stored (often big) fields are NOT copied to heap.
+@return own: index entry built; see the NOTE below! */
UNIV_INTERN
dtuple_t*
row_rec_to_index_entry(
/*===================*/
- /* out, own: index entry
- built; see the NOTE below! */
- ulint type, /* in: ROW_COPY_DATA, or
+ ulint type, /*!< in: ROW_COPY_DATA, or
ROW_COPY_POINTERS: the former
copies also the data fields to
heap as the latter only places
pointers to data fields on the
index page */
- const rec_t* rec, /* in: record in the index;
+ const rec_t* rec, /*!< in: record in the index;
NOTE: in the case
ROW_COPY_POINTERS the data
fields in the row will point
@@ -394,11 +390,11 @@ row_rec_to_index_entry(
this record must be at least
s-latched and the latch held
as long as the dtuple is used! */
- const dict_index_t* index, /* in: index */
- ulint* offsets,/* in/out: rec_get_offsets(rec) */
- ulint* n_ext, /* out: number of externally
+ const dict_index_t* index, /*!< in: index */
+ ulint* offsets,/*!< in/out: rec_get_offsets(rec) */
+ ulint* n_ext, /*!< out: number of externally
stored columns */
- mem_heap_t* heap) /* in: memory heap from which
+ mem_heap_t* heap) /*!< in: memory heap from which
the memory needed is allocated */
{
dtuple_t* entry;
@@ -423,28 +419,27 @@ row_rec_to_index_entry(
return(entry);
}
-/***********************************************************************
+/*******************************************************************//**
Builds from a secondary index record a row reference with which we can
-search the clustered index record. */
+search the clustered index record.
+@return own: row reference built; see the NOTE below! */
UNIV_INTERN
dtuple_t*
row_build_row_ref(
/*==============*/
- /* out, own: row reference built; see the
- NOTE below! */
- ulint type, /* in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
+ ulint type, /*!< in: ROW_COPY_DATA, or ROW_COPY_POINTERS:
the former copies also the data fields to
heap, whereas the latter only places pointers
to data fields on the index page */
- dict_index_t* index, /* in: secondary index */
- const rec_t* rec, /* in: record in the index;
+ dict_index_t* index, /*!< in: secondary index */
+ const rec_t* rec, /*!< in: record in the index;
NOTE: in the case ROW_COPY_POINTERS
the data fields in the row will point
directly into this record, therefore,
the buffer page of this record must be
at least s-latched and the latch held
as long as the row reference is used! */
- mem_heap_t* heap) /* in: memory heap from which the memory
+ mem_heap_t* heap) /*!< in: memory heap from which the memory
needed is allocated */
{
dict_table_t* table;
@@ -535,16 +530,16 @@ row_build_row_ref(
return(ref);
}
-/***********************************************************************
+/*******************************************************************//**
Builds from a secondary index record a row reference with which we can
search the clustered index record. */
UNIV_INTERN
void
row_build_row_ref_in_tuple(
/*=======================*/
- dtuple_t* ref, /* in/out: row reference built;
+ dtuple_t* ref, /*!< in/out: row reference built;
see the NOTE below! */
- const rec_t* rec, /* in: record in the index;
+ const rec_t* rec, /*!< in: record in the index;
NOTE: the data fields in ref
will point directly into this
record, therefore, the buffer
@@ -552,10 +547,10 @@ row_build_row_ref_in_tuple(
least s-latched and the latch
held as long as the row
reference is used! */
- const dict_index_t* index, /* in: secondary index */
- ulint* offsets,/* in: rec_get_offsets(rec, index)
+ const dict_index_t* index, /*!< in: secondary index */
+ ulint* offsets,/*!< in: rec_get_offsets(rec, index)
or NULL */
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
const dict_index_t* clust_index;
dfield_t* dfield;
@@ -648,80 +643,19 @@ notfound:
}
}
-/***********************************************************************
-From a row build a row reference with which we can search the clustered
-index record. */
-UNIV_INTERN
-void
-row_build_row_ref_from_row(
-/*=======================*/
- dtuple_t* ref, /* in/out: row reference built;
- see the NOTE below!
- ref must have the right number
- of fields! */
- const dict_table_t* table, /* in: table */
- const dtuple_t* row) /* in: row
- NOTE: the data fields in ref will point
- directly into data of this row */
-{
- const dict_index_t* clust_index;
- ulint ref_len;
- ulint i;
-
- ut_ad(ref && table && row);
-
- clust_index = dict_table_get_first_index(table);
-
- ref_len = dict_index_get_n_unique(clust_index);
-
- ut_ad(ref_len == dtuple_get_n_fields(ref));
-
- for (i = 0; i < ref_len; i++) {
- const dict_col_t* col;
- const dict_field_t* field;
- dfield_t* dfield;
- const dfield_t* dfield2;
-
- dfield = dtuple_get_nth_field(ref, i);
-
- field = dict_index_get_nth_field(clust_index, i);
-
- col = dict_field_get_col(field);
-
- dfield2 = dtuple_get_nth_field(row, dict_col_get_no(col));
-
- dfield_copy(dfield, dfield2);
- ut_ad(!dfield_is_ext(dfield));
-
- if (field->prefix_len > 0 && !dfield_is_null(dfield)) {
-
- ulint len = dfield_get_len(dfield);
-
- len = dtype_get_at_most_n_mbchars(
- col->prtype, col->mbminlen, col->mbmaxlen,
- field->prefix_len,
- len, dfield_get_data(dfield));
-
- dfield_set_len(dfield, len);
- }
- }
-
- ut_ad(dtuple_check_typed(ref));
-}
-
-/*******************************************************************
-Searches the clustered index record for a row, if we have the row reference. */
+/***************************************************************//**
+Searches the clustered index record for a row, if we have the row reference.
+@return TRUE if found */
UNIV_INTERN
ibool
row_search_on_row_ref(
/*==================*/
- /* out: TRUE if found */
- btr_pcur_t* pcur, /* out: persistent cursor, which must
+ btr_pcur_t* pcur, /*!< out: persistent cursor, which must
be closed by the caller */
- ulint mode, /* in: BTR_MODIFY_LEAF, ... */
- const dict_table_t* table, /* in: table */
- const dtuple_t* ref, /* in: row reference */
- mtr_t* mtr) /* in/out: mtr */
+ ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */
+ const dict_table_t* table, /*!< in: table */
+ const dtuple_t* ref, /*!< in: row reference */
+ mtr_t* mtr) /*!< in/out: mtr */
{
ulint low_match;
rec_t* rec;
@@ -752,19 +686,19 @@ row_search_on_row_ref(
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
Fetches the clustered index record for a secondary index record. The latches
-on the secondary index record are preserved. */
+on the secondary index record are preserved.
+@return record or NULL, if no record found */
UNIV_INTERN
rec_t*
row_get_clust_rec(
/*==============*/
- /* out: record or NULL, if no record found */
- ulint mode, /* in: BTR_MODIFY_LEAF, ... */
- const rec_t* rec, /* in: record in a secondary index */
- dict_index_t* index, /* in: secondary index */
- dict_index_t** clust_index,/* out: clustered index */
- mtr_t* mtr) /* in: mtr */
+ ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */
+ const rec_t* rec, /*!< in: record in a secondary index */
+ dict_index_t* index, /*!< in: secondary index */
+ dict_index_t** clust_index,/*!< out: clustered index */
+ mtr_t* mtr) /*!< in: mtr */
{
mem_heap_t* heap;
dtuple_t* ref;
@@ -794,19 +728,19 @@ row_get_clust_rec(
return(clust_rec);
}
-/*******************************************************************
-Searches an index record. */
+/***************************************************************//**
+Searches an index record.
+@return TRUE if found */
UNIV_INTERN
ibool
row_search_index_entry(
/*===================*/
- /* out: TRUE if found */
- dict_index_t* index, /* in: index */
- const dtuple_t* entry, /* in: index entry */
- ulint mode, /* in: BTR_MODIFY_LEAF, ... */
- btr_pcur_t* pcur, /* in/out: persistent cursor, which must
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* entry, /*!< in: index entry */
+ ulint mode, /*!< in: BTR_MODIFY_LEAF, ... */
+ btr_pcur_t* pcur, /*!< in/out: persistent cursor, which must
be closed by the caller */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint n_fields;
ulint low_match;
@@ -824,11 +758,9 @@ row_search_index_entry(
return(!page_rec_is_infimum(rec) && low_match == n_fields);
}
-#ifndef UNIV_HOTBACKUP
-
#include <my_sys.h>
-/***********************************************************************
+/*******************************************************************//**
Formats the raw data in "data" (in InnoDB on-disk format) that is of
type DATA_INT using "prtype" and writes the result to "buf".
If the data is in unknown format, then nothing is written to "buf",
@@ -837,21 +769,20 @@ If the data is in unknown format, then nothing is written to "buf",
Not more than "buf_size" bytes are written to "buf".
The result is always '\0'-terminated (provided buf_size > 0) and the
number of bytes that were written to "buf" is returned (including the
-terminating '\0'). */
+terminating '\0').
+@return number of bytes that were written */
static
ulint
row_raw_format_int(
/*===============*/
- /* out: number of bytes
- that were written */
- const char* data, /* in: raw data */
- ulint data_len, /* in: raw data length
+ const char* data, /*!< in: raw data */
+ ulint data_len, /*!< in: raw data length
in bytes */
- ulint prtype, /* in: precise type */
- char* buf, /* out: output buffer */
- ulint buf_size, /* in: output buffer size
+ ulint prtype, /*!< in: precise type */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size, /*!< in: output buffer size
in bytes */
- ibool* format_in_hex) /* out: should the data be
+ ibool* format_in_hex) /*!< out: should the data be
formated in hex */
{
ulint ret;
@@ -883,7 +814,7 @@ row_raw_format_int(
return(ut_min(ret, buf_size));
}
-/***********************************************************************
+/*******************************************************************//**
Formats the raw data in "data" (in InnoDB on-disk format) that is of
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "prtype" and writes the
result to "buf".
@@ -893,21 +824,20 @@ If the data is in binary format, then nothing is written to "buf",
Not more than "buf_size" bytes are written to "buf".
The result is always '\0'-terminated (provided buf_size > 0) and the
number of bytes that were written to "buf" is returned (including the
-terminating '\0'). */
+terminating '\0').
+@return number of bytes that were written */
static
ulint
row_raw_format_str(
/*===============*/
- /* out: number of bytes
- that were written */
- const char* data, /* in: raw data */
- ulint data_len, /* in: raw data length
+ const char* data, /*!< in: raw data */
+ ulint data_len, /*!< in: raw data length
in bytes */
- ulint prtype, /* in: precise type */
- char* buf, /* out: output buffer */
- ulint buf_size, /* in: output buffer size
+ ulint prtype, /*!< in: precise type */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size, /*!< in: output buffer size
in bytes */
- ibool* format_in_hex) /* out: should the data be
+ ibool* format_in_hex) /*!< out: should the data be
formated in hex */
{
ulint charset_coll;
@@ -938,25 +868,24 @@ row_raw_format_str(
buf, buf_size));
}
-/***********************************************************************
+/*******************************************************************//**
Formats the raw data in "data" (in InnoDB on-disk format) using
"dict_field" and writes the result to "buf".
Not more than "buf_size" bytes are written to "buf".
-The result is always '\0'-terminated (provided buf_size > 0) and the
+The result is always NUL-terminated (provided buf_size is positive) and the
number of bytes that were written to "buf" is returned (including the
-terminating '\0'). */
+terminating NUL).
+@return number of bytes that were written */
UNIV_INTERN
ulint
row_raw_format(
/*===========*/
- /* out: number of bytes
- that were written */
- const char* data, /* in: raw data */
- ulint data_len, /* in: raw data length
+ const char* data, /*!< in: raw data */
+ ulint data_len, /*!< in: raw data length
in bytes */
- const dict_field_t* dict_field, /* in: index field */
- char* buf, /* out: output buffer */
- ulint buf_size) /* in: output buffer size
+ const dict_field_t* dict_field, /*!< in: index field */
+ char* buf, /*!< out: output buffer */
+ ulint buf_size) /*!< in: output buffer size
in bytes */
{
ulint mtype;
@@ -1020,8 +949,6 @@ row_raw_format(
return(ret);
}
-#endif /* !UNIV_HOTBACKUP */
-
#ifdef UNIV_COMPILE_TEST_FUNCS
#include "ut0dbg.h"
diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c
index fb1523d3370..3ef9726588e 100644
--- a/storage/xtradb/row/row0sel.c
+++ b/storage/xtradb/row/row0sel.c
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/*******************************************************
+/***************************************************//**
+@file row/row0sel.c
Select
Created 12/19/1997 Heikki Tuuri
@@ -74,34 +75,33 @@ to que_run_threads: this is to allow canceling runaway queries */
#define SEL_EXHAUSTED 1
#define SEL_RETRY 2
-/************************************************************************
+/********************************************************************//**
Returns TRUE if the user-defined column in a secondary index record
is alphabetically the same as the corresponding BLOB column in the clustered
index record.
NOTE: the comparison is NOT done as a binary comparison, but character
-fields are compared with collation! */
+fields are compared with collation!
+@return TRUE if the columns are equal */
static
ibool
row_sel_sec_rec_is_for_blob(
/*========================*/
- /* out: TRUE if the columns
- are equal */
- ulint mtype, /* in: main type */
- ulint prtype, /* in: precise type */
- ulint mbminlen, /* in: minimum length of a
+ ulint mtype, /*!< in: main type */
+ ulint prtype, /*!< in: precise type */
+ ulint mbminlen, /*!< in: minimum length of a
multi-byte character */
- ulint mbmaxlen, /* in: maximum length of a
+ ulint mbmaxlen, /*!< in: maximum length of a
multi-byte character */
- const byte* clust_field, /* in: the locally stored part of
+ const byte* clust_field, /*!< in: the locally stored part of
the clustered index column, including
the BLOB pointer; the clustered
index record must be covered by
a lock or a page latch to protect it
against deletion (rollback or purge) */
- ulint clust_len, /* in: length of clust_field */
- const byte* sec_field, /* in: column in secondary index */
- ulint sec_len, /* in: length of sec_field */
- ulint zip_size) /* in: compressed page size, or 0 */
+ ulint clust_len, /*!< in: length of clust_field */
+ const byte* sec_field, /*!< in: column in secondary index */
+ ulint sec_len, /*!< in: length of sec_field */
+ ulint zip_size) /*!< in: compressed page size, or 0 */
{
ulint len;
byte buf[DICT_MAX_INDEX_COL_LEN];
@@ -125,27 +125,25 @@ row_sel_sec_rec_is_for_blob(
return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len));
}
-/************************************************************************
+/********************************************************************//**
Returns TRUE if the user-defined column values in a secondary index record
are alphabetically the same as the corresponding columns in the clustered
index record.
NOTE: the comparison is NOT done as a binary comparison, but character
-fields are compared with collation! */
+fields are compared with collation!
+@return TRUE if the secondary record is equal to the corresponding
+fields in the clustered record, when compared with collation */
static
ibool
row_sel_sec_rec_is_for_clust_rec(
/*=============================*/
- /* out: TRUE if the secondary
- record is equal to the corresponding
- fields in the clustered record,
- when compared with collation */
- const rec_t* sec_rec, /* in: secondary index record */
- dict_index_t* sec_index, /* in: secondary index */
- const rec_t* clust_rec, /* in: clustered index record;
+ const rec_t* sec_rec, /*!< in: secondary index record */
+ dict_index_t* sec_index, /*!< in: secondary index */
+ const rec_t* clust_rec, /*!< in: clustered index record;
must be protected by a lock or
a page latch against deletion
in rollback or purge */
- dict_index_t* clust_index) /* in: clustered index */
+ dict_index_t* clust_index) /*!< in: clustered index */
{
const byte* sec_field;
ulint sec_len;
@@ -238,14 +236,14 @@ func_exit:
return(is_equal);
}
-/*************************************************************************
-Creates a select node struct. */
+/*********************************************************************//**
+Creates a select node struct.
+@return own: select node struct */
UNIV_INTERN
sel_node_t*
sel_node_create(
/*============*/
- /* out, own: select node struct */
- mem_heap_t* heap) /* in: memory heap where created */
+ mem_heap_t* heap) /*!< in: memory heap where created */
{
sel_node_t* node;
@@ -258,14 +256,14 @@ sel_node_create(
return(node);
}
-/*************************************************************************
+/*********************************************************************//**
Frees the memory private to a select node when a query graph is freed,
does not free the heap where the node was originally created. */
UNIV_INTERN
void
sel_node_free_private(
/*==================*/
- sel_node_t* node) /* in: select node struct */
+ sel_node_t* node) /*!< in: select node struct */
{
ulint i;
plan_t* plan;
@@ -284,14 +282,14 @@ sel_node_free_private(
}
}
-/*************************************************************************
+/*********************************************************************//**
Evaluates the values in a select list. If there are aggregate functions,
their argument value is added to the aggregate total. */
UNIV_INLINE
void
sel_eval_select_list(
/*=================*/
- sel_node_t* node) /* in: select node */
+ sel_node_t* node) /*!< in: select node */
{
que_node_t* exp;
@@ -304,15 +302,15 @@ sel_eval_select_list(
}
}
-/*************************************************************************
+/*********************************************************************//**
Assigns the values in the select list to the possible into-variables in
SELECT ... INTO ... */
UNIV_INLINE
void
sel_assign_into_var_values(
/*=======================*/
- sym_node_t* var, /* in: first variable in a list of variables */
- sel_node_t* node) /* in: select node */
+ sym_node_t* var, /*!< in: first variable in a list of variables */
+ sel_node_t* node) /*!< in: select node */
{
que_node_t* exp;
@@ -333,14 +331,14 @@ sel_assign_into_var_values(
}
}
-/*************************************************************************
+/*********************************************************************//**
Resets the aggregate value totals in the select list of an aggregate type
query. */
UNIV_INLINE
void
sel_reset_aggregate_vals(
/*=====================*/
- sel_node_t* node) /* in: select node */
+ sel_node_t* node) /*!< in: select node */
{
func_node_t* func_node;
@@ -357,13 +355,13 @@ sel_reset_aggregate_vals(
node->aggregate_already_fetched = FALSE;
}
-/*************************************************************************
+/*********************************************************************//**
Copies the input variable values when an explicit cursor is opened. */
UNIV_INLINE
void
row_sel_copy_input_variable_vals(
/*=============================*/
- sel_node_t* node) /* in: select node */
+ sel_node_t* node) /*!< in: select node */
{
sym_node_t* var;
@@ -378,17 +376,17 @@ row_sel_copy_input_variable_vals(
}
}
-/*************************************************************************
+/*********************************************************************//**
Fetches the column values from a record. */
static
void
row_sel_fetch_columns(
/*==================*/
- dict_index_t* index, /* in: record index */
- const rec_t* rec, /* in: record in a clustered or non-clustered
+ dict_index_t* index, /*!< in: record index */
+ const rec_t* rec, /*!< in: record in a clustered or non-clustered
index; must be protected by a page latch */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- sym_node_t* column) /* in: first column in a column list, or
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ sym_node_t* column) /*!< in: first column in a column list, or
NULL */
{
dfield_t* val;
@@ -457,13 +455,13 @@ row_sel_fetch_columns(
}
}
-/*************************************************************************
+/*********************************************************************//**
Allocates a prefetch buffer for a column when prefetch is first time done. */
static
void
sel_col_prefetch_buf_alloc(
/*=======================*/
- sym_node_t* column) /* in: symbol table node for a column */
+ sym_node_t* column) /*!< in: symbol table node for a column */
{
sel_buf_t* sel_buf;
ulint i;
@@ -481,14 +479,14 @@ sel_col_prefetch_buf_alloc(
}
}
-/*************************************************************************
+/*********************************************************************//**
Frees a prefetch buffer for a column, including the dynamically allocated
memory for data stored there. */
UNIV_INTERN
void
sel_col_prefetch_buf_free(
/*======================*/
- sel_buf_t* prefetch_buf) /* in, own: prefetch buffer */
+ sel_buf_t* prefetch_buf) /*!< in, own: prefetch buffer */
{
sel_buf_t* sel_buf;
ulint i;
@@ -503,14 +501,14 @@ sel_col_prefetch_buf_free(
}
}
-/*************************************************************************
+/*********************************************************************//**
Pops the column values for a prefetched, cached row from the column prefetch
buffers and places them to the val fields in the column nodes. */
static
void
sel_pop_prefetched_row(
/*===================*/
- plan_t* plan) /* in: plan node for a table */
+ plan_t* plan) /*!< in: plan node for a table */
{
sym_node_t* column;
sel_buf_t* sel_buf;
@@ -565,14 +563,14 @@ next_col:
plan->first_prefetched++;
}
-/*************************************************************************
+/*********************************************************************//**
Pushes the column values for a prefetched, cached row to the column prefetch
buffers from the val fields in the column nodes. */
UNIV_INLINE
void
sel_push_prefetched_row(
/*====================*/
- plan_t* plan) /* in: plan node for a table */
+ plan_t* plan) /*!< in: plan node for a table */
{
sym_node_t* column;
sel_buf_t* sel_buf;
@@ -637,26 +635,26 @@ next_col:
}
}
-/*************************************************************************
-Builds a previous version of a clustered index record for a consistent read */
+/*********************************************************************//**
+Builds a previous version of a clustered index record for a consistent read
+@return DB_SUCCESS or error code */
static
ulint
row_sel_build_prev_vers(
/*====================*/
- /* out: DB_SUCCESS or error code */
- read_view_t* read_view, /* in: read view */
- dict_index_t* index, /* in: plan node for table */
- rec_t* rec, /* in: record in a clustered index */
- ulint** offsets, /* in/out: offsets returned by
+ read_view_t* read_view, /*!< in: read view */
+ dict_index_t* index, /*!< in: plan node for table */
+ rec_t* rec, /*!< in: record in a clustered index */
+ ulint** offsets, /*!< in/out: offsets returned by
rec_get_offsets(rec, plan->index) */
- mem_heap_t** offset_heap, /* in/out: memory heap from which
+ mem_heap_t** offset_heap, /*!< in/out: memory heap from which
the offsets are allocated */
- mem_heap_t** old_vers_heap, /* out: old version heap to use */
- rec_t** old_vers, /* out: old version, or NULL if the
+ mem_heap_t** old_vers_heap, /*!< out: old version heap to use */
+ rec_t** old_vers, /*!< out: old version, or NULL if the
record does not exist in the view:
i.e., it was freshly inserted
afterwards */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint err;
@@ -672,26 +670,26 @@ row_sel_build_prev_vers(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Builds the last committed version of a clustered index record for a
-semi-consistent read. */
+semi-consistent read.
+@return DB_SUCCESS or error code */
static
ulint
row_sel_build_committed_vers_for_mysql(
/*===================================*/
- /* out: DB_SUCCESS or error code */
- dict_index_t* clust_index, /* in: clustered index */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct */
- const rec_t* rec, /* in: record in a clustered index */
- ulint** offsets, /* in/out: offsets returned by
+ dict_index_t* clust_index, /*!< in: clustered index */
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
+ const rec_t* rec, /*!< in: record in a clustered index */
+ ulint** offsets, /*!< in/out: offsets returned by
rec_get_offsets(rec, clust_index) */
- mem_heap_t** offset_heap, /* in/out: memory heap from which
+ mem_heap_t** offset_heap, /*!< in/out: memory heap from which
the offsets are allocated */
- const rec_t** old_vers, /* out: old version, or NULL if the
+ const rec_t** old_vers, /*!< out: old version, or NULL if the
record does not exist in the view:
i.e., it was freshly inserted
afterwards */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint err;
@@ -707,15 +705,15 @@ row_sel_build_committed_vers_for_mysql(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Tests the conditions which determine when the index segment we are searching
-through has been exhausted. */
+through has been exhausted.
+@return TRUE if row passed the tests */
UNIV_INLINE
ibool
row_sel_test_end_conds(
/*===================*/
- /* out: TRUE if row passed the tests */
- plan_t* plan) /* in: plan for the table; the column values must
+ plan_t* plan) /*!< in: plan for the table; the column values must
already have been retrieved and the right sides of
comparisons evaluated */
{
@@ -745,14 +743,14 @@ row_sel_test_end_conds(
return(TRUE);
}
-/*************************************************************************
-Tests the other conditions. */
+/*********************************************************************//**
+Tests the other conditions.
+@return TRUE if row passed the tests */
UNIV_INLINE
ibool
row_sel_test_other_conds(
/*=====================*/
- /* out: TRUE if row passed the tests */
- plan_t* plan) /* in: plan for the table; the column values must
+ plan_t* plan) /*!< in: plan for the table; the column values must
already have been retrieved */
{
func_node_t* cond;
@@ -773,23 +771,23 @@ row_sel_test_other_conds(
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
Retrieves the clustered index record corresponding to a record in a
-non-clustered index. Does the necessary locking. */
+non-clustered index. Does the necessary locking.
+@return DB_SUCCESS or error code */
static
ulint
row_sel_get_clust_rec(
/*==================*/
- /* out: DB_SUCCESS or error code */
- sel_node_t* node, /* in: select_node */
- plan_t* plan, /* in: plan node for table */
- rec_t* rec, /* in: record in a non-clustered index */
- que_thr_t* thr, /* in: query thread */
- rec_t** out_rec,/* out: clustered record or an old version of
+ sel_node_t* node, /*!< in: select_node */
+ plan_t* plan, /*!< in: plan node for table */
+ rec_t* rec, /*!< in: record in a non-clustered index */
+ que_thr_t* thr, /*!< in: query thread */
+ rec_t** out_rec,/*!< out: clustered record or an old version of
it, NULL if the old version did not exist
in the read view, i.e., it was a fresh
inserted version */
- mtr_t* mtr) /* in: mtr used to get access to the
+ mtr_t* mtr) /*!< in: mtr used to get access to the
non-clustered record; the same mtr is used to
access the clustered index */
{
@@ -937,21 +935,21 @@ err_exit:
return(err);
}
-/*************************************************************************
-Sets a lock on a record. */
+/*********************************************************************//**
+Sets a lock on a record.
+@return DB_SUCCESS or error code */
UNIV_INLINE
ulint
sel_set_rec_lock(
/*=============*/
- /* out: DB_SUCCESS or error code */
- const buf_block_t* block, /* in: buffer block of rec */
- const rec_t* rec, /* in: record */
- dict_index_t* index, /* in: index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- ulint mode, /* in: lock mode */
- ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or
+ const buf_block_t* block, /*!< in: buffer block of rec */
+ const rec_t* rec, /*!< in: record */
+ dict_index_t* index, /*!< in: index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ ulint mode, /*!< in: lock mode */
+ ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
LOC_REC_NOT_GAP */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
trx_t* trx;
ulint err;
@@ -976,18 +974,18 @@ sel_set_rec_lock(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Opens a pcur to a table index. */
static
void
row_sel_open_pcur(
/*==============*/
- plan_t* plan, /* in: table plan */
+ plan_t* plan, /*!< in: table plan */
ibool search_latch_locked,
- /* in: TRUE if the thread currently
+ /*!< in: TRUE if the thread currently
has the search latch locked in
s-mode */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
func_node_t* cond;
@@ -1051,19 +1049,18 @@ row_sel_open_pcur(
plan->pcur_is_open = TRUE;
}
-/*************************************************************************
-Restores a stored pcur position to a table index. */
+/*********************************************************************//**
+Restores a stored pcur position to a table index.
+@return TRUE if the cursor should be moved to the next record after we
+return from this function (moved to the previous, in the case of a
+descending cursor) without processing again the current cursor
+record */
static
ibool
row_sel_restore_pcur_pos(
/*=====================*/
- /* out: TRUE if the cursor should be moved to
- the next record after we return from this
- function (moved to the previous, in the case
- of a descending cursor) without processing
- again the current cursor record */
- plan_t* plan, /* in: table plan */
- mtr_t* mtr) /* in: mtr */
+ plan_t* plan, /*!< in: table plan */
+ mtr_t* mtr) /*!< in: mtr */
{
ibool equal_position;
ulint relative_position;
@@ -1147,13 +1144,13 @@ row_sel_restore_pcur_pos(
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
Resets a plan cursor to a closed state. */
UNIV_INLINE
void
plan_reset_cursor(
/*==============*/
- plan_t* plan) /* in: plan */
+ plan_t* plan) /*!< in: plan */
{
plan->pcur_is_open = FALSE;
plan->cursor_at_end = FALSE;
@@ -1161,18 +1158,18 @@ plan_reset_cursor(
plan->n_rows_prefetched = 0;
}
-/*************************************************************************
+/*********************************************************************//**
Tries to do a shortcut to fetch a clustered index record with a unique key,
-using the hash index if possible (not always). */
+using the hash index if possible (not always).
+@return SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
static
ulint
row_sel_try_search_shortcut(
/*========================*/
- /* out: SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
- sel_node_t* node, /* in: select node for a consistent read */
- plan_t* plan, /* in: plan for a unique search in clustered
+ sel_node_t* node, /*!< in: select node for a consistent read */
+ plan_t* plan, /*!< in: plan for a unique search in clustered
index */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_index_t* index;
rec_t* rec;
@@ -1263,15 +1260,15 @@ func_exit:
return(ret);
}
-/*************************************************************************
-Performs a select step. */
+/*********************************************************************//**
+Performs a select step.
+@return DB_SUCCESS or error code */
static
ulint
row_sel(
/*====*/
- /* out: DB_SUCCESS or error code */
- sel_node_t* node, /* in: select node */
- que_thr_t* thr) /* in: query thread */
+ sel_node_t* node, /*!< in: select node */
+ que_thr_t* thr) /*!< in: query thread */
{
dict_index_t* index;
plan_t* plan;
@@ -1964,15 +1961,15 @@ func_exit:
return(err);
}
-/**************************************************************************
+/**********************************************************************//**
Performs a select step. This is a high-level function used in SQL execution
-graphs. */
+graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_sel_step(
/*=========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint i_lock_mode;
sym_node_t* table_node;
@@ -2066,14 +2063,14 @@ row_sel_step(
return(thr);
}
-/**************************************************************************
-Performs a fetch for a cursor. */
+/**********************************************************************//**
+Performs a fetch for a cursor.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
fetch_step(
/*=======*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
sel_node_t* sel_node;
fetch_node_t* node;
@@ -2129,15 +2126,15 @@ fetch_step(
return(thr);
}
-/********************************************************************
-Sample callback function for fetch that prints each row.*/
+/****************************************************************//**
+Sample callback function for fetch that prints each row.
+@return always returns non-NULL */
UNIV_INTERN
void*
row_fetch_print(
/*============*/
- /* out: always returns non-NULL */
- void* row, /* in: sel_node_t* */
- void* user_arg) /* in: not used */
+ void* row, /*!< in: sel_node_t* */
+ void* user_arg) /*!< in: not used */
{
sel_node_t* node = row;
que_node_t* exp;
@@ -2173,17 +2170,17 @@ row_fetch_print(
return((void*)42);
}
-/********************************************************************
+/****************************************************************//**
Callback function for fetch that stores an unsigned 4 byte integer to the
location pointed. The column's type must be DATA_INT, DATA_UNSIGNED, length
-= 4. */
+= 4.
+@return always returns NULL */
UNIV_INTERN
void*
row_fetch_store_uint4(
/*==================*/
- /* out: always returns NULL */
- void* row, /* in: sel_node_t* */
- void* user_arg) /* in: data pointer */
+ void* row, /*!< in: sel_node_t* */
+ void* user_arg) /*!< in: data pointer */
{
sel_node_t* node = row;
ib_uint32_t* val = user_arg;
@@ -2203,14 +2200,14 @@ row_fetch_store_uint4(
return(NULL);
}
-/***************************************************************
-Prints a row in a select result. */
+/***********************************************************//**
+Prints a row in a select result.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_printf_step(
/*============*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
row_printf_node_t* node;
sel_node_t* sel_node;
@@ -2266,7 +2263,7 @@ row_printf_step(
return(thr);
}
-/********************************************************************
+/****************************************************************//**
Converts a key value stored in MySQL format to an Innobase dtuple. The last
field of the key value may be just a prefix of a fixed length field: hence
the parameter key_len. But currently we do not allow search keys where the
@@ -2277,17 +2274,17 @@ UNIV_INTERN
void
row_sel_convert_mysql_key_to_innobase(
/*==================================*/
- dtuple_t* tuple, /* in/out: tuple where to build;
+ dtuple_t* tuple, /*!< in/out: tuple where to build;
NOTE: we assume that the type info
in the tuple is already according
to index! */
- byte* buf, /* in: buffer to use in field
+ byte* buf, /*!< in: buffer to use in field
conversions */
- ulint buf_len, /* in: buffer length */
- dict_index_t* index, /* in: index of the key value */
- const byte* key_ptr, /* in: MySQL key value */
- ulint key_len, /* in: MySQL key value length */
- trx_t* trx) /* in: transaction */
+ ulint buf_len, /*!< in: buffer length */
+ dict_index_t* index, /*!< in: index of the key value */
+ const byte* key_ptr, /*!< in: MySQL key value */
+ ulint key_len, /*!< in: MySQL key value length */
+ trx_t* trx) /*!< in: transaction */
{
byte* original_buf = buf;
const byte* original_key_ptr = key_ptr;
@@ -2470,16 +2467,16 @@ row_sel_convert_mysql_key_to_innobase(
dtuple_set_n_fields(tuple, n_fields);
}
-/******************************************************************
+/**************************************************************//**
Stores the row id to the prebuilt struct. */
static
void
row_sel_store_row_id_to_prebuilt(
/*=============================*/
- row_prebuilt_t* prebuilt, /* in/out: prebuilt */
- const rec_t* index_rec, /* in: record */
- const dict_index_t* index, /* in: index of the record */
- const ulint* offsets) /* in: rec_get_offsets
+ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt */
+ const rec_t* index_rec, /*!< in: record */
+ const dict_index_t* index, /*!< in: index of the record */
+ const ulint* offsets) /*!< in: rec_get_offsets
(index_rec, index) */
{
const byte* data;
@@ -2508,26 +2505,26 @@ row_sel_store_row_id_to_prebuilt(
ut_memcpy(prebuilt->row_id, data, len);
}
-/******************************************************************
+/**************************************************************//**
Stores a non-SQL-NULL field in the MySQL format. The counterpart of this
function is row_mysql_store_col_in_innobase_format() in row0mysql.c. */
static
void
row_sel_field_store_in_mysql_format(
/*================================*/
- byte* dest, /* in/out: buffer where to store; NOTE
+ byte* dest, /*!< in/out: buffer where to store; NOTE
that BLOBs are not in themselves
stored here: the caller must allocate
and copy the BLOB into buffer before,
and pass the pointer to the BLOB in
'data' */
const mysql_row_templ_t* templ,
- /* in: MySQL column template.
+ /*!< in: MySQL column template.
Its following fields are referenced:
type, is_unsigned, mysql_col_len,
mbminlen, mbmaxlen */
- const byte* data, /* in: data to store */
- ulint len) /* in: length of the data */
+ const byte* data, /*!< in: data to store */
+ ulint len) /*!< in: length of the data */
{
byte* ptr;
byte* field_end;
@@ -2663,26 +2660,24 @@ row_sel_field_store_in_mysql_format(
}
}
-/******************************************************************
+/**************************************************************//**
Convert a row in the Innobase format to a row in the MySQL format.
Note that the template in prebuilt may advise us to copy only a few
columns to mysql_rec, other columns are left blank. All columns may not
-be needed in the query. */
+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
ibool
row_sel_store_mysql_rec(
/*====================*/
- /* out: TRUE if success, FALSE if
- could not allocate memory for a BLOB
- (though we may also assert in that
- case) */
- byte* mysql_rec, /* out: row in the MySQL format */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct */
- const rec_t* rec, /* in: Innobase record in the index
+ byte* mysql_rec, /*!< out: row in the MySQL format */
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
+ const rec_t* rec, /*!< in: Innobase record in the index
which was described in prebuilt's
template; must be protected by
a page latch */
- const ulint* offsets) /* in: array returned by
+ const ulint* offsets) /*!< in: array returned by
rec_get_offsets() */
{
mysql_row_templ_t* templ;
@@ -2787,7 +2782,8 @@ row_sel_store_mysql_rec(
mysql_rec[templ->mysql_null_byte_offset]
|= (byte) templ->mysql_null_bit_mask;
memcpy(mysql_rec + templ->mysql_col_offset,
- prebuilt->default_rec + templ->mysql_col_offset,
+ (const byte*) prebuilt->default_rec
+ + templ->mysql_col_offset,
templ->mysql_col_len);
}
}
@@ -2795,26 +2791,26 @@ row_sel_store_mysql_rec(
return(TRUE);
}
-/*************************************************************************
-Builds a previous version of a clustered index record for a consistent read */
+/*********************************************************************//**
+Builds a previous version of a clustered index record for a consistent read
+@return DB_SUCCESS or error code */
static
ulint
row_sel_build_prev_vers_for_mysql(
/*==============================*/
- /* out: DB_SUCCESS or error code */
- read_view_t* read_view, /* in: read view */
- dict_index_t* clust_index, /* in: clustered index */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct */
- const rec_t* rec, /* in: record in a clustered index */
- ulint** offsets, /* in/out: offsets returned by
+ read_view_t* read_view, /*!< in: read view */
+ dict_index_t* clust_index, /*!< in: clustered index */
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
+ const rec_t* rec, /*!< in: record in a clustered index */
+ ulint** offsets, /*!< in/out: offsets returned by
rec_get_offsets(rec, clust_index) */
- mem_heap_t** offset_heap, /* in/out: memory heap from which
+ mem_heap_t** offset_heap, /*!< in/out: memory heap from which
the offsets are allocated */
- rec_t** old_vers, /* out: old version, or NULL if the
+ rec_t** old_vers, /*!< out: old version, or NULL if the
record does not exist in the view:
i.e., it was freshly inserted
afterwards */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint err;
@@ -2830,33 +2826,33 @@ row_sel_build_prev_vers_for_mysql(
return(err);
}
-/*************************************************************************
+/*********************************************************************//**
Retrieves the clustered index record corresponding to a record in a
non-clustered index. Does the necessary locking. Used in the MySQL
-interface. */
+interface.
+@return DB_SUCCESS or error code */
static
ulint
row_sel_get_clust_rec_for_mysql(
/*============================*/
- /* out: DB_SUCCESS or error code */
- row_prebuilt_t* prebuilt,/* in: prebuilt struct in the handle */
- dict_index_t* sec_index,/* in: secondary index where rec resides */
- const rec_t* rec, /* in: record in a non-clustered index; if
+ row_prebuilt_t* prebuilt,/*!< in: prebuilt struct in the handle */
+ dict_index_t* sec_index,/*!< in: secondary index where rec resides */
+ const rec_t* rec, /*!< in: record in a non-clustered index; if
this is a locking read, then rec is not
allowed to be delete-marked, and that would
not make sense either */
- que_thr_t* thr, /* in: query thread */
- const rec_t** out_rec,/* out: clustered record or an old version of
+ que_thr_t* thr, /*!< in: query thread */
+ const rec_t** out_rec,/*!< out: clustered record or an old version of
it, NULL if the old version did not exist
in the read view, i.e., it was a fresh
inserted version */
- ulint** offsets,/* in: offsets returned by
+ ulint** offsets,/*!< in: offsets returned by
rec_get_offsets(rec, sec_index);
out: offsets returned by
rec_get_offsets(out_rec, clust_index) */
- mem_heap_t** offset_heap,/* in/out: memory heap from which
+ mem_heap_t** offset_heap,/*!< in/out: memory heap from which
the offsets are allocated */
- mtr_t* mtr) /* in: mtr used to get access to the
+ mtr_t* mtr) /*!< in: mtr used to get access to the
non-clustered record; the same mtr is used to
access the clustered index */
{
@@ -3014,29 +3010,27 @@ err_exit:
return(err);
}
-/************************************************************************
+/********************************************************************//**
Restores cursor position after it has been stored. We have to take into
account that the record cursor was positioned on may have been deleted.
-Then we may have to move the cursor one step up or down. */
+Then we may have to move the cursor one step up or down.
+@return TRUE if we may need to process the record the cursor is now
+positioned on (i.e. we should not go to the next record yet) */
static
ibool
sel_restore_position_for_mysql(
/*===========================*/
- /* out: TRUE if we may need to
- process the record the cursor is
- now positioned on (i.e. we should
- not go to the next record yet) */
- ibool* same_user_rec, /* out: TRUE if we were able to restore
+ ibool* same_user_rec, /*!< out: TRUE if we were able to restore
the cursor on a user record with the
same ordering prefix in in the
B-tree index */
- ulint latch_mode, /* in: latch mode wished in
+ ulint latch_mode, /*!< in: latch mode wished in
restoration */
- btr_pcur_t* pcur, /* in: cursor whose position
+ btr_pcur_t* pcur, /*!< in: cursor whose position
has been stored */
- ibool moves_up, /* in: TRUE if the cursor moves up
+ ibool moves_up, /*!< in: TRUE if the cursor moves up
in the index */
- mtr_t* mtr) /* in: mtr; CAUTION: may commit
+ mtr_t* mtr) /*!< in: mtr; CAUTION: may commit
mtr temporarily! */
{
ibool success;
@@ -3084,15 +3078,15 @@ sel_restore_position_for_mysql(
return(TRUE);
}
-/************************************************************************
+/********************************************************************//**
Pops a cached row for MySQL from the fetch cache. */
UNIV_INLINE
void
row_sel_pop_cached_row_for_mysql(
/*=============================*/
- byte* buf, /* in/out: buffer where to copy the
+ byte* buf, /*!< in/out: buffer where to copy the
row */
- row_prebuilt_t* prebuilt) /* in: prebuilt struct */
+ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct */
{
ulint i;
mysql_row_templ_t* templ;
@@ -3134,16 +3128,16 @@ row_sel_pop_cached_row_for_mysql(
}
}
-/************************************************************************
+/********************************************************************//**
Pushes a row for MySQL to the fetch cache. */
UNIV_INLINE
void
row_sel_push_cache_row_for_mysql(
/*=============================*/
- row_prebuilt_t* prebuilt, /* in: prebuilt struct */
- const rec_t* rec, /* in: record to push; must
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
+ const rec_t* rec, /*!< in: record to push; must
be protected by a page latch */
- const ulint* offsets) /* in: rec_get_offsets() */
+ const ulint* offsets) /*!< in: rec_get_offsets() */
{
byte* buf;
ulint i;
@@ -3183,21 +3177,21 @@ row_sel_push_cache_row_for_mysql(
prebuilt->n_fetch_cached++;
}
-/*************************************************************************
+/*********************************************************************//**
Tries to do a shortcut to fetch a clustered index record with a unique key,
using the hash index if possible (not always). We assume that the search
mode is PAGE_CUR_GE, it is a consistent read, there is a read view in trx,
-btr search latch has been locked in S-mode. */
+btr search latch has been locked in S-mode.
+@return SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
static
ulint
row_sel_try_search_shortcut_for_mysql(
/*==================================*/
- /* out: SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
- const rec_t** out_rec,/* out: record if found */
- row_prebuilt_t* prebuilt,/* in: prebuilt struct */
- ulint** offsets,/* in/out: for rec_get_offsets(*out_rec) */
- mem_heap_t** heap, /* in/out: heap for rec_get_offsets() */
- mtr_t* mtr) /* in: started mtr */
+ const rec_t** out_rec,/*!< out: record if found */
+ row_prebuilt_t* prebuilt,/*!< in: prebuilt struct */
+ ulint** offsets,/*!< in/out: for rec_get_offsets(*out_rec) */
+ mem_heap_t** heap, /*!< in/out: heap for rec_get_offsets() */
+ mtr_t* mtr) /*!< in: started mtr */
{
dict_index_t* index = prebuilt->index;
const dtuple_t* search_tuple = prebuilt->search_tuple;
@@ -3254,34 +3248,31 @@ row_sel_try_search_shortcut_for_mysql(
return(SEL_FOUND);
}
-/************************************************************************
+/********************************************************************//**
Searches for rows in the database. This is used in the interface to
MySQL. This function opens a cursor, and also implements fetch next
and fetch prev. NOTE that if we do a search with a full key value
from a unique index (ROW_SEL_EXACT), then we will not store the cursor
-position and fetch next or fetch prev must not be tried to the cursor! */
+position and fetch next or fetch prev must not be tried to the cursor!
+@return DB_SUCCESS, DB_RECORD_NOT_FOUND, DB_END_OF_INDEX, DB_DEADLOCK,
+DB_LOCK_TABLE_FULL, DB_CORRUPTION, or DB_TOO_BIG_RECORD */
UNIV_INTERN
ulint
row_search_for_mysql(
/*=================*/
- /* out: DB_SUCCESS,
- DB_RECORD_NOT_FOUND,
- DB_END_OF_INDEX, DB_DEADLOCK,
- DB_LOCK_TABLE_FULL, DB_CORRUPTION,
- or DB_TOO_BIG_RECORD */
- byte* buf, /* in/out: buffer for the fetched
+ byte* buf, /*!< in/out: buffer for the fetched
row in the MySQL format */
- ulint mode, /* in: search mode PAGE_CUR_L, ... */
- row_prebuilt_t* prebuilt, /* in: prebuilt struct for the
+ ulint mode, /*!< in: search mode PAGE_CUR_L, ... */
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct for the
table handle; this contains the info
of search_tuple, index; if search
tuple contains 0 fields then we
position the cursor at the start or
the end of the index, depending on
'mode' */
- ulint match_mode, /* in: 0 or ROW_SEL_EXACT or
+ ulint match_mode, /*!< in: 0 or ROW_SEL_EXACT or
ROW_SEL_EXACT_PREFIX */
- ulint direction) /* in: 0 or ROW_SEL_NEXT or
+ ulint direction) /*!< in: 0 or ROW_SEL_NEXT or
ROW_SEL_PREV; NOTE: if this is != 0,
then prebuilt must have a pcur
with stored position! In opening of a
@@ -3335,14 +3326,18 @@ row_search_for_mysql(
"InnoDB: the MySQL datadir, or have you used"
" DISCARD TABLESPACE?\n"
"InnoDB: Look from\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "innodb-troubleshooting.html\n"
+ "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
"InnoDB: how you can resolve the problem.\n",
prebuilt->table->name);
return(DB_ERROR);
}
+ if (UNIV_UNLIKELY(!prebuilt->index_usable)) {
+
+ return(DB_MISSING_HISTORY);
+ }
+
if (UNIV_UNLIKELY(prebuilt->magic_n != ROW_PREBUILT_ALLOCATED)) {
fprintf(stderr,
"InnoDB: Error: trying to free a corrupt\n"
@@ -4554,17 +4549,16 @@ func_exit:
return(err);
}
-/***********************************************************************
+/*******************************************************************//**
Checks if MySQL at the moment is allowed for this table to retrieve a
-consistent read result, or store it to the query cache. */
+consistent read result, or store it to the query cache.
+@return TRUE if storing or retrieving from the query cache is permitted */
UNIV_INTERN
ibool
row_search_check_if_query_cache_permitted(
/*======================================*/
- /* out: TRUE if storing or retrieving
- from the query cache is permitted */
- trx_t* trx, /* in: transaction object */
- const char* norm_name) /* in: concatenation of database name,
+ trx_t* trx, /*!< in: transaction object */
+ const char* norm_name) /*!< in: concatenation of database name,
'/' char, table name */
{
dict_table_t* table;
@@ -4611,18 +4605,18 @@ row_search_check_if_query_cache_permitted(
return(ret);
}
-/***********************************************************************
+/*******************************************************************//**
Read the AUTOINC column from the current row. If the value is less than
-0 and the type is not unsigned then we reset the value to 0. */
+0 and the type is not unsigned then we reset the value to 0.
+@return value read from the column */
static
ib_uint64_t
row_search_autoinc_read_column(
/*===========================*/
- /* out: value read from the column */
- dict_index_t* index, /* in: index to read from */
- const rec_t* rec, /* in: current rec */
- ulint col_no, /* in: column number */
- ibool unsigned_type) /* in: signed or unsigned flag */
+ dict_index_t* index, /*!< in: index to read from */
+ const rec_t* rec, /*!< in: current rec */
+ ulint col_no, /*!< in: column number */
+ ibool unsigned_type) /*!< in: signed or unsigned flag */
{
ulint len;
const byte* data;
@@ -4654,15 +4648,15 @@ row_search_autoinc_read_column(
return(value);
}
-/***********************************************************************
-Get the last row. */
+/*******************************************************************//**
+Get the last row.
+@return current rec or NULL */
static
const rec_t*
row_search_autoinc_get_rec(
/*=======================*/
- /* out: current rec or NULL */
- btr_pcur_t* pcur, /* in: the current cursor */
- mtr_t* mtr) /* in: mini transaction */
+ btr_pcur_t* pcur, /*!< in: the current cursor */
+ mtr_t* mtr) /*!< in: mini transaction */
{
do {
const rec_t* rec = btr_pcur_get_rec(pcur);
@@ -4675,18 +4669,17 @@ row_search_autoinc_get_rec(
return(NULL);
}
-/***********************************************************************
-Read the max AUTOINC value from an index. */
+/*******************************************************************//**
+Read the max AUTOINC value from an index.
+@return DB_SUCCESS if all OK else error code, DB_RECORD_NOT_FOUND if
+column name can't be found in index */
UNIV_INTERN
ulint
row_search_max_autoinc(
/*===================*/
- /* out: DB_SUCCESS if all OK else
- error code, DB_RECORD_NOT_FOUND if
- column name can't be found in index */
- dict_index_t* index, /* in: index to search */
- const char* col_name, /* in: name of autoinc column */
- ib_uint64_t* value) /* out: AUTOINC value read */
+ dict_index_t* index, /*!< in: index to search */
+ const char* col_name, /*!< in: name of autoinc column */
+ ib_uint64_t* value) /*!< out: AUTOINC value read */
{
ulint i;
ulint n_cols;
diff --git a/storage/xtradb/row/row0uins.c b/storage/xtradb/row/row0uins.c
index 69d6b2e6c2a..9f9c814f1a5 100644
--- a/storage/xtradb/row/row0uins.c
+++ b/storage/xtradb/row/row0uins.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0uins.c
Fresh insert undo
Created 2/25/1997 Heikki Tuuri
@@ -45,15 +46,15 @@ Created 2/25/1997 Heikki Tuuri
#include "ibuf0ibuf.h"
#include "log0log.h"
-/*******************************************************************
+/***************************************************************//**
Removes a clustered index record. The pcur in node was positioned on the
-record, now it is detached. */
+record, now it is detached.
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_ins_remove_clust_rec(
/*==========================*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- undo_node_t* node) /* in: undo node */
+ undo_node_t* node) /*!< in: undo node */
{
btr_cur_t* btr_cur;
ibool success;
@@ -131,19 +132,18 @@ retry:
return(err);
}
-/*******************************************************************
-Removes a secondary index entry if found. */
+/***************************************************************//**
+Removes a secondary index entry if found.
+@return DB_SUCCESS, DB_FAIL, or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_ins_remove_sec_low(
/*========================*/
- /* out: DB_SUCCESS, DB_FAIL, or
- DB_OUT_OF_FILE_SPACE */
- ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
+ ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
depending on whether we wish optimistic or
pessimistic descent down the index tree */
- dict_index_t* index, /* in: index */
- dtuple_t* entry) /* in: index entry to remove */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry) /*!< in: index entry to remove */
{
btr_pcur_t pcur;
btr_cur_t* btr_cur;
@@ -195,16 +195,16 @@ row_undo_ins_remove_sec_low(
return(err);
}
-/*******************************************************************
+/***************************************************************//**
Removes a secondary index entry from the index if found. Tries first
-optimistic, then pessimistic descent down the tree. */
+optimistic, then pessimistic descent down the tree.
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_ins_remove_sec(
/*====================*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- dict_index_t* index, /* in: index */
- dtuple_t* entry) /* in: index entry to insert */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry) /*!< in: index entry to insert */
{
ulint err;
ulint n_tries = 0;
@@ -238,17 +238,17 @@ retry:
return(err);
}
-/***************************************************************
+/***********************************************************//**
Parses the row reference and other info in a fresh insert undo record. */
static
void
row_undo_ins_parse_undo_rec(
/*========================*/
- undo_node_t* node) /* in/out: row undo node */
+ undo_node_t* node) /*!< in/out: row undo node */
{
dict_index_t* clust_index;
byte* ptr;
- dulint undo_no;
+ undo_no_t undo_no;
dulint table_id;
ulint type;
ulint dummy;
@@ -287,18 +287,18 @@ row_undo_ins_parse_undo_rec(
}
}
-/***************************************************************
+/***********************************************************//**
Undoes a fresh insert of a row to a table. A fresh insert means that
the same clustered index unique key did not have any record, even delete
marked, at the time of the insert. InnoDB is eager in a rollback:
if it figures out that an index record will be removed in the purge
-anyway, it will remove it in the rollback. */
+anyway, it will remove it in the rollback.
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
UNIV_INTERN
ulint
row_undo_ins(
/*=========*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- undo_node_t* node) /* in: row undo node */
+ undo_node_t* node) /*!< in: row undo node */
{
ut_ad(node);
ut_ad(node->state == UNDO_NODE_INSERT);
diff --git a/storage/xtradb/row/row0umod.c b/storage/xtradb/row/row0umod.c
index 835f357fc8d..6be475d8c78 100644
--- a/storage/xtradb/row/row0umod.c
+++ b/storage/xtradb/row/row0umod.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0umod.c
Undo modify of a row
Created 2/27/1997 Heikki Tuuri
@@ -57,18 +58,17 @@ 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. */
-/***************************************************************
+/***********************************************************//**
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. */
+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
ibool
row_undo_mod_undo_also_prev_vers(
/*=============================*/
- /* out: TRUE if also previous modify or
- insert of this row should be undone */
- undo_node_t* node, /* in: row undo node */
- dulint* undo_no)/* out: the undo number */
+ undo_node_t* node, /*!< in: row undo node */
+ undo_no_t* undo_no)/*!< out: the undo number */
{
trx_undo_rec_t* undo_rec;
trx_t* trx;
@@ -88,19 +88,18 @@ row_undo_mod_undo_also_prev_vers(
return(ut_dulint_cmp(trx->roll_limit, *undo_no) <= 0);
}
-/***************************************************************
-Undoes a modify in a clustered index record. */
+/***********************************************************//**
+Undoes a modify in a clustered index record.
+@return DB_SUCCESS, DB_FAIL, or error code: we may run out of file space */
static
ulint
row_undo_mod_clust_low(
/*===================*/
- /* out: DB_SUCCESS, DB_FAIL, or error code:
- we may run out of file space */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr, /* in: mtr; must be committed before
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr, /*!< in: mtr; must be committed before
latching any further pages */
- ulint mode) /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
+ ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
{
btr_pcur_t* pcur;
btr_cur_t* btr_cur;
@@ -143,18 +142,17 @@ row_undo_mod_clust_low(
return(err);
}
-/***************************************************************
-Removes a clustered index record after undo if possible. */
+/***********************************************************//**
+Removes a clustered index record after undo if possible.
+@return DB_SUCCESS, DB_FAIL, or error code: we may run out of file space */
static
ulint
row_undo_mod_remove_clust_low(
/*==========================*/
- /* out: DB_SUCCESS, DB_FAIL, or error code:
- we may run out of file space */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr __attribute__((unused)), /* in: query thread */
- mtr_t* mtr, /* in: mtr */
- ulint mode) /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr __attribute__((unused)), /*!< in: query thread */
+ mtr_t* mtr, /*!< in: mtr */
+ ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
{
btr_pcur_t* pcur;
btr_cur_t* btr_cur;
@@ -206,24 +204,23 @@ row_undo_mod_remove_clust_low(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Undoes a modify in a clustered index record. Sets also the node state for the
-next round of undo. */
+next round of undo.
+@return DB_SUCCESS or error code: we may run out of file space */
static
ulint
row_undo_mod_clust(
/*===============*/
- /* out: DB_SUCCESS or error code: we may run
- out of file space */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr) /*!< in: query thread */
{
btr_pcur_t* pcur;
mtr_t mtr;
ulint err;
ibool success;
ibool more_vers;
- dulint new_undo_no;
+ undo_no_t new_undo_no;
ut_ad(node && thr);
@@ -296,19 +293,18 @@ row_undo_mod_clust(
return(err);
}
-/***************************************************************
-Delete marks or removes a secondary index entry if found. */
+/***********************************************************//**
+Delete marks or removes a secondary index entry if found.
+@return DB_SUCCESS, DB_FAIL, or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_mod_del_mark_or_remove_sec_low(
/*====================================*/
- /* out: DB_SUCCESS, DB_FAIL, or
- DB_OUT_OF_FILE_SPACE */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr, /* in: query thread */
- dict_index_t* index, /* in: index */
- dtuple_t* entry, /* in: index entry */
- ulint mode) /* in: latch mode BTR_MODIFY_LEAF or
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr, /*!< in: query thread */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry, /*!< in: index entry */
+ ulint mode) /*!< in: latch mode BTR_MODIFY_LEAF or
BTR_MODIFY_TREE */
{
ibool found;
@@ -396,23 +392,23 @@ row_undo_mod_del_mark_or_remove_sec_low(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Delete marks or removes a secondary index entry if found.
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. */
+record through which we do the search is delete-marked.
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_mod_del_mark_or_remove_sec(
/*================================*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr, /* in: query thread */
- dict_index_t* index, /* in: index */
- dtuple_t* entry) /* in: index entry */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr, /*!< in: query thread */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry) /*!< in: index entry */
{
ulint err;
@@ -428,22 +424,21 @@ row_undo_mod_del_mark_or_remove_sec(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Delete unmarks a secondary index entry which must be found. It might not be
delete-marked at the moment, but it does not harm to unmark it anyway. We also
need to update the fields of the secondary index record if we updated its
-fields but alphabetically they stayed the same, e.g., 'abc' -> 'aBc'. */
+fields but alphabetically they stayed the same, e.g., 'abc' -> 'aBc'.
+@return DB_FAIL or DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_mod_del_unmark_sec_and_undo_update(
/*========================================*/
- /* out: DB_FAIL or DB_SUCCESS or
- DB_OUT_OF_FILE_SPACE */
- ulint mode, /* in: search mode: BTR_MODIFY_LEAF or
+ ulint mode, /*!< in: search mode: BTR_MODIFY_LEAF or
BTR_MODIFY_TREE */
- que_thr_t* thr, /* in: query thread */
- dict_index_t* index, /* in: index */
- dtuple_t* entry) /* in: index entry */
+ que_thr_t* thr, /*!< in: query thread */
+ dict_index_t* index, /*!< in: index */
+ dtuple_t* entry) /*!< in: index entry */
{
mem_heap_t* heap;
btr_pcur_t pcur;
@@ -523,15 +518,15 @@ row_undo_mod_del_unmark_sec_and_undo_update(
return(err);
}
-/***************************************************************
-Undoes a modify in secondary indexes when undo record type is UPD_DEL. */
+/***********************************************************//**
+Undoes a modify in secondary indexes when undo record type is UPD_DEL.
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_mod_upd_del_sec(
/*=====================*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr) /*!< in: query thread */
{
mem_heap_t* heap;
dtuple_t* entry;
@@ -576,15 +571,15 @@ row_undo_mod_upd_del_sec(
return(err);
}
-/***************************************************************
-Undoes a modify in secondary indexes when undo record type is DEL_MARK. */
+/***********************************************************//**
+Undoes a modify in secondary indexes when undo record type is DEL_MARK.
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_mod_del_mark_sec(
/*======================*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr) /*!< in: query thread */
{
mem_heap_t* heap;
dtuple_t* entry;
@@ -621,15 +616,15 @@ row_undo_mod_del_mark_sec(
return(DB_SUCCESS);
}
-/***************************************************************
-Undoes a modify in secondary indexes when undo record type is UPD_EXIST. */
+/***********************************************************//**
+Undoes a modify in secondary indexes when undo record type is UPD_EXIST.
+@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
static
ulint
row_undo_mod_upd_exist_sec(
/*=======================*/
- /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr) /*!< in: query thread */
{
mem_heap_t* heap;
dtuple_t* entry;
@@ -707,21 +702,21 @@ row_undo_mod_upd_exist_sec(
return(DB_SUCCESS);
}
-/***************************************************************
+/***********************************************************//**
Parses the row reference and other info in a modify undo log record. */
static
void
row_undo_mod_parse_undo_rec(
/*========================*/
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr) /*!< in: query thread */
{
dict_index_t* clust_index;
byte* ptr;
- dulint undo_no;
+ undo_no_t undo_no;
dulint table_id;
- dulint trx_id;
- dulint roll_ptr;
+ trx_id_t trx_id;
+ roll_ptr_t roll_ptr;
ulint info_bits;
ulint type;
ulint cmpl_info;
@@ -767,15 +762,15 @@ row_undo_mod_parse_undo_rec(
node->cmpl_info = cmpl_info;
}
-/***************************************************************
-Undoes a modify operation on a row of a table. */
+/***********************************************************//**
+Undoes a modify operation on a row of a table.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
row_undo_mod(
/*=========*/
- /* out: DB_SUCCESS or error code */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
diff --git a/storage/xtradb/row/row0undo.c b/storage/xtradb/row/row0undo.c
index d372f88e207..3d739c9689a 100644
--- a/storage/xtradb/row/row0undo.c
+++ b/storage/xtradb/row/row0undo.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0undo.c
Row undo
Created 1/8/1997 Heikki Tuuri
@@ -119,16 +120,16 @@ doing the purge. Similarly, during a rollback, a record can be removed
if the stored roll ptr in the undo log points to a trx already (being) purged,
or if the roll ptr is NULL, i.e., it was a fresh insert. */
-/************************************************************************
-Creates a row undo node to a query graph. */
+/********************************************************************//**
+Creates a row undo node to a query graph.
+@return own: undo node */
UNIV_INTERN
undo_node_t*
row_undo_node_create(
/*=================*/
- /* out, own: undo node */
- trx_t* trx, /* in: transaction */
- que_thr_t* parent, /* in: parent node, i.e., a thr node */
- mem_heap_t* heap) /* in: memory heap where created */
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t* parent, /*!< in: parent node, i.e., a thr node */
+ mem_heap_t* heap) /*!< in: memory heap where created */
{
undo_node_t* undo;
@@ -149,19 +150,18 @@ row_undo_node_create(
return(undo);
}
-/***************************************************************
+/***********************************************************//**
Looks for the clustered index record when node has the row reference.
The pcur in node is used in the search. If found, stores the row to node,
and stores the position of pcur, and detaches it. The pcur must be closed
-by the caller in any case. */
+by the caller in any case.
+@return TRUE if found; NOTE the node->pcur must be closed by the
+caller, regardless of the return value */
UNIV_INTERN
ibool
row_undo_search_clust_to_pcur(
/*==========================*/
- /* out: TRUE if found; NOTE the node->pcur
- must be closed by the caller, regardless of
- the return value */
- undo_node_t* node) /* in: row undo node */
+ undo_node_t* node) /*!< in: row undo node */
{
dict_index_t* clust_index;
ibool found;
@@ -223,23 +223,22 @@ row_undo_search_clust_to_pcur(
return(ret);
}
-/***************************************************************
+/***********************************************************//**
Fetches an undo log record and does the undo for the recorded operation.
If none left, or a partial rollback completed, returns control to the
-parent node, which is always a query thread node. */
+parent node, which is always a query thread node.
+@return DB_SUCCESS if operation successfully completed, else error code */
static
ulint
row_undo(
/*=====*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code */
- undo_node_t* node, /* in: row undo node */
- que_thr_t* thr) /* in: query thread */
+ undo_node_t* node, /*!< in: row undo node */
+ que_thr_t* thr) /*!< in: query thread */
{
- ulint err;
- trx_t* trx;
- dulint roll_ptr;
- ibool locked_data_dict;
+ ulint err;
+ trx_t* trx;
+ roll_ptr_t roll_ptr;
+ ibool locked_data_dict;
ut_ad(node && thr);
@@ -326,15 +325,15 @@ row_undo(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Undoes a row operation in a table. This is a high-level function used
-in SQL execution graphs. */
+in SQL execution graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_undo_step(
/*==========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err;
undo_node_t* node;
diff --git a/storage/xtradb/row/row0upd.c b/storage/xtradb/row/row0upd.c
index 740f1ee593d..58dfd43ead9 100644
--- a/storage/xtradb/row/row0upd.c
+++ b/storage/xtradb/row/row0upd.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0upd.c
Update of a row
Created 12/27/1996 Heikki Tuuri
@@ -29,10 +30,12 @@ Created 12/27/1996 Heikki Tuuri
#endif
#include "dict0dict.h"
+#include "trx0undo.h"
+#include "rem0rec.h"
+#ifndef UNIV_HOTBACKUP
#include "dict0boot.h"
#include "dict0crea.h"
#include "mach0data.h"
-#include "trx0undo.h"
#include "btr0btr.h"
#include "btr0cur.h"
#include "que0que.h"
@@ -89,36 +92,36 @@ 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. */
-/***************************************************************
+/***********************************************************//**
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
-that index does not contain column prefixes. */
+that index does not contain column prefixes.
+@return TRUE if changes */
static
ibool
row_upd_changes_first_fields_binary(
/*================================*/
- /* out: TRUE if changes */
- dtuple_t* entry, /* in: old value of index entry */
- dict_index_t* index, /* in: index of entry */
- const upd_t* update, /* in: update vector for the row */
- ulint n); /* in: how many first fields to check */
+ dtuple_t* entry, /*!< in: old value of index entry */
+ dict_index_t* index, /*!< in: index of entry */
+ const upd_t* update, /*!< in: update vector for the row */
+ ulint n); /*!< in: how many first fields to check */
-/*************************************************************************
+/*********************************************************************//**
Checks if index currently is mentioned as a referenced index in a foreign
-key constraint. */
+key constraint.
+
+NOTE that since we do not hold dict_operation_lock when leaving the
+function, it may be that the referencing table has been dropped when
+we leave this function: this function is only for heuristic use!
+
+@return TRUE if referenced */
static
ibool
row_upd_index_is_referenced(
/*========================*/
- /* out: TRUE if referenced; NOTE that since
- we do not hold dict_operation_lock
- when leaving the function, it may be that
- the referencing table has been dropped when
- we leave this function: this function is only
- for heuristic use! */
- dict_index_t* index, /* in: index */
- trx_t* trx) /* in: transaction */
+ dict_index_t* index, /*!< in: index */
+ trx_t* trx) /*!< in: transaction */
{
dict_table_t* table = index->table;
dict_foreign_t* foreign;
@@ -155,23 +158,26 @@ func_exit:
return(is_referenced);
}
-/*************************************************************************
+/*********************************************************************//**
Checks if possible foreign key constraints hold after a delete of the record
-under pcur. NOTE that this function will temporarily commit mtr and lose the
-pcur position! */
+under pcur.
+
+NOTE that this function will temporarily commit mtr and lose the
+pcur position!
+
+@return DB_SUCCESS or an error code */
static
ulint
row_upd_check_references_constraints(
/*=================================*/
- /* out: DB_SUCCESS or an error code */
- upd_node_t* node, /* in: row update node */
- btr_pcur_t* pcur, /* in: cursor positioned on a record; NOTE: the
+ upd_node_t* node, /*!< in: row update node */
+ btr_pcur_t* pcur, /*!< in: cursor positioned on a record; NOTE: the
cursor position is lost in this function! */
- dict_table_t* table, /* in: table in question */
- dict_index_t* index, /* in: index of the cursor */
- ulint* offsets,/* in/out: rec_get_offsets(pcur.rec, index) */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr */
+ dict_table_t* table, /*!< in: table in question */
+ dict_index_t* index, /*!< in: index of the cursor */
+ ulint* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_foreign_t* foreign;
mem_heap_t* heap;
@@ -276,14 +282,14 @@ func_exit:
return(err);
}
-/*************************************************************************
-Creates an update node for a query graph. */
+/*********************************************************************//**
+Creates an update node for a query graph.
+@return own: update node */
UNIV_INTERN
upd_node_t*
upd_node_create(
/*============*/
- /* out, own: update node */
- mem_heap_t* heap) /* in: mem heap where created */
+ mem_heap_t* heap) /*!< in: mem heap where created */
{
upd_node_t* node;
@@ -313,20 +319,21 @@ upd_node_create(
return(node);
}
+#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
+/*********************************************************************//**
Updates the trx id and roll ptr field in a clustered index record in database
recovery. */
UNIV_INTERN
void
row_upd_rec_sys_fields_in_recovery(
/*===============================*/
- rec_t* rec, /* in/out: record */
- page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- ulint pos, /* in: TRX_ID position in rec */
- dulint trx_id, /* in: transaction id */
- dulint roll_ptr)/* in: roll ptr of the undo log record */
+ rec_t* rec, /*!< in/out: record */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ ulint pos, /*!< in: TRX_ID position in rec */
+ trx_id_t trx_id, /*!< in: transaction id */
+ roll_ptr_t roll_ptr)/*!< in: roll ptr of the undo log record */
{
ut_ad(rec_offs_validate(rec, NULL, offsets));
@@ -347,19 +354,20 @@ row_upd_rec_sys_fields_in_recovery(
}
}
-/*************************************************************************
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
Sets the trx id or roll ptr field of a clustered index entry. */
UNIV_INTERN
void
row_upd_index_entry_sys_field(
/*==========================*/
- const dtuple_t* entry, /* in: index entry, where the memory buffers
+ const dtuple_t* entry, /*!< in: index entry, where the memory buffers
for sys fields are already allocated:
the function just copies the new values to
them */
- dict_index_t* index, /* in: clustered index */
- ulint type, /* in: DATA_TRX_ID or DATA_ROLL_PTR */
- dulint val) /* in: value to write */
+ dict_index_t* index, /*!< in: clustered index */
+ ulint type, /*!< in: DATA_TRX_ID or DATA_ROLL_PTR */
+ dulint val) /*!< in: value to write */
{
dfield_t* dfield;
byte* field;
@@ -380,19 +388,18 @@ row_upd_index_entry_sys_field(
}
}
-/***************************************************************
+/***********************************************************//**
Returns TRUE if row update changes size of some field in index or if some
-field to be updated is stored externally in rec or update. */
+field to be updated is stored externally in rec or update.
+@return TRUE if the update changes the size of some field in index or
+the field is external in rec or update */
UNIV_INTERN
ibool
row_upd_changes_field_size_or_external(
/*===================================*/
- /* out: TRUE if the update changes the size of
- some field in index or the field is external
- in rec or update */
- dict_index_t* index, /* in: index */
- const ulint* offsets,/* in: rec_get_offsets(rec, index) */
- const upd_t* update) /* in: update vector */
+ dict_index_t* index, /*!< in: index */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ const upd_t* update) /*!< in: update vector */
{
const upd_field_t* upd_field;
const dfield_t* new_val;
@@ -418,7 +425,8 @@ row_upd_changes_field_size_or_external(
new_len = dict_col_get_sql_null_size(
dict_index_get_nth_col(index,
- upd_field->field_no));
+ upd_field->field_no),
+ 0);
}
old_len = rec_offs_nth_size(offsets, upd_field->field_no);
@@ -445,19 +453,20 @@ row_upd_changes_field_size_or_external(
return(FALSE);
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
+/***********************************************************//**
Replaces the new column values stored in the update vector to the record
given. No field size changes are allowed. */
UNIV_INTERN
void
row_upd_rec_in_place(
/*=================*/
- rec_t* rec, /* in/out: record where replaced */
- dict_index_t* index, /* in: the index the record belongs to */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- const upd_t* update, /* in: update vector */
- page_zip_des_t* page_zip)/* in: compressed page with enough space
+ rec_t* rec, /*!< in/out: record where replaced */
+ dict_index_t* index, /*!< in: the index the record belongs to */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const upd_t* update, /*!< in: update vector */
+ page_zip_des_t* page_zip)/*!< in: compressed page with enough space
available, or NULL */
{
const upd_field_t* upd_field;
@@ -491,20 +500,21 @@ row_upd_rec_in_place(
}
}
-/*************************************************************************
+#ifndef UNIV_HOTBACKUP
+/*********************************************************************//**
Writes into the redo log the values of trx id and roll ptr and enough info
-to determine their positions within a clustered index record. */
+to determine their positions within a clustered index record.
+@return new pointer to mlog */
UNIV_INTERN
byte*
row_upd_write_sys_vals_to_log(
/*==========================*/
- /* out: new pointer to mlog */
- dict_index_t* index, /* in: clustered index */
- trx_t* trx, /* in: transaction */
- dulint roll_ptr,/* in: roll ptr of the undo log record */
- byte* log_ptr,/* pointer to a buffer of size > 20 opened
+ dict_index_t* index, /*!< in: clustered index */
+ trx_t* trx, /*!< in: transaction */
+ roll_ptr_t roll_ptr,/*!< in: roll ptr of the undo log record */
+ byte* log_ptr,/*!< pointer to a buffer of size > 20 opened
in mlog */
- mtr_t* mtr __attribute__((unused))) /* in: mtr */
+ mtr_t* mtr __attribute__((unused))) /*!< in: mtr */
{
ut_ad(dict_index_is_clust(index));
ut_ad(mtr);
@@ -520,19 +530,20 @@ row_upd_write_sys_vals_to_log(
return(log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
-Parses the log data of system field values. */
+/*********************************************************************//**
+Parses the log data of system field values.
+@return log data end or NULL */
UNIV_INTERN
byte*
row_upd_parse_sys_vals(
/*===================*/
- /* out: log data end or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- ulint* pos, /* out: TRX_ID position in record */
- dulint* trx_id, /* out: trx id */
- dulint* roll_ptr)/* out: roll ptr */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ ulint* pos, /*!< out: TRX_ID position in record */
+ trx_id_t* trx_id, /*!< out: trx id */
+ roll_ptr_t* roll_ptr)/*!< out: roll ptr */
{
ptr = mach_parse_compressed(ptr, end_ptr, pos);
@@ -554,18 +565,19 @@ row_upd_parse_sys_vals(
return(ptr);
}
-/***************************************************************
+#ifndef UNIV_HOTBACKUP
+/***********************************************************//**
Writes to the redo log the new values of the fields occurring in the index. */
UNIV_INTERN
void
row_upd_index_write_log(
/*====================*/
- const upd_t* update, /* in: update vector */
- byte* log_ptr,/* in: pointer to mlog buffer: must
+ const upd_t* update, /*!< in: update vector */
+ byte* log_ptr,/*!< in: pointer to mlog buffer: must
contain at least MLOG_BUF_MARGIN bytes
of free space; the buffer is closed
within this function */
- mtr_t* mtr) /* in: mtr into whose log to write */
+ mtr_t* mtr) /*!< in: mtr into whose log to write */
{
const upd_field_t* upd_field;
const dfield_t* new_val;
@@ -624,19 +636,20 @@ row_upd_index_write_log(
mlog_close(mtr, log_ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
-Parses the log data written by row_upd_index_write_log. */
+/*********************************************************************//**
+Parses the log data written by row_upd_index_write_log.
+@return log data end or NULL */
UNIV_INTERN
byte*
row_upd_index_parse(
/*================*/
- /* out: log data end or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- mem_heap_t* heap, /* in: memory heap where update vector is
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ mem_heap_t* heap, /*!< in: memory heap where update vector is
built */
- upd_t** update_out)/* out: update vector */
+ upd_t** update_out)/*!< out: update vector */
{
upd_t* update;
upd_field_t* upd_field;
@@ -704,21 +717,21 @@ row_upd_index_parse(
return(ptr);
}
-/*******************************************************************
+#ifndef UNIV_HOTBACKUP
+/***************************************************************//**
Builds an update vector from those fields which in a secondary index entry
differ from a record that has the equal ordering fields. NOTE: we compare
-the fields as binary strings! */
+the fields as binary strings!
+@return own: update vector of differing fields */
UNIV_INTERN
upd_t*
row_upd_build_sec_rec_difference_binary(
/*====================================*/
- /* out, own: update vector of differing
- fields */
- dict_index_t* index, /* in: index */
- const dtuple_t* entry, /* in: entry to insert */
- const rec_t* rec, /* in: secondary index record */
- trx_t* trx, /* in: transaction */
- mem_heap_t* heap) /* in: memory heap from which allocated */
+ dict_index_t* index, /*!< in: index */
+ const dtuple_t* entry, /*!< in: entry to insert */
+ const rec_t* rec, /*!< in: secondary index record */
+ trx_t* trx, /*!< in: transaction */
+ mem_heap_t* heap) /*!< in: memory heap from which allocated */
{
upd_field_t* upd_field;
const dfield_t* dfield;
@@ -774,21 +787,21 @@ row_upd_build_sec_rec_difference_binary(
return(update);
}
-/*******************************************************************
+/***************************************************************//**
Builds an update vector from those fields, excluding the roll ptr and
trx id fields, which in an index entry differ from a record that has
-the equal ordering fields. NOTE: we compare the fields as binary strings! */
+the equal ordering fields. NOTE: we compare the fields as binary strings!
+@return own: update vector of differing fields, excluding roll ptr and
+trx id */
UNIV_INTERN
upd_t*
row_upd_build_difference_binary(
/*============================*/
- /* out, own: update vector of differing
- fields, excluding roll ptr and trx id */
- dict_index_t* index, /* in: clustered index */
- const dtuple_t* entry, /* in: entry to insert */
- const rec_t* rec, /* in: clustered index record */
- trx_t* trx, /* in: transaction */
- mem_heap_t* heap) /* in: memory heap from which allocated */
+ dict_index_t* index, /*!< in: clustered index */
+ const dtuple_t* entry, /*!< in: entry to insert */
+ const rec_t* rec, /*!< in: clustered index record */
+ trx_t* trx, /*!< in: transaction */
+ mem_heap_t* heap) /*!< in: memory heap from which allocated */
{
upd_field_t* upd_field;
const dfield_t* dfield;
@@ -851,25 +864,25 @@ skip_compare:
return(update);
}
-/***************************************************************
+/***********************************************************//**
Fetch a prefix of an externally stored column. This is similar
to row_ext_lookup(), but the row_ext_t holds the old values
-of the column and must not be poisoned with the new values. */
+of the column and must not be poisoned with the new values.
+@return BLOB prefix */
static
byte*
row_upd_ext_fetch(
/*==============*/
- /* out: BLOB prefix */
- const byte* data, /* in: 'internally' stored part of the
+ const byte* data, /*!< in: 'internally' stored part of the
field containing also the reference to
the external part */
- ulint local_len, /* in: length of data, in bytes */
- ulint zip_size, /* in: nonzero=compressed BLOB
+ ulint local_len, /*!< in: length of data, in bytes */
+ ulint zip_size, /*!< in: nonzero=compressed BLOB
page size, zero for uncompressed
BLOBs */
- ulint* len, /* in: length of prefix to fetch;
+ ulint* len, /*!< in: length of prefix to fetch;
out: fetched length of the prefix */
- mem_heap_t* heap) /* in: heap where to allocate */
+ mem_heap_t* heap) /*!< in: heap where to allocate */
{
byte* buf = mem_heap_alloc(heap, *len);
@@ -882,21 +895,21 @@ row_upd_ext_fetch(
return(buf);
}
-/***************************************************************
+/***********************************************************//**
Replaces the new column value stored in the update vector in
the given index entry field. */
static
void
row_upd_index_replace_new_col_val(
/*==============================*/
- dfield_t* dfield, /* in/out: data field
+ dfield_t* dfield, /*!< in/out: data field
of the index entry */
- const dict_field_t* field, /* in: index field */
- const dict_col_t* col, /* in: field->col */
- const upd_field_t* uf, /* in: update field */
- mem_heap_t* heap, /* in: memory heap for allocating
+ const dict_field_t* field, /*!< in: index field */
+ const dict_col_t* col, /*!< in: field->col */
+ const upd_field_t* uf, /*!< in: update field */
+ mem_heap_t* heap, /*!< in: memory heap for allocating
and copying the new value */
- ulint zip_size)/* in: compressed page
+ ulint zip_size)/*!< in: compressed page
size of the table, or 0 */
{
ulint len;
@@ -975,27 +988,27 @@ row_upd_index_replace_new_col_val(
}
}
-/***************************************************************
+/***********************************************************//**
Replaces the new column values stored in the update vector to the index entry
given. */
UNIV_INTERN
void
row_upd_index_replace_new_col_vals_index_pos(
/*=========================================*/
- dtuple_t* entry, /* in/out: index entry where replaced;
+ dtuple_t* entry, /*!< in/out: index entry where replaced;
the clustered index record must be
covered by a lock or a page latch to
prevent deletion (rollback or purge) */
- dict_index_t* index, /* in: index; NOTE that this may also be a
+ dict_index_t* index, /*!< in: index; NOTE that this may also be a
non-clustered index */
- const upd_t* update, /* in: an update vector built for the index so
+ const upd_t* update, /*!< in: an update vector built for the index so
that the field number in an upd_field is the
index position */
ibool order_only,
- /* in: if TRUE, limit the replacement to
+ /*!< in: if TRUE, limit the replacement to
ordering fields of index; note that this
does not work for non-clustered indexes. */
- mem_heap_t* heap) /* in: memory heap for allocating and
+ mem_heap_t* heap) /*!< in: memory heap for allocating and
copying the new values */
{
ulint i;
@@ -1029,23 +1042,23 @@ row_upd_index_replace_new_col_vals_index_pos(
}
}
-/***************************************************************
+/***********************************************************//**
Replaces the new column values stored in the update vector to the index entry
given. */
UNIV_INTERN
void
row_upd_index_replace_new_col_vals(
/*===============================*/
- dtuple_t* entry, /* in/out: index entry where replaced;
+ dtuple_t* entry, /*!< in/out: index entry where replaced;
the clustered index record must be
covered by a lock or a page latch to
prevent deletion (rollback or purge) */
- dict_index_t* index, /* in: index; NOTE that this may also be a
+ dict_index_t* index, /*!< in: index; NOTE that this may also be a
non-clustered index */
- const upd_t* update, /* in: an update vector built for the
+ const upd_t* update, /*!< in: an update vector built for the
CLUSTERED index so that the field number in
an upd_field is the clustered index position */
- mem_heap_t* heap) /* in: memory heap for allocating and
+ mem_heap_t* heap) /*!< in: memory heap for allocating and
copying the new values */
{
ulint i;
@@ -1074,23 +1087,23 @@ row_upd_index_replace_new_col_vals(
}
}
-/***************************************************************
+/***********************************************************//**
Replaces the new column values stored in the update vector. */
UNIV_INTERN
void
row_upd_replace(
/*============*/
- dtuple_t* row, /* in/out: row where replaced,
+ dtuple_t* row, /*!< in/out: row where replaced,
indexed by col_no;
the clustered index record must be
covered by a lock or a page latch to
prevent deletion (rollback or purge) */
- row_ext_t** ext, /* out, own: NULL, or externally
+ row_ext_t** ext, /*!< out, own: NULL, or externally
stored column prefixes */
- const dict_index_t* index, /* in: clustered index */
- const upd_t* update, /* in: an update vector built for the
+ const dict_index_t* index, /*!< in: clustered index */
+ const upd_t* update, /*!< in: an update vector built for the
clustered index */
- mem_heap_t* heap) /* in: memory heap */
+ mem_heap_t* heap) /*!< in: memory heap */
{
ulint col_no;
ulint i;
@@ -1157,25 +1170,23 @@ row_upd_replace(
}
}
-/***************************************************************
+/***********************************************************//**
Checks if an update vector changes an ordering field of an index record.
+
This function is fast if the update vector is short or the number of ordering
fields in the index is small. Otherwise, this can be quadratic.
-NOTE: we compare the fields as binary strings! */
+NOTE: we compare the fields as binary strings!
+@return TRUE if update vector changes an ordering field in the index record */
UNIV_INTERN
ibool
row_upd_changes_ord_field_binary(
/*=============================*/
- /* out: TRUE if update vector changes
- an ordering field in the index record;
- NOTE: the fields are compared as binary
- strings */
- const dtuple_t* row, /* in: old value of row, or NULL if the
+ const dtuple_t* row, /*!< in: old value of row, or NULL if the
row and the data values in update are not
known when this function is called, e.g., at
compile time */
- dict_index_t* index, /* in: index of the record */
- const upd_t* update) /* in: update vector for the row; NOTE: the
+ dict_index_t* index, /*!< in: index of the record */
+ const upd_t* update) /*!< in: update vector for the row; NOTE: the
field numbers in this MUST be clustered index
positions! */
{
@@ -1228,18 +1239,17 @@ row_upd_changes_ord_field_binary(
return(FALSE);
}
-/***************************************************************
+/***********************************************************//**
Checks if an update vector changes an ordering field of an index record.
-NOTE: we compare the fields as binary strings! */
+NOTE: we compare the fields as binary strings!
+@return TRUE if update vector may change an ordering field in an index
+record */
UNIV_INTERN
ibool
row_upd_changes_some_index_ord_field_binary(
/*========================================*/
- /* out: TRUE if update vector
- may change an ordering field
- in an index record */
- const dict_table_t* table, /* in: table */
- const upd_t* update) /* in: update vector for the row */
+ const dict_table_t* table, /*!< in: table */
+ const upd_t* update) /*!< in: update vector for the row */
{
upd_field_t* upd_field;
dict_index_t* index;
@@ -1262,19 +1272,19 @@ row_upd_changes_some_index_ord_field_binary(
return(FALSE);
}
-/***************************************************************
+/***********************************************************//**
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
-that index does not contain column prefixes. */
+that index does not contain column prefixes.
+@return TRUE if changes */
static
ibool
row_upd_changes_first_fields_binary(
/*================================*/
- /* out: TRUE if changes */
- dtuple_t* entry, /* in: index entry */
- dict_index_t* index, /* in: index of entry */
- const upd_t* update, /* in: update vector for the row */
- ulint n) /* in: how many first fields to check */
+ dtuple_t* entry, /*!< in: index entry */
+ dict_index_t* index, /*!< in: index of entry */
+ const upd_t* update, /*!< in: update vector for the row */
+ ulint n) /*!< in: how many first fields to check */
{
ulint n_upd_fields;
ulint i, j;
@@ -1316,15 +1326,15 @@ row_upd_changes_first_fields_binary(
return(FALSE);
}
-/*************************************************************************
+/*********************************************************************//**
Copies the column values from a record. */
UNIV_INLINE
void
row_upd_copy_columns(
/*=================*/
- rec_t* rec, /* in: record in a clustered index */
- const ulint* offsets,/* in: array returned by rec_get_offsets() */
- sym_node_t* column) /* in: first column in a column list, or
+ rec_t* rec, /*!< in: record in a clustered index */
+ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ sym_node_t* column) /*!< in: first column in a column list, or
NULL */
{
byte* data;
@@ -1343,14 +1353,14 @@ row_upd_copy_columns(
}
}
-/*************************************************************************
+/*********************************************************************//**
Calculates the new values for fields to update. Note that row_upd_copy_columns
must have been called first. */
UNIV_INLINE
void
row_upd_eval_new_vals(
/*==================*/
- upd_t* update) /* in/out: update vector */
+ upd_t* update) /*!< in/out: update vector */
{
que_node_t* exp;
upd_field_t* upd_field;
@@ -1370,13 +1380,13 @@ row_upd_eval_new_vals(
}
}
-/***************************************************************
+/***********************************************************//**
Stores to the heap the row on which the node->pcur is positioned. */
static
void
row_upd_store_row(
/*==============*/
- upd_node_t* node) /* in: row update node */
+ upd_node_t* node) /*!< in: row update node */
{
dict_index_t* clust_index;
rec_t* rec;
@@ -1413,16 +1423,16 @@ row_upd_store_row(
}
}
-/***************************************************************
-Updates a secondary index entry of a row. */
+/***********************************************************//**
+Updates a secondary index entry of a row.
+@return DB_SUCCESS if operation successfully completed, else error
+code or DB_LOCK_WAIT */
static
ulint
row_upd_sec_index_entry(
/*====================*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code or DB_LOCK_WAIT */
- upd_node_t* node, /* in: row update node */
- que_thr_t* thr) /* in: query thread */
+ upd_node_t* node, /*!< in: row update node */
+ que_thr_t* thr) /*!< in: query thread */
{
ibool check_ref;
ibool found;
@@ -1517,17 +1527,17 @@ func_exit:
return(err);
}
-/***************************************************************
+/***********************************************************//**
Updates the secondary index record if it is changed in the row update or
-deletes it if this is a delete. */
+deletes it if this is a delete.
+@return DB_SUCCESS if operation successfully completed, else error
+code or DB_LOCK_WAIT */
UNIV_INLINE
ulint
row_upd_sec_step(
/*=============*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code or DB_LOCK_WAIT */
- upd_node_t* node, /* in: row update node */
- que_thr_t* thr) /* in: query thread */
+ upd_node_t* node, /*!< in: row update node */
+ que_thr_t* thr) /*!< in: query thread */
{
ut_ad((node->state == UPD_NODE_UPDATE_ALL_SEC)
|| (node->state == UPD_NODE_UPDATE_SOME_SEC));
@@ -1542,23 +1552,23 @@ row_upd_sec_step(
return(DB_SUCCESS);
}
-/***************************************************************
+/***********************************************************//**
Marks the clustered index record deleted and inserts the updated version
of the record to the index. This function should be used when the ordering
fields of the clustered index record change. This should be quite rare in
-database applications. */
+database applications.
+@return DB_SUCCESS if operation successfully completed, else error
+code or DB_LOCK_WAIT */
static
ulint
row_upd_clust_rec_by_insert(
/*========================*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code or DB_LOCK_WAIT */
- upd_node_t* node, /* in: row update node */
- dict_index_t* index, /* in: clustered index of the record */
- que_thr_t* thr, /* in: query thread */
- ibool check_ref,/* in: TRUE if index may be referenced in
+ upd_node_t* node, /*!< in: row update node */
+ dict_index_t* index, /*!< in: clustered index of the record */
+ que_thr_t* thr, /*!< in: query thread */
+ ibool check_ref,/*!< in: TRUE if index may be referenced in
a foreign key constraint */
- mtr_t* mtr) /* in: mtr; gets committed here */
+ mtr_t* mtr) /*!< in: mtr; gets committed here */
{
mem_heap_t* heap = NULL;
btr_pcur_t* pcur;
@@ -1651,19 +1661,19 @@ row_upd_clust_rec_by_insert(
return(err);
}
-/***************************************************************
+/***********************************************************//**
Updates a clustered index record of a row when the ordering fields do
-not change. */
+not change.
+@return DB_SUCCESS if operation successfully completed, else error
+code or DB_LOCK_WAIT */
static
ulint
row_upd_clust_rec(
/*==============*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code or DB_LOCK_WAIT */
- upd_node_t* node, /* in: row update node */
- dict_index_t* index, /* in: clustered index */
- que_thr_t* thr, /* in: query thread */
- mtr_t* mtr) /* in: mtr; gets committed here */
+ upd_node_t* node, /*!< in: row update node */
+ dict_index_t* index, /*!< in: clustered index */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr; gets committed here */
{
mem_heap_t* heap = NULL;
big_rec_t* big_rec = NULL;
@@ -1754,22 +1764,21 @@ row_upd_clust_rec(
return(err);
}
-/***************************************************************
-Delete marks a clustered index record. */
+/***********************************************************//**
+Delete marks a clustered index record.
+@return DB_SUCCESS if operation successfully completed, else error code */
static
ulint
row_upd_del_mark_clust_rec(
/*=======================*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code */
- upd_node_t* node, /* in: row update node */
- dict_index_t* index, /* in: clustered index */
- ulint* offsets,/* in/out: rec_get_offsets() for the
+ upd_node_t* node, /*!< in: row update node */
+ dict_index_t* index, /*!< in: clustered index */
+ ulint* offsets,/*!< in/out: rec_get_offsets() for the
record under the cursor */
- que_thr_t* thr, /* in: query thread */
- ibool check_ref,/* in: TRUE if index may be referenced in
+ que_thr_t* thr, /*!< in: query thread */
+ ibool check_ref,/*!< in: TRUE if index may be referenced in
a foreign key constraint */
- mtr_t* mtr) /* in: mtr; gets committed here */
+ mtr_t* mtr) /*!< in: mtr; gets committed here */
{
btr_pcur_t* pcur;
btr_cur_t* btr_cur;
@@ -1806,17 +1815,16 @@ row_upd_del_mark_clust_rec(
return(err);
}
-/***************************************************************
-Updates the clustered index record. */
+/***********************************************************//**
+Updates the clustered index record.
+@return DB_SUCCESS if operation successfully completed, DB_LOCK_WAIT
+in case of a lock wait, else error code */
static
ulint
row_upd_clust_step(
/*===============*/
- /* out: DB_SUCCESS if operation successfully
- completed, DB_LOCK_WAIT in case of a lock wait,
- else error code */
- upd_node_t* node, /* in: row update node */
- que_thr_t* thr) /* in: query thread */
+ upd_node_t* node, /*!< in: row update node */
+ que_thr_t* thr) /*!< in: query thread */
{
dict_index_t* index;
btr_pcur_t* pcur;
@@ -1976,18 +1984,18 @@ exit_func:
return(err);
}
-/***************************************************************
+/***********************************************************//**
Updates the affected index records of a row. When the control is transferred
to this node, we assume that we have a persistent cursor which was on a
-record, and the position of the cursor is stored in the cursor. */
+record, and the position of the cursor is stored in the cursor.
+@return DB_SUCCESS if operation successfully completed, else error
+code or DB_LOCK_WAIT */
static
ulint
row_upd(
/*====*/
- /* out: DB_SUCCESS if operation successfully
- completed, else error code or DB_LOCK_WAIT */
- upd_node_t* node, /* in: row update node */
- que_thr_t* thr) /* in: query thread */
+ upd_node_t* node, /*!< in: row update node */
+ que_thr_t* thr) /*!< in: query thread */
{
ulint err = DB_SUCCESS;
@@ -2052,15 +2060,15 @@ function_exit:
return(err);
}
-/***************************************************************
+/***********************************************************//**
Updates a row in a table. This is a high-level function used in SQL execution
-graphs. */
+graphs.
+@return query thread to run next or NULL */
UNIV_INTERN
que_thr_t*
row_upd_step(
/*=========*/
- /* out: query thread to run next or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
upd_node_t* node;
sel_node_t* sel_node;
@@ -2166,3 +2174,4 @@ error_handling:
return(thr);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/row/row0vers.c b/storage/xtradb/row/row0vers.c
index 3abba6d6fb8..a4fbb5289aa 100644
--- a/storage/xtradb/row/row0vers.c
+++ b/storage/xtradb/row/row0vers.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file row/row0vers.c
Row versions
Created 2/6/1997 Heikki Tuuri
@@ -45,26 +46,24 @@ Created 2/6/1997 Heikki Tuuri
#include "read0read.h"
#include "lock0lock.h"
-/*********************************************************************
+/*****************************************************************//**
Finds out if an active transaction has inserted or modified a secondary
index record. NOTE: the kernel mutex is temporarily released in this
-function! */
+function!
+@return NULL if committed, else the active transaction */
UNIV_INTERN
trx_t*
row_vers_impl_x_locked_off_kernel(
/*==============================*/
- /* out: NULL if committed, else the active
- transaction; NOTE that the kernel mutex is
- temporarily released! */
- const rec_t* rec, /* in: record in a secondary index */
- dict_index_t* index, /* in: the secondary index */
- const ulint* offsets)/* in: rec_get_offsets(rec, index) */
+ const rec_t* rec, /*!< in: record in a secondary index */
+ dict_index_t* index, /*!< in: the secondary index */
+ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */
{
dict_index_t* clust_index;
rec_t* clust_rec;
ulint* clust_offsets;
rec_t* version;
- dulint trx_id;
+ trx_id_t trx_id;
mem_heap_t* heap;
mem_heap_t* heap2;
dtuple_t* row;
@@ -157,7 +156,7 @@ row_vers_impl_x_locked_off_kernel(
rec_t* prev_version;
ulint vers_del;
row_ext_t* ext;
- dulint prev_trx_id;
+ trx_id_t prev_trx_id;
mutex_exit(&kernel_mutex);
@@ -298,17 +297,18 @@ exit_func:
return(trx);
}
-/*********************************************************************
+/*****************************************************************//**
Finds out if we must preserve a delete marked earlier version of a clustered
-index record, because it is >= the purge view. */
+index record, because it is >= the purge view.
+@return TRUE if earlier version should be preserved */
UNIV_INTERN
ibool
row_vers_must_preserve_del_marked(
/*==============================*/
- /* out: TRUE if earlier version should be preserved */
- dulint trx_id, /* in: transaction id in the version */
- mtr_t* mtr) /* in: mtr holding the latch on the clustered index
- record; it will also hold the latch on purge_view */
+ trx_id_t trx_id, /*!< in: transaction id in the version */
+ mtr_t* mtr) /*!< in: mtr holding the latch on the
+ clustered index record; it will also
+ hold the latch on purge_view */
{
#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
@@ -327,26 +327,26 @@ row_vers_must_preserve_del_marked(
return(FALSE);
}
-/*********************************************************************
+/*****************************************************************//**
Finds out if a version of the record, where the version >= the current
purge view, should have ientry as its secondary index entry. We check
if there is any not delete marked version of the record where the trx
id >= purge view, and the secondary index entry and ientry are identified in
-the alphabetical ordering; exactly in this case we return TRUE. */
+the alphabetical ordering; exactly in this case we return TRUE.
+@return TRUE if earlier version should have */
UNIV_INTERN
ibool
row_vers_old_has_index_entry(
/*=========================*/
- /* out: TRUE if earlier version should have */
- ibool also_curr,/* in: TRUE if also rec is included in the
+ ibool also_curr,/*!< in: TRUE if also rec is included in the
versions to search; otherwise only versions
prior to it are searched */
- const rec_t* rec, /* in: record in the clustered index; the
+ const rec_t* rec, /*!< in: record in the clustered index; the
caller must have a latch on the page */
- mtr_t* mtr, /* in: mtr holding the latch on rec; it will
+ mtr_t* mtr, /*!< in: mtr holding the latch on rec; it will
also hold the latch on purge_view */
- dict_index_t* index, /* in: the secondary index */
- const dtuple_t* ientry) /* in: the secondary index entry */
+ dict_index_t* index, /*!< in: the secondary index */
+ const dtuple_t* ientry) /*!< in: the secondary index entry */
{
const rec_t* version;
rec_t* prev_version;
@@ -469,37 +469,37 @@ row_vers_old_has_index_entry(
}
}
-/*********************************************************************
+/*****************************************************************//**
Constructs the version of a clustered index record which a consistent
read should see. We assume that the trx id stored in rec is such that
-the consistent read should not see rec in its present version. */
+the consistent read should not see rec in its present version.
+@return DB_SUCCESS or DB_MISSING_HISTORY */
UNIV_INTERN
ulint
row_vers_build_for_consistent_read(
/*===============================*/
- /* out: DB_SUCCESS or DB_MISSING_HISTORY */
- const rec_t* rec, /* in: record in a clustered index; the
+ const rec_t* rec, /*!< in: record in a clustered index; the
caller must have a latch on the page; this
latch locks the top of the stack of versions
of this records */
- mtr_t* mtr, /* in: mtr holding the latch on rec */
- dict_index_t* index, /* in: the clustered index */
- ulint** offsets,/* in/out: offsets returned by
+ mtr_t* mtr, /*!< in: mtr holding the latch on rec */
+ dict_index_t* index, /*!< in: the clustered index */
+ ulint** offsets,/*!< in/out: offsets returned by
rec_get_offsets(rec, index) */
- read_view_t* view, /* in: the consistent read view */
- mem_heap_t** offset_heap,/* in/out: memory heap from which
+ read_view_t* view, /*!< in: the consistent read view */
+ mem_heap_t** offset_heap,/*!< in/out: memory heap from which
the offsets are allocated */
- mem_heap_t* in_heap,/* in: memory heap from which the memory for
+ mem_heap_t* in_heap,/*!< in: memory heap from which the memory for
*old_vers is allocated; memory for possible
intermediate versions is allocated and freed
locally within the function */
- rec_t** old_vers)/* out, own: old version, or NULL if the
+ rec_t** old_vers)/*!< out, own: old version, or NULL if the
record does not exist in the view, that is,
it was freshly inserted afterwards */
{
const rec_t* version;
rec_t* prev_version;
- dulint trx_id;
+ trx_id_t trx_id;
mem_heap_t* heap = NULL;
byte* buf;
ulint err;
@@ -523,8 +523,8 @@ row_vers_build_for_consistent_read(
for (;;) {
mem_heap_t* heap2 = heap;
trx_undo_rec_t* undo_rec;
- dulint roll_ptr;
- dulint undo_no;
+ roll_ptr_t roll_ptr;
+ undo_no_t undo_no;
heap = mem_heap_create(1024);
/* If we have high-granularity consistent read view and
@@ -602,29 +602,29 @@ row_vers_build_for_consistent_read(
return(err);
}
-/*********************************************************************
+/*****************************************************************//**
Constructs the last committed version of a clustered index record,
-which should be seen by a semi-consistent read. */
+which should be seen by a semi-consistent read.
+@return DB_SUCCESS or DB_MISSING_HISTORY */
UNIV_INTERN
ulint
row_vers_build_for_semi_consistent_read(
/*====================================*/
- /* out: DB_SUCCESS or DB_MISSING_HISTORY */
- const rec_t* rec, /* in: record in a clustered index; the
+ const rec_t* rec, /*!< in: record in a clustered index; the
caller must have a latch on the page; this
latch locks the top of the stack of versions
of this records */
- mtr_t* mtr, /* in: mtr holding the latch on rec */
- dict_index_t* index, /* in: the clustered index */
- ulint** offsets,/* in/out: offsets returned by
+ mtr_t* mtr, /*!< in: mtr holding the latch on rec */
+ dict_index_t* index, /*!< in: the clustered index */
+ ulint** offsets,/*!< in/out: offsets returned by
rec_get_offsets(rec, index) */
- mem_heap_t** offset_heap,/* in/out: memory heap from which
+ mem_heap_t** offset_heap,/*!< in/out: memory heap from which
the offsets are allocated */
- mem_heap_t* in_heap,/* in: memory heap from which the memory for
+ mem_heap_t* in_heap,/*!< in: memory heap from which the memory for
*old_vers is allocated; memory for possible
intermediate versions is allocated and freed
locally within the function */
- const rec_t** old_vers)/* out: rec, old version, or NULL if the
+ const rec_t** old_vers)/*!< out: rec, old version, or NULL if the
record does not exist in the view, that is,
it was freshly inserted afterwards */
{
@@ -632,7 +632,7 @@ row_vers_build_for_semi_consistent_read(
mem_heap_t* heap = NULL;
byte* buf;
ulint err;
- dulint rec_trx_id = ut_dulint_zero;
+ trx_id_t rec_trx_id = ut_dulint_zero;
ut_ad(dict_index_is_clust(index));
ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
@@ -655,7 +655,7 @@ row_vers_build_for_semi_consistent_read(
trx_t* version_trx;
mem_heap_t* heap2;
rec_t* prev_version;
- dulint version_trx_id;
+ trx_id_t version_trx_id;
version_trx_id = row_get_rec_trx_id(version, index, *offsets);
if (rec == version) {
diff --git a/storage/xtradb/srv/srv0que.c b/storage/xtradb/srv/srv0que.c
index 344aaed8775..fc50a86a55c 100644
--- a/storage/xtradb/srv/srv0que.c
+++ b/storage/xtradb/srv/srv0que.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file srv/srv0que.c
Server query execution
Created 6/5/1996 Heikki Tuuri
@@ -30,72 +31,14 @@ Created 6/5/1996 Heikki Tuuri
#include "usr0sess.h"
#include "que0que.h"
-/**************************************************************************
-Checks if there is work to do in the server task queue. If there is, the
-thread starts processing a task. Before leaving, it again checks the task
-queue and picks a new task if any exists. This is called by a SRV_WORKER
-thread. */
-UNIV_INTERN
-void
-srv_que_task_queue_check(void)
-/*==========================*/
-{
- que_thr_t* thr;
-
- for (;;) {
- mutex_enter(&kernel_mutex);
-
- thr = UT_LIST_GET_FIRST(srv_sys->tasks);
-
- if (thr == NULL) {
- mutex_exit(&kernel_mutex);
-
- return;
- }
-
- UT_LIST_REMOVE(queue, srv_sys->tasks, thr);
-
- mutex_exit(&kernel_mutex);
-
- que_run_threads(thr);
- }
-}
-
-/**************************************************************************
-Performs round-robin on the server tasks. This is called by a SRV_WORKER
-thread every second or so. */
-UNIV_INTERN
-que_thr_t*
-srv_que_round_robin(
-/*================*/
- /* out: the new (may be == thr) query thread
- to run */
- que_thr_t* thr) /* in: query thread */
-{
- que_thr_t* new_thr;
-
- ut_ad(thr);
- ut_ad(thr->state == QUE_THR_RUNNING);
-
- mutex_enter(&kernel_mutex);
-
- UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr);
-
- new_thr = UT_LIST_GET_FIRST(srv_sys->tasks);
-
- mutex_exit(&kernel_mutex);
-
- return(new_thr);
-}
-
-/**************************************************************************
+/**********************************************************************//**
Enqueues a task to server task queue and releases a worker thread, if there
is a suspended one. */
UNIV_INTERN
void
srv_que_task_enqueue_low(
/*=====================*/
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
ut_ad(thr);
ut_ad(mutex_own(&kernel_mutex));
@@ -104,23 +47,3 @@ srv_que_task_enqueue_low(
srv_release_threads(SRV_WORKER, 1);
}
-
-/**************************************************************************
-Enqueues a task to server task queue and releases a worker thread, if there
-is a suspended one. */
-UNIV_INTERN
-void
-srv_que_task_enqueue(
-/*=================*/
- que_thr_t* thr) /* in: query thread */
-{
- ut_ad(thr);
-
- ut_a(0); /* Under MySQL this is never called */
-
- mutex_enter(&kernel_mutex);
-
- srv_que_task_enqueue_low(thr);
-
- mutex_exit(&kernel_mutex);
-}
diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c
index 35b80d72615..5768249fc8d 100644
--- a/storage/xtradb/srv/srv0srv.c
+++ b/storage/xtradb/srv/srv0srv.c
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
-Copyright (c) 2008, Google Inc.
+Copyright (c) 2008, 2009 Google Inc.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -22,8 +22,35 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
+
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+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
+
+***********************************************************************/
+
+/**************************************************//**
+@file srv/srv0srv.c
The database server main program
NOTE: SQL Server 7 uses something which the documentation
@@ -96,7 +123,7 @@ UNIV_INTERN ibool srv_error_monitor_active = FALSE;
UNIV_INTERN const char* srv_main_thread_op_info = "";
-/* Prefix used by MySQL to indicate pre-5.1 table name encoding */
+/** Prefix used by MySQL to indicate pre-5.1 table name encoding */
UNIV_INTERN const char srv_mysql50_table_name_prefix[9] = "#mysql50#";
/* Server parameters which are read from the initfile */
@@ -109,12 +136,12 @@ UNIV_INTERN char* srv_data_home = NULL;
UNIV_INTERN char* srv_arch_dir = NULL;
#endif /* UNIV_LOG_ARCHIVE */
-/* store to its own file each table created by an user; data
+/** store to its own file each table created by an user; data
dictionary tables are in the system tablespace 0 */
UNIV_INTERN my_bool srv_file_per_table;
-/* The file format to use on new *.ibd files. */
+/** The file format to use on new *.ibd files. */
UNIV_INTERN ulint srv_file_format = 0;
-/* Whether to check file format during startup a value of
+/** Whether to check file format during startup. A value of
DICT_TF_FORMAT_MAX + 1 means no checking ie. FALSE. The default is to
set it to the highest format we support. */
UNIV_INTERN ulint srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX;
@@ -122,7 +149,7 @@ UNIV_INTERN ulint srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX;
#if DICT_TF_FORMAT_51
# error "DICT_TF_FORMAT_51 must be 0!"
#endif
-/* Place locks to records only i.e. do not use next-key locking except
+/** Place locks to records only i.e. do not use next-key locking except
on duplicate key checking and foreign key checking */
UNIV_INTERN ibool srv_locks_unsafe_for_binlog = FALSE;
@@ -135,6 +162,8 @@ UNIV_INTERN ibool srv_extra_undoslots = FALSE;
UNIV_INTERN ibool srv_fast_recovery = FALSE;
+UNIV_INTERN ibool srv_use_purge_thread = FALSE;
+
/* if TRUE, then we auto-extend the last data file */
UNIV_INTERN ibool srv_auto_extend_last_data_file = FALSE;
/* if != 0, this tells the max size auto-extending may increase the
@@ -160,6 +189,10 @@ UNIV_INTERN ulint srv_log_file_size = ULINT_MAX;
UNIV_INTERN ulint srv_log_buffer_size = ULINT_MAX;
UNIV_INTERN ulong srv_flush_log_at_trx_commit = 1;
+/* Try to flush dirty pages so as to avoid IO bursts at
+the checkpoints. */
+UNIV_INTERN char srv_adaptive_flushing = TRUE;
+
UNIV_INTERN ulong srv_show_locks_held = 10;
UNIV_INTERN ulong srv_show_verbose_locks = 0;
@@ -180,9 +213,16 @@ 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;
+/* This parameter is deprecated. Use srv_n_io_[read|write]_threads
+instead. */
UNIV_INTERN ulint srv_n_file_io_threads = ULINT_MAX;
-UNIV_INTERN ulint srv_n_read_io_threads = 1;
-UNIV_INTERN ulint srv_n_write_io_threads = 1;
+UNIV_INTERN ulint srv_n_read_io_threads = ULINT_MAX;
+UNIV_INTERN ulint srv_n_write_io_threads = ULINT_MAX;
+
+/* User settable value of the number of pages that must be present
+in the buffer cache and accessed sequentially for InnoDB to trigger a
+readahead request. */
+UNIV_INTERN ulong srv_read_ahead_threshold = 56;
#ifdef UNIV_LOG_ARCHIVE
UNIV_INTERN ibool srv_log_archive_on = FALSE;
@@ -206,12 +246,15 @@ UNIV_INTERN ulint srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
UNIV_INTERN ulint srv_max_n_open_files = 300;
+/* Number of IO operations per second the server can do */
+UNIV_INTERN ulong srv_io_capacity = 200;
+
/* The InnoDB main thread tries to keep the ratio of modified pages
in the buffer pool to all database pages in the buffer pool smaller than
the following number. But it is not guaranteed that the value stays below
that during a time of heavy update/insert activity. */
-UNIV_INTERN ulong srv_max_buf_pool_modified_pct = 90;
+UNIV_INTERN ulong srv_max_buf_pool_modified_pct = 75;
/* variable counts amount of data read in total (in bytes) */
UNIV_INTERN ulint srv_data_read = 0;
@@ -255,14 +298,14 @@ UNIV_INTERN ulint srv_buf_pool_wait_free = 0;
pool to the disk */
UNIV_INTERN ulint srv_buf_pool_flushed = 0;
-/* variable to count the number of buffer pool reads that led to the
+/** Number of buffer pool reads that led to the
reading of a disk page */
UNIV_INTERN ulint srv_buf_pool_reads = 0;
-/* variable to count the number of sequential read-aheads */
+/** Number of sequential read-aheads */
UNIV_INTERN ulint srv_read_ahead_seq = 0;
-/* variable to count the number of random read-aheads */
+/** Number of random read-aheads */
UNIV_INTERN ulint srv_read_ahead_rnd = 0;
/* structure to pass status variables to MySQL */
@@ -303,17 +346,17 @@ UNIV_INTERN ulint srv_conc_n_waiting_threads = 0;
typedef struct srv_conc_slot_struct srv_conc_slot_t;
struct srv_conc_slot_struct{
- os_event_t event; /* event to wait */
- ibool reserved; /* TRUE if slot
+ os_event_t event; /*!< event to wait */
+ ibool reserved; /*!< TRUE if slot
reserved */
- ibool wait_ended; /* TRUE when another
+ ibool wait_ended; /*!< TRUE when another
thread has already set
the event and the
thread in this slot is
free to proceed; but
reserved may still be
TRUE at that point */
- UT_LIST_NODE_T(srv_conc_slot_t) srv_conc_queue; /* queue node */
+ UT_LIST_NODE_T(srv_conc_slot_t) srv_conc_queue; /*!< queue node */
};
/* queue of threads waiting to get in */
@@ -340,6 +383,7 @@ this many index pages */
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_doublewrite_buf = TRUE;
UNIV_INTERN ibool srv_use_checksums = TRUE;
@@ -349,13 +393,6 @@ UNIV_INTERN int srv_query_thread_priority = 0;
UNIV_INTERN ulong srv_replication_delay = 0;
-UNIV_INTERN ulong srv_io_capacity = 100;
-
-/* Returns the number of IO operations that is X percent of the capacity.
-PCT_IO(5) -> returns the number of IO operations that is 5% of the max
-where max is srv_io_capacity. */
-#define PCT_IO(pct) ((ulint) (srv_io_capacity * ((double) pct / 100.0)))
-
UNIV_INTERN long long srv_ibuf_max_size = 0;
UNIV_INTERN ulong srv_ibuf_active_contract = 0; /* 0:disable 1:enable */
UNIV_INTERN ulong srv_ibuf_accel_rate = 100;
@@ -372,11 +409,10 @@ UNIV_INTERN ulong srv_expand_import = 0; /* 0:disable 1:enable */
UNIV_INTERN ulong srv_extra_rsegments = 0; /* extra rseg for users */
UNIV_INTERN ulong srv_dict_size_limit = 0;
/*-------------------------------------------*/
-UNIV_INTERN ulong srv_n_spin_wait_rounds = 20;
+UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500;
UNIV_INTERN ulong srv_thread_sleep_delay = 10000;
-UNIV_INTERN ulint srv_spin_wait_delay = 5;
-UNIV_INTERN ulint srv_spins_microsec = 50;
+UNIV_INTERN ulong srv_spin_wait_delay = 6;
UNIV_INTERN ibool srv_priority_boost = TRUE;
#ifdef UNIV_DEBUG
@@ -391,12 +427,11 @@ UNIV_INTERN ulint srv_n_rows_inserted = 0;
UNIV_INTERN ulint srv_n_rows_updated = 0;
UNIV_INTERN ulint srv_n_rows_deleted = 0;
UNIV_INTERN ulint srv_n_rows_read = 0;
-#ifndef UNIV_HOTBACKUP
+
static ulint srv_n_rows_inserted_old = 0;
static ulint srv_n_rows_updated_old = 0;
static ulint srv_n_rows_deleted_old = 0;
static ulint srv_n_rows_read_old = 0;
-#endif /* !UNIV_HOTBACKUP */
UNIV_INTERN ulint srv_n_lock_wait_count = 0;
UNIV_INTERN ulint srv_n_lock_wait_current_count = 0;
@@ -444,6 +479,36 @@ UNIV_INTERN FILE* srv_misc_tmpfile;
UNIV_INTERN ulint srv_main_thread_process_no = 0;
UNIV_INTERN ulint srv_main_thread_id = 0;
+/* The following count work done by srv_master_thread. */
+
+/* Iterations by the 'once per second' loop. */
+static ulint srv_main_1_second_loops = 0;
+/* Calls to sleep by the 'once per second' loop. */
+static ulint srv_main_sleeps = 0;
+/* Iterations by the 'once per 10 seconds' loop. */
+static ulint srv_main_10_second_loops = 0;
+/* Iterations of the loop bounded by the 'background_loop' label. */
+static ulint srv_main_background_loops = 0;
+/* Iterations of the loop bounded by the 'flush_loop' label. */
+static ulint srv_main_flush_loops = 0;
+/* Log writes involving flush. */
+static ulint srv_log_writes_and_flush = 0;
+/* Log writes not including flush. */
+static ulint srv_log_buffer_writes = 0;
+
+/* This is only ever touched by the master thread. It records the
+time when the last flush of log file has happened. The master
+thread ensures that we flush the log files at least once per
+second. */
+static time_t srv_last_log_flush_time;
+
+/* The master thread performs various tasks based on the current
+state of IO activity and the level of IO utilization is past
+intervals. Following macros define thresholds for these conditions. */
+#define SRV_PEND_IO_THRESHOLD (PCT_IO(3))
+#define SRV_RECENT_IO_ACTIVITY (PCT_IO(5))
+#define SRV_PAST_IO_ACTIVITY (PCT_IO(200))
+
/*
IMPLEMENTATION OF THE SERVER MAIN PROGRAM
=========================================
@@ -614,17 +679,17 @@ Unix.*/
/* Thread slot in the thread table */
struct srv_slot_struct{
- os_thread_id_t id; /* thread id */
- os_thread_t handle; /* thread handle */
- unsigned type:3; /* thread type: user, utility etc. */
- unsigned in_use:1; /* TRUE if this slot is in use */
- unsigned suspended:1; /* TRUE if the thread is waiting
+ os_thread_id_t id; /*!< thread id */
+ os_thread_t handle; /*!< thread handle */
+ unsigned type:3; /*!< thread type: user, utility etc. */
+ unsigned in_use:1; /*!< TRUE if this slot is in use */
+ unsigned suspended:1; /*!< TRUE if the thread is waiting
for the event of this slot */
- ib_time_t suspend_time; /* time when the thread was
+ ib_time_t suspend_time; /*!< time when the thread was
suspended */
- os_event_t event; /* event used in suspending the
+ os_event_t event; /*!< event used in suspending the
thread when it has nothing to do */
- que_thr_t* thr; /* suspended query thread (only
+ que_thr_t* thr; /*!< suspended query thread (only
used for MySQL threads) */
};
@@ -665,55 +730,32 @@ are indexed by the type of the thread. */
UNIV_INTERN ulint srv_n_threads_active[SRV_MASTER + 1];
UNIV_INTERN ulint srv_n_threads[SRV_MASTER + 1];
+/***********************************************************************
+Prints counters for work done by srv_master_thread. */
static
void
-srv_align_spins_microsec(void)
+srv_print_master_thread_info(
+/*=========================*/
+ FILE *file) /* in: output stream */
{
- ulint start_sec, end_sec;
- ulint start_usec, end_usec;
- ib_uint64_t usecs;
-
- /* change temporary */
- srv_spins_microsec = 1;
-
- if (ut_usectime(&start_sec, &start_usec)) {
- srv_spins_microsec = 50;
- goto end;
- }
-
- ut_delay(100000);
-
- if (ut_usectime(&end_sec, &end_usec)) {
- srv_spins_microsec = 50;
- goto end;
- }
-
- usecs = (end_sec - start_sec) * 1000000LL + (end_usec - start_usec);
-
- if (usecs) {
- srv_spins_microsec = 100000 / usecs;
- if (srv_spins_microsec == 0)
- srv_spins_microsec = 1;
- if (srv_spins_microsec > 50)
- srv_spins_microsec = 50;
- } else {
- srv_spins_microsec = 50;
- }
-end:
- if (srv_spins_microsec != 50)
- fprintf(stderr,
- "InnoDB: unit of spin count at ut_delay() is aligned to %lu\n",
- srv_spins_microsec);
+ fprintf(file, "srv_master_thread loops: %lu 1_second, %lu sleeps, "
+ "%lu 10_second, %lu background, %lu flush\n",
+ srv_main_1_second_loops, srv_main_sleeps,
+ srv_main_10_second_loops, srv_main_background_loops,
+ srv_main_flush_loops);
+ fprintf(file, "srv_master_thread log flush and writes: %lu "
+ " log writes only: %lu\n",
+ srv_log_writes_and_flush, srv_log_buffer_writes);
}
-/*************************************************************************
+/*********************************************************************//**
Sets the info describing an i/o thread current state. */
UNIV_INTERN
void
srv_set_io_thread_op_info(
/*======================*/
- ulint i, /* in: the 'segment' of the i/o thread */
- const char* str) /* in: constant char string describing the
+ ulint i, /*!< in: the 'segment' of the i/o thread */
+ const char* str) /*!< in: constant char string describing the
state */
{
ut_a(i < SRV_MAX_N_IO_THREADS);
@@ -721,24 +763,24 @@ srv_set_io_thread_op_info(
srv_io_thread_op_info[i] = str;
}
-/*************************************************************************
+/*********************************************************************//**
Accessor function to get pointer to n'th slot in the server thread
-table. */
+table.
+@return pointer to the slot */
static
srv_slot_t*
srv_table_get_nth_slot(
/*===================*/
- /* out: pointer to the slot */
- ulint index) /* in: index of the slot */
+ ulint index) /*!< in: index of the slot */
{
ut_a(index < OS_THREAD_MAX_N);
return(srv_sys->threads + index);
}
-#ifndef UNIV_HOTBACKUP
-/*************************************************************************
-Gets the number of threads in the system. */
+/*********************************************************************//**
+Gets the number of threads in the system.
+@return sum of srv_n_threads[] */
UNIV_INTERN
ulint
srv_get_n_threads(void)
@@ -759,16 +801,16 @@ srv_get_n_threads(void)
return(n_threads);
}
-/*************************************************************************
+/*********************************************************************//**
Reserves a slot in the thread table for the current thread. Also creates the
thread local storage struct for the current thread. NOTE! The server mutex
-has to be reserved by the caller! */
+has to be reserved by the caller!
+@return reserved slot index */
static
ulint
srv_table_reserve_slot(
/*===================*/
- /* out: reserved slot index */
- enum srv_thread_type type) /* in: type of the thread */
+ enum srv_thread_type type) /*!< in: type of the thread */
{
srv_slot_t* slot;
ulint i;
@@ -799,14 +841,14 @@ srv_table_reserve_slot(
return(i);
}
-/*************************************************************************
+/*********************************************************************//**
Suspends the calling thread to wait for the event in its thread slot.
-NOTE! The server mutex has to be reserved by the caller! */
+NOTE! The server mutex has to be reserved by the caller!
+@return event for the calling thread to wait */
static
os_event_t
srv_suspend_thread(void)
/*====================*/
- /* out: event for the calling thread to wait */
{
srv_slot_t* slot;
os_event_t event;
@@ -842,21 +884,18 @@ srv_suspend_thread(void)
return(event);
}
-#endif /* !UNIV_HOTBACKUP */
-/*************************************************************************
+/*********************************************************************//**
Releases threads of the type given from suspension in the thread table.
-NOTE! The server mutex has to be reserved by the caller! */
+NOTE! The server mutex has to be reserved by the caller!
+@return number of threads released: this may be less than n if not
+enough threads were suspended at the moment */
UNIV_INTERN
ulint
srv_release_threads(
/*================*/
- /* out: number of threads
- released: this may be < n if
- not enough threads were
- suspended at the moment */
- enum srv_thread_type type, /* in: thread type */
- ulint n) /* in: number of threads to release */
+ enum srv_thread_type type, /*!< in: thread type */
+ ulint n) /*!< in: number of threads to release */
{
srv_slot_t* slot;
ulint i;
@@ -898,13 +937,13 @@ srv_release_threads(
return(count);
}
-/*************************************************************************
-Returns the calling thread type. */
+/*********************************************************************//**
+Returns the calling thread type.
+@return SRV_COM, ... */
UNIV_INTERN
enum srv_thread_type
srv_get_thread_type(void)
/*=====================*/
- /* out: SRV_COM, ... */
{
ulint slot_no;
srv_slot_t* slot;
@@ -926,7 +965,7 @@ srv_get_thread_type(void)
return(type);
}
-/*************************************************************************
+/*********************************************************************//**
Initializes the server. */
UNIV_INTERN
void
@@ -935,11 +974,8 @@ srv_init(void)
{
srv_conc_slot_t* conc_slot;
srv_slot_t* slot;
- dict_table_t* table;
ulint i;
- srv_align_spins_microsec();
-
srv_sys = mem_alloc(sizeof(srv_sys_t));
kernel_mutex_temp = mem_alloc(sizeof(mutex_t));
@@ -983,30 +1019,9 @@ srv_init(void)
UT_LIST_INIT(srv_sys->tasks);
- /* create dummy table and index for old-style infimum and supremum */
- table = dict_mem_table_create("SYS_DUMMY1",
- DICT_HDR_SPACE, 1, 0);
- dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
- DATA_ENGLISH | DATA_NOT_NULL, 8);
-
- srv_sys->dummy_ind1 = dict_mem_index_create(
- "SYS_DUMMY1", "SYS_DUMMY1", DICT_HDR_SPACE, 0, 1);
- dict_index_add_col(srv_sys->dummy_ind1, table,
- dict_table_get_nth_col(table, 0), 0);
- srv_sys->dummy_ind1->table = table;
- /* create dummy table and index for new-style infimum and supremum */
- table = dict_mem_table_create("SYS_DUMMY2",
- DICT_HDR_SPACE, 1, DICT_TF_COMPACT);
- dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
- DATA_ENGLISH | DATA_NOT_NULL, 8);
- srv_sys->dummy_ind2 = dict_mem_index_create(
- "SYS_DUMMY2", "SYS_DUMMY2", DICT_HDR_SPACE, 0, 1);
- dict_index_add_col(srv_sys->dummy_ind2, table,
- dict_table_get_nth_col(table, 0), 0);
- srv_sys->dummy_ind2->table = table;
-
- /* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
- srv_sys->dummy_ind1->cached = srv_sys->dummy_ind2->cached = TRUE;
+ /* Create dummy indexes for infimum and supremum records */
+
+ dict_ind_init();
/* Init the server concurrency restriction data structures */
@@ -1027,7 +1042,7 @@ srv_init(void)
trx_i_s_cache_init(trx_i_s_cache);
}
-/*************************************************************************
+/*********************************************************************//**
Frees the OS fast mutex created in srv_init(). */
UNIV_INTERN
void
@@ -1037,7 +1052,7 @@ srv_free(void)
os_fast_mutex_free(&srv_conc_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
Initializes the synchronization primitives, memory system, and the thread
local storage. */
UNIV_INTERN
@@ -1057,7 +1072,7 @@ srv_general_init(void)
/* Maximum allowable purge history length. <=0 means 'infinite'. */
UNIV_INTERN ulong srv_max_purge_lag = 0;
-/*************************************************************************
+/*********************************************************************//**
Puts an OS thread to wait if there are too many concurrent threads
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
@@ -1133,7 +1148,7 @@ UNIV_INTERN
void
srv_conc_enter_innodb(
/*==================*/
- trx_t* trx) /* in: transaction object associated with the
+ trx_t* trx) /*!< in: transaction object associated with the
thread */
{
ibool has_slept = FALSE;
@@ -1293,14 +1308,14 @@ retry:
os_fast_mutex_unlock(&srv_conc_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
This lets a thread enter InnoDB regardless of the number of threads inside
InnoDB. This must be called when a thread ends a lock wait. */
UNIV_INTERN
void
srv_conc_force_enter_innodb(
/*========================*/
- trx_t* trx) /* in: transaction object associated with the
+ trx_t* trx) /*!< in: transaction object associated with the
thread */
{
if (UNIV_LIKELY(!srv_thread_concurrency)) {
@@ -1327,14 +1342,14 @@ srv_conc_force_enter_innodb(
os_fast_mutex_unlock(&srv_conc_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
This must be called when a thread exits InnoDB in a lock wait or at the
end of an SQL statement. */
UNIV_INTERN
void
srv_conc_force_exit_innodb(
/*=======================*/
- trx_t* trx) /* in: transaction object associated with the
+ trx_t* trx) /*!< in: transaction object associated with the
thread */
{
srv_conc_slot_t* slot = NULL;
@@ -1391,13 +1406,13 @@ srv_conc_force_exit_innodb(
}
}
-/*************************************************************************
+/*********************************************************************//**
This must be called when a thread exits InnoDB. */
UNIV_INTERN
void
srv_conc_exit_innodb(
/*=================*/
- trx_t* trx) /* in: transaction object associated with the
+ trx_t* trx) /*!< in: transaction object associated with the
thread */
{
if (trx->n_tickets_to_enter_innodb > 0) {
@@ -1416,13 +1431,13 @@ srv_conc_exit_innodb(
/*========================================================================*/
-/*************************************************************************
-Normalizes init parameter values to use units we use inside InnoDB. */
+/*********************************************************************//**
+Normalizes init parameter values to use units we use inside InnoDB.
+@return DB_SUCCESS or error code */
static
ulint
srv_normalize_init_values(void)
/*===========================*/
- /* out: DB_SUCCESS or error code */
{
ulint n;
ulint i;
@@ -1446,13 +1461,13 @@ srv_normalize_init_values(void)
return(DB_SUCCESS);
}
-/*************************************************************************
-Boots the InnoDB server. */
+/*********************************************************************//**
+Boots the InnoDB server.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
srv_boot(void)
/*==========*/
- /* out: DB_SUCCESS or error code */
{
ulint err;
@@ -1477,15 +1492,14 @@ srv_boot(void)
return(DB_SUCCESS);
}
-#ifndef UNIV_HOTBACKUP
-/*************************************************************************
+/*********************************************************************//**
Reserves a slot in the thread table for the current MySQL OS thread.
-NOTE! The kernel mutex has to be reserved by the caller! */
+NOTE! The kernel mutex has to be reserved by the caller!
+@return reserved slot */
static
srv_slot_t*
srv_table_reserve_slot_for_mysql(void)
/*==================================*/
- /* out: reserved slot */
{
srv_slot_t* slot;
ulint i;
@@ -1542,9 +1556,8 @@ srv_table_reserve_slot_for_mysql(void)
return(slot);
}
-#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
Puts a MySQL OS thread to wait for a lock to be released. If an error
occurs during the wait trx->error_state associated with thr is
!= DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK
@@ -1554,10 +1567,9 @@ UNIV_INTERN
void
srv_suspend_mysql_thread(
/*=====================*/
- que_thr_t* thr) /* in: query thread associated with the MySQL
+ que_thr_t* thr) /*!< in: query thread associated with the MySQL
OS thread */
{
-#ifndef UNIV_HOTBACKUP
srv_slot_t* slot;
os_event_t event;
double wait_time;
@@ -1722,25 +1734,18 @@ srv_suspend_mysql_thread(
trx->error_state = DB_LOCK_WAIT_TIMEOUT;
}
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
-#endif /* UNIV_HOTBACKUP */
}
-/************************************************************************
+/********************************************************************//**
Releases a MySQL OS thread waiting for a lock to be released, if the
thread is already suspended. */
UNIV_INTERN
void
srv_release_mysql_thread_if_suspended(
/*==================================*/
- que_thr_t* thr) /* in: query thread associated with the
+ que_thr_t* thr) /*!< in: query thread associated with the
MySQL OS thread */
{
-#ifndef UNIV_HOTBACKUP
srv_slot_t* slot;
ulint i;
@@ -1760,16 +1765,9 @@ srv_release_mysql_thread_if_suspended(
}
/* not found */
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
-#endif /* UNIV_HOTBACKUP */
}
-#ifndef UNIV_HOTBACKUP
-/**********************************************************************
+/******************************************************************//**
Refreshes the values used to calculate per-second averages. */
static
void
@@ -1797,16 +1795,16 @@ srv_refresh_innodb_monitor_stats(void)
mutex_exit(&srv_innodb_monitor_mutex);
}
-/**********************************************************************
+/******************************************************************//**
Outputs to a file the output of the InnoDB Monitor. */
UNIV_INTERN
void
srv_printf_innodb_monitor(
/*======================*/
- FILE* file, /* in: output stream */
- ulint* trx_start, /* out: file position of the start of
+ FILE* file, /*!< in: output stream */
+ ulint* trx_start, /*!< out: file position of the start of
the list of active transactions */
- ulint* trx_end) /* out: file position of the end of
+ ulint* trx_end) /*!< out: file position of the end of
the list of active transactions */
{
double time_elapsed;
@@ -1843,6 +1841,11 @@ srv_printf_innodb_monitor(
(ulong)time_elapsed);
fputs("----------\n"
+ "BACKGROUND THREAD\n"
+ "----------\n", file);
+ srv_print_master_thread_info(file);
+
+ fputs("----------\n"
"SEMAPHORES\n"
"----------\n", file);
sync_print(file);
@@ -2055,11 +2058,12 @@ srv_printf_innodb_monitor(
fflush(file);
}
-/**********************************************************************
+/******************************************************************//**
Function to pass InnoDB status variables to MySQL */
UNIV_INTERN
void
srv_export_innodb_status(void)
+/*==========================*/
{
mutex_enter(&srv_innodb_monitor_mutex);
@@ -2099,7 +2103,7 @@ srv_export_innodb_status(void)
export_vars.innodb_buffer_pool_pages_misc = buf_pool->curr_size
- UT_LIST_GET_LEN(buf_pool->LRU)
- UT_LIST_GET_LEN(buf_pool->free);
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
+#ifdef HAVE_ATOMIC_BUILTINS
export_vars.innodb_have_atomic_builtins = 1;
#else
export_vars.innodb_have_atomic_builtins = 0;
@@ -2137,16 +2141,16 @@ srv_export_innodb_status(void)
mutex_exit(&srv_innodb_monitor_mutex);
}
-/*************************************************************************
+/*********************************************************************//**
A thread which wakes up threads whose lock wait may have lasted too long.
-This also prints the info output by various InnoDB monitors. */
+This also prints the info output by various InnoDB monitors.
+@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
srv_lock_timeout_and_monitor_thread(
/*================================*/
- /* out: a dummy parameter */
void* arg __attribute__((unused)))
- /* in: a dummy parameter required by
+ /*!< in: a dummy parameter required by
os_thread_create */
{
srv_slot_t* slot;
@@ -2324,16 +2328,16 @@ exit_func:
OS_THREAD_DUMMY_RETURN;
}
-/*************************************************************************
+/*********************************************************************//**
A thread which prints warnings about semaphore waits which have lasted
-too long. These can be used to track bugs which cause hangs. */
+too long. These can be used to track bugs which cause hangs.
+@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
srv_error_monitor_thread(
/*=====================*/
- /* out: a dummy parameter */
void* arg __attribute__((unused)))
- /* in: a dummy parameter required by
+ /*!< in: a dummy parameter required by
os_thread_create */
{
/* number of successive fatal timeouts observed */
@@ -2376,13 +2380,16 @@ loop:
}
/* Update the statistics collected for deciding LRU
- eviction policy. */
+ eviction policy. */
buf_LRU_stat_update();
+ /* Update the statistics collected for flush rate policy. */
+ buf_flush_stat_update();
+
/* In case mutex_exit is not a memory barrier, it is
theoretically possible some threads are left waiting though
the semaphore is already released. Wake up those threads: */
-
+
sync_arr_wake_threads_if_sema_free();
if (sync_array_print_long_waits()) {
@@ -2424,7 +2431,7 @@ loop:
OS_THREAD_DUMMY_RETURN;
}
-/***********************************************************************
+/*******************************************************************//**
Tells the InnoDB server that there has been activity in the database
and wakes up the master thread if it is suspended (not sleeping). Used
in the MySQL interface. Note that there is a small chance that the master
@@ -2447,7 +2454,7 @@ srv_active_wake_master_thread(void)
}
}
-/***********************************************************************
+/*******************************************************************//**
Wakes up the master thread if it is suspended or being suspended. */
UNIV_INTERN
void
@@ -2463,20 +2470,44 @@ srv_wake_master_thread(void)
mutex_exit(&kernel_mutex);
}
-/*************************************************************************
-The master thread controlling the server. */
+/**********************************************************************
+The master thread is tasked to ensure that flush of log file happens
+once every second in the background. This is to ensure that not more
+than one second of trxs are lost in case of crash when
+innodb_flush_logs_at_trx_commit != 1 */
+static
+void
+srv_sync_log_buffer_in_background(void)
+/*===================================*/
+{
+ time_t current_time = time(NULL);
+
+ srv_main_thread_op_info = "flushing log";
+ if (difftime(current_time, srv_last_log_flush_time) >= 1) {
+ log_buffer_sync_in_background(TRUE);
+ srv_last_log_flush_time = current_time;
+ srv_log_writes_and_flush++;
+ } else {
+ /* Actually we don't need to write logs here.
+ We are just being extra safe here by forcing
+ the log buffer to log file. */
+ log_buffer_sync_in_background(FALSE);
+ srv_log_buffer_writes++;
+ }
+}
+
+/*********************************************************************//**
+The master thread controlling the server.
+@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
srv_master_thread(
/*==============*/
- /* out: a dummy parameter */
void* arg __attribute__((unused)))
- /* in: a dummy parameter required by
+ /*!< in: a dummy parameter required by
os_thread_create */
{
os_event_t event;
- time_t last_flush_time;
- time_t current_time;
ulint old_activity_count;
ulint n_pages_purged = 0;
ulint n_bytes_merged;
@@ -2493,7 +2524,7 @@ srv_master_thread(
ib_uint64_t lsn_old;
ib_uint64_t oldest_lsn;
-
+
#ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Master thread starts, id %lu\n",
os_thread_pf(os_thread_get_curr_id()));
@@ -2536,16 +2567,19 @@ loop:
/* ---- We run the following loop approximately once per second
when there is database activity */
+ srv_last_log_flush_time = time(NULL);
skip_sleep = FALSE;
for (i = 0; i < 10; i++) {
n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written;
srv_main_thread_op_info = "sleeping";
+ srv_main_1_second_loops++;
if (!skip_sleep) {
os_thread_sleep(1000000);
+ srv_main_sleeps++;
/*
mutex_enter(&(log_sys->mutex));
@@ -2578,34 +2612,27 @@ loop:
goto background_loop;
}
- /* We flush the log once in a second even if no commit
- is issued or the we have specified in my.cnf no flush
- at transaction commit */
-
- srv_main_thread_op_info = "flushing log";
- log_buffer_flush_to_disk();
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
srv_main_thread_op_info = "making checkpoint";
log_free_check();
- /* If there were less than 5 i/os during the
- one second sleep, we assume that there is free
- disk i/o capacity available, and it makes sense to
- do an insert buffer merge. */
+ /* If i/os during one second sleep were less than 5% of
+ capacity, we assume that there is free disk i/o capacity
+ available, and it makes sense to do an insert buffer merge. */
n_pend_ios = buf_get_n_pending_ios()
+ log_sys->n_pending_writes;
n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written;
- if (n_pend_ios < PCT_IO(3) && (n_ios - n_ios_old < PCT_IO(5))) {
+ if (n_pend_ios < SRV_PEND_IO_THRESHOLD
+ && (n_ios - n_ios_old < SRV_RECENT_IO_ACTIVITY)) {
srv_main_thread_op_info = "doing insert buffer merge";
- ibuf_contract_for_n_pages(
- TRUE, PCT_IBUF_IO((srv_insert_buffer_batch_size / 4)));
+ ibuf_contract_for_n_pages(FALSE, PCT_IBUF_IO(5));
- srv_main_thread_op_info = "flushing log";
-
- /* No fsync when srv_flush_log_at_trx_commit != 1 */
- log_buffer_flush_maybe_sync();
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
}
if (UNIV_UNLIKELY(buf_get_modified_ratio_pct()
@@ -2614,7 +2641,8 @@ loop:
/* Try to keep the number of modified pages in the
buffer pool under the limit wished by the user */
- n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100),
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
+ PCT_IO(100),
IB_ULONGLONG_MAX);
/* If we had to do the flush, it may have taken
@@ -2623,10 +2651,32 @@ loop:
iteration of this loop. */
skip_sleep = TRUE;
+
+ mutex_enter(&(log_sys->mutex));
+ lsn_old = log_sys->lsn;
+ mutex_exit(&(log_sys->mutex));
+ } else if (srv_adaptive_flushing) {
+
+ /* Try to keep the rate of flushing of dirty
+ pages such that redo log generation does not
+ produce bursts of IO at checkpoint time. */
+ ulint n_flush = buf_flush_get_desired_flush_rate();
+
+ if (n_flush) {
+ n_flush = ut_min(PCT_IO(100), n_flush);
+ n_pages_flushed =
+ buf_flush_batch(
+ BUF_FLUSH_LIST,
+ n_flush,
+ IB_ULONGLONG_MAX);
+ skip_sleep = TRUE;
+ }
+
mutex_enter(&(log_sys->mutex));
lsn_old = log_sys->lsn;
mutex_exit(&(log_sys->mutex));
} else if (srv_adaptive_checkpoint == 1) {
+ /* adaptive_flushing option is prior to adaptive_checkpoint option, for now */
/* Try to keep modified age not to exceed
max_checkpoint_age * 7/8 line */
@@ -2688,16 +2738,16 @@ loop:
lsn_old = log_sys->lsn;
mutex_exit(&(log_sys->mutex));
} else if ((log_sys->lsn - oldest_lsn)
- > (log_sys->max_checkpoint_age)/2 ) {
+ > (log_sys->max_checkpoint_age)/4 ) {
/* defence line (max_checkpoint_age * 1/2) */
ib_uint64_t lsn = log_sys->lsn;
+
ib_uint64_t level, bpl;
buf_page_t* bpage;
- mutex_exit(&(log_sys->mutex));
-
mutex_exit(&(log_sys->mutex));
+
mutex_enter(&flush_list_mutex);
level = 0;
@@ -2724,7 +2774,7 @@ loop:
if (!srv_use_doublewrite_buf) {
/* flush is faster than when doublewrite */
- bpl = (bpl * 3) / 4;
+ bpl = (bpl * 7) / 8;
}
if (bpl) {
@@ -2774,38 +2824,43 @@ retry_flush_batch:
seconds */
mem_validate_all_blocks();
#endif
- /* If there were less than 200 i/os during the 10 second period,
- we assume that there is free disk i/o capacity available, and it
- makes sense to flush 100 pages. */
+ /* If i/os during the 10 second period were less than 200% of
+ capacity, we assume that there is free disk i/o capacity
+ available, and it makes sense to flush srv_io_capacity pages.
+
+ Note that this is done regardless of the fraction of dirty
+ pages relative to the max requested by the user. The one second
+ loop above requests writes for that case. The writes done here
+ are not required, and may be disabled. */
n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes;
n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written;
- if (n_pend_ios < 3 && (n_ios - n_ios_very_old < PCT_IO(200))) {
-
- srv_main_thread_op_info = "flushing buffer pool pages";
- buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100), IB_ULONGLONG_MAX);
- srv_main_thread_op_info = "flushing log";
- /* No fsync when srv_flush_log_at_trx_commit != 1 */
- log_buffer_flush_maybe_sync();
+ srv_main_10_second_loops++;
+ if (n_pend_ios < SRV_PEND_IO_THRESHOLD
+ && (n_ios - n_ios_very_old < SRV_PAST_IO_ACTIVITY)) {
+
+ srv_main_thread_op_info = "flushing buffer pool pages";
+ buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100),
+ IB_ULONGLONG_MAX);
+
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
}
/* We run a batch of insert buffer merge every 10 seconds,
even if the server were active */
srv_main_thread_op_info = "doing insert buffer merge";
- ibuf_contract_for_n_pages(TRUE, PCT_IBUF_IO((srv_insert_buffer_batch_size / 4)));
+ ibuf_contract_for_n_pages(FALSE, PCT_IBUF_IO(5));
- srv_main_thread_op_info = "flushing log";
- /* No fsync when srv_flush_log_at_trx_commit != 1 */
- log_buffer_flush_maybe_sync();
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
+ if (!srv_use_purge_thread) {
/* We run a full purge every 10 seconds, even if the server
were active */
-
- last_flush_time = time(NULL);
-
do {
if (srv_fast_shutdown && srv_shutdown_state > 0) {
@@ -2816,15 +2871,11 @@ retry_flush_batch:
srv_main_thread_op_info = "purging";
n_pages_purged = trx_purge();
- current_time = time(NULL);
-
- if (difftime(current_time, last_flush_time) > 1) {
- srv_main_thread_op_info = "flushing log";
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
- log_buffer_flush_to_disk();
- last_flush_time = current_time;
- }
} while (n_pages_purged);
+ }
srv_main_thread_op_info = "flushing buffer pool pages";
@@ -2836,14 +2887,16 @@ retry_flush_batch:
(> 70 %), we assume we can afford reserving the disk(s) for
the time it requires to flush 100 pages */
- n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100),
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
+ PCT_IO(100),
IB_ULONGLONG_MAX);
} else {
/* Otherwise, we only flush a small number of pages so that
we do not unnecessarily use much disk i/o capacity from
other work */
- n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(10),
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
+ PCT_IO(10),
IB_ULONGLONG_MAX);
}
@@ -2877,7 +2930,7 @@ background_loop:
/* The server has been quiet for a while: start running background
operations */
-
+ srv_main_background_loops++;
srv_main_thread_op_info = "doing background drop tables";
n_tables_to_drop = row_drop_tables_for_mysql_in_background();
@@ -2891,12 +2944,10 @@ background_loop:
os_thread_sleep(100000);
}
+ if (!srv_use_purge_thread) {
srv_main_thread_op_info = "purging";
/* Run a full purge */
-
- last_flush_time = time(NULL);
-
do {
if (srv_fast_shutdown && srv_shutdown_state > 0) {
@@ -2906,15 +2957,11 @@ background_loop:
srv_main_thread_op_info = "purging";
n_pages_purged = trx_purge();
- current_time = time(NULL);
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
- if (difftime(current_time, last_flush_time) > 1) {
- srv_main_thread_op_info = "flushing log";
-
- log_buffer_flush_to_disk();
- last_flush_time = current_time;
- }
} while (n_pages_purged);
+ }
srv_main_thread_op_info = "reserving kernel mutex";
@@ -2930,8 +2977,12 @@ background_loop:
if (srv_fast_shutdown && srv_shutdown_state > 0) {
n_bytes_merged = 0;
} else {
- n_bytes_merged = ibuf_contract_for_n_pages(
- TRUE, PCT_IBUF_IO((srv_insert_buffer_batch_size * 5)));
+ /* This should do an amount of IO similar to the number of
+ dirty pages that will be flushed in the call to
+ buf_flush_batch below. Otherwise, the system favors
+ clean pages over cleanup throughput. */
+ n_bytes_merged = ibuf_contract_for_n_pages(FALSE,
+ PCT_IBUF_IO(100));
}
srv_main_thread_op_info = "reserving kernel mutex";
@@ -2945,9 +2996,10 @@ background_loop:
flush_loop:
srv_main_thread_op_info = "flushing buffer pool pages";
-
+ srv_main_flush_loops++;
if (srv_fast_shutdown < 2) {
- n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100),
+ n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
+ PCT_IO(100),
IB_ULONGLONG_MAX);
} else {
/* In the fastest shutdown we do not flush the buffer pool
@@ -2968,16 +3020,8 @@ flush_loop:
srv_main_thread_op_info = "waiting for buffer pool flush to end";
buf_flush_wait_batch_end(BUF_FLUSH_LIST);
- srv_main_thread_op_info = "flushing log";
-
- current_time = time(NULL);
- if (difftime(current_time, last_flush_time) > 1) {
- log_buffer_flush_to_disk();
- last_flush_time = current_time;
- } else {
- /* No fsync when srv_flush_log_at_trx_commit != 1 */
- log_buffer_flush_maybe_sync();
- }
+ /* Flush logs if needed */
+ srv_sync_log_buffer_in_background();
srv_main_thread_op_info = "making checkpoint";
@@ -3070,4 +3114,67 @@ suspend_thread:
OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
}
-#endif /* !UNIV_HOTBACKUP */
+
+/*************************************************************************
+A thread which is devoted to purge, for take over the master thread's
+purging */
+UNIV_INTERN
+os_thread_ret_t
+srv_purge_thread(
+/*=============*/
+ void* arg __attribute__((unused)))
+ /* in: a dummy parameter required by os_thread_create */
+{
+ ulint n_pages_purged;
+ ulint n_pages_purged_sum = 1; /* dummy */
+ ulint history_len;
+ ulint sleep_ms= 10000; /* initial: 10 sec. */
+
+#ifdef UNIV_DEBUG_THREAD_CREATION
+ fprintf(stderr, "Purge thread starts, id %lu\n",
+ os_thread_pf(os_thread_get_curr_id()));
+#endif
+
+ srv_table_reserve_slot(SRV_PURGE);
+ mutex_enter(&kernel_mutex);
+ srv_n_threads_active[SRV_PURGE]++;
+ mutex_exit(&kernel_mutex);
+
+loop:
+ if (srv_fast_shutdown && srv_shutdown_state > 0) {
+ goto exit_func;
+ }
+
+ os_thread_sleep( sleep_ms * 1000 );
+
+ history_len = trx_sys->rseg_history_len;
+ if (history_len > 1000)
+ sleep_ms /= 10;
+ if (sleep_ms < 10)
+ sleep_ms = 10;
+
+ n_pages_purged_sum = 0;
+
+ do {
+ if (srv_fast_shutdown && srv_shutdown_state > 0) {
+ goto exit_func;
+ }
+ n_pages_purged = trx_purge();
+ n_pages_purged_sum += n_pages_purged;
+ } while (n_pages_purged);
+
+ if (n_pages_purged_sum == 0)
+ sleep_ms *= 10;
+ if (sleep_ms > 10000)
+ sleep_ms = 10000;
+
+ goto loop;
+
+exit_func:
+ /* We count the number of threads in os_thread_exit(). A created
+ thread should always use that to exit and not use return() to exit. */
+
+ os_thread_exit(NULL);
+
+ OS_THREAD_DUMMY_RETURN;
+}
diff --git a/storage/xtradb/srv/srv0start.c b/storage/xtradb/srv/srv0start.c
index 3d5ddb9c89b..e8a9dabdc41 100644
--- a/storage/xtradb/srv/srv0start.c
+++ b/storage/xtradb/srv/srv0start.c
@@ -22,113 +22,152 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/***********************************************************************
-/************************************************************************
+Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Percona Inc.
+
+Portions of this file contain modifications contributed and copyrighted
+by Percona Inc.. Those modifications are
+gratefully acknowledged and are described briefly in the InnoDB
+documentation. The contributions by Percona Inc. are incorporated with
+their permission, and subject to the conditions contained in the file
+COPYING.Percona.
+
+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
+
+***********************************************************************/
+
+/********************************************************************//**
+@file srv/srv0start.c
Starts the InnoDB database server
Created 2/16/1996 Heikki Tuuri
*************************************************************************/
-#include "os0proc.h"
-#include "sync0sync.h"
#include "ut0mem.h"
#include "mem0mem.h"
#include "data0data.h"
#include "data0type.h"
#include "dict0dict.h"
#include "buf0buf.h"
-#include "buf0flu.h"
-#include "buf0rea.h"
#include "os0file.h"
#include "os0thread.h"
#include "fil0fil.h"
#include "fsp0fsp.h"
#include "rem0rec.h"
-#include "rem0cmp.h"
#include "mtr0mtr.h"
#include "log0log.h"
#include "log0recv.h"
#include "page0page.h"
#include "page0cur.h"
#include "trx0trx.h"
-#include "dict0boot.h"
-#include "dict0load.h"
#include "trx0sys.h"
-#include "dict0crea.h"
#include "btr0btr.h"
-#include "btr0pcur.h"
#include "btr0cur.h"
-#include "btr0sea.h"
#include "rem0rec.h"
-#include "srv0srv.h"
-#include "que0que.h"
-#include "usr0sess.h"
-#include "lock0lock.h"
-#include "trx0roll.h"
-#include "trx0purge.h"
-#include "row0ins.h"
-#include "row0sel.h"
-#include "row0upd.h"
-#include "row0row.h"
-#include "row0mysql.h"
-#include "lock0lock.h"
#include "ibuf0ibuf.h"
-#include "pars0pars.h"
-#include "btr0sea.h"
#include "srv0start.h"
-#include "que0que.h"
-
-/* Log sequence number immediately after startup */
+#include "srv0srv.h"
+#ifndef UNIV_HOTBACKUP
+# include "os0proc.h"
+# include "sync0sync.h"
+# include "buf0flu.h"
+# include "buf0rea.h"
+# include "dict0boot.h"
+# include "dict0load.h"
+# include "que0que.h"
+# include "usr0sess.h"
+# include "lock0lock.h"
+# include "trx0roll.h"
+# include "trx0purge.h"
+# include "lock0lock.h"
+# include "pars0pars.h"
+# include "btr0sea.h"
+# include "rem0cmp.h"
+# include "dict0crea.h"
+# include "row0ins.h"
+# include "row0sel.h"
+# include "row0upd.h"
+# include "row0row.h"
+# include "row0mysql.h"
+# include "btr0pcur.h"
+
+/** Log sequence number immediately after startup */
UNIV_INTERN ib_uint64_t srv_start_lsn;
-/* Log sequence number at shutdown */
+/** Log sequence number at shutdown */
UNIV_INTERN ib_uint64_t srv_shutdown_lsn;
#ifdef HAVE_DARWIN_THREADS
# include <sys/utsname.h>
+/** TRUE if the F_FULLFSYNC option is available */
UNIV_INTERN ibool srv_have_fullfsync = FALSE;
#endif
+/** TRUE if a raw partition is in use */
UNIV_INTERN ibool srv_start_raw_disk_in_use = FALSE;
+/** TRUE if the server is being started, before rolling back any
+incomplete transactions */
UNIV_INTERN ibool srv_startup_is_before_trx_rollback_phase = FALSE;
+/** TRUE if the server is being started */
UNIV_INTERN ibool srv_is_being_started = FALSE;
+/** TRUE if the server was successfully started */
UNIV_INTERN ibool srv_was_started = FALSE;
-#ifndef UNIV_HOTBACKUP
+/** TRUE if innobase_start_or_create_for_mysql() has been called */
static ibool srv_start_has_been_called = FALSE;
-#endif /* !UNIV_HOTBACKUP */
-/* At a shutdown the value first climbs to SRV_SHUTDOWN_CLEANUP
-and then to SRV_SHUTDOWN_LAST_PHASE */
-UNIV_INTERN ulint srv_shutdown_state = 0;
+/** At a shutdown this value climbs from SRV_SHUTDOWN_NONE to
+SRV_SHUTDOWN_CLEANUP and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
+UNIV_INTERN enum srv_shutdown_state srv_shutdown_state = SRV_SHUTDOWN_NONE;
-#ifndef UNIV_HOTBACKUP
+/** Files comprising the system tablespace */
static os_file_t files[1000];
+/** Mutex protecting the ios count */
static mutex_t ios_mutex;
+/** Count of I/O operations in io_handler_thread() */
static ulint ios;
+/** io_handler_thread parameters for thread identification */
static ulint n[SRV_MAX_N_IO_THREADS + 5];
+/** io_handler_thread identifiers */
static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5];
-/* We use this mutex to test the return value of pthread_mutex_trylock
+/** We use this mutex to test the return value of pthread_mutex_trylock
on successful locking. HP-UX does NOT return 0, though Linux et al do. */
static os_fast_mutex_t srv_os_test_mutex;
-/* Name of srv_monitor_file */
+/** Name of srv_monitor_file */
static char* srv_monitor_file_name;
#endif /* !UNIV_HOTBACKUP */
+/** */
#define SRV_N_PENDING_IOS_PER_THREAD OS_AIO_N_PENDING_IOS_PER_THREAD
#define SRV_MAX_N_PENDING_SYNC_IOS 100
+/*********************************************************************//**
+Convert a numeric string that optionally ends in G or M, to a number
+containing megabytes.
+@return next character in string */
static
char*
srv_parse_megabytes(
/*================*/
- /* out: next character in string */
- char* str, /* in: string containing a quantity in bytes */
- ulint* megs) /* out: the number in megabytes */
+ char* str, /*!< in: string containing a quantity in bytes */
+ ulint* megs) /*!< out: the number in megabytes */
{
char* endp;
ulint size;
@@ -153,15 +192,15 @@ srv_parse_megabytes(
return(str);
}
-/*************************************************************************
+/*********************************************************************//**
Reads the data files and their sizes from a character string given in
-the .cnf file. */
+the .cnf file.
+@return TRUE if ok, FALSE on parse error */
UNIV_INTERN
ibool
srv_parse_data_file_paths_and_sizes(
/*================================*/
- /* out: TRUE if ok, FALSE on parse error */
- char* str) /* in/out: the data file path string */
+ char* str) /*!< in/out: the data file path string */
{
char* input_str;
char* path;
@@ -337,15 +376,15 @@ srv_parse_data_file_paths_and_sizes(
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
Reads log group home directories from a character string given in
-the .cnf file. */
+the .cnf file.
+@return TRUE if ok, FALSE on parse error */
UNIV_INTERN
ibool
srv_parse_log_group_home_dirs(
/*==========================*/
- /* out: TRUE if ok, FALSE on parse error */
- char* str) /* in/out: character string */
+ char* str) /*!< in/out: character string */
{
char* input_str;
char* path;
@@ -409,7 +448,7 @@ srv_parse_log_group_home_dirs(
return(TRUE);
}
-/*************************************************************************
+/*********************************************************************//**
Frees the memory allocated by srv_parse_data_file_paths_and_sizes()
and srv_parse_log_group_home_dirs(). */
UNIV_INTERN
@@ -428,14 +467,15 @@ srv_free_paths_and_sizes(void)
}
#ifndef UNIV_HOTBACKUP
-/************************************************************************
-I/o-handler thread function. */
+/********************************************************************//**
+I/o-handler thread function.
+@return OS_THREAD_DUMMY_RETURN */
static
-
os_thread_ret_t
io_handler_thread(
/*==============*/
- void* arg)
+ void* arg) /*!< in: pointer to the number of the segment in
+ the aio array */
{
ulint segment;
ulint i;
@@ -471,13 +511,13 @@ io_handler_thread(
#define SRV_PATH_SEPARATOR '/'
#endif
-/*************************************************************************
+/*********************************************************************//**
Normalizes a directory path for Windows: converts slashes to backslashes. */
UNIV_INTERN
void
srv_normalize_path_for_win(
/*=======================*/
- char* str __attribute__((unused))) /* in/out: null-terminated
+ char* str __attribute__((unused))) /*!< in/out: null-terminated
character string */
{
#ifdef __WIN__
@@ -490,16 +530,15 @@ srv_normalize_path_for_win(
#endif
}
-/*************************************************************************
+/*********************************************************************//**
Adds a slash or a backslash to the end of a string if it is missing
-and the string is not empty. */
+and the string is not empty.
+@return string which has the separator if the string is not empty */
UNIV_INTERN
char*
srv_add_path_separator_if_needed(
/*=============================*/
- /* out: string which has the separator if the
- string is not empty */
- char* str) /* in: null-terminated character string */
+ char* str) /*!< in: null-terminated character string */
{
char* out_str;
ulint len = ut_strlen(str);
@@ -518,50 +557,48 @@ srv_add_path_separator_if_needed(
}
#ifndef UNIV_HOTBACKUP
-/*************************************************************************
+/*********************************************************************//**
Calculates the low 32 bits when a file size which is given as a number
-database pages is converted to the number of bytes. */
+database pages is converted to the number of bytes.
+@return low 32 bytes of file size when expressed in bytes */
static
ulint
srv_calc_low32(
/*===========*/
- /* out: low 32 bytes of file size when
- expressed in bytes */
- ulint file_size) /* in: file size in database pages */
+ ulint file_size) /*!< in: file size in database pages */
{
return(0xFFFFFFFFUL & (file_size << UNIV_PAGE_SIZE_SHIFT));
}
-/*************************************************************************
+/*********************************************************************//**
Calculates the high 32 bits when a file size which is given as a number
-database pages is converted to the number of bytes. */
+database pages is converted to the number of bytes.
+@return high 32 bytes of file size when expressed in bytes */
static
ulint
srv_calc_high32(
/*============*/
- /* out: high 32 bytes of file size when
- expressed in bytes */
- ulint file_size) /* in: file size in database pages */
+ ulint file_size) /*!< in: file size in database pages */
{
return(file_size >> (32 - UNIV_PAGE_SIZE_SHIFT));
}
-/*************************************************************************
-Creates or opens the log files and closes them. */
+/*********************************************************************//**
+Creates or opens the log files and closes them.
+@return DB_SUCCESS or error code */
static
ulint
open_or_create_log_file(
/*====================*/
- /* out: DB_SUCCESS or error code */
- ibool create_new_db, /* in: TRUE if we should create a
+ ibool create_new_db, /*!< in: TRUE if we should create a
new database */
- ibool* log_file_created, /* out: TRUE if new log file
+ ibool* log_file_created, /*!< out: TRUE if new log file
created */
- ibool log_file_has_been_opened,/* in: TRUE if a log file has been
+ ibool log_file_has_been_opened,/*!< in: TRUE if a log file has been
opened before: then it is an error
to try to create another log file */
- ulint k, /* in: log group number */
- ulint i) /* in: log file number in group */
+ ulint k, /*!< in: log group number */
+ ulint i) /*!< in: log file number in group */
{
ibool ret;
ulint size;
@@ -699,26 +736,26 @@ open_or_create_log_file(
return(DB_SUCCESS);
}
-/*************************************************************************
-Creates or opens database data files and closes them. */
+/*********************************************************************//**
+Creates or opens database data files and closes them.
+@return DB_SUCCESS or error code */
static
ulint
open_or_create_data_files(
/*======================*/
- /* out: DB_SUCCESS or error code */
- ibool* create_new_db, /* out: TRUE if new database should be
+ ibool* create_new_db, /*!< out: TRUE if new database should be
created */
#ifdef UNIV_LOG_ARCHIVE
- ulint* min_arch_log_no,/* out: min of archived log
+ ulint* min_arch_log_no,/*!< out: min of archived log
numbers in data files */
- ulint* max_arch_log_no,/* out: max of archived log
+ ulint* max_arch_log_no,/*!< out: max of archived log
numbers in data files */
#endif /* UNIV_LOG_ARCHIVE */
- ib_uint64_t* min_flushed_lsn,/* out: min of flushed lsn
+ ib_uint64_t* min_flushed_lsn,/*!< out: min of flushed lsn
values in data files */
- ib_uint64_t* max_flushed_lsn,/* out: max of flushed lsn
+ ib_uint64_t* max_flushed_lsn,/*!< out: max of flushed lsn
values in data files */
- ulint* sum_of_new_sizes)/* out: sum of sizes of the
+ ulint* sum_of_new_sizes)/*!< out: sum of sizes of the
new files added */
{
ibool ret;
@@ -971,14 +1008,14 @@ skip_size_check:
return(DB_SUCCESS);
}
-/********************************************************************
+/****************************************************************//**
Starts InnoDB and creates a new database if database files
-are not found and the user wants. */
+are not found and the user wants.
+@return DB_SUCCESS or error code */
UNIV_INTERN
int
innobase_start_or_create_for_mysql(void)
/*====================================*/
- /* out: DB_SUCCESS or error code */
{
buf_pool_t* ret;
ibool create_new_db;
@@ -996,6 +1033,7 @@ innobase_start_or_create_for_mysql(void)
ulint tablespace_size_in_header;
ulint err;
ulint i;
+ ulint io_limit;
my_bool srv_file_per_table_original_value
= srv_file_per_table;
mtr_t mtr;
@@ -1069,13 +1107,29 @@ innobase_start_or_create_for_mysql(void)
}
#ifdef HAVE_GCC_ATOMIC_BUILTINS
-#ifdef INNODB_RW_LOCKS_USE_ATOMICS
+# ifdef INNODB_RW_LOCKS_USE_ATOMICS
fprintf(stderr,
"InnoDB: Mutexes and rw_locks use GCC atomic builtins.\n");
-#else /* INNODB_RW_LOCKS_USE_ATOMICS */
+# else /* INNODB_RW_LOCKS_USE_ATOMICS */
fprintf(stderr,
"InnoDB: Mutexes use GCC atomic builtins, rw_locks do not.\n");
-#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
+# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
+#elif defined(HAVE_SOLARIS_ATOMICS)
+# ifdef INNODB_RW_LOCKS_USE_ATOMICS
+ fprintf(stderr,
+ "InnoDB: Mutexes and rw_locks use Solaris atomic functions.\n");
+# else
+ fprintf(stderr,
+ "InnoDB: Mutexes use Solaris atomic functions.\n");
+# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
+#elif HAVE_WINDOWS_ATOMICS
+# ifdef INNODB_RW_LOCKS_USE_ATOMICS
+ fprintf(stderr,
+ "InnoDB: Mutexes and rw_locks use Windows interlocked functions.\n");
+# else
+ fprintf(stderr,
+ "InnoDB: Mutexes use Windows interlocked functions.\n");
+# endif /* INNODB_RW_LOCKS_USE_ATOMICS */
#else /* HAVE_GCC_ATOMIC_BUILTINS */
fprintf(stderr,
"InnoDB: Neither mutexes nor rw_locks use GCC atomic builtins.\n");
@@ -1108,25 +1162,26 @@ innobase_start_or_create_for_mysql(void)
os_aio_use_native_aio = FALSE;
#ifdef __WIN__
- if (os_get_os_version() == OS_WIN95
- || os_get_os_version() == OS_WIN31
- || os_get_os_version() == OS_WINNT) {
-
+ switch (os_get_os_version()) {
+ case OS_WIN95:
+ case OS_WIN31:
+ case OS_WINNT:
/* On Win 95, 98, ME, Win32 subsystem for Windows 3.1,
and NT use simulated aio. In NT Windows provides async i/o,
but when run in conjunction with InnoDB Hot Backup, it seemed
to corrupt the data files. */
os_aio_use_native_aio = FALSE;
- } else {
- /* On Win 2000 and XP currently native async i/o
- is not used for xtradb by default */
+ break;
+ default:
+ /* On Win 2000 and XP use async i/o */
//os_aio_use_native_aio = TRUE;
os_aio_use_native_aio = FALSE;
fprintf(stderr,
"InnoDB: Windows native async i/o is disabled as default.\n"
"InnoDB: It is not applicable for the current"
" multi io threads implementation.\n");
+ break;
}
#endif
if (srv_file_flush_method_str == NULL) {
@@ -1250,32 +1305,37 @@ innobase_start_or_create_for_mysql(void)
return(DB_ERROR);
}
- /* over write innodb_file_io_threads */
- srv_n_file_io_threads = 2 + srv_n_read_io_threads + srv_n_write_io_threads;
+ /* If user has set the value of innodb_file_io_threads then
+ we'll emit a message telling the user that this parameter
+ is now deprecated. */
+ if (srv_n_file_io_threads != 4) {
+ fprintf(stderr, "InnoDB: Warning:"
+ " innodb_file_io_threads is deprecated."
+ " Please use innodb_read_io_threads and"
+ " innodb_write_io_threads instead\n");
+ }
- /* Restrict the maximum number of file i/o threads */
- if (srv_n_file_io_threads > SRV_MAX_N_IO_THREADS) {
+ /* Now overwrite the value on srv_n_file_io_threads */
+ srv_n_file_io_threads = 2 + srv_n_read_io_threads
+ + srv_n_write_io_threads;
- srv_n_file_io_threads = SRV_MAX_N_IO_THREADS;
- srv_n_read_io_threads = srv_n_write_io_threads = (SRV_MAX_N_IO_THREADS - 2) / 2;
- }
+ ut_a(srv_n_file_io_threads <= SRV_MAX_N_IO_THREADS);
+ /* TODO: Investigate if SRV_N_PENDING_IOS_PER_THREAD (32) limit
+ still applies to windows. */
if (!os_aio_use_native_aio) {
- /* In simulated aio we currently have use only for 4 threads */
- /*srv_n_file_io_threads = 4;*/
-
- os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD
- * srv_n_file_io_threads,
- srv_n_read_io_threads, srv_n_write_io_threads,
- SRV_MAX_N_PENDING_SYNC_IOS);
+ io_limit = 8 * SRV_N_PENDING_IOS_PER_THREAD;
} else {
- os_aio_init(SRV_N_PENDING_IOS_PER_THREAD
- * srv_n_file_io_threads,
- srv_n_read_io_threads, srv_n_write_io_threads,
- SRV_MAX_N_PENDING_SYNC_IOS);
+ io_limit = SRV_N_PENDING_IOS_PER_THREAD;
}
- fil_init(srv_max_n_open_files);
+ os_aio_init(io_limit,
+ srv_n_read_io_threads,
+ srv_n_write_io_threads,
+ SRV_MAX_N_PENDING_SYNC_IOS);
+
+ fil_init(srv_file_per_table ? 50000 : 5000,
+ srv_max_n_open_files);
ret = buf_pool_init();
@@ -1484,6 +1544,12 @@ innobase_start_or_create_for_mysql(void)
dict_create();
srv_startup_is_before_trx_rollback_phase = FALSE;
+ if (trx_doublewrite == NULL) {
+ /* Create the doublewrite buffer here to avoid assertion error
+ about page_no of doublewrite_buf */
+ trx_sys_create_doublewrite_buf();
+ }
+
if (srv_extra_rsegments)
trx_sys_create_extra_rseg(srv_extra_rsegments);
#ifdef UNIV_LOG_ARCHIVE
@@ -1671,6 +1737,11 @@ innobase_start_or_create_for_mysql(void)
os_thread_create(&srv_master_thread, NULL, thread_ids
+ (1 + SRV_MAX_N_IO_THREADS));
+
+ if (srv_use_purge_thread) {
+ os_thread_create(&srv_purge_thread, NULL, thread_ids
+ + (4 + SRV_MAX_N_IO_THREADS));
+ }
#ifdef UNIV_DEBUG
/* buf_debug_prints = TRUE; */
#endif /* UNIV_DEBUG */
@@ -1822,8 +1893,7 @@ innobase_start_or_create_for_mysql(void)
" to an earlier version of\n"
"InnoDB: InnoDB! But if you absolutely need to"
" downgrade, see\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "multiple-tablespaces.html\n"
+ "InnoDB: " REFMAN "multiple-tablespaces.html\n"
"InnoDB: for instructions.\n");
}
@@ -1843,13 +1913,13 @@ innobase_start_or_create_for_mysql(void)
return((int) DB_SUCCESS);
}
-/********************************************************************
-Shuts down the InnoDB database. */
+/****************************************************************//**
+Shuts down the InnoDB database.
+@return DB_SUCCESS or error code */
UNIV_INTERN
int
innobase_shutdown_for_mysql(void)
/*=============================*/
- /* out: DB_SUCCESS or error code */
{
ulint i;
#ifdef __NETWARE__
@@ -1884,7 +1954,7 @@ innobase_shutdown_for_mysql(void)
}
#ifdef __NETWARE__
- if(!panic_shutdown)
+ if (!panic_shutdown)
#endif
logs_empty_and_mark_files_at_shutdown();
diff --git a/storage/xtradb/sync/sync0arr.c b/storage/xtradb/sync/sync0arr.c
index 62165eefd46..0519e13dee0 100644
--- a/storage/xtradb/sync/sync0arr.c
+++ b/storage/xtradb/sync/sync0arr.c
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file sync/sync0arr.c
The wait array used in synchronization primitives
Created 9/5/1995 Heikki Tuuri
@@ -73,27 +74,29 @@ wait array for the sake of diagnostics and also to avoid infinite
wait The error_monitor thread scans the global wait array to signal
any waiting threads who have missed the signal. */
-/* A cell where an individual thread may wait suspended
+/** A cell where an individual thread may wait suspended
until a resource is released. The suspending is implemented
using an operating system event semaphore. */
struct sync_cell_struct {
- void* wait_object; /* pointer to the object the
+ void* wait_object; /*!< pointer to the object the
thread is waiting for; if NULL
the cell is free for use */
- mutex_t* old_wait_mutex; /* the latest wait mutex in cell */
- rw_lock_t* old_wait_rw_lock;/* the latest wait rw-lock in cell */
- ulint request_type; /* lock type requested on the
+ mutex_t* old_wait_mutex; /*!< the latest wait mutex in cell */
+ rw_lock_t* old_wait_rw_lock;
+ /*!< the latest wait rw-lock
+ in cell */
+ ulint request_type; /*!< lock type requested on the
object */
- const char* file; /* in debug version file where
+ const char* file; /*!< in debug version file where
requested */
- ulint line; /* in debug version line where
+ ulint line; /*!< in debug version line where
requested */
- os_thread_id_t thread; /* thread id of this waiting
+ os_thread_id_t thread; /*!< thread id of this waiting
thread */
- ibool waiting; /* TRUE if the thread has already
+ ibool waiting; /*!< TRUE if the thread has already
called sync_array_event_wait
on this cell */
- ib_int64_t signal_count; /* We capture the signal_count
+ ib_int64_t signal_count; /*!< We capture the signal_count
of the wait_object when we
reset the event. This value is
then passed on to os_event_wait
@@ -101,7 +104,7 @@ struct sync_cell_struct {
has not been signalled in the
period between the reset and
wait call. */
- time_t reservation_time;/* time when the thread reserved
+ time_t reservation_time;/*!< time when the thread reserved
the wait cell */
};
@@ -110,54 +113,56 @@ for an event allocated for the array without owning the
protecting mutex (depending on the case: OS or database mutex), but
all changes (set or reset) to the state of the event must be made
while owning the mutex. */
+
+/** Synchronization array */
struct sync_array_struct {
- ulint n_reserved; /* number of currently reserved
+ ulint n_reserved; /*!< number of currently reserved
cells in the wait array */
- ulint n_cells; /* number of cells in the
+ ulint n_cells; /*!< number of cells in the
wait array */
- sync_cell_t* array; /* pointer to wait array */
- ulint protection; /* this flag tells which
+ sync_cell_t* array; /*!< pointer to wait array */
+ ulint protection; /*!< this flag tells which
mutex protects the data */
- mutex_t mutex; /* possible database mutex
+ mutex_t mutex; /*!< possible database mutex
protecting this data structure */
- os_mutex_t os_mutex; /* Possible operating system mutex
+ os_mutex_t os_mutex; /*!< Possible operating system mutex
protecting the data structure.
As this data structure is used in
constructing the database mutex,
to prevent infinite recursion
in implementation, we fall back to
an OS mutex. */
- ulint sg_count; /* count of how many times an
+ ulint sg_count; /*!< count of how many times an
object has been signalled */
- ulint res_count; /* count of cell reservations
+ ulint res_count; /*!< count of cell reservations
since creation of the array */
};
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
This function is called only in the debug version. Detects a deadlock
-of one or more threads because of waits of semaphores. */
+of one or more threads because of waits of semaphores.
+@return TRUE if deadlock detected */
static
ibool
sync_array_detect_deadlock(
/*=======================*/
- /* out: TRUE if deadlock detected */
- sync_array_t* arr, /* in: wait array; NOTE! the caller must
+ sync_array_t* arr, /*!< in: wait array; NOTE! the caller must
own the mutex to array */
- sync_cell_t* start, /* in: cell where recursive search started */
- sync_cell_t* cell, /* in: cell to search */
- ulint depth); /* in: recursion depth */
+ sync_cell_t* start, /*!< in: cell where recursive search started */
+ sync_cell_t* cell, /*!< in: cell to search */
+ ulint depth); /*!< in: recursion depth */
#endif /* UNIV_SYNC_DEBUG */
-/*********************************************************************
-Gets the nth cell in array. */
+/*****************************************************************//**
+Gets the nth cell in array.
+@return cell */
static
sync_cell_t*
sync_array_get_nth_cell(
/*====================*/
- /* out: cell */
- sync_array_t* arr, /* in: sync array */
- ulint n) /* in: index */
+ sync_array_t* arr, /*!< in: sync array */
+ ulint n) /*!< in: index */
{
ut_a(arr);
ut_a(n < arr->n_cells);
@@ -165,13 +170,13 @@ sync_array_get_nth_cell(
return(arr->array + n);
}
-/**********************************************************************
+/******************************************************************//**
Reserves the mutex semaphore protecting a sync array. */
static
void
sync_array_enter(
/*=============*/
- sync_array_t* arr) /* in: sync wait array */
+ sync_array_t* arr) /*!< in: sync wait array */
{
ulint protection;
@@ -186,13 +191,13 @@ sync_array_enter(
}
}
-/**********************************************************************
+/******************************************************************//**
Releases the mutex semaphore protecting a sync array. */
static
void
sync_array_exit(
/*============*/
- sync_array_t* arr) /* in: sync wait array */
+ sync_array_t* arr) /*!< in: sync wait array */
{
ulint protection;
@@ -207,18 +212,18 @@ sync_array_exit(
}
}
-/***********************************************************************
+/*******************************************************************//**
Creates a synchronization wait array. It is protected by a mutex
which is automatically reserved when the functions operating on it
-are called. */
+are called.
+@return own: created wait array */
UNIV_INTERN
sync_array_t*
sync_array_create(
/*==============*/
- /* out, own: created wait array */
- ulint n_cells, /* in: number of cells in the array
+ ulint n_cells, /*!< in: number of cells in the array
to create */
- ulint protection) /* in: either SYNC_ARRAY_OS_MUTEX or
+ ulint protection) /*!< in: either SYNC_ARRAY_OS_MUTEX or
SYNC_ARRAY_MUTEX: determines the type
of mutex protecting the data structure */
{
@@ -260,13 +265,13 @@ sync_array_create(
return(arr);
}
-/**********************************************************************
+/******************************************************************//**
Frees the resources in a wait array. */
UNIV_INTERN
void
sync_array_free(
/*============*/
- sync_array_t* arr) /* in, own: sync wait array */
+ sync_array_t* arr) /*!< in, own: sync wait array */
{
ulint protection;
@@ -290,14 +295,14 @@ sync_array_free(
ut_free(arr);
}
-/************************************************************************
+/********************************************************************//**
Validates the integrity of the wait array. Checks
that the number of reserved cells equals the count variable. */
UNIV_INTERN
void
sync_array_validate(
/*================*/
- sync_array_t* arr) /* in: sync wait array */
+ sync_array_t* arr) /*!< in: sync wait array */
{
ulint i;
sync_cell_t* cell;
@@ -317,13 +322,13 @@ sync_array_validate(
sync_array_exit(arr);
}
-/***********************************************************************
+/*******************************************************************//**
Returns the event that the thread owning the cell waits for. */
static
os_event_t
sync_cell_get_event(
/*================*/
- sync_cell_t* cell) /* in: non-empty sync array cell */
+ sync_cell_t* cell) /*!< in: non-empty sync array cell */
{
ulint type = cell->request_type;
@@ -336,19 +341,19 @@ sync_cell_get_event(
}
}
-/**********************************************************************
+/******************************************************************//**
Reserves a wait array cell for waiting for an object.
The event of the cell is reset to nonsignalled state. */
UNIV_INTERN
void
sync_array_reserve_cell(
/*====================*/
- sync_array_t* arr, /* in: wait array */
- void* object, /* in: pointer to the object to wait for */
- ulint type, /* in: lock request type */
- const char* file, /* in: file where requested */
- ulint line, /* in: line where requested */
- ulint* index) /* out: index of the reserved cell */
+ sync_array_t* arr, /*!< in: wait array */
+ void* object, /*!< in: pointer to the object to wait for */
+ ulint type, /*!< in: lock request type */
+ const char* file, /*!< in: file where requested */
+ ulint line, /*!< in: line where requested */
+ ulint* index) /*!< out: index of the reserved cell */
{
sync_cell_t* cell;
os_event_t event;
@@ -406,7 +411,7 @@ sync_array_reserve_cell(
return;
}
-/**********************************************************************
+/******************************************************************//**
This function should be called when a thread starts to wait on
a wait array cell. In the debug version this function checks
if the wait for a semaphore will result in a deadlock, in which
@@ -415,8 +420,8 @@ UNIV_INTERN
void
sync_array_wait_event(
/*==================*/
- sync_array_t* arr, /* in: wait array */
- ulint index) /* in: index of the reserved cell */
+ sync_array_t* arr, /*!< in: wait array */
+ ulint index) /*!< in: index of the reserved cell */
{
sync_cell_t* cell;
os_event_t event;
@@ -458,14 +463,14 @@ sync_array_wait_event(
sync_array_free_cell(arr, index);
}
-/**********************************************************************
+/******************************************************************//**
Reports info of a wait array cell. */
static
void
sync_array_cell_print(
/*==================*/
- FILE* file, /* in: file where to print */
- sync_cell_t* cell) /* in: sync cell */
+ FILE* file, /*!< in: file where to print */
+ sync_cell_t* cell) /*!< in: sync cell */
{
mutex_t* mutex;
rw_lock_t* rwlock;
@@ -544,16 +549,15 @@ sync_array_cell_print(
}
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
-Looks for a cell with the given thread id. */
+/******************************************************************//**
+Looks for a cell with the given thread id.
+@return pointer to cell or NULL if not found */
static
sync_cell_t*
sync_array_find_thread(
/*===================*/
- /* out: pointer to cell or NULL
- if not found */
- sync_array_t* arr, /* in: wait array */
- os_thread_id_t thread) /* in: thread id */
+ sync_array_t* arr, /*!< in: wait array */
+ os_thread_id_t thread) /*!< in: thread id */
{
ulint i;
sync_cell_t* cell;
@@ -572,20 +576,20 @@ sync_array_find_thread(
return(NULL); /* Not found */
}
-/**********************************************************************
-Recursion step for deadlock detection. */
+/******************************************************************//**
+Recursion step for deadlock detection.
+@return TRUE if deadlock detected */
static
ibool
sync_array_deadlock_step(
/*=====================*/
- /* out: TRUE if deadlock detected */
- sync_array_t* arr, /* in: wait array; NOTE! the caller must
+ sync_array_t* arr, /*!< in: wait array; NOTE! the caller must
own the mutex to array */
- sync_cell_t* start, /* in: cell where recursive search
+ sync_cell_t* start, /*!< in: cell where recursive search
started */
- os_thread_id_t thread, /* in: thread to look at */
- ulint pass, /* in: pass value */
- ulint depth) /* in: recursion depth */
+ os_thread_id_t thread, /*!< in: thread to look at */
+ ulint pass, /*!< in: pass value */
+ ulint depth) /*!< in: recursion depth */
{
sync_cell_t* new;
ibool ret;
@@ -623,19 +627,19 @@ sync_array_deadlock_step(
return(FALSE);
}
-/**********************************************************************
+/******************************************************************//**
This function is called only in the debug version. Detects a deadlock
-of one or more threads because of waits of semaphores. */
+of one or more threads because of waits of semaphores.
+@return TRUE if deadlock detected */
static
ibool
sync_array_detect_deadlock(
/*=======================*/
- /* out: TRUE if deadlock detected */
- sync_array_t* arr, /* in: wait array; NOTE! the caller must
+ sync_array_t* arr, /*!< in: wait array; NOTE! the caller must
own the mutex to array */
- sync_cell_t* start, /* in: cell where recursive search started */
- sync_cell_t* cell, /* in: cell to search */
- ulint depth) /* in: recursion depth */
+ sync_cell_t* start, /*!< in: cell where recursive search started */
+ sync_cell_t* cell, /*!< in: cell to search */
+ ulint depth) /*!< in: recursion depth */
{
mutex_t* mutex;
rw_lock_t* lock;
@@ -768,13 +772,13 @@ print:
}
#endif /* UNIV_SYNC_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Determines if we can wake up the thread waiting for a sempahore. */
static
ibool
sync_arr_cell_can_wake_up(
/*======================*/
- sync_cell_t* cell) /* in: cell to search */
+ sync_cell_t* cell) /*!< in: cell to search */
{
mutex_t* mutex;
rw_lock_t* lock;
@@ -820,15 +824,15 @@ sync_arr_cell_can_wake_up(
return(FALSE);
}
-/**********************************************************************
+/******************************************************************//**
Frees the cell. NOTE! sync_array_wait_event frees the cell
automatically! */
UNIV_INTERN
void
sync_array_free_cell(
/*=================*/
- sync_array_t* arr, /* in: wait array */
- ulint index) /* in: index of the cell in array */
+ sync_array_t* arr, /*!< in: wait array */
+ ulint index) /*!< in: index of the cell in array */
{
sync_cell_t* cell;
@@ -848,16 +852,16 @@ sync_array_free_cell(
sync_array_exit(arr);
}
-/**************************************************************************
+/**********************************************************************//**
Increments the signalled count. */
UNIV_INTERN
void
sync_array_object_signalled(
/*========================*/
- sync_array_t* arr) /* in: wait array */
+ sync_array_t* arr) /*!< in: wait array */
{
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
- (void) os_atomic_increment(&arr->sg_count, 1);
+#ifdef HAVE_ATOMIC_BUILTINS
+ (void) os_atomic_increment_ulint(&arr->sg_count, 1);
#else
sync_array_enter(arr);
@@ -867,7 +871,7 @@ sync_array_object_signalled(
#endif
}
-/**************************************************************************
+/**********************************************************************//**
If the wakeup algorithm does not work perfectly at semaphore relases,
this function will do the waking (see the comment in mutex_exit). This
function should be called about every 1 second in the server.
@@ -913,14 +917,13 @@ sync_arr_wake_threads_if_sema_free(void)
sync_array_exit(arr);
}
-/**************************************************************************
-Prints warnings of long semaphore waits to stderr. */
+/**********************************************************************//**
+Prints warnings of long semaphore waits to stderr.
+@return TRUE if fatal semaphore wait threshold was exceeded */
UNIV_INTERN
ibool
sync_array_print_long_waits(void)
/*=============================*/
- /* out: TRUE if fatal semaphore wait threshold
- was exceeded */
{
sync_cell_t* cell;
ibool old_val;
@@ -979,14 +982,14 @@ sync_array_print_long_waits(void)
return(fatal);
}
-/**************************************************************************
+/**********************************************************************//**
Prints info of the wait array. */
static
void
sync_array_output_info(
/*===================*/
- FILE* file, /* in: file where to print */
- sync_array_t* arr) /* in: wait array; NOTE! caller must own the
+ FILE* file, /*!< in: file where to print */
+ sync_array_t* arr) /*!< in: wait array; NOTE! caller must own the
mutex */
{
sync_cell_t* cell;
@@ -1012,14 +1015,14 @@ sync_array_output_info(
}
}
-/**************************************************************************
+/**********************************************************************//**
Prints info of the wait array. */
UNIV_INTERN
void
sync_array_print_info(
/*==================*/
- FILE* file, /* in: file where to print */
- sync_array_t* arr) /* in: wait array */
+ FILE* file, /*!< in: file where to print */
+ sync_array_t* arr) /*!< in: wait array */
{
sync_array_enter(arr);
diff --git a/storage/xtradb/sync/sync0rw.c b/storage/xtradb/sync/sync0rw.c
index 09c732eefc9..0ed114e330c 100644
--- a/storage/xtradb/sync/sync0rw.c
+++ b/storage/xtradb/sync/sync0rw.c
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file sync/sync0rw.c
The read-write lock (for thread synchronization)
Created 9/11/1995 Heikki Tuuri
@@ -132,29 +133,33 @@ wait_ex_event: A thread may only wait on the wait_ex_event after it has
*/
-/* number of spin waits on rw-latches,
+/** number of spin waits on rw-latches,
resulted during shared (read) locks */
UNIV_INTERN ib_int64_t rw_s_spin_wait_count = 0;
+/** number of spin loop rounds on rw-latches,
+resulted during shared (read) locks */
UNIV_INTERN ib_int64_t rw_s_spin_round_count = 0;
-/* number of OS waits on rw-latches,
+/** number of OS waits on rw-latches,
resulted during shared (read) locks */
UNIV_INTERN ib_int64_t rw_s_os_wait_count = 0;
-/* number of unlocks (that unlock shared locks),
+/** number of unlocks (that unlock shared locks),
set only when UNIV_SYNC_PERF_STAT is defined */
UNIV_INTERN ib_int64_t rw_s_exit_count = 0;
-/* number of spin waits on rw-latches,
+/** number of spin waits on rw-latches,
resulted during exclusive (write) locks */
UNIV_INTERN ib_int64_t rw_x_spin_wait_count = 0;
+/** number of spin loop rounds on rw-latches,
+resulted during exclusive (write) locks */
UNIV_INTERN ib_int64_t rw_x_spin_round_count = 0;
-/* number of OS waits on rw-latches,
+/** number of OS waits on rw-latches,
resulted during exclusive (write) locks */
UNIV_INTERN ib_int64_t rw_x_os_wait_count = 0;
-/* number of unlocks (that unlock exclusive locks),
+/** number of unlocks (that unlock exclusive locks),
set only when UNIV_SYNC_PERF_STAT is defined */
UNIV_INTERN ib_int64_t rw_x_exit_count = 0;
@@ -174,13 +179,13 @@ UNIV_INTERN os_event_t rw_lock_debug_event;
/* This is set to TRUE, if there may be waiters for the event */
UNIV_INTERN ibool rw_lock_debug_waiters;
-/**********************************************************************
+/******************************************************************//**
Creates a debug info struct. */
static
rw_lock_debug_t*
rw_lock_debug_create(void);
/*======================*/
-/**********************************************************************
+/******************************************************************//**
Frees a debug info struct. */
static
void
@@ -188,8 +193,9 @@ rw_lock_debug_free(
/*===============*/
rw_lock_debug_t* info);
-/**********************************************************************
-Creates a debug info struct. */
+/******************************************************************//**
+Creates a debug info struct.
+@return own: debug info struct */
static
rw_lock_debug_t*
rw_lock_debug_create(void)
@@ -198,7 +204,7 @@ rw_lock_debug_create(void)
return((rw_lock_debug_t*) mem_alloc(sizeof(rw_lock_debug_t)));
}
-/**********************************************************************
+/******************************************************************//**
Frees a debug info struct. */
static
void
@@ -210,7 +216,7 @@ rw_lock_debug_free(
}
#endif /* UNIV_SYNC_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Creates, or rather, initializes an rw-lock object in a specified memory
location (which must be appropriately aligned). The rw-lock is initialized
to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
@@ -219,15 +225,15 @@ UNIV_INTERN
void
rw_lock_create_func(
/*================*/
- rw_lock_t* lock, /* in: pointer to memory */
+ rw_lock_t* lock, /*!< in: pointer to memory */
#ifdef UNIV_DEBUG
# ifdef UNIV_SYNC_DEBUG
- ulint level, /* in: level */
+ ulint level, /*!< in: level */
# endif /* UNIV_SYNC_DEBUG */
- const char* cmutex_name, /* in: mutex name */
+ const char* cmutex_name, /*!< in: mutex name */
#endif /* UNIV_DEBUG */
- const char* cfile_name, /* in: file name where created */
- ulint cline) /* in: file line where created */
+ const char* cfile_name, /*!< in: file name where created */
+ ulint cline) /*!< in: file line where created */
{
/* If this is the very first time a synchronization object is
created, then the following call initializes the sync system. */
@@ -238,11 +244,8 @@ rw_lock_create_func(
lock->mutex.cfile_name = cfile_name;
lock->mutex.cline = cline;
-# if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
- lock->mutex.cmutex_name = cmutex_name;
- lock->mutex.mutex_type = 1;
-# endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
-
+ ut_d(lock->mutex.cmutex_name = cmutex_name);
+ ut_d(lock->mutex.mutex_type = 1);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
# ifdef UNIV_DEBUG
UT_NOT_USED(cmutex_name);
@@ -288,7 +291,7 @@ rw_lock_create_func(
mutex_exit(&rw_lock_list_mutex);
}
-/**********************************************************************
+/******************************************************************//**
Calling this function is obligatory only if the memory buffer containing
the rw-lock is freed. Removes an rw-lock object from the global list. The
rw-lock is checked to be in the non-locked state. */
@@ -296,7 +299,7 @@ UNIV_INTERN
void
rw_lock_free(
/*=========*/
- rw_lock_t* lock) /* in: rw-lock */
+ rw_lock_t* lock) /*!< in: rw-lock */
{
ut_ad(rw_lock_validate(lock));
ut_a(lock->lock_word == X_LOCK_DECR);
@@ -325,14 +328,15 @@ rw_lock_free(
}
#ifdef UNIV_DEBUG
-/**********************************************************************
+/******************************************************************//**
Checks that the rw-lock has been initialized and that there are no
-simultaneous shared and exclusive locks. */
+simultaneous shared and exclusive locks.
+@return TRUE */
UNIV_INTERN
ibool
rw_lock_validate(
/*=============*/
- rw_lock_t* lock)
+ rw_lock_t* lock) /*!< in: rw-lock */
{
ut_a(lock);
@@ -347,7 +351,7 @@ rw_lock_validate(
}
#endif /* UNIV_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Lock an rw-lock in shared mode for the current thread. If the rw-lock is
locked in exclusive mode, or there is an exclusive lock request waiting,
the function spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting
@@ -356,18 +360,18 @@ UNIV_INTERN
void
rw_lock_s_lock_spin(
/*================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ ulint pass, /*!< in: pass value; != 0, if the lock
will be passed to another thread to unlock */
- const char* file_name, /* in: file name where lock requested */
- ulint line) /* in: line where requested */
+ const char* file_name, /*!< in: file name where lock requested */
+ ulint line) /*!< in: line where requested */
{
ulint index; /* index of the reserved wait cell */
ulint i = 0; /* spin round count */
ut_ad(rw_lock_validate(lock));
- rw_s_spin_wait_count++; /* Count calls to this function */
+ rw_s_spin_wait_count++; /*!< Count calls to this function */
lock_loop:
/* Spin waiting for the writer field to become free */
@@ -439,7 +443,7 @@ lock_loop:
}
}
-/**********************************************************************
+/******************************************************************//**
This function is used in the insert buffer to move the ownership of an
x-latch on a buffer frame to the current thread. The x-latch was set by
the buffer read operation and it protected the buffer frame while the
@@ -451,7 +455,7 @@ UNIV_INTERN
void
rw_lock_x_lock_move_ownership(
/*==========================*/
- rw_lock_t* lock) /* in: lock which was x-locked in the
+ rw_lock_t* lock) /*!< in: lock which was x-locked in the
buffer read */
{
ut_ad(rw_lock_is_locked(lock, RW_LOCK_EX));
@@ -459,20 +463,20 @@ rw_lock_x_lock_move_ownership(
rw_lock_set_writer_id_and_recursion_flag(lock, TRUE);
}
-/**********************************************************************
+/******************************************************************//**
Function for the next writer to call. Waits for readers to exit.
-The caller must have already decremented lock_word by X_LOCK_DECR.*/
+The caller must have already decremented lock_word by X_LOCK_DECR. */
UNIV_INLINE
void
rw_lock_x_lock_wait(
/*================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
#ifdef UNIV_SYNC_DEBUG
- ulint pass, /* in: pass value; != 0, if the lock will
+ ulint pass, /*!< in: pass value; != 0, if the lock will
be passed to another thread to unlock */
#endif
- const char* file_name,/* in: file name where lock requested */
- ulint line) /* in: line where requested */
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line) /*!< in: line where requested */
{
ulint index;
ulint i = 0;
@@ -527,19 +531,18 @@ rw_lock_x_lock_wait(
rw_x_spin_round_count += i;
}
-/**********************************************************************
-Low-level function for acquiring an exclusive lock. */
+/******************************************************************//**
+Low-level function for acquiring an exclusive lock.
+@return RW_LOCK_NOT_LOCKED if did not succeed, RW_LOCK_EX if success. */
UNIV_INLINE
ibool
rw_lock_x_lock_low(
/*===============*/
- /* out: RW_LOCK_NOT_LOCKED if did
- not succeed, RW_LOCK_EX if success. */
- rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock will
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ ulint pass, /*!< in: pass value; != 0, if the lock will
be passed to another thread to unlock */
- const char* file_name,/* in: file name where lock requested */
- ulint line) /* in: line where requested */
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line) /*!< in: line where requested */
{
os_thread_id_t curr_thread = os_thread_get_curr_id();
@@ -582,7 +585,7 @@ rw_lock_x_lock_low(
return(TRUE);
}
-/**********************************************************************
+/******************************************************************//**
NOTE! Use the corresponding macro, not directly this function! Lock an
rw-lock in exclusive mode for the current thread. If the rw-lock is locked
in shared or exclusive mode, or there is an exclusive lock request waiting,
@@ -595,14 +598,14 @@ UNIV_INTERN
void
rw_lock_x_lock_func(
/*================*/
- rw_lock_t* lock, /* in: pointer to rw-lock */
- ulint pass, /* in: pass value; != 0, if the lock will
+ rw_lock_t* lock, /*!< in: pointer to rw-lock */
+ ulint pass, /*!< in: pass value; != 0, if the lock will
be passed to another thread to unlock */
- const char* file_name,/* in: file name where lock requested */
- ulint line) /* in: line where requested */
+ const char* file_name,/*!< in: file name where lock requested */
+ ulint line) /*!< in: line where requested */
{
- ulint index; /* index of the reserved wait cell */
- ulint i; /* spin round count */
+ ulint index; /*!< index of the reserved wait cell */
+ ulint i; /*!< spin round count */
ibool spinning = FALSE;
ut_ad(rw_lock_validate(lock));
@@ -684,7 +687,7 @@ lock_loop:
}
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
Acquires the debug mutex. We cannot use the mutex defined in sync0sync,
because the debug mutex is also acquired in sync0arr while holding the OS
mutex protecting the sync array, and the ordinary mutex_enter might
@@ -713,7 +716,7 @@ loop:
goto loop;
}
-/**********************************************************************
+/******************************************************************//**
Releases the debug mutex. */
UNIV_INTERN
void
@@ -728,17 +731,17 @@ rw_lock_debug_mutex_exit(void)
}
}
-/**********************************************************************
+/******************************************************************//**
Inserts the debug information for an rw-lock. */
UNIV_INTERN
void
rw_lock_add_debug_info(
/*===================*/
- rw_lock_t* lock, /* in: rw-lock */
- ulint pass, /* in: pass value */
- ulint lock_type, /* in: lock type */
- const char* file_name, /* in: file where requested */
- ulint line) /* in: line where requested */
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint pass, /*!< in: pass value */
+ ulint lock_type, /*!< in: lock type */
+ const char* file_name, /*!< in: file where requested */
+ ulint line) /*!< in: line where requested */
{
rw_lock_debug_t* info;
@@ -764,15 +767,15 @@ rw_lock_add_debug_info(
}
}
-/**********************************************************************
+/******************************************************************//**
Removes a debug information struct for an rw-lock. */
UNIV_INTERN
void
rw_lock_remove_debug_info(
/*======================*/
- rw_lock_t* lock, /* in: rw-lock */
- ulint pass, /* in: pass value */
- ulint lock_type) /* in: lock type */
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint pass, /*!< in: pass value */
+ ulint lock_type) /*!< in: lock type */
{
rw_lock_debug_t* info;
@@ -810,16 +813,16 @@ rw_lock_remove_debug_info(
#endif /* UNIV_SYNC_DEBUG */
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
Checks if the thread has locked the rw-lock in the specified mode, with
-the pass value == 0. */
+the pass value == 0.
+@return TRUE if locked */
UNIV_INTERN
ibool
rw_lock_own(
/*========*/
- /* out: TRUE if locked */
- rw_lock_t* lock, /* in: rw-lock */
- ulint lock_type) /* in: lock type: RW_LOCK_SHARED,
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint lock_type) /*!< in: lock type: RW_LOCK_SHARED,
RW_LOCK_EX */
{
rw_lock_debug_t* info;
@@ -851,15 +854,15 @@ rw_lock_own(
}
#endif /* UNIV_SYNC_DEBUG */
-/**********************************************************************
-Checks if somebody has locked the rw-lock in the specified mode. */
+/******************************************************************//**
+Checks if somebody has locked the rw-lock in the specified mode.
+@return TRUE if locked */
UNIV_INTERN
ibool
rw_lock_is_locked(
/*==============*/
- /* out: TRUE if locked */
- rw_lock_t* lock, /* in: rw-lock */
- ulint lock_type) /* in: lock type: RW_LOCK_SHARED,
+ rw_lock_t* lock, /*!< in: rw-lock */
+ ulint lock_type) /*!< in: lock type: RW_LOCK_SHARED,
RW_LOCK_EX */
{
ibool ret = FALSE;
@@ -883,13 +886,13 @@ rw_lock_is_locked(
}
#ifdef UNIV_SYNC_DEBUG
-/*******************************************************************
+/***************************************************************//**
Prints debug info of currently locked rw-locks. */
UNIV_INTERN
void
rw_lock_list_print_info(
/*====================*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
rw_lock_t* lock;
ulint count = 0;
@@ -937,13 +940,13 @@ rw_lock_list_print_info(
mutex_exit(&rw_lock_list_mutex);
}
-/*******************************************************************
+/***************************************************************//**
Prints debug info of an rw-lock. */
UNIV_INTERN
void
rw_lock_print(
/*==========*/
- rw_lock_t* lock) /* in: rw-lock */
+ rw_lock_t* lock) /*!< in: rw-lock */
{
rw_lock_debug_t* info;
@@ -953,7 +956,12 @@ rw_lock_print(
"RW-LATCH: %p ", (void*) lock);
#ifndef INNODB_RW_LOCKS_USE_ATOMICS
- mutex_enter(&(lock->mutex));
+ /* We used to acquire lock->mutex here, but it would cause a
+ recursive call to sync_thread_add_level() if UNIV_SYNC_DEBUG
+ is defined. Since this function is only invoked from
+ sync_thread_levels_g(), let us choose the smaller evil:
+ performing dirty reads instead of causing bogus deadlocks or
+ assertion failures. */
#endif
if (lock->lock_word != X_LOCK_DECR) {
@@ -969,18 +977,15 @@ rw_lock_print(
info = UT_LIST_GET_NEXT(list, info);
}
}
-#ifndef INNODB_RW_LOCKS_USE_ATOMICS
- mutex_exit(&(lock->mutex));
-#endif
}
-/*************************************************************************
+/*********************************************************************//**
Prints info of a debug struct. */
UNIV_INTERN
void
rw_lock_debug_print(
/*================*/
- rw_lock_debug_t* info) /* in: debug struct */
+ rw_lock_debug_t* info) /*!< in: debug struct */
{
ulint rwt;
@@ -1004,9 +1009,10 @@ rw_lock_debug_print(
putc('\n', stderr);
}
-/*******************************************************************
+/***************************************************************//**
Returns the number of currently locked rw-locks. Works only in the debug
-version. */
+version.
+@return number of locked rw-locks */
UNIV_INTERN
ulint
rw_lock_n_locked(void)
diff --git a/storage/xtradb/sync/sync0sync.c b/storage/xtradb/sync/sync0sync.c
index 1e7f6f95580..01aa49688b7 100644
--- a/storage/xtradb/sync/sync0sync.c
+++ b/storage/xtradb/sync/sync0sync.c
@@ -23,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file sync/sync0sync.c
Mutex, the basic synchronization primitive
Created 9/5/1995 Heikki Tuuri
@@ -163,60 +164,70 @@ Q.E.D. */
/* Number of spin waits on mutexes: for performance monitoring */
-/* round=one iteration of a spin loop */
-UNIV_INTERN ib_int64_t mutex_spin_round_count = 0;
-UNIV_INTERN ib_int64_t mutex_spin_wait_count = 0;
-UNIV_INTERN ib_int64_t mutex_os_wait_count = 0;
+/** The number of iterations in the mutex_spin_wait() spin loop.
+Intended for performance monitoring. */
+static ib_int64_t mutex_spin_round_count = 0;
+/** The number of mutex_spin_wait() calls. Intended for
+performance monitoring. */
+static ib_int64_t mutex_spin_wait_count = 0;
+/** The number of OS waits in mutex_spin_wait(). Intended for
+performance monitoring. */
+static ib_int64_t mutex_os_wait_count = 0;
+/** The number of mutex_exit() calls. Intended for performance
+monitoring. */
UNIV_INTERN ib_int64_t mutex_exit_count = 0;
-/* The global array of wait cells for implementation of the database's own
+/** The global array of wait cells for implementation of the database's own
mutexes and read-write locks */
UNIV_INTERN sync_array_t* sync_primary_wait_array;
-/* This variable is set to TRUE when sync_init is called */
+/** This variable is set to TRUE when sync_init is called */
UNIV_INTERN ibool sync_initialized = FALSE;
-
+/** An acquired mutex or rw-lock and its level in the latching order */
typedef struct sync_level_struct sync_level_t;
+/** Mutexes or rw-locks held by a thread */
typedef struct sync_thread_struct sync_thread_t;
#ifdef UNIV_SYNC_DEBUG
-/* The latch levels currently owned by threads are stored in this data
+/** The latch levels currently owned by threads are stored in this data
structure; the size of this array is OS_THREAD_MAX_N */
UNIV_INTERN sync_thread_t* sync_thread_level_arrays;
-/* Mutex protecting sync_thread_level_arrays */
+/** Mutex protecting sync_thread_level_arrays */
UNIV_INTERN mutex_t sync_thread_mutex;
#endif /* UNIV_SYNC_DEBUG */
-/* Global list of database mutexes (not OS mutexes) created. */
+/** Global list of database mutexes (not OS mutexes) created. */
UNIV_INTERN ut_list_base_node_t mutex_list;
-/* Mutex protecting the mutex_list variable */
+/** Mutex protecting the mutex_list variable */
UNIV_INTERN mutex_t mutex_list_mutex;
#ifdef UNIV_SYNC_DEBUG
-/* Latching order checks start when this is set TRUE */
+/** Latching order checks start when this is set TRUE */
UNIV_INTERN ibool sync_order_checks_on = FALSE;
#endif /* UNIV_SYNC_DEBUG */
+/** Mutexes or rw-locks held by a thread */
struct sync_thread_struct{
- os_thread_id_t id; /* OS thread id */
- sync_level_t* levels; /* level array for this thread; if this is NULL
- this slot is unused */
+ os_thread_id_t id; /*!< OS thread id */
+ sync_level_t* levels; /*!< level array for this thread; if
+ this is NULL this slot is unused */
};
-/* Number of slots reserved for each OS thread in the sync level array */
+/** Number of slots reserved for each OS thread in the sync level array */
#define SYNC_THREAD_N_LEVELS 10000
+/** An acquired mutex or rw-lock and its level in the latching order */
struct sync_level_struct{
- void* latch; /* pointer to a mutex or an rw-lock; NULL means that
+ void* latch; /*!< pointer to a mutex or an rw-lock; NULL means that
the slot is empty */
- ulint level; /* level of the latch in the latching order */
+ ulint level; /*!< level of the latch in the latching order */
};
-/**********************************************************************
+/******************************************************************//**
Creates, or rather, initializes a mutex object in a specified memory
location (which must be appropriately aligned). The mutex is initialized
in the reset state. Explicit freeing of the mutex with mutex_free is
@@ -225,19 +236,17 @@ UNIV_INTERN
void
mutex_create_func(
/*==============*/
- mutex_t* mutex, /* in: pointer to memory */
+ mutex_t* mutex, /*!< in: pointer to memory */
#ifdef UNIV_DEBUG
- const char* cmutex_name, /* in: mutex name */
+ const char* cmutex_name, /*!< in: mutex name */
# ifdef UNIV_SYNC_DEBUG
- ulint level, /* in: level */
+ ulint level, /*!< in: level */
# endif /* UNIV_SYNC_DEBUG */
#endif /* UNIV_DEBUG */
- const char* cfile_name, /* in: file name where created */
- ulint cline) /* in: file line where created */
+ const char* cfile_name, /*!< in: file name where created */
+ ulint cline) /*!< in: file line where created */
{
-#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
- mutex_reset_lock_word(mutex);
-#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
+#if defined(HAVE_ATOMIC_BUILTINS)
mutex_reset_lock_word(mutex);
#else
os_fast_mutex_init(&(mutex->os_fast_mutex));
@@ -255,9 +264,8 @@ mutex_create_func(
#endif /* UNIV_SYNC_DEBUG */
mutex->cfile_name = cfile_name;
mutex->cline = cline;
-#ifndef UNIV_HOTBACKUP
mutex->count_os_wait = 0;
-# ifdef UNIV_DEBUG
+#ifdef UNIV_DEBUG
mutex->cmutex_name= cmutex_name;
mutex->count_using= 0;
mutex->mutex_type= 0;
@@ -266,8 +274,7 @@ mutex_create_func(
mutex->count_spin_loop= 0;
mutex->count_spin_rounds= 0;
mutex->count_os_yield= 0;
-# endif /* UNIV_DEBUG */
-#endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG */
/* Check that lock_word is aligned; this is important on Intel */
ut_ad(((ulint)(&(mutex->lock_word))) % 4 == 0);
@@ -293,7 +300,7 @@ mutex_create_func(
mutex_exit(&mutex_list_mutex);
}
-/**********************************************************************
+/******************************************************************//**
Calling this function is obligatory only if the memory buffer containing
the mutex is freed. Removes a mutex object from the mutex list. The mutex
is checked to be in the reset state. */
@@ -301,7 +308,7 @@ UNIV_INTERN
void
mutex_free(
/*=======*/
- mutex_t* mutex) /* in: mutex */
+ mutex_t* mutex) /*!< in: mutex */
{
ut_ad(mutex_validate(mutex));
ut_a(mutex_get_lock_word(mutex) == 0);
@@ -329,9 +336,7 @@ mutex_free(
os_event_free(mutex->event);
-#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
-#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
-#else
+#if !defined(HAVE_ATOMIC_BUILTINS)
os_fast_mutex_free(&(mutex->os_fast_mutex));
#endif
/* If we free the mutex protecting the mutex list (freeing is
@@ -342,21 +347,21 @@ mutex_free(
#endif /* UNIV_DEBUG */
}
-/************************************************************************
+/********************************************************************//**
NOTE! Use the corresponding macro in the header file, not this function
directly. Tries to lock the mutex for the current thread. If the lock is not
-acquired immediately, returns with return value 1. */
+acquired immediately, returns with return value 1.
+@return 0 if succeed, 1 if not */
UNIV_INTERN
ulint
mutex_enter_nowait_func(
/*====================*/
- /* out: 0 if succeed, 1 if not */
- mutex_t* mutex, /* in: pointer to mutex */
+ mutex_t* mutex, /*!< in: pointer to mutex */
const char* file_name __attribute__((unused)),
- /* in: file name where mutex
+ /*!< in: file name where mutex
requested */
ulint line __attribute__((unused)))
- /* in: line where requested */
+ /*!< in: line where requested */
{
ut_ad(mutex_validate(mutex));
@@ -374,13 +379,14 @@ mutex_enter_nowait_func(
}
#ifdef UNIV_DEBUG
-/**********************************************************************
-Checks that the mutex has been initialized. */
+/******************************************************************//**
+Checks that the mutex has been initialized.
+@return TRUE */
UNIV_INTERN
ibool
mutex_validate(
/*===========*/
- const mutex_t* mutex)
+ const mutex_t* mutex) /*!< in: mutex */
{
ut_a(mutex);
ut_a(mutex->magic_n == MUTEX_MAGIC_N);
@@ -388,15 +394,15 @@ mutex_validate(
return(TRUE);
}
-/**********************************************************************
+/******************************************************************//**
Checks that the current thread owns the mutex. Works only in the debug
-version. */
+version.
+@return TRUE if owns */
UNIV_INTERN
ibool
mutex_own(
/*======*/
- /* out: TRUE if owns */
- const mutex_t* mutex) /* in: mutex */
+ const mutex_t* mutex) /*!< in: mutex */
{
ut_ad(mutex_validate(mutex));
@@ -405,14 +411,14 @@ mutex_own(
}
#endif /* UNIV_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Sets the waiters field in a mutex. */
UNIV_INTERN
void
mutex_set_waiters(
/*==============*/
- mutex_t* mutex, /* in: mutex */
- ulint n) /* in: value to set */
+ mutex_t* mutex, /*!< in: mutex */
+ ulint n) /*!< in: value to set */
{
volatile ulint* ptr; /* declared volatile to ensure that
the value is stored to memory */
@@ -424,7 +430,7 @@ mutex_set_waiters(
word in memory is atomic */
}
-/**********************************************************************
+/******************************************************************//**
Reserves a mutex for the current thread. If the mutex is reserved, the
function spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting
for the mutex before suspending the thread. */
@@ -432,20 +438,20 @@ UNIV_INTERN
void
mutex_spin_wait(
/*============*/
- mutex_t* mutex, /* in: pointer to mutex */
- const char* file_name, /* in: file name where mutex
+ mutex_t* mutex, /*!< in: pointer to mutex */
+ const char* file_name, /*!< in: file name where mutex
requested */
- ulint line) /* in: line where requested */
+ ulint line) /*!< in: line where requested */
{
ulint index; /* index of the reserved wait cell */
ulint i; /* spin round count */
-#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
+#ifdef UNIV_DEBUG
ib_int64_t lstart_time = 0, lfinish_time; /* for timing os_wait */
ulint ltime_diff;
ulint sec;
ulint ms;
uint timer_started = 0;
-#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG */
ut_ad(mutex);
/* This update is not thread safe, but we don't mind if the count
@@ -465,9 +471,7 @@ mutex_loop:
a memory word. */
spin_loop:
-#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
- mutex->count_spin_loop++;
-#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
+ ut_d(mutex->count_spin_loop++);
while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) {
if (srv_spin_wait_delay) {
@@ -478,14 +482,16 @@ spin_loop:
}
if (i == SYNC_SPIN_ROUNDS) {
-#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
+#ifdef UNIV_DEBUG
mutex->count_os_yield++;
- if (timed_mutexes == 1 && timer_started==0) {
+#ifndef UNIV_HOTBACKUP
+ if (timed_mutexes && timer_started == 0) {
ut_usectime(&sec, &ms);
lstart_time= (ib_int64_t)sec * 1000000 + ms;
timer_started = 1;
}
-#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
+#endif /* UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG */
os_thread_yield();
}
@@ -499,9 +505,7 @@ spin_loop:
mutex_spin_round_count += i;
-#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
- mutex->count_spin_rounds += i;
-#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
+ ut_d(mutex->count_spin_rounds += i);
if (mutex_test_and_set(mutex) == 0) {
/* Succeeded! */
@@ -578,24 +582,23 @@ spin_loop:
mutex_os_wait_count++;
-#ifndef UNIV_HOTBACKUP
mutex->count_os_wait++;
-# ifdef UNIV_DEBUG
+#ifdef UNIV_DEBUG
/* !!!!! Sometimes os_wait can be called without os_thread_yield */
-
- if (timed_mutexes == 1 && timer_started==0) {
+#ifndef UNIV_HOTBACKUP
+ if (timed_mutexes == 1 && timer_started == 0) {
ut_usectime(&sec, &ms);
lstart_time= (ib_int64_t)sec * 1000000 + ms;
timer_started = 1;
}
-# endif /* UNIV_DEBUG */
-#endif /* !UNIV_HOTBACKUP */
+#endif /* UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG */
sync_array_wait_event(sync_primary_wait_array, index);
goto mutex_loop;
finish_timing:
-#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
+#ifdef UNIV_DEBUG
if (timed_mutexes == 1 && timer_started==1) {
ut_usectime(&sec, &ms);
lfinish_time= (ib_int64_t)sec * 1000000 + ms;
@@ -607,17 +610,17 @@ finish_timing:
mutex->lmax_spent_time= ltime_diff;
}
}
-#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
+#endif /* UNIV_DEBUG */
return;
}
-/**********************************************************************
+/******************************************************************//**
Releases the threads waiting in the primary wait array for this mutex. */
UNIV_INTERN
void
mutex_signal_object(
/*================*/
- mutex_t* mutex) /* in: mutex */
+ mutex_t* mutex) /*!< in: mutex */
{
mutex_set_waiters(mutex, 0);
@@ -628,15 +631,15 @@ mutex_signal_object(
}
#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
+/******************************************************************//**
Sets the debug information for a reserved mutex. */
UNIV_INTERN
void
mutex_set_debug_info(
/*=================*/
- mutex_t* mutex, /* in: mutex */
- const char* file_name, /* in: file where requested */
- ulint line) /* in: line where requested */
+ mutex_t* mutex, /*!< in: mutex */
+ const char* file_name, /*!< in: file where requested */
+ ulint line) /*!< in: line where requested */
{
ut_ad(mutex);
ut_ad(file_name);
@@ -647,16 +650,16 @@ mutex_set_debug_info(
mutex->line = line;
}
-/**********************************************************************
+/******************************************************************//**
Gets the debug information for a reserved mutex. */
UNIV_INTERN
void
mutex_get_debug_info(
/*=================*/
- mutex_t* mutex, /* in: mutex */
- const char** file_name, /* out: file where requested */
- ulint* line, /* out: line where requested */
- os_thread_id_t* thread_id) /* out: id of the thread which owns
+ mutex_t* mutex, /*!< in: mutex */
+ const char** file_name, /*!< out: file where requested */
+ ulint* line, /*!< out: line where requested */
+ os_thread_id_t* thread_id) /*!< out: id of the thread which owns
the mutex */
{
ut_ad(mutex);
@@ -666,13 +669,13 @@ mutex_get_debug_info(
*thread_id = mutex->thread_id;
}
-/**********************************************************************
+/******************************************************************//**
Prints debug info of currently reserved mutexes. */
static
void
mutex_list_print_info(
/*==================*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
mutex_t* mutex;
const char* file_name;
@@ -709,8 +712,9 @@ mutex_list_print_info(
mutex_exit(&mutex_list_mutex);
}
-/**********************************************************************
-Counts currently reserved mutexes. Works only in the debug version. */
+/******************************************************************//**
+Counts currently reserved mutexes. Works only in the debug version.
+@return number of reserved mutexes */
UNIV_INTERN
ulint
mutex_n_reserved(void)
@@ -740,9 +744,10 @@ mutex_n_reserved(void)
was holding one mutex (mutex_list_mutex) */
}
-/**********************************************************************
+/******************************************************************//**
Returns TRUE if no mutex or rw-lock is currently locked. Works only in
-the debug version. */
+the debug version.
+@return TRUE if no mutexes and rw-locks reserved */
UNIV_INTERN
ibool
sync_all_freed(void)
@@ -751,27 +756,27 @@ sync_all_freed(void)
return(mutex_n_reserved() + rw_lock_n_locked() == 0);
}
-/**********************************************************************
-Gets the value in the nth slot in the thread level arrays. */
+/******************************************************************//**
+Gets the value in the nth slot in the thread level arrays.
+@return pointer to thread slot */
static
sync_thread_t*
sync_thread_level_arrays_get_nth(
/*=============================*/
- /* out: pointer to thread slot */
- ulint n) /* in: slot number */
+ ulint n) /*!< in: slot number */
{
ut_ad(n < OS_THREAD_MAX_N);
return(sync_thread_level_arrays + n);
}
-/**********************************************************************
-Looks for the thread slot for the calling thread. */
+/******************************************************************//**
+Looks for the thread slot for the calling thread.
+@return pointer to thread slot, NULL if not found */
static
sync_thread_t*
sync_thread_level_arrays_find_slot(void)
/*====================================*/
- /* out: pointer to thread slot, NULL if not found */
{
sync_thread_t* slot;
@@ -793,13 +798,13 @@ sync_thread_level_arrays_find_slot(void)
return(NULL);
}
-/**********************************************************************
-Looks for an unused thread slot. */
+/******************************************************************//**
+Looks for an unused thread slot.
+@return pointer to thread slot */
static
sync_thread_t*
sync_thread_level_arrays_find_free(void)
/*====================================*/
- /* out: pointer to thread slot */
{
sync_thread_t* slot;
@@ -818,33 +823,33 @@ sync_thread_level_arrays_find_free(void)
return(NULL);
}
-/**********************************************************************
-Gets the value in the nth slot in the thread level array. */
+/******************************************************************//**
+Gets the value in the nth slot in the thread level array.
+@return pointer to level slot */
static
sync_level_t*
sync_thread_levels_get_nth(
/*=======================*/
- /* out: pointer to level slot */
- sync_level_t* arr, /* in: pointer to level array for an OS
+ sync_level_t* arr, /*!< in: pointer to level array for an OS
thread */
- ulint n) /* in: slot number */
+ ulint n) /*!< in: slot number */
{
ut_ad(n < SYNC_THREAD_N_LEVELS);
return(arr + n);
}
-/**********************************************************************
+/******************************************************************//**
Checks if all the level values stored in the level array are greater than
-the given limit. */
+the given limit.
+@return TRUE if all greater */
static
ibool
sync_thread_levels_g(
/*=================*/
- /* out: TRUE if all greater */
- sync_level_t* arr, /* in: pointer to level array for an OS
+ sync_level_t* arr, /*!< in: pointer to level array for an OS
thread */
- ulint limit) /* in: level limit */
+ ulint limit) /*!< in: level limit */
{
sync_level_t* slot;
rw_lock_t* lock;
@@ -905,16 +910,16 @@ sync_thread_levels_g(
return(TRUE);
}
-/**********************************************************************
-Checks if the level value is stored in the level array. */
+/******************************************************************//**
+Checks if the level value is stored in the level array.
+@return TRUE if stored */
static
ibool
sync_thread_levels_contain(
/*=======================*/
- /* out: TRUE if stored */
- sync_level_t* arr, /* in: pointer to level array for an OS
+ sync_level_t* arr, /*!< in: pointer to level array for an OS
thread */
- ulint level) /* in: level */
+ ulint level) /*!< in: level */
{
sync_level_t* slot;
ulint i;
@@ -934,15 +939,14 @@ sync_thread_levels_contain(
return(FALSE);
}
-/**********************************************************************
-Checks that the level array for the current thread is empty. */
+/******************************************************************//**
+Checks that the level array for the current thread is empty.
+@return TRUE if empty except the exceptions specified below */
UNIV_INTERN
ibool
sync_thread_levels_empty_gen(
/*=========================*/
- /* out: TRUE if empty except the
- exceptions specified below */
- ibool dict_mutex_allowed) /* in: TRUE if dictionary mutex is
+ ibool dict_mutex_allowed) /*!< in: TRUE if dictionary mutex is
allowed to be owned by the thread,
also purge_is_running mutex is
allowed */
@@ -991,18 +995,18 @@ sync_thread_levels_empty_gen(
return(TRUE);
}
-/**********************************************************************
-Checks that the level array for the current thread is empty. */
+/******************************************************************//**
+Checks that the level array for the current thread is empty.
+@return TRUE if empty */
UNIV_INTERN
ibool
sync_thread_levels_empty(void)
/*==========================*/
- /* out: TRUE if empty */
{
return(sync_thread_levels_empty_gen(FALSE));
}
-/**********************************************************************
+/******************************************************************//**
Adds a latch and its level in the thread level array. Allocates the memory
for the array if called first time for this OS thread. Makes the checks
against other latch levels stored in the array for this thread. */
@@ -1010,8 +1014,8 @@ UNIV_INTERN
void
sync_thread_add_level(
/*==================*/
- void* latch, /* in: pointer to a mutex or an rw-lock */
- ulint level) /* in: level in the latching order; if
+ void* latch, /*!< in: pointer to a mutex or an rw-lock */
+ ulint level) /*!< in: level in the latching order; if
SYNC_LEVEL_VARYING, nothing is done */
{
sync_level_t* array;
@@ -1113,9 +1117,10 @@ sync_thread_add_level(
/* Either the thread must own the buffer pool mutex
(buf_pool_mutex), or it is allowed to latch only ONE
buffer block (block->mutex or buf_pool_zip_mutex). */
- ut_a((sync_thread_levels_contain(array, SYNC_BUF_LRU_LIST)
- && sync_thread_levels_g(array, SYNC_BUF_BLOCK - 1))
- || sync_thread_levels_g(array, SYNC_BUF_BLOCK));
+ if (!sync_thread_levels_g(array, level)) {
+ ut_a(sync_thread_levels_g(array, level - 1));
+ ut_a(sync_thread_levels_contain(array, SYNC_BUF_LRU_LIST));
+ }
break;
case SYNC_REC_LOCK:
ut_a((sync_thread_levels_contain(array, SYNC_KERNEL)
@@ -1207,15 +1212,16 @@ sync_thread_add_level(
mutex_exit(&sync_thread_mutex);
}
-/**********************************************************************
-Removes a latch from the thread level array if it is found there. */
+/******************************************************************//**
+Removes a latch from the thread level array if it is found there.
+@return TRUE if found in the array; it is no error if the latch is
+not found, as we presently are not able to determine the level for
+every latch reservation the program does */
UNIV_INTERN
ibool
sync_thread_reset_level(
/*====================*/
- /* out: TRUE if found from the array; it is an error
- if the latch is not found */
- void* latch) /* in: pointer to a mutex or an rw-lock */
+ void* latch) /*!< in: pointer to a mutex or an rw-lock */
{
sync_level_t* array;
sync_level_t* slot;
@@ -1282,7 +1288,7 @@ sync_thread_reset_level(
}
#endif /* UNIV_SYNC_DEBUG */
-/**********************************************************************
+/******************************************************************//**
Initializes the synchronization data structures. */
UNIV_INTERN
void
@@ -1336,7 +1342,7 @@ sync_init(void)
#endif /* UNIV_SYNC_DEBUG */
}
-/**********************************************************************
+/******************************************************************//**
Frees the resources in InnoDB's own synchronization data structures. Use
os_sync_free() after calling this. */
UNIV_INTERN
@@ -1361,13 +1367,13 @@ sync_close(void)
#endif /* UNIV_SYNC_DEBUG */
}
-/***********************************************************************
+/*******************************************************************//**
Prints wait info of the sync system. */
UNIV_INTERN
void
sync_print_wait_info(
/*=================*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
#ifdef UNIV_SYNC_DEBUG
fprintf(file, "Mutex exits %llu, rws exits %llu, rwx exits %llu\n",
@@ -1397,13 +1403,13 @@ sync_print_wait_info(
(rw_x_spin_wait_count ? rw_x_spin_wait_count : 1));
}
-/***********************************************************************
+/*******************************************************************//**
Prints info of the sync system. */
UNIV_INTERN
void
sync_print(
/*=======*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
#ifdef UNIV_SYNC_DEBUG
mutex_list_print_info(file);
diff --git a/storage/xtradb/thr/thr0loc.c b/storage/xtradb/thr/thr0loc.c
index aea1992a921..ecc7d720dd5 100644
--- a/storage/xtradb/thr/thr0loc.c
+++ b/storage/xtradb/thr/thr0loc.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file thr/thr0loc.c
The thread local storage
Created 10/5/1995 Heikki Tuuri
@@ -43,39 +44,42 @@ is protected by a mutex. If you need modify the program and put new data to
the thread local storage, just add it to struct thr_local_struct in the
header file. */
-/* Mutex protecting the local storage hash table */
+/** Mutex protecting thr_local_hash */
static mutex_t thr_local_mutex;
-/* The hash table. The module is not yet initialized when it is NULL. */
+/** The hash table. The module is not yet initialized when it is NULL. */
static hash_table_t* thr_local_hash = NULL;
ulint thr_local_hash_n_nodes = 0;
-/* The private data for each thread should be put to
-the structure below and the accessor functions written
-for the field. */
+/** Thread local data */
typedef struct thr_local_struct thr_local_t;
+/** @brief Thread local data.
+The private data for each thread should be put to
+the structure below and the accessor functions written
+for the field. */
struct thr_local_struct{
- os_thread_id_t id; /* id of the thread which owns this struct */
- os_thread_t handle; /* operating system handle to the thread */
- ulint slot_no;/* the index of the slot in the thread table
+ os_thread_id_t id; /*!< id of the thread which owns this struct */
+ os_thread_t handle; /*!< operating system handle to the thread */
+ ulint slot_no;/*!< the index of the slot in the thread table
for this thread */
- ibool in_ibuf;/* TRUE if the the thread is doing an ibuf
+ ibool in_ibuf;/*!< TRUE if the the thread is doing an ibuf
operation */
- hash_node_t hash; /* hash chain node */
- ulint magic_n;
+ hash_node_t hash; /*!< hash chain node */
+ ulint magic_n;/*!< magic number (THR_LOCAL_MAGIC_N) */
};
+/** The value of thr_local_struct::magic_n */
#define THR_LOCAL_MAGIC_N 1231234
-/***********************************************************************
-Returns the local storage struct for a thread. */
+/*******************************************************************//**
+Returns the local storage struct for a thread.
+@return local storage */
static
thr_local_t*
thr_local_get(
/*==========*/
- /* out: local storage */
- os_thread_id_t id) /* in: thread id of the thread */
+ os_thread_id_t id) /*!< in: thread id of the thread */
{
thr_local_t* local;
@@ -104,14 +108,14 @@ try_again:
return(local);
}
-/***********************************************************************
-Gets the slot number in the thread table of a thread. */
+/*******************************************************************//**
+Gets the slot number in the thread table of a thread.
+@return slot number */
UNIV_INTERN
ulint
thr_local_get_slot_no(
/*==================*/
- /* out: slot number */
- os_thread_id_t id) /* in: thread id of the thread */
+ os_thread_id_t id) /*!< in: thread id of the thread */
{
ulint slot_no;
thr_local_t* local;
@@ -127,14 +131,14 @@ thr_local_get_slot_no(
return(slot_no);
}
-/***********************************************************************
+/*******************************************************************//**
Sets the slot number in the thread table of a thread. */
UNIV_INTERN
void
thr_local_set_slot_no(
/*==================*/
- os_thread_id_t id, /* in: thread id of the thread */
- ulint slot_no)/* in: slot number */
+ os_thread_id_t id, /*!< in: thread id of the thread */
+ ulint slot_no)/*!< in: slot number */
{
thr_local_t* local;
@@ -147,14 +151,14 @@ thr_local_set_slot_no(
mutex_exit(&thr_local_mutex);
}
-/***********************************************************************
+/*******************************************************************//**
Returns pointer to the 'in_ibuf' field within the current thread local
-storage. */
+storage.
+@return pointer to the in_ibuf field */
UNIV_INTERN
ibool*
thr_local_get_in_ibuf_field(void)
/*=============================*/
- /* out: pointer to the in_ibuf field */
{
thr_local_t* local;
@@ -167,7 +171,7 @@ thr_local_get_in_ibuf_field(void)
return(&(local->in_ibuf));
}
-/***********************************************************************
+/*******************************************************************//**
Creates a local storage struct for the calling new thread. */
UNIV_INTERN
void
@@ -198,13 +202,13 @@ thr_local_create(void)
mutex_exit(&thr_local_mutex);
}
-/***********************************************************************
+/*******************************************************************//**
Frees the local storage struct for the specified thread. */
UNIV_INTERN
void
thr_local_free(
/*===========*/
- os_thread_id_t id) /* in: thread id */
+ os_thread_id_t id) /*!< in: thread id */
{
thr_local_t* local;
@@ -231,7 +235,7 @@ thr_local_free(
mem_free(local);
}
-/********************************************************************
+/****************************************************************//**
Initializes the thread local storage module. */
UNIV_INTERN
void
diff --git a/storage/xtradb/trx/trx0i_s.c b/storage/xtradb/trx/trx0i_s.c
index 512e38cc17e..90b73ad9e07 100644
--- a/storage/xtradb/trx/trx0i_s.c
+++ b/storage/xtradb/trx/trx0i_s.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0i_s.c
INFORMATION SCHEMA innodb_trx, innodb_locks and
innodb_lock_waits tables fetch code.
@@ -27,11 +28,11 @@ table cache" for later retrieval.
Created July 17, 2007 Vasil Dimov
*******************************************************/
-#include <mysql/plugin.h>
#include "mysql_addons.h"
#include "univ.i"
+#include <mysql/plugin.h>
#include "buf0buf.h"
#include "dict0dict.h"
#include "ha0storage.h"
@@ -53,22 +54,25 @@ Created July 17, 2007 Vasil Dimov
#include "ut0mem.h"
#include "ut0ut.h"
+/** Initial number of rows in the table cache */
#define TABLE_CACHE_INITIAL_ROWSNUM 1024
-/* Table cache's rows are stored in a set of chunks. When a new row is
-added a new chunk is allocated if necessary. MEM_CHUNKS_IN_TABLE_CACHE
-specifies the maximum number of chunks.
-Assuming that the first one is 1024 rows (TABLE_CACHE_INITIAL_ROWSNUM)
-and each subsequent is N/2 where N is the number of rows we have
-allocated till now, then 39th chunk would have 1677416425 number of rows
-and all chunks would have 3354832851 number of rows. */
+/** @brief The maximum number of chunks to allocate for a table cache.
+
+The rows of a table cache are stored in a set of chunks. When a new
+row is added a new chunk is allocated if necessary. Assuming that the
+first one is 1024 rows (TABLE_CACHE_INITIAL_ROWSNUM) and each
+subsequent is N/2 where N is the number of rows we have allocated till
+now, then 39th chunk would accommodate 1677416425 rows and all chunks
+would accommodate 3354832851 rows. */
#define MEM_CHUNKS_IN_TABLE_CACHE 39
-/* The following are some testing auxiliary macros. Do not enable them
+/** The following are some testing auxiliary macros. Do not enable them
in a production environment. */
+/* @{ */
#if 0
-/* If this is enabled then lock folds will always be different
+/** If this is enabled then lock folds will always be different
resulting in equal rows being put in a different cells of the hash
table. Checking for duplicates will be flawed because different
fold will be calculated when a row is searched in the hash table. */
@@ -76,7 +80,7 @@ fold will be calculated when a row is searched in the hash table. */
#endif
#if 0
-/* This effectively kills the search-for-duplicate-before-adding-a-row
+/** This effectively kills the search-for-duplicate-before-adding-a-row
function, but searching in the hash is still performed. It will always
be assumed that lock is not present and insertion will be performed in
the hash table. */
@@ -84,101 +88,113 @@ the hash table. */
#endif
#if 0
-/* This aggressively repeats adding each row many times. Depending on
+/** This aggressively repeats adding each row many times. Depending on
the above settings this may be noop or may result in lots of rows being
added. */
#define TEST_ADD_EACH_LOCKS_ROW_MANY_TIMES
#endif
#if 0
-/* Very similar to TEST_NO_LOCKS_ROW_IS_EVER_EQUAL_TO_LOCK_T but hash
+/** Very similar to TEST_NO_LOCKS_ROW_IS_EVER_EQUAL_TO_LOCK_T but hash
table search is not performed at all. */
#define TEST_DO_NOT_CHECK_FOR_DUPLICATE_ROWS
#endif
#if 0
-/* Do not insert each row into the hash table, duplicates may appear
+/** Do not insert each row into the hash table, duplicates may appear
if this is enabled, also if this is enabled searching into the hash is
noop because it will be empty. */
#define TEST_DO_NOT_INSERT_INTO_THE_HASH_TABLE
#endif
+/* @} */
+/** Memory limit passed to ha_storage_put_memlim().
+@param cache hash storage
+@return maximum allowed allocation size */
#define MAX_ALLOWED_FOR_STORAGE(cache) \
(TRX_I_S_MEM_LIMIT \
- (cache)->mem_allocd)
+/** Memory limit in table_cache_create_empty_row().
+@param cache hash storage
+@return maximum allowed allocation size */
#define MAX_ALLOWED_FOR_ALLOC(cache) \
(TRX_I_S_MEM_LIMIT \
- (cache)->mem_allocd \
- ha_storage_get_size((cache)->storage))
-/* Memory for each table in the intermediate buffer is allocated in
+/** Memory for each table in the intermediate buffer is allocated in
separate chunks. These chunks are considered to be concatenated to
represent one flat array of rows. */
typedef struct i_s_mem_chunk_struct {
- ulint offset; /* offset, in number of rows */
- ulint rows_allocd; /* the size of this chunk, in number
+ ulint offset; /*!< offset, in number of rows */
+ ulint rows_allocd; /*!< the size of this chunk, in number
of rows */
- void* base; /* start of the chunk */
+ void* base; /*!< start of the chunk */
} i_s_mem_chunk_t;
-/* This represents one table's cache. */
+/** This represents one table's cache. */
typedef struct i_s_table_cache_struct {
- ulint rows_used; /* number of used rows */
- ulint rows_allocd; /* number of allocated rows */
- ulint row_size; /* size of a single row */
- i_s_mem_chunk_t chunks[MEM_CHUNKS_IN_TABLE_CACHE]; /* array of
+ ulint rows_used; /*!< number of used rows */
+ ulint rows_allocd; /*!< number of allocated rows */
+ ulint row_size; /*!< size of a single row */
+ i_s_mem_chunk_t chunks[MEM_CHUNKS_IN_TABLE_CACHE]; /*!< array of
memory chunks that stores the
rows */
} i_s_table_cache_t;
-/* This structure describes the intermediate buffer */
+/** This structure describes the intermediate buffer */
struct trx_i_s_cache_struct {
- rw_lock_t rw_lock; /* read-write lock protecting
+ rw_lock_t rw_lock; /*!< read-write lock protecting
the rest of this structure */
- ullint last_read; /* last time the cache was read;
+ ullint last_read; /*!< last time the cache was read;
measured in microseconds since
epoch */
- mutex_t last_read_mutex;/* mutex protecting the
+ mutex_t last_read_mutex;/*!< mutex protecting the
last_read member - it is updated
inside a shared lock of the
rw_lock member */
- i_s_table_cache_t innodb_trx; /* innodb_trx table */
- i_s_table_cache_t innodb_locks; /* innodb_locks table */
- i_s_table_cache_t innodb_lock_waits;/* innodb_lock_waits table */
-/* the hash table size is LOCKS_HASH_CELLS_NUM * sizeof(void*) bytes */
+ i_s_table_cache_t innodb_trx; /*!< innodb_trx table */
+ i_s_table_cache_t innodb_locks; /*!< innodb_locks table */
+ i_s_table_cache_t innodb_lock_waits;/*!< innodb_lock_waits table */
+/** the hash table size is LOCKS_HASH_CELLS_NUM * sizeof(void*) bytes */
#define LOCKS_HASH_CELLS_NUM 10000
- hash_table_t* locks_hash; /* hash table used to eliminate
+ hash_table_t* locks_hash; /*!< hash table used to eliminate
duplicate entries in the
innodb_locks table */
+/** Initial size of the cache storage */
#define CACHE_STORAGE_INITIAL_SIZE 1024
+/** Number of hash cells in the cache storage */
#define CACHE_STORAGE_HASH_CELLS 2048
- ha_storage_t* storage; /* storage for external volatile
+ ha_storage_t* storage; /*!< storage for external volatile
data that can possibly not be
available later, when we release
the kernel mutex */
- ulint mem_allocd; /* the amount of memory
+ ulint mem_allocd; /*!< the amount of memory
allocated with mem_alloc*() */
- ibool is_truncated; /* this is TRUE if the memory
+ ibool is_truncated; /*!< this is TRUE if the memory
limit was hit and thus the data
in the cache is truncated */
};
-/* This is the intermediate buffer where data needed to fill the
+/** This is the intermediate buffer where data needed to fill the
INFORMATION SCHEMA tables is fetched and later retrieved by the C++
code in handler/i_s.cc. */
static trx_i_s_cache_t trx_i_s_cache_static;
+/** This is the intermediate buffer where data needed to fill the
+INFORMATION SCHEMA tables is fetched and later retrieved by the C++
+code in handler/i_s.cc. */
UNIV_INTERN trx_i_s_cache_t* trx_i_s_cache = &trx_i_s_cache_static;
-/***********************************************************************
+/*******************************************************************//**
For a record lock that is in waiting state retrieves the only bit that
-is set, for a table lock returns ULINT_UNDEFINED. */
+is set, for a table lock returns ULINT_UNDEFINED.
+@return record number within the heap */
static
ulint
wait_lock_get_heap_no(
/*==================*/
- /* out: record number within the heap */
- const lock_t* lock) /* in: lock */
+ const lock_t* lock) /*!< in: lock */
{
ulint ret;
@@ -197,14 +213,14 @@ wait_lock_get_heap_no(
return(ret);
}
-/***********************************************************************
+/*******************************************************************//**
Initializes the members of a table cache. */
static
void
table_cache_init(
/*=============*/
- i_s_table_cache_t* table_cache, /* out: table cache */
- size_t row_size) /* in: the size of a
+ i_s_table_cache_t* table_cache, /*!< out: table cache */
+ size_t row_size) /*!< in: the size of a
row */
{
ulint i;
@@ -221,19 +237,18 @@ table_cache_init(
}
}
-/***********************************************************************
+/*******************************************************************//**
Returns an empty row from a table cache. The row is allocated if no more
empty rows are available. The number of used rows is incremented.
If the memory limit is hit then NULL is returned and nothing is
-allocated. */
+allocated.
+@return empty row, or NULL if out of memory */
static
void*
table_cache_create_empty_row(
/*=========================*/
- /* out: empty row, or
- NULL if out of memory */
- i_s_table_cache_t* table_cache, /* in/out: table cache */
- trx_i_s_cache_t* cache) /* in/out: cache to record
+ i_s_table_cache_t* table_cache, /*!< in/out: table cache */
+ trx_i_s_cache_t* cache) /*!< in/out: cache to record
how many bytes are
allocated */
{
@@ -365,25 +380,24 @@ table_cache_create_empty_row(
return(row);
}
-/***********************************************************************
+/*******************************************************************//**
Fills i_s_trx_row_t object.
-If memory can not be allocated then FALSE is returned. */
+If memory can not be allocated then FALSE is returned.
+@return FALSE if allocation fails */
static
ibool
fill_trx_row(
/*=========*/
- /* out: FALSE if
- allocation fails */
- i_s_trx_row_t* row, /* out: result object
+ i_s_trx_row_t* row, /*!< out: result object
that's filled */
- const trx_t* trx, /* in: transaction to
+ const trx_t* trx, /*!< in: transaction to
get data from */
- const i_s_locks_row_t* requested_lock_row,/* in: pointer to the
+ const i_s_locks_row_t* requested_lock_row,/*!< in: pointer to the
corresponding row in
innodb_locks if trx is
waiting or NULL if trx
is not waiting */
- trx_i_s_cache_t* cache) /* in/out: cache into
+ trx_i_s_cache_t* cache) /*!< in/out: cache into
which to copy volatile
strings */
{
@@ -451,21 +465,21 @@ fill_trx_row(
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
Format the nth field of "rec" and put it in "buf". The result is always
-'\0'-terminated. Returns the number of bytes that were written to "buf"
-(including the terminating '\0'). */
+NUL-terminated. Returns the number of bytes that were written to "buf"
+(including the terminating NUL).
+@return end of the result */
static
ulint
put_nth_field(
/*==========*/
- /* out: end of the result */
- char* buf, /* out: buffer */
- ulint buf_size,/* in: buffer size in bytes */
- ulint n, /* in: number of field */
- const dict_index_t* index, /* in: index */
- const rec_t* rec, /* in: record */
- const ulint* offsets)/* in: record offsets, returned
+ char* buf, /*!< out: buffer */
+ ulint buf_size,/*!< in: buffer size in bytes */
+ ulint n, /*!< in: number of field */
+ const dict_index_t* index, /*!< in: index */
+ const rec_t* rec, /*!< in: record */
+ const ulint* offsets)/*!< in: record offsets, returned
by rec_get_offsets() */
{
const byte* data;
@@ -510,18 +524,18 @@ put_nth_field(
return(ret);
}
-/***********************************************************************
+/*******************************************************************//**
Fills the "lock_data" member of i_s_locks_row_t object.
-If memory can not be allocated then FALSE is returned. */
+If memory can not be allocated then FALSE is returned.
+@return FALSE if allocation fails */
static
ibool
fill_lock_data(
/*===========*/
- /* out: FALSE if allocation fails */
- const char** lock_data,/* out: "lock_data" to fill */
- const lock_t* lock, /* in: lock used to find the data */
- ulint heap_no,/* in: rec num used to find the data */
- trx_i_s_cache_t* cache) /* in/out: cache where to store
+ const char** lock_data,/*!< out: "lock_data" to fill */
+ const lock_t* lock, /*!< in: lock used to find the data */
+ ulint heap_no,/*!< in: rec num used to find the data */
+ trx_i_s_cache_t* cache) /*!< in/out: cache where to store
volatile data */
{
mtr_t mtr;
@@ -619,20 +633,20 @@ fill_lock_data(
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
Fills i_s_locks_row_t object. Returns its first argument.
-If memory can not be allocated then FALSE is returned. */
+If memory can not be allocated then FALSE is returned.
+@return FALSE if allocation fails */
static
ibool
fill_locks_row(
/*===========*/
- /* out: FALSE if allocation fails */
- i_s_locks_row_t* row, /* out: result object that's filled */
- const lock_t* lock, /* in: lock to get data from */
- ulint heap_no,/* in: lock's record number
+ i_s_locks_row_t* row, /*!< out: result object that's filled */
+ const lock_t* lock, /*!< in: lock to get data from */
+ ulint heap_no,/*!< in: lock's record number
or ULINT_UNDEFINED if the lock
is a table lock */
- trx_i_s_cache_t* cache) /* in/out: cache into which to copy
+ trx_i_s_cache_t* cache) /*!< in/out: cache into which to copy
volatile strings */
{
row->lock_trx_id = lock_get_trx_id(lock);
@@ -693,20 +707,19 @@ fill_locks_row(
return(TRUE);
}
-/***********************************************************************
-Fills i_s_lock_waits_row_t object. Returns its first argument. */
+/*******************************************************************//**
+Fills i_s_lock_waits_row_t object. Returns its first argument.
+@return result object that's filled */
static
i_s_lock_waits_row_t*
fill_lock_waits_row(
/*================*/
- /* out: result object
- that's filled */
- i_s_lock_waits_row_t* row, /* out: result object
+ i_s_lock_waits_row_t* row, /*!< out: result object
that's filled */
- const i_s_locks_row_t* requested_lock_row,/* in: pointer to the
+ const i_s_locks_row_t* requested_lock_row,/*!< in: pointer to the
relevant requested lock
row in innodb_locks */
- const i_s_locks_row_t* blocking_lock_row)/* in: pointer to the
+ const i_s_locks_row_t* blocking_lock_row)/*!< in: pointer to the
relevant blocking lock
row in innodb_locks */
{
@@ -716,18 +729,18 @@ fill_lock_waits_row(
return(row);
}
-/***********************************************************************
+/*******************************************************************//**
Calculates a hash fold for a lock. For a record lock the fold is
calculated from 4 elements, which uniquely identify a lock at a given
point in time: transaction id, space id, page number, record number.
-For a table lock the fold is table's id. */
+For a table lock the fold is table's id.
+@return fold */
static
ulint
fold_lock(
/*======*/
- /* out: fold */
- const lock_t* lock, /* in: lock object to fold */
- ulint heap_no)/* in: lock's record number
+ const lock_t* lock, /*!< in: lock object to fold */
+ ulint heap_no)/*!< in: lock's record number
or ULINT_UNDEFINED if the lock
is a table lock */
{
@@ -768,16 +781,16 @@ fold_lock(
#endif
}
-/***********************************************************************
-Checks whether i_s_locks_row_t object represents a lock_t object. */
+/*******************************************************************//**
+Checks whether i_s_locks_row_t object represents a lock_t object.
+@return TRUE if they match */
static
ibool
locks_row_eq_lock(
/*==============*/
- /* out: TRUE if they match */
- const i_s_locks_row_t* row, /* in: innodb_locks row */
- const lock_t* lock, /* in: lock object */
- ulint heap_no)/* in: lock's record number
+ const i_s_locks_row_t* row, /*!< in: innodb_locks row */
+ const lock_t* lock, /*!< in: lock object */
+ ulint heap_no)/*!< in: lock's record number
or ULINT_UNDEFINED if the lock
is a table lock */
{
@@ -809,18 +822,18 @@ locks_row_eq_lock(
#endif
}
-/***********************************************************************
+/*******************************************************************//**
Searches for a row in the innodb_locks cache that has a specified id.
This happens in O(1) time since a hash table is used. Returns pointer to
-the row or NULL if none is found. */
+the row or NULL if none is found.
+@return row or NULL */
static
i_s_locks_row_t*
search_innodb_locks(
/*================*/
- /* out: row or NULL */
- trx_i_s_cache_t* cache, /* in: cache */
- const lock_t* lock, /* in: lock to search for */
- ulint heap_no)/* in: lock's record number
+ trx_i_s_cache_t* cache, /*!< in: cache */
+ const lock_t* lock, /*!< in: lock to search for */
+ ulint heap_no)/*!< in: lock's record number
or ULINT_UNDEFINED if the lock
is a table lock */
{
@@ -851,19 +864,19 @@ search_innodb_locks(
return(hash_chain->value);
}
-/***********************************************************************
+/*******************************************************************//**
Adds new element to the locks cache, enlarging it if necessary.
Returns a pointer to the added row. If the row is already present then
no row is added and a pointer to the existing row is returned.
-If row can not be allocated then NULL is returned. */
+If row can not be allocated then NULL is returned.
+@return row */
static
i_s_locks_row_t*
add_lock_to_cache(
/*==============*/
- /* out: row */
- trx_i_s_cache_t* cache, /* in/out: cache */
- const lock_t* lock, /* in: the element to add */
- ulint heap_no)/* in: lock's record number
+ trx_i_s_cache_t* cache, /*!< in/out: cache */
+ const lock_t* lock, /*!< in: the element to add */
+ ulint heap_no)/*!< in: lock's record number
or ULINT_UNDEFINED if the lock
is a table lock */
{
@@ -918,20 +931,19 @@ add_lock_to_cache(
return(dst_row);
}
-/***********************************************************************
+/*******************************************************************//**
Adds new pair of locks to the lock waits cache.
-If memory can not be allocated then FALSE is returned. */
+If memory can not be allocated then FALSE is returned.
+@return FALSE if allocation fails */
static
ibool
add_lock_wait_to_cache(
/*===================*/
- /* out: FALSE if
- allocation fails */
- trx_i_s_cache_t* cache, /* in/out: cache */
- const i_s_locks_row_t* requested_lock_row,/* in: pointer to the
+ trx_i_s_cache_t* cache, /*!< in/out: cache */
+ const i_s_locks_row_t* requested_lock_row,/*!< in: pointer to the
relevant requested lock
row in innodb_locks */
- const i_s_locks_row_t* blocking_lock_row)/* in: pointer to the
+ const i_s_locks_row_t* blocking_lock_row)/*!< in: pointer to the
relevant blocking lock
row in innodb_locks */
{
@@ -952,21 +964,21 @@ add_lock_wait_to_cache(
return(TRUE);
}
-/***********************************************************************
+/*******************************************************************//**
Adds transaction's relevant (important) locks to cache.
If the transaction is waiting, then the wait lock is added to
innodb_locks and a pointer to the added row is returned in
requested_lock_row, otherwise requested_lock_row is set to NULL.
If rows can not be allocated then FALSE is returned and the value of
-requested_lock_row is undefined. */
+requested_lock_row is undefined.
+@return FALSE if allocation fails */
static
ibool
add_trx_relevant_locks_to_cache(
/*============================*/
- /* out: FALSE if allocation fails */
- trx_i_s_cache_t* cache, /* in/out: cache */
- const trx_t* trx, /* in: transaction */
- i_s_locks_row_t** requested_lock_row)/* out: pointer to the
+ trx_i_s_cache_t* cache, /*!< in/out: cache */
+ const trx_t* trx, /*!< in: transaction */
+ i_s_locks_row_t** requested_lock_row)/*!< out: pointer to the
requested lock row, or NULL or
undefined */
{
@@ -1046,22 +1058,23 @@ add_trx_relevant_locks_to_cache(
return(TRUE);
}
-/***********************************************************************
-Checks if the cache can safely be updated. */
+/** The minimum time that a cache must not be updated after it has been
+read for the last time; measured in microseconds. We use this technique
+to ensure that SELECTs which join several INFORMATION SCHEMA tables read
+the same version of the cache. */
+#define CACHE_MIN_IDLE_TIME_US 100000 /* 0.1 sec */
+
+/*******************************************************************//**
+Checks if the cache can safely be updated.
+@return TRUE if can be updated */
static
ibool
can_cache_be_updated(
/*=================*/
- trx_i_s_cache_t* cache) /* in: cache */
+ trx_i_s_cache_t* cache) /*!< in: cache */
{
ullint now;
-/* The minimum time that a cache must not be updated after it has been
-read for the last time; measured in microseconds. We use this technique
-to ensure that SELECTs which join several INFORMATION SCHEMA tables read
-the same version of the cache. */
-#define CACHE_MIN_IDLE_TIME_US 100000 /* 0.1 sec */
-
/* Here we read cache->last_read without acquiring its mutex
because last_read is only updated when a shared rw lock on the
whole cache is being held (see trx_i_s_cache_end_read()) and
@@ -1082,14 +1095,14 @@ the same version of the cache. */
return(FALSE);
}
-/***********************************************************************
+/*******************************************************************//**
Declare a cache empty, preparing it to be filled up. Not all resources
are freed because they can be reused. */
static
void
trx_i_s_cache_clear(
/*================*/
- trx_i_s_cache_t* cache) /* out: cache to clear */
+ trx_i_s_cache_t* cache) /*!< out: cache to clear */
{
cache->innodb_trx.rows_used = 0;
cache->innodb_locks.rows_used = 0;
@@ -1100,14 +1113,14 @@ trx_i_s_cache_clear(
ha_storage_empty(&cache->storage);
}
-/***********************************************************************
+/*******************************************************************//**
Fetches the data needed to fill the 3 INFORMATION SCHEMA tables into the
table cache buffer. Cache must be locked for write. */
static
void
fetch_data_into_cache(
/*==================*/
- trx_i_s_cache_t* cache) /* in/out: cache */
+ trx_i_s_cache_t* cache) /*!< in/out: cache */
{
trx_t* trx;
i_s_trx_row_t* trx_row;
@@ -1156,15 +1169,15 @@ fetch_data_into_cache(
cache->is_truncated = FALSE;
}
-/***********************************************************************
+/*******************************************************************//**
Update the transactions cache if it has not been read for some time.
-Called from handler/i_s.cc. */
+Called from handler/i_s.cc.
+@return 0 - fetched, 1 - not */
UNIV_INTERN
int
trx_i_s_possibly_fetch_data_into_cache(
/*===================================*/
- /* out: 0 - fetched, 1 - not */
- trx_i_s_cache_t* cache) /* in/out: cache */
+ trx_i_s_cache_t* cache) /*!< in/out: cache */
{
if (!can_cache_be_updated(cache)) {
@@ -1186,26 +1199,26 @@ trx_i_s_possibly_fetch_data_into_cache(
return(0);
}
-/***********************************************************************
+/*******************************************************************//**
Returns TRUE if the data in the cache is truncated due to the memory
-limit posed by TRX_I_S_MEM_LIMIT. */
+limit posed by TRX_I_S_MEM_LIMIT.
+@return TRUE if truncated */
UNIV_INTERN
ibool
trx_i_s_cache_is_truncated(
/*=======================*/
- /* out: TRUE if truncated */
- trx_i_s_cache_t* cache) /* in: cache */
+ trx_i_s_cache_t* cache) /*!< in: cache */
{
return(cache->is_truncated);
}
-/***********************************************************************
+/*******************************************************************//**
Initialize INFORMATION SCHEMA trx related cache. */
UNIV_INTERN
void
trx_i_s_cache_init(
/*===============*/
- trx_i_s_cache_t* cache) /* out: cache to init */
+ trx_i_s_cache_t* cache) /*!< out: cache to init */
{
/* The latching is done in the following order:
acquire trx_i_s_cache_t::rw_lock, X
@@ -1238,24 +1251,24 @@ trx_i_s_cache_init(
cache->is_truncated = FALSE;
}
-/***********************************************************************
+/*******************************************************************//**
Issue a shared/read lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_start_read(
/*=====================*/
- trx_i_s_cache_t* cache) /* in: cache */
+ trx_i_s_cache_t* cache) /*!< in: cache */
{
rw_lock_s_lock(&cache->rw_lock);
}
-/***********************************************************************
+/*******************************************************************//**
Release a shared/read lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_end_read(
/*===================*/
- trx_i_s_cache_t* cache) /* in: cache */
+ trx_i_s_cache_t* cache) /*!< in: cache */
{
ullint now;
@@ -1272,24 +1285,24 @@ trx_i_s_cache_end_read(
rw_lock_s_unlock(&cache->rw_lock);
}
-/***********************************************************************
+/*******************************************************************//**
Issue an exclusive/write lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_start_write(
/*======================*/
- trx_i_s_cache_t* cache) /* in: cache */
+ trx_i_s_cache_t* cache) /*!< in: cache */
{
rw_lock_x_lock(&cache->rw_lock);
}
-/***********************************************************************
+/*******************************************************************//**
Release an exclusive/write lock on the tables cache. */
UNIV_INTERN
void
trx_i_s_cache_end_write(
/*====================*/
- trx_i_s_cache_t* cache) /* in: cache */
+ trx_i_s_cache_t* cache) /*!< in: cache */
{
#ifdef UNIV_SYNC_DEBUG
ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_EX));
@@ -1298,15 +1311,15 @@ trx_i_s_cache_end_write(
rw_lock_x_unlock(&cache->rw_lock);
}
-/***********************************************************************
-Selects a INFORMATION SCHEMA table cache from the whole cache. */
+/*******************************************************************//**
+Selects a INFORMATION SCHEMA table cache from the whole cache.
+@return table cache */
static
i_s_table_cache_t*
cache_select_table(
/*===============*/
- /* out: table cache */
- trx_i_s_cache_t* cache, /* in: whole cache */
- enum i_s_table table) /* in: which table */
+ trx_i_s_cache_t* cache, /*!< in: whole cache */
+ enum i_s_table table) /*!< in: which table */
{
i_s_table_cache_t* table_cache;
@@ -1332,16 +1345,16 @@ cache_select_table(
return(table_cache);
}
-/***********************************************************************
+/*******************************************************************//**
Retrieves the number of used rows in the cache for a given
-INFORMATION SCHEMA table. */
+INFORMATION SCHEMA table.
+@return number of rows */
UNIV_INTERN
ulint
trx_i_s_cache_get_rows_used(
/*========================*/
- /* out: number of rows */
- trx_i_s_cache_t* cache, /* in: cache */
- enum i_s_table table) /* in: which table */
+ trx_i_s_cache_t* cache, /*!< in: cache */
+ enum i_s_table table) /*!< in: which table */
{
i_s_table_cache_t* table_cache;
@@ -1350,17 +1363,17 @@ trx_i_s_cache_get_rows_used(
return(table_cache->rows_used);
}
-/***********************************************************************
+/*******************************************************************//**
Retrieves the nth row (zero-based) in the cache for a given
-INFORMATION SCHEMA table. */
+INFORMATION SCHEMA table.
+@return row */
UNIV_INTERN
void*
trx_i_s_cache_get_nth_row(
/*======================*/
- /* out: row */
- trx_i_s_cache_t* cache, /* in: cache */
- enum i_s_table table, /* in: which table */
- ulint n) /* in: row number */
+ trx_i_s_cache_t* cache, /*!< in: cache */
+ enum i_s_table table, /*!< in: which table */
+ ulint n) /*!< in: row number */
{
i_s_table_cache_t* table_cache;
ulint i;
@@ -1389,19 +1402,19 @@ trx_i_s_cache_get_nth_row(
return(row);
}
-/***********************************************************************
+/*******************************************************************//**
Crafts a lock id string from a i_s_locks_row_t object. Returns its
second argument. This function aborts if there is not enough space in
lock_id. Be sure to provide at least TRX_I_S_LOCK_ID_MAX_LEN + 1 if you
-want to be 100% sure that it will not abort. */
+want to be 100% sure that it will not abort.
+@return resulting lock id */
UNIV_INTERN
char*
trx_i_s_create_lock_id(
/*===================*/
- /* out: resulting lock id */
- const i_s_locks_row_t* row, /* in: innodb_locks row */
- char* lock_id,/* out: resulting lock_id */
- ulint lock_id_size)/* in: size of the lock id
+ const i_s_locks_row_t* row, /*!< in: innodb_locks row */
+ char* lock_id,/*!< out: resulting lock_id */
+ ulint lock_id_size)/*!< in: size of the lock id
buffer */
{
int res_len;
diff --git a/storage/xtradb/trx/trx0purge.c b/storage/xtradb/trx/trx0purge.c
index 7a2a27a94ff..cd79fd1c315 100644
--- a/storage/xtradb/trx/trx0purge.c
+++ b/storage/xtradb/trx/trx0purge.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0purge.c
Purge old versions
Created 3/26/1996 Heikki Tuuri
@@ -30,6 +31,7 @@ Created 3/26/1996 Heikki Tuuri
#include "fsp0fsp.h"
#include "mach0data.h"
+#include "mtr0log.h"
#include "trx0rseg.h"
#include "trx0trx.h"
#include "trx0roll.h"
@@ -42,24 +44,24 @@ Created 3/26/1996 Heikki Tuuri
#include "srv0que.h"
#include "os0thread.h"
-/* The global data structure coordinating a purge */
+/** The global data structure coordinating a purge */
UNIV_INTERN trx_purge_t* purge_sys = NULL;
-/* A dummy undo record used as a return value when we have a whole undo log
+/** A dummy undo record used as a return value when we have a whole undo log
which needs no purge */
UNIV_INTERN trx_undo_rec_t trx_purge_dummy_rec;
-/*********************************************************************
+/*****************************************************************//**
Checks if trx_id is >= purge_view: then it is guaranteed that its update
-undo log still exists in the system. */
+undo log still exists in the system.
+@return TRUE if is sure that it is preserved, also if the function
+returns FALSE, it is possible that the undo log still exists in the
+system */
UNIV_INTERN
ibool
trx_purge_update_undo_must_exist(
/*=============================*/
- /* out: TRUE if is sure that it is preserved, also
- if the function returns FALSE, it is possible that
- the undo log still exists in the system */
- dulint trx_id) /* in: transaction id */
+ trx_id_t trx_id) /*!< in: transaction id */
{
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
@@ -75,15 +77,15 @@ trx_purge_update_undo_must_exist(
/*=================== PURGE RECORD ARRAY =============================*/
-/***********************************************************************
-Stores info of an undo log record during a purge. */
+/*******************************************************************//**
+Stores info of an undo log record during a purge.
+@return pointer to the storage cell */
static
trx_undo_inf_t*
trx_purge_arr_store_info(
/*=====================*/
- /* out: pointer to the storage cell */
- dulint trx_no, /* in: transaction number */
- dulint undo_no)/* in: undo number */
+ trx_id_t trx_no, /*!< in: transaction number */
+ undo_no_t undo_no)/*!< in: undo number */
{
trx_undo_inf_t* cell;
trx_undo_arr_t* arr;
@@ -107,13 +109,13 @@ trx_purge_arr_store_info(
}
}
-/***********************************************************************
+/*******************************************************************//**
Removes info of an undo log record during a purge. */
UNIV_INLINE
void
trx_purge_arr_remove_info(
/*======================*/
- trx_undo_inf_t* cell) /* in: pointer to the storage cell */
+ trx_undo_inf_t* cell) /*!< in: pointer to the storage cell */
{
trx_undo_arr_t* arr;
@@ -126,20 +128,20 @@ trx_purge_arr_remove_info(
arr->n_used--;
}
-/***********************************************************************
+/*******************************************************************//**
Gets the biggest pair of a trx number and an undo number in a purge array. */
static
void
trx_purge_arr_get_biggest(
/*======================*/
- trx_undo_arr_t* arr, /* in: purge array */
- dulint* trx_no, /* out: transaction number: ut_dulint_zero
+ trx_undo_arr_t* arr, /*!< in: purge array */
+ trx_id_t* trx_no, /*!< out: transaction number: ut_dulint_zero
if array is empty */
- dulint* undo_no)/* out: undo number */
+ undo_no_t* undo_no)/*!< out: undo number */
{
trx_undo_inf_t* cell;
- dulint pair_trx_no;
- dulint pair_undo_no;
+ trx_id_t pair_trx_no;
+ undo_no_t pair_undo_no;
int trx_cmp;
ulint n_used;
ulint i;
@@ -176,14 +178,14 @@ trx_purge_arr_get_biggest(
}
}
-/********************************************************************
+/****************************************************************//**
Builds a purge 'query' graph. The actual purge is performed by executing
-this query graph. */
+this query graph.
+@return own: the query graph */
static
que_t*
trx_purge_graph_build(void)
/*=======================*/
- /* out, own: the query graph */
{
mem_heap_t* heap;
que_fork_t* fork;
@@ -205,7 +207,7 @@ trx_purge_graph_build(void)
return(fork);
}
-/************************************************************************
+/********************************************************************//**
Creates the global purge system control structure and inits the history
mutex. */
UNIV_INTERN
@@ -249,17 +251,17 @@ trx_purge_sys_create(void)
/*================ UNDO LOG HISTORY LIST =============================*/
-/************************************************************************
+/********************************************************************//**
Adds the update undo log as the first log in the history list. Removes the
update undo log segment from the rseg slot if it is too big for reuse. */
UNIV_INTERN
void
trx_purge_add_update_undo_to_history(
/*=================================*/
- trx_t* trx, /* in: transaction */
- page_t* undo_page, /* in: update undo log header page,
+ trx_t* trx, /*!< in: transaction */
+ page_t* undo_page, /*!< in: update undo log header page,
x-latched */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_undo_t* undo;
trx_rseg_t* rseg;
@@ -330,16 +332,16 @@ trx_purge_add_update_undo_to_history(
}
}
-/**************************************************************************
+/**********************************************************************//**
Frees an undo log segment which is in the history list. Cuts the end of the
history list at the youngest undo log in this segment. */
static
void
trx_purge_free_segment(
/*===================*/
- trx_rseg_t* rseg, /* in: rollback segment */
- fil_addr_t hdr_addr, /* in: the file address of log_hdr */
- ulint n_removed_logs) /* in: count of how many undo logs we
+ trx_rseg_t* rseg, /*!< in: rollback segment */
+ fil_addr_t hdr_addr, /*!< in: the file address of log_hdr */
+ ulint n_removed_logs) /*!< in: count of how many undo logs we
will cut off from the end of the
history list */
{
@@ -436,16 +438,16 @@ loop:
mtr_commit(&mtr);
}
-/************************************************************************
+/********************************************************************//**
Removes unnecessary history data from a rollback segment. */
static
void
trx_purge_truncate_rseg_history(
/*============================*/
- trx_rseg_t* rseg, /* in: rollback segment */
- dulint limit_trx_no, /* in: remove update undo logs whose
+ trx_rseg_t* rseg, /*!< in: rollback segment */
+ trx_id_t limit_trx_no, /*!< in: remove update undo logs whose
trx number is < limit_trx_no */
- dulint limit_undo_no) /* in: if transaction number is equal
+ undo_no_t limit_undo_no) /*!< in: if transaction number is equal
to limit_trx_no, truncate undo records
with undo number < limit_undo_no */
{
@@ -540,7 +542,7 @@ loop:
goto loop;
}
-/************************************************************************
+/********************************************************************//**
Removes unnecessary history data from rollback segments. NOTE that when this
function is called, the caller must not have any latches on undo log pages! */
static
@@ -549,8 +551,8 @@ trx_purge_truncate_history(void)
/*============================*/
{
trx_rseg_t* rseg;
- dulint limit_trx_no;
- dulint limit_undo_no;
+ trx_id_t limit_trx_no;
+ undo_no_t limit_undo_no;
ut_ad(mutex_own(&(purge_sys->mutex)));
@@ -583,14 +585,14 @@ trx_purge_truncate_history(void)
}
}
-/************************************************************************
+/********************************************************************//**
Does a truncate if the purge array is empty. NOTE that when this function is
-called, the caller must not have any latches on undo log pages! */
+called, the caller must not have any latches on undo log pages!
+@return TRUE if array empty */
UNIV_INLINE
ibool
trx_purge_truncate_if_arr_empty(void)
/*=================================*/
- /* out: TRUE if array empty */
{
ut_ad(mutex_own(&(purge_sys->mutex)));
@@ -604,20 +606,20 @@ trx_purge_truncate_if_arr_empty(void)
return(FALSE);
}
-/***************************************************************************
+/***********************************************************************//**
Updates the last not yet purged history log info in rseg when we have purged
a whole undo log. Advances also purge_sys->purge_trx_no past the purged log. */
static
void
trx_purge_rseg_get_next_history_log(
/*================================*/
- trx_rseg_t* rseg) /* in: rollback segment */
+ trx_rseg_t* rseg) /*!< in: rollback segment */
{
page_t* undo_page;
trx_ulogf_t* log_hdr;
trx_usegf_t* seg_hdr;
fil_addr_t prev_log_addr;
- dulint trx_no;
+ trx_id_t trx_no;
ibool del_marks;
mtr_t mtr;
@@ -705,7 +707,7 @@ trx_purge_rseg_get_next_history_log(
mutex_exit(&(rseg->mutex));
}
-/***************************************************************************
+/***********************************************************************//**
Chooses the next undo log to purge and updates the info in purge_sys. This
function is used to initialize purge_sys when the next record to purge is
not known, and also to update the purge system info on the next record when
@@ -718,7 +720,7 @@ trx_purge_choose_next_log(void)
trx_undo_rec_t* rec;
trx_rseg_t* rseg;
trx_rseg_t* min_rseg;
- dulint min_trx_no;
+ trx_id_t min_trx_no;
ulint space = 0; /* remove warning (??? bug ???) */
ulint zip_size = 0;
ulint page_no = 0; /* remove warning (??? bug ???) */
@@ -804,15 +806,14 @@ trx_purge_choose_next_log(void)
mtr_commit(&mtr);
}
-/***************************************************************************
-Gets the next record to purge and updates the info in the purge system. */
+/***********************************************************************//**
+Gets the next record to purge and updates the info in the purge system.
+@return copy of an undo log record or pointer to the dummy undo log record */
static
trx_undo_rec_t*
trx_purge_get_next_rec(
/*===================*/
- /* out: copy of an undo log record or
- pointer to the dummy undo log record */
- mem_heap_t* heap) /* in: memory heap where copied */
+ mem_heap_t* heap) /*!< in: memory heap where copied */
{
trx_undo_rec_t* rec;
trx_undo_rec_t* rec_copy;
@@ -927,21 +928,19 @@ trx_purge_get_next_rec(
return(rec_copy);
}
-/************************************************************************
+/********************************************************************//**
Fetches the next undo log record from the history list to purge. It must be
-released with the corresponding release function. */
+released with the corresponding release function.
+@return copy of an undo log record or pointer to trx_purge_dummy_rec,
+if the whole undo log can skipped in purge; NULL if none left */
UNIV_INTERN
trx_undo_rec_t*
trx_purge_fetch_next_rec(
/*=====================*/
- /* out: copy of an undo log record or
- pointer to the dummy undo log record
- &trx_purge_dummy_rec, if the whole undo log
- can skipped in purge; NULL if none left */
- dulint* roll_ptr,/* out: roll pointer to undo record */
- trx_undo_inf_t** cell, /* out: storage cell for the record in the
+ roll_ptr_t* roll_ptr,/*!< out: roll pointer to undo record */
+ trx_undo_inf_t** cell, /*!< out: storage cell for the record in the
purge array */
- mem_heap_t* heap) /* in: memory heap where copied */
+ mem_heap_t* heap) /*!< in: memory heap where copied */
{
trx_undo_rec_t* undo_rec;
@@ -1023,13 +1022,13 @@ trx_purge_fetch_next_rec(
return(undo_rec);
}
-/***********************************************************************
+/*******************************************************************//**
Releases a reserved purge undo record. */
UNIV_INTERN
void
trx_purge_rec_release(
/*==================*/
- trx_undo_inf_t* cell) /* in: storage cell */
+ trx_undo_inf_t* cell) /*!< in: storage cell */
{
trx_undo_arr_t* arr;
@@ -1042,14 +1041,13 @@ trx_purge_rec_release(
mutex_exit(&(purge_sys->mutex));
}
-/***********************************************************************
-This function runs a purge batch. */
+/*******************************************************************//**
+This function runs a purge batch.
+@return number of undo log pages handled in the batch */
UNIV_INTERN
ulint
trx_purge(void)
/*===========*/
- /* out: number of undo log pages handled in
- the batch */
{
que_thr_t* thr;
/* que_thr_t* thr2; */
@@ -1150,7 +1148,7 @@ trx_purge(void)
return(purge_sys->n_pages_handled - old_pages_handled);
}
-/**********************************************************************
+/******************************************************************//**
Prints information of the purge system to stderr. */
UNIV_INTERN
void
diff --git a/storage/xtradb/trx/trx0rec.c b/storage/xtradb/trx/trx0rec.c
index 148f93cdbe7..36911c9df85 100644
--- a/storage/xtradb/trx/trx0rec.c
+++ b/storage/xtradb/trx/trx0rec.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0rec.c
Transaction undo log record
Created 3/26/1996 Heikki Tuuri
@@ -30,30 +31,31 @@ Created 3/26/1996 Heikki Tuuri
#include "fsp0fsp.h"
#include "mach0data.h"
-#include "trx0rseg.h"
-#include "trx0trx.h"
#include "trx0undo.h"
+#include "mtr0log.h"
+#ifndef UNIV_HOTBACKUP
#include "dict0dict.h"
#include "ut0mem.h"
#include "row0ext.h"
#include "row0upd.h"
#include "que0que.h"
#include "trx0purge.h"
+#include "trx0rseg.h"
#include "row0row.h"
/*=========== UNDO LOG RECORD CREATION AND DECODING ====================*/
-/**************************************************************************
+/**********************************************************************//**
Writes the mtr log entry of the inserted undo log record on the undo log
page. */
UNIV_INLINE
void
trx_undof_page_add_undo_rec_log(
/*============================*/
- page_t* undo_page, /* in: undo log page */
- ulint old_free, /* in: start offset of the inserted entry */
- ulint new_free, /* in: end offset of the entry */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in: undo log page */
+ ulint old_free, /*!< in: start offset of the inserted entry */
+ ulint new_free, /*!< in: end offset of the entry */
+ mtr_t* mtr) /*!< in: mtr */
{
byte* log_ptr;
const byte* log_end;
@@ -82,17 +84,18 @@ trx_undof_page_add_undo_rec_log(
mlog_catenate_string(mtr, undo_page + old_free + 2, len);
}
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses a redo log record of adding an undo log record. */
+/***********************************************************//**
+Parses a redo log record of adding an undo log record.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_add_undo_rec(
/*========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page) /* in: page or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page) /*!< in: page or NULL */
{
ulint len;
byte* rec;
@@ -130,15 +133,16 @@ trx_undo_parse_add_undo_rec(
return(ptr + len);
}
-/**************************************************************************
-Calculates the free space left for extending an undo log record. */
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
+Calculates the free space left for extending an undo log record.
+@return bytes left */
UNIV_INLINE
ulint
trx_undo_left(
/*==========*/
- /* out: bytes left */
- const page_t* page, /* in: undo log page */
- const byte* ptr) /* in: pointer to page */
+ const page_t* page, /*!< in: undo log page */
+ const byte* ptr) /*!< in: pointer to page */
{
/* The '- 10' is a safety margin, in case we have some small
calculation error below */
@@ -146,23 +150,22 @@ trx_undo_left(
return(UNIV_PAGE_SIZE - (ptr - page) - 10 - FIL_PAGE_DATA_END);
}
-/**************************************************************************
+/**********************************************************************//**
Set the next and previous pointers in the undo page for the undo record
that was written to ptr. Update the first free value by the number of bytes
-written for this undo record.*/
+written for this undo record.
+@return offset of the inserted entry on the page if succeeded, 0 if fail */
static
ulint
trx_undo_page_set_next_prev_and_add(
/*================================*/
- /* out: offset of the inserted entry
- on the page if succeeded, 0 if fail */
- page_t* undo_page, /* in/out: undo log page */
- byte* ptr, /* in: ptr up to where data has been
+ page_t* undo_page, /*!< in/out: undo log page */
+ byte* ptr, /*!< in: ptr up to where data has been
written on this undo page. */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
- ulint first_free; /* offset within undo_page */
- ulint end_of_rec; /* offset within undo_page */
+ ulint first_free; /*!< offset within undo_page */
+ ulint end_of_rec; /*!< offset within undo_page */
byte* ptr_to_first_free;
/* pointer within undo_page
that points to the next free
@@ -199,20 +202,19 @@ trx_undo_page_set_next_prev_and_add(
return(first_free);
}
-/**************************************************************************
-Reports in the undo log of an insert of a clustered index record. */
+/**********************************************************************//**
+Reports in the undo log of an insert of a clustered index record.
+@return offset of the inserted entry on the page if succeed, 0 if fail */
static
ulint
trx_undo_page_report_insert(
/*========================*/
- /* out: offset of the inserted entry
- on the page if succeed, 0 if fail */
- page_t* undo_page, /* in: undo log page */
- trx_t* trx, /* in: transaction */
- dict_index_t* index, /* in: clustered index */
- const dtuple_t* clust_entry, /* in: index entry which will be
+ page_t* undo_page, /*!< in: undo log page */
+ trx_t* trx, /*!< in: transaction */
+ dict_index_t* index, /*!< in: clustered index */
+ const dtuple_t* clust_entry, /*!< in: index entry which will be
inserted to the clustered index */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint first_free;
byte* ptr;
@@ -272,23 +274,22 @@ trx_undo_page_report_insert(
return(trx_undo_page_set_next_prev_and_add(undo_page, ptr, mtr));
}
-/**************************************************************************
-Reads from an undo log record the general parameters. */
+/**********************************************************************//**
+Reads from an undo log record the general parameters.
+@return remaining part of undo log record after reading these values */
UNIV_INTERN
byte*
trx_undo_rec_get_pars(
/*==================*/
- /* out: remaining part of undo log
- record after reading these values */
- trx_undo_rec_t* undo_rec, /* in: undo log record */
- ulint* type, /* out: undo record type:
+ trx_undo_rec_t* undo_rec, /*!< in: undo log record */
+ ulint* type, /*!< out: undo record type:
TRX_UNDO_INSERT_REC, ... */
- ulint* cmpl_info, /* out: compiler info, relevant only
+ ulint* cmpl_info, /*!< out: compiler info, relevant only
for update type records */
- ibool* updated_extern, /* out: TRUE if we updated an
+ ibool* updated_extern, /*!< out: TRUE if we updated an
externally stored fild */
- dulint* undo_no, /* out: undo log record number */
- dulint* table_id) /* out: table id */
+ undo_no_t* undo_no, /*!< out: undo log record number */
+ dulint* table_id) /*!< out: table id */
{
byte* ptr;
ulint type_cmpl;
@@ -317,18 +318,17 @@ trx_undo_rec_get_pars(
return(ptr);
}
-/**************************************************************************
-Reads from an undo log record a stored column value. */
+/**********************************************************************//**
+Reads from an undo log record a stored column value.
+@return remaining part of undo log record after reading these values */
static
byte*
trx_undo_rec_get_col_val(
/*=====================*/
- /* out: remaining part of undo log record after
- reading these values */
- byte* ptr, /* in: pointer to remaining part of undo log record */
- byte** field, /* out: pointer to stored field */
- ulint* len, /* out: length of the field, or UNIV_SQL_NULL */
- ulint* orig_len)/* out: original length of the locally
+ byte* ptr, /*!< in: pointer to remaining part of undo log record */
+ byte** field, /*!< out: pointer to stored field */
+ ulint* len, /*!< out: length of the field, or UNIV_SQL_NULL */
+ ulint* orig_len)/*!< out: original length of the locally
stored part of an externally stored column, or 0 */
{
*len = mach_read_compressed(ptr);
@@ -367,23 +367,22 @@ trx_undo_rec_get_col_val(
return(ptr);
}
-/***********************************************************************
-Builds a row reference from an undo log record. */
+/*******************************************************************//**
+Builds a row reference from an undo log record.
+@return pointer to remaining part of undo record */
UNIV_INTERN
byte*
trx_undo_rec_get_row_ref(
/*=====================*/
- /* out: pointer to remaining part of undo
- record */
- byte* ptr, /* in: remaining part of a copy of an undo log
+ byte* ptr, /*!< in: remaining part of a copy of an undo log
record, at the start of the row reference;
NOTE that this copy of the undo log record must
be preserved as long as the row reference is
used, as we do NOT copy the data in the
record! */
- dict_index_t* index, /* in: clustered index */
- dtuple_t** ref, /* out, own: row reference */
- mem_heap_t* heap) /* in: memory heap from which the memory
+ dict_index_t* index, /*!< in: clustered index */
+ dtuple_t** ref, /*!< out, own: row reference */
+ mem_heap_t* heap) /*!< in: memory heap from which the memory
needed is allocated */
{
ulint ref_len;
@@ -414,17 +413,16 @@ trx_undo_rec_get_row_ref(
return(ptr);
}
-/***********************************************************************
-Skips a row reference from an undo log record. */
+/*******************************************************************//**
+Skips a row reference from an undo log record.
+@return pointer to remaining part of undo record */
UNIV_INTERN
byte*
trx_undo_rec_skip_row_ref(
/*======================*/
- /* out: pointer to remaining part of undo
- record */
- byte* ptr, /* in: remaining part in update undo log
+ byte* ptr, /*!< in: remaining part in update undo log
record, at the start of the row reference */
- dict_index_t* index) /* in: clustered index */
+ dict_index_t* index) /*!< in: clustered index */
{
ulint ref_len;
ulint i;
@@ -445,21 +443,21 @@ trx_undo_rec_skip_row_ref(
return(ptr);
}
-/**************************************************************************
+/**********************************************************************//**
Fetch a prefix of an externally stored column, for writing to the undo log
-of an update or delete marking of a clustered index record. */
+of an update or delete marking of a clustered index record.
+@return ext_buf */
static
byte*
trx_undo_page_fetch_ext(
/*====================*/
- /* out: ext_buf */
- byte* ext_buf, /* in: a buffer of
+ byte* ext_buf, /*!< in: a buffer of
REC_MAX_INDEX_COL_LEN
+ BTR_EXTERN_FIELD_REF_SIZE */
- ulint zip_size, /* compressed page size in bytes,
+ ulint zip_size, /*!< compressed page size in bytes,
or 0 for uncompressed BLOB */
- const byte* field, /* in: an externally stored column */
- ulint* len) /* in: length of field;
+ const byte* field, /*!< in: an externally stored column */
+ ulint* len) /*!< in: length of field;
out: used length of ext_buf */
{
/* Fetch the BLOB. */
@@ -475,25 +473,25 @@ trx_undo_page_fetch_ext(
return(ext_buf);
}
-/**************************************************************************
-Writes to the undo log a prefix of an externally stored column. */
+/**********************************************************************//**
+Writes to the undo log a prefix of an externally stored column.
+@return undo log position */
static
byte*
trx_undo_page_report_modify_ext(
/*============================*/
- /* out: undo log position */
- byte* ptr, /* in: undo log position,
+ byte* ptr, /*!< in: undo log position,
at least 15 bytes must be available */
- byte* ext_buf, /* in: a buffer of
+ byte* ext_buf, /*!< in: a buffer of
REC_MAX_INDEX_COL_LEN
+ BTR_EXTERN_FIELD_REF_SIZE,
or NULL when should not fetch
a longer prefix */
- ulint zip_size, /* compressed page size in bytes,
+ ulint zip_size, /*!< compressed page size in bytes,
or 0 for uncompressed BLOB */
- const byte** field, /* in/out: the locally stored part of
+ const byte** field, /*!< in/out: the locally stored part of
the externally stored column */
- ulint* len) /* in/out: length of field, in bytes */
+ ulint* len) /*!< in/out: length of field, in bytes */
{
if (ext_buf) {
/* If an ordering column is externally stored, we will
@@ -516,29 +514,28 @@ trx_undo_page_report_modify_ext(
return(ptr);
}
-/**************************************************************************
+/**********************************************************************//**
Reports in the undo log of an update or delete marking of a clustered index
-record. */
+record.
+@return byte offset of the inserted undo log entry on the page if
+succeed, 0 if fail */
static
ulint
trx_undo_page_report_modify(
/*========================*/
- /* out: byte offset of the inserted
- undo log entry on the page if succeed,
- 0 if fail */
- page_t* undo_page, /* in: undo log page */
- trx_t* trx, /* in: transaction */
- dict_index_t* index, /* in: clustered index where update or
+ page_t* undo_page, /*!< in: undo log page */
+ trx_t* trx, /*!< in: transaction */
+ dict_index_t* index, /*!< in: clustered index where update or
delete marking is done */
- const rec_t* rec, /* in: clustered index record which
+ const rec_t* rec, /*!< in: clustered index record which
has NOT yet been modified */
- const ulint* offsets, /* in: rec_get_offsets(rec, index) */
- const upd_t* update, /* in: update vector which tells the
+ const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */
+ const upd_t* update, /*!< in: update vector which tells the
columns to be updated; in the case of
a delete, this should be set to NULL */
- ulint cmpl_info, /* in: compiler info on secondary
+ ulint cmpl_info, /*!< in: compiler info on secondary
index updates */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
dict_table_t* table;
ulint first_free;
@@ -549,7 +546,7 @@ trx_undo_page_report_modify(
ulint type_cmpl;
byte* type_cmpl_ptr;
ulint i;
- dulint trx_id;
+ trx_id_t trx_id;
ibool ignore_prefix = FALSE;
byte ext_buf[REC_MAX_INDEX_COL_LEN
+ BTR_EXTERN_FIELD_REF_SIZE];
@@ -825,21 +822,20 @@ trx_undo_page_report_modify(
return(first_free);
}
-/**************************************************************************
+/**********************************************************************//**
Reads from an undo log update record the system field values of the old
-version. */
+version.
+@return remaining part of undo log record after reading these values */
UNIV_INTERN
byte*
trx_undo_update_rec_get_sys_cols(
/*=============================*/
- /* out: remaining part of undo log
- record after reading these values */
- byte* ptr, /* in: remaining part of undo log
- record after reading general
- parameters */
- dulint* trx_id, /* out: trx id */
- dulint* roll_ptr, /* out: roll ptr */
- ulint* info_bits) /* out: info bits state */
+ byte* ptr, /*!< in: remaining part of undo
+ log record after reading
+ general parameters */
+ trx_id_t* trx_id, /*!< out: trx id */
+ roll_ptr_t* roll_ptr, /*!< out: roll ptr */
+ ulint* info_bits) /*!< out: info bits state */
{
/* Read the state of the info bits */
*info_bits = mach_read_from_1(ptr);
@@ -856,16 +852,15 @@ trx_undo_update_rec_get_sys_cols(
return(ptr);
}
-/**************************************************************************
-Reads from an update undo log record the number of updated fields. */
+/**********************************************************************//**
+Reads from an update undo log record the number of updated fields.
+@return remaining part of undo log record after reading this value */
UNIV_INLINE
byte*
trx_undo_update_rec_get_n_upd_fields(
/*=================================*/
- /* out: remaining part of undo log record after
- reading this value */
- byte* ptr, /* in: pointer to remaining part of undo log record */
- ulint* n) /* out: number of fields */
+ byte* ptr, /*!< in: pointer to remaining part of undo log record */
+ ulint* n) /*!< out: number of fields */
{
*n = mach_read_compressed(ptr);
ptr += mach_get_compressed_size(*n);
@@ -873,16 +868,15 @@ trx_undo_update_rec_get_n_upd_fields(
return(ptr);
}
-/**************************************************************************
-Reads from an update undo log record a stored field number. */
+/**********************************************************************//**
+Reads from an update undo log record a stored field number.
+@return remaining part of undo log record after reading this value */
UNIV_INLINE
byte*
trx_undo_update_rec_get_field_no(
/*=============================*/
- /* out: remaining part of undo log record after
- reading this value */
- byte* ptr, /* in: pointer to remaining part of undo log record */
- ulint* field_no)/* out: field number */
+ byte* ptr, /*!< in: pointer to remaining part of undo log record */
+ ulint* field_no)/*!< out: field number */
{
*field_no = mach_read_compressed(ptr);
ptr += mach_get_compressed_size(*field_no);
@@ -890,34 +884,33 @@ trx_undo_update_rec_get_field_no(
return(ptr);
}
-/***********************************************************************
-Builds an update vector based on a remaining part of an undo log record. */
+/*******************************************************************//**
+Builds an update vector based on a remaining part of an undo log record.
+@return remaining part of the record, NULL if an error detected, which
+means that the record is corrupted */
UNIV_INTERN
byte*
trx_undo_update_rec_get_update(
/*===========================*/
- /* out: remaining part of the record,
- NULL if an error detected, which means that
- the record is corrupted */
- byte* ptr, /* in: remaining part in update undo log
+ byte* ptr, /*!< in: remaining part in update undo log
record, after reading the row reference
NOTE that this copy of the undo log record must
be preserved as long as the update vector is
used, as we do NOT copy the data in the
record! */
- dict_index_t* index, /* in: clustered index */
- ulint type, /* in: TRX_UNDO_UPD_EXIST_REC,
+ dict_index_t* index, /*!< in: clustered index */
+ ulint type, /*!< in: TRX_UNDO_UPD_EXIST_REC,
TRX_UNDO_UPD_DEL_REC, or
TRX_UNDO_DEL_MARK_REC; in the last case,
only trx id and roll ptr fields are added to
the update vector */
- dulint trx_id, /* in: transaction id from this undo record */
- dulint roll_ptr,/* in: roll pointer from this undo record */
- ulint info_bits,/* in: info bits from this undo record */
- trx_t* trx, /* in: transaction */
- mem_heap_t* heap, /* in: memory heap from which the memory
+ trx_id_t trx_id, /*!< in: transaction id from this undo record */
+ roll_ptr_t roll_ptr,/*!< in: roll pointer from this undo record */
+ ulint info_bits,/*!< in: info bits from this undo record */
+ trx_t* trx, /*!< in: transaction */
+ mem_heap_t* heap, /*!< in: memory heap from which the memory
needed is allocated */
- upd_t** upd) /* out, own: update vector */
+ upd_t** upd) /*!< out, own: update vector */
{
upd_field_t* upd_field;
upd_t* update;
@@ -1012,28 +1005,27 @@ trx_undo_update_rec_get_update(
return(ptr);
}
-/***********************************************************************
+/*******************************************************************//**
Builds a partial row from an update undo log record. It contains the
-columns which occur as ordering in any index of the table. */
+columns which occur as ordering in any index of the table.
+@return pointer to remaining part of undo record */
UNIV_INTERN
byte*
trx_undo_rec_get_partial_row(
/*=========================*/
- /* out: pointer to remaining part of undo
- record */
- byte* ptr, /* in: remaining part in update undo log
+ byte* ptr, /*!< in: remaining part in update undo log
record of a suitable type, at the start of
the stored index columns;
NOTE that this copy of the undo log record must
be preserved as long as the partial row is
used, as we do NOT copy the data in the
record! */
- dict_index_t* index, /* in: clustered index */
- dtuple_t** row, /* out, own: partial row */
- ibool ignore_prefix, /* in: flag to indicate if we
+ dict_index_t* index, /*!< in: clustered index */
+ dtuple_t** row, /*!< out, own: partial row */
+ ibool ignore_prefix, /*!< in: flag to indicate if we
expect blob prefixes in undo. Used
only in the assertion. */
- mem_heap_t* heap) /* in: memory heap from which the memory
+ mem_heap_t* heap) /*!< in: memory heap from which the memory
needed is allocated */
{
const byte* end_ptr;
@@ -1092,15 +1084,16 @@ trx_undo_rec_get_partial_row(
return(ptr);
}
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************************
+/***********************************************************************//**
Erases the unused undo log page end. */
static
void
trx_undo_erase_page_end(
/*====================*/
- page_t* undo_page, /* in: undo page whose end to erase */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in: undo page whose end to erase */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint first_free;
@@ -1112,17 +1105,17 @@ trx_undo_erase_page_end(
mlog_write_initial_log_record(undo_page, MLOG_UNDO_ERASE_END, mtr);
}
-/***************************************************************
-Parses a redo log record of erasing of an undo page end. */
+/***********************************************************//**
+Parses a redo log record of erasing of an undo page end.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_erase_page_end(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr __attribute__((unused)), /* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr __attribute__((unused)), /*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ut_ad(ptr && end_ptr);
@@ -1136,33 +1129,34 @@ trx_undo_parse_erase_page_end(
return(ptr);
}
-/***************************************************************************
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
Writes information to an undo log about an insert, update, or a delete marking
of a clustered index record. This information is used in a rollback of the
transaction and in consistent reads that must look to the history of this
-transaction. */
+transaction.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
trx_undo_report_row_operation(
/*==========================*/
- /* out: DB_SUCCESS or error code */
- ulint flags, /* in: if BTR_NO_UNDO_LOG_FLAG bit is
+ ulint flags, /*!< in: if BTR_NO_UNDO_LOG_FLAG bit is
set, does nothing */
- ulint op_type, /* in: TRX_UNDO_INSERT_OP or
+ ulint op_type, /*!< in: TRX_UNDO_INSERT_OP or
TRX_UNDO_MODIFY_OP */
- que_thr_t* thr, /* in: query thread */
- dict_index_t* index, /* in: clustered index */
- const dtuple_t* clust_entry, /* in: in the case of an insert,
+ que_thr_t* thr, /*!< in: query thread */
+ dict_index_t* index, /*!< in: clustered index */
+ const dtuple_t* clust_entry, /*!< in: in the case of an insert,
index entry to insert into the
clustered index, otherwise NULL */
- const upd_t* update, /* in: in the case of an update,
+ const upd_t* update, /*!< in: in the case of an update,
the update vector, otherwise NULL */
- ulint cmpl_info, /* in: compiler info on secondary
+ ulint cmpl_info, /*!< in: compiler info on secondary
index updates */
- const rec_t* rec, /* in: in case of an update or delete
+ const rec_t* rec, /*!< in: in case of an update or delete
marking, the record in the clustered
index, otherwise NULL */
- dulint* roll_ptr) /* out: rollback pointer to the
+ roll_ptr_t* roll_ptr) /*!< out: rollback pointer to the
inserted undo log record,
ut_dulint_zero if BTR_NO_UNDO_LOG
flag was specified */
@@ -1324,16 +1318,16 @@ trx_undo_report_row_operation(
/*============== BUILDING PREVIOUS VERSION OF A RECORD ===============*/
-/**********************************************************************
+/******************************************************************//**
Copies an undo record to heap. This function can be called if we know that
-the undo log record exists. */
+the undo log record exists.
+@return own: copy of the record */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_undo_rec_low(
/*======================*/
- /* out, own: copy of the record */
- dulint roll_ptr, /* in: roll pointer to record */
- mem_heap_t* heap) /* in: memory heap where copied */
+ roll_ptr_t roll_ptr, /*!< in: roll pointer to record */
+ mem_heap_t* heap) /*!< in: memory heap where copied */
{
trx_undo_rec_t* undo_rec;
ulint rseg_id;
@@ -1360,24 +1354,24 @@ trx_undo_get_undo_rec_low(
return(undo_rec);
}
-/**********************************************************************
-Copies an undo record to heap. */
+/******************************************************************//**
+Copies an undo record to heap.
+
+NOTE: the caller must have latches on the clustered index page and
+purge_view.
+
+@return DB_SUCCESS, or DB_MISSING_HISTORY if the undo log has been
+truncated and we cannot fetch the old version */
UNIV_INTERN
ulint
trx_undo_get_undo_rec(
/*==================*/
- /* out: DB_SUCCESS, or
- DB_MISSING_HISTORY if the undo log
- has been truncated and we cannot
- fetch the old version; NOTE: the
- caller must have latches on the
- clustered index page and purge_view */
- dulint roll_ptr, /* in: roll pointer to record */
- dulint trx_id, /* in: id of the trx that generated
+ roll_ptr_t roll_ptr, /*!< in: roll pointer to record */
+ trx_id_t trx_id, /*!< in: id of the trx that generated
the roll pointer: it points to an
undo log of this transaction */
- trx_undo_rec_t** undo_rec, /* out, own: copy of the record */
- mem_heap_t* heap) /* in: memory heap where copied */
+ trx_undo_rec_t** undo_rec, /*!< out, own: copy of the record */
+ mem_heap_t* heap) /*!< in: memory heap where copied */
{
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
@@ -1396,30 +1390,29 @@ trx_undo_get_undo_rec(
return(DB_SUCCESS);
}
-/***********************************************************************
+/*******************************************************************//**
Build a previous version of a clustered index record. This function checks
that the caller has a latch on the index page of the clustered index record
and an s-latch on the purge_view. This guarantees that the stack of versions
-is locked all the way down to the purge_view. */
+is locked all the way down to the purge_view.
+@return DB_SUCCESS, or DB_MISSING_HISTORY if the previous version is
+earlier than purge_view, which means that it may have been removed,
+DB_ERROR if corrupted record */
UNIV_INTERN
ulint
trx_undo_prev_version_build(
/*========================*/
- /* out: DB_SUCCESS, or DB_MISSING_HISTORY if
- the previous version is not >= purge_view,
- which means that it may have been removed,
- DB_ERROR if corrupted record */
- const rec_t* index_rec,/* in: clustered index record in the
+ const rec_t* index_rec,/*!< in: clustered index record in the
index tree */
mtr_t* index_mtr __attribute__((unused)),
- /* in: mtr which contains the latch to
+ /*!< in: mtr which contains the latch to
index_rec page and purge_view */
- const rec_t* rec, /* in: version of a clustered index record */
- dict_index_t* index, /* in: clustered index */
- ulint* offsets,/* in: rec_get_offsets(rec, index) */
- mem_heap_t* heap, /* in: memory heap from which the memory
+ const rec_t* rec, /*!< in: version of a clustered index record */
+ dict_index_t* index, /*!< in: clustered index */
+ ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
+ mem_heap_t* heap, /*!< in: memory heap from which the memory
needed is allocated */
- rec_t** old_vers)/* out, own: previous version, or NULL if
+ rec_t** old_vers)/*!< out, own: previous version, or NULL if
rec is the first inserted version, or if
history data has been deleted (an error),
or if the purge COULD have removed the version
@@ -1427,13 +1420,13 @@ trx_undo_prev_version_build(
{
trx_undo_rec_t* undo_rec = NULL;
dtuple_t* entry;
- dulint rec_trx_id;
+ trx_id_t rec_trx_id;
ulint type;
- dulint undo_no;
+ undo_no_t undo_no;
dulint table_id;
- dulint trx_id;
- dulint roll_ptr;
- dulint old_roll_ptr;
+ trx_id_t trx_id;
+ roll_ptr_t roll_ptr;
+ roll_ptr_t old_roll_ptr;
upd_t* update;
byte* ptr;
ulint info_bits;
@@ -1605,3 +1598,4 @@ trx_undo_prev_version_build(
return(DB_SUCCESS);
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/trx/trx0roll.c b/storage/xtradb/trx/trx0roll.c
index 5f3cb15a254..51d17192d5b 100644
--- a/storage/xtradb/trx/trx0roll.c
+++ b/storage/xtradb/trx/trx0roll.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0roll.c
Transaction rollback
Created 3/26/1996 Heikki Tuuri
@@ -43,32 +44,32 @@ Created 3/26/1996 Heikki Tuuri
#include "lock0lock.h"
#include "pars0pars.h"
-/* This many pages must be undone before a truncate is tried within rollback */
+/** This many pages must be undone before a truncate is tried within
+rollback */
#define TRX_ROLL_TRUNC_THRESHOLD 1
-/* In crash recovery, the current trx to be rolled back */
+/** In crash recovery, the current trx to be rolled back */
static trx_t* trx_roll_crash_recv_trx = NULL;
-/* In crash recovery we set this to the undo n:o of the current trx to be
+/** In crash recovery we set this to the undo n:o of the current trx to be
rolled back. Then we can print how many % the rollback has progressed. */
static ib_int64_t trx_roll_max_undo_no;
-/* Auxiliary variable which tells the previous progress % we printed */
+/** Auxiliary variable which tells the previous progress % we printed */
static ulint trx_roll_progress_printed_pct;
-/***********************************************************************
-Rollback a transaction used in MySQL. */
+/*******************************************************************//**
+Rollback a transaction used in MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
trx_general_rollback_for_mysql(
/*===========================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- ibool partial,/* in: TRUE if partial rollback requested */
- trx_savept_t* savept) /* in: pointer to savepoint undo number, if
+ trx_t* trx, /*!< in: transaction handle */
+ ibool partial,/*!< in: TRUE if partial rollback requested */
+ trx_savept_t* savept) /*!< in: pointer to savepoint undo number, if
partial rollback requested */
{
-#ifndef UNIV_HOTBACKUP
mem_heap_t* heap;
que_thr_t* thr;
roll_node_t* roll_node;
@@ -120,23 +121,16 @@ trx_general_rollback_for_mysql(
srv_active_wake_master_thread();
return((int) trx->error_state);
-#else /* UNIV_HOTBACKUP */
- /* This function depends on MySQL code that is not included in
- InnoDB Hot Backup builds. Besides, this function should never
- be called in InnoDB Hot Backup. */
- ut_error;
- return(DB_FAIL);
-#endif /* UNIV_HOTBACKUP */
}
-/***********************************************************************
-Rollback a transaction used in MySQL. */
+/*******************************************************************//**
+Rollback a transaction used in MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
trx_rollback_for_mysql(
/*===================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx) /*!< in: transaction handle */
{
int err;
@@ -158,14 +152,14 @@ trx_rollback_for_mysql(
return(err);
}
-/***********************************************************************
-Rollback the latest SQL statement for MySQL. */
+/*******************************************************************//**
+Rollback the latest SQL statement for MySQL.
+@return error code or DB_SUCCESS */
UNIV_INTERN
int
trx_rollback_last_sql_stat_for_mysql(
/*=================================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx) /*!< in: transaction handle */
{
int err;
@@ -186,14 +180,14 @@ trx_rollback_last_sql_stat_for_mysql(
return(err);
}
-/***********************************************************************
+/*******************************************************************//**
Frees a single savepoint struct. */
UNIV_INTERN
void
trx_roll_savepoint_free(
/*=====================*/
- trx_t* trx, /* in: transaction handle */
- trx_named_savept_t* savep) /* in: savepoint to free */
+ trx_t* trx, /*!< in: transaction handle */
+ trx_named_savept_t* savep) /*!< in: savepoint to free */
{
ut_a(savep != NULL);
ut_a(UT_LIST_GET_LEN(trx->trx_savepoints) > 0);
@@ -203,15 +197,15 @@ trx_roll_savepoint_free(
mem_free(savep);
}
-/***********************************************************************
+/*******************************************************************//**
Frees savepoint structs starting from savep, if savep == NULL then
free all savepoints. */
-
+UNIV_INTERN
void
trx_roll_savepoints_free(
/*=====================*/
- trx_t* trx, /* in: transaction handle */
- trx_named_savept_t* savep) /* in: free all savepoints > this one;
+ trx_t* trx, /*!< in: transaction handle */
+ trx_named_savept_t* savep) /*!< in: free all savepoints > this one;
if this is NULL, free all savepoints
of trx */
{
@@ -232,24 +226,22 @@ trx_roll_savepoints_free(
}
}
-/***********************************************************************
+/*******************************************************************//**
Rolls back a transaction back to a named savepoint. Modifications after the
savepoint are undone but InnoDB does NOT release the corresponding locks
which are stored in memory. If a lock is 'implicit', that is, a new inserted
row holds a lock where the lock information is carried by the trx id stored in
the row, these locks are naturally released in the rollback. Savepoints which
-were set after this savepoint are deleted. */
+were set after this savepoint are deleted.
+@return if no savepoint of the name found then DB_NO_SAVEPOINT,
+otherwise DB_SUCCESS */
UNIV_INTERN
ulint
trx_rollback_to_savepoint_for_mysql(
/*================================*/
- /* out: if no savepoint
- of the name found then
- DB_NO_SAVEPOINT,
- otherwise DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- const char* savepoint_name, /* in: savepoint name */
- ib_int64_t* mysql_binlog_cache_pos) /* out: the MySQL binlog cache
+ trx_t* trx, /*!< in: transaction handle */
+ const char* savepoint_name, /*!< in: savepoint name */
+ ib_int64_t* mysql_binlog_cache_pos) /*!< out: the MySQL binlog cache
position corresponding to this
savepoint; MySQL needs this
information to remove the
@@ -302,19 +294,19 @@ trx_rollback_to_savepoint_for_mysql(
return(err);
}
-/***********************************************************************
+/*******************************************************************//**
Creates a named savepoint. If the transaction is not yet started, starts it.
If there is already a savepoint of the same name, this call erases that old
savepoint and replaces it with a new. Savepoints are deleted in a transaction
-commit or rollback. */
+commit or rollback.
+@return always DB_SUCCESS */
UNIV_INTERN
ulint
trx_savepoint_for_mysql(
/*====================*/
- /* out: always DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- const char* savepoint_name, /* in: savepoint name */
- ib_int64_t binlog_cache_pos) /* in: MySQL binlog cache
+ trx_t* trx, /*!< in: transaction handle */
+ const char* savepoint_name, /*!< in: savepoint name */
+ ib_int64_t binlog_cache_pos) /*!< in: MySQL binlog cache
position corresponding to this
connection at the time of the
savepoint */
@@ -360,19 +352,17 @@ trx_savepoint_for_mysql(
return(DB_SUCCESS);
}
-/***********************************************************************
+/*******************************************************************//**
Releases only the named savepoint. Savepoints which were set after this
-savepoint are left as is. */
+savepoint are left as is.
+@return if no savepoint of the name found then DB_NO_SAVEPOINT,
+otherwise DB_SUCCESS */
UNIV_INTERN
ulint
trx_release_savepoint_for_mysql(
/*============================*/
- /* out: if no savepoint
- of the name found then
- DB_NO_SAVEPOINT,
- otherwise DB_SUCCESS */
- trx_t* trx, /* in: transaction handle */
- const char* savepoint_name) /* in: savepoint name */
+ trx_t* trx, /*!< in: transaction handle */
+ const char* savepoint_name) /*!< in: savepoint name */
{
trx_named_savept_t* savep;
@@ -390,29 +380,28 @@ trx_release_savepoint_for_mysql(
return(DB_NO_SAVEPOINT);
}
-/***********************************************************************
+/*******************************************************************//**
Determines if this transaction is rolling back an incomplete transaction
-in crash recovery. */
+in crash recovery.
+@return TRUE if trx is an incomplete transaction that is being rolled
+back in crash recovery */
UNIV_INTERN
ibool
trx_is_recv(
/*========*/
- /* out: TRUE if trx is an incomplete
- transaction that is being rolled back
- in crash recovery */
- const trx_t* trx) /* in: transaction */
+ const trx_t* trx) /*!< in: transaction */
{
return(trx == trx_roll_crash_recv_trx);
}
-/***********************************************************************
-Returns a transaction savepoint taken at this point in time. */
+/*******************************************************************//**
+Returns a transaction savepoint taken at this point in time.
+@return savepoint */
UNIV_INTERN
trx_savept_t
trx_savept_take(
/*============*/
- /* out: savepoint */
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
trx_savept_t savept;
@@ -421,13 +410,13 @@ trx_savept_take(
return(savept);
}
-/***********************************************************************
+/*******************************************************************//**
Roll back an active transaction. */
static
void
trx_rollback_active(
/*================*/
- trx_t* trx) /* in/out: transaction */
+ trx_t* trx) /*!< in/out: transaction */
{
mem_heap_t* heap;
que_fork_t* fork;
@@ -541,19 +530,19 @@ trx_rollback_active(
trx_roll_crash_recv_trx = NULL;
}
-/***********************************************************************
+/*******************************************************************//**
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
committed, then we clean up a possible insert undo log. If the
transaction was not yet committed, then we roll it back.
-Note: this is done in a background thread. */
+Note: this is done in a background thread.
+@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
trx_rollback_or_clean_all_recovered(
/*================================*/
- /* out: a dummy parameter */
void* arg __attribute__((unused)))
- /* in: a dummy parameter required by
+ /*!< in: a dummy parameter required by
os_thread_create */
{
trx_t* trx;
@@ -616,8 +605,9 @@ leave_function:
OS_THREAD_DUMMY_RETURN;
}
-/***********************************************************************
-Creates an undo number array. */
+/*******************************************************************//**
+Creates an undo number array.
+@return own: undo number array */
UNIV_INTERN
trx_undo_arr_t*
trx_undo_arr_create(void)
@@ -646,29 +636,28 @@ trx_undo_arr_create(void)
return(arr);
}
-/***********************************************************************
+/*******************************************************************//**
Frees an undo number array. */
UNIV_INTERN
void
trx_undo_arr_free(
/*==============*/
- trx_undo_arr_t* arr) /* in: undo number array */
+ trx_undo_arr_t* arr) /*!< in: undo number array */
{
ut_ad(arr->n_used == 0);
mem_heap_free(arr->heap);
}
-/***********************************************************************
-Stores info of an undo log record to the array if it is not stored yet. */
+/*******************************************************************//**
+Stores info of an undo log record to the array if it is not stored yet.
+@return FALSE if the record already existed in the array */
static
ibool
trx_undo_arr_store_info(
/*====================*/
- /* out: FALSE if the record already existed in the
- array */
- trx_t* trx, /* in: transaction */
- dulint undo_no)/* in: undo number */
+ trx_t* trx, /*!< in: transaction */
+ undo_no_t undo_no)/*!< in: undo number */
{
trx_undo_inf_t* cell;
trx_undo_inf_t* stored_here;
@@ -721,14 +710,14 @@ trx_undo_arr_store_info(
}
}
-/***********************************************************************
+/*******************************************************************//**
Removes an undo number from the array. */
static
void
trx_undo_arr_remove_info(
/*=====================*/
- trx_undo_arr_t* arr, /* in: undo number array */
- dulint undo_no)/* in: undo number */
+ trx_undo_arr_t* arr, /*!< in: undo number array */
+ undo_no_t undo_no)/*!< in: undo number */
{
trx_undo_inf_t* cell;
ulint n_used;
@@ -755,19 +744,18 @@ trx_undo_arr_remove_info(
}
}
-/***********************************************************************
-Gets the biggest undo number in an array. */
+/*******************************************************************//**
+Gets the biggest undo number in an array.
+@return biggest value, ut_dulint_zero if the array is empty */
static
-dulint
+undo_no_t
trx_undo_arr_get_biggest(
/*=====================*/
- /* out: biggest value, ut_dulint_zero if
- the array is empty */
- trx_undo_arr_t* arr) /* in: undo number array */
+ trx_undo_arr_t* arr) /*!< in: undo number array */
{
trx_undo_inf_t* cell;
ulint n_used;
- dulint biggest;
+ undo_no_t biggest;
ulint n;
ulint i;
@@ -792,17 +780,17 @@ trx_undo_arr_get_biggest(
}
}
-/***************************************************************************
+/***********************************************************************//**
Tries truncate the undo logs. */
UNIV_INTERN
void
trx_roll_try_truncate(
/*==================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in/out: transaction */
{
trx_undo_arr_t* arr;
- dulint limit;
- dulint biggest;
+ undo_no_t limit;
+ undo_no_t biggest;
ut_ad(mutex_own(&(trx->undo_mutex)));
ut_ad(mutex_own(&((trx->rseg)->mutex)));
@@ -831,17 +819,17 @@ trx_roll_try_truncate(
}
}
-/***************************************************************************
+/***********************************************************************//**
Pops the topmost undo log record in a single undo log and updates the info
-about the topmost record in the undo log memory struct. */
+about the topmost record in the undo log memory struct.
+@return undo log record, the page s-latched */
static
trx_undo_rec_t*
trx_roll_pop_top_rec(
/*=================*/
- /* out: undo log record, the page s-latched */
- trx_t* trx, /* in: transaction */
- trx_undo_t* undo, /* in: undo log */
- mtr_t* mtr) /* in: mtr */
+ trx_t* trx, /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* undo_page;
ulint offset;
@@ -880,30 +868,29 @@ trx_roll_pop_top_rec(
return(undo_page + offset);
}
-/************************************************************************
+/********************************************************************//**
Pops the topmost record when the two undo logs of a transaction are seen
as a single stack of records ordered by their undo numbers. Inserts the
undo number of the popped undo record to the array of currently processed
undo numbers in the transaction. When the query thread finishes processing
-of this undo record, it must be released with trx_undo_rec_release. */
+of this undo record, it must be released with trx_undo_rec_release.
+@return undo log record copied to heap, NULL if none left, or if the
+undo number of the top record would be less than the limit */
UNIV_INTERN
trx_undo_rec_t*
trx_roll_pop_top_rec_of_trx(
/*========================*/
- /* out: undo log record copied to heap, NULL
- if none left, or if the undo number of the
- top record would be less than the limit */
- trx_t* trx, /* in: transaction */
- dulint limit, /* in: least undo number we need */
- dulint* roll_ptr,/* out: roll pointer to undo record */
- mem_heap_t* heap) /* in: memory heap where copied */
+ trx_t* trx, /*!< in: transaction */
+ undo_no_t limit, /*!< in: least undo number we need */
+ roll_ptr_t* roll_ptr,/*!< out: roll pointer to undo record */
+ mem_heap_t* heap) /*!< in: memory heap where copied */
{
trx_undo_t* undo;
trx_undo_t* ins_undo;
trx_undo_t* upd_undo;
trx_undo_rec_t* undo_rec;
trx_undo_rec_t* undo_rec_copy;
- dulint undo_no;
+ undo_no_t undo_no;
ibool is_insert;
trx_rseg_t* rseg;
ulint progress_pct;
@@ -1013,17 +1000,17 @@ try_again:
return(undo_rec_copy);
}
-/************************************************************************
+/********************************************************************//**
Reserves an undo log record for a query thread to undo. This should be
called if the query thread gets the undo log record not using the pop
-function above. */
+function above.
+@return TRUE if succeeded */
UNIV_INTERN
ibool
trx_undo_rec_reserve(
/*=================*/
- /* out: TRUE if succeeded */
- trx_t* trx, /* in: transaction */
- dulint undo_no)/* in: undo number of the record */
+ trx_t* trx, /*!< in/out: transaction */
+ undo_no_t undo_no)/*!< in: undo number of the record */
{
ibool ret;
@@ -1036,14 +1023,14 @@ trx_undo_rec_reserve(
return(ret);
}
-/***********************************************************************
+/*******************************************************************//**
Releases a reserved undo record. */
UNIV_INTERN
void
trx_undo_rec_release(
/*=================*/
- trx_t* trx, /* in: transaction */
- dulint undo_no)/* in: undo number */
+ trx_t* trx, /*!< in/out: transaction */
+ undo_no_t undo_no)/*!< in: undo number */
{
trx_undo_arr_t* arr;
@@ -1056,15 +1043,15 @@ trx_undo_rec_release(
mutex_exit(&(trx->undo_mutex));
}
-/*************************************************************************
+/*********************************************************************//**
Starts a rollback operation. */
UNIV_INTERN
void
trx_rollback(
/*=========*/
- trx_t* trx, /* in: transaction */
- trx_sig_t* sig, /* in: signal starting the rollback */
- que_thr_t** next_thr)/* in/out: next query thread to run;
+ trx_t* trx, /*!< in: transaction */
+ trx_sig_t* sig, /*!< in: signal starting the rollback */
+ que_thr_t** next_thr)/*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -1127,17 +1114,17 @@ trx_rollback(
}
}
-/********************************************************************
+/****************************************************************//**
Builds an undo 'query' graph for a transaction. The actual rollback is
performed by executing this query graph like a query subprocedure call.
The reply about the completion of the rollback will be sent by this
-graph. */
+graph.
+@return own: the query graph */
UNIV_INTERN
que_t*
trx_roll_graph_build(
/*=================*/
- /* out, own: the query graph */
- trx_t* trx) /* in: trx handle */
+ trx_t* trx) /*!< in: trx handle */
{
mem_heap_t* heap;
que_fork_t* fork;
@@ -1159,14 +1146,14 @@ trx_roll_graph_build(
return(fork);
}
-/*************************************************************************
+/*********************************************************************//**
Finishes error processing after the necessary partial rollback has been
done. */
static
void
trx_finish_error_processing(
/*========================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
trx_sig_t* sig;
trx_sig_t* next_sig;
@@ -1189,14 +1176,14 @@ trx_finish_error_processing(
trx->que_state = TRX_QUE_RUNNING;
}
-/*************************************************************************
+/*********************************************************************//**
Finishes a partial rollback operation. */
static
void
trx_finish_partial_rollback_off_kernel(
/*===================================*/
- trx_t* trx, /* in: transaction */
- que_thr_t** next_thr)/* in/out: next query thread to run;
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t** next_thr)/*!< in/out: next query thread to run;
if the value which is passed in is a pointer
to a NULL pointer, then the calling function
can start running a new query thread; if this
@@ -1217,15 +1204,15 @@ trx_finish_partial_rollback_off_kernel(
trx->que_state = TRX_QUE_RUNNING;
}
-/********************************************************************
+/****************************************************************//**
Finishes a transaction rollback. */
UNIV_INTERN
void
trx_finish_rollback_off_kernel(
/*===========================*/
- que_t* graph, /* in: undo graph which can now be freed */
- trx_t* trx, /* in: transaction */
- que_thr_t** next_thr)/* in/out: next query thread to run;
+ que_t* graph, /*!< in: undo graph which can now be freed */
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t** next_thr)/*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -1285,14 +1272,14 @@ trx_finish_rollback_off_kernel(
}
}
-/*************************************************************************
-Creates a rollback command node struct. */
+/*********************************************************************//**
+Creates a rollback command node struct.
+@return own: rollback node struct */
UNIV_INTERN
roll_node_t*
roll_node_create(
/*=============*/
- /* out, own: rollback node struct */
- mem_heap_t* heap) /* in: mem heap where created */
+ mem_heap_t* heap) /*!< in: mem heap where created */
{
roll_node_t* node;
@@ -1305,14 +1292,14 @@ roll_node_create(
return(node);
}
-/***************************************************************
-Performs an execution step for a rollback command node in a query graph. */
+/***********************************************************//**
+Performs an execution step for a rollback command node in a query graph.
+@return query thread to run next, or NULL */
UNIV_INTERN
que_thr_t*
trx_rollback_step(
/*==============*/
- /* out: query thread to run next, or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
roll_node_t* node;
ulint sig_no;
diff --git a/storage/xtradb/trx/trx0rseg.c b/storage/xtradb/trx/trx0rseg.c
index db5efd65eb3..580762e8716 100644
--- a/storage/xtradb/trx/trx0rseg.c
+++ b/storage/xtradb/trx/trx0rseg.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0rseg.c
Rollback segment
Created 3/26/1996 Heikki Tuuri
@@ -33,14 +34,14 @@ Created 3/26/1996 Heikki Tuuri
#include "srv0srv.h"
#include "trx0purge.h"
-/**********************************************************************
-Looks for a rollback segment, based on the rollback segment id. */
+/******************************************************************//**
+Looks for a rollback segment, based on the rollback segment id.
+@return rollback segment */
UNIV_INTERN
trx_rseg_t*
trx_rseg_get_on_id(
/*===============*/
- /* out: rollback segment */
- ulint id) /* in: rollback segment id */
+ ulint id) /*!< in: rollback segment id */
{
trx_rseg_t* rseg;
@@ -55,21 +56,20 @@ trx_rseg_get_on_id(
return(rseg);
}
-/********************************************************************
+/****************************************************************//**
Creates a rollback segment header. This function is called only when
-a new rollback segment is created in the database. */
+a new rollback segment is created in the database.
+@return page number of the created segment, FIL_NULL if fail */
UNIV_INTERN
ulint
trx_rseg_header_create(
/*===================*/
- /* out: page number of the created segment,
- FIL_NULL if fail */
- ulint space, /* in: space id */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space id */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint max_size, /* in: max size in pages */
- ulint* slot_no, /* out: rseg id == slot number in trx sys */
- mtr_t* mtr) /* in: mtr */
+ ulint max_size, /*!< in: max size in pages */
+ ulint* slot_no, /*!< out: rseg id == slot number in trx sys */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint page_no;
trx_rsegf_t* rsegf;
@@ -131,22 +131,22 @@ trx_rseg_header_create(
return(page_no);
}
-/***************************************************************************
+/***********************************************************************//**
Creates and initializes a rollback segment object. The values for the
fields are read from the header. The object is inserted to the rseg
list of the trx system object and a pointer is inserted in the rseg
-array in the trx system object. */
+array in the trx system object.
+@return own: rollback segment object */
static
trx_rseg_t*
trx_rseg_mem_create(
/*================*/
- /* out, own: rollback segment object */
- ulint id, /* in: rollback segment id */
- ulint space, /* in: space where the segment placed */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint id, /*!< in: rollback segment id */
+ ulint space, /*!< in: space where the segment placed */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no, /* in: page number of the segment header */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no, /*!< in: page number of the segment header */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_rsegf_t* rseg_header;
trx_rseg_t* rseg;
@@ -207,15 +207,15 @@ trx_rseg_mem_create(
return(rseg);
}
-/*************************************************************************
+/*********************************************************************//**
Creates the memory copies for rollback segments and initializes the
rseg list and array in trx_sys at a database startup. */
UNIV_INTERN
void
trx_rseg_list_and_array_init(
/*=========================*/
- trx_sysf_t* sys_header, /* in: trx system header */
- mtr_t* mtr) /* in: mtr */
+ trx_sysf_t* sys_header, /*!< in: trx system header */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint i;
ulint page_no;
@@ -244,18 +244,17 @@ trx_rseg_list_and_array_init(
}
}
-/********************************************************************
-Creates a new rollback segment to the database. */
+/****************************************************************//**
+Creates a new rollback segment to the database.
+@return the created segment object, NULL if fail */
UNIV_INTERN
trx_rseg_t*
trx_rseg_create(
/*============*/
- /* out: the created segment object, NULL if
- fail */
- ulint space, /* in: space id */
- ulint max_size, /* in: max size in pages */
- ulint* id, /* out: rseg id */
- mtr_t* mtr) /* in: mtr */
+ ulint space, /*!< in: space id */
+ ulint max_size, /*!< in: max size in pages */
+ ulint* id, /*!< out: rseg id */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint flags;
ulint zip_size;
diff --git a/storage/xtradb/trx/trx0sys.c b/storage/xtradb/trx/trx0sys.c
index b80a50738c0..81c614c8323 100644
--- a/storage/xtradb/trx/trx0sys.c
+++ b/storage/xtradb/trx/trx0sys.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0sys.c
Transaction system
Created 3/26/1996 Heikki Tuuri
@@ -28,8 +29,10 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0sys.ic"
#endif
+#ifndef UNIV_HOTBACKUP
#include "fsp0fsp.h"
-#include "mtr0mtr.h"
+#include "mtr0log.h"
+#include "mtr0log.h"
#include "trx0trx.h"
#include "trx0rseg.h"
#include "trx0undo.h"
@@ -38,52 +41,60 @@ Created 3/26/1996 Heikki Tuuri
#include "log0log.h"
#include "os0file.h"
-/* The file format tag structure with id and name. */
+/** The file format tag structure with id and name. */
struct file_format_struct {
- ulint id; /* id of the file format */
- const char* name; /* text representation of the
+ ulint id; /*!< id of the file format */
+ const char* name; /*!< text representation of the
file format */
- mutex_t mutex; /* covers changes to the above
+ mutex_t mutex; /*!< covers changes to the above
fields */
};
+/** The file format tag */
typedef struct file_format_struct file_format_t;
-/* The transaction system */
+/** The transaction system */
UNIV_INTERN trx_sys_t* trx_sys = NULL;
+/** The doublewrite buffer */
UNIV_INTERN trx_doublewrite_t* trx_doublewrite = NULL;
-/* The following is set to TRUE when we are upgrading from the old format data
-files to the new >= 4.1.x format multiple tablespaces format data files */
-
+/** The following is set to TRUE when we are upgrading from pre-4.1
+format data files to the multiple tablespaces format data files */
UNIV_INTERN ibool trx_doublewrite_must_reset_space_ids = FALSE;
+/** Set to TRUE when the doublewrite buffer is being created */
+UNIV_INTERN ibool trx_doublewrite_buf_is_being_created = FALSE;
-/* The following is TRUE when we are using the database in the new format,
-i.e., we have successfully upgraded, or have created a new database
-installation */
-
+/** The following is TRUE when we are using the database in the
+post-4.1 format, i.e., we have successfully upgraded, or have created
+a new database installation */
UNIV_INTERN ibool trx_sys_multiple_tablespace_format = FALSE;
-/* In a MySQL replication slave, in crash recovery we store the master log
-file name and position here. We have successfully got the updates to InnoDB
-up to this position. If .._pos is -1, it means no crash recovery was needed,
-or there was no master log position info inside InnoDB. */
-
+/** In a MySQL replication slave, in crash recovery we store the master log
+file name and position here. */
+/* @{ */
+/** Master binlog file name */
UNIV_INTERN char trx_sys_mysql_master_log_name[TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN];
+/** Master binlog file position. We have successfully got the updates
+up to this position. -1 means that no crash recovery was needed, or
+there was no master log position info inside InnoDB.*/
UNIV_INTERN ib_int64_t trx_sys_mysql_master_log_pos = -1;
+/* @} */
UNIV_INTERN char trx_sys_mysql_relay_log_name[TRX_SYS_MYSQL_MASTER_LOG_NAME_LEN];
UNIV_INTERN ib_int64_t trx_sys_mysql_relay_log_pos = -1;
-/* If this MySQL server uses binary logging, after InnoDB has been inited
+/** If this MySQL server uses binary logging, after InnoDB has been inited
and if it has done a crash recovery, we store the binlog file name and position
-here. If .._pos is -1, it means there was no binlog position info inside
-InnoDB. */
-
+here. */
+/* @{ */
+/** Binlog file name */
UNIV_INTERN char trx_sys_mysql_bin_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN];
+/** Binlog file position, or -1 if unknown */
UNIV_INTERN ib_int64_t trx_sys_mysql_bin_log_pos = -1;
+/* @} */
+#endif /* !UNIV_HOTBACKUP */
-/* List of animal names representing file format. */
+/** List of animal names representing file format. */
static const char* file_format_name_map[] = {
"Antelope",
"Barracuda",
@@ -113,24 +124,25 @@ static const char* file_format_name_map[] = {
"Zebra"
};
-/* The number of elements in the file format name array. */
+/** The number of elements in the file format name array. */
static const ulint FILE_FORMAT_NAME_N
= sizeof(file_format_name_map) / sizeof(file_format_name_map[0]);
-/* This is used to track the maximum file format id known to InnoDB. It's
+#ifndef UNIV_HOTBACKUP
+/** This is used to track the maximum file format id known to InnoDB. It's
updated via SET GLOBAL innodb_file_format_check = 'x' or when we open
or create a table. */
static file_format_t file_format_max;
-/********************************************************************
-Determines if a page number is located inside the doublewrite buffer. */
+/****************************************************************//**
+Determines if a page number is located inside the doublewrite buffer.
+@return TRUE if the location is inside the two blocks of the
+doublewrite buffer */
UNIV_INTERN
ibool
trx_doublewrite_page_inside(
/*========================*/
- /* out: TRUE if the location is inside
- the two blocks of the doublewrite buffer */
- ulint page_no) /* in: page number */
+ ulint page_no) /*!< in: page number */
{
if (trx_doublewrite == NULL) {
@@ -152,13 +164,13 @@ trx_doublewrite_page_inside(
return(FALSE);
}
-/********************************************************************
+/****************************************************************//**
Creates or initialializes the doublewrite buffer at a database start. */
static
void
trx_doublewrite_init(
/*=================*/
- byte* doublewrite) /* in: pointer to the doublewrite buf
+ byte* doublewrite) /*!< in: pointer to the doublewrite buf
header on trx sys page */
{
trx_doublewrite = mem_alloc(sizeof(trx_doublewrite_t));
@@ -186,7 +198,7 @@ trx_doublewrite_init(
2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * sizeof(void*));
}
-/********************************************************************
+/****************************************************************//**
Marks the trx sys header when we have successfully upgraded to the >= 4.1.x
multiple tablespace format. */
UNIV_INTERN
@@ -221,7 +233,7 @@ trx_sys_mark_upgraded_to_multiple_tablespaces(void)
trx_sys_multiple_tablespace_format = TRUE;
}
-/********************************************************************
+/****************************************************************//**
Creates the doublewrite buffer to a new InnoDB installation. The header of the
doublewrite buffer is placed on the trx system header page. */
UNIV_INTERN
@@ -247,6 +259,7 @@ trx_sys_create_doublewrite_buf(void)
start_again:
mtr_start(&mtr);
+ trx_doublewrite_buf_is_being_created = TRUE;
block = buf_page_get(TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO,
RW_X_LATCH, &mtr);
@@ -262,6 +275,7 @@ start_again:
trx_doublewrite_init(doublewrite);
mtr_commit(&mtr);
+ trx_doublewrite_buf_is_being_created = FALSE;
} else {
fprintf(stderr,
"InnoDB: Doublewrite buffer not found:"
@@ -337,15 +351,8 @@ start_again:
buf_block_dbg_add_level(new_block,
SYNC_NO_ORDER_CHECK);
- /* Make a dummy change to the page to ensure it will
- be written to disk in a flush */
-
- mlog_write_ulint(buf_block_get_frame(new_block)
- + FIL_PAGE_DATA,
- TRX_SYS_DOUBLEWRITE_MAGIC_N,
- MLOG_4BYTES, &mtr);
-
if (i == FSP_EXTENT_SIZE / 2) {
+ ut_a(page_no == FSP_EXTENT_SIZE);
mlog_write_ulint(doublewrite
+ TRX_SYS_DOUBLEWRITE_BLOCK1,
page_no, MLOG_4BYTES, &mtr);
@@ -355,6 +362,7 @@ start_again:
page_no, MLOG_4BYTES, &mtr);
} else if (i == FSP_EXTENT_SIZE / 2
+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
+ ut_a(page_no == 2 * FSP_EXTENT_SIZE);
mlog_write_ulint(doublewrite
+ TRX_SYS_DOUBLEWRITE_BLOCK2,
page_no, MLOG_4BYTES, &mtr);
@@ -394,7 +402,7 @@ start_again:
}
}
-/********************************************************************
+/****************************************************************//**
At a database startup initializes the doublewrite buffer memory structure if
we already have a doublewrite buffer created in the data files. If we are
upgrading to an InnoDB version which supports multiple tablespaces, then this
@@ -405,7 +413,7 @@ UNIV_INTERN
void
trx_sys_doublewrite_init_or_restore_pages(
/*======================================*/
- ibool restore_corrupt_pages)
+ ibool restore_corrupt_pages) /*!< in: TRUE=restore pages */
{
byte* buf;
byte* read_buf;
@@ -606,14 +614,14 @@ leave_func:
ut_free(unaligned_read_buf);
}
-/********************************************************************
-Checks that trx is in the trx list. */
+/****************************************************************//**
+Checks that trx is in the trx list.
+@return TRUE if is in */
UNIV_INTERN
ibool
trx_in_trx_list(
/*============*/
- /* out: TRUE if is in */
- trx_t* in_trx) /* in: trx */
+ trx_t* in_trx) /*!< in: trx */
{
trx_t* trx;
@@ -634,7 +642,7 @@ trx_in_trx_list(
return(FALSE);
}
-/*********************************************************************
+/*****************************************************************//**
Writes the value of max_trx_id to the file based trx system header. */
UNIV_INTERN
void
@@ -655,7 +663,7 @@ trx_sys_flush_max_trx_id(void)
mtr_commit(&mtr);
}
-/*********************************************************************
+/*****************************************************************//**
Updates the offset information about the end of the MySQL binlog entry
which corresponds to the transaction just being committed. In a MySQL
replication slave updates the latest master binlog position up to which
@@ -664,11 +672,11 @@ UNIV_INTERN
void
trx_sys_update_mysql_binlog_offset(
/*===============================*/
- 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
+ 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 */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_sysf_t* sys_header;
const char* file_name;
@@ -721,42 +729,7 @@ trx_sys_update_mysql_binlog_offset(
MLOG_4BYTES, mtr);
}
-#ifdef UNIV_HOTBACKUP
-/*********************************************************************
-Prints to stderr the MySQL binlog info in the system header if the
-magic number shows it valid. */
-UNIV_INTERN
-void
-trx_sys_print_mysql_binlog_offset_from_page(
-/*========================================*/
- const byte* page) /* in: buffer containing the trx
- system header page, i.e., page number
- TRX_SYS_PAGE_NO in the tablespace */
-{
- const trx_sysf_t* sys_header;
-
- sys_header = page + TRX_SYS;
-
- if (mach_read_from_4(sys_header + TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
- == TRX_SYS_MYSQL_LOG_MAGIC_N) {
-
- fprintf(stderr,
- "ibbackup: Last MySQL binlog file position %lu %lu,"
- " file name %s\n",
- (ulong) mach_read_from_4(
- sys_header + TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_OFFSET_HIGH),
- (ulong) mach_read_from_4(
- sys_header + TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
- sys_header + TRX_SYS_MYSQL_LOG_INFO
- + TRX_SYS_MYSQL_LOG_NAME);
- }
-}
-#endif /* UNIV_HOTBACKUP */
-
-/*********************************************************************
+/*****************************************************************//**
Stores the MySQL binlog offset info in the trx system header if
the magic number shows it valid, and print the info to stderr */
UNIV_INTERN
@@ -806,7 +779,7 @@ trx_sys_print_mysql_binlog_offset(void)
mtr_commit(&mtr);
}
-/*********************************************************************
+/*****************************************************************//**
Prints to stderr the MySQL master log offset info in the trx system header if
the magic number shows it valid. */
UNIV_INTERN
@@ -886,14 +859,14 @@ trx_sys_print_mysql_master_log_pos(void)
mtr_commit(&mtr);
}
-/********************************************************************
-Looks for a free slot for a rollback segment in the trx system file copy. */
+/****************************************************************//**
+Looks for a free slot for a rollback segment in the trx system file copy.
+@return slot index or ULINT_UNDEFINED if not found */
UNIV_INTERN
ulint
trx_sysf_rseg_find_free(
/*====================*/
- /* out: slot index or ULINT_UNDEFINED if not found */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_sysf_t* sys_header;
ulint page_no;
@@ -916,14 +889,14 @@ trx_sysf_rseg_find_free(
return(ULINT_UNDEFINED);
}
-/*********************************************************************
+/*****************************************************************//**
Creates the file page for the transaction system. This function is called only
at the database creation, before trx_sys_init. */
static
void
trx_sysf_create(
/*============*/
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_sysf_t* sys_header;
ulint slot_no;
@@ -993,7 +966,7 @@ trx_sysf_create(
mutex_exit(&kernel_mutex);
}
-/*********************************************************************
+/*****************************************************************//**
Creates and initializes the central memory structures for the transaction
system. This is called when the database is started. */
UNIV_INTERN
@@ -1081,7 +1054,7 @@ trx_sys_init_at_db_start(void)
mtr_commit(&mtr);
}
-/*********************************************************************
+/*****************************************************************//**
Creates and initializes the transaction system at the database creation. */
UNIV_INTERN
void
@@ -1124,15 +1097,15 @@ trx_sys_create_extra_rseg(
mtr_commit(&mtr);
}
-/*********************************************************************
-Update the file format tag. */
+/*****************************************************************//**
+Update the file format tag.
+@return always TRUE */
static
ibool
trx_sys_file_format_max_write(
/*==========================*/
- /* out: always TRUE */
- ulint format_id, /* in: file format id */
- const char** name) /* out: max file format name, can
+ ulint format_id, /*!< in: file format id */
+ const char** name) /*!< out: max file format name, can
be NULL */
{
mtr_t mtr;
@@ -1166,14 +1139,13 @@ trx_sys_file_format_max_write(
return(TRUE);
}
-/*********************************************************************
-Read the file format tag. */
+/*****************************************************************//**
+Read the file format tag.
+@return the file format or ULINT_UNDEFINED if not set. */
static
ulint
trx_sys_file_format_max_read(void)
/*==============================*/
- /* out: the file format or
- ULINT_UNDEFINED if not set. */
{
mtr_t mtr;
const byte* ptr;
@@ -1205,29 +1177,29 @@ trx_sys_file_format_max_read(void)
return(format_id);
}
-/*********************************************************************
-Get the name representation of the file format from its id. */
+/*****************************************************************//**
+Get the name representation of the file format from its id.
+@return pointer to the name */
UNIV_INTERN
const char*
trx_sys_file_format_id_to_name(
/*===========================*/
- /* out: pointer to the name */
- const ulint id) /* in: id of the file format */
+ const ulint id) /*!< in: id of the file format */
{
ut_a(id < FILE_FORMAT_NAME_N);
return(file_format_name_map[id]);
}
-/*********************************************************************
+/*****************************************************************//**
Check for the max file format tag stored on disk. Note: If max_format_id
-is == DICT_TF_FORMAT_MAX + 1 then we only print a warning. */
+is == DICT_TF_FORMAT_MAX + 1 then we only print a warning.
+@return DB_SUCCESS or error code */
UNIV_INTERN
ulint
trx_sys_file_format_max_check(
/*==========================*/
- /* out: DB_SUCCESS or error code */
- ulint max_format_id) /* in: max format id to check */
+ ulint max_format_id) /*!< in: max format id to check */
{
ulint format_id;
@@ -1273,16 +1245,16 @@ trx_sys_file_format_max_check(
return(DB_SUCCESS);
}
-/*********************************************************************
+/*****************************************************************//**
Set the file format id unconditionally except if it's already the
-same value. */
+same value.
+@return TRUE if value updated */
UNIV_INTERN
ibool
trx_sys_file_format_max_set(
/*========================*/
- /* out: TRUE if value updated */
- ulint format_id, /* in: file format id */
- const char** name) /* out: max file format name or
+ ulint format_id, /*!< in: file format id */
+ const char** name) /*!< out: max file format name or
NULL if not needed. */
{
ibool ret = FALSE;
@@ -1302,7 +1274,7 @@ trx_sys_file_format_max_set(
return(ret);
}
-/************************************************************************
+/********************************************************************//**
Tags the system table space with minimum format id if it has not been
tagged yet.
WARNING: This function is only called during the startup and AFTER the
@@ -1322,17 +1294,16 @@ trx_sys_file_format_tag_init(void)
}
}
-/************************************************************************
+/********************************************************************//**
Update the file format tag in the system tablespace only if the given
-format id is greater than the known max id. */
+format id is greater than the known max id.
+@return TRUE if format_id was bigger than the known max id */
UNIV_INTERN
ibool
trx_sys_file_format_max_upgrade(
/*============================*/
- /* out: TRUE if format_id was
- bigger than the known max id */
- const char** name, /* out: max file format name */
- ulint format_id) /* in: file format identifier */
+ const char** name, /*!< out: max file format name */
+ ulint format_id) /*!< in: file format identifier */
{
ibool ret = FALSE;
@@ -1352,18 +1323,18 @@ trx_sys_file_format_max_upgrade(
return(ret);
}
-/*********************************************************************
-Get the name representation of the file format from its id. */
+/*****************************************************************//**
+Get the name representation of the file format from its id.
+@return pointer to the max format name */
UNIV_INTERN
const char*
trx_sys_file_format_max_get(void)
/*=============================*/
- /* out: pointer to the max format name */
{
return(file_format_max.name);
}
-/*********************************************************************
+/*****************************************************************//**
Initializes the tablespace tag system. */
UNIV_INTERN
void
@@ -1380,7 +1351,7 @@ trx_sys_file_format_init(void)
file_format_max.id);
}
-/*********************************************************************
+/*****************************************************************//**
Closes the tablespace tag system. */
UNIV_INTERN
void
@@ -1389,3 +1360,235 @@ trx_sys_file_format_close(void)
{
/* Does nothing at the moment */
}
+#else /* !UNIV_HOTBACKUP */
+/*****************************************************************//**
+Prints to stderr the MySQL binlog info in the system header if the
+magic number shows it valid. */
+UNIV_INTERN
+void
+trx_sys_print_mysql_binlog_offset_from_page(
+/*========================================*/
+ const byte* page) /*!< in: buffer containing the trx
+ system header page, i.e., page number
+ TRX_SYS_PAGE_NO in the tablespace */
+{
+ const trx_sysf_t* sys_header;
+
+ sys_header = page + TRX_SYS;
+
+ if (mach_read_from_4(sys_header + TRX_SYS_MYSQL_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD)
+ == TRX_SYS_MYSQL_LOG_MAGIC_N) {
+
+ fprintf(stderr,
+ "ibbackup: Last MySQL binlog file position %lu %lu,"
+ " file name %s\n",
+ (ulong) mach_read_from_4(
+ sys_header + TRX_SYS_MYSQL_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_OFFSET_HIGH),
+ (ulong) mach_read_from_4(
+ sys_header + TRX_SYS_MYSQL_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_OFFSET_LOW),
+ sys_header + TRX_SYS_MYSQL_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_NAME);
+ }
+}
+
+
+/* THESE ARE COPIED FROM NON-HOTBACKUP PART OF THE INNODB SOURCE TREE
+ (This code duplicaton should be fixed at some point!)
+*/
+
+#define TRX_SYS_SPACE 0 /* the SYSTEM tablespace */
+/* The offset of the file format tag on the trx system header page */
+#define TRX_SYS_FILE_FORMAT_TAG (UNIV_PAGE_SIZE - 16)
+/* We use these random constants to reduce the probability of reading
+garbage (from previous versions) that maps to an actual format id. We
+use these as bit masks at the time of reading and writing from/to disk. */
+#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW 3645922177UL
+#define TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH 2745987765UL
+
+/* END OF COPIED DEFINITIONS */
+
+
+/*****************************************************************//**
+Reads the file format id from the first system table space file.
+Even if the call succeeds and returns TRUE, the returned format id
+may be ULINT_UNDEFINED signalling that the format id was not present
+in the data file.
+@return TRUE if call succeeds */
+UNIV_INTERN
+ibool
+trx_sys_read_file_format_id(
+/*========================*/
+ const char *pathname, /*!< in: pathname of the first system
+ table space file */
+ ulint *format_id) /*!< out: file format of the system table
+ space */
+{
+ os_file_t file;
+ ibool success;
+ byte buf[UNIV_PAGE_SIZE * 2];
+ page_t* page = ut_align(buf, UNIV_PAGE_SIZE);
+ const byte* ptr;
+ dulint file_format_id;
+
+ *format_id = ULINT_UNDEFINED;
+
+ file = os_file_create_simple_no_error_handling(
+ pathname,
+ OS_FILE_OPEN,
+ OS_FILE_READ_ONLY,
+ &success
+ );
+ if (!success) {
+ /* The following call prints an error message */
+ os_file_get_last_error(TRUE);
+
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+" ibbackup: Error: trying to read system tablespace file format,\n"
+" ibbackup: but could not open the tablespace file %s!\n",
+ pathname
+ );
+ return(FALSE);
+ }
+
+ /* Read the page on which file format is stored */
+
+ success = os_file_read_no_error_handling(
+ file, page, TRX_SYS_PAGE_NO * UNIV_PAGE_SIZE, 0, UNIV_PAGE_SIZE
+ );
+ if (!success) {
+ /* The following call prints an error message */
+ os_file_get_last_error(TRUE);
+
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+" ibbackup: Error: trying to read system table space file format,\n"
+" ibbackup: but failed to read the tablespace file %s!\n",
+ pathname
+ );
+ os_file_close(file);
+ return(FALSE);
+ }
+ os_file_close(file);
+
+ /* get the file format from the page */
+ ptr = page + TRX_SYS_FILE_FORMAT_TAG;
+ file_format_id = mach_read_from_8(ptr);
+
+ *format_id = file_format_id.low - TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW;
+
+ if (file_format_id.high != TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH
+ || *format_id >= FILE_FORMAT_NAME_N) {
+
+ /* Either it has never been tagged, or garbage in it. */
+ *format_id = ULINT_UNDEFINED;
+ return(TRUE);
+ }
+
+ return(TRUE);
+}
+
+
+/*****************************************************************//**
+Reads the file format id from the given per-table data file.
+@return TRUE if call succeeds */
+UNIV_INTERN
+ibool
+trx_sys_read_pertable_file_format_id(
+/*=================================*/
+ const char *pathname, /*!< in: pathname of a per-table
+ datafile */
+ ulint *format_id) /*!< out: file format of the per-table
+ data file */
+{
+ os_file_t file;
+ ibool success;
+ byte buf[UNIV_PAGE_SIZE * 2];
+ page_t* page = ut_align(buf, UNIV_PAGE_SIZE);
+ const byte* ptr;
+ ib_uint32_t flags;
+
+ *format_id = ULINT_UNDEFINED;
+
+ file = os_file_create_simple_no_error_handling(
+ pathname,
+ OS_FILE_OPEN,
+ OS_FILE_READ_ONLY,
+ &success
+ );
+ if (!success) {
+ /* The following call prints an error message */
+ os_file_get_last_error(TRUE);
+
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+" ibbackup: Error: trying to read per-table tablespace format,\n"
+" ibbackup: but could not open the tablespace file %s!\n",
+ pathname
+ );
+ return(FALSE);
+ }
+
+ /* Read the first page of the per-table datafile */
+
+ success = os_file_read_no_error_handling(
+ file, page, 0, 0, UNIV_PAGE_SIZE
+ );
+ if (!success) {
+ /* The following call prints an error message */
+ os_file_get_last_error(TRUE);
+
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+" ibbackup: Error: trying to per-table data file format,\n"
+" ibbackup: but failed to read the tablespace file %s!\n",
+ pathname
+ );
+ os_file_close(file);
+ return(FALSE);
+ }
+ os_file_close(file);
+
+ /* get the file format from the page */
+ ptr = page + 54;
+ flags = mach_read_from_4(ptr);
+ if (flags == 0) {
+ /* file format is Antelope */
+ *format_id = 0;
+ return (TRUE);
+ } else if (flags & 1) {
+ /* tablespace flags are ok */
+ *format_id = (flags / 32) % 128;
+ return (TRUE);
+ } else {
+ /* bad tablespace flags */
+ return(FALSE);
+ }
+}
+
+
+/*****************************************************************//**
+Get the name representation of the file format from its id.
+@return pointer to the name */
+UNIV_INTERN
+const char*
+trx_sys_file_format_id_to_name(
+/*===========================*/
+ const ulint id) /*!< in: id of the file format */
+{
+ if (!(id < FILE_FORMAT_NAME_N)) {
+ /* unknown id */
+ return ("Unknown");
+ }
+
+ return(file_format_name_map[id]);
+}
+
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/trx/trx0trx.c b/storage/xtradb/trx/trx0trx.c
index 0f81bba0427..12253c131a8 100644
--- a/storage/xtradb/trx/trx0trx.c
+++ b/storage/xtradb/trx/trx0trx.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0trx.c
The transaction
Created 3/26/1996 Heikki Tuuri
@@ -43,47 +44,47 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0xa.h"
#include "ha_prototypes.h"
-/* Dummy session used currently in MySQL interface */
+/** Dummy session used currently in MySQL interface */
UNIV_INTERN sess_t* trx_dummy_sess = NULL;
-/* Number of transactions currently allocated for MySQL: protected by
+/** Number of transactions currently allocated for MySQL: protected by
the kernel mutex */
UNIV_INTERN ulint trx_n_mysql_transactions = 0;
-/*****************************************************************
+/*************************************************************//**
Set detailed error message for the transaction. */
UNIV_INTERN
void
trx_set_detailed_error(
/*===================*/
- trx_t* trx, /* in: transaction struct */
- const char* msg) /* in: detailed error message */
+ trx_t* trx, /*!< in: transaction struct */
+ const char* msg) /*!< in: detailed error message */
{
ut_strlcpy(trx->detailed_error, msg, sizeof(trx->detailed_error));
}
-/*****************************************************************
+/*************************************************************//**
Set detailed error message for the transaction from a file. Note that the
file is rewinded before reading from it. */
UNIV_INTERN
void
trx_set_detailed_error_from_file(
/*=============================*/
- trx_t* trx, /* in: transaction struct */
- FILE* file) /* in: file to read message from */
+ trx_t* trx, /*!< in: transaction struct */
+ FILE* file) /*!< in: file to read message from */
{
os_file_read_string(file, trx->detailed_error,
sizeof(trx->detailed_error));
}
-/********************************************************************
-Creates and initializes a transaction object. */
+/****************************************************************//**
+Creates and initializes a transaction object.
+@return own: the transaction */
UNIV_INTERN
trx_t*
trx_create(
/*=======*/
- /* out, own: the transaction */
- sess_t* sess) /* in: session */
+ sess_t* sess) /*!< in: session */
{
trx_t* trx;
@@ -190,13 +191,13 @@ trx_create(
return(trx);
}
-/************************************************************************
-Creates a transaction object for MySQL. */
+/********************************************************************//**
+Creates a transaction object for MySQL.
+@return own: transaction object */
UNIV_INTERN
trx_t*
trx_allocate_for_mysql(void)
/*========================*/
- /* out, own: transaction object */
{
trx_t* trx;
@@ -217,13 +218,13 @@ trx_allocate_for_mysql(void)
return(trx);
}
-/************************************************************************
-Creates a transaction object for background operations by the master thread. */
+/********************************************************************//**
+Creates a transaction object for background operations by the master thread.
+@return own: transaction object */
UNIV_INTERN
trx_t*
trx_allocate_for_background(void)
/*=============================*/
- /* out, own: transaction object */
{
trx_t* trx;
@@ -236,13 +237,13 @@ trx_allocate_for_background(void)
return(trx);
}
-/************************************************************************
+/********************************************************************//**
Releases the search latch if trx has reserved it. */
UNIV_INTERN
void
trx_search_latch_release_if_reserved(
/*=================================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
if (trx->has_search_latch) {
rw_lock_s_unlock(&btr_search_latch);
@@ -251,13 +252,13 @@ trx_search_latch_release_if_reserved(
}
}
-/************************************************************************
+/********************************************************************//**
Frees a transaction object. */
UNIV_INTERN
void
trx_free(
/*=====*/
- trx_t* trx) /* in, own: trx object */
+ trx_t* trx) /*!< in, own: trx object */
{
ut_ad(mutex_own(&kernel_mutex));
@@ -337,13 +338,13 @@ trx_free(
mem_free(trx);
}
-/************************************************************************
+/********************************************************************//**
Frees a transaction object for MySQL. */
UNIV_INTERN
void
trx_free_for_mysql(
/*===============*/
- trx_t* trx) /* in, own: trx object */
+ trx_t* trx) /*!< in, own: trx object */
{
mutex_enter(&kernel_mutex);
@@ -358,13 +359,13 @@ trx_free_for_mysql(
mutex_exit(&kernel_mutex);
}
-/************************************************************************
+/********************************************************************//**
Frees a transaction object of a background operation of the master thread. */
UNIV_INTERN
void
trx_free_for_background(
/*====================*/
- trx_t* trx) /* in, own: trx object */
+ trx_t* trx) /*!< in, own: trx object */
{
mutex_enter(&kernel_mutex);
@@ -373,7 +374,7 @@ trx_free_for_background(
mutex_exit(&kernel_mutex);
}
-/********************************************************************
+/****************************************************************//**
Inserts the trx handle in the trx system trx list in the right position.
The list is sorted on the trx id so that the biggest id is at the list
start. This function is used at the database startup to insert incomplete
@@ -382,7 +383,7 @@ static
void
trx_list_insert_ordered(
/*====================*/
- trx_t* trx) /* in: trx handle */
+ trx_t* trx) /*!< in: trx handle */
{
trx_t* trx2;
@@ -413,7 +414,7 @@ trx_list_insert_ordered(
}
}
-/********************************************************************
+/****************************************************************//**
Creates trx objects for transactions and initializes the trx list of
trx_sys at database start. Rollback segment and undo log lists must
already exist when this function is called, because the lists of
@@ -601,14 +602,14 @@ trx_lists_init_at_db_start(void)
}
}
-/**********************************************************************
+/******************************************************************//**
Assigns a rollback segment to a transaction in a round-robin fashion.
-Skips the SYSTEM rollback segment if another is available. */
+Skips the SYSTEM rollback segment if another is available.
+@return assigned rollback segment id */
UNIV_INLINE
ulint
trx_assign_rseg(void)
/*=================*/
- /* out: assigned rollback segment id */
{
trx_rseg_t* rseg = trx_sys->latest_rseg;
@@ -635,15 +636,15 @@ loop:
return(rseg->id);
}
-/********************************************************************
-Starts a new transaction. */
+/****************************************************************//**
+Starts a new transaction.
+@return TRUE */
UNIV_INTERN
ibool
trx_start_low(
/*==========*/
- /* out: TRUE */
- trx_t* trx, /* in: transaction */
- ulint rseg_id)/* in: rollback segment id; if ULINT_UNDEFINED
+ trx_t* trx, /*!< in: transaction */
+ ulint rseg_id)/*!< in: rollback segment id; if ULINT_UNDEFINED
is passed, the system chooses the rollback segment
automatically in a round-robin fashion */
{
@@ -686,15 +687,15 @@ trx_start_low(
return(TRUE);
}
-/********************************************************************
-Starts a new transaction. */
+/****************************************************************//**
+Starts a new transaction.
+@return TRUE */
UNIV_INTERN
ibool
trx_start(
/*======*/
- /* out: TRUE */
- trx_t* trx, /* in: transaction */
- ulint rseg_id)/* in: rollback segment id; if ULINT_UNDEFINED
+ trx_t* trx, /*!< in: transaction */
+ ulint rseg_id)/*!< in: rollback segment id; if ULINT_UNDEFINED
is passed, the system chooses the rollback segment
automatically in a round-robin fashion */
{
@@ -717,13 +718,13 @@ trx_start(
return(ret);
}
-/********************************************************************
+/****************************************************************//**
Commits a transaction. */
UNIV_INTERN
void
trx_commit_off_kernel(
/*==================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
page_t* update_hdr_page;
ib_uint64_t lsn = 0;
@@ -907,11 +908,11 @@ trx_commit_off_kernel(
there are > 2 users in the database. Then at least 2 users can
gather behind one doing the physical log write to disk.
- If we are calling trx_commit() under MySQL's binlog mutex, we
+ If we are calling trx_commit() under prepare_commit_mutex, we
will delay possible log write and flush to a separate function
trx_commit_complete_for_mysql(), which is only called when the
- thread has released the binlog mutex. This is to make the
- group commit algorithm to work. Otherwise, the MySQL binlog
+ thread has released the mutex. This is to make the
+ group commit algorithm to work. Otherwise, the prepare_commit
mutex would serialize all commits and prevent a group of
transactions from gathering. */
@@ -963,7 +964,7 @@ trx_commit_off_kernel(
UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx);
}
-/********************************************************************
+/****************************************************************//**
Cleans up a transaction at database startup. The cleanup is needed if
the transaction already got to the middle of a commit when the database
crashed, andf we cannot roll it back. */
@@ -971,7 +972,7 @@ UNIV_INTERN
void
trx_cleanup_at_db_startup(
/*======================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
if (trx->insert_undo != NULL) {
@@ -986,16 +987,16 @@ trx_cleanup_at_db_startup(
UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx);
}
-/************************************************************************
+/********************************************************************//**
Assigns a read view for a consistent read query. All the consistent reads
within the same transaction will get the same read view, which is created
-when this function is first called for a new started transaction. */
+when this function is first called for a new started transaction.
+@return consistent read view */
UNIV_INTERN
read_view_t*
trx_assign_read_view(
/*=================*/
- /* out: consistent read view */
- trx_t* trx) /* in: active transaction */
+ trx_t* trx) /*!< in: active transaction */
{
ut_ad(trx->conc_state == TRX_ACTIVE);
@@ -1016,14 +1017,14 @@ trx_assign_read_view(
return(trx->read_view);
}
-/********************************************************************
+/****************************************************************//**
Commits a transaction. NOTE that the kernel mutex is temporarily released. */
static
void
trx_handle_commit_sig_off_kernel(
/*=============================*/
- trx_t* trx, /* in: transaction */
- que_thr_t** next_thr) /* in/out: next query thread to run;
+ trx_t* trx, /*!< in: transaction */
+ que_thr_t** next_thr) /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -1060,7 +1061,7 @@ trx_handle_commit_sig_off_kernel(
trx->que_state = TRX_QUE_RUNNING;
}
-/***************************************************************
+/***********************************************************//**
The transaction must be in the TRX_QUE_LOCK_WAIT state. Puts it to
the TRX_QUE_RUNNING state and releases query threads which were
waiting for a lock in the wait_thrs list. */
@@ -1068,7 +1069,7 @@ UNIV_INTERN
void
trx_end_lock_wait(
/*==============*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
que_thr_t* thr;
@@ -1088,14 +1089,14 @@ trx_end_lock_wait(
trx->que_state = TRX_QUE_RUNNING;
}
-/***************************************************************
+/***********************************************************//**
Moves the query threads in the lock wait list to the SUSPENDED state and puts
the transaction to the TRX_QUE_RUNNING state. */
static
void
trx_lock_wait_to_suspended(
/*=======================*/
- trx_t* trx) /* in: transaction in the TRX_QUE_LOCK_WAIT state */
+ trx_t* trx) /*!< in: transaction in the TRX_QUE_LOCK_WAIT state */
{
que_thr_t* thr;
@@ -1115,14 +1116,14 @@ trx_lock_wait_to_suspended(
trx->que_state = TRX_QUE_RUNNING;
}
-/***************************************************************
+/***********************************************************//**
Moves the query threads in the sig reply wait list of trx to the SUSPENDED
state. */
static
void
trx_sig_reply_wait_to_suspended(
/*============================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
trx_sig_t* sig;
que_thr_t* thr;
@@ -1146,17 +1147,17 @@ trx_sig_reply_wait_to_suspended(
}
}
-/*********************************************************************
+/*****************************************************************//**
Checks the compatibility of a new signal with the other signals in the
-queue. */
+queue.
+@return TRUE if the signal can be queued */
static
ibool
trx_sig_is_compatible(
/*==================*/
- /* out: TRUE if the signal can be queued */
- trx_t* trx, /* in: trx handle */
- ulint type, /* in: signal type */
- ulint sender) /* in: TRX_SIG_SELF or TRX_SIG_OTHER_SESS */
+ trx_t* trx, /*!< in: trx handle */
+ ulint type, /*!< in: signal type */
+ ulint sender) /*!< in: TRX_SIG_SELF or TRX_SIG_OTHER_SESS */
{
trx_sig_t* sig;
@@ -1220,22 +1221,22 @@ trx_sig_is_compatible(
}
}
-/********************************************************************
+/****************************************************************//**
Sends a signal to a trx object. */
UNIV_INTERN
void
trx_sig_send(
/*=========*/
- trx_t* trx, /* in: trx handle */
- ulint type, /* in: signal type */
- ulint sender, /* in: TRX_SIG_SELF or
+ trx_t* trx, /*!< in: trx handle */
+ ulint type, /*!< in: signal type */
+ ulint sender, /*!< in: TRX_SIG_SELF or
TRX_SIG_OTHER_SESS */
- que_thr_t* receiver_thr, /* in: query thread which wants the
+ que_thr_t* receiver_thr, /*!< in: query thread which wants the
reply, or NULL; if type is
TRX_SIG_END_WAIT, this must be NULL */
- trx_savept_t* savept, /* in: possible rollback savepoint, or
+ trx_savept_t* savept, /*!< in: possible rollback savepoint, or
NULL */
- que_thr_t** next_thr) /* in/out: next query thread to run;
+ que_thr_t** next_thr) /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -1304,7 +1305,7 @@ trx_sig_send(
}
}
-/********************************************************************
+/****************************************************************//**
Ends signal handling. If the session is in the error state, and
trx->graph_before_signal_handling != NULL, then returns control to the error
handling routine of the graph (currently just returns the control to the
@@ -1313,7 +1314,7 @@ UNIV_INTERN
void
trx_end_signal_handling(
/*====================*/
- trx_t* trx) /* in: trx */
+ trx_t* trx) /*!< in: trx */
{
ut_ad(mutex_own(&kernel_mutex));
ut_ad(trx->handling_signals == TRUE);
@@ -1328,14 +1329,14 @@ trx_end_signal_handling(
}
}
-/********************************************************************
+/****************************************************************//**
Starts handling of a trx signal. */
UNIV_INTERN
void
trx_sig_start_handle(
/*=================*/
- trx_t* trx, /* in: trx handle */
- que_thr_t** next_thr) /* in/out: next query thread to run;
+ trx_t* trx, /*!< in: trx handle */
+ que_thr_t** next_thr) /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -1433,15 +1434,15 @@ loop:
goto loop;
}
-/********************************************************************
+/****************************************************************//**
Send the reply message when a signal in the queue of the trx has been
handled. */
UNIV_INTERN
void
trx_sig_reply(
/*==========*/
- trx_sig_t* sig, /* in: signal */
- que_thr_t** next_thr) /* in/out: next query thread to run;
+ trx_sig_t* sig, /*!< in: signal */
+ que_thr_t** next_thr) /*!< in/out: next query thread to run;
if the value which is passed in is
a pointer to a NULL pointer, then the
calling function can start running
@@ -1468,14 +1469,14 @@ trx_sig_reply(
}
}
-/********************************************************************
+/****************************************************************//**
Removes a signal object from the trx signal queue. */
UNIV_INTERN
void
trx_sig_remove(
/*===========*/
- trx_t* trx, /* in: trx handle */
- trx_sig_t* sig) /* in, own: signal */
+ trx_t* trx, /*!< in: trx handle */
+ trx_sig_t* sig) /*!< in, own: signal */
{
ut_ad(trx && sig);
ut_ad(mutex_own(&kernel_mutex));
@@ -1490,14 +1491,14 @@ trx_sig_remove(
}
}
-/*************************************************************************
-Creates a commit command node struct. */
+/*********************************************************************//**
+Creates a commit command node struct.
+@return own: commit node struct */
UNIV_INTERN
commit_node_t*
commit_node_create(
/*===============*/
- /* out, own: commit node struct */
- mem_heap_t* heap) /* in: mem heap where created */
+ mem_heap_t* heap) /*!< in: mem heap where created */
{
commit_node_t* node;
@@ -1508,14 +1509,14 @@ commit_node_create(
return(node);
}
-/***************************************************************
-Performs an execution step for a commit type node in a query graph. */
+/***********************************************************//**
+Performs an execution step for a commit type node in a query graph.
+@return query thread to run next, or NULL */
UNIV_INTERN
que_thr_t*
trx_commit_step(
/*============*/
- /* out: query thread to run next, or NULL */
- que_thr_t* thr) /* in: query thread */
+ que_thr_t* thr) /*!< in: query thread */
{
commit_node_t* node;
que_thr_t* next_thr;
@@ -1556,14 +1557,14 @@ trx_commit_step(
return(thr);
}
-/**************************************************************************
-Does the transaction commit for MySQL. */
+/**********************************************************************//**
+Does the transaction commit for MySQL.
+@return DB_SUCCESS or error number */
UNIV_INTERN
ulint
trx_commit_for_mysql(
/*=================*/
- /* out: DB_SUCCESS or error number */
- trx_t* trx) /* in: trx handle */
+ trx_t* trx) /*!< in: trx handle */
{
/* Because we do not do the commit by sending an Innobase
sig to the transaction, we must here make sure that trx has been
@@ -1586,15 +1587,15 @@ trx_commit_for_mysql(
return(DB_SUCCESS);
}
-/**************************************************************************
+/**********************************************************************//**
If required, flushes the log to disk if we called trx_commit_for_mysql()
-with trx->flush_log_later == TRUE. */
+with trx->flush_log_later == TRUE.
+@return 0 or error number */
UNIV_INTERN
ulint
trx_commit_complete_for_mysql(
/*==========================*/
- /* out: 0 or error number */
- trx_t* trx) /* in: trx handle */
+ trx_t* trx) /*!< in: trx handle */
{
ib_uint64_t lsn = trx->commit_lsn;
@@ -1633,13 +1634,13 @@ trx_commit_complete_for_mysql(
return(0);
}
-/**************************************************************************
+/**********************************************************************//**
Marks the latest SQL statement ended. */
UNIV_INTERN
void
trx_mark_sql_stat_end(
/*==================*/
- trx_t* trx) /* in: trx handle */
+ trx_t* trx) /*!< in: trx handle */
{
ut_a(trx);
@@ -1650,7 +1651,7 @@ trx_mark_sql_stat_end(
trx->last_sql_stat_start.least_undo_no = trx->undo_no;
}
-/**************************************************************************
+/**********************************************************************//**
Prints info about a transaction to the given file. The caller must own the
kernel mutex and must have called
innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL
@@ -1659,9 +1660,9 @@ UNIV_INTERN
void
trx_print(
/*======*/
- FILE* f, /* in: output stream */
- trx_t* trx, /* in: transaction */
- ulint max_query_len) /* in: max query length to print, or 0 to
+ FILE* f, /*!< in: output stream */
+ trx_t* trx, /*!< in: transaction */
+ ulint max_query_len) /*!< in: max query length to print, or 0 to
use the default max length */
{
ibool newline;
@@ -1765,17 +1766,17 @@ trx_print(
}
}
-/***********************************************************************
+/*******************************************************************//**
Compares the "weight" (or size) of two transactions. Transactions that
have edited non-transactional tables are considered heavier than ones
-that have not. */
+that have not.
+@return <0, 0 or >0; similar to strcmp(3) */
UNIV_INTERN
int
trx_weight_cmp(
/*===========*/
- /* out: <0, 0 or >0; similar to strcmp(3) */
- const trx_t* a, /* in: the first transaction to be compared */
- const trx_t* b) /* in: the second transaction to be compared */
+ const trx_t* a, /*!< in: the first transaction to be compared */
+ const trx_t* b) /*!< in: the second transaction to be compared */
{
ibool a_notrans_edit;
ibool b_notrans_edit;
@@ -1816,13 +1817,13 @@ trx_weight_cmp(
return(ut_dulint_cmp(TRX_WEIGHT(a), TRX_WEIGHT(b)));
}
-/********************************************************************
+/****************************************************************//**
Prepares a transaction. */
UNIV_INTERN
void
trx_prepare_off_kernel(
/*===================*/
- trx_t* trx) /* in: transaction */
+ trx_t* trx) /*!< in: transaction */
{
page_t* update_hdr_page;
trx_rseg_t* rseg;
@@ -1926,14 +1927,14 @@ trx_prepare_off_kernel(
}
}
-/**************************************************************************
-Does the transaction prepare for MySQL. */
+/**********************************************************************//**
+Does the transaction prepare for MySQL.
+@return 0 or error number */
UNIV_INTERN
ulint
trx_prepare_for_mysql(
/*==================*/
- /* out: 0 or error number */
- trx_t* trx) /* in: trx handle */
+ trx_t* trx) /*!< in: trx handle */
{
/* Because we do not do the prepare by sending an Innobase
sig to the transaction, we must here make sure that trx has been
@@ -1956,17 +1957,16 @@ trx_prepare_for_mysql(
return(0);
}
-/**************************************************************************
+/**********************************************************************//**
This function is used to find number of prepared transactions and
-their transaction objects for a recovery. */
+their transaction objects for a recovery.
+@return number of prepared transactions stored in xid_list */
UNIV_INTERN
int
trx_recover_for_mysql(
/*==================*/
- /* out: number of prepared transactions
- stored in xid_list */
- XID* xid_list, /* in/out: prepared transactions */
- ulint len) /* in: number of slots in xid_list */
+ XID* xid_list, /*!< in/out: prepared transactions */
+ ulint len) /*!< in: number of slots in xid_list */
{
trx_t* trx;
ulint count = 0;
@@ -2028,15 +2028,15 @@ trx_recover_for_mysql(
return ((int) count);
}
-/***********************************************************************
+/*******************************************************************//**
This function is used to find one X/Open XA distributed transaction
-which is in the prepared state */
+which is in the prepared state
+@return trx or NULL */
UNIV_INTERN
trx_t*
trx_get_trx_by_xid(
/*===============*/
- /* out: trx or NULL */
- XID* xid) /* in: X/Open XA transaction identification */
+ XID* xid) /*!< in: X/Open XA transaction identification */
{
trx_t* trx;
diff --git a/storage/xtradb/trx/trx0undo.c b/storage/xtradb/trx/trx0undo.c
index bb5710aeba9..99672d4eb81 100644
--- a/storage/xtradb/trx/trx0undo.c
+++ b/storage/xtradb/trx/trx0undo.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file trx/trx0undo.c
Transaction undo log
Created 3/26/1996 Heikki Tuuri
@@ -29,13 +30,14 @@ Created 3/26/1996 Heikki Tuuri
#endif
#include "fsp0fsp.h"
+#ifndef UNIV_HOTBACKUP
#include "mach0data.h"
+#include "mtr0log.h"
#include "trx0rseg.h"
#include "trx0trx.h"
#include "srv0srv.h"
#include "trx0rec.h"
#include "trx0purge.h"
-#include "trx0xa.h"
/* How should the old versions in the history list be managed?
----------------------------------------------------------
@@ -91,68 +93,71 @@ it until a truncate operation occurs, which can remove undo logs from the end
of the list and release undo log segments. In stepping through the list,
s-latches on the undo log pages are enough, but in a truncate, x-latches must
be obtained on the rollback segment and individual pages. */
+#endif /* !UNIV_HOTBACKUP */
-/************************************************************************
+/********************************************************************//**
Initializes the fields in an undo log segment page. */
static
void
trx_undo_page_init(
/*===============*/
- page_t* undo_page, /* in: undo log segment page */
- ulint type, /* in: undo log segment type */
- mtr_t* mtr); /* in: mtr */
-/************************************************************************
-Creates and initializes an undo log memory object. */
+ page_t* undo_page, /*!< in: undo log segment page */
+ ulint type, /*!< in: undo log segment type */
+ mtr_t* mtr); /*!< in: mtr */
+
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Creates and initializes an undo log memory object.
+@return own: the undo log memory object */
static
trx_undo_t*
trx_undo_mem_create(
/*================*/
- /* out, own: the undo log memory object */
- trx_rseg_t* rseg, /* in: rollback segment memory object */
- ulint id, /* in: slot index within rseg */
- ulint type, /* in: type of the log: TRX_UNDO_INSERT or
+ trx_rseg_t* rseg, /*!< in: rollback segment memory object */
+ ulint id, /*!< in: slot index within rseg */
+ ulint type, /*!< in: type of the log: TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
- dulint trx_id, /* in: id of the trx for which the undo log
+ trx_id_t trx_id, /*!< in: id of the trx for which the undo log
is created */
- const XID* xid, /* in: X/Open XA transaction identification*/
- ulint page_no,/* in: undo log header page number */
- ulint offset);/* in: undo log header byte offset on page */
-/*******************************************************************
+ const XID* xid, /*!< in: X/Open XA transaction identification*/
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset);/*!< in: undo log header byte offset on page */
+#endif /* !UNIV_HOTBACKUP */
+/***************************************************************//**
Initializes a cached insert undo log header page for new use. NOTE that this
function has its own log record type MLOG_UNDO_HDR_REUSE. You must NOT change
-the operation of this function! */
+the operation of this function!
+@return undo log header byte offset on page */
static
ulint
trx_undo_insert_header_reuse(
/*=========================*/
- /* out: undo log header byte offset on page */
- page_t* undo_page, /* in: insert undo log segment header page,
- x-latched */
- dulint trx_id, /* in: transaction id */
- mtr_t* mtr); /* in: mtr */
-/**************************************************************************
+ page_t* undo_page, /*!< in/out: insert undo log segment
+ header page, x-latched */
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr); /*!< in: mtr */
+/**********************************************************************//**
If an update undo log can be discarded immediately, this function frees the
space, resetting the page to the proper state for caching. */
static
void
trx_undo_discard_latest_update_undo(
/*================================*/
- page_t* undo_page, /* in: header page of an undo log of size 1 */
- mtr_t* mtr); /* in: mtr */
-
+ page_t* undo_page, /*!< in: header page of an undo log of size 1 */
+ mtr_t* mtr); /*!< in: mtr */
-/***************************************************************************
-Gets the previous record in an undo log from the previous page. */
+#ifndef UNIV_HOTBACKUP
+/***********************************************************************//**
+Gets the previous record in an undo log from the previous page.
+@return undo log record, the page s-latched, NULL if none */
static
trx_undo_rec_t*
trx_undo_get_prev_rec_from_prev_page(
/*=================================*/
- /* out: undo log record, the page s-latched,
- NULL if none */
- trx_undo_rec_t* rec, /* in: undo record */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- mtr_t* mtr) /* in: mtr */
+ trx_undo_rec_t* rec, /*!< in: undo record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint space;
ulint zip_size;
@@ -180,18 +185,17 @@ trx_undo_get_prev_rec_from_prev_page(
return(trx_undo_page_get_last_rec(prev_page, page_no, offset));
}
-/***************************************************************************
-Gets the previous record in an undo log. */
+/***********************************************************************//**
+Gets the previous record in an undo log.
+@return undo log record, the page s-latched, NULL if none */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_prev_rec(
/*==================*/
- /* out: undo log record, the page s-latched,
- NULL if none */
- trx_undo_rec_t* rec, /* in: undo record */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- mtr_t* mtr) /* in: mtr */
+ trx_undo_rec_t* rec, /*!< in: undo record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_undo_rec_t* prev_rec;
@@ -209,22 +213,21 @@ trx_undo_get_prev_rec(
mtr));
}
-/***************************************************************************
-Gets the next record in an undo log from the next page. */
+/***********************************************************************//**
+Gets the next record in an undo log from the next page.
+@return undo log record, the page latched, NULL if none */
static
trx_undo_rec_t*
trx_undo_get_next_rec_from_next_page(
/*=================================*/
- /* out: undo log record, the page latched, NULL if
- none */
- ulint space, /* in: undo log header space */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: undo log header space */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- page_t* undo_page, /* in: undo log page */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- ulint mode, /* in: latch mode: RW_S_LATCH or RW_X_LATCH */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in: undo log page */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ ulint mode, /*!< in: latch mode: RW_S_LATCH or RW_X_LATCH */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_ulogf_t* log_hdr;
ulint next_page_no;
@@ -262,18 +265,17 @@ trx_undo_get_next_rec_from_next_page(
return(trx_undo_page_get_first_rec(next_page, page_no, offset));
}
-/***************************************************************************
-Gets the next record in an undo log. */
+/***********************************************************************//**
+Gets the next record in an undo log.
+@return undo log record, the page s-latched, NULL if none */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_next_rec(
/*==================*/
- /* out: undo log record, the page s-latched,
- NULL if none */
- trx_undo_rec_t* rec, /* in: undo record */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- mtr_t* mtr) /* in: mtr */
+ trx_undo_rec_t* rec, /*!< in: undo record */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint space;
ulint zip_size;
@@ -294,21 +296,20 @@ trx_undo_get_next_rec(
RW_S_LATCH, mtr));
}
-/***************************************************************************
-Gets the first record in an undo log. */
+/***********************************************************************//**
+Gets the first record in an undo log.
+@return undo log record, the page latched, NULL if none */
UNIV_INTERN
trx_undo_rec_t*
trx_undo_get_first_rec(
/*===================*/
- /* out: undo log record, the page latched, NULL if
- none */
- ulint space, /* in: undo log header space */
- ulint zip_size,/* in: compressed page size in bytes
+ ulint space, /*!< in: undo log header space */
+ ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint page_no,/* in: undo log header page number */
- ulint offset, /* in: undo log header offset on page */
- ulint mode, /* in: latching mode: RW_S_LATCH or RW_X_LATCH */
- mtr_t* mtr) /* in: mtr */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset, /*!< in: undo log header offset on page */
+ ulint mode, /*!< in: latching mode: RW_S_LATCH or RW_X_LATCH */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* undo_page;
trx_undo_rec_t* rec;
@@ -333,32 +334,35 @@ trx_undo_get_first_rec(
/*============== UNDO LOG FILE COPY CREATION AND FREEING ==================*/
-/**************************************************************************
+/**********************************************************************//**
Writes the mtr log entry of an undo log page initialization. */
UNIV_INLINE
void
trx_undo_page_init_log(
/*===================*/
- page_t* undo_page, /* in: undo log page */
- ulint type, /* in: undo log type */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in: undo log page */
+ ulint type, /*!< in: undo log type */
+ mtr_t* mtr) /*!< in: mtr */
{
mlog_write_initial_log_record(undo_page, MLOG_UNDO_INIT, mtr);
mlog_catenate_ulint_compressed(mtr, type);
}
+#else /* !UNIV_HOTBACKUP */
+# define trx_undo_page_init_log(undo_page,type,mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses the redo log entry of an undo log page initialization. */
+/***********************************************************//**
+Parses the redo log entry of an undo log page initialization.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_page_init(
/*=====================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ulint type;
@@ -376,15 +380,15 @@ trx_undo_parse_page_init(
return(ptr);
}
-/************************************************************************
+/********************************************************************//**
Initializes the fields in an undo log segment page. */
static
void
trx_undo_page_init(
/*===============*/
- page_t* undo_page, /* in: undo log segment page */
- ulint type, /* in: undo log segment type */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in: undo log segment page */
+ ulint type, /*!< in: undo log segment type */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_upagef_t* page_hdr;
@@ -402,26 +406,25 @@ trx_undo_page_init(
trx_undo_page_init_log(undo_page, type, mtr);
}
-/*******************************************************************
-Creates a new undo log segment in file. */
+#ifndef UNIV_HOTBACKUP
+/***************************************************************//**
+Creates a new undo log segment in file.
+@return DB_SUCCESS if page creation OK possible error codes are:
+DB_TOO_MANY_CONCURRENT_TRXS DB_OUT_OF_FILE_SPACE */
static
ulint
trx_undo_seg_create(
/*================*/
- /* out: DB_SUCCESS if page creation OK
- possible error codes are:
- DB_TOO_MANY_CONCURRENT_TRXS
- DB_OUT_OF_FILE_SPACE */
- trx_rseg_t* rseg __attribute__((unused)),/* in: rollback segment */
- trx_rsegf_t* rseg_hdr,/* in: rollback segment header, page
+ trx_rseg_t* rseg __attribute__((unused)),/*!< in: rollback segment */
+ trx_rsegf_t* rseg_hdr,/*!< in: rollback segment header, page
x-latched */
- ulint type, /* in: type of the segment: TRX_UNDO_INSERT or
+ ulint type, /*!< in: type of the segment: TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
- ulint* id, /* out: slot index within rseg header */
+ ulint* id, /*!< out: slot index within rseg header */
page_t** undo_page,
- /* out: segment header page x-latched, NULL
+ /*!< out: segment header page x-latched, NULL
if there was an error */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
ulint slot_no;
ulint space;
@@ -500,36 +503,40 @@ trx_undo_seg_create(
return(err);
}
-/**************************************************************************
+/**********************************************************************//**
Writes the mtr log entry of an undo log header initialization. */
UNIV_INLINE
void
trx_undo_header_create_log(
/*=======================*/
- page_t* undo_page, /* in: undo log header page */
- dulint trx_id, /* in: transaction id */
- mtr_t* mtr) /* in: mtr */
+ const page_t* undo_page, /*!< in: undo log header page */
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr) /*!< in: mtr */
{
mlog_write_initial_log_record(undo_page, MLOG_UNDO_HDR_CREATE, mtr);
mlog_catenate_dulint_compressed(mtr, trx_id);
}
+#else /* !UNIV_HOTBACKUP */
+# define trx_undo_header_create_log(undo_page,trx_id,mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/*******************************************************************
+/***************************************************************//**
Creates a new undo log header in file. NOTE that this function has its own
log record type MLOG_UNDO_HDR_CREATE. You must NOT change the operation of
-this function! */
+this function!
+@return header byte offset on page */
static
ulint
trx_undo_header_create(
/*===================*/
- /* out: header byte offset on page */
- page_t* undo_page, /* in: undo log segment header page,
- x-latched; it is assumed that there are
- TRX_UNDO_LOG_XA_HDR_SIZE bytes free space
- on it */
- dulint trx_id, /* in: transaction id */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in/out: undo log segment
+ header page, x-latched; it is
+ assumed that there is
+ TRX_UNDO_LOG_XA_HDR_SIZE bytes
+ free space on it */
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_upagef_t* page_hdr;
trx_usegf_t* seg_hdr;
@@ -587,15 +594,16 @@ trx_undo_header_create(
return(free);
}
-/************************************************************************
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
Write X/Open XA Transaction Identification (XID) to undo log header */
static
void
trx_undo_write_xid(
/*===============*/
- trx_ulogf_t* log_hdr,/* in: undo log header */
- const XID* xid, /* in: X/Open XA Transaction Identification */
- mtr_t* mtr) /* in: mtr */
+ trx_ulogf_t* log_hdr,/*!< in: undo log header */
+ const XID* xid, /*!< in: X/Open XA Transaction Identification */
+ mtr_t* mtr) /*!< in: mtr */
{
mlog_write_ulint(log_hdr + TRX_UNDO_XA_FORMAT,
(ulint)xid->formatID, MLOG_4BYTES, mtr);
@@ -610,14 +618,14 @@ trx_undo_write_xid(
XIDDATASIZE, mtr);
}
-/************************************************************************
+/********************************************************************//**
Read X/Open XA Transaction Identification (XID) from undo log header */
static
void
trx_undo_read_xid(
/*==============*/
- trx_ulogf_t* log_hdr,/* in: undo log header */
- XID* xid) /* out: X/Open XA Transaction Identification */
+ trx_ulogf_t* log_hdr,/*!< in: undo log header */
+ XID* xid) /*!< out: X/Open XA Transaction Identification */
{
xid->formatID = (long)mach_read_from_4(log_hdr + TRX_UNDO_XA_FORMAT);
@@ -629,15 +637,15 @@ trx_undo_read_xid(
memcpy(xid->data, log_hdr + TRX_UNDO_XA_XID, XIDDATASIZE);
}
-/*******************************************************************
+/***************************************************************//**
Adds space for the XA XID after an undo log old-style header. */
static
void
trx_undo_header_add_space_for_xid(
/*==============================*/
- page_t* undo_page,/* in: undo log segment header page */
- trx_ulogf_t* log_hdr,/* in: undo log header */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page,/*!< in: undo log segment header page */
+ trx_ulogf_t* log_hdr,/*!< in: undo log header */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_upagef_t* page_hdr;
ulint free;
@@ -667,35 +675,38 @@ trx_undo_header_add_space_for_xid(
MLOG_2BYTES, mtr);
}
-/**************************************************************************
+/**********************************************************************//**
Writes the mtr log entry of an undo log header reuse. */
UNIV_INLINE
void
trx_undo_insert_header_reuse_log(
/*=============================*/
- page_t* undo_page, /* in: undo log header page */
- dulint trx_id, /* in: transaction id */
- mtr_t* mtr) /* in: mtr */
+ const page_t* undo_page, /*!< in: undo log header page */
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr) /*!< in: mtr */
{
mlog_write_initial_log_record(undo_page, MLOG_UNDO_HDR_REUSE, mtr);
mlog_catenate_dulint_compressed(mtr, trx_id);
}
+#else /* !UNIV_HOTBACKUP */
+# define trx_undo_insert_header_reuse_log(undo_page,trx_id,mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses the redo log entry of an undo log page header create or reuse. */
+/***********************************************************//**
+Parses the redo log entry of an undo log page header create or reuse.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_page_header(
/*=======================*/
- /* out: end of log record or NULL */
- ulint type, /* in: MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ ulint type, /*!< in: MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr,/*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
- dulint trx_id;
+ trx_id_t trx_id;
ptr = mach_dulint_parse_compressed(ptr, end_ptr, &trx_id);
@@ -716,19 +727,19 @@ trx_undo_parse_page_header(
return(ptr);
}
-/*******************************************************************
+/***************************************************************//**
Initializes a cached insert undo log header page for new use. NOTE that this
function has its own log record type MLOG_UNDO_HDR_REUSE. You must NOT change
-the operation of this function! */
+the operation of this function!
+@return undo log header byte offset on page */
static
ulint
trx_undo_insert_header_reuse(
/*=========================*/
- /* out: undo log header byte offset on page */
- page_t* undo_page, /* in: insert undo log segment header page,
- x-latched */
- dulint trx_id, /* in: transaction id */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in/out: insert undo log segment
+ header page, x-latched */
+ trx_id_t trx_id, /*!< in: transaction id */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_upagef_t* page_hdr;
trx_usegf_t* seg_hdr;
@@ -776,29 +787,33 @@ trx_undo_insert_header_reuse(
return(free);
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Writes the redo log entry of an update undo log header discard. */
UNIV_INLINE
void
trx_undo_discard_latest_log(
/*========================*/
- page_t* undo_page, /* in: undo log header page */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in: undo log header page */
+ mtr_t* mtr) /*!< in: mtr */
{
mlog_write_initial_log_record(undo_page, MLOG_UNDO_HDR_DISCARD, mtr);
}
+#else /* !UNIV_HOTBACKUP */
+# define trx_undo_discard_latest_log(undo_page, mtr) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
-/***************************************************************
-Parses the redo log entry of an undo log page header discard. */
+/***********************************************************//**
+Parses the redo log entry of an undo log page header discard.
+@return end of log record or NULL */
UNIV_INTERN
byte*
trx_undo_parse_discard_latest(
/*==========================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr __attribute__((unused)), /* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ byte* ptr, /*!< in: buffer */
+ byte* end_ptr __attribute__((unused)), /*!< in: buffer end */
+ page_t* page, /*!< in: page or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
{
ut_ad(end_ptr);
@@ -809,15 +824,15 @@ trx_undo_parse_discard_latest(
return(ptr);
}
-/**************************************************************************
+/**********************************************************************//**
If an update undo log can be discarded immediately, this function frees the
space, resetting the page to the proper state for caching. */
static
void
trx_undo_discard_latest_update_undo(
/*================================*/
- page_t* undo_page, /* in: header page of an undo log of size 1 */
- mtr_t* mtr) /* in: mtr */
+ page_t* undo_page, /*!< in: header page of an undo log of size 1 */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_usegf_t* seg_hdr;
trx_upagef_t* page_hdr;
@@ -851,17 +866,17 @@ trx_undo_discard_latest_update_undo(
trx_undo_discard_latest_log(undo_page, mtr);
}
-/************************************************************************
-Tries to add a page to the undo log segment where the undo log is placed. */
+#ifndef UNIV_HOTBACKUP
+/********************************************************************//**
+Tries to add a page to the undo log segment where the undo log is placed.
+@return page number if success, else FIL_NULL */
UNIV_INTERN
ulint
trx_undo_add_page(
/*==============*/
- /* out: page number if success, else
- FIL_NULL */
- trx_t* trx, /* in: transaction */
- trx_undo_t* undo, /* in: undo log memory object */
- mtr_t* mtr) /* in: mtr which does not have a latch to any
+ trx_t* trx, /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log memory object */
+ mtr_t* mtr) /*!< in: mtr which does not have a latch to any
undo log page; the caller must have reserved
the rollback segment mutex */
{
@@ -922,21 +937,21 @@ trx_undo_add_page(
return(page_no);
}
-/************************************************************************
-Frees an undo log page that is not the header page. */
+/********************************************************************//**
+Frees an undo log page that is not the header page.
+@return last page number in remaining log */
static
ulint
trx_undo_free_page(
/*===============*/
- /* out: last page number in remaining log */
- trx_rseg_t* rseg, /* in: rollback segment */
- ibool in_history, /* in: TRUE if the undo log is in the history
+ trx_rseg_t* rseg, /*!< in: rollback segment */
+ ibool in_history, /*!< in: TRUE if the undo log is in the history
list */
- ulint space, /* in: space */
- ulint hdr_page_no, /* in: header page number */
- ulint page_no, /* in: page number to free: must not be the
+ ulint space, /*!< in: space */
+ ulint hdr_page_no, /*!< in: header page number */
+ ulint page_no, /*!< in: page number to free: must not be the
header page */
- mtr_t* mtr) /* in: mtr which does not have a latch to any
+ mtr_t* mtr) /*!< in: mtr which does not have a latch to any
undo log page; the caller must have reserved
the rollback segment mutex */
{
@@ -981,18 +996,18 @@ trx_undo_free_page(
return(last_addr.page);
}
-/************************************************************************
+/********************************************************************//**
Frees an undo log page when there is also the memory object for the undo
log. */
static
void
trx_undo_free_page_in_rollback(
/*===========================*/
- trx_t* trx __attribute__((unused)), /* in: transaction */
- trx_undo_t* undo, /* in: undo log memory copy */
- ulint page_no,/* in: page number to free: must not be the
+ trx_t* trx __attribute__((unused)), /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log memory copy */
+ ulint page_no,/*!< in: page number to free: must not be the
header page */
- mtr_t* mtr) /* in: mtr which does not have a latch to any
+ mtr_t* mtr) /*!< in: mtr which does not have a latch to any
undo log page; the caller must have reserved
the rollback segment mutex */
{
@@ -1008,19 +1023,19 @@ trx_undo_free_page_in_rollback(
undo->size--;
}
-/************************************************************************
+/********************************************************************//**
Empties an undo log header page of undo records for that undo log. Other
undo logs may still have records on that page, if it is an update undo log. */
static
void
trx_undo_empty_header_page(
/*=======================*/
- ulint space, /* in: space */
- ulint zip_size, /* in: compressed page size in bytes
+ ulint space, /*!< in: space */
+ ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
- ulint hdr_page_no, /* in: header page number */
- ulint hdr_offset, /* in: header offset */
- mtr_t* mtr) /* in: mtr */
+ ulint hdr_page_no, /*!< in: header page number */
+ ulint hdr_offset, /*!< in: header offset */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* header_page;
trx_ulogf_t* log_hdr;
@@ -1035,16 +1050,16 @@ trx_undo_empty_header_page(
mlog_write_ulint(log_hdr + TRX_UNDO_LOG_START, end, MLOG_2BYTES, mtr);
}
-/***************************************************************************
+/***********************************************************************//**
Truncates an undo log from the end. This function is used during a rollback
to free space from an undo log. */
UNIV_INTERN
void
trx_undo_truncate_end(
/*==================*/
- trx_t* trx, /* in: transaction whose undo log it is */
- trx_undo_t* undo, /* in: undo log */
- dulint limit) /* in: all undo records with undo number
+ trx_t* trx, /*!< in: transaction whose undo log it is */
+ trx_undo_t* undo, /*!< in: undo log */
+ undo_no_t limit) /*!< in: all undo records with undo number
>= this value should be truncated */
{
page_t* undo_page;
@@ -1110,22 +1125,24 @@ function_exit:
mtr_commit(&mtr);
}
-/***************************************************************************
+/***********************************************************************//**
Truncates an undo log from the start. This function is used during a purge
operation. */
UNIV_INTERN
void
trx_undo_truncate_start(
/*====================*/
- trx_rseg_t* rseg, /* in: rollback segment */
- ulint space, /* in: space id of the log */
- ulint hdr_page_no, /* in: header page number */
- ulint hdr_offset, /* in: header offset on the page */
- dulint limit) /* in: all undo pages with undo numbers <
- this value should be truncated; NOTE that
- the function only frees whole pages; the
- header page is not freed, but emptied, if
- all the records there are < limit */
+ trx_rseg_t* rseg, /*!< in: rollback segment */
+ ulint space, /*!< in: space id of the log */
+ ulint hdr_page_no, /*!< in: header page number */
+ ulint hdr_offset, /*!< in: header offset on the page */
+ undo_no_t limit) /*!< in: all undo pages with
+ undo numbers < this value
+ should be truncated; NOTE that
+ the function only frees whole
+ pages; the header page is not
+ freed, but emptied, if all the
+ records there are < limit */
{
page_t* undo_page;
trx_undo_rec_t* rec;
@@ -1180,13 +1197,13 @@ loop:
goto loop;
}
-/**************************************************************************
+/**********************************************************************//**
Frees an undo log segment which is not in the history list. */
static
void
trx_undo_seg_free(
/*==============*/
- trx_undo_t* undo) /* in: undo log */
+ trx_undo_t* undo) /*!< in: undo log */
{
trx_rseg_t* rseg;
fseg_header_t* file_seg;
@@ -1229,19 +1246,19 @@ trx_undo_seg_free(
/*========== UNDO LOG MEMORY COPY INITIALIZATION =====================*/
-/************************************************************************
+/********************************************************************//**
Creates and initializes an undo log memory object according to the values
in the header in file, when the database is started. The memory object is
-inserted in the appropriate list of rseg. */
+inserted in the appropriate list of rseg.
+@return own: the undo log memory object */
static
trx_undo_t*
trx_undo_mem_create_at_db_start(
/*============================*/
- /* out, own: the undo log memory object */
- trx_rseg_t* rseg, /* in: rollback segment memory object */
- ulint id, /* in: slot index within rseg */
- ulint page_no,/* in: undo log segment page number */
- mtr_t* mtr) /* in: mtr */
+ trx_rseg_t* rseg, /*!< in: rollback segment memory object */
+ ulint id, /*!< in: slot index within rseg */
+ ulint page_no,/*!< in: undo log segment page number */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* undo_page;
trx_upagef_t* page_header;
@@ -1250,7 +1267,7 @@ trx_undo_mem_create_at_db_start(
trx_undo_t* undo;
ulint type;
ulint state;
- dulint trx_id;
+ trx_id_t trx_id;
ulint offset;
fil_addr_t last_addr;
page_t* last_page;
@@ -1353,17 +1370,16 @@ add_to_list:
return(undo);
}
-/************************************************************************
+/********************************************************************//**
Initializes the undo log lists for a rollback segment memory copy. This
function is only called when the database is started or a new rollback
-segment is created. */
+segment is created.
+@return the combined size of undo log segments in pages */
UNIV_INTERN
ulint
trx_undo_lists_init(
/*================*/
- /* out: the combined size of undo log segments
- in pages */
- trx_rseg_t* rseg) /* in: rollback segment memory object */
+ trx_rseg_t* rseg) /*!< in: rollback segment memory object */
{
ulint page_no;
trx_undo_t* undo;
@@ -1450,22 +1466,22 @@ trx_undo_lists_init(
return(size);
}
-/************************************************************************
-Creates and initializes an undo log memory object. */
+/********************************************************************//**
+Creates and initializes an undo log memory object.
+@return own: the undo log memory object */
static
trx_undo_t*
trx_undo_mem_create(
/*================*/
- /* out, own: the undo log memory object */
- trx_rseg_t* rseg, /* in: rollback segment memory object */
- ulint id, /* in: slot index within rseg */
- ulint type, /* in: type of the log: TRX_UNDO_INSERT or
+ trx_rseg_t* rseg, /*!< in: rollback segment memory object */
+ ulint id, /*!< in: slot index within rseg */
+ ulint type, /*!< in: type of the log: TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
- dulint trx_id, /* in: id of the trx for which the undo log
+ trx_id_t trx_id, /*!< in: id of the trx for which the undo log
is created */
- const XID* xid, /* in: X/Open transaction identification */
- ulint page_no,/* in: undo log header page number */
- ulint offset) /* in: undo log header byte offset on page */
+ const XID* xid, /*!< in: X/Open transaction identification */
+ ulint page_no,/*!< in: undo log header page number */
+ ulint offset) /*!< in: undo log header byte offset on page */
{
trx_undo_t* undo;
@@ -1509,17 +1525,17 @@ trx_undo_mem_create(
return(undo);
}
-/************************************************************************
+/********************************************************************//**
Initializes a cached undo log object for new use. */
static
void
trx_undo_mem_init_for_reuse(
/*========================*/
- trx_undo_t* undo, /* in: undo log to init */
- dulint trx_id, /* in: id of the trx for which the undo log
+ trx_undo_t* undo, /*!< in: undo log to init */
+ trx_id_t trx_id, /*!< in: id of the trx for which the undo log
is created */
- const XID* xid, /* in: X/Open XA transaction identification*/
- ulint offset) /* in: undo log header byte offset on page */
+ const XID* xid, /*!< in: X/Open XA transaction identification*/
+ ulint offset) /*!< in: undo log header byte offset on page */
{
ut_ad(mutex_own(&((undo->rseg)->mutex)));
@@ -1542,13 +1558,13 @@ trx_undo_mem_init_for_reuse(
undo->empty = TRUE;
}
-/************************************************************************
+/********************************************************************//**
Frees an undo log memory copy. */
static
void
trx_undo_mem_free(
/*==============*/
- trx_undo_t* undo) /* in: the undo object to be freed */
+ trx_undo_t* undo) /*!< in: the undo object to be freed */
{
if (undo->id >= TRX_RSEG_N_SLOTS) {
fprintf(stderr,
@@ -1559,28 +1575,25 @@ trx_undo_mem_free(
mem_free(undo);
}
-/**************************************************************************
-Creates a new undo log. */
+/**********************************************************************//**
+Creates a new undo log.
+@return DB_SUCCESS if successful in creating the new undo lob object,
+possible error codes are: DB_TOO_MANY_CONCURRENT_TRXS
+DB_OUT_OF_FILE_SPACE DB_OUT_OF_MEMORY */
static
ulint
trx_undo_create(
/*============*/
- /* out: DB_SUCCESS if successful in creating
- the new undo lob object, possible error
- codes are:
- DB_TOO_MANY_CONCURRENT_TRXS
- DB_OUT_OF_FILE_SPACE
- DB_OUT_OF_MEMORY*/
- trx_t* trx, /* in: transaction */
- trx_rseg_t* rseg, /* in: rollback segment memory copy */
- ulint type, /* in: type of the log: TRX_UNDO_INSERT or
+ trx_t* trx, /*!< in: transaction */
+ trx_rseg_t* rseg, /*!< in: rollback segment memory copy */
+ ulint type, /*!< in: type of the log: TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
- dulint trx_id, /* in: id of the trx for which the undo log
+ trx_id_t trx_id, /*!< in: id of the trx for which the undo log
is created */
- const XID* xid, /* in: X/Open transaction identification*/
- trx_undo_t** undo, /* out: the new undo log object, undefined
+ const XID* xid, /*!< in: X/Open transaction identification*/
+ trx_undo_t** undo, /*!< out: the new undo log object, undefined
* if did not succeed */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_rsegf_t* rseg_header;
ulint page_no;
@@ -1633,22 +1646,21 @@ trx_undo_create(
/*================ UNDO LOG ASSIGNMENT AND CLEANUP =====================*/
-/************************************************************************
-Reuses a cached undo log. */
+/********************************************************************//**
+Reuses a cached undo log.
+@return the undo log memory object, NULL if none cached */
static
trx_undo_t*
trx_undo_reuse_cached(
/*==================*/
- /* out: the undo log memory object, NULL if
- none cached */
- trx_t* trx, /* in: transaction */
- trx_rseg_t* rseg, /* in: rollback segment memory object */
- ulint type, /* in: type of the log: TRX_UNDO_INSERT or
+ trx_t* trx, /*!< in: transaction */
+ trx_rseg_t* rseg, /*!< in: rollback segment memory object */
+ ulint type, /*!< in: type of the log: TRX_UNDO_INSERT or
TRX_UNDO_UPDATE */
- dulint trx_id, /* in: id of the trx for which the undo log
+ trx_id_t trx_id, /*!< in: id of the trx for which the undo log
is used */
- const XID* xid, /* in: X/Open XA transaction identification */
- mtr_t* mtr) /* in: mtr */
+ const XID* xid, /*!< in: X/Open XA transaction identification */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_undo_t* undo;
page_t* undo_page;
@@ -1714,16 +1726,16 @@ trx_undo_reuse_cached(
return(undo);
}
-/**************************************************************************
+/**********************************************************************//**
Marks an undo log header as a header of a data dictionary operation
transaction. */
static
void
trx_undo_mark_as_dict_operation(
/*============================*/
- trx_t* trx, /* in: dict op transaction */
- trx_undo_t* undo, /* in: assigned undo log */
- mtr_t* mtr) /* in: mtr */
+ trx_t* trx, /*!< in: dict op transaction */
+ trx_undo_t* undo, /*!< in: assigned undo log */
+ mtr_t* mtr) /*!< in: mtr */
{
page_t* hdr_page;
@@ -1752,19 +1764,18 @@ trx_undo_mark_as_dict_operation(
undo->dict_operation = TRUE;
}
-/**************************************************************************
+/**********************************************************************//**
Assigns an undo log for a transaction. A new undo log is created or a cached
-undo log reused. */
+undo log reused.
+@return DB_SUCCESS if undo log assign successful, possible error codes
+are: DB_TOO_MANY_CONCURRENT_TRXS DB_OUT_OF_FILE_SPACE
+DB_OUT_OF_MEMORY */
UNIV_INTERN
ulint
trx_undo_assign_undo(
/*=================*/
- /* out: DB_SUCCESS if undo log assign
- successful, possible error codes are:
- DB_TOO_MANY_CONCURRENT_TRXS
- DB_OUT_OF_FILE_SPACE DB_OUT_OF_MEMORY*/
- trx_t* trx, /* in: transaction */
- ulint type) /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */
+ trx_t* trx, /*!< in: transaction */
+ ulint type) /*!< in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */
{
trx_rseg_t* rseg;
trx_undo_t* undo;
@@ -1816,18 +1827,17 @@ func_exit:
return err;
}
-/**********************************************************************
-Sets the state of the undo log segment at a transaction finish. */
+/******************************************************************//**
+Sets the state of the undo log segment at a transaction finish.
+@return undo log segment header page, x-latched */
UNIV_INTERN
page_t*
trx_undo_set_state_at_finish(
/*=========================*/
- /* out: undo log segment header page,
- x-latched */
- trx_rseg_t* rseg, /* in: rollback segment memory object */
- trx_t* trx __attribute__((unused)), /* in: transaction */
- trx_undo_t* undo, /* in: undo log memory copy */
- mtr_t* mtr) /* in: mtr */
+ trx_rseg_t* rseg, /*!< in: rollback segment memory object */
+ trx_t* trx __attribute__((unused)), /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log memory copy */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_usegf_t* seg_hdr;
trx_upagef_t* page_hdr;
@@ -1884,17 +1894,16 @@ trx_undo_set_state_at_finish(
return(undo_page);
}
-/**********************************************************************
-Sets the state of the undo log segment at a transaction prepare. */
+/******************************************************************//**
+Sets the state of the undo log segment at a transaction prepare.
+@return undo log segment header page, x-latched */
UNIV_INTERN
page_t*
trx_undo_set_state_at_prepare(
/*==========================*/
- /* out: undo log segment header page,
- x-latched */
- trx_t* trx, /* in: transaction */
- trx_undo_t* undo, /* in: undo log memory copy */
- mtr_t* mtr) /* in: mtr */
+ trx_t* trx, /*!< in: transaction */
+ trx_undo_t* undo, /*!< in: undo log memory copy */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_usegf_t* seg_hdr;
trx_upagef_t* page_hdr;
@@ -1936,7 +1945,7 @@ trx_undo_set_state_at_prepare(
return(undo_page);
}
-/**************************************************************************
+/**********************************************************************//**
Adds the update undo log header as the first in the history list, and
frees the memory object, or puts it to the list of cached update undo log
segments. */
@@ -1944,10 +1953,10 @@ UNIV_INTERN
void
trx_undo_update_cleanup(
/*====================*/
- trx_t* trx, /* in: trx owning the update undo log */
- page_t* undo_page, /* in: update undo log header page,
+ trx_t* trx, /*!< in: trx owning the update undo log */
+ page_t* undo_page, /*!< in: update undo log header page,
x-latched */
- mtr_t* mtr) /* in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
{
trx_rseg_t* rseg;
trx_undo_t* undo;
@@ -1973,7 +1982,7 @@ trx_undo_update_cleanup(
}
}
-/**********************************************************************
+/******************************************************************//**
Frees or caches an insert undo log after a transaction commit or rollback.
Knowledge of inserts is not needed after a commit or rollback, therefore
the data can be discarded. */
@@ -1981,7 +1990,7 @@ UNIV_INTERN
void
trx_undo_insert_cleanup(
/*====================*/
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx) /*!< in: transaction handle */
{
trx_undo_t* undo;
trx_rseg_t* rseg;
@@ -2019,3 +2028,4 @@ trx_undo_insert_cleanup(
mutex_exit(&(rseg->mutex));
}
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/usr/usr0sess.c b/storage/xtradb/usr/usr0sess.c
index f45c43869ea..990991a2c06 100644
--- a/storage/xtradb/usr/usr0sess.c
+++ b/storage/xtradb/usr/usr0sess.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/******************************************************
+/**************************************************//**
+@file usr/usr0sess.c
Sessions
Created 6/25/1996 Heikki Tuuri
@@ -30,21 +31,21 @@ Created 6/25/1996 Heikki Tuuri
#include "trx0trx.h"
-/*************************************************************************
+/*********************************************************************//**
Closes a session, freeing the memory occupied by it. */
static
void
sess_close(
/*=======*/
- sess_t* sess); /* in, own: session object */
+ sess_t* sess); /*!< in, own: session object */
-/*************************************************************************
-Opens a session. */
+/*********************************************************************//**
+Opens a session.
+@return own: session object */
UNIV_INTERN
sess_t*
sess_open(void)
/*===========*/
- /* out, own: session object */
{
sess_t* sess;
@@ -61,13 +62,13 @@ sess_open(void)
return(sess);
}
-/*************************************************************************
+/*********************************************************************//**
Closes a session, freeing the memory occupied by it. */
static
void
sess_close(
/*=======*/
- sess_t* sess) /* in, own: session object */
+ sess_t* sess) /*!< in, own: session object */
{
ut_ad(mutex_own(&kernel_mutex));
ut_ad(sess->trx == NULL);
@@ -75,15 +76,15 @@ sess_close(
mem_free(sess);
}
-/*************************************************************************
+/*********************************************************************//**
Closes a session, freeing the memory occupied by it, if it is in a state
-where it should be closed. */
+where it should be closed.
+@return TRUE if closed */
UNIV_INTERN
ibool
sess_try_close(
/*===========*/
- /* out: TRUE if closed */
- sess_t* sess) /* in, own: session object */
+ sess_t* sess) /*!< in, own: session object */
{
ut_ad(mutex_own(&kernel_mutex));
diff --git a/storage/xtradb/ut/ut0auxconf.c b/storage/xtradb/ut/ut0auxconf.c
deleted file mode 100644
index fd9433d16f6..00000000000
--- a/storage/xtradb/ut/ut0auxconf.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <pthread.h>
-
-int
-main(int argc, char** argv)
-{
- pthread_t x1;
- pthread_t x2;
- pthread_t x3;
-
- __sync_bool_compare_and_swap(&x1, x2, x3);
-
- return(0);
-}
diff --git a/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_gcc.c b/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_gcc.c
new file mode 100644
index 00000000000..30de5aa6f17
--- /dev/null
+++ b/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_gcc.c
@@ -0,0 +1,43 @@
+/*****************************************************************************
+
+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
new file mode 100644
index 00000000000..a18a537d1d4
--- /dev/null
+++ b/storage/xtradb/ut/ut0auxconf_atomic_pthread_t_solaris.c
@@ -0,0 +1,34 @@
+/*****************************************************************************
+
+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 Solaris libc atomic functions.
+
+Created April 18, 2009 Vasil Dimov
+*****************************************************************************/
+
+#include <pthread.h>
+
+int
+main(int argc, char** argv)
+{
+ pthread_t x = 0;
+
+ return(0);
+}
diff --git a/storage/xtradb/ut/ut0auxconf_have_solaris_atomics.c b/storage/xtradb/ut/ut0auxconf_have_solaris_atomics.c
new file mode 100644
index 00000000000..7eb704edd4b
--- /dev/null
+++ b/storage/xtradb/ut/ut0auxconf_have_solaris_atomics.c
@@ -0,0 +1,39 @@
+/*****************************************************************************
+
+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
new file mode 100644
index 00000000000..54d63bdd9bc
--- /dev/null
+++ b/storage/xtradb/ut/ut0auxconf_pause.c
@@ -0,0 +1,32 @@
+/*****************************************************************************
+
+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
new file mode 100644
index 00000000000..96add4526ef
--- /dev/null
+++ b/storage/xtradb/ut/ut0auxconf_sizeof_pthread_t.c
@@ -0,0 +1,35 @@
+/*****************************************************************************
+
+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/storage/xtradb/ut/ut0byte.c b/storage/xtradb/ut/ut0byte.c
index 5e11e37d0b6..4e093f72ce2 100644
--- a/storage/xtradb/ut/ut0byte.c
+++ b/storage/xtradb/ut/ut0byte.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/*******************************************************************
+/***************************************************************//**
+@file ut/ut0byte.c
Byte utilities
Created 5/11/1994 Heikki Tuuri
@@ -28,21 +29,25 @@ Created 5/11/1994 Heikki Tuuri
#include "ut0byte.ic"
#endif
-/* Zero value for a dulint */
+/** Zero value for a dulint */
UNIV_INTERN const dulint ut_dulint_zero = {0, 0};
-/* Maximum value for a dulint */
+/** Maximum value for a dulint */
UNIV_INTERN const dulint ut_dulint_max = {0xFFFFFFFFUL, 0xFFFFFFFFUL};
#ifdef notdefined /* unused code */
#include "ut0sort.h"
-/****************************************************************
+/************************************************************//**
Sort function for dulint arrays. */
UNIV_INTERN
void
-ut_dulint_sort(dulint* arr, dulint* aux_arr, ulint low, ulint high)
-/*===============================================================*/
+ut_dulint_sort(
+/*===========*/
+ dulint* arr, /*!< in/out: array to be sorted */
+ dulint* aux_arr,/*!< in/out: auxiliary array (same size as arr) */
+ ulint low, /*!< in: low bound of sort interval, inclusive */
+ ulint high) /*!< in: high bound of sort interval, noninclusive */
{
UT_SORT_FUNCTION_BODY(ut_dulint_sort, arr, aux_arr, low, high,
ut_dulint_cmp);
diff --git a/storage/xtradb/ut/ut0dbg.c b/storage/xtradb/ut/ut0dbg.c
index 55dd457a177..4484e6c36de 100644
--- a/storage/xtradb/ut/ut0dbg.c
+++ b/storage/xtradb/ut/ut0dbg.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/*********************************************************************
+/*****************************************************************//**
+@file ut/ut0dbg.c
Debug utilities for Innobase.
Created 1/30/1994 Heikki Tuuri
@@ -27,40 +28,45 @@ Created 1/30/1994 Heikki Tuuri
#if defined(__GNUC__) && (__GNUC__ > 2)
#else
-/* This is used to eliminate compiler warnings */
+/** This is used to eliminate compiler warnings */
UNIV_INTERN ulint ut_dbg_zero = 0;
#endif
#if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
-/* If this is set to TRUE all threads will stop into the next assertion
-and assert */
+/** If this is set to TRUE by ut_dbg_assertion_failed(), all threads
+will stop at the next ut_a() or ut_ad(). */
UNIV_INTERN ibool ut_dbg_stop_threads = FALSE;
#endif
#ifdef __NETWARE__
-/* This is set to TRUE when on NetWare there happens an InnoDB
-assertion failure or other fatal error condition that requires an
-immediate shutdown. */
+/** Flag for ignoring further assertion failures. This is set to TRUE
+when on NetWare there happens an InnoDB assertion failure or other
+fatal error condition that requires an immediate shutdown. */
UNIV_INTERN ibool panic_shutdown = FALSE;
#elif !defined(UT_DBG_USE_ABORT)
-/* Null pointer used to generate memory trap */
+/** A null pointer that will be dereferenced to trigger a memory trap */
UNIV_INTERN ulint* ut_dbg_null_ptr = NULL;
#endif
-/*****************************************************************
+/*************************************************************//**
Report a failed assertion. */
UNIV_INTERN
void
ut_dbg_assertion_failed(
/*====================*/
- const char* expr, /* in: the failed assertion (optional) */
- const char* file, /* in: source file containing the assertion */
- ulint line) /* in: line number of the assertion */
+ const char* expr, /*!< in: the failed assertion (optional) */
+ const char* file, /*!< in: source file containing the assertion */
+ ulint line) /*!< in: line number of the assertion */
{
ut_print_timestamp(stderr);
+#ifdef UNIV_HOTBACKUP
+ fprintf(stderr, " InnoDB: Assertion failure in file %s line %lu\n",
+ file, line);
+#else /* UNIV_HOTBACKUP */
fprintf(stderr,
" InnoDB: Assertion failure in thread %lu"
" in file %s line %lu\n",
os_thread_pf(os_thread_get_curr_id()), file, line);
+#endif /* UNIV_HOTBACKUP */
if (expr) {
fprintf(stderr,
"InnoDB: Failing assertion: %s\n", expr);
@@ -73,8 +79,7 @@ ut_dbg_assertion_failed(
" or crashes, even\n"
"InnoDB: immediately after the mysqld startup, there may be\n"
"InnoDB: corruption in the InnoDB tablespace. Please refer to\n"
- "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
- "forcing-recovery.html\n"
+ "InnoDB: " REFMAN "forcing-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
#if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
ut_dbg_stop_threads = TRUE;
@@ -82,7 +87,7 @@ ut_dbg_assertion_failed(
}
#ifdef __NETWARE__
-/*****************************************************************
+/*************************************************************//**
Shut down MySQL/InnoDB after assertion failure. */
UNIV_INTERN
void
@@ -97,7 +102,7 @@ ut_dbg_panic(void)
}
#else /* __NETWARE__ */
# if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
-/*****************************************************************
+/*************************************************************//**
Stop a thread after assertion failure. */
UNIV_INTERN
void
@@ -106,9 +111,11 @@ ut_dbg_stop_thread(
const char* file,
ulint line)
{
+#ifndef UNIV_HOTBACKUP
fprintf(stderr, "InnoDB: Thread %lu stopped in file %s line %lu\n",
os_thread_pf(os_thread_get_curr_id()), file, line);
os_thread_sleep(1000000000);
+#endif /* !UNIV_HOTBACKUP */
}
# endif
#endif /* __NETWARE__ */
@@ -133,27 +140,27 @@ ut_dbg_stop_thread(
} while (0)
#endif /* timersub */
-/***********************************************************************
+/*******************************************************************//**
Resets a speedo (records the current time in it). */
UNIV_INTERN
void
speedo_reset(
/*=========*/
- speedo_t* speedo) /* out: speedo */
+ speedo_t* speedo) /*!< out: speedo */
{
gettimeofday(&speedo->tv, NULL);
getrusage(RUSAGE_SELF, &speedo->ru);
}
-/***********************************************************************
+/*******************************************************************//**
Shows the time elapsed and usage statistics since the last reset of a
speedo. */
UNIV_INTERN
void
speedo_show(
/*========*/
- const speedo_t* speedo) /* in: speedo */
+ const speedo_t* speedo) /*!< in: speedo */
{
struct rusage ru_now;
struct timeval tv_now;
diff --git a/storage/xtradb/ut/ut0list.c b/storage/xtradb/ut/ut0list.c
index c6250edb6cd..895a575c535 100644
--- a/storage/xtradb/ut/ut0list.c
+++ b/storage/xtradb/ut/ut0list.c
@@ -16,18 +16,25 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/*******************************************************************//**
+@file ut/ut0list.c
+A double-linked list
+
+Created 4/26/2006 Osku Salerma
+************************************************************************/
+
#include "ut0list.h"
#ifdef UNIV_NONINL
#include "ut0list.ic"
#endif
-/********************************************************************
-Create a new list. */
+/****************************************************************//**
+Create a new list.
+@return list */
UNIV_INTERN
ib_list_t*
ib_list_create(void)
/*=================*/
- /* out: list */
{
ib_list_t* list = mem_alloc(sizeof(ib_list_t));
@@ -38,15 +45,15 @@ ib_list_create(void)
return(list);
}
-/********************************************************************
+/****************************************************************//**
Create a new list using the given heap. ib_list_free MUST NOT BE CALLED for
-lists created with this function. */
+lists created with this function.
+@return list */
UNIV_INTERN
ib_list_t*
ib_list_create_heap(
/*================*/
- /* out: list */
- mem_heap_t* heap) /* in: memory heap to use */
+ mem_heap_t* heap) /*!< in: memory heap to use */
{
ib_list_t* list = mem_heap_alloc(heap, sizeof(ib_list_t));
@@ -57,13 +64,13 @@ ib_list_create_heap(
return(list);
}
-/********************************************************************
+/****************************************************************//**
Free a list. */
UNIV_INTERN
void
ib_list_free(
/*=========*/
- ib_list_t* list) /* in: list */
+ ib_list_t* list) /*!< in: list */
{
ut_a(!list->is_heap_list);
@@ -74,46 +81,46 @@ ib_list_free(
mem_free(list);
}
-/********************************************************************
-Add the data to the start of the list. */
+/****************************************************************//**
+Add the data to the start of the list.
+@return new list node */
UNIV_INTERN
ib_list_node_t*
ib_list_add_first(
/*==============*/
- /* out: new list node*/
- ib_list_t* list, /* in: list */
- void* data, /* in: data */
- mem_heap_t* heap) /* in: memory heap to use */
+ ib_list_t* list, /*!< in: list */
+ void* data, /*!< in: data */
+ mem_heap_t* heap) /*!< in: memory heap to use */
{
return(ib_list_add_after(list, ib_list_get_first(list), data, heap));
}
-/********************************************************************
-Add the data to the end of the list. */
+/****************************************************************//**
+Add the data to the end of the list.
+@return new list node */
UNIV_INTERN
ib_list_node_t*
ib_list_add_last(
/*=============*/
- /* out: new list node*/
- ib_list_t* list, /* in: list */
- void* data, /* in: data */
- mem_heap_t* heap) /* in: memory heap to use */
+ ib_list_t* list, /*!< in: list */
+ void* data, /*!< in: data */
+ mem_heap_t* heap) /*!< in: memory heap to use */
{
return(ib_list_add_after(list, ib_list_get_last(list), data, heap));
}
-/********************************************************************
-Add the data after the indicated node. */
+/****************************************************************//**
+Add the data after the indicated node.
+@return new list node */
UNIV_INTERN
ib_list_node_t*
ib_list_add_after(
/*==============*/
- /* out: new list node*/
- ib_list_t* list, /* in: list */
- ib_list_node_t* prev_node, /* in: node preceding new node (can
+ ib_list_t* list, /*!< in: list */
+ ib_list_node_t* prev_node, /*!< in: node preceding new node (can
be NULL) */
- void* data, /* in: data */
- mem_heap_t* heap) /* in: memory heap to use */
+ void* data, /*!< in: data */
+ mem_heap_t* heap) /*!< in: memory heap to use */
{
ib_list_node_t* node = mem_heap_alloc(heap, sizeof(ib_list_node_t));
@@ -156,14 +163,14 @@ ib_list_add_after(
return(node);
}
-/********************************************************************
+/****************************************************************//**
Remove the node from the list. */
UNIV_INTERN
void
ib_list_remove(
/*===========*/
- ib_list_t* list, /* in: list */
- ib_list_node_t* node) /* in: node to remove */
+ ib_list_t* list, /*!< in: list */
+ ib_list_node_t* node) /*!< in: node to remove */
{
if (node->prev) {
node->prev->next = node->next;
diff --git a/storage/xtradb/ut/ut0mem.c b/storage/xtradb/ut/ut0mem.c
index c87a6a4b57e..edb63c95700 100644
--- a/storage/xtradb/ut/ut0mem.c
+++ b/storage/xtradb/ut/ut0mem.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/************************************************************************
+/********************************************************************//**
+@file ut/ut0mem.c
Memory primitives
Created 5/11/1994 Heikki Tuuri
@@ -28,41 +29,47 @@ Created 5/11/1994 Heikki Tuuri
#include "ut0mem.ic"
#endif
-#include "mem0mem.h"
-#include "os0thread.h"
-#include "srv0srv.h"
+#ifndef UNIV_HOTBACKUP
+# include "os0thread.h"
+# include "srv0srv.h"
#include <stdlib.h>
-/* This struct is placed first in every allocated memory block */
+/** This struct is placed first in every allocated memory block */
typedef struct ut_mem_block_struct ut_mem_block_t;
-/* The total amount of memory currently allocated from the operating
+/** The total amount of memory currently allocated from the operating
system with os_mem_alloc_large() or malloc(). Does not count malloc()
if srv_use_sys_malloc is set. Protected by ut_list_mutex. */
UNIV_INTERN ulint ut_total_allocated_memory = 0;
-/* Mutex protecting ut_total_allocated_memory and ut_mem_block_list */
+/** Mutex protecting ut_total_allocated_memory and ut_mem_block_list */
UNIV_INTERN os_fast_mutex_t ut_list_mutex;
+/** Dynamically allocated memory block */
struct ut_mem_block_struct{
UT_LIST_NODE_T(ut_mem_block_t) mem_block_list;
- /* mem block list node */
- ulint size; /* size of allocated memory */
- ulint magic_n;
+ /*!< mem block list node */
+ ulint size; /*!< size of allocated memory */
+ ulint magic_n;/*!< magic number (UT_MEM_MAGIC_N) */
};
+/** The value of ut_mem_block_struct::magic_n. Used in detecting
+memory corruption. */
#define UT_MEM_MAGIC_N 1601650166
-/* List of all memory blocks allocated from the operating system
+/** List of all memory blocks allocated from the operating system
with malloc. Protected by ut_list_mutex. */
static UT_LIST_BASE_NODE_T(ut_mem_block_t) ut_mem_block_list;
+/** Flag: has ut_mem_block_list been initialized? */
static ibool ut_mem_block_list_inited = FALSE;
+/** A dummy pointer for generating a null pointer exception in
+ut_malloc_low() */
static ulint* ut_mem_null_ptr = NULL;
-/**************************************************************************
+/**********************************************************************//**
Initializes the mem block list at database startup. */
UNIV_INTERN
void
@@ -74,22 +81,24 @@ ut_mem_init(void)
UT_LIST_INIT(ut_mem_block_list);
ut_mem_block_list_inited = TRUE;
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is
-defined and set_to_zero is TRUE. */
+defined and set_to_zero is TRUE.
+@return own: allocated memory */
UNIV_INTERN
void*
ut_malloc_low(
/*==========*/
- /* out, own: allocated memory */
- ulint n, /* in: number of bytes to allocate */
- ibool set_to_zero, /* in: TRUE if allocated memory should be
+ ulint n, /*!< in: number of bytes to allocate */
+ ibool set_to_zero, /*!< in: TRUE if allocated memory should be
set to zero if UNIV_SET_MEM_TO_ZERO is
defined */
- ibool assert_on_error)/* in: if TRUE, we crash mysqld if the
+ ibool assert_on_error)/*!< in: if TRUE, we crash mysqld if the
memory cannot be allocated */
{
+#ifndef UNIV_HOTBACKUP
ulint retry_count;
void* ret;
@@ -208,31 +217,47 @@ retry:
os_fast_mutex_unlock(&ut_list_mutex);
return((void*)((byte*)ret + sizeof(ut_mem_block_t)));
+#else /* !UNIV_HOTBACKUP */
+ void* ret = malloc(n);
+ ut_a(ret || !assert_on_error);
+
+# ifdef UNIV_SET_MEM_TO_ZERO
+ if (set_to_zero) {
+ memset(ret, '\0', n);
+ }
+# endif
+ return(ret);
+#endif /* !UNIV_HOTBACKUP */
}
-/**************************************************************************
+/**********************************************************************//**
Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is
-defined. */
+defined.
+@return own: allocated memory */
UNIV_INTERN
void*
ut_malloc(
/*======*/
- /* out, own: allocated memory */
- ulint n) /* in: number of bytes to allocate */
+ ulint n) /*!< in: number of bytes to allocate */
{
+#ifndef UNIV_HOTBACKUP
return(ut_malloc_low(n, TRUE, TRUE));
+#else /* !UNIV_HOTBACKUP */
+ return(malloc(n));
+#endif /* !UNIV_HOTBACKUP */
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Tests if malloc of n bytes would succeed. ut_malloc() asserts if memory runs
out. It cannot be used if we want to return an error message. Prints to
-stderr a message if fails. */
+stderr a message if fails.
+@return TRUE if succeeded */
UNIV_INTERN
ibool
ut_test_malloc(
/*===========*/
- /* out: TRUE if succeeded */
- ulint n) /* in: try to allocate this many bytes */
+ ulint n) /*!< in: try to allocate this many bytes */
{
void* ret;
@@ -262,15 +287,17 @@ ut_test_malloc(
return(TRUE);
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Frees a memory block allocated with ut_malloc. */
UNIV_INTERN
void
ut_free(
/*====*/
- void* ptr) /* in, own: memory block */
+ void* ptr) /*!< in, own: memory block */
{
+#ifndef UNIV_HOTBACKUP
ut_mem_block_t* block;
if (UNIV_LIKELY(srv_use_sys_malloc)) {
@@ -291,9 +318,13 @@ ut_free(
free(block);
os_fast_mutex_unlock(&ut_list_mutex);
+#else /* !UNIV_HOTBACKUP */
+ free(ptr);
+#endif /* !UNIV_HOTBACKUP */
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Implements realloc. This is needed by /pars/lexyy.c. Otherwise, you should not
use this function because the allocation functions in mem0mem.h are the
recommended ones in InnoDB.
@@ -302,7 +333,7 @@ man realloc in Linux, 2004:
realloc() changes the size of the memory block pointed to
by ptr to size bytes. The contents will be unchanged to
- the minimum of the old and new sizes; newly allocated mem­
+ the minimum of the old and new sizes; newly allocated mem-
ory will be uninitialized. If ptr is NULL, the call is
equivalent to malloc(size); if size is equal to zero, the
call is equivalent to free(ptr). Unless ptr is NULL, it
@@ -316,14 +347,14 @@ RETURN VALUE
size was equal to 0, either NULL or a pointer suitable to
be passed to free() is returned. If realloc() fails the
original block is left untouched - it is not freed or
- moved. */
+ moved.
+@return own: pointer to new mem block or NULL */
UNIV_INTERN
void*
ut_realloc(
/*=======*/
- /* out, own: pointer to new mem block or NULL */
- void* ptr, /* in: pointer to old block or NULL */
- ulint size) /* in: desired size */
+ void* ptr, /*!< in: pointer to old block or NULL */
+ ulint size) /*!< in: desired size */
{
ut_mem_block_t* block;
ulint old_size;
@@ -372,7 +403,7 @@ ut_realloc(
return(new_ptr);
}
-/**************************************************************************
+/**********************************************************************//**
Frees in shutdown all allocated memory not freed yet. */
UNIV_INTERN
void
@@ -403,19 +434,20 @@ ut_free_all_mem(void)
(ulong) ut_total_allocated_memory);
}
}
+#endif /* !UNIV_HOTBACKUP */
-/**************************************************************************
+/**********************************************************************//**
Copies up to size - 1 characters from the NUL-terminated string src to
dst, NUL-terminating the result. Returns strlen(src), so truncation
-occurred if the return value >= size. */
+occurred if the return value >= size.
+@return strlen(src) */
UNIV_INTERN
ulint
ut_strlcpy(
/*=======*/
- /* out: strlen(src) */
- char* dst, /* in: destination buffer */
- const char* src, /* in: source buffer */
- ulint size) /* in: size of destination buffer */
+ char* dst, /*!< in: destination buffer */
+ const char* src, /*!< in: source buffer */
+ ulint size) /*!< in: size of destination buffer */
{
ulint src_size = strlen(src);
@@ -429,17 +461,17 @@ ut_strlcpy(
return(src_size);
}
-/**************************************************************************
+/**********************************************************************//**
Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last
-(size - 1) bytes of src, not the first. */
+(size - 1) bytes of src, not the first.
+@return strlen(src) */
UNIV_INTERN
ulint
ut_strlcpy_rev(
/*===========*/
- /* out: strlen(src) */
- char* dst, /* in: destination buffer */
- const char* src, /* in: source buffer */
- ulint size) /* in: size of destination buffer */
+ char* dst, /*!< in: destination buffer */
+ const char* src, /*!< in: source buffer */
+ ulint size) /*!< in: size of destination buffer */
{
ulint src_size = strlen(src);
@@ -452,18 +484,18 @@ ut_strlcpy_rev(
return(src_size);
}
-/**************************************************************************
+/**********************************************************************//**
Make a quoted copy of a NUL-terminated string. Leading and trailing
quotes will not be included; only embedded quotes will be escaped.
-See also ut_strlenq() and ut_memcpyq(). */
+See also ut_strlenq() and ut_memcpyq().
+@return pointer to end of dest */
UNIV_INTERN
char*
ut_strcpyq(
/*=======*/
- /* out: pointer to end of dest */
- char* dest, /* in: output buffer */
- char q, /* in: the quote character */
- const char* src) /* in: null-terminated string */
+ char* dest, /*!< in: output buffer */
+ char q, /*!< in: the quote character */
+ const char* src) /*!< in: null-terminated string */
{
while (*src) {
if ((*dest++ = *src++) == q) {
@@ -474,19 +506,19 @@ ut_strcpyq(
return(dest);
}
-/**************************************************************************
+/**********************************************************************//**
Make a quoted copy of a fixed-length string. Leading and trailing
quotes will not be included; only embedded quotes will be escaped.
-See also ut_strlenq() and ut_strcpyq(). */
+See also ut_strlenq() and ut_strcpyq().
+@return pointer to end of dest */
UNIV_INTERN
char*
ut_memcpyq(
/*=======*/
- /* out: pointer to end of dest */
- char* dest, /* in: output buffer */
- char q, /* in: the quote character */
- const char* src, /* in: string to be quoted */
- ulint len) /* in: length of src */
+ char* dest, /*!< in: output buffer */
+ char q, /*!< in: the quote character */
+ const char* src, /*!< in: string to be quoted */
+ ulint len) /*!< in: length of src */
{
const char* srcend = src + len;
@@ -499,16 +531,17 @@ ut_memcpyq(
return(dest);
}
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Return the number of times s2 occurs in s1. Overlapping instances of s2
-are only counted once. */
+are only counted once.
+@return the number of times s2 occurs in s1 */
UNIV_INTERN
ulint
ut_strcount(
/*========*/
- /* out: the number of times s2 occurs in s1 */
- const char* s1, /* in: string to search in */
- const char* s2) /* in: string to search for */
+ const char* s1, /*!< in: string to search in */
+ const char* s2) /*!< in: string to search for */
{
ulint count = 0;
ulint len = strlen(s2);
@@ -533,18 +566,17 @@ ut_strcount(
return(count);
}
-/**************************************************************************
+/**********************************************************************//**
Replace every occurrence of s1 in str with s2. Overlapping instances of s1
-are only replaced once. */
+are only replaced once.
+@return own: modified string, must be freed with mem_free() */
UNIV_INTERN
char*
ut_strreplace(
/*==========*/
- /* out, own: modified string, must be
- freed with mem_free() */
- const char* str, /* in: string to operate on */
- const char* s1, /* in: string to replace */
- const char* s2) /* in: string to replace s1 with */
+ const char* str, /*!< in: string to operate on */
+ const char* s1, /*!< in: string to replace */
+ const char* s2) /*!< in: string to replace s1 with */
{
char* new_str;
char* ptr;
@@ -671,3 +703,4 @@ test_ut_str_sql_format()
}
#endif /* UNIV_COMPILE_TEST_FUNCS */
+#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/ut/ut0rnd.c b/storage/xtradb/ut/ut0rnd.c
index f5d6cb08b0f..cefd0990ecc 100644
--- a/storage/xtradb/ut/ut0rnd.c
+++ b/storage/xtradb/ut/ut0rnd.c
@@ -16,7 +16,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/*******************************************************************
+/***************************************************************//**
+@file ut/ut0rnd.c
Random numbers and hashing
Created 5/11/1994 Heikki Tuuri
@@ -28,23 +29,25 @@ Created 5/11/1994 Heikki Tuuri
#include "ut0rnd.ic"
#endif
-/* These random numbers are used in ut_find_prime */
+/** These random numbers are used in ut_find_prime */
+/*@{*/
#define UT_RANDOM_1 1.0412321
#define UT_RANDOM_2 1.1131347
#define UT_RANDOM_3 1.0132677
+/*@}*/
-
+/** Seed value of ut_rnd_gen_ulint(). */
UNIV_INTERN ulint ut_rnd_ulint_counter = 65654363;
-/***************************************************************
+/***********************************************************//**
Looks for a prime number slightly greater than the given argument.
-The prime is chosen so that it is not near any power of 2. */
+The prime is chosen so that it is not near any power of 2.
+@return prime */
UNIV_INTERN
ulint
ut_find_prime(
/*==========*/
- /* out: prime */
- ulint n) /* in: positive number > 100 */
+ ulint n) /*!< in: positive number > 100 */
{
ulint pow2;
ulint i;
diff --git a/storage/xtradb/ut/ut0ut.c b/storage/xtradb/ut/ut0ut.c
index d94e0771a54..e4cc226fbad 100644
--- a/storage/xtradb/ut/ut0ut.c
+++ b/storage/xtradb/ut/ut0ut.c
@@ -1,6 +1,13 @@
/*****************************************************************************
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2009, Sun Microsystems, Inc.
+
+Portions of this file contain modifications contributed and copyrighted by
+Sun Microsystems, Inc. Those modifications are gratefully acknowledged and
+are described briefly in the InnoDB documentation. The contributions by
+Sun Microsystems are incorporated with their permission, and subject to the
+conditions contained in the file COPYING.Sun_Microsystems.
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
@@ -16,7 +23,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
-/*******************************************************************
+/***************************************************************//**
+@file ut/ut0ut.c
Various utilities for Innobase.
Created 5/11/1994 Heikki Tuuri
@@ -32,31 +40,32 @@ Created 5/11/1994 Heikki Tuuri
#include <string.h>
#include <ctype.h>
-#include "trx0trx.h"
-#include "ha_prototypes.h"
#ifndef UNIV_HOTBACKUP
+# include "trx0trx.h"
+# include "ha_prototypes.h"
# include "mysql_com.h" /* NAME_LEN */
#endif /* UNIV_HOTBACKUP */
+/** A constant to prevent the compiler from optimizing ut_delay() away. */
UNIV_INTERN ibool ut_always_false = FALSE;
#ifdef __WIN__
-/*********************************************************************
+/*****************************************************************//**
NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix
epoch starts from 1970/1/1. For selection of constant see:
http://support.microsoft.com/kb/167296/ */
#define WIN_TO_UNIX_DELTA_USEC ((ib_int64_t) 11644473600000000ULL)
-/*********************************************************************
-This is the Windows version of gettimeofday(2).*/
+/*****************************************************************//**
+This is the Windows version of gettimeofday(2).
+@return 0 if all OK else -1 */
static
int
ut_gettimeofday(
/*============*/
- /* out: 0 if all OK else -1 */
- struct timeval* tv, /* out: Values are relative to Unix epoch */
- void* tz) /* in: not used */
+ struct timeval* tv, /*!< out: Values are relative to Unix epoch */
+ void* tz) /*!< in: not used */
{
FILETIME ft;
ib_int64_t tm;
@@ -86,19 +95,21 @@ ut_gettimeofday(
return(0);
}
#else
+/** An alias for gettimeofday(2). On Microsoft Windows, we have to
+reimplement this function. */
#define ut_gettimeofday gettimeofday
#endif
-/************************************************************
+/********************************************************//**
Gets the high 32 bits in a ulint. That is makes a shift >> 32,
but since there seem to be compiler bugs in both gcc and Visual C++,
-we do this by a special conversion. */
+we do this by a special conversion.
+@return a >> 32 */
UNIV_INTERN
ulint
ut_get_high32(
/*==========*/
- /* out: a >> 32 */
- ulint a) /* in: ulint */
+ ulint a) /*!< in: ulint */
{
ib_int64_t i;
@@ -109,9 +120,10 @@ ut_get_high32(
return((ulint)i);
}
-/**************************************************************
+/**********************************************************//**
Returns system time. We do not specify the format of the time returned:
-the only way to manipulate it is to use the function ut_difftime. */
+the only way to manipulate it is to use the function ut_difftime.
+@return system time */
UNIV_INTERN
ib_time_t
ut_time(void)
@@ -120,18 +132,18 @@ ut_time(void)
return(time(NULL));
}
-/**************************************************************
+/**********************************************************//**
Returns system time.
Upon successful completion, the value 0 is returned; otherwise the
value -1 is returned and the global variable errno is set to indicate the
-error. */
+error.
+@return 0 on success, -1 otherwise */
UNIV_INTERN
int
ut_usectime(
/*========*/
- /* out: 0 on success, -1 otherwise */
- ulint* sec, /* out: seconds since the Epoch */
- ulint* ms) /* out: microseconds since the Epoch+*sec */
+ ulint* sec, /*!< out: seconds since the Epoch */
+ ulint* ms) /*!< out: microseconds since the Epoch+*sec */
{
struct timeval tv;
int ret;
@@ -162,16 +174,16 @@ ut_usectime(
return(ret);
}
-/**************************************************************
+/**********************************************************//**
Returns the number of microseconds since epoch. Similar to
time(3), the return value is also stored in *tloc, provided
-that tloc is non-NULL. */
+that tloc is non-NULL.
+@return us since epoch */
UNIV_INTERN
ullint
ut_time_us(
/*=======*/
- /* out: us since epoch */
- ullint* tloc) /* out: us since epoch, if non-NULL */
+ ullint* tloc) /*!< out: us since epoch, if non-NULL */
{
struct timeval tv;
ullint us;
@@ -187,26 +199,26 @@ ut_time_us(
return(us);
}
-/**************************************************************
-Returns the difference of two times in seconds. */
+/**********************************************************//**
+Returns the difference of two times in seconds.
+@return time2 - time1 expressed in seconds */
UNIV_INTERN
double
ut_difftime(
/*========*/
- /* out: time2 - time1 expressed in seconds */
- ib_time_t time2, /* in: time */
- ib_time_t time1) /* in: time */
+ ib_time_t time2, /*!< in: time */
+ ib_time_t time1) /*!< in: time */
{
return(difftime(time2, time1));
}
-/**************************************************************
+/**********************************************************//**
Prints a timestamp to a file. */
UNIV_INTERN
void
ut_print_timestamp(
/*===============*/
- FILE* file) /* in: file where to print */
+ FILE* file) /*!< in: file where to print */
{
#ifdef __WIN__
SYSTEMTIME cal_tm;
@@ -243,13 +255,13 @@ ut_print_timestamp(
#endif
}
-/**************************************************************
+/**********************************************************//**
Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
UNIV_INTERN
void
ut_sprintf_timestamp(
/*=================*/
- char* buf) /* in: buffer where to sprintf */
+ char* buf) /*!< in: buffer where to sprintf */
{
#ifdef __WIN__
SYSTEMTIME cal_tm;
@@ -287,14 +299,14 @@ ut_sprintf_timestamp(
}
#ifdef UNIV_HOTBACKUP
-/**************************************************************
+/**********************************************************//**
Sprintfs a timestamp to a buffer with no spaces and with ':' characters
replaced by '_'. */
UNIV_INTERN
void
ut_sprintf_timestamp_without_extra_chars(
/*=====================================*/
- char* buf) /* in: buffer where to sprintf */
+ char* buf) /*!< in: buffer where to sprintf */
{
#ifdef __WIN__
SYSTEMTIME cal_tm;
@@ -331,15 +343,15 @@ ut_sprintf_timestamp_without_extra_chars(
#endif
}
-/**************************************************************
+/**********************************************************//**
Returns current year, month, day. */
UNIV_INTERN
void
ut_get_year_month_day(
/*==================*/
- ulint* year, /* out: current year */
- ulint* month, /* out: month */
- ulint* day) /* out: day */
+ ulint* year, /*!< out: current year */
+ ulint* month, /*!< out: month */
+ ulint* day) /*!< out: day */
{
#ifdef __WIN__
SYSTEMTIME cal_tm;
@@ -369,28 +381,24 @@ ut_get_year_month_day(
}
#endif /* UNIV_HOTBACKUP */
-/*****************************************************************
+#ifndef UNIV_HOTBACKUP
+/*************************************************************//**
Runs an idle loop on CPU. The argument gives the desired delay
-in microseconds on 100 MHz Pentium + Visual C++. */
-extern ulint srv_spins_microsec;
-
+in microseconds on 100 MHz Pentium + Visual C++.
+@return dummy value */
UNIV_INTERN
ulint
ut_delay(
/*=====*/
- /* out: dummy value */
- ulint delay) /* in: delay in microseconds on 100 MHz Pentium */
+ ulint delay) /*!< in: delay in microseconds on 100 MHz Pentium */
{
ulint i, j;
j = 0;
- for (i = 0; i < delay * srv_spins_microsec; i++) {
-#if (defined (__i386__) || defined (__x86_64__)) && defined (__GNUC__)
- /* it is equal to the instruction 'pause' */
- __asm__ __volatile__ ("rep; nop");
-#endif
+ for (i = 0; i < delay * 50; i++) {
j += i;
+ UT_RELAX_CPU();
}
if (ut_always_false) {
@@ -399,16 +407,17 @@ ut_delay(
return(j);
}
+#endif /* !UNIV_HOTBACKUP */
-/*****************************************************************
+/*************************************************************//**
Prints the contents of a memory buffer in hex and ascii. */
UNIV_INTERN
void
ut_print_buf(
/*=========*/
- FILE* file, /* in: file where to print */
- const void* buf, /* in: memory buffer */
- ulint len) /* in: length of the buffer */
+ FILE* file, /*!< in: file where to print */
+ const void* buf, /*!< in: memory buffer */
+ ulint len) /*!< in: length of the buffer */
{
const byte* data;
ulint i;
@@ -433,14 +442,14 @@ ut_print_buf(
putc(';', file);
}
-/*****************************************************************
-Calculates fast the number rounded up to the nearest power of 2. */
+/*************************************************************//**
+Calculates fast the number rounded up to the nearest power of 2.
+@return first power of 2 which is >= n */
UNIV_INTERN
ulint
ut_2_power_up(
/*==========*/
- /* out: first power of 2 which is >= n */
- ulint n) /* in: number != 0 */
+ ulint n) /*!< in: number != 0 */
{
ulint res;
@@ -455,14 +464,14 @@ ut_2_power_up(
return(res);
}
-/**************************************************************************
+/**********************************************************************//**
Outputs a NUL-terminated file name, quoted with apostrophes. */
UNIV_INTERN
void
ut_print_filename(
/*==============*/
- FILE* f, /* in: output stream */
- const char* name) /* in: name to print */
+ FILE* f, /*!< in: output stream */
+ const char* name) /*!< in: name to print */
{
putc('\'', f);
for (;;) {
@@ -480,8 +489,8 @@ ut_print_filename(
done:
putc('\'', f);
}
-
-/**************************************************************************
+#ifndef UNIV_HOTBACKUP
+/**********************************************************************//**
Outputs a fixed-length string, quoted as an SQL identifier.
If the string contains a slash '/', the string will be
output as two identifiers separated by a period (.),
@@ -490,16 +499,16 @@ UNIV_INTERN
void
ut_print_name(
/*==========*/
- FILE* f, /* in: output stream */
- trx_t* trx, /* in: transaction */
- ibool table_id,/* in: TRUE=print a table name,
+ FILE* f, /*!< in: output stream */
+ trx_t* trx, /*!< in: transaction */
+ ibool table_id,/*!< in: TRUE=print a table name,
FALSE=print other identifier */
- const char* name) /* in: name to print */
+ const char* name) /*!< in: name to print */
{
ut_print_namel(f, trx, table_id, name, strlen(name));
}
-/**************************************************************************
+/**********************************************************************//**
Outputs a fixed-length string, quoted as an SQL identifier.
If the string contains a slash '/', the string will be
output as two identifiers separated by a period (.),
@@ -508,16 +517,13 @@ UNIV_INTERN
void
ut_print_namel(
/*===========*/
- FILE* f, /* in: output stream */
- trx_t* trx, /* in: transaction (NULL=no quotes) */
- ibool table_id,/* in: TRUE=print a table name,
+ FILE* f, /*!< in: output stream */
+ trx_t* trx, /*!< in: transaction (NULL=no quotes) */
+ ibool table_id,/*!< in: TRUE=print a table name,
FALSE=print other identifier */
- const char* name, /* in: name to print */
- ulint namelen)/* in: length of name */
+ const char* name, /*!< in: name to print */
+ ulint namelen)/*!< in: length of name */
{
-#ifdef UNIV_HOTBACKUP
- fwrite(name, 1, namelen, f);
-#else
/* 2 * NAME_LEN for database and table name,
and some slack for the #mysql50# prefix and quotes */
char buf[3 * NAME_LEN];
@@ -529,17 +535,16 @@ ut_print_namel(
table_id);
fwrite(buf, 1, bufend - buf, f);
-#endif
}
-/**************************************************************************
+/**********************************************************************//**
Catenate files. */
UNIV_INTERN
void
ut_copy_file(
/*=========*/
- FILE* dest, /* in: output file */
- FILE* src) /* in: input file to be appended to output */
+ FILE* dest, /*!< in: output file */
+ FILE* src) /*!< in: input file to be appended to output */
{
long len = ftell(src);
char buf[4096];
@@ -557,22 +562,23 @@ ut_copy_file(
}
} while (len > 0);
}
-
-/**************************************************************************
-snprintf(). */
+#endif /* !UNIV_HOTBACKUP */
#ifdef __WIN__
-#include <stdarg.h>
+# include <stdarg.h>
+/**********************************************************************//**
+A substitute for snprintf(3), formatted output conversion into
+a limited buffer.
+@return number of characters that would have been printed if the size
+were unlimited, not including the terminating '\0'. */
+UNIV_INTERN
int
ut_snprintf(
- /* out: number of characters that would
- have been printed if the size were
- unlimited, not including the terminating
- '\0'. */
- char* str, /* out: string */
- size_t size, /* in: str size */
- const char* fmt, /* in: format */
- ...) /* in: format values */
+/*========*/
+ char* str, /*!< out: string */
+ size_t size, /*!< in: str size */
+ const char* fmt, /*!< in: format */
+ ...) /*!< in: format values */
{
int res;
va_list ap1;
diff --git a/storage/xtradb/ut/ut0vec.c b/storage/xtradb/ut/ut0vec.c
index 69b7bec701a..45f2bc9771f 100644
--- a/storage/xtradb/ut/ut0vec.c
+++ b/storage/xtradb/ut/ut0vec.c
@@ -16,21 +16,28 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
+/*******************************************************************//**
+@file ut/ut0vec.c
+A vector of pointers to data items
+
+Created 4/6/2006 Osku Salerma
+************************************************************************/
+
#include "ut0vec.h"
#ifdef UNIV_NONINL
#include "ut0vec.ic"
#endif
#include <string.h>
-/********************************************************************
-Create a new vector with the given initial size. */
+/****************************************************************//**
+Create a new vector with the given initial size.
+@return vector */
UNIV_INTERN
ib_vector_t*
ib_vector_create(
/*=============*/
- /* out: vector */
- mem_heap_t* heap, /* in: heap */
- ulint size) /* in: initial size */
+ mem_heap_t* heap, /*!< in: heap */
+ ulint size) /*!< in: initial size */
{
ib_vector_t* vec;
@@ -46,14 +53,14 @@ ib_vector_create(
return(vec);
}
-/********************************************************************
+/****************************************************************//**
Push a new element to the vector, increasing its size if necessary. */
UNIV_INTERN
void
ib_vector_push(
/*===========*/
- ib_vector_t* vec, /* in: vector */
- void* elem) /* in: data element */
+ ib_vector_t* vec, /*!< in: vector */
+ void* elem) /*!< in: data element */
{
if (vec->used >= vec->total) {
void** new_data;
diff --git a/storage/xtradb/ut/ut0wqueue.c b/storage/xtradb/ut/ut0wqueue.c
index a5c14ac8130..5220d1e17f4 100644
--- a/storage/xtradb/ut/ut0wqueue.c
+++ b/storage/xtradb/ut/ut0wqueue.c
@@ -18,13 +18,20 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "ut0wqueue.h"
-/********************************************************************
-Create a new work queue. */
+/*******************************************************************//**
+@file ut/ut0wqueue.c
+A work queue
+
+Created 4/26/2006 Osku Salerma
+************************************************************************/
+
+/****************************************************************//**
+Create a new work queue.
+@return work queue */
UNIV_INTERN
ib_wqueue_t*
ib_wqueue_create(void)
/*===================*/
- /* out: work queue */
{
ib_wqueue_t* wq = mem_alloc(sizeof(ib_wqueue_t));
@@ -36,13 +43,13 @@ ib_wqueue_create(void)
return(wq);
}
-/********************************************************************
+/****************************************************************//**
Free a work queue. */
UNIV_INTERN
void
ib_wqueue_free(
/*===========*/
- ib_wqueue_t* wq) /* in: work queue */
+ ib_wqueue_t* wq) /*!< in: work queue */
{
ut_a(!ib_list_get_first(wq->items));
@@ -53,15 +60,15 @@ ib_wqueue_free(
mem_free(wq);
}
-/********************************************************************
+/****************************************************************//**
Add a work item to the queue. */
UNIV_INTERN
void
ib_wqueue_add(
/*==========*/
- ib_wqueue_t* wq, /* in: work queue */
- void* item, /* in: work item */
- mem_heap_t* heap) /* in: memory heap to use for allocating the
+ ib_wqueue_t* wq, /*!< in: work queue */
+ void* item, /*!< in: work item */
+ mem_heap_t* heap) /*!< in: memory heap to use for allocating the
list node */
{
mutex_enter(&wq->mutex);
@@ -72,13 +79,14 @@ ib_wqueue_add(
mutex_exit(&wq->mutex);
}
-/********************************************************************
-Wait for a work item to appear in the queue. */
+/****************************************************************//**
+Wait for a work item to appear in the queue.
+@return work item */
UNIV_INTERN
void*
ib_wqueue_wait(
- /* out: work item */
- ib_wqueue_t* wq) /* in: work queue */
+/*===========*/
+ ib_wqueue_t* wq) /*!< in: work queue */
{
ib_list_node_t* node;
diff --git a/storage/xtradb/win-plugin/README b/storage/xtradb/win-plugin/README
index 9182f2c555c..00f4e996a3f 100644
--- a/storage/xtradb/win-plugin/README
+++ b/storage/xtradb/win-plugin/README
@@ -13,9 +13,6 @@ When applying the patch, the following files will be modified:
* CMakeLists.txt
* sql/CMakeLists.txt
* win/configure.js
- * win/build-vs71.bat
- * win/build-vs8.bat
- * win/build-vs8_x64.bat
Also, two new files will be added:
diff --git a/storage/xtradb/win-plugin/win-plugin.diff b/storage/xtradb/win-plugin/win-plugin.diff
index 46d2e5b2d2d..4b3354ac4de 100644
--- a/storage/xtradb/win-plugin/win-plugin.diff
+++ b/storage/xtradb/win-plugin/win-plugin.diff
@@ -1,7 +1,7 @@
diff -Nur CMakeLists.txt.orig CMakeLists.txt
--- CMakeLists.txt.orig 2008-10-03 12:25:41 -05:00
+++ CMakeLists.txt 2008-09-26 17:32:51 -05:00
-@@ -244,9 +244,9 @@
+@@ -254,9 +254,9 @@
IF(WITH_FEDERATED_STORAGE_ENGINE)
ADD_SUBDIRECTORY(storage/federated)
ENDIF(WITH_FEDERATED_STORAGE_ENGINE)
@@ -17,7 +17,7 @@ diff -Nur CMakeLists.txt.orig CMakeLists.txt
diff -Nur sql/CMakeLists.txt.orig sql/CMakeLists.txt
--- sql/CMakeLists.txt.orig 2008-10-03 12:25:41 -05:00
+++ sql/CMakeLists.txt 2008-09-24 03:58:19 -05:00
-@@ -100,6 +100,15 @@
+@@ -98,6 +98,15 @@
LINK_FLAGS "/PDB:${CMAKE_CFG_INTDIR}/mysqld${MYSQLD_EXE_SUFFIX}.pdb")
ENDIF(cmake_version EQUAL 20406)
@@ -33,11 +33,11 @@ diff -Nur sql/CMakeLists.txt.orig sql/CMakeLists.txt
IF(EMBED_MANIFESTS)
MYSQL_EMBED_MANIFEST("mysqld" "asInvoker")
ENDIF(EMBED_MANIFESTS)
-
+
diff -Nur sql/mysqld.def.orig sql/mysqld.def
--- sql/mysqld.def.orig 1969-12-31 18:00:00 -06:00
-+++ sql/mysqld.def 2008-10-31 02:20:32 -05:00
-@@ -0,0 +1,98 @@
++++ sql/mysqld.def 2009-04-09 02:20:32 -05:00
+@@ -0,0 +1,111 @@
+EXPORTS
+ ?use_hidden_primary_key@handler@@UAEXXZ
+ ?get_dynamic_partition_info@handler@@UAEXPAUPARTITION_INFO@@I@Z
@@ -136,11 +136,24 @@ diff -Nur sql/mysqld.def.orig sql/mysqld.def
+ pthread_cond_destroy
+ localtime_r
+ my_strdup
++ deflate
++ deflateEnd
++ deflateReset
++ deflateInit2_
++ inflateEnd
++ inflateInit_
++ inflate
++ compressBound
++ inflateInit2_
++ adler32
++ longlong2str
++ strend
++ my_snprintf
diff -Nur sql/mysqld_x64.def.orig sql/mysqld_x64.def
--- sql/mysqld_x64.def.orig 1969-12-31 18:00:00 -06:00
-+++ sql/mysqld_x64.def 2008-10-31 02:22:04 -05:00
-@@ -0,0 +1,98 @@
++++ sql/mysqld_x64.def 2009-04-09 02:22:04 -05:00
+@@ -0,0 +1,111 @@
+EXPORTS
+ ?use_hidden_primary_key@handler@@UEAAXXZ
+ ?get_dynamic_partition_info@handler@@UEAAXPEAUPARTITION_INFO@@I@Z
@@ -239,59 +252,28 @@ diff -Nur sql/mysqld_x64.def.orig sql/mysqld_x64.def
+ pthread_cond_destroy
+ localtime_r
+ my_strdup
++ deflate
++ deflateEnd
++ deflateReset
++ deflateInit2_
++ inflateEnd
++ inflateInit_
++ inflate
++ compressBound
++ inflateInit2_
++ adler32
++ longlong2str
++ strend
++ my_snprintf
diff -Nur win/configure.js.orig win/configure.js
--- win/configure.js.orig 2008-09-26 21:18:37 -05:00
+++ win/configure.js 2008-10-01 11:21:27 -05:00
-@@ -49,6 +49,7 @@
- case "CYBOZU":
+@@ -50,6 +50,7 @@
case "EMBED_MANIFESTS":
+ case "EXTRA_DEBUG":
case "WITH_EMBEDDED_SERVER":
+ case "INNODB_DYNAMIC_PLUGIN":
configfile.WriteLine("SET (" + args.Item(i) + " TRUE)");
break;
case "MYSQL_SERVER_SUFFIX":
-
-diff -Nur win/build-vs71.bat.orig win/build-vs71.bat
---- win/build-vs71.bat.orig 2008-08-20 10:21:59 -05:00
-+++ win/build-vs71.bat 2008-10-27 10:52:38 -05:00
-@@ -15,8 +15,10 @@
- REM along with this program; if not, write to the Free Software
- REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-+REM CMAKE_BUILD_TYPE can be specified as Release or Debug
-+
- if exist cmakecache.txt del cmakecache.txt
- copy win\vs71cache.txt cmakecache.txt
--cmake -G "Visual Studio 7 .NET 2003"
-+cmake -G "Visual Studio 7 .NET 2003" -DCMAKE_BUILD_TYPE=%1
- copy cmakecache.txt win\vs71cache.txt
-
-diff -Nur win/build-vs8.bat.orig win/build-vs8.bat
---- win/build-vs8.bat.orig 2008-08-20 10:21:59 -05:00
-+++ win/build-vs8.bat 2008-10-27 10:52:31 -05:00
-@@ -15,7 +15,9 @@
- REM along with this program; if not, write to the Free Software
- REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-+REM CMAKE_BUILD_TYPE can be specified as Release or Debug
-+
- if exist cmakecache.txt del cmakecache.txt
- copy win\vs8cache.txt cmakecache.txt
--cmake -G "Visual Studio 8 2005"
-+cmake -G "Visual Studio 8 2005" -DCMAKE_BUILD_TYPE=%1
- copy cmakecache.txt win\vs8cache.txt
-diff -Nur win/build-vs8_x64.bat.orig win/build-vs8_x64.bat
---- win/build-vs8_x64.bat.orig 2008-08-20 10:21:59 -05:00
-+++ win/build-vs8_x64.bat 2008-10-27 10:53:11 -05:00
-@@ -15,7 +15,9 @@
- REM along with this program; if not, write to the Free Software
- REM Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-+REM CMAKE_BUILD_TYPE can be specified as Release or Debug
-+
- if exist cmakecache.txt del cmakecache.txt
- copy win\vs8cache.txt cmakecache.txt
--cmake -G "Visual Studio 8 2005 Win64"
-+cmake -G "Visual Studio 8 2005 Win64" -DCMAKE_BUILD_TYPE=%1
- copy cmakecache.txt win\vs8cache.txt
diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c
index 903811e2ab9..51f93954bd5 100644
--- a/strings/ctype-mb.c
+++ b/strings/ctype-mb.c
@@ -567,8 +567,7 @@ my_bool my_like_range_mb(CHARSET_INFO *cs,
char *min_end= min_str + res_length;
char *max_end= max_str + res_length;
size_t maxcharlen= res_length / cs->mbmaxlen;
- const char *contraction_flags= cs->contractions ?
- ((const char*) cs->contractions) + 0x40*0x40 : NULL;
+ my_bool have_contractions= my_uca_have_contractions(cs);
for (; ptr != end && min_str != min_end && maxcharlen ; maxcharlen--)
{
@@ -636,8 +635,8 @@ fill_max_and_min:
'ab\min\min\min\min' and 'ab\max\max\max\max'.
*/
- if (contraction_flags && ptr + 1 < end &&
- contraction_flags[(uchar) *ptr])
+ if (have_contractions && ptr + 1 < end &&
+ my_uca_can_be_contraction_head(cs, (uchar) *ptr))
{
/* Ptr[0] is a contraction head. */
@@ -659,8 +658,8 @@ fill_max_and_min:
is not a contraction, then we put only ptr[0],
and continue with ptr[1] on the next loop.
*/
- if (contraction_flags[(uchar) ptr[1]] &&
- cs->contractions[(*ptr-0x40)*0x40 + ptr[1] - 0x40])
+ if (my_uca_can_be_contraction_tail(cs, (uchar) ptr[1]) &&
+ my_uca_contraction2_weight(cs, (uchar) ptr[0], (uchar) ptr[1]))
{
/* Contraction found */
if (maxcharlen == 1 || min_str + 1 >= min_end)
diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c
index 7de00025eda..4f3aaa6f668 100644
--- a/strings/ctype-simple.c
+++ b/strings/ctype-simple.c
@@ -185,8 +185,8 @@ int my_strnncollsp_simple(CHARSET_INFO * cs, const uchar *a, size_t a_length,
}
for (end= a + a_length-length; a < end ; a++)
{
- if (map[*a] != ' ')
- return (map[*a] < ' ') ? -swap : swap;
+ if (map[*a] != map[' '])
+ return (map[*a] < map[' ']) ? -swap : swap;
}
}
return res;
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c
index 589276dbf23..b2a60265a0a 100644
--- a/strings/ctype-uca.c
+++ b/strings/ctype-uca.c
@@ -36,6 +36,12 @@
#include "m_string.h"
#include "m_ctype.h"
+
+#define MY_UCA_CNT_FLAG_SIZE 4096
+#define MY_UCA_CNT_FLAG_MASK 4095
+#define MY_UCA_CNT_HEAD 1
+#define MY_UCA_CNT_TAIL 2
+
#ifdef HAVE_UCA_COLLATIONS
#define MY_UCA_NPAGES 256
@@ -6713,6 +6719,16 @@ static const char hungarian[]=
"&U < \\u00FC <<< \\u00DC << \\u0171 <<< \\u0170";
+static const char croatian[]=
+
+"&C < \\u010D <<< \\u010C < \\u0107 <<< \\u0106 "
+"&D < d\\u017E <<< \\u01C6 <<< D\\u017E <<< \\u01C5 <<< D\\u017D <<< \\u01C4 "
+" < \\u0111 <<< \\u0110 "
+"&L < lj <<< \\u01C9 <<< Lj <<< \\u01C8 <<< LJ <<< \\u01C7 "
+"&N < nj <<< \\u01CC <<< Nj <<< \\u01CB <<< NJ <<< \\u01CA "
+"&S < \\u0161 <<< \\u0160 "
+"&Z < \\u017E <<< \\u017D";
+
/*
Unicode Collation Algorithm:
Collation element (weight) scanner,
@@ -6726,7 +6742,7 @@ typedef struct my_uca_scanner_st
const uchar *send; /* End of the input string */
uchar *uca_length;
uint16 **uca_weight;
- uint16 *contractions;
+ MY_CONTRACTIONS *contractions;
uint16 implicit[2];
int page;
int code;
@@ -6746,6 +6762,75 @@ typedef struct my_uca_scanner_handler_st
static uint16 nochar[]= {0,0};
+/********** Helper functions to handle contraction ************/
+
+
+/**
+ Mark a character as a contraction part
+
+ @cs Pointer to CHARSET_INFO data
+ @wc Unicode code point
+ @flag flag: "is contraction head", "is contraction tail"
+*/
+
+static void
+my_uca_add_contraction_flag(CHARSET_INFO *cs, my_wc_t wc, int flag)
+{
+ cs->contractions->flags[wc & MY_UCA_CNT_FLAG_MASK]|= flag;
+}
+
+
+/**
+ Add a new contraction into contraction list
+
+ @cs Pointer to CHARSET_INFO data
+ @wc Unicode code points of the characters
+ @len Number of characters
+
+ @return New contraction
+ @retval Pointer to a newly added contraction
+*/
+
+static MY_CONTRACTION *
+my_uca_add_contraction(CHARSET_INFO *cs,
+ my_wc_t *wc, int len __attribute__((unused)))
+{
+ MY_CONTRACTIONS *list= cs->contractions;
+ MY_CONTRACTION *next= &list->item[list->nitems];
+ DBUG_ASSERT(len == 2); /* We currently support only contraction2 */
+ next->ch[0]= wc[0];
+ next->ch[1]= wc[1];
+ list->nitems++;
+ return next;
+}
+
+
+/**
+ Allocate and initialize memory for contraction list and flags
+
+ @cs Pointer to CHARSET_INFO data
+ @alloc Memory allocation function (typically points to my_alloc_once)
+ @n Number of contractions
+
+ @return Error code
+ @retval 0 - memory allocated successfully
+ @retval 1 - not enough memory
+*/
+
+static my_bool
+my_uca_alloc_contractions(CHARSET_INFO *cs, void *(*alloc)(size_t), size_t n)
+{
+ uint size= n * sizeof(MY_CONTRACTION);
+ if (!(cs->contractions= (*alloc)(sizeof(MY_CONTRACTIONS))))
+ return 1;
+ bzero(cs->contractions, sizeof(MY_CONTRACTIONS));
+ if (!(cs->contractions->item= (*alloc)(size)) ||
+ !(cs->contractions->flags= (char*) (*alloc)(MY_UCA_CNT_FLAG_SIZE)))
+ return 1;
+ bzero((void*) cs->contractions->item, size);
+ bzero((void*) cs->contractions->flags, MY_UCA_CNT_FLAG_SIZE);
+ return 0;
+}
#ifdef HAVE_CHARSET_ucs2
/*
@@ -6766,7 +6851,7 @@ static uint16 nochar[]= {0,0};
*/
static void my_uca_scanner_init_ucs2(my_uca_scanner *scanner,
- CHARSET_INFO *cs __attribute__((unused)),
+ CHARSET_INFO *cs,
const uchar *str, size_t length)
{
scanner->wbeg= nochar;
@@ -6777,6 +6862,7 @@ static void my_uca_scanner_init_ucs2(my_uca_scanner *scanner,
scanner->uca_length= cs->sort_order;
scanner->uca_weight= cs->sort_order_big;
scanner->contractions= cs->contractions;
+ scanner->cs= cs;
return;
}
@@ -6865,18 +6951,23 @@ static int my_uca_scanner_next_ucs2(my_uca_scanner *scanner)
if (scanner->contractions && (scanner->sbeg <= scanner->send))
{
- int cweight;
+ my_wc_t wc1= ((scanner->page << 8) | scanner->code);
- if (!scanner->page && !scanner->sbeg[0] &&
- (scanner->sbeg[1] > 0x40) && (scanner->sbeg[1] < 0x80) &&
- (scanner->code > 0x40) && (scanner->code < 0x80) &&
- (cweight= scanner->contractions[(scanner->code-0x40)*0x40+scanner->sbeg[1]-0x40]))
+ if (my_uca_can_be_contraction_head(scanner->cs, wc1))
+ {
+ uint16 *cweight;
+ my_wc_t wc2= (((my_wc_t) scanner->sbeg[0]) << 8) | scanner->sbeg[1];
+ if (my_uca_can_be_contraction_tail(scanner->cs, wc2) &&
+ (cweight= my_uca_contraction2_weight(scanner->cs,
+ scanner->code,
+ scanner->sbeg[1])))
{
scanner->implicit[0]= 0;
scanner->wbeg= scanner->implicit;
scanner->sbeg+=2;
- return cweight;
+ return *cweight;
}
+ }
}
if (!ucaw[scanner->page])
@@ -6959,23 +7050,22 @@ static int my_uca_scanner_next_any(my_uca_scanner *scanner)
scanner->code= wc & 0xFF;
scanner->sbeg+= mb_len;
- if (scanner->contractions && !scanner->page &&
- (scanner->code > 0x40) && (scanner->code < 0x80))
+ if (my_uca_have_contractions(scanner->cs) &&
+ my_uca_can_be_contraction_head(scanner->cs, wc))
{
- uint page1, code1, cweight;
+ my_wc_t wc2;
+ uint16 *cweight;
- if (((mb_len= scanner->cs->cset->mb_wc(scanner->cs, &wc,
+ if (((mb_len= scanner->cs->cset->mb_wc(scanner->cs, &wc2,
scanner->sbeg,
scanner->send)) >=0) &&
- (!(page1= (wc >> 8))) &&
- ((code1= (wc & 0xFF)) > 0x40) &&
- (code1 < 0x80) &&
- (cweight= scanner->contractions[(scanner->code-0x40)*0x40 + code1-0x40]))
+ my_uca_can_be_contraction_tail(scanner->cs, wc2) &&
+ (cweight= my_uca_contraction2_weight(scanner->cs, wc, wc2)))
{
scanner->implicit[0]= 0;
scanner->wbeg= scanner->implicit;
scanner->sbeg+= mb_len;
- return cweight;
+ return *cweight;
}
}
@@ -7012,6 +7102,33 @@ static my_uca_scanner_handler my_any_uca_scanner_handler=
my_uca_scanner_next_any
};
+
+
+/**
+ Helper function:
+ Find address of weights of the given character.
+
+ @weights UCA weight array
+ @lengths UCA length array
+ @ch character Unicode code point
+
+ @return Weight array
+ @retval pointer to weight array for the given character,
+ or NULL if this page does not have implicit weights.
+*/
+
+static inline uint16 *
+my_char_weight_addr(CHARSET_INFO *cs, uint wc)
+{
+ uint page= (wc >> 8);
+ uint ofst= wc & 0xFF;
+ return cs->sort_order_big[page] ?
+ cs->sort_order_big[page] + ofst * cs->sort_order[page] :
+ NULL;
+}
+
+
+
/*
Compares two strings according to the collation
@@ -7683,8 +7800,8 @@ ex:
typedef struct my_coll_rule_item_st
{
- uint base; /* Base character */
- uint curr[2]; /* Current character */
+ my_wc_t base; /* Base character */
+ my_wc_t curr[2]; /* Current character */
int diff[3]; /* Primary, Secondary and Tertiary difference */
} MY_COLL_RULE;
@@ -7834,6 +7951,7 @@ static int my_coll_rule_parse(MY_COLL_RULE *rule, size_t mitems,
static my_bool create_tailoring(CHARSET_INFO *cs, void *(*alloc)(size_t))
{
MY_COLL_RULE rule[MY_MAX_COLL_RULE];
+ MY_COLL_RULE *r, *rfirst, *rlast;
char errstr[128];
uchar *newlengths;
uint16 **newweights;
@@ -7858,6 +7976,12 @@ static my_bool create_tailoring(CHARSET_INFO *cs, void *(*alloc)(size_t))
return 1;
}
+ rfirst= rule;
+ rlast= rule + rc;
+
+ if (!cs->caseinfo)
+ cs->caseinfo= my_unicase_default;
+
if (!(newweights= (uint16**) (*alloc)(256*sizeof(uint16*))))
return 1;
bzero(newweights, 256*sizeof(uint16*));
@@ -7938,44 +8062,21 @@ static my_bool create_tailoring(CHARSET_INFO *cs, void *(*alloc)(size_t))
/* Now process contractions */
if (ncontractions)
{
- /*
- 8K for weights for basic latin letter pairs,
- plus 256 bytes for "is contraction part" flags.
- */
- uint size= 0x40*0x40*sizeof(uint16) + 256;
- char *contraction_flags;
- if (!(cs->contractions= (uint16*) (*alloc)(size)))
- return 1;
- bzero((void*)cs->contractions, size);
- contraction_flags= ((char*) cs->contractions) + 0x40*0x40;
- for (i=0; i < rc; i++)
+ if (my_uca_alloc_contractions(cs, alloc, ncontractions))
+ return 1;
+ for (r= rfirst; r < rlast; r++)
{
- if (rule[i].curr[1])
+ uint16 *to;
+ if (r->curr[1]) /* Contraction */
{
- uint pageb= (rule[i].base >> 8) & 0xFF;
- uint chb= rule[i].base & 0xFF;
- uint16 *offsb= defweights[pageb] + chb*deflengths[pageb];
- uint offsc;
-
- if (offsb[1] ||
- rule[i].curr[0] < 0x40 || rule[i].curr[0] > 0x7f ||
- rule[i].curr[1] < 0x40 || rule[i].curr[1] > 0x7f)
- {
- /*
- TODO: add error reporting;
- We support only basic latin letters contractions at this point.
- Also, We don't support contractions with weight longer than one.
- Otherwise, we'd need much more memory.
- */
- return 1;
- }
- offsc= (rule[i].curr[0]-0x40)*0x40+(rule[i].curr[1]-0x40);
-
- /* Copy base weight applying primary difference */
- cs->contractions[offsc]= offsb[0] + rule[i].diff[0];
- /* Mark both letters as "is contraction part */
- contraction_flags[rule[i].curr[0]]= 1;
- contraction_flags[rule[i].curr[1]]= 1;
+ /* Mark both letters as "is contraction part" */
+ my_uca_add_contraction_flag(cs, r->curr[0], MY_UCA_CNT_HEAD);
+ my_uca_add_contraction_flag(cs, r->curr[1], MY_UCA_CNT_TAIL);
+ to= my_uca_add_contraction(cs, r->curr, 2)->weight;
+ /* Copy weight from the reset character */
+ to[0]= my_char_weight_addr(cs, r->base)[0];
+ /* Apply primary difference */
+ to[0]+= r->diff[0];
}
}
}
@@ -8698,6 +8799,39 @@ CHARSET_INFO my_charset_ucs2_hungarian_uca_ci=
};
+CHARSET_INFO my_charset_ucs2_croatian_uca_ci=
+{
+ 149,0,0, /* number */
+ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+ "ucs2", /* cs name */
+ "ucs2_croatian_ci", /* name */
+ "", /* comment */
+ croatian, /* tailoring */
+ NULL, /* ctype */
+ NULL, /* to_lower */
+ NULL, /* to_upper */
+ NULL, /* sort_order */
+ NULL, /* contractions */
+ NULL, /* sort_order_big*/
+ NULL, /* tab_to_uni */
+ NULL, /* tab_from_uni */
+ my_unicase_default, /* caseinfo */
+ NULL, /* state_map */
+ NULL, /* ident_map */
+ 8, /* strxfrm_multiply */
+ 1, /* caseup_multiply */
+ 1, /* casedn_multiply */
+ 2, /* mbminlen */
+ 2, /* mbmaxlen */
+ 9, /* min_sort_char */
+ 0xFFFF, /* max_sort_char */
+ ' ', /* pad char */
+ 0, /* escape_with_backslash_is_dangerous */
+ &my_charset_ucs2_handler,
+ &my_collation_ucs2_uca_handler
+};
+
+
#endif
@@ -9355,6 +9489,113 @@ CHARSET_INFO my_charset_utf8_hungarian_uca_ci=
&my_collation_any_uca_handler
};
+CHARSET_INFO my_charset_utf8_croatian_uca_ci=
+{
+ 213,0,0, /* number */
+ MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
+ "utf8", /* cs name */
+ "utf8_croatian_ci", /* name */
+ "", /* comment */
+ croatian, /* tailoring */
+ ctype_utf8, /* ctype */
+ NULL, /* to_lower */
+ NULL, /* to_upper */
+ NULL, /* sort_order */
+ NULL, /* contractions */
+ NULL, /* sort_order_big*/
+ NULL, /* tab_to_uni */
+ NULL, /* tab_from_uni */
+ my_unicase_default, /* caseinfo */
+ NULL, /* state_map */
+ NULL, /* ident_map */
+ 8, /* strxfrm_multiply */
+ 1, /* caseup_multiply */
+ 1, /* casedn_multiply */
+ 1, /* mbminlen */
+ 3, /* mbmaxlen */
+ 9, /* min_sort_char */
+ 0xFFFF, /* max_sort_char */
+ ' ', /* pad char */
+ 0, /* escape_with_backslash_is_dangerous */
+ &my_charset_utf8_handler,
+ &my_collation_any_uca_handler
+};
+
#endif /* HAVE_CHARSET_utf8 */
#endif /* HAVE_UCA_COLLATIONS */
+
+/**
+ Check if UCA data has contractions (public version)
+
+ @cs Pointer to CHARSET_INFO data
+ @retval 0 - no contraction, 1 - have contractions.
+*/
+
+my_bool
+my_uca_have_contractions(CHARSET_INFO *cs)
+{
+ return cs->contractions != NULL;
+}
+
+/**
+ Check if a character can be contraction head
+
+ @cs Pointer to CHARSET_INFO data
+ @wc Code point
+
+ @retval 0 - cannot be contraction head
+ @retval 1 - can be contraction head
+*/
+
+my_bool
+my_uca_can_be_contraction_head(CHARSET_INFO *cs, my_wc_t wc)
+{
+ return cs->contractions->flags[wc & MY_UCA_CNT_FLAG_MASK] & MY_UCA_CNT_HEAD;
+}
+
+
+/**
+ Check if a character can be contraction tail
+
+ @cs Pointer to CHARSET_INFO data
+ @wc Code point
+
+ @retval 0 - cannot be contraction tail
+ @retval 1 - can be contraction tail
+*/
+
+my_bool
+my_uca_can_be_contraction_tail(CHARSET_INFO *cs, my_wc_t wc)
+{
+ return cs->contractions->flags[wc & MY_UCA_CNT_FLAG_MASK] & MY_UCA_CNT_TAIL;
+}
+
+
+/**
+ Find a contraction and return its weight array
+
+ @cs Pointer to CHARSET data
+ @wc1 First character
+ @wc2 Second character
+
+ @return Weight array
+ @retval NULL - no contraction found
+ @retval ptr - contraction weight array
+*/
+
+uint16 *
+my_uca_contraction2_weight(CHARSET_INFO *cs, my_wc_t wc1, my_wc_t wc2)
+{
+ MY_CONTRACTIONS *list= cs->contractions;
+ MY_CONTRACTION *c, *last;
+ for (c= list->item, last= &list->item[list->nitems]; c < last; c++)
+ {
+ if (c->ch[0] == wc1 && c->ch[1] == wc2)
+ {
+ return c->weight;
+ }
+ }
+ return NULL;
+}
+
diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c
index f030c08523c..2607e0f6d43 100644
--- a/strings/ctype-ucs2.c
+++ b/strings/ctype-ucs2.c
@@ -1526,8 +1526,7 @@ my_bool my_like_range_ucs2(CHARSET_INFO *cs,
char *min_org=min_str;
char *min_end=min_str+res_length;
size_t charlen= res_length / cs->mbmaxlen;
- const char *contraction_flags= cs->contractions ?
- ((const char*) cs->contractions) + 0x40*0x40 : NULL;
+ my_bool have_contractions= my_uca_have_contractions(cs);
for ( ; ptr + 1 < end && min_str + 1 < min_end && charlen > 0
; ptr+=2, charlen--)
@@ -1567,8 +1566,9 @@ fill_max_and_min:
return 0;
}
- if (contraction_flags && ptr + 3 < end &&
- ptr[0] == '\0' && contraction_flags[(uchar) ptr[1]])
+ if (have_contractions && ptr + 3 < end &&
+ ptr[0] == '\0' &&
+ my_uca_can_be_contraction_head(cs, (uchar) ptr[1]))
{
/* Contraction head found */
if (ptr[2] == '\0' && (ptr[3] == w_one || ptr[3] == w_many))
@@ -1581,8 +1581,9 @@ fill_max_and_min:
Check if the second letter can be contraction part,
and if two letters really produce a contraction.
*/
- if (ptr[2] == '\0' && contraction_flags[(uchar) ptr[3]] &&
- cs->contractions[(ptr[1]-0x40)*0x40 + ptr[3] - 0x40])
+ if (ptr[2] == '\0' &&
+ my_uca_can_be_contraction_tail(cs, (uchar) ptr[3]) &&
+ my_uca_contraction2_weight(cs,(uchar) ptr[1], (uchar) ptr[3]))
{
/* Contraction found */
if (charlen == 1 || min_str + 2 >= min_end)
diff --git a/support-files/MacOSX/ReadMe.txt b/support-files/MacOSX/ReadMe.txt
index d1ea8514e79..d81ec1f66d6 100644
--- a/support-files/MacOSX/ReadMe.txt
+++ b/support-files/MacOSX/ReadMe.txt
@@ -1,5 +1,47 @@
-2.5. Installing MySQL on Mac OS X
+2.7. Installing MySQL on Mac OS X
+
+ MySQL for Mac OS X is available in a number of different forms:
+
+ * Native Package Installer format, which uses the native Mac OS
+ X installer to walk you through the installation of MySQL. For
+ more information, see Section 2.7.1, "Installing MySQL Using
+ the Installation Package." You can use the package installer
+ with Mac OS X 10.3 and later, and available for both PowerPC
+ and Intel architectures, and both 32-bit and 64-bit
+ architectures. There is no Universal Binary available using
+ the package installation method. The user you use to perform
+ the installation must have administrator privileges.
+
+ * Tar package format, which uses a file packaged using the Unix
+ tar and gzip commands. To use this method, you will need to
+ open a Terminal window. You do not need administrator
+ privileges using this method, as you can install the MySQL
+ server anywhere using this method. For more information on
+ using this method, you can use the generic instructions for
+ using a tarball, Section 2.2, "Installing MySQL from Generic
+ Binaries on Unix/Linux."You can use the package installer with
+ Mac OS X 10.3 and later, and available for both PowerPC and
+ Intel architectures, and both 32-bit and 64-bit architectures.
+ A Universal Binary, incorporating both Power PC and Intel
+ architectures and 32-bit and 64-bit binaries is available.
+ In addition to the core installation, the Package Installer
+ also includes Section 2.7.2, "Installing the MySQL Startup
+ Item" and Section 2.7.3, "Installing and Using the MySQL
+ Preference Pane," both of which simplify the management of
+ your installation.
+
+ * Mac OS X server includes a version of MySQL as standard. If
+ you want to use a more recent version than that supplied with
+ the Mac OS X server release, you can make use of the package
+ or tar formats. For more information on using the MySQL
+ bundled with Mac OS X, see Section 2.7.4, "Using MySQL on Mac
+ OS X Server."
+
+ For additional information on using MySQL on Mac OS X, see Section
+ 2.7.5, "MySQL Installation on Mac OS X Notes."
+
+2.7.1. Installing MySQL Using the Installation Package
You can install MySQL on Mac OS X 10.3.x ("Panther") or newer
using a Mac OS X binary package in PKG format instead of the
@@ -11,8 +53,6 @@
first need to mount by double-clicking its icon in the Finder. It
should then mount the image and display its contents.
- To obtain MySQL, see Section 2.1.3, "How to Get MySQL."
-
Note
Before proceeding with the installation, be sure to shut down all
@@ -20,37 +60,213 @@ Note
Application (on Mac OS X Server) or via mysqladmin shutdown on the
command line.
- To actually install the MySQL PKG file, double-click on the
- package icon. This launches the Mac OS X Package Installer, which
- guides you through the installation of MySQL.
+ When installing from the package version, you should also install
+ the MySQL Preference Pane, which will allow you to control the
+ startup and execution of your MySQL server from System
+ Preferences. For more information, see Section 2.7.3, "Installing
+ and Using the MySQL Preference Pane."
- Due to a bug in the Mac OS X package installer, you may see this
- error message in the destination disk selection dialog:
-You cannot install this software on this disk. (null)
+ When installing using the package installer, the files are
+ installed into a directory within /usr/local matching the name of
+ the installation version and platform. For example, the installer
+ file mysql-5.1.39-osx10.5-x86_64.pkg installs MySQL into
+ /usr/local/mysql-5.1.39-osx10.5-x86_64 . The installation layout
+ of the directory is as shown in the following table:
+ Directory Contents of Directory
+ bin Client programs and the mysqld server
+ data Log files, databases
+ docs Manual in Info format
+ include Include (header) files
+ lib Libraries
+ man Unix manual pages
+ mysql-test MySQL test suite
+ scripts Contains the mysql_install_db script
+ share/mysql Error message files
+ sql-bench Benchmarks
+ support-files Scripts and sample configuration files
+ /tmp/mysql.sock The location of the MySQL Unix socket
+
+ During the package installer process, a symbolic link from
+ /usr/local/mysql to the version/platform specific directory
+ created during installation will be created automatically.
+
+ 1. Download and open the MySQL package installer, which is
+ provided on a disk image (.dmg). Double-click to open the disk
+ image, which includes the main MySQL installation package, the
+ MySQLStartupItem.pkg installation package, and the
+ MySQL.prefPane.
+
+ 2. Double-click on the MySQL installer package. It will be named
+ according to the version of MySQL you have downloaded. For
+ example, if you have downloaded MySQL 5.1.39, double-click
+ mysql-5.1.39-osx10.5-x86.pkg.
+
+ 3. You will be presented with the openin installer dialog. Click
+ Continue to begihn installation.
+ MySQL Package Installer: Step 1
+
+ 4. A copy of the installation instructions and other important
+ information relevant to this installation are display. Click
+ Continue .
+
+ 5. If you have downloaded the community version of MySQL, you
+ will be shown a copy of the relevent GNU General Public
+ License. Click Continue .
+
+ 6. Select the drive you want to use to install the MySQL Startup
+ Item. The drive must have a valid, bootable, Mac OS X
+ operating system installed. Click Continue.
+ MySQL Package Installer: Step 4
+
+ 7. You will be asked to confirm the details of the installation,
+ including the space required for the installation. To change
+ the drive on which the startup item is installed you can click
+ either Go Back or Change Install Location.... To install the
+ startup item, click Install.
+
+ 8. Once the installation has been completed successfully, you
+ will be given an Install Succeeded message.
+
+ Once you have completed the basic installation, you must complete
+ the post-installation steps as specifed in Section 2.13,
+ "Post-Installation Setup and Testing."
+
+ For convenience, you may also want to install the Section 2.7.2,
+ "Installing the MySQL Startup Item" and Section 2.7.3, "Installing
+ and Using the MySQL Preference Pane."
+
+2.7.2. Installing the MySQL Startup Item
+
+ The MySQL Installation Package includes a startup item that can be
+ used to automatically startup and shutdown MySQL during boot.
+
+ To install the MySQL Startup Item:
+
+ 1. Download and open the MySQL package installer, which is
+ provided on a disk image (.dmg). Double-click to open the disk
+ image, which includes the main MySQL installation package, the
+ MySQLStartupItem.pkg installation package, and the
+ MySQL.prefPane.
+
+ 2. Double-click on the MySQLStartItem.pkg file to start the
+ installation process.
+
+ 3. You will be presented with the Install MySQL Startup Item
+ dialog.
+ MySQL Startup Item Installer: Step 1
+ Click Continue to continue the installation process.
+
+ 4. A copy of the installation instructions and other important
+ information relevant to this installation are display. Click
+ Continue .
- If this error occurs, simply click the Go Back button once to
- return to the previous screen. Then click Continue to advance to
- the destination disk selection again, and you should be able to
- choose the destination disk correctly. We have reported this bug
- to Apple and it is investigating this problem.
-
- The Mac OS X PKG of MySQL installs itself into
- /usr/local/mysql-VERSION and also installs a symbolic link,
- /usr/local/mysql, that points to the new location. If a directory
- named /usr/local/mysql exists, it is renamed to
- /usr/local/mysql.bak first. Additionally, the installer creates
- the grant tables in the mysql database by executing
- mysql_install_db.
-
- The installation layout is similar to that of a tar file binary
- distribution; all MySQL binaries are located in the directory
- /usr/local/mysql/bin. The MySQL socket file is created as
- /tmp/mysql.sock by default. See Section 2.1.5, "Installation
- Layouts."
-
- MySQL installation requires a Mac OS X user account named mysql. A
- user account with this name should exist by default on Mac OS X
- 10.2 and up.
+ 5. Select the drive you want to use to install the MySQL Startup
+ Item. The drive must have a valid, bootable, Mac OS X
+ operating system installed. Click Continue.
+ MySQL Startup Item Installer: Step 3
+
+ 6. You will be asked to confirm the details of the installation.
+ To change the drive on which the startup item is installed you
+ can click either Go Back or Change Install Location.... To
+ install the startup item, click Install.
+
+ 7. Once the installation has been completed successfully, you
+ will be given an Install Succeeded message.
+ MySQL Startup Item Installer: Step 5
+
+ The Startup Item for MySQL is installed into
+ /Library/StartupItems/MySQLCOM. The Startup Item installation adds
+ a variable MYSQLCOM=-YES- to the system configuration file
+ /etc/hostconfig. If you want to disable the automatic startup of
+ MySQL, simply change this variable to MYSQLCOM=-NO-.
+
+ After the installation, you can start up MySQL by running the
+ following commands in a terminal window. You must have
+ administrator privileges to perform this task.
+
+ If you have installed the Startup Item, use this command to start
+ the server:
+shell> sudo /Library/StartupItems/MySQLCOM/MySQLCOM start
+
+ You may be prompted for your password to complete the startup.
+
+ If you have installed the Startup Item, use this command to stop
+ the server:
+shell> sudo /Library/StartupItems/MySQLCOM/MySQLCOM stop
+
+ You may be prompted for your password to complete the shutdown.
+
+2.7.3. Installing and Using the MySQL Preference Pane
+
+ The MySQL Package installer disk image also includes a custom
+ MySQL Preference Pane that enables you to start, stop and control
+ automated startup during boot of your MySQL installation.
+
+ To install the MySQL Preference Pane:
+
+ 1. Download and open the MySQL package installer package, which
+ is provided on a disk image (.dmg). Double-click to open the
+ disk image, which includes the main MySQL installation
+ package, the MySQLStartupItem.pkg installation package, and
+ the MySQL.prefPane.
+
+ 2. Double click on MySQL.prefPane. The MySQL System Preferences
+ will open.
+
+ 3. If this is the first time you have installed the preference
+ pane, you will be asked to confirm installation and whether
+ you want to install the preference pane for all users, or only
+ the current user. To install the preference pane for all users
+ you will need administrator privileges. If necessary, you will
+ be prompted for the username and password for a user with
+ administrator privileges.
+
+ 4. If you already have the MySQL Preference Pane installed, you
+ will be asked to confirm whether you want to overwrite the
+ existing MySQL Preference Pane.
+
+Note
+
+ The MySQL Preference Pane only starts and stops MySQL installation
+ installed from the MySQL package installation that have been
+ installed in the default location.
+
+ Once the MySQL Preference Pane has been installed, you can control
+ your MySQL server instance using the preference pane. To use the
+ preference pane, open the System Preferences... from the Apple
+ menu. Select the MySQL preference pane by clicking on the MySQL
+ logo within the Other section of the preference panes list.
+ MySQL Preference Pane
+
+ The MySQL Preference Pane shows the current status of the MySQL
+ server, showing stopped (in red) if the server is not running and
+ running (in green) if the server has already been started. The
+ preference pane will also show the current setting for whether the
+ MySQL server has been set to start up automatically.
+
+ * To start MySQL using the preference pane:
+ Click Start MySQL Server. You may be prompted for the username
+ and password of a user with administrator privileges to start
+ the MySQL server.
+
+ * To stop MySQL using the preference pane:
+ Click Stop MySQL Server. You may be prompted for the username
+ and password of a user with administrator privileges to
+ shutdown the MySQL server.
+
+ * To automatically start the MySQL server when the system boots:
+ Check the checkbox next to Automatically Start MySQL Server on
+ Startup.
+
+ * To disable the automatic starting of the MySQL server when the
+ system boots:
+ Uncheck the checkbox next to Automatically Start MySQL Server
+ on Startup.
+
+ You can close the System Preferences... once you have completed
+ your settings.
+
+2.7.4. Using MySQL on Mac OS X Server
If you are running Mac OS X Server, a version of MySQL should
already be installed. The following table shows the versions of
@@ -61,103 +277,102 @@ You cannot install this software on this disk. (null)
10.3 4.0.14
10.3.2 4.0.16
10.4.0 4.1.10a
+ 10.5.0 5.0.45
+ 10.6.0 5.0.82
- This manual section covers the installation of the official MySQL
- Mac OS X PKG only. Make sure to read Apple's help information
- about installing MySQL: Run the "Help View" application, select
- "Mac OS X Server" help, do a search for "MySQL," and read the item
- entitled "Installing MySQL."
-
- If you previously used Marc Liyanage's MySQL packages for Mac OS X
- from http://www.entropy.ch, you can simply follow the update
- instructions for packages using the binary installation layout as
- given on his pages.
-
- If you are upgrading from Marc's 3.23.x versions or from the Mac
- OS X Server version of MySQL to the official MySQL PKG, you also
- need to convert the existing MySQL privilege tables to the current
- format, because some new security privileges have been added. See
- Section 4.4.8, "mysql_upgrade --- Check Tables for MySQL Upgrade."
-
- If you want MySQL to start automatically during system startup,
- you also need to install the MySQL Startup Item. It is part of the
- Mac OS X installation disk images as a separate installation
- package. Simply double-click the MySQLStartupItem.pkg icon and
- follow the instructions to install it. The Startup Item need be
- installed only once. There is no need to install it each time you
- upgrade the MySQL package later.
+ The installation layout of MySQL on Mac OS X Server is as shown in
+ the table below:
+ Directory Contents of Directory
+ /usr/bin Client programs
+ /var/mysql Log files, databases
+ /usr/libexec The mysqld server
+ /usr/share/man Unix manual pages
+ /usr/share/mysql/mysql-test MySQL test suite
+ /usr/share/mysql Contains the mysql_install_db script
+ /var/mysql/mysql.sock The location of the MySQL Unix socket
- The Startup Item for MySQL is installed into
- /Library/StartupItems/MySQLCOM. (Before MySQL 4.1.2, the location
- was /Library/StartupItems/MySQL, but that collided with the MySQL
- Startup Item installed by Mac OS X Server.) Startup Item
- installation adds a variable MYSQLCOM=-YES- to the system
- configuration file /etc/hostconfig. If you want to disable the
- automatic startup of MySQL, simply change this variable to
- MYSQLCOM=-NO-.
-
- On Mac OS X Server, the default MySQL installation uses the
- variable MYSQL in the /etc/hostconfig file. The MySQL Startup Item
- installer disables this variable by setting it to MYSQL=-NO-. This
- avoids boot time conflicts with the MYSQLCOM variable used by the
- MySQL Startup Item. However, it does not shut down a running MySQL
- server. You should do that yourself.
+Note
- After the installation, you can start up MySQL by running the
- following commands in a terminal window. You must have
- administrator privileges to perform this task.
+ The MySQL server bundled with Mac OS X Server does not include the
+ MySQL client libraries and header files required if you want to
+ access and use MySQL from a third-party driver, such as Perl DBI
+ or PHP. For more information on obtaining and installing MySQL
+ libraries, see Mac OS X Server version 10.5: MySQL libraries
+ available for download (http://support.apple.com/kb/TA25017).
+ Alternatively, you can ignore the bundled MySQL server and install
+ MySQL from the package or tarball installation.
- If you have installed the Startup Item, use this command:
-shell> sudo /Library/StartupItems/MySQLCOM/MySQLCOM start
-(Enter your password, if necessary)
-(Press Control-D or enter "exit" to exit the shell)
+ For more information on managing the bundled MySQL instance in Mac
+ OS X Server 10.5, see Mac OS X Server: Web Technologies
+ Administration For Version 10.5 Leopard
+ (http://images.apple.com/server/macosx/docs/Web_Technologies_Admin
+ _v10.5.pdf). For more information on managing the bundled MySQL
+ instance in Mac OS X Server 10.6, see Mac OS X Server: Web
+ Technologies Administration Version 10.6 Snow Leopard
+ (http://manuals.info.apple.com/en_US/WebTech_v10.6.pdf).
- If you don't use the Startup Item, enter the following command
- sequence:
-shell> cd /usr/local/mysql
-shell> sudo ./bin/mysqld_safe
-(Enter your password, if necessary)
-(Press Control-Z)
-shell> bg
-(Press Control-D or enter "exit" to exit the shell)
+2.7.5. MySQL Installation on Mac OS X Notes
- You should be able to connect to the MySQL server, for example, by
- running /usr/local/mysql/bin/mysql.
+ You should keep the following issues and notes in mind:
-Note
+ * The default location for the MySQL Unix socket is different on
+ Mac OS X and Mac OS X Server depending on the installation
+ type you chose. The default locations by installation are as
+ follows:
- The accounts that are listed in the MySQL grant tables initially
- have no passwords. After starting the server, you should set up
- passwords for them using the instructions in Section 2.11,
- "Post-Installation Setup and Testing."
+ Package Installer from MySQL /tmp/mysql.sock
+ Tarball from MySQL /tmp/mysql.sock
+ MySQL Bundled with Mac OS X Server /var/mysql/mysql.sock
+ To prevent issues, you should either change the configuration
+ of the socket used within your application (for example,
+ changing php.ini), or you should configure the socket location
+ using a MySQL configuration file and the socket option. For
+ more information, see Section 5.1.2, "Server Command Options."
+
+ * You may need (or want) to create a specific mysql user to own
+ the MySQL directory and data. On Mac OS X 10.4 and lower you
+ can do this by using the Netinfo Manager application, located
+ within the Utilities folder within the Applications folder. On
+ Mac OS X 10.5 and later you can do this through the Directory
+ Utility. From Mac OS X 10.5 and later (including Mac OS X
+ Server 10.5) the mysql should already exist. For use in single
+ user mode, an entry for _mysql (note the underscore prefix)
+ should already exist within the system /etc/passwd file.
- You might want to add aliases to your shell's resource file to
- make it easier to access commonly used programs such as mysql and
- mysqladmin from the command line. The syntax for bash is:
+ * Due to a bug in the Mac OS X package installer, you may see
+ this error message in the destination disk selection dialog:
+You cannot install this software on this disk. (null)
+ If this error occurs, simply click the Go Back button once to
+ return to the previous screen. Then click Continue to advance
+ to the destination disk selection again, and you should be
+ able to choose the destination disk correctly. We have
+ reported this bug to Apple and it is investigating this
+ problem.
+
+ * Because the MySQL package installer installs the MySQL
+ contents into a version and platform specific directory, you
+ can use this to upgrade and migrate your database between
+ versions. You will need to either copy the data directory from
+ the old version to the new version, or alternatively specify
+ an alternative datadir value to set location of the data
+ directory.
+
+ * You might want to add aliases to your shell's resource file to
+ make it easier to access commonly used programs such as mysql
+ and mysqladmin from the command line. The syntax for bash is:
alias mysql=/usr/local/mysql/bin/mysql
alias mysqladmin=/usr/local/mysql/bin/mysqladmin
-
- For tcsh, use:
+ For tcsh, use:
alias mysql /usr/local/mysql/bin/mysql
alias mysqladmin /usr/local/mysql/bin/mysqladmin
+ Even better, add /usr/local/mysql/bin to your PATH environment
+ variable. You can do this by modifying the appropriate startup
+ file for your shell. For more information, see Section 4.2.1,
+ "Invoking MySQL Programs."
- Even better, add /usr/local/mysql/bin to your PATH environment
- variable. You can do this by modifying the appropriate startup
- file for your shell. For more information, see Section 4.2.1,
- "Invoking MySQL Programs."
-
- If you are upgrading an existing installation, note that
- installing a new MySQL PKG does not remove the directory of an
- older installation. Unfortunately, the Mac OS X Installer does not
- yet offer the functionality required to properly upgrade
- previously installed packages.
-
- To use your existing databases with the new installation, you'll
- need to copy the contents of the old data directory to the new
- data directory. Make sure that neither the old server nor the new
- one is running when you do this. After you have copied over the
- MySQL database files from the previous installation and have
- successfully started the new server, you should consider removing
- the old installation files to save disk space. Additionally, you
- should also remove older versions of the Package Receipt
- directories located in /Library/Receipts/mysql-VERSION.pkg.
+ * After you have copied over the MySQL database files from the
+ previous installation and have successfully started the new
+ server, you should consider removing the old installation
+ files to save disk space. Additionally, you should also remove
+ older versions of the Package Receipt directories located in
+ /Library/Receipts/mysql-VERSION.pkg.
diff --git a/support-files/binary-configure.sh b/support-files/binary-configure.sh
index 884a8363e22..5e6d62f69a0 100644
--- a/support-files/binary-configure.sh
+++ b/support-files/binary-configure.sh
@@ -1,4 +1,28 @@
#!/bin/sh
+
+SCRIPT_NAME="`basename $0`"
+
+usage()
+{
+ echo "Usage: ${SCRIPT_NAME} [--help|-h]"
+ echo ""
+ echo "This script creates the MySQL system tables and starts the server."
+}
+
+for arg do
+ case "$arg" in
+ --help|-h)
+ usage
+ exit 0
+ ;;
+ *)
+ echo "${SCRIPT_NAME}: unknown option $arg"
+ usage
+ exit 2
+ ;;
+ esac
+done
+
if test ! -x ./scripts/mysql_install_db
then
echo "I didn't find the script './scripts/mysql_install_db'."
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index b126e12712f..0efe779c7bc 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -49,6 +49,9 @@ static char *opt_user= 0;
static char *opt_password= 0;
static char *opt_host= 0;
static char *opt_unix_socket= 0;
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name= 0;
+#endif
static unsigned int opt_port;
static my_bool tty_password= 0, opt_silent= 0;
@@ -233,6 +236,26 @@ static void print_st_error(MYSQL_STMT *stmt, const char *msg)
}
}
+/*
+ Enhanced version of mysql_client_init(), which may also set shared memory
+ base on Windows.
+*/
+static MYSQL *mysql_client_init(MYSQL* con)
+{
+ MYSQL* res = mysql_init(con);
+#ifdef HAVE_SMEM
+ if (res && shared_memory_base_name)
+ mysql_options(res, MYSQL_SHARED_MEMORY_BASE_NAME, shared_memory_base_name);
+#endif
+ return res;
+}
+
+/*
+ Disable direct calls of mysql_init, as it disregards shared memory base.
+*/
+#define mysql_init(A) Please use mysql_client_init instead of mysql_init
+
+
/* Check if the connection has InnoDB tables */
static my_bool check_have_innodb(MYSQL *conn)
@@ -296,10 +319,10 @@ static MYSQL* client_connect(ulong flag, uint protocol, my_bool auto_reconnect)
fprintf(stdout, "\n Establishing a connection to '%s' ...",
opt_host ? opt_host : "");
- if (!(mysql= mysql_init(NULL)))
+ if (!(mysql= mysql_client_init(NULL)))
{
opt_silent= 0;
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
/* enable local infile, in non-binary builds often disabled by default */
@@ -1165,9 +1188,9 @@ static my_bool thread_query(const char *query)
error= 0;
if (!opt_silent)
fprintf(stdout, "\n in thread_query(%s)", query);
- if (!(l_mysql= mysql_init(NULL)))
+ if (!(l_mysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
return 1;
}
if (!(mysql_real_connect(l_mysql, opt_host, opt_user,
@@ -2517,9 +2540,9 @@ static void test_ps_query_cache()
case TEST_QCACHE_ON_WITH_OTHER_CONN:
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- printf("mysql_init() failed");
+ printf("mysql_client_init() failed");
DIE_UNLESS(0);
}
if (!(mysql_real_connect(lmysql, opt_host, opt_user,
@@ -4965,9 +4988,9 @@ static void test_stmt_close()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
if (!(mysql_real_connect(lmysql, opt_host, opt_user,
@@ -5856,9 +5879,9 @@ DROP TABLE IF EXISTS test_multi_tab";
rc= mysql_more_results(mysql);
DIE_UNLESS(rc == 0);
- if (!(mysql_local= mysql_init(NULL)))
+ if (!(mysql_local= mysql_client_init(NULL)))
{
- fprintf(stdout, "\n mysql_init() failed");
+ fprintf(stdout, "\n mysql_client_init() failed");
exit(1);
}
@@ -5981,9 +6004,9 @@ static void test_prepare_multi_statements()
char query[MAX_TEST_QUERY_LENGTH];
myheader("test_prepare_multi_statements");
- if (!(mysql_local= mysql_init(NULL)))
+ if (!(mysql_local= mysql_client_init(NULL)))
{
- fprintf(stderr, "\n mysql_init() failed");
+ fprintf(stderr, "\n mysql_client_init() failed");
exit(1);
}
@@ -7464,9 +7487,9 @@ static void test_prepare_grant()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
if (!(mysql_real_connect(lmysql, opt_host, "test_grant",
@@ -7921,9 +7944,9 @@ static void test_drop_temp()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
@@ -13165,7 +13188,7 @@ static void test_bug15518()
int rc;
myheader("test_bug15518");
- mysql1= mysql_init(NULL);
+ mysql1= mysql_client_init(NULL);
if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
opt_db ? opt_db : "test", opt_port, opt_unix_socket,
@@ -13321,9 +13344,9 @@ static void test_bug8378()
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk"))
@@ -13862,7 +13885,7 @@ static void test_bug9992()
if (!opt_silent)
printf("Establishing a connection with option CLIENT_MULTI_STATEMENTS..\n");
- mysql1= mysql_init(NULL);
+ mysql1= mysql_client_init(NULL);
if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
opt_db ? opt_db : "test", opt_port, opt_unix_socket,
@@ -14451,9 +14474,9 @@ static void test_bug12001()
myheader("test_bug12001");
- if (!(mysql_local= mysql_init(NULL)))
+ if (!(mysql_local= mysql_client_init(NULL)))
{
- fprintf(stdout, "\n mysql_init() failed");
+ fprintf(stdout, "\n mysql_client_init() failed");
exit(1);
}
@@ -15178,9 +15201,9 @@ static void test_opt_reconnect()
myheader("test_opt_reconnect");
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
exit(1);
}
@@ -15215,9 +15238,9 @@ static void test_opt_reconnect()
mysql_close(lmysql);
- if (!(lmysql= mysql_init(NULL)))
+ if (!(lmysql= mysql_client_init(NULL)))
{
- myerror("mysql_init() failed");
+ myerror("mysql_client_init() failed");
DIE_UNLESS(0);
}
@@ -15252,7 +15275,7 @@ static void test_bug12744()
int rc;
myheader("test_bug12744");
- lmysql= mysql_init(NULL);
+ lmysql= mysql_client_init(NULL);
DIE_UNLESS(lmysql);
if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
@@ -15825,7 +15848,7 @@ static void test_bug15752()
rc= mysql_query(mysql, "create procedure p1() select 1");
myquery(rc);
- mysql_init(&mysql_local);
+ mysql_client_init(&mysql_local);
if (! mysql_real_connect(&mysql_local, opt_host, opt_user,
opt_password, current_db, opt_port,
opt_unix_socket,
@@ -16712,7 +16735,7 @@ static void test_bug29692()
{
MYSQL* conn;
- if (!(conn= mysql_init(NULL)))
+ if (!(conn= mysql_client_init(NULL)))
{
myerror("test_bug29692 init failed");
exit(1);
@@ -16847,7 +16870,7 @@ static void test_bug30472()
/* Create a new connection. */
- DIE_UNLESS(mysql_init(&con));
+ DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
@@ -17021,7 +17044,7 @@ static void test_bug20023()
/* Create a new connection. */
- DIE_UNLESS(mysql_init(&con));
+ DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
@@ -17158,7 +17181,7 @@ static void bug31418_impl()
/* Create a new connection. */
- DIE_UNLESS(mysql_init(&con));
+ DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con,
opt_host,
@@ -18008,7 +18031,7 @@ static void test_bug44495()
"END;");
myquery(rc);
- DIE_UNLESS(mysql_init(&con));
+ DIE_UNLESS(mysql_client_init(&con));
DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
current_db, opt_port, opt_unix_socket,
@@ -18071,6 +18094,11 @@ static struct my_option client_test_long_options[] =
0, 0, 0, 0, 0, 0},
{"silent", 's', "Be more silent", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0,
0},
+#ifdef HAVE_SMEM
+ {"shared-memory-base-name", 'm', "Base name of shared memory.",
+ (uchar**) &shared_memory_base_name, (uchar**)&shared_memory_base_name, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
{"socket", 'S', "Socket file to use for connection",
(uchar **) &opt_unix_socket, (uchar **) &opt_unix_socket, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
diff --git a/unittest/mysys/Makefile.am b/unittest/mysys/Makefile.am
index ab997c79b33..7fb487ffabf 100644
--- a/unittest/mysys/Makefile.am
+++ b/unittest/mysys/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (C) 2006 MySQL AB
+# Copyright (C) 2009 Sun Microsystems, Inc.
#
# 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
@@ -18,14 +18,20 @@ INCLUDES = @ZLIB_INCLUDES@ -I$(top_builddir)/include \
noinst_HEADERS = thr_template.c
-noinst_PROGRAMS = bitmap-t base64-t my_atomic-t lf-t waiting_threads-t
-
LDADD = $(top_builddir)/unittest/mytap/libmytap.a \
$(top_builddir)/mysys/libmysys.a \
$(top_builddir)/dbug/libdbug.a \
$(top_builddir)/strings/libmystrings.a
EXTRA_DIST = CMakeLists.txt
+noinst_PROGRAMS = bitmap-t base64-t lf-t waiting_threads-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/vio/vio.c b/vio/vio.c
index e088687098b..fd8e2e5a402 100644
--- a/vio/vio.c
+++ b/vio/vio.c
@@ -43,7 +43,7 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
if ((flags & VIO_BUFFERED_READ) &&
!(vio->read_buffer= (char*)my_malloc(VIO_READ_BUFFER_SIZE, MYF(MY_WME))))
flags&= ~VIO_BUFFERED_READ;
-#ifdef __WIN__
+#ifdef _WIN32
if (type == VIO_TYPE_NAMEDPIPE)
{
vio->viodelete =vio_delete;
@@ -59,9 +59,16 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
vio->in_addr =vio_in_addr;
vio->vioblocking =vio_blocking;
vio->is_blocking =vio_is_blocking;
- vio->timeout =vio_ignore_timeout;
+
+ vio->timeout=vio_win32_timeout;
+ /* Set default timeout */
+ vio->read_timeout_millis = INFINITE;
+ vio->write_timeout_millis = INFINITE;
+
+ memset(&(vio->pipe_overlapped), 0, sizeof(OVERLAPPED));
+ vio->pipe_overlapped.hEvent= CreateEvent(NULL, TRUE, FALSE, NULL);
+ DBUG_VOID_RETURN;
}
- else /* default is VIO_TYPE_TCPIP */
#endif
#ifdef HAVE_SMEM
if (type == VIO_TYPE_SHARED_MEMORY)
@@ -79,9 +86,14 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
vio->in_addr =vio_in_addr;
vio->vioblocking =vio_blocking;
vio->is_blocking =vio_is_blocking;
- vio->timeout =vio_ignore_timeout;
+
+ /* Currently, shared memory is on Windows only, hence the below is ok*/
+ vio->timeout= vio_win32_timeout;
+ /* Set default timeout */
+ vio->read_timeout_millis= INFINITE;
+ vio->write_timeout_millis= INFINITE;
+ DBUG_VOID_RETURN;
}
- else
#endif
#ifdef HAVE_OPENSSL
if (type == VIO_TYPE_SSL)
@@ -100,8 +112,8 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
vio->vioblocking =vio_ssl_blocking;
vio->is_blocking =vio_is_blocking;
vio->timeout =vio_timeout;
+ DBUG_VOID_RETURN;
}
- else /* default is VIO_TYPE_TCPIP */
#endif /* HAVE_OPENSSL */
{
vio->viodelete =vio_delete;
@@ -193,7 +205,7 @@ Vio *vio_new_win32pipe(HANDLE hPipe)
}
#ifdef HAVE_SMEM
-Vio *vio_new_win32shared_memory(NET *net,HANDLE handle_file_map, HANDLE handle_map,
+Vio *vio_new_win32shared_memory(HANDLE handle_file_map, HANDLE handle_map,
HANDLE event_server_wrote, HANDLE event_server_read,
HANDLE event_client_wrote, HANDLE event_client_read,
HANDLE event_conn_closed)
@@ -212,7 +224,6 @@ Vio *vio_new_win32shared_memory(NET *net,HANDLE handle_file_map, HANDLE handle_m
vio->event_conn_closed= event_conn_closed;
vio->shared_memory_remain= 0;
vio->shared_memory_pos= handle_map;
- vio->net= net;
strmov(vio->desc, "shared memory");
}
DBUG_RETURN(vio);
diff --git a/vio/vio_priv.h b/vio/vio_priv.h
index b9f5dd0c9c4..b662a616eef 100644
--- a/vio/vio_priv.h
+++ b/vio/vio_priv.h
@@ -22,7 +22,10 @@
#include <m_string.h>
#include <violite.h>
-void vio_ignore_timeout(Vio *vio, uint which, uint timeout);
+#ifdef _WIN32
+void vio_win32_timeout(Vio *vio, uint which, uint timeout);
+#endif
+
void vio_timeout(Vio *vio,uint which, uint timeout);
#ifdef HAVE_OPENSSL
diff --git a/vio/viosocket.c b/vio/viosocket.c
index fead2ca7c1c..a26d421bc3b 100644
--- a/vio/viosocket.c
+++ b/vio/viosocket.c
@@ -261,19 +261,13 @@ int vio_close(Vio * vio)
{
int r=0;
DBUG_ENTER("vio_close");
-#ifdef __WIN__
- if (vio->type == VIO_TYPE_NAMEDPIPE)
- {
-#if defined(__NT__) && defined(MYSQL_SERVER)
- CancelIo(vio->hPipe);
- DisconnectNamedPipe(vio->hPipe);
-#endif
- r=CloseHandle(vio->hPipe);
- }
- else
-#endif /* __WIN__ */
+
if (vio->type != VIO_CLOSED)
{
+ DBUG_ASSERT(vio->type == VIO_TYPE_TCPIP ||
+ vio->type == VIO_TYPE_SOCKET ||
+ vio->type == VIO_TYPE_SSL);
+
DBUG_ASSERT(vio->sd >= 0);
if (shutdown(vio->sd, SHUT_RDWR))
r= -1;
@@ -430,44 +424,97 @@ void vio_timeout(Vio *vio, uint which, uint timeout)
#ifdef __WIN__
-size_t vio_read_pipe(Vio * vio, uchar* buf, size_t size)
+
+/*
+ Finish pending IO on pipe. Honor wait timeout
+*/
+static int pipe_complete_io(Vio* vio, char* buf, size_t size, DWORD timeout_millis)
{
DWORD length;
+ DWORD ret;
+
+ DBUG_ENTER("pipe_complete_io");
+
+ ret= WaitForSingleObject(vio->pipe_overlapped.hEvent, timeout_millis);
+ /*
+ WaitForSingleObjects will normally return WAIT_OBJECT_O (success, IO completed)
+ or WAIT_TIMEOUT.
+ */
+ if(ret != WAIT_OBJECT_0)
+ {
+ CancelIo(vio->hPipe);
+ DBUG_PRINT("error",("WaitForSingleObject() returned %d", ret));
+ DBUG_RETURN(-1);
+ }
+
+ if (!GetOverlappedResult(vio->hPipe,&(vio->pipe_overlapped),&length, FALSE))
+ {
+ DBUG_PRINT("error",("GetOverlappedResult() returned last error %d",
+ GetLastError()));
+ DBUG_RETURN(-1);
+ }
+
+ DBUG_RETURN(length);
+}
+
+
+size_t vio_read_pipe(Vio * vio, uchar *buf, size_t size)
+{
+ DWORD bytes_read;
DBUG_ENTER("vio_read_pipe");
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %u", vio->sd, (long) buf,
(uint) size));
- if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
- DBUG_RETURN(-1);
+ if (!ReadFile(vio->hPipe, buf, (DWORD)size, &bytes_read,
+ &(vio->pipe_overlapped)))
+ {
+ if (GetLastError() != ERROR_IO_PENDING)
+ {
+ DBUG_PRINT("error",("ReadFile() returned last error %d",
+ GetLastError()));
+ DBUG_RETURN((size_t)-1);
+ }
+ bytes_read= pipe_complete_io(vio, buf, size,vio->read_timeout_millis);
+ }
- DBUG_PRINT("exit", ("%d", length));
- DBUG_RETURN((size_t) length);
+ DBUG_PRINT("exit", ("%d", bytes_read));
+ DBUG_RETURN(bytes_read);
}
size_t vio_write_pipe(Vio * vio, const uchar* buf, size_t size)
{
- DWORD length;
+ DWORD bytes_written;
DBUG_ENTER("vio_write_pipe");
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %u", vio->sd, (long) buf,
(uint) size));
- if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
- DBUG_RETURN(-1);
+ if (!WriteFile(vio->hPipe, buf, (DWORD)size, &bytes_written,
+ &(vio->pipe_overlapped)))
+ {
+ if (GetLastError() != ERROR_IO_PENDING)
+ {
+ DBUG_PRINT("vio_error",("WriteFile() returned last error %d",
+ GetLastError()));
+ DBUG_RETURN((size_t)-1);
+ }
+ bytes_written = pipe_complete_io(vio, (char *)buf, size,
+ vio->write_timeout_millis);
+ }
- DBUG_PRINT("exit", ("%d", length));
- DBUG_RETURN((size_t) length);
+ DBUG_PRINT("exit", ("%d", bytes_written));
+ DBUG_RETURN(bytes_written);
}
+
int vio_close_pipe(Vio * vio)
{
int r;
DBUG_ENTER("vio_close_pipe");
-#if defined(__NT__) && defined(MYSQL_SERVER)
- CancelIo(vio->hPipe);
+
+ CloseHandle(vio->pipe_overlapped.hEvent);
DisconnectNamedPipe(vio->hPipe);
-#endif
- r=CloseHandle(vio->hPipe);
+ r= CloseHandle(vio->hPipe);
if (r)
{
DBUG_PRINT("vio_error", ("close() failed, error: %d",GetLastError()));
@@ -479,10 +526,23 @@ int vio_close_pipe(Vio * vio)
}
-void vio_ignore_timeout(Vio *vio __attribute__((unused)),
- uint which __attribute__((unused)),
- uint timeout __attribute__((unused)))
+void vio_win32_timeout(Vio *vio, uint which , uint timeout_sec)
{
+ DWORD timeout_millis;
+ /*
+ Windows is measuring timeouts in milliseconds. Check for possible int
+ overflow.
+ */
+ if (timeout_sec > UINT_MAX/1000)
+ timeout_millis= INFINITE;
+ else
+ timeout_millis= timeout_sec * 1000;
+
+ /* which == 1 means "write", which == 0 means "read".*/
+ if(which)
+ vio->write_timeout_millis= timeout_millis;
+ else
+ vio->read_timeout_millis= timeout_millis;
}
@@ -517,7 +577,7 @@ size_t vio_read_shared_memory(Vio * vio, uchar* buf, size_t size)
WAIT_ABANDONED_0 and WAIT_TIMEOUT - fail. We can't read anything
*/
if (WaitForMultipleObjects(array_elements(events), events, FALSE,
- vio->net->read_timeout*1000) != WAIT_OBJECT_0)
+ vio->read_timeout_millis) != WAIT_OBJECT_0)
{
DBUG_RETURN(-1);
};
@@ -574,7 +634,7 @@ size_t vio_write_shared_memory(Vio * vio, const uchar* buf, size_t size)
while (remain != 0)
{
if (WaitForMultipleObjects(array_elements(events), events, FALSE,
- vio->net->write_timeout*1000) != WAIT_OBJECT_0)
+ vio->write_timeout_millis) != WAIT_OBJECT_0)
{
DBUG_RETURN((size_t) -1);
}
diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c
index 6a6e08818c6..d0a0a69f70b 100644
--- a/vio/viosslfactories.c
+++ b/vio/viosslfactories.c
@@ -19,7 +19,6 @@
static my_bool ssl_algorithms_added = FALSE;
static my_bool ssl_error_strings_loaded= FALSE;
-static int verify_depth = 0;
static unsigned char dh512_p[]=
{
@@ -144,55 +143,6 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file,
}
-static int
-vio_verify_callback(int ok, X509_STORE_CTX *ctx)
-{
- char buf[256];
- X509 *err_cert;
-
- DBUG_ENTER("vio_verify_callback");
- DBUG_PRINT("enter", ("ok: %d ctx: 0x%lx", ok, (long) ctx));
-
- err_cert= X509_STORE_CTX_get_current_cert(ctx);
- X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
- DBUG_PRINT("info", ("cert: %s", buf));
- if (!ok)
- {
- int err, depth;
- err= X509_STORE_CTX_get_error(ctx);
- depth= X509_STORE_CTX_get_error_depth(ctx);
-
- DBUG_PRINT("error",("verify error: %d '%s'",err,
- X509_verify_cert_error_string(err)));
- /*
- Approve cert if depth is greater then "verify_depth", currently
- verify_depth is always 0 and there is no way to increase it.
- */
- if (verify_depth >= depth)
- ok= 1;
- }
- switch (ctx->error)
- {
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
- DBUG_PRINT("info",("issuer= %s\n", buf));
- break;
- case X509_V_ERR_CERT_NOT_YET_VALID:
- case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
- DBUG_PRINT("error", ("notBefore"));
- /*ASN1_TIME_print_fp(stderr,X509_get_notBefore(ctx->current_cert));*/
- break;
- case X509_V_ERR_CERT_HAS_EXPIRED:
- case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
- DBUG_PRINT("error", ("notAfter error"));
- /*ASN1_TIME_print_fp(stderr,X509_get_notAfter(ctx->current_cert));*/
- break;
- }
- DBUG_PRINT("exit", ("%d", ok));
- DBUG_RETURN(ok);
-}
-
-
#ifdef __NETWARE__
/* NetWare SSL cleanup */
@@ -354,11 +304,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
/* Init the VioSSLFd as a "connector" ie. the client side */
- /*
- The verify_callback function is used to control the behaviour
- when the SSL_VERIFY_PEER flag is set.
- */
- SSL_CTX_set_verify(ssl_fd->ssl_context, verify, vio_verify_callback);
+ SSL_CTX_set_verify(ssl_fd->ssl_context, verify, NULL);
return ssl_fd;
}
@@ -382,11 +328,7 @@ new_VioSSLAcceptorFd(const char *key_file, const char *cert_file,
/* Set max number of cached sessions, returns the previous size */
SSL_CTX_sess_set_cache_size(ssl_fd->ssl_context, 128);
- /*
- The verify_callback function is used to control the behaviour
- when the SSL_VERIFY_PEER flag is set.
- */
- SSL_CTX_set_verify(ssl_fd->ssl_context, verify, vio_verify_callback);
+ SSL_CTX_set_verify(ssl_fd->ssl_context, verify, NULL);
/*
Set session_id - an identifier for this server session