You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3037 lines
83 KiB

branches/innodb+: Merge revisions 4150:4528 from branches/zip: ------------------------------------------------------------------------ r4152 | marko | 2009-02-10 12:52:27 +0200 (Tue, 10 Feb 2009) | 12 lines branches/zip: When innodb_use_sys_malloc is set, ignore innodb_additional_mem_pool_size, because nothing will be allocated from mem_comm_pool. mem_pool_create(): Remove the assertion about size. The function will work with any size. However, an assertion would fail in ut_malloc_low() when size==0. mem_init(): When srv_use_sys_malloc is set, pass size=1 to mem_pool_create(). mem0mem.c: Add #include "srv0srv.h" that is needed by mem0dbg.c. ------------------------------------------------------------------------ r4153 | vasil | 2009-02-10 22:58:17 +0200 (Tue, 10 Feb 2009) | 14 lines branches/zip: (followup to r4145) Non-functional change: Change the os_atomic_increment() and os_compare_and_swap() functions to macros to avoid artificial limitations on the types of those functions' arguments. As a consequence typecasts from the source code can be removed. Also remove Google's copyright from os0sync.ic because that file no longer contains code from Google. Approved by: Marko (rb://88), also ok from Inaam via IM ------------------------------------------------------------------------ r4163 | marko | 2009-02-12 00:14:19 +0200 (Thu, 12 Feb 2009) | 4 lines branches/zip: Make innodb_thread_concurrency=0 the default. The old default was 8. ------------------------------------------------------------------------ r4169 | calvin | 2009-02-12 10:37:10 +0200 (Thu, 12 Feb 2009) | 3 lines branches/zip: Adjust the result file of innodb_thread_concurrency_basic test. The default value of innodb_thread_concurrency is changed to 0 (from 8) via r4163. ------------------------------------------------------------------------ r4174 | vasil | 2009-02-12 17:38:27 +0200 (Thu, 12 Feb 2009) | 4 lines branches/zip: Fix pathname of the file to patch. ------------------------------------------------------------------------ r4176 | vasil | 2009-02-13 10:06:31 +0200 (Fri, 13 Feb 2009) | 7 lines branches/zip: Fix the failing mysql-test partition_innodb, which failed only if run after innodb_trx_weight (or other test that would leave LATEST DEADLOCK ERROR into the output of SHOW ENGINE INNODB STATUS). Find further explanation for the failure at the top of the added patch partition_innodb.diff. ------------------------------------------------------------------------ r4198 | vasil | 2009-02-17 09:06:07 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: Add the full text of the GPLv2 license into the root directory of the plugin. In previous releases this file was copied from an external source (https://svn.innodb.com/svn/plugin/trunk/support/COPYING) "manually" when creating the source and binary archives. It is less confusing to have this present in the root directory of the SVN branch. ------------------------------------------------------------------------ r4199 | vasil | 2009-02-17 09:11:58 +0200 (Tue, 17 Feb 2009) | 4 lines branches/zip: Add Google's license into COPYING.Google. ------------------------------------------------------------------------ r4200 | vasil | 2009-02-17 09:56:33 +0200 (Tue, 17 Feb 2009) | 11 lines branches/zip: To the files touched by the Google patch from c4144 (excluding include/os0sync.ic because later we removed Google code from that file): * Remove the Google license * Remove old Innobase copyright lines * Add a reference to the Google license and to the GPLv2 license at the top, as recommended by the lawyers at Oracle Legal. ------------------------------------------------------------------------ r4201 | vasil | 2009-02-17 10:12:02 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 1/28] ------------------------------------------------------------------------ r4202 | vasil | 2009-02-17 10:15:06 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 2/28] ------------------------------------------------------------------------ r4203 | vasil | 2009-02-17 10:25:45 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 3/28] ------------------------------------------------------------------------ r4204 | vasil | 2009-02-17 10:55:41 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 4/28] ------------------------------------------------------------------------ r4205 | vasil | 2009-02-17 10:59:22 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 5/28] ------------------------------------------------------------------------ r4206 | vasil | 2009-02-17 11:02:27 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 6/28] ------------------------------------------------------------------------ r4207 | vasil | 2009-02-17 11:04:28 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 7/28] ------------------------------------------------------------------------ r4208 | vasil | 2009-02-17 11:06:49 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 8/28] ------------------------------------------------------------------------ r4209 | vasil | 2009-02-17 11:10:18 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 9/28] ------------------------------------------------------------------------ r4210 | vasil | 2009-02-17 11:12:41 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 10/28] ------------------------------------------------------------------------ r4211 | vasil | 2009-02-17 11:14:40 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 11/28] ------------------------------------------------------------------------ r4212 | vasil | 2009-02-17 11:18:35 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 12/28] ------------------------------------------------------------------------ r4213 | vasil | 2009-02-17 11:24:40 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 13/28] ------------------------------------------------------------------------ r4214 | vasil | 2009-02-17 11:27:31 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 13/28] ------------------------------------------------------------------------ r4215 | vasil | 2009-02-17 11:29:55 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 15/28] ------------------------------------------------------------------------ r4216 | vasil | 2009-02-17 11:33:38 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 16/28] ------------------------------------------------------------------------ r4217 | vasil | 2009-02-17 11:36:44 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 17/28] ------------------------------------------------------------------------ r4218 | vasil | 2009-02-17 11:39:11 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 18/28] ------------------------------------------------------------------------ r4219 | vasil | 2009-02-17 11:41:24 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 19/28] ------------------------------------------------------------------------ r4220 | vasil | 2009-02-17 11:43:50 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 20/28] ------------------------------------------------------------------------ r4221 | vasil | 2009-02-17 11:46:52 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 21/28] ------------------------------------------------------------------------ r4222 | vasil | 2009-02-17 11:50:12 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 22/28] ------------------------------------------------------------------------ r4223 | vasil | 2009-02-17 11:53:58 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 23/28] ------------------------------------------------------------------------ r4224 | vasil | 2009-02-17 12:01:41 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 24/28] ------------------------------------------------------------------------ r4225 | vasil | 2009-02-17 12:05:45 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 25/28] ------------------------------------------------------------------------ r4226 | vasil | 2009-02-17 12:09:16 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 26/28] ------------------------------------------------------------------------ r4227 | vasil | 2009-02-17 12:12:56 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 27/28] ------------------------------------------------------------------------ r4228 | vasil | 2009-02-17 12:14:04 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 28/28] ------------------------------------------------------------------------ r4229 | vasil | 2009-02-17 12:30:55 +0200 (Tue, 17 Feb 2009) | 4 lines branches/zip: Add the copyright notice to the non C files. ------------------------------------------------------------------------ r4231 | marko | 2009-02-17 14:26:53 +0200 (Tue, 17 Feb 2009) | 12 lines Minor cleanup of the Google SMP patch. sync_array_object_signalled(): Add a (void) cast to eliminate a gcc warning about the return value of os_atomic_increment() being ignored. rw_lock_create_func(): Properly indent the preprocessor directives. rw_lock_x_lock_low(), rw_lock_x_lock_func_nowait(): Split lines correctly. rw_lock_set_writer_id_and_recursion_flag(): Silence a Valgrind warning. Do not mix statements and variable declarations. ------------------------------------------------------------------------ r4232 | marko | 2009-02-17 14:59:54 +0200 (Tue, 17 Feb 2009) | 3 lines branches/zip: When assigning lock->recursive = FALSE, also flag lock->writer_thread invalid, so that Valgrind will catch more errors. This is related to Issue #175. ------------------------------------------------------------------------ r4242 | marko | 2009-02-18 17:01:09 +0200 (Wed, 18 Feb 2009) | 2 lines branches/zip: UT_DBG_STOP: Use do{} while(0) to silence a g++-4.3.2 warning about a while(0); statement. This should fix (part of) Issue #176. ------------------------------------------------------------------------ r4243 | marko | 2009-02-18 17:04:03 +0200 (Wed, 18 Feb 2009) | 3 lines branches/zip: buf_buddy_get_slot(): Fix a gcc 4.3.2 warning about an empty body of a "for" statement. This fixes part of Issue #176. ------------------------------------------------------------------------ r4244 | marko | 2009-02-18 17:25:45 +0200 (Wed, 18 Feb 2009) | 11 lines branches/zip: Protect ut_total_allocated_memory with ut_list_mutex. Unprotected updates to ut_total_allocated_memory in os_mem_alloc_large() and os_mem_free_large(), called during fast index creation, may corrupt the variable and cause assertion failures. Also, add UNIV_MEM_ALLOC() and UNIV_MEM_FREE() instrumentation around os_mem_alloc_large() and os_mem_free_large(), so that Valgrind can detect more errors. rb://90 approved by Heikki Tuuri. This addresses Issue #177. ------------------------------------------------------------------------ r4248 | marko | 2009-02-19 11:52:39 +0200 (Thu, 19 Feb 2009) | 2 lines branches/zip: page_zip_set_size(): Fix a g++ 4.3.2 warning about an empty body in a "for" statement. This closes Issue #176. ------------------------------------------------------------------------ r4251 | inaam | 2009-02-19 15:46:27 +0200 (Thu, 19 Feb 2009) | 8 lines branches/zip: Issue #178 rb://91 Change plug.in to have same CXXFLAGS as CFLAGS. This is to ensure that both .c and .cc files get compiled with same flags. To fix the issue where UNIV_LINUX was defined only in .c files. Approved by: Marko ------------------------------------------------------------------------ r4258 | vasil | 2009-02-20 11:52:19 +0200 (Fri, 20 Feb 2009) | 7 lines branches/zip: Cleanup in ChangeLog: * Wrap lines at 78 characters * Changed files are listed alphabetically * White-space cleanup ------------------------------------------------------------------------ r4259 | vasil | 2009-02-20 11:59:42 +0200 (Fri, 20 Feb 2009) | 6 lines branches/zip: ChangeLog: Remove include/os0sync.ic from the entry about the google patch, this file was modified later to not include Google's code. ------------------------------------------------------------------------ r4262 | vasil | 2009-02-20 14:56:59 +0200 (Fri, 20 Feb 2009) | 373 lines branches/zip: Merge revisions 4035:4261 from branches/5.1: ------------------------------------------------------------------------ r4065 | sunny | 2009-01-29 16:01:36 +0200 (Thu, 29 Jan 2009) | 8 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: In the last round of AUTOINC cleanup we assumed that AUTOINC is only defined for integer columns. This caused an assertion failure when we checked for the maximum value of a column type. We now calculate the max value for floating-point autoinc columns too. Fix Bug#42400 - InnoDB autoinc code can't handle floating-point columns rb://84 and Mantis issue://162 ------------------------------------------------------------------------ r4111 | sunny | 2009-02-03 22:06:52 +0200 (Tue, 03 Feb 2009) | 2 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: Add the ULL suffix otherwise there is an overflow. ------------------------------------------------------------------------ r4128 | vasil | 2009-02-08 21:36:45 +0200 (Sun, 08 Feb 2009) | 18 lines Changed paths: M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Merge a change from MySQL: ------------------------------------------------------------ revno: 2709.20.31 committer: Timothy Smith <timothy.smith@sun.com> branch nick: 51 timestamp: Fri 2008-12-19 01:28:51 +0100 message: Disable part of innodb-autoinc.test, because the MySQL server asserts when compiled --with-debug, due to bug 39828, "autoinc wraps around when offset and increment > 1". This change should be reverted when that bug is fixed (and a a few other minor changes to the test as described in comments). modified: mysql-test/r/innodb-autoinc.result mysql-test/t/innodb-autoinc.test ------------------------------------------------------------------------ r4129 | vasil | 2009-02-08 21:54:25 +0200 (Sun, 08 Feb 2009) | 310 lines Changed paths: M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Merge a change from MySQL: [looks like the changes to innodb-autoinc.test were made as part of the following huge merge, but we are merging only changes to that file] ------------------------------------------------------------ revno: 2546.47.1 committer: Luis Soares <luis.soares@sun.com> branch nick: 5.1-rpl timestamp: Fri 2009-01-23 13:22:05 +0100 message: merge: 5.1 -> 5.1-rpl conflicts: Text conflict in client/mysqltest.cc Text conflict in mysql-test/include/wait_until_connected_again.inc Text conflict in mysql-test/lib/mtr_report.pm Text conflict in mysql-test/mysql-test-run.pl Text conflict in mysql-test/r/events_bugs.result Text conflict in mysql-test/r/log_state.result Text conflict in mysql-test/r/myisam_data_pointer_size_func.result Text conflict in mysql-test/r/mysqlcheck.result Text conflict in mysql-test/r/query_cache.result Text conflict in mysql-test/r/status.result Text conflict in mysql-test/suite/binlog/r/binlog_index.result Text conflict in mysql-test/suite/binlog/r/binlog_innodb.result Text conflict in mysql-test/suite/rpl/r/rpl_packet.result Text conflict in mysql-test/suite/rpl/t/rpl_packet.test Text conflict in mysql-test/t/disabled.def Text conflict in mysql-test/t/events_bugs.test Text conflict in mysql-test/t/log_state.test Text conflict in mysql-test/t/myisam_data_pointer_size_func.test Text conflict in mysql-test/t/mysqlcheck.test Text conflict in mysql-test/t/query_cache.test Text conflict in mysql-test/t/rpl_init_slave_func.test Text conflict in mysql-test/t/status.test removed: mysql-test/suite/parts/r/partition_bit_ndb.result mysql-test/suite/parts/t/partition_bit_ndb.test mysql-test/suite/parts/t/partition_sessions.test mysql-test/suite/sys_vars/inc/tmp_table_size_basic.inc mysql-test/suite/sys_vars/r/tmp_table_size_basic_32.result mysql-test/suite/sys_vars/r/tmp_table_size_basic_64.result mysql-test/suite/sys_vars/t/tmp_table_size_basic_32.test mysql-test/suite/sys_vars/t/tmp_table_size_basic_64.test mysql-test/t/log_bin_trust_function_creators_func-master.opt mysql-test/t/rpl_init_slave_func-slave.opt added: mysql-test/include/check_events_off.inc mysql-test/include/cleanup_fake_relay_log.inc mysql-test/include/have_simple_parser.inc mysql-test/include/no_running_event_scheduler.inc mysql-test/include/no_running_events.inc mysql-test/include/running_event_scheduler.inc mysql-test/include/setup_fake_relay_log.inc mysql-test/include/wait_condition_sp.inc mysql-test/r/fulltext_plugin.result mysql-test/r/have_simple_parser.require mysql-test/r/innodb_bug38231.result mysql-test/r/innodb_bug39438.result mysql-test/r/innodb_mysql_rbk.result mysql-test/r/partition_innodb_semi_consistent.result mysql-test/r/query_cache_28249.result mysql-test/r/status2.result mysql-test/std_data/bug40482-bin.000001 mysql-test/suite/binlog/r/binlog_innodb_row.result mysql-test/suite/binlog/t/binlog_innodb_row.test mysql-test/suite/rpl/r/rpl_binlog_corruption.result mysql-test/suite/rpl/t/rpl_binlog_corruption-master.opt mysql-test/suite/rpl/t/rpl_binlog_corruption.test mysql-test/suite/sys_vars/r/tmp_table_size_basic.result mysql-test/suite/sys_vars/t/tmp_table_size_basic.test mysql-test/t/fulltext_plugin-master.opt mysql-test/t/fulltext_plugin.test mysql-test/t/innodb_bug38231.test mysql-test/t/innodb_bug39438-master.opt mysql-test/t/innodb_bug39438.test mysql-test/t/innodb_mysql_rbk-master.opt mysql-test/t/innodb_mysql_rbk.test mysql-test/t/partition_innodb_semi_consistent-master.opt mysql-test/t/partition_innodb_semi_consistent.test mysql-test/t/query_cache_28249.test mysql-test/t/status2.test renamed: mysql-test/suite/funcs_1/r/is_collation_character_set_applicability.result => mysql-test/suite/funcs_1/r/is_coll_char_set_appl.result mysql-test/suite/funcs_1/t/is_collation_character_set_applicability.test => mysql-test/suite/funcs_1/t/is_coll_char_set_appl.test modified: .bzr-mysql/default.conf CMakeLists.txt client/mysql.cc client/mysql_upgrade.c client/mysqlcheck.c client/mysqltest.cc configure.in extra/resolve_stack_dump.c extra/yassl/include/openssl/ssl.h include/config-win.h include/m_ctype.h include/my_global.h mysql-test/extra/binlog_tests/database.test mysql-test/extra/rpl_tests/rpl_auto_increment.test mysql-test/include/commit.inc mysql-test/include/have_32bit.inc mysql-test/include/have_64bit.inc mysql-test/include/index_merge1.inc mysql-test/include/linux_sys_vars.inc mysql-test/include/windows_sys_vars.inc mysql-test/lib/mtr_report.pm mysql-test/mysql-test-run.pl mysql-test/r/alter_table.result mysql-test/r/commit_1innodb.result mysql-test/r/create.result mysql-test/r/csv.result mysql-test/r/ctype_ucs.result mysql-test/r/date_formats.result mysql-test/r/events_bugs.result mysql-test/r/events_scheduling.result mysql-test/r/fulltext.result mysql-test/r/func_if.result mysql-test/r/func_in.result mysql-test/r/func_str.result mysql-test/r/func_time.result mysql-test/r/grant.result mysql-test/r/index_merge_myisam.result mysql-test/r/information_schema.result mysql-test/r/innodb-autoinc.result mysql-test/r/innodb.result mysql-test/r/innodb_mysql.result mysql-test/r/log_bin_trust_function_creators_func.result mysql-test/r/log_state.result mysql-test/r/myisampack.result mysql-test/r/mysql.result mysql-test/r/mysqlcheck.result mysql-test/r/partition_datatype.result mysql-test/r/partition_mgm.result mysql-test/r/partition_pruning.result mysql-test/r/query_cache.result mysql-test/r/read_buffer_size_basic.result mysql-test/r/read_rnd_buffer_size_basic.result mysql-test/r/rpl_init_slave_func.result mysql-test/r/select.result mysql-test/r/status.result mysql-test/r/strict.result mysql-test/r/temp_table.result mysql-test/r/type_bit.result mysql-test/r/type_date.result mysql-test/r/type_float.result mysql-test/r/warnings_engine_disabled.result mysql-test/r/xml.result mysql-test/suite/binlog/r/binlog_database.result mysql-test/suite/binlog/r/binlog_index.result mysql-test/suite/binlog/r/binlog_innodb.result mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result mysql-test/suite/binlog/t/binlog_innodb.test mysql-test/suite/funcs_1/r/is_columns_is.result mysql-test/suite/funcs_1/r/is_engines.result mysql-test/suite/funcs_1/r/storedproc.result mysql-test/suite/funcs_1/storedproc/param_check.inc mysql-test/suite/funcs_2/t/disabled.def mysql-test/suite/ndb/t/disabled.def mysql-test/suite/parts/r/partition_bit_innodb.result mysql-test/suite/parts/r/partition_bit_myisam.result mysql-test/suite/parts/r/partition_special_innodb.result mysql-test/suite/parts/t/disabled.def mysql-test/suite/parts/t/partition_special_innodb.test mysql-test/suite/parts/t/partition_value_innodb.test mysql-test/suite/parts/t/partition_value_myisam.test mysql-test/suite/parts/t/partition_value_ndb.test mysql-test/suite/rpl/r/rpl_auto_increment.result mysql-test/suite/rpl/r/rpl_packet.result mysql-test/suite/rpl/r/rpl_row_create_table.result mysql-test/suite/rpl/r/rpl_slave_skip.result mysql-test/suite/rpl/r/rpl_trigger.result mysql-test/suite/rpl/t/disabled.def mysql-test/suite/rpl/t/rpl_packet.test mysql-test/suite/rpl/t/rpl_row_create_table.test mysql-test/suite/rpl/t/rpl_slave_skip.test mysql-test/suite/rpl/t/rpl_trigger.test mysql-test/suite/rpl_ndb/t/disabled.def mysql-test/suite/sys_vars/inc/key_buffer_size_basic.inc mysql-test/suite/sys_vars/inc/sort_buffer_size_basic.inc mysql-test/suite/sys_vars/r/key_buffer_size_basic_32.result mysql-test/suite/sys_vars/r/key_buffer_size_basic_64.result mysql-test/suite/sys_vars/r/sort_buffer_size_basic_32.result mysql-test/suite/sys_vars/r/sort_buffer_size_basic_64.result mysql-test/t/alter_table.test mysql-test/t/create.test mysql-test/t/csv.test mysql-test/t/ctype_ucs.test mysql-test/t/date_formats.test mysql-test/t/disabled.def mysql-test/t/events_bugs.test mysql-test/t/events_scheduling.test mysql-test/t/fulltext.test mysql-test/t/func_if.test mysql-test/t/func_in.test mysql-test/t/func_str.test mysql-test/t/func_time.test mysql-test/t/grant.test mysql-test/t/information_schema.test mysql-test/t/innodb-autoinc.test mysql-test/t/innodb.test mysql-test/t/innodb_mysql.test mysql-test/t/log_bin_trust_function_creators_func.test mysql-test/t/log_state.test mysql-test/t/myisam_data_pointer_size_func.test mysql-test/t/myisampack.test mysql-test/t/mysql.test mysql-test/t/mysqlcheck.test mysql-test/t/partition_innodb_stmt.test mysql-test/t/partition_mgm.test mysql-test/t/partition_pruning.test mysql-test/t/query_cache.test mysql-test/t/rpl_init_slave_func.test mysql-test/t/select.test mysql-test/t/status.test mysql-test/t/strict.test mysql-test/t/temp_table.test mysql-test/t/type_bit.test mysql-test/t/type_date.test mysql-test/t/type_float.test mysql-test/t/warnings_engine_disabled.test mysql-test/t/xml.test mysys/my_getopt.c mysys/my_init.c scripts/mysql_install_db.sh sql-common/my_time.c sql/field.cc sql/field.h sql/filesort.cc sql/ha_partition.cc sql/ha_partition.h sql/item.cc sql/item_cmpfunc.cc sql/item_func.h sql/item_strfunc.cc sql/item_sum.cc sql/item_timefunc.cc sql/item_timefunc.h sql/log.cc sql/log.h sql/log_event.cc sql/log_event.h sql/mysql_priv.h sql/mysqld.cc sql/opt_range.cc sql/partition_info.cc sql/repl_failsafe.cc sql/rpl_constants.h sql/set_var.cc sql/slave.cc sql/spatial.h sql/sql_acl.cc sql/sql_base.cc sql/sql_binlog.cc sql/sql_class.h sql/sql_cursor.cc sql/sql_delete.cc sql/sql_lex.cc sql/sql_lex.h sql/sql_locale.cc sql/sql_parse.cc sql/sql_partition.cc sql/sql_plugin.cc sql/sql_plugin.h sql/sql_profile.cc sql/sql_repl.cc sql/sql_select.cc sql/sql_select.h sql/sql_show.cc sql/sql_table.cc sql/sql_trigger.cc sql/sql_trigger.h sql/table.cc sql/table.h sql/unireg.cc storage/csv/ha_tina.cc storage/federated/ha_federated.cc storage/heap/ha_heap.cc storage/innobase/Makefile.am storage/innobase/btr/btr0sea.c storage/innobase/buf/buf0lru.c storage/innobase/dict/dict0dict.c storage/innobase/dict/dict0mem.c storage/innobase/handler/ha_innodb.cc storage/innobase/handler/ha_innodb.h storage/innobase/include/btr0sea.h storage/innobase/include/dict0dict.h storage/innobase/include/dict0mem.h storage/innobase/include/ha_prototypes.h storage/innobase/include/lock0lock.h storage/innobase/include/row0mysql.h storage/innobase/include/sync0sync.ic storage/innobase/include/ut0ut.h storage/innobase/lock/lock0lock.c storage/innobase/os/os0file.c storage/innobase/plug.in storage/innobase/row/row0mysql.c storage/innobase/row/row0sel.c storage/innobase/srv/srv0srv.c storage/innobase/srv/srv0start.c storage/innobase/ut/ut0ut.c storage/myisam/ft_boolean_search.c strings/ctype.c strings/xml.c tests/mysql_client_test.c win/configure.js mysql-test/suite/funcs_1/t/is_coll_char_set_appl.test ------------------------------------------------------------------------ r4165 | calvin | 2009-02-12 01:34:27 +0200 (Thu, 12 Feb 2009) | 1 line Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: minor non-functional changes. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4263 | vasil | 2009-02-20 15:00:46 +0200 (Fri, 20 Feb 2009) | 4 lines branches/zip: Add a ChangeLog entry for a change in r4262. ------------------------------------------------------------------------ r4265 | marko | 2009-02-20 22:31:03 +0200 (Fri, 20 Feb 2009) | 5 lines branches/zip: Make innodb_use_sys_malloc=ON the default. Replace srv_use_sys_malloc with UNIV_LIKELY(srv_use_sys_malloc) to improve branch prediction in the default case. Approved by Ken over the IM. ------------------------------------------------------------------------ r4266 | vasil | 2009-02-20 23:29:32 +0200 (Fri, 20 Feb 2009) | 7 lines branches/zip: Add a sentence at the top of COPYING.Google to clarify that this license does not apply to the whole InnoDB. Suggested by: Ken ------------------------------------------------------------------------ r4268 | marko | 2009-02-23 12:43:51 +0200 (Mon, 23 Feb 2009) | 9 lines branches/zip: Initialize ut_list_mutex at startup. Without this fix, ut_list_mutex would be used uninitialized when innodb_use_sys_malloc=1. This fix addresses Issue #181. ut_mem_block_list_init(): Rename to ut_mem_init() and make public. ut_malloc_low(), ut_free_all_mem(): Add ut_a(ut_mem_block_list_inited). mem_init(): Call ut_mem_init(). ------------------------------------------------------------------------ r4269 | marko | 2009-02-23 15:09:49 +0200 (Mon, 23 Feb 2009) | 7 lines branches/zip: When freeing an uncompressed BLOB page, tolerate garbage in FIL_PAGE_TYPE. (Bug #43043, Issue #182) btr_check_blob_fil_page_type(): New function. btr_free_externally_stored_field(), btr_copy_blob_prefix(): Call btr_check_blob_fil_page_type() to check FIL_PAGE_TYPE. ------------------------------------------------------------------------ r4272 | marko | 2009-02-23 23:10:18 +0200 (Mon, 23 Feb 2009) | 8 lines branches/zip: Adjust the fix of Issue #182 in r4269 per Inaam's suggestion. btr_check_blob_fil_page_type(): Replace the parameter const char* op with ibool read. Do not print anything about page type mismatch when reading a BLOB page in Antelope format. Print space id before page number. ------------------------------------------------------------------------ r4273 | marko | 2009-02-24 00:11:11 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: ut_mem_init(): Add the assertion !ut_mem_block_list_inited. ------------------------------------------------------------------------ r4274 | marko | 2009-02-24 00:14:38 +0200 (Tue, 24 Feb 2009) | 12 lines branches/zip: Fix bugs in the fix of Issue #181. Tested inside and outside Valgrind, with innodb_use_sys_malloc set to 0 and 1. mem_init(): Invoke ut_mem_init() before mem_pool_create(), because the latter one will invoke ut_malloc(). srv_general_init(): Do not initialize the memory subsystem (mem_init()). innobase_init(): Initialize the memory subsystem (mem_init()) before calling srv_parse_data_file_paths_and_sizes(), which needs ut_malloc(). Call ut_free_all_mem() in error handling to clean up after the mem_init(). ------------------------------------------------------------------------ r4280 | marko | 2009-02-24 15:14:59 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: Remove unused function os_mem_alloc_nocache(). ------------------------------------------------------------------------ r4281 | marko | 2009-02-24 16:02:48 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: Remove the unused function dict_index_get_type(). ------------------------------------------------------------------------ r4283 | marko | 2009-02-24 23:06:56 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: srv0start.c: Remove unnecessary #include "mem0pool.h". ------------------------------------------------------------------------ r4284 | marko | 2009-02-24 23:26:38 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: mem0mem.c: Remove unnecessary #include "mach0data.h". ------------------------------------------------------------------------ r4288 | vasil | 2009-02-25 10:48:07 +0200 (Wed, 25 Feb 2009) | 21 lines branches/zip: Merge revisions 4261:4287 from branches/5.1: ------------------------------------------------------------------------ r4287 | sunny | 2009-02-25 05:32:01 +0200 (Wed, 25 Feb 2009) | 10 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Fix Bug#42714 AUTO_INCREMENT errors in 5.1.31. There are two changes to the autoinc handling. 1. To fix the immediate problem from the bug report, we must ensure that the value written to the table is always less than the max value stored in dict_table_t. 2. The second related change is that according to MySQL documentation when the offset is greater than the increment, we should ignore the offset. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4289 | vasil | 2009-02-25 10:53:51 +0200 (Wed, 25 Feb 2009) | 4 lines branches/zip: Add ChangeLog entry for the fix in r4288. ------------------------------------------------------------------------ r4290 | vasil | 2009-02-25 11:05:44 +0200 (Wed, 25 Feb 2009) | 11 lines branches/zip: Make ChangeLog entries for bugs in bugs.mysql.com in the form: Fix Bug#12345 bug title (for bugs after 1.0.2 was released and the ChangeLog published) There is no need to bloat the ChangeLog with information that is available via bugs.mysql.com. Discussed with: Marko ------------------------------------------------------------------------ r4291 | vasil | 2009-02-25 11:08:32 +0200 (Wed, 25 Feb 2009) | 4 lines branches/zip: Fix Bug synopsis and remove explanation ------------------------------------------------------------------------ r4292 | marko | 2009-02-25 12:09:15 +0200 (Wed, 25 Feb 2009) | 25 lines branches/zip: Correct the initialization of the memory subsystem once again, to finally put Issue #181 to rest. Revert some parts of r4274. It is best not to call ut_malloc() before srv_general_init(). mem_init(): Do not call ut_mem_init(). srv_general_init(): Initialize the memory subsystem in two phases: first ut_mem_init(), then mem_init(). This is because os_sync_init() and sync_init() depend on ut_mem_init() and mem_init() depends on os_sync_init() or sync_init(). srv_parse_data_file_paths_and_sizes(), srv_parse_log_group_home_dirs(): Remove the output parameters. Assign to the global variables directly. Allocate memory with malloc() instead of ut_malloc(), because these functions will be called before srv_general_init(). srv_free_paths_and_sizes(): New function, for cleaning up after srv_parse_data_file_paths_and_sizes() and srv_parse_log_group_home_dirs(). rb://92 approved by Sunny Bains ------------------------------------------------------------------------ r4297 | vasil | 2009-02-25 17:19:19 +0200 (Wed, 25 Feb 2009) | 4 lines branches/zip: White-space cleanup in the ChangeLog ------------------------------------------------------------------------ r4301 | vasil | 2009-02-25 21:33:32 +0200 (Wed, 25 Feb 2009) | 5 lines branches/zip: Do not output the commands that restore the environment because they depend on the state of the environment before the test starts executing. ------------------------------------------------------------------------ r4315 | vasil | 2009-02-26 09:21:20 +0200 (Thu, 26 Feb 2009) | 5 lines branches/zip: Apply any necessary patches to the mysql tree at the end of setup.sh This step was previously done manually (and sometimes forgotten). ------------------------------------------------------------------------ r4319 | marko | 2009-02-26 23:27:51 +0200 (Thu, 26 Feb 2009) | 6 lines branches/zip: btr_check_blob_fil_page_type(): Do not report FIL_PAGE_TYPE mismatch even when purging a BLOB. Heavy users may have large data files created with MySQL 5.0 or earlier, and they don not want to have the error log flooded with such messages. This fixes Issue #182. ------------------------------------------------------------------------ r4320 | inaam | 2009-02-27 02:13:19 +0200 (Fri, 27 Feb 2009) | 8 lines branches/zip This is to revert the changes made to the plug.in (r4251) as a fix for issue# 178. Changes to plug.in will not propogate to a plugin installation unless autotools are rerun which is unacceptable. A fix for issue# 178 will be committed in a separate commit. ------------------------------------------------------------------------ r4321 | inaam | 2009-02-27 02:16:46 +0200 (Fri, 27 Feb 2009) | 6 lines branches/zip This is a fix for issue#178. Instead of using UNIV_LINUX which is defined through CFLAGS we use compiler generated define __linux__ that is effective for both .c and .cc files. ------------------------------------------------------------------------ r4324 | vasil | 2009-02-27 13:27:18 +0200 (Fri, 27 Feb 2009) | 39 lines branches/zip: Add FreeBSD to the list of the operating systems that have sizeof(pthread_t) == sizeof(void*) (i.e. word size). On FreeBSD pthread_t is defined like: /usr/include/sys/_pthreadtypes.h: typedef struct pthread *pthread_t; I did the following tests (per Inaam's recommendation): a) appropriate version of GCC is available on that platform (4.1.2 or higher for atomics to be available) On FreeBSD 6.x the default compiler is 3.4.6, on FreeBSD 7.x the default one is 4.2.1. One can always install the version of choice from the ports collection. If gcc 3.x is used then HAVE_GCC_ATOMIC_BUILTINS will not be defined and thus the change I am committing will make no difference. b) find out if sizeof(pthread_t) == sizeof(long) On 32 bit both are 4 bytes, on 64 bit both are 8 bytes. c) find out the compiler generated platform define (e.g.: __aix, __sunos__ etc.) The macro is __FreeBSD__. d) patch univ.i with the appropriate platform define e) build the mysql f) ensure it is using atomic builtins (look at the err.log message at system startup. It should say we are using atomics for both mutexes and rw-locks) g) do sanity testing (keeping in view the smp changes) I ran the mysql-test suite. All tests pass. ------------------------------------------------------------------------ r4353 | vasil | 2009-03-05 09:27:29 +0200 (Thu, 05 Mar 2009) | 6 lines branches/zip: As suggested by Ken, print a message that says that the Google SMP patch (GCC atomics) is disabled if it is. Also extend the message when the patch is partially enabled to make it clear that it is partially enabled. ------------------------------------------------------------------------ r4356 | vasil | 2009-03-05 13:49:51 +0200 (Thu, 05 Mar 2009) | 4 lines branches/zip: Fix typo made in r4353. ------------------------------------------------------------------------ r4357 | vasil | 2009-03-05 16:38:59 +0200 (Thu, 05 Mar 2009) | 23 lines branches/zip: Implement a check whether pthread_t objects can be used by GCC atomic builtin functions. This check is implemented in plug.in and defines the macro HAVE_ATOMIC_PTHREAD_T. This macro is checked in univ.i and the relevant part of the code enabled (the one that uses GCC atomics against pthread_t objects). In addition to this, the same program that is compiled as part of the plug.in check is added in ut/ut0auxconf.c. In the InnoDB Plugin source archives that are shipped to the users, a generated Makefile.in is added. That Makefile.in will be modified to compile ut/ut0auxconf.c and define the macro HAVE_ATOMIC_PTHREAD_T if the compilation succeeds. I.e. Makefile.in will emulate the work that is done by plug.in. This is done in order to make the check happen and HAVE_ATOMIC_PTHREAD_T eventually defined without regenerating MySQL's ./configure from ./storage/innobase/plug.in. The point is not to ask users to install the autotools and regenerate ./configure. rb://95 Approved by: Marko ------------------------------------------------------------------------ r4360 | vasil | 2009-03-05 22:23:17 +0200 (Thu, 05 Mar 2009) | 21 lines branches/zip: Merge revisions 4287:4357 from branches/5.1: ------------------------------------------------------------------------ r4325 | sunny | 2009-03-02 02:28:52 +0200 (Mon, 02 Mar 2009) | 10 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Bug#43203: Overflow from auto incrementing causes server segv It was not a SIGSEGV but an assertion failure. The assertion was checking the invariant that *first_value passed in by MySQL doesn't contain a value that is greater than the max value for that type. The assertion has been changed to a check and if the value is greater than the max we report a generic AUTOINC failure. rb://93 Approved by Heikki ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4361 | vasil | 2009-03-05 22:27:54 +0200 (Thu, 05 Mar 2009) | 30 lines branches/zip: Merge revision 4358 from branches/5.1 (resolving a conflict): ------------------------------------------------------------------------ r4358 | vasil | 2009-03-05 21:21:10 +0200 (Thu, 05 Mar 2009) | 21 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: Merge a change from MySQL: ------------------------------------------------------------ revno: 2728.19.1 committer: Alfranio Correia <alfranio.correia@sun.com> branch nick: mysql-5.1-bugteam timestamp: Tue 2009-02-03 11:36:46 +0000 message: BUG#42445 Warning messages in innobase/handler/ha_innodb.cc There was a type casting problem in the storage/innobase/handler/ha_innodb.cc, (int ha_innobase::write_row(...)). Innobase uses has an internal error variable of type 'ulint' while mysql uses an 'int'. To fix the problem the function manipulates an error variable of type 'ulint' and only casts it into 'int' when needs to return the value. modified: storage/innobase/handler/ha_innodb.cc ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4362 | vasil | 2009-03-05 22:29:07 +0200 (Thu, 05 Mar 2009) | 23 lines branches/zip: Merge revision 4359 from branches/5.1: ------------------------------------------------------------------------ r4359 | vasil | 2009-03-05 21:42:01 +0200 (Thu, 05 Mar 2009) | 14 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: Merge a change from MySQL: ------------------------------------------------------------ revno: 2747 committer: Timothy Smith <timothy.smith@sun.com> branch nick: 51 timestamp: Fri 2009-01-16 17:49:07 +0100 message: Add another cast to ignore int/ulong difference in error types, silence warning on Win64 modified: storage/innobase/handler/ha_innodb.cc ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4363 | vasil | 2009-03-05 22:31:37 +0200 (Thu, 05 Mar 2009) | 4 lines branches/zip: Add ChangeLog entry for the bugfix in c4360. ------------------------------------------------------------------------ r4378 | calvin | 2009-03-09 10:10:17 +0200 (Mon, 09 Mar 2009) | 7 lines branches/zip: remove compile flag MYSQL_SERVER for dynamic plugin The dynamic plugin on Windows used to be built with MYSQL_SERVER compile flag, while it is not the case for other platforms. r3797 assumed MYSQL_SERVER was not defined for dynamic plugin, which introduced the engine crash during dropping a database. ------------------------------------------------------------------------ r4396 | marko | 2009-03-12 09:22:27 +0200 (Thu, 12 Mar 2009) | 3 lines branches/zip: btr_store_big_rec_extern_fields(): Initialize FIL_PAGE_TYPE in a separate redo log entry. This will make ibbackup --apply-log debugging easier. ------------------------------------------------------------------------ r4397 | marko | 2009-03-12 09:26:11 +0200 (Thu, 12 Mar 2009) | 3 lines branches/zip: trx_sys_create_doublewrite_buf(): As the dummy change, initialize FIL_PAGE_TYPE. This will make it easier to write the debug assertions for ibbackup --apply-log. ------------------------------------------------------------------------ r4401 | marko | 2009-03-12 10:26:40 +0200 (Thu, 12 Mar 2009) | 19 lines branches/zip: Merge revisions 4359:4400 from branches/5.1: ------------------------------------------------------------------------ r4399 | marko | 2009-03-12 09:38:05 +0200 (Thu, 12 Mar 2009) | 2 lines branches/5.1: row_sel_get_clust_rec_for_mysql(): Store the cursor position also for unlock_row(). (Bug #39320) ------------------------------------------------------------------------ r4400 | marko | 2009-03-12 10:06:44 +0200 (Thu, 12 Mar 2009) | 5 lines branches/5.1: Fix a bug in multi-table semi-consistent reads. Remember the acquired record locks per table handle (row_prebuilt_t) rather than per transaction (trx_t), so that unlock_row should successfully unlock all non-matching rows in multi-table operations. This deficiency was found while investigating Bug #39320. ------------------------------------------------------------------------ These were submitted as rb://94 and rb://96 and approved by Heikki Tuuri. ------------------------------------------------------------------------ r4455 | marko | 2009-03-16 11:43:34 +0200 (Mon, 16 Mar 2009) | 2 lines branches/zip: UT_LIST_VALIDATE(): Add the parameter ASSERTION and adjust all callers. ------------------------------------------------------------------------ r4456 | marko | 2009-03-16 12:59:25 +0200 (Mon, 16 Mar 2009) | 6 lines branches/zip: UT_LIST_VALIDATE(): Assert that the link is non-NULL before dereferencing it. In this way, ut_list_node_313 will be pointing to the last non-NULL list item at the time of the assertion failure. (gcc-4.3.2 -O3 seems to optimize the common subexpressions and make the variable NULL, though.) ------------------------------------------------------------------------ r4457 | marko | 2009-03-16 14:12:02 +0200 (Mon, 16 Mar 2009) | 2 lines branches/zip: sync_thread_add_level(): Make the assertions about level == SYNC_BUF_BLOCK more readable. ------------------------------------------------------------------------ r4461 | vasil | 2009-03-17 09:38:19 +0200 (Tue, 17 Mar 2009) | 6 lines branches/zip: Remove mysql-test/patches/bug32625.diff because that bug was fixed in the mysql repository (1 year and 4 months after sending them the simple patch!). See http://bugs.mysql.com/32625 ------------------------------------------------------------------------ r4465 | marko | 2009-03-17 12:34:19 +0200 (Tue, 17 Mar 2009) | 1 line branches/zip: buf0buddy.c: Add and adjust some debug assertions. ------------------------------------------------------------------------ r4473 | vasil | 2009-03-17 15:50:30 +0200 (Tue, 17 Mar 2009) | 5 lines branches/zip: Increment the InnoDB Plugin version from 1.0.3 to 1.0.4 now that 1.0.3 has been released. ------------------------------------------------------------------------ r4478 | vasil | 2009-03-18 11:53:53 +0200 (Wed, 18 Mar 2009) | 5 lines branches/zip: Remove mysql-test/patches/bug41893.diff because that bug has been fixed in the MySQL repository, see http://bugs.mysql.com/41893. ------------------------------------------------------------------------ r4479 | marko | 2009-03-18 12:43:54 +0200 (Wed, 18 Mar 2009) | 2 lines branches/zip: buf_LRU_block_remove_hashed_page(): Add some debug assertions. ------------------------------------------------------------------------ r4480 | marko | 2009-03-18 14:32:13 +0200 (Wed, 18 Mar 2009) | 1 line branches/zip: buf_buddy_free_low(): Correct the function comment. ------------------------------------------------------------------------ r4482 | marko | 2009-03-19 15:23:32 +0200 (Thu, 19 Mar 2009) | 12 lines branches/zip: Merge revisions 4400:4481 from branches/5.1: ------------------------------------------------------------------------ r4481 | marko | 2009-03-19 15:01:48 +0200 (Thu, 19 Mar 2009) | 6 lines branches/5.1: row_unlock_for_mysql(): Do not unlock records that were modified by the current transaction. This bug was introduced or unmasked in r4400. rb://97 approved by Heikki Tuuri ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4490 | marko | 2009-03-20 12:33:33 +0200 (Fri, 20 Mar 2009) | 4 lines branches/zip: Non-functional change for reducing dependencies in InnoDB Hot Backup: Replace srv_sys->dummy_ind1 and srv_sys->dummy_ind2 with dict_ind_redundant and dict_ind_compact, initialized in dict_init(). ------------------------------------------------------------------------ r4491 | marko | 2009-03-20 12:45:18 +0200 (Fri, 20 Mar 2009) | 2 lines branches/zip: Add const qualifiers or in/out comments to some function parameters in log0log. ------------------------------------------------------------------------ r4492 | marko | 2009-03-20 12:52:14 +0200 (Fri, 20 Mar 2009) | 5 lines branches/zip: page_validate(): Always report the space id and the name of the index. In Hot Backup, do not invoke comparison functions, as MySQL collations will be unavailable. ------------------------------------------------------------------------ r4493 | marko | 2009-03-20 13:24:06 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: Replace fil_get_space_for_id_low() with fil_space_get_by_id(). ------------------------------------------------------------------------ r4494 | marko | 2009-03-20 13:51:35 +0200 (Fri, 20 Mar 2009) | 3 lines branches/zip: fil0fil.c: Refer to fil_system directly, not via local vars. This eliminates some "unused variable" warnings when building InnoDB Hot Backup in such a way that all mutex operations are no-ops. ------------------------------------------------------------------------ r4495 | marko | 2009-03-20 14:15:52 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: innobase_get_at_most_n_mbchars(): Declare in ha_prototypes.h. ------------------------------------------------------------------------ r4496 | marko | 2009-03-20 14:48:26 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: recv_recover_page(): Remove compile-time constant parameters. ------------------------------------------------------------------------ r4497 | marko | 2009-03-20 14:56:19 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: recv_sys_init(): Remove a compile-time constant parameter. ------------------------------------------------------------------------ r4498 | marko | 2009-03-20 15:08:05 +0200 (Fri, 20 Mar 2009) | 4 lines branches/zip: Non-functional change: Add const qualifiers. log_block_checksum_is_ok_or_old_format(), recv_sys_add_to_parsing_buf(): The log block is read-only. Make it const. ------------------------------------------------------------------------ r4499 | marko | 2009-03-20 15:10:25 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: recv_scan_log_recs(): Remove a compile-time constant parameter. ------------------------------------------------------------------------ r4500 | marko | 2009-03-20 15:47:17 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: fil_init(): Add the parameter hash_size. ------------------------------------------------------------------------ r4501 | vasil | 2009-03-20 16:50:41 +0200 (Fri, 20 Mar 2009) | 4 lines branches/zip: Add any entry about the release of 1.0.3 in the ChangeLog. ------------------------------------------------------------------------ r4515 | marko | 2009-03-23 10:49:53 +0200 (Mon, 23 Mar 2009) | 1 line branches/zip: hash_table_t: adaptive: Remove from UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4516 | marko | 2009-03-23 10:57:16 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Define and use ASSERT_HASH_MUTEX_OWN. Make it a no-op in UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4517 | marko | 2009-03-23 11:07:20 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Define and use PAGE_ZIP_MATCH. In UNIV_HOTBACKUP builds, assume fixed allocation. ------------------------------------------------------------------------ r4521 | marko | 2009-03-23 12:05:47 +0200 (Mon, 23 Mar 2009) | 1 line branches/zip: buf_page_print(): Clean up the code #ifdef UNIV_HOTBACKUP. ------------------------------------------------------------------------ r4522 | marko | 2009-03-23 12:20:50 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Exclude some operating system interface code from UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4523 | marko | 2009-03-23 13:00:43 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Remove the remaining references to hash_table_t::adapive from UNIV_HOTBACKUP builds. This should have been done in r4515. ------------------------------------------------------------------------ r4524 | marko | 2009-03-23 14:05:18 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Enclose recv_recovery_from_backup_on and recv_recovery_from_backup_is_on() in #ifdef UNIV_LOG_ARCHIVE. ------------------------------------------------------------------------ r4525 | marko | 2009-03-23 14:57:45 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: recv_parse_or_apply_log_rec_body(): Add debug assertions ensuring that FIL_PAGE_TYPE makes sense when applying log records. ------------------------------------------------------------------------ r4526 | marko | 2009-03-23 16:21:34 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Remove unneeded definitions and dependencies from UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4527 | calvin | 2009-03-23 23:15:33 +0200 (Mon, 23 Mar 2009) | 5 lines branches/zip: adjust build files on Windows Adjust the patch positions based on the latest MySQL source. Also add the patches to the .bat files for vs9. ------------------------------------------------------------------------
17 years ago
MDEV-15250 UPSERT during ALTER TABLE results in 'Duplicate entry' error for alter - InnoDB DDL results in `Duplicate entry' if concurrent DML throws duplicate key error. The following scenario explains the problem connection con1: ALTER TABLE t1 FORCE; connection con2: INSERT INTO t1(pk, uk) VALUES (2, 2), (3, 2); In connection con2, InnoDB throws the 'DUPLICATE KEY' error because of unique index. Alter operation will throw the error when applying the concurrent DML log. - Inserting the duplicate key for unique index logs the insert operation for online ALTER TABLE. When insertion fails, transaction does rollback and it leads to logging of delete operation for online ALTER TABLE. While applying the insert log entries, alter operation encounters 'DUPLICATE KEY' error. - To avoid the above fake duplicate scenario, InnoDB should not write any log for online ALTER TABLE before DML transaction commit. - User thread which does DML can apply the online log if InnoDB ran out of online log and index is marked as completed. Set online log error if apply phase encountered any error. It can also clear all other indexes log, marks the newly added indexes as corrupted. - Removed the old online code which was a part of DML operations commit_inplace_alter_table() : Does apply the online log for the last batch of secondary index log and does frees the log for the completed index. trx_t::apply_online_log: Set to true while writing the undo log if the modified table has active DDL trx_t::apply_log(): Apply the DML changes to online DDL tables dict_table_t::is_active_ddl(): Returns true if the table has an active DDL dict_index_t::online_log_make_dummy(): Assign dummy value for clustered index online log to indicate the secondary indexes are being rebuild. dict_index_t::online_log_is_dummy(): Check whether the online log has dummy value ha_innobase_inplace_ctx::log_failure(): Handle the apply log failure for online DDL transaction row_log_mark_other_online_index_abort(): Clear out all other online index log after encountering the error during row_log_apply() row_log_get_error(): Get the error happened during row_log_apply() row_log_online_op(): Does apply the online log if index is completed and ran out of memory. Returns false if apply log fails UndorecApplier: Introduced a class to maintain the undo log record, latched undo buffer page, parse the undo log record, maintain the undo record type, info bits and update vector UndorecApplier::get_old_rec(): Get the correct version of the clustered index record that was modified by the current undo log record UndorecApplier::clear_undo_rec(): Clear the undo log related information after applying the undo log record UndorecApplier::log_update(): Handle the update, delete undo log and apply it on online indexes UndorecApplier::log_insert(): Handle the insert undo log and apply it on online indexes UndorecApplier::is_same(): Check whether the given roll pointer is generated by the current undo log record information trx_t::rollback_low(): Set apply_online_log for the transaction after partially rollbacked transaction has any active DDL prepare_inplace_alter_table_dict(): After allocating the online log, InnoDB does create fulltext common tables. Fulltext index doesn't allow the index to be online. So removed the dead code of online log removal Thanks to Marko Mäkelä for providing the initial prototype and Matthias Leich for testing the issue patiently.
4 years ago
branches/innodb+: Merge revisions 4150:4528 from branches/zip: ------------------------------------------------------------------------ r4152 | marko | 2009-02-10 12:52:27 +0200 (Tue, 10 Feb 2009) | 12 lines branches/zip: When innodb_use_sys_malloc is set, ignore innodb_additional_mem_pool_size, because nothing will be allocated from mem_comm_pool. mem_pool_create(): Remove the assertion about size. The function will work with any size. However, an assertion would fail in ut_malloc_low() when size==0. mem_init(): When srv_use_sys_malloc is set, pass size=1 to mem_pool_create(). mem0mem.c: Add #include "srv0srv.h" that is needed by mem0dbg.c. ------------------------------------------------------------------------ r4153 | vasil | 2009-02-10 22:58:17 +0200 (Tue, 10 Feb 2009) | 14 lines branches/zip: (followup to r4145) Non-functional change: Change the os_atomic_increment() and os_compare_and_swap() functions to macros to avoid artificial limitations on the types of those functions' arguments. As a consequence typecasts from the source code can be removed. Also remove Google's copyright from os0sync.ic because that file no longer contains code from Google. Approved by: Marko (rb://88), also ok from Inaam via IM ------------------------------------------------------------------------ r4163 | marko | 2009-02-12 00:14:19 +0200 (Thu, 12 Feb 2009) | 4 lines branches/zip: Make innodb_thread_concurrency=0 the default. The old default was 8. ------------------------------------------------------------------------ r4169 | calvin | 2009-02-12 10:37:10 +0200 (Thu, 12 Feb 2009) | 3 lines branches/zip: Adjust the result file of innodb_thread_concurrency_basic test. The default value of innodb_thread_concurrency is changed to 0 (from 8) via r4163. ------------------------------------------------------------------------ r4174 | vasil | 2009-02-12 17:38:27 +0200 (Thu, 12 Feb 2009) | 4 lines branches/zip: Fix pathname of the file to patch. ------------------------------------------------------------------------ r4176 | vasil | 2009-02-13 10:06:31 +0200 (Fri, 13 Feb 2009) | 7 lines branches/zip: Fix the failing mysql-test partition_innodb, which failed only if run after innodb_trx_weight (or other test that would leave LATEST DEADLOCK ERROR into the output of SHOW ENGINE INNODB STATUS). Find further explanation for the failure at the top of the added patch partition_innodb.diff. ------------------------------------------------------------------------ r4198 | vasil | 2009-02-17 09:06:07 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: Add the full text of the GPLv2 license into the root directory of the plugin. In previous releases this file was copied from an external source (https://svn.innodb.com/svn/plugin/trunk/support/COPYING) "manually" when creating the source and binary archives. It is less confusing to have this present in the root directory of the SVN branch. ------------------------------------------------------------------------ r4199 | vasil | 2009-02-17 09:11:58 +0200 (Tue, 17 Feb 2009) | 4 lines branches/zip: Add Google's license into COPYING.Google. ------------------------------------------------------------------------ r4200 | vasil | 2009-02-17 09:56:33 +0200 (Tue, 17 Feb 2009) | 11 lines branches/zip: To the files touched by the Google patch from c4144 (excluding include/os0sync.ic because later we removed Google code from that file): * Remove the Google license * Remove old Innobase copyright lines * Add a reference to the Google license and to the GPLv2 license at the top, as recommended by the lawyers at Oracle Legal. ------------------------------------------------------------------------ r4201 | vasil | 2009-02-17 10:12:02 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 1/28] ------------------------------------------------------------------------ r4202 | vasil | 2009-02-17 10:15:06 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 2/28] ------------------------------------------------------------------------ r4203 | vasil | 2009-02-17 10:25:45 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 3/28] ------------------------------------------------------------------------ r4204 | vasil | 2009-02-17 10:55:41 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 4/28] ------------------------------------------------------------------------ r4205 | vasil | 2009-02-17 10:59:22 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 5/28] ------------------------------------------------------------------------ r4206 | vasil | 2009-02-17 11:02:27 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 6/28] ------------------------------------------------------------------------ r4207 | vasil | 2009-02-17 11:04:28 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 7/28] ------------------------------------------------------------------------ r4208 | vasil | 2009-02-17 11:06:49 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 8/28] ------------------------------------------------------------------------ r4209 | vasil | 2009-02-17 11:10:18 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 9/28] ------------------------------------------------------------------------ r4210 | vasil | 2009-02-17 11:12:41 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 10/28] ------------------------------------------------------------------------ r4211 | vasil | 2009-02-17 11:14:40 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 11/28] ------------------------------------------------------------------------ r4212 | vasil | 2009-02-17 11:18:35 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 12/28] ------------------------------------------------------------------------ r4213 | vasil | 2009-02-17 11:24:40 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 13/28] ------------------------------------------------------------------------ r4214 | vasil | 2009-02-17 11:27:31 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 13/28] ------------------------------------------------------------------------ r4215 | vasil | 2009-02-17 11:29:55 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 15/28] ------------------------------------------------------------------------ r4216 | vasil | 2009-02-17 11:33:38 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 16/28] ------------------------------------------------------------------------ r4217 | vasil | 2009-02-17 11:36:44 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 17/28] ------------------------------------------------------------------------ r4218 | vasil | 2009-02-17 11:39:11 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 18/28] ------------------------------------------------------------------------ r4219 | vasil | 2009-02-17 11:41:24 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 19/28] ------------------------------------------------------------------------ r4220 | vasil | 2009-02-17 11:43:50 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 20/28] ------------------------------------------------------------------------ r4221 | vasil | 2009-02-17 11:46:52 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 21/28] ------------------------------------------------------------------------ r4222 | vasil | 2009-02-17 11:50:12 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 22/28] ------------------------------------------------------------------------ r4223 | vasil | 2009-02-17 11:53:58 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 23/28] ------------------------------------------------------------------------ r4224 | vasil | 2009-02-17 12:01:41 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 24/28] ------------------------------------------------------------------------ r4225 | vasil | 2009-02-17 12:05:45 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 25/28] ------------------------------------------------------------------------ r4226 | vasil | 2009-02-17 12:09:16 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 26/28] ------------------------------------------------------------------------ r4227 | vasil | 2009-02-17 12:12:56 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 27/28] ------------------------------------------------------------------------ r4228 | vasil | 2009-02-17 12:14:04 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 28/28] ------------------------------------------------------------------------ r4229 | vasil | 2009-02-17 12:30:55 +0200 (Tue, 17 Feb 2009) | 4 lines branches/zip: Add the copyright notice to the non C files. ------------------------------------------------------------------------ r4231 | marko | 2009-02-17 14:26:53 +0200 (Tue, 17 Feb 2009) | 12 lines Minor cleanup of the Google SMP patch. sync_array_object_signalled(): Add a (void) cast to eliminate a gcc warning about the return value of os_atomic_increment() being ignored. rw_lock_create_func(): Properly indent the preprocessor directives. rw_lock_x_lock_low(), rw_lock_x_lock_func_nowait(): Split lines correctly. rw_lock_set_writer_id_and_recursion_flag(): Silence a Valgrind warning. Do not mix statements and variable declarations. ------------------------------------------------------------------------ r4232 | marko | 2009-02-17 14:59:54 +0200 (Tue, 17 Feb 2009) | 3 lines branches/zip: When assigning lock->recursive = FALSE, also flag lock->writer_thread invalid, so that Valgrind will catch more errors. This is related to Issue #175. ------------------------------------------------------------------------ r4242 | marko | 2009-02-18 17:01:09 +0200 (Wed, 18 Feb 2009) | 2 lines branches/zip: UT_DBG_STOP: Use do{} while(0) to silence a g++-4.3.2 warning about a while(0); statement. This should fix (part of) Issue #176. ------------------------------------------------------------------------ r4243 | marko | 2009-02-18 17:04:03 +0200 (Wed, 18 Feb 2009) | 3 lines branches/zip: buf_buddy_get_slot(): Fix a gcc 4.3.2 warning about an empty body of a "for" statement. This fixes part of Issue #176. ------------------------------------------------------------------------ r4244 | marko | 2009-02-18 17:25:45 +0200 (Wed, 18 Feb 2009) | 11 lines branches/zip: Protect ut_total_allocated_memory with ut_list_mutex. Unprotected updates to ut_total_allocated_memory in os_mem_alloc_large() and os_mem_free_large(), called during fast index creation, may corrupt the variable and cause assertion failures. Also, add UNIV_MEM_ALLOC() and UNIV_MEM_FREE() instrumentation around os_mem_alloc_large() and os_mem_free_large(), so that Valgrind can detect more errors. rb://90 approved by Heikki Tuuri. This addresses Issue #177. ------------------------------------------------------------------------ r4248 | marko | 2009-02-19 11:52:39 +0200 (Thu, 19 Feb 2009) | 2 lines branches/zip: page_zip_set_size(): Fix a g++ 4.3.2 warning about an empty body in a "for" statement. This closes Issue #176. ------------------------------------------------------------------------ r4251 | inaam | 2009-02-19 15:46:27 +0200 (Thu, 19 Feb 2009) | 8 lines branches/zip: Issue #178 rb://91 Change plug.in to have same CXXFLAGS as CFLAGS. This is to ensure that both .c and .cc files get compiled with same flags. To fix the issue where UNIV_LINUX was defined only in .c files. Approved by: Marko ------------------------------------------------------------------------ r4258 | vasil | 2009-02-20 11:52:19 +0200 (Fri, 20 Feb 2009) | 7 lines branches/zip: Cleanup in ChangeLog: * Wrap lines at 78 characters * Changed files are listed alphabetically * White-space cleanup ------------------------------------------------------------------------ r4259 | vasil | 2009-02-20 11:59:42 +0200 (Fri, 20 Feb 2009) | 6 lines branches/zip: ChangeLog: Remove include/os0sync.ic from the entry about the google patch, this file was modified later to not include Google's code. ------------------------------------------------------------------------ r4262 | vasil | 2009-02-20 14:56:59 +0200 (Fri, 20 Feb 2009) | 373 lines branches/zip: Merge revisions 4035:4261 from branches/5.1: ------------------------------------------------------------------------ r4065 | sunny | 2009-01-29 16:01:36 +0200 (Thu, 29 Jan 2009) | 8 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: In the last round of AUTOINC cleanup we assumed that AUTOINC is only defined for integer columns. This caused an assertion failure when we checked for the maximum value of a column type. We now calculate the max value for floating-point autoinc columns too. Fix Bug#42400 - InnoDB autoinc code can't handle floating-point columns rb://84 and Mantis issue://162 ------------------------------------------------------------------------ r4111 | sunny | 2009-02-03 22:06:52 +0200 (Tue, 03 Feb 2009) | 2 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: Add the ULL suffix otherwise there is an overflow. ------------------------------------------------------------------------ r4128 | vasil | 2009-02-08 21:36:45 +0200 (Sun, 08 Feb 2009) | 18 lines Changed paths: M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Merge a change from MySQL: ------------------------------------------------------------ revno: 2709.20.31 committer: Timothy Smith <timothy.smith@sun.com> branch nick: 51 timestamp: Fri 2008-12-19 01:28:51 +0100 message: Disable part of innodb-autoinc.test, because the MySQL server asserts when compiled --with-debug, due to bug 39828, "autoinc wraps around when offset and increment > 1". This change should be reverted when that bug is fixed (and a a few other minor changes to the test as described in comments). modified: mysql-test/r/innodb-autoinc.result mysql-test/t/innodb-autoinc.test ------------------------------------------------------------------------ r4129 | vasil | 2009-02-08 21:54:25 +0200 (Sun, 08 Feb 2009) | 310 lines Changed paths: M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Merge a change from MySQL: [looks like the changes to innodb-autoinc.test were made as part of the following huge merge, but we are merging only changes to that file] ------------------------------------------------------------ revno: 2546.47.1 committer: Luis Soares <luis.soares@sun.com> branch nick: 5.1-rpl timestamp: Fri 2009-01-23 13:22:05 +0100 message: merge: 5.1 -> 5.1-rpl conflicts: Text conflict in client/mysqltest.cc Text conflict in mysql-test/include/wait_until_connected_again.inc Text conflict in mysql-test/lib/mtr_report.pm Text conflict in mysql-test/mysql-test-run.pl Text conflict in mysql-test/r/events_bugs.result Text conflict in mysql-test/r/log_state.result Text conflict in mysql-test/r/myisam_data_pointer_size_func.result Text conflict in mysql-test/r/mysqlcheck.result Text conflict in mysql-test/r/query_cache.result Text conflict in mysql-test/r/status.result Text conflict in mysql-test/suite/binlog/r/binlog_index.result Text conflict in mysql-test/suite/binlog/r/binlog_innodb.result Text conflict in mysql-test/suite/rpl/r/rpl_packet.result Text conflict in mysql-test/suite/rpl/t/rpl_packet.test Text conflict in mysql-test/t/disabled.def Text conflict in mysql-test/t/events_bugs.test Text conflict in mysql-test/t/log_state.test Text conflict in mysql-test/t/myisam_data_pointer_size_func.test Text conflict in mysql-test/t/mysqlcheck.test Text conflict in mysql-test/t/query_cache.test Text conflict in mysql-test/t/rpl_init_slave_func.test Text conflict in mysql-test/t/status.test removed: mysql-test/suite/parts/r/partition_bit_ndb.result mysql-test/suite/parts/t/partition_bit_ndb.test mysql-test/suite/parts/t/partition_sessions.test mysql-test/suite/sys_vars/inc/tmp_table_size_basic.inc mysql-test/suite/sys_vars/r/tmp_table_size_basic_32.result mysql-test/suite/sys_vars/r/tmp_table_size_basic_64.result mysql-test/suite/sys_vars/t/tmp_table_size_basic_32.test mysql-test/suite/sys_vars/t/tmp_table_size_basic_64.test mysql-test/t/log_bin_trust_function_creators_func-master.opt mysql-test/t/rpl_init_slave_func-slave.opt added: mysql-test/include/check_events_off.inc mysql-test/include/cleanup_fake_relay_log.inc mysql-test/include/have_simple_parser.inc mysql-test/include/no_running_event_scheduler.inc mysql-test/include/no_running_events.inc mysql-test/include/running_event_scheduler.inc mysql-test/include/setup_fake_relay_log.inc mysql-test/include/wait_condition_sp.inc mysql-test/r/fulltext_plugin.result mysql-test/r/have_simple_parser.require mysql-test/r/innodb_bug38231.result mysql-test/r/innodb_bug39438.result mysql-test/r/innodb_mysql_rbk.result mysql-test/r/partition_innodb_semi_consistent.result mysql-test/r/query_cache_28249.result mysql-test/r/status2.result mysql-test/std_data/bug40482-bin.000001 mysql-test/suite/binlog/r/binlog_innodb_row.result mysql-test/suite/binlog/t/binlog_innodb_row.test mysql-test/suite/rpl/r/rpl_binlog_corruption.result mysql-test/suite/rpl/t/rpl_binlog_corruption-master.opt mysql-test/suite/rpl/t/rpl_binlog_corruption.test mysql-test/suite/sys_vars/r/tmp_table_size_basic.result mysql-test/suite/sys_vars/t/tmp_table_size_basic.test mysql-test/t/fulltext_plugin-master.opt mysql-test/t/fulltext_plugin.test mysql-test/t/innodb_bug38231.test mysql-test/t/innodb_bug39438-master.opt mysql-test/t/innodb_bug39438.test mysql-test/t/innodb_mysql_rbk-master.opt mysql-test/t/innodb_mysql_rbk.test mysql-test/t/partition_innodb_semi_consistent-master.opt mysql-test/t/partition_innodb_semi_consistent.test mysql-test/t/query_cache_28249.test mysql-test/t/status2.test renamed: mysql-test/suite/funcs_1/r/is_collation_character_set_applicability.result => mysql-test/suite/funcs_1/r/is_coll_char_set_appl.result mysql-test/suite/funcs_1/t/is_collation_character_set_applicability.test => mysql-test/suite/funcs_1/t/is_coll_char_set_appl.test modified: .bzr-mysql/default.conf CMakeLists.txt client/mysql.cc client/mysql_upgrade.c client/mysqlcheck.c client/mysqltest.cc configure.in extra/resolve_stack_dump.c extra/yassl/include/openssl/ssl.h include/config-win.h include/m_ctype.h include/my_global.h mysql-test/extra/binlog_tests/database.test mysql-test/extra/rpl_tests/rpl_auto_increment.test mysql-test/include/commit.inc mysql-test/include/have_32bit.inc mysql-test/include/have_64bit.inc mysql-test/include/index_merge1.inc mysql-test/include/linux_sys_vars.inc mysql-test/include/windows_sys_vars.inc mysql-test/lib/mtr_report.pm mysql-test/mysql-test-run.pl mysql-test/r/alter_table.result mysql-test/r/commit_1innodb.result mysql-test/r/create.result mysql-test/r/csv.result mysql-test/r/ctype_ucs.result mysql-test/r/date_formats.result mysql-test/r/events_bugs.result mysql-test/r/events_scheduling.result mysql-test/r/fulltext.result mysql-test/r/func_if.result mysql-test/r/func_in.result mysql-test/r/func_str.result mysql-test/r/func_time.result mysql-test/r/grant.result mysql-test/r/index_merge_myisam.result mysql-test/r/information_schema.result mysql-test/r/innodb-autoinc.result mysql-test/r/innodb.result mysql-test/r/innodb_mysql.result mysql-test/r/log_bin_trust_function_creators_func.result mysql-test/r/log_state.result mysql-test/r/myisampack.result mysql-test/r/mysql.result mysql-test/r/mysqlcheck.result mysql-test/r/partition_datatype.result mysql-test/r/partition_mgm.result mysql-test/r/partition_pruning.result mysql-test/r/query_cache.result mysql-test/r/read_buffer_size_basic.result mysql-test/r/read_rnd_buffer_size_basic.result mysql-test/r/rpl_init_slave_func.result mysql-test/r/select.result mysql-test/r/status.result mysql-test/r/strict.result mysql-test/r/temp_table.result mysql-test/r/type_bit.result mysql-test/r/type_date.result mysql-test/r/type_float.result mysql-test/r/warnings_engine_disabled.result mysql-test/r/xml.result mysql-test/suite/binlog/r/binlog_database.result mysql-test/suite/binlog/r/binlog_index.result mysql-test/suite/binlog/r/binlog_innodb.result mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result mysql-test/suite/binlog/t/binlog_innodb.test mysql-test/suite/funcs_1/r/is_columns_is.result mysql-test/suite/funcs_1/r/is_engines.result mysql-test/suite/funcs_1/r/storedproc.result mysql-test/suite/funcs_1/storedproc/param_check.inc mysql-test/suite/funcs_2/t/disabled.def mysql-test/suite/ndb/t/disabled.def mysql-test/suite/parts/r/partition_bit_innodb.result mysql-test/suite/parts/r/partition_bit_myisam.result mysql-test/suite/parts/r/partition_special_innodb.result mysql-test/suite/parts/t/disabled.def mysql-test/suite/parts/t/partition_special_innodb.test mysql-test/suite/parts/t/partition_value_innodb.test mysql-test/suite/parts/t/partition_value_myisam.test mysql-test/suite/parts/t/partition_value_ndb.test mysql-test/suite/rpl/r/rpl_auto_increment.result mysql-test/suite/rpl/r/rpl_packet.result mysql-test/suite/rpl/r/rpl_row_create_table.result mysql-test/suite/rpl/r/rpl_slave_skip.result mysql-test/suite/rpl/r/rpl_trigger.result mysql-test/suite/rpl/t/disabled.def mysql-test/suite/rpl/t/rpl_packet.test mysql-test/suite/rpl/t/rpl_row_create_table.test mysql-test/suite/rpl/t/rpl_slave_skip.test mysql-test/suite/rpl/t/rpl_trigger.test mysql-test/suite/rpl_ndb/t/disabled.def mysql-test/suite/sys_vars/inc/key_buffer_size_basic.inc mysql-test/suite/sys_vars/inc/sort_buffer_size_basic.inc mysql-test/suite/sys_vars/r/key_buffer_size_basic_32.result mysql-test/suite/sys_vars/r/key_buffer_size_basic_64.result mysql-test/suite/sys_vars/r/sort_buffer_size_basic_32.result mysql-test/suite/sys_vars/r/sort_buffer_size_basic_64.result mysql-test/t/alter_table.test mysql-test/t/create.test mysql-test/t/csv.test mysql-test/t/ctype_ucs.test mysql-test/t/date_formats.test mysql-test/t/disabled.def mysql-test/t/events_bugs.test mysql-test/t/events_scheduling.test mysql-test/t/fulltext.test mysql-test/t/func_if.test mysql-test/t/func_in.test mysql-test/t/func_str.test mysql-test/t/func_time.test mysql-test/t/grant.test mysql-test/t/information_schema.test mysql-test/t/innodb-autoinc.test mysql-test/t/innodb.test mysql-test/t/innodb_mysql.test mysql-test/t/log_bin_trust_function_creators_func.test mysql-test/t/log_state.test mysql-test/t/myisam_data_pointer_size_func.test mysql-test/t/myisampack.test mysql-test/t/mysql.test mysql-test/t/mysqlcheck.test mysql-test/t/partition_innodb_stmt.test mysql-test/t/partition_mgm.test mysql-test/t/partition_pruning.test mysql-test/t/query_cache.test mysql-test/t/rpl_init_slave_func.test mysql-test/t/select.test mysql-test/t/status.test mysql-test/t/strict.test mysql-test/t/temp_table.test mysql-test/t/type_bit.test mysql-test/t/type_date.test mysql-test/t/type_float.test mysql-test/t/warnings_engine_disabled.test mysql-test/t/xml.test mysys/my_getopt.c mysys/my_init.c scripts/mysql_install_db.sh sql-common/my_time.c sql/field.cc sql/field.h sql/filesort.cc sql/ha_partition.cc sql/ha_partition.h sql/item.cc sql/item_cmpfunc.cc sql/item_func.h sql/item_strfunc.cc sql/item_sum.cc sql/item_timefunc.cc sql/item_timefunc.h sql/log.cc sql/log.h sql/log_event.cc sql/log_event.h sql/mysql_priv.h sql/mysqld.cc sql/opt_range.cc sql/partition_info.cc sql/repl_failsafe.cc sql/rpl_constants.h sql/set_var.cc sql/slave.cc sql/spatial.h sql/sql_acl.cc sql/sql_base.cc sql/sql_binlog.cc sql/sql_class.h sql/sql_cursor.cc sql/sql_delete.cc sql/sql_lex.cc sql/sql_lex.h sql/sql_locale.cc sql/sql_parse.cc sql/sql_partition.cc sql/sql_plugin.cc sql/sql_plugin.h sql/sql_profile.cc sql/sql_repl.cc sql/sql_select.cc sql/sql_select.h sql/sql_show.cc sql/sql_table.cc sql/sql_trigger.cc sql/sql_trigger.h sql/table.cc sql/table.h sql/unireg.cc storage/csv/ha_tina.cc storage/federated/ha_federated.cc storage/heap/ha_heap.cc storage/innobase/Makefile.am storage/innobase/btr/btr0sea.c storage/innobase/buf/buf0lru.c storage/innobase/dict/dict0dict.c storage/innobase/dict/dict0mem.c storage/innobase/handler/ha_innodb.cc storage/innobase/handler/ha_innodb.h storage/innobase/include/btr0sea.h storage/innobase/include/dict0dict.h storage/innobase/include/dict0mem.h storage/innobase/include/ha_prototypes.h storage/innobase/include/lock0lock.h storage/innobase/include/row0mysql.h storage/innobase/include/sync0sync.ic storage/innobase/include/ut0ut.h storage/innobase/lock/lock0lock.c storage/innobase/os/os0file.c storage/innobase/plug.in storage/innobase/row/row0mysql.c storage/innobase/row/row0sel.c storage/innobase/srv/srv0srv.c storage/innobase/srv/srv0start.c storage/innobase/ut/ut0ut.c storage/myisam/ft_boolean_search.c strings/ctype.c strings/xml.c tests/mysql_client_test.c win/configure.js mysql-test/suite/funcs_1/t/is_coll_char_set_appl.test ------------------------------------------------------------------------ r4165 | calvin | 2009-02-12 01:34:27 +0200 (Thu, 12 Feb 2009) | 1 line Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: minor non-functional changes. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4263 | vasil | 2009-02-20 15:00:46 +0200 (Fri, 20 Feb 2009) | 4 lines branches/zip: Add a ChangeLog entry for a change in r4262. ------------------------------------------------------------------------ r4265 | marko | 2009-02-20 22:31:03 +0200 (Fri, 20 Feb 2009) | 5 lines branches/zip: Make innodb_use_sys_malloc=ON the default. Replace srv_use_sys_malloc with UNIV_LIKELY(srv_use_sys_malloc) to improve branch prediction in the default case. Approved by Ken over the IM. ------------------------------------------------------------------------ r4266 | vasil | 2009-02-20 23:29:32 +0200 (Fri, 20 Feb 2009) | 7 lines branches/zip: Add a sentence at the top of COPYING.Google to clarify that this license does not apply to the whole InnoDB. Suggested by: Ken ------------------------------------------------------------------------ r4268 | marko | 2009-02-23 12:43:51 +0200 (Mon, 23 Feb 2009) | 9 lines branches/zip: Initialize ut_list_mutex at startup. Without this fix, ut_list_mutex would be used uninitialized when innodb_use_sys_malloc=1. This fix addresses Issue #181. ut_mem_block_list_init(): Rename to ut_mem_init() and make public. ut_malloc_low(), ut_free_all_mem(): Add ut_a(ut_mem_block_list_inited). mem_init(): Call ut_mem_init(). ------------------------------------------------------------------------ r4269 | marko | 2009-02-23 15:09:49 +0200 (Mon, 23 Feb 2009) | 7 lines branches/zip: When freeing an uncompressed BLOB page, tolerate garbage in FIL_PAGE_TYPE. (Bug #43043, Issue #182) btr_check_blob_fil_page_type(): New function. btr_free_externally_stored_field(), btr_copy_blob_prefix(): Call btr_check_blob_fil_page_type() to check FIL_PAGE_TYPE. ------------------------------------------------------------------------ r4272 | marko | 2009-02-23 23:10:18 +0200 (Mon, 23 Feb 2009) | 8 lines branches/zip: Adjust the fix of Issue #182 in r4269 per Inaam's suggestion. btr_check_blob_fil_page_type(): Replace the parameter const char* op with ibool read. Do not print anything about page type mismatch when reading a BLOB page in Antelope format. Print space id before page number. ------------------------------------------------------------------------ r4273 | marko | 2009-02-24 00:11:11 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: ut_mem_init(): Add the assertion !ut_mem_block_list_inited. ------------------------------------------------------------------------ r4274 | marko | 2009-02-24 00:14:38 +0200 (Tue, 24 Feb 2009) | 12 lines branches/zip: Fix bugs in the fix of Issue #181. Tested inside and outside Valgrind, with innodb_use_sys_malloc set to 0 and 1. mem_init(): Invoke ut_mem_init() before mem_pool_create(), because the latter one will invoke ut_malloc(). srv_general_init(): Do not initialize the memory subsystem (mem_init()). innobase_init(): Initialize the memory subsystem (mem_init()) before calling srv_parse_data_file_paths_and_sizes(), which needs ut_malloc(). Call ut_free_all_mem() in error handling to clean up after the mem_init(). ------------------------------------------------------------------------ r4280 | marko | 2009-02-24 15:14:59 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: Remove unused function os_mem_alloc_nocache(). ------------------------------------------------------------------------ r4281 | marko | 2009-02-24 16:02:48 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: Remove the unused function dict_index_get_type(). ------------------------------------------------------------------------ r4283 | marko | 2009-02-24 23:06:56 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: srv0start.c: Remove unnecessary #include "mem0pool.h". ------------------------------------------------------------------------ r4284 | marko | 2009-02-24 23:26:38 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: mem0mem.c: Remove unnecessary #include "mach0data.h". ------------------------------------------------------------------------ r4288 | vasil | 2009-02-25 10:48:07 +0200 (Wed, 25 Feb 2009) | 21 lines branches/zip: Merge revisions 4261:4287 from branches/5.1: ------------------------------------------------------------------------ r4287 | sunny | 2009-02-25 05:32:01 +0200 (Wed, 25 Feb 2009) | 10 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Fix Bug#42714 AUTO_INCREMENT errors in 5.1.31. There are two changes to the autoinc handling. 1. To fix the immediate problem from the bug report, we must ensure that the value written to the table is always less than the max value stored in dict_table_t. 2. The second related change is that according to MySQL documentation when the offset is greater than the increment, we should ignore the offset. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4289 | vasil | 2009-02-25 10:53:51 +0200 (Wed, 25 Feb 2009) | 4 lines branches/zip: Add ChangeLog entry for the fix in r4288. ------------------------------------------------------------------------ r4290 | vasil | 2009-02-25 11:05:44 +0200 (Wed, 25 Feb 2009) | 11 lines branches/zip: Make ChangeLog entries for bugs in bugs.mysql.com in the form: Fix Bug#12345 bug title (for bugs after 1.0.2 was released and the ChangeLog published) There is no need to bloat the ChangeLog with information that is available via bugs.mysql.com. Discussed with: Marko ------------------------------------------------------------------------ r4291 | vasil | 2009-02-25 11:08:32 +0200 (Wed, 25 Feb 2009) | 4 lines branches/zip: Fix Bug synopsis and remove explanation ------------------------------------------------------------------------ r4292 | marko | 2009-02-25 12:09:15 +0200 (Wed, 25 Feb 2009) | 25 lines branches/zip: Correct the initialization of the memory subsystem once again, to finally put Issue #181 to rest. Revert some parts of r4274. It is best not to call ut_malloc() before srv_general_init(). mem_init(): Do not call ut_mem_init(). srv_general_init(): Initialize the memory subsystem in two phases: first ut_mem_init(), then mem_init(). This is because os_sync_init() and sync_init() depend on ut_mem_init() and mem_init() depends on os_sync_init() or sync_init(). srv_parse_data_file_paths_and_sizes(), srv_parse_log_group_home_dirs(): Remove the output parameters. Assign to the global variables directly. Allocate memory with malloc() instead of ut_malloc(), because these functions will be called before srv_general_init(). srv_free_paths_and_sizes(): New function, for cleaning up after srv_parse_data_file_paths_and_sizes() and srv_parse_log_group_home_dirs(). rb://92 approved by Sunny Bains ------------------------------------------------------------------------ r4297 | vasil | 2009-02-25 17:19:19 +0200 (Wed, 25 Feb 2009) | 4 lines branches/zip: White-space cleanup in the ChangeLog ------------------------------------------------------------------------ r4301 | vasil | 2009-02-25 21:33:32 +0200 (Wed, 25 Feb 2009) | 5 lines branches/zip: Do not output the commands that restore the environment because they depend on the state of the environment before the test starts executing. ------------------------------------------------------------------------ r4315 | vasil | 2009-02-26 09:21:20 +0200 (Thu, 26 Feb 2009) | 5 lines branches/zip: Apply any necessary patches to the mysql tree at the end of setup.sh This step was previously done manually (and sometimes forgotten). ------------------------------------------------------------------------ r4319 | marko | 2009-02-26 23:27:51 +0200 (Thu, 26 Feb 2009) | 6 lines branches/zip: btr_check_blob_fil_page_type(): Do not report FIL_PAGE_TYPE mismatch even when purging a BLOB. Heavy users may have large data files created with MySQL 5.0 or earlier, and they don not want to have the error log flooded with such messages. This fixes Issue #182. ------------------------------------------------------------------------ r4320 | inaam | 2009-02-27 02:13:19 +0200 (Fri, 27 Feb 2009) | 8 lines branches/zip This is to revert the changes made to the plug.in (r4251) as a fix for issue# 178. Changes to plug.in will not propogate to a plugin installation unless autotools are rerun which is unacceptable. A fix for issue# 178 will be committed in a separate commit. ------------------------------------------------------------------------ r4321 | inaam | 2009-02-27 02:16:46 +0200 (Fri, 27 Feb 2009) | 6 lines branches/zip This is a fix for issue#178. Instead of using UNIV_LINUX which is defined through CFLAGS we use compiler generated define __linux__ that is effective for both .c and .cc files. ------------------------------------------------------------------------ r4324 | vasil | 2009-02-27 13:27:18 +0200 (Fri, 27 Feb 2009) | 39 lines branches/zip: Add FreeBSD to the list of the operating systems that have sizeof(pthread_t) == sizeof(void*) (i.e. word size). On FreeBSD pthread_t is defined like: /usr/include/sys/_pthreadtypes.h: typedef struct pthread *pthread_t; I did the following tests (per Inaam's recommendation): a) appropriate version of GCC is available on that platform (4.1.2 or higher for atomics to be available) On FreeBSD 6.x the default compiler is 3.4.6, on FreeBSD 7.x the default one is 4.2.1. One can always install the version of choice from the ports collection. If gcc 3.x is used then HAVE_GCC_ATOMIC_BUILTINS will not be defined and thus the change I am committing will make no difference. b) find out if sizeof(pthread_t) == sizeof(long) On 32 bit both are 4 bytes, on 64 bit both are 8 bytes. c) find out the compiler generated platform define (e.g.: __aix, __sunos__ etc.) The macro is __FreeBSD__. d) patch univ.i with the appropriate platform define e) build the mysql f) ensure it is using atomic builtins (look at the err.log message at system startup. It should say we are using atomics for both mutexes and rw-locks) g) do sanity testing (keeping in view the smp changes) I ran the mysql-test suite. All tests pass. ------------------------------------------------------------------------ r4353 | vasil | 2009-03-05 09:27:29 +0200 (Thu, 05 Mar 2009) | 6 lines branches/zip: As suggested by Ken, print a message that says that the Google SMP patch (GCC atomics) is disabled if it is. Also extend the message when the patch is partially enabled to make it clear that it is partially enabled. ------------------------------------------------------------------------ r4356 | vasil | 2009-03-05 13:49:51 +0200 (Thu, 05 Mar 2009) | 4 lines branches/zip: Fix typo made in r4353. ------------------------------------------------------------------------ r4357 | vasil | 2009-03-05 16:38:59 +0200 (Thu, 05 Mar 2009) | 23 lines branches/zip: Implement a check whether pthread_t objects can be used by GCC atomic builtin functions. This check is implemented in plug.in and defines the macro HAVE_ATOMIC_PTHREAD_T. This macro is checked in univ.i and the relevant part of the code enabled (the one that uses GCC atomics against pthread_t objects). In addition to this, the same program that is compiled as part of the plug.in check is added in ut/ut0auxconf.c. In the InnoDB Plugin source archives that are shipped to the users, a generated Makefile.in is added. That Makefile.in will be modified to compile ut/ut0auxconf.c and define the macro HAVE_ATOMIC_PTHREAD_T if the compilation succeeds. I.e. Makefile.in will emulate the work that is done by plug.in. This is done in order to make the check happen and HAVE_ATOMIC_PTHREAD_T eventually defined without regenerating MySQL's ./configure from ./storage/innobase/plug.in. The point is not to ask users to install the autotools and regenerate ./configure. rb://95 Approved by: Marko ------------------------------------------------------------------------ r4360 | vasil | 2009-03-05 22:23:17 +0200 (Thu, 05 Mar 2009) | 21 lines branches/zip: Merge revisions 4287:4357 from branches/5.1: ------------------------------------------------------------------------ r4325 | sunny | 2009-03-02 02:28:52 +0200 (Mon, 02 Mar 2009) | 10 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Bug#43203: Overflow from auto incrementing causes server segv It was not a SIGSEGV but an assertion failure. The assertion was checking the invariant that *first_value passed in by MySQL doesn't contain a value that is greater than the max value for that type. The assertion has been changed to a check and if the value is greater than the max we report a generic AUTOINC failure. rb://93 Approved by Heikki ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4361 | vasil | 2009-03-05 22:27:54 +0200 (Thu, 05 Mar 2009) | 30 lines branches/zip: Merge revision 4358 from branches/5.1 (resolving a conflict): ------------------------------------------------------------------------ r4358 | vasil | 2009-03-05 21:21:10 +0200 (Thu, 05 Mar 2009) | 21 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: Merge a change from MySQL: ------------------------------------------------------------ revno: 2728.19.1 committer: Alfranio Correia <alfranio.correia@sun.com> branch nick: mysql-5.1-bugteam timestamp: Tue 2009-02-03 11:36:46 +0000 message: BUG#42445 Warning messages in innobase/handler/ha_innodb.cc There was a type casting problem in the storage/innobase/handler/ha_innodb.cc, (int ha_innobase::write_row(...)). Innobase uses has an internal error variable of type 'ulint' while mysql uses an 'int'. To fix the problem the function manipulates an error variable of type 'ulint' and only casts it into 'int' when needs to return the value. modified: storage/innobase/handler/ha_innodb.cc ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4362 | vasil | 2009-03-05 22:29:07 +0200 (Thu, 05 Mar 2009) | 23 lines branches/zip: Merge revision 4359 from branches/5.1: ------------------------------------------------------------------------ r4359 | vasil | 2009-03-05 21:42:01 +0200 (Thu, 05 Mar 2009) | 14 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: Merge a change from MySQL: ------------------------------------------------------------ revno: 2747 committer: Timothy Smith <timothy.smith@sun.com> branch nick: 51 timestamp: Fri 2009-01-16 17:49:07 +0100 message: Add another cast to ignore int/ulong difference in error types, silence warning on Win64 modified: storage/innobase/handler/ha_innodb.cc ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4363 | vasil | 2009-03-05 22:31:37 +0200 (Thu, 05 Mar 2009) | 4 lines branches/zip: Add ChangeLog entry for the bugfix in c4360. ------------------------------------------------------------------------ r4378 | calvin | 2009-03-09 10:10:17 +0200 (Mon, 09 Mar 2009) | 7 lines branches/zip: remove compile flag MYSQL_SERVER for dynamic plugin The dynamic plugin on Windows used to be built with MYSQL_SERVER compile flag, while it is not the case for other platforms. r3797 assumed MYSQL_SERVER was not defined for dynamic plugin, which introduced the engine crash during dropping a database. ------------------------------------------------------------------------ r4396 | marko | 2009-03-12 09:22:27 +0200 (Thu, 12 Mar 2009) | 3 lines branches/zip: btr_store_big_rec_extern_fields(): Initialize FIL_PAGE_TYPE in a separate redo log entry. This will make ibbackup --apply-log debugging easier. ------------------------------------------------------------------------ r4397 | marko | 2009-03-12 09:26:11 +0200 (Thu, 12 Mar 2009) | 3 lines branches/zip: trx_sys_create_doublewrite_buf(): As the dummy change, initialize FIL_PAGE_TYPE. This will make it easier to write the debug assertions for ibbackup --apply-log. ------------------------------------------------------------------------ r4401 | marko | 2009-03-12 10:26:40 +0200 (Thu, 12 Mar 2009) | 19 lines branches/zip: Merge revisions 4359:4400 from branches/5.1: ------------------------------------------------------------------------ r4399 | marko | 2009-03-12 09:38:05 +0200 (Thu, 12 Mar 2009) | 2 lines branches/5.1: row_sel_get_clust_rec_for_mysql(): Store the cursor position also for unlock_row(). (Bug #39320) ------------------------------------------------------------------------ r4400 | marko | 2009-03-12 10:06:44 +0200 (Thu, 12 Mar 2009) | 5 lines branches/5.1: Fix a bug in multi-table semi-consistent reads. Remember the acquired record locks per table handle (row_prebuilt_t) rather than per transaction (trx_t), so that unlock_row should successfully unlock all non-matching rows in multi-table operations. This deficiency was found while investigating Bug #39320. ------------------------------------------------------------------------ These were submitted as rb://94 and rb://96 and approved by Heikki Tuuri. ------------------------------------------------------------------------ r4455 | marko | 2009-03-16 11:43:34 +0200 (Mon, 16 Mar 2009) | 2 lines branches/zip: UT_LIST_VALIDATE(): Add the parameter ASSERTION and adjust all callers. ------------------------------------------------------------------------ r4456 | marko | 2009-03-16 12:59:25 +0200 (Mon, 16 Mar 2009) | 6 lines branches/zip: UT_LIST_VALIDATE(): Assert that the link is non-NULL before dereferencing it. In this way, ut_list_node_313 will be pointing to the last non-NULL list item at the time of the assertion failure. (gcc-4.3.2 -O3 seems to optimize the common subexpressions and make the variable NULL, though.) ------------------------------------------------------------------------ r4457 | marko | 2009-03-16 14:12:02 +0200 (Mon, 16 Mar 2009) | 2 lines branches/zip: sync_thread_add_level(): Make the assertions about level == SYNC_BUF_BLOCK more readable. ------------------------------------------------------------------------ r4461 | vasil | 2009-03-17 09:38:19 +0200 (Tue, 17 Mar 2009) | 6 lines branches/zip: Remove mysql-test/patches/bug32625.diff because that bug was fixed in the mysql repository (1 year and 4 months after sending them the simple patch!). See http://bugs.mysql.com/32625 ------------------------------------------------------------------------ r4465 | marko | 2009-03-17 12:34:19 +0200 (Tue, 17 Mar 2009) | 1 line branches/zip: buf0buddy.c: Add and adjust some debug assertions. ------------------------------------------------------------------------ r4473 | vasil | 2009-03-17 15:50:30 +0200 (Tue, 17 Mar 2009) | 5 lines branches/zip: Increment the InnoDB Plugin version from 1.0.3 to 1.0.4 now that 1.0.3 has been released. ------------------------------------------------------------------------ r4478 | vasil | 2009-03-18 11:53:53 +0200 (Wed, 18 Mar 2009) | 5 lines branches/zip: Remove mysql-test/patches/bug41893.diff because that bug has been fixed in the MySQL repository, see http://bugs.mysql.com/41893. ------------------------------------------------------------------------ r4479 | marko | 2009-03-18 12:43:54 +0200 (Wed, 18 Mar 2009) | 2 lines branches/zip: buf_LRU_block_remove_hashed_page(): Add some debug assertions. ------------------------------------------------------------------------ r4480 | marko | 2009-03-18 14:32:13 +0200 (Wed, 18 Mar 2009) | 1 line branches/zip: buf_buddy_free_low(): Correct the function comment. ------------------------------------------------------------------------ r4482 | marko | 2009-03-19 15:23:32 +0200 (Thu, 19 Mar 2009) | 12 lines branches/zip: Merge revisions 4400:4481 from branches/5.1: ------------------------------------------------------------------------ r4481 | marko | 2009-03-19 15:01:48 +0200 (Thu, 19 Mar 2009) | 6 lines branches/5.1: row_unlock_for_mysql(): Do not unlock records that were modified by the current transaction. This bug was introduced or unmasked in r4400. rb://97 approved by Heikki Tuuri ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4490 | marko | 2009-03-20 12:33:33 +0200 (Fri, 20 Mar 2009) | 4 lines branches/zip: Non-functional change for reducing dependencies in InnoDB Hot Backup: Replace srv_sys->dummy_ind1 and srv_sys->dummy_ind2 with dict_ind_redundant and dict_ind_compact, initialized in dict_init(). ------------------------------------------------------------------------ r4491 | marko | 2009-03-20 12:45:18 +0200 (Fri, 20 Mar 2009) | 2 lines branches/zip: Add const qualifiers or in/out comments to some function parameters in log0log. ------------------------------------------------------------------------ r4492 | marko | 2009-03-20 12:52:14 +0200 (Fri, 20 Mar 2009) | 5 lines branches/zip: page_validate(): Always report the space id and the name of the index. In Hot Backup, do not invoke comparison functions, as MySQL collations will be unavailable. ------------------------------------------------------------------------ r4493 | marko | 2009-03-20 13:24:06 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: Replace fil_get_space_for_id_low() with fil_space_get_by_id(). ------------------------------------------------------------------------ r4494 | marko | 2009-03-20 13:51:35 +0200 (Fri, 20 Mar 2009) | 3 lines branches/zip: fil0fil.c: Refer to fil_system directly, not via local vars. This eliminates some "unused variable" warnings when building InnoDB Hot Backup in such a way that all mutex operations are no-ops. ------------------------------------------------------------------------ r4495 | marko | 2009-03-20 14:15:52 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: innobase_get_at_most_n_mbchars(): Declare in ha_prototypes.h. ------------------------------------------------------------------------ r4496 | marko | 2009-03-20 14:48:26 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: recv_recover_page(): Remove compile-time constant parameters. ------------------------------------------------------------------------ r4497 | marko | 2009-03-20 14:56:19 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: recv_sys_init(): Remove a compile-time constant parameter. ------------------------------------------------------------------------ r4498 | marko | 2009-03-20 15:08:05 +0200 (Fri, 20 Mar 2009) | 4 lines branches/zip: Non-functional change: Add const qualifiers. log_block_checksum_is_ok_or_old_format(), recv_sys_add_to_parsing_buf(): The log block is read-only. Make it const. ------------------------------------------------------------------------ r4499 | marko | 2009-03-20 15:10:25 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: recv_scan_log_recs(): Remove a compile-time constant parameter. ------------------------------------------------------------------------ r4500 | marko | 2009-03-20 15:47:17 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: fil_init(): Add the parameter hash_size. ------------------------------------------------------------------------ r4501 | vasil | 2009-03-20 16:50:41 +0200 (Fri, 20 Mar 2009) | 4 lines branches/zip: Add any entry about the release of 1.0.3 in the ChangeLog. ------------------------------------------------------------------------ r4515 | marko | 2009-03-23 10:49:53 +0200 (Mon, 23 Mar 2009) | 1 line branches/zip: hash_table_t: adaptive: Remove from UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4516 | marko | 2009-03-23 10:57:16 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Define and use ASSERT_HASH_MUTEX_OWN. Make it a no-op in UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4517 | marko | 2009-03-23 11:07:20 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Define and use PAGE_ZIP_MATCH. In UNIV_HOTBACKUP builds, assume fixed allocation. ------------------------------------------------------------------------ r4521 | marko | 2009-03-23 12:05:47 +0200 (Mon, 23 Mar 2009) | 1 line branches/zip: buf_page_print(): Clean up the code #ifdef UNIV_HOTBACKUP. ------------------------------------------------------------------------ r4522 | marko | 2009-03-23 12:20:50 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Exclude some operating system interface code from UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4523 | marko | 2009-03-23 13:00:43 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Remove the remaining references to hash_table_t::adapive from UNIV_HOTBACKUP builds. This should have been done in r4515. ------------------------------------------------------------------------ r4524 | marko | 2009-03-23 14:05:18 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Enclose recv_recovery_from_backup_on and recv_recovery_from_backup_is_on() in #ifdef UNIV_LOG_ARCHIVE. ------------------------------------------------------------------------ r4525 | marko | 2009-03-23 14:57:45 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: recv_parse_or_apply_log_rec_body(): Add debug assertions ensuring that FIL_PAGE_TYPE makes sense when applying log records. ------------------------------------------------------------------------ r4526 | marko | 2009-03-23 16:21:34 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Remove unneeded definitions and dependencies from UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4527 | calvin | 2009-03-23 23:15:33 +0200 (Mon, 23 Mar 2009) | 5 lines branches/zip: adjust build files on Windows Adjust the patch positions based on the latest MySQL source. Also add the patches to the .bat files for vs9. ------------------------------------------------------------------------
17 years ago
branches/innodb+: Merge revisions 4150:4528 from branches/zip: ------------------------------------------------------------------------ r4152 | marko | 2009-02-10 12:52:27 +0200 (Tue, 10 Feb 2009) | 12 lines branches/zip: When innodb_use_sys_malloc is set, ignore innodb_additional_mem_pool_size, because nothing will be allocated from mem_comm_pool. mem_pool_create(): Remove the assertion about size. The function will work with any size. However, an assertion would fail in ut_malloc_low() when size==0. mem_init(): When srv_use_sys_malloc is set, pass size=1 to mem_pool_create(). mem0mem.c: Add #include "srv0srv.h" that is needed by mem0dbg.c. ------------------------------------------------------------------------ r4153 | vasil | 2009-02-10 22:58:17 +0200 (Tue, 10 Feb 2009) | 14 lines branches/zip: (followup to r4145) Non-functional change: Change the os_atomic_increment() and os_compare_and_swap() functions to macros to avoid artificial limitations on the types of those functions' arguments. As a consequence typecasts from the source code can be removed. Also remove Google's copyright from os0sync.ic because that file no longer contains code from Google. Approved by: Marko (rb://88), also ok from Inaam via IM ------------------------------------------------------------------------ r4163 | marko | 2009-02-12 00:14:19 +0200 (Thu, 12 Feb 2009) | 4 lines branches/zip: Make innodb_thread_concurrency=0 the default. The old default was 8. ------------------------------------------------------------------------ r4169 | calvin | 2009-02-12 10:37:10 +0200 (Thu, 12 Feb 2009) | 3 lines branches/zip: Adjust the result file of innodb_thread_concurrency_basic test. The default value of innodb_thread_concurrency is changed to 0 (from 8) via r4163. ------------------------------------------------------------------------ r4174 | vasil | 2009-02-12 17:38:27 +0200 (Thu, 12 Feb 2009) | 4 lines branches/zip: Fix pathname of the file to patch. ------------------------------------------------------------------------ r4176 | vasil | 2009-02-13 10:06:31 +0200 (Fri, 13 Feb 2009) | 7 lines branches/zip: Fix the failing mysql-test partition_innodb, which failed only if run after innodb_trx_weight (or other test that would leave LATEST DEADLOCK ERROR into the output of SHOW ENGINE INNODB STATUS). Find further explanation for the failure at the top of the added patch partition_innodb.diff. ------------------------------------------------------------------------ r4198 | vasil | 2009-02-17 09:06:07 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: Add the full text of the GPLv2 license into the root directory of the plugin. In previous releases this file was copied from an external source (https://svn.innodb.com/svn/plugin/trunk/support/COPYING) "manually" when creating the source and binary archives. It is less confusing to have this present in the root directory of the SVN branch. ------------------------------------------------------------------------ r4199 | vasil | 2009-02-17 09:11:58 +0200 (Tue, 17 Feb 2009) | 4 lines branches/zip: Add Google's license into COPYING.Google. ------------------------------------------------------------------------ r4200 | vasil | 2009-02-17 09:56:33 +0200 (Tue, 17 Feb 2009) | 11 lines branches/zip: To the files touched by the Google patch from c4144 (excluding include/os0sync.ic because later we removed Google code from that file): * Remove the Google license * Remove old Innobase copyright lines * Add a reference to the Google license and to the GPLv2 license at the top, as recommended by the lawyers at Oracle Legal. ------------------------------------------------------------------------ r4201 | vasil | 2009-02-17 10:12:02 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 1/28] ------------------------------------------------------------------------ r4202 | vasil | 2009-02-17 10:15:06 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 2/28] ------------------------------------------------------------------------ r4203 | vasil | 2009-02-17 10:25:45 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 3/28] ------------------------------------------------------------------------ r4204 | vasil | 2009-02-17 10:55:41 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 4/28] ------------------------------------------------------------------------ r4205 | vasil | 2009-02-17 10:59:22 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 5/28] ------------------------------------------------------------------------ r4206 | vasil | 2009-02-17 11:02:27 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 6/28] ------------------------------------------------------------------------ r4207 | vasil | 2009-02-17 11:04:28 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 7/28] ------------------------------------------------------------------------ r4208 | vasil | 2009-02-17 11:06:49 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 8/28] ------------------------------------------------------------------------ r4209 | vasil | 2009-02-17 11:10:18 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 9/28] ------------------------------------------------------------------------ r4210 | vasil | 2009-02-17 11:12:41 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 10/28] ------------------------------------------------------------------------ r4211 | vasil | 2009-02-17 11:14:40 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 11/28] ------------------------------------------------------------------------ r4212 | vasil | 2009-02-17 11:18:35 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 12/28] ------------------------------------------------------------------------ r4213 | vasil | 2009-02-17 11:24:40 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 13/28] ------------------------------------------------------------------------ r4214 | vasil | 2009-02-17 11:27:31 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 13/28] ------------------------------------------------------------------------ r4215 | vasil | 2009-02-17 11:29:55 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 15/28] ------------------------------------------------------------------------ r4216 | vasil | 2009-02-17 11:33:38 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 16/28] ------------------------------------------------------------------------ r4217 | vasil | 2009-02-17 11:36:44 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 17/28] ------------------------------------------------------------------------ r4218 | vasil | 2009-02-17 11:39:11 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 18/28] ------------------------------------------------------------------------ r4219 | vasil | 2009-02-17 11:41:24 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 19/28] ------------------------------------------------------------------------ r4220 | vasil | 2009-02-17 11:43:50 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 20/28] ------------------------------------------------------------------------ r4221 | vasil | 2009-02-17 11:46:52 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 21/28] ------------------------------------------------------------------------ r4222 | vasil | 2009-02-17 11:50:12 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 22/28] ------------------------------------------------------------------------ r4223 | vasil | 2009-02-17 11:53:58 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 23/28] ------------------------------------------------------------------------ r4224 | vasil | 2009-02-17 12:01:41 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 24/28] ------------------------------------------------------------------------ r4225 | vasil | 2009-02-17 12:05:45 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 25/28] ------------------------------------------------------------------------ r4226 | vasil | 2009-02-17 12:09:16 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 26/28] ------------------------------------------------------------------------ r4227 | vasil | 2009-02-17 12:12:56 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 27/28] ------------------------------------------------------------------------ r4228 | vasil | 2009-02-17 12:14:04 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 28/28] ------------------------------------------------------------------------ r4229 | vasil | 2009-02-17 12:30:55 +0200 (Tue, 17 Feb 2009) | 4 lines branches/zip: Add the copyright notice to the non C files. ------------------------------------------------------------------------ r4231 | marko | 2009-02-17 14:26:53 +0200 (Tue, 17 Feb 2009) | 12 lines Minor cleanup of the Google SMP patch. sync_array_object_signalled(): Add a (void) cast to eliminate a gcc warning about the return value of os_atomic_increment() being ignored. rw_lock_create_func(): Properly indent the preprocessor directives. rw_lock_x_lock_low(), rw_lock_x_lock_func_nowait(): Split lines correctly. rw_lock_set_writer_id_and_recursion_flag(): Silence a Valgrind warning. Do not mix statements and variable declarations. ------------------------------------------------------------------------ r4232 | marko | 2009-02-17 14:59:54 +0200 (Tue, 17 Feb 2009) | 3 lines branches/zip: When assigning lock->recursive = FALSE, also flag lock->writer_thread invalid, so that Valgrind will catch more errors. This is related to Issue #175. ------------------------------------------------------------------------ r4242 | marko | 2009-02-18 17:01:09 +0200 (Wed, 18 Feb 2009) | 2 lines branches/zip: UT_DBG_STOP: Use do{} while(0) to silence a g++-4.3.2 warning about a while(0); statement. This should fix (part of) Issue #176. ------------------------------------------------------------------------ r4243 | marko | 2009-02-18 17:04:03 +0200 (Wed, 18 Feb 2009) | 3 lines branches/zip: buf_buddy_get_slot(): Fix a gcc 4.3.2 warning about an empty body of a "for" statement. This fixes part of Issue #176. ------------------------------------------------------------------------ r4244 | marko | 2009-02-18 17:25:45 +0200 (Wed, 18 Feb 2009) | 11 lines branches/zip: Protect ut_total_allocated_memory with ut_list_mutex. Unprotected updates to ut_total_allocated_memory in os_mem_alloc_large() and os_mem_free_large(), called during fast index creation, may corrupt the variable and cause assertion failures. Also, add UNIV_MEM_ALLOC() and UNIV_MEM_FREE() instrumentation around os_mem_alloc_large() and os_mem_free_large(), so that Valgrind can detect more errors. rb://90 approved by Heikki Tuuri. This addresses Issue #177. ------------------------------------------------------------------------ r4248 | marko | 2009-02-19 11:52:39 +0200 (Thu, 19 Feb 2009) | 2 lines branches/zip: page_zip_set_size(): Fix a g++ 4.3.2 warning about an empty body in a "for" statement. This closes Issue #176. ------------------------------------------------------------------------ r4251 | inaam | 2009-02-19 15:46:27 +0200 (Thu, 19 Feb 2009) | 8 lines branches/zip: Issue #178 rb://91 Change plug.in to have same CXXFLAGS as CFLAGS. This is to ensure that both .c and .cc files get compiled with same flags. To fix the issue where UNIV_LINUX was defined only in .c files. Approved by: Marko ------------------------------------------------------------------------ r4258 | vasil | 2009-02-20 11:52:19 +0200 (Fri, 20 Feb 2009) | 7 lines branches/zip: Cleanup in ChangeLog: * Wrap lines at 78 characters * Changed files are listed alphabetically * White-space cleanup ------------------------------------------------------------------------ r4259 | vasil | 2009-02-20 11:59:42 +0200 (Fri, 20 Feb 2009) | 6 lines branches/zip: ChangeLog: Remove include/os0sync.ic from the entry about the google patch, this file was modified later to not include Google's code. ------------------------------------------------------------------------ r4262 | vasil | 2009-02-20 14:56:59 +0200 (Fri, 20 Feb 2009) | 373 lines branches/zip: Merge revisions 4035:4261 from branches/5.1: ------------------------------------------------------------------------ r4065 | sunny | 2009-01-29 16:01:36 +0200 (Thu, 29 Jan 2009) | 8 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: In the last round of AUTOINC cleanup we assumed that AUTOINC is only defined for integer columns. This caused an assertion failure when we checked for the maximum value of a column type. We now calculate the max value for floating-point autoinc columns too. Fix Bug#42400 - InnoDB autoinc code can't handle floating-point columns rb://84 and Mantis issue://162 ------------------------------------------------------------------------ r4111 | sunny | 2009-02-03 22:06:52 +0200 (Tue, 03 Feb 2009) | 2 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: Add the ULL suffix otherwise there is an overflow. ------------------------------------------------------------------------ r4128 | vasil | 2009-02-08 21:36:45 +0200 (Sun, 08 Feb 2009) | 18 lines Changed paths: M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Merge a change from MySQL: ------------------------------------------------------------ revno: 2709.20.31 committer: Timothy Smith <timothy.smith@sun.com> branch nick: 51 timestamp: Fri 2008-12-19 01:28:51 +0100 message: Disable part of innodb-autoinc.test, because the MySQL server asserts when compiled --with-debug, due to bug 39828, "autoinc wraps around when offset and increment > 1". This change should be reverted when that bug is fixed (and a a few other minor changes to the test as described in comments). modified: mysql-test/r/innodb-autoinc.result mysql-test/t/innodb-autoinc.test ------------------------------------------------------------------------ r4129 | vasil | 2009-02-08 21:54:25 +0200 (Sun, 08 Feb 2009) | 310 lines Changed paths: M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Merge a change from MySQL: [looks like the changes to innodb-autoinc.test were made as part of the following huge merge, but we are merging only changes to that file] ------------------------------------------------------------ revno: 2546.47.1 committer: Luis Soares <luis.soares@sun.com> branch nick: 5.1-rpl timestamp: Fri 2009-01-23 13:22:05 +0100 message: merge: 5.1 -> 5.1-rpl conflicts: Text conflict in client/mysqltest.cc Text conflict in mysql-test/include/wait_until_connected_again.inc Text conflict in mysql-test/lib/mtr_report.pm Text conflict in mysql-test/mysql-test-run.pl Text conflict in mysql-test/r/events_bugs.result Text conflict in mysql-test/r/log_state.result Text conflict in mysql-test/r/myisam_data_pointer_size_func.result Text conflict in mysql-test/r/mysqlcheck.result Text conflict in mysql-test/r/query_cache.result Text conflict in mysql-test/r/status.result Text conflict in mysql-test/suite/binlog/r/binlog_index.result Text conflict in mysql-test/suite/binlog/r/binlog_innodb.result Text conflict in mysql-test/suite/rpl/r/rpl_packet.result Text conflict in mysql-test/suite/rpl/t/rpl_packet.test Text conflict in mysql-test/t/disabled.def Text conflict in mysql-test/t/events_bugs.test Text conflict in mysql-test/t/log_state.test Text conflict in mysql-test/t/myisam_data_pointer_size_func.test Text conflict in mysql-test/t/mysqlcheck.test Text conflict in mysql-test/t/query_cache.test Text conflict in mysql-test/t/rpl_init_slave_func.test Text conflict in mysql-test/t/status.test removed: mysql-test/suite/parts/r/partition_bit_ndb.result mysql-test/suite/parts/t/partition_bit_ndb.test mysql-test/suite/parts/t/partition_sessions.test mysql-test/suite/sys_vars/inc/tmp_table_size_basic.inc mysql-test/suite/sys_vars/r/tmp_table_size_basic_32.result mysql-test/suite/sys_vars/r/tmp_table_size_basic_64.result mysql-test/suite/sys_vars/t/tmp_table_size_basic_32.test mysql-test/suite/sys_vars/t/tmp_table_size_basic_64.test mysql-test/t/log_bin_trust_function_creators_func-master.opt mysql-test/t/rpl_init_slave_func-slave.opt added: mysql-test/include/check_events_off.inc mysql-test/include/cleanup_fake_relay_log.inc mysql-test/include/have_simple_parser.inc mysql-test/include/no_running_event_scheduler.inc mysql-test/include/no_running_events.inc mysql-test/include/running_event_scheduler.inc mysql-test/include/setup_fake_relay_log.inc mysql-test/include/wait_condition_sp.inc mysql-test/r/fulltext_plugin.result mysql-test/r/have_simple_parser.require mysql-test/r/innodb_bug38231.result mysql-test/r/innodb_bug39438.result mysql-test/r/innodb_mysql_rbk.result mysql-test/r/partition_innodb_semi_consistent.result mysql-test/r/query_cache_28249.result mysql-test/r/status2.result mysql-test/std_data/bug40482-bin.000001 mysql-test/suite/binlog/r/binlog_innodb_row.result mysql-test/suite/binlog/t/binlog_innodb_row.test mysql-test/suite/rpl/r/rpl_binlog_corruption.result mysql-test/suite/rpl/t/rpl_binlog_corruption-master.opt mysql-test/suite/rpl/t/rpl_binlog_corruption.test mysql-test/suite/sys_vars/r/tmp_table_size_basic.result mysql-test/suite/sys_vars/t/tmp_table_size_basic.test mysql-test/t/fulltext_plugin-master.opt mysql-test/t/fulltext_plugin.test mysql-test/t/innodb_bug38231.test mysql-test/t/innodb_bug39438-master.opt mysql-test/t/innodb_bug39438.test mysql-test/t/innodb_mysql_rbk-master.opt mysql-test/t/innodb_mysql_rbk.test mysql-test/t/partition_innodb_semi_consistent-master.opt mysql-test/t/partition_innodb_semi_consistent.test mysql-test/t/query_cache_28249.test mysql-test/t/status2.test renamed: mysql-test/suite/funcs_1/r/is_collation_character_set_applicability.result => mysql-test/suite/funcs_1/r/is_coll_char_set_appl.result mysql-test/suite/funcs_1/t/is_collation_character_set_applicability.test => mysql-test/suite/funcs_1/t/is_coll_char_set_appl.test modified: .bzr-mysql/default.conf CMakeLists.txt client/mysql.cc client/mysql_upgrade.c client/mysqlcheck.c client/mysqltest.cc configure.in extra/resolve_stack_dump.c extra/yassl/include/openssl/ssl.h include/config-win.h include/m_ctype.h include/my_global.h mysql-test/extra/binlog_tests/database.test mysql-test/extra/rpl_tests/rpl_auto_increment.test mysql-test/include/commit.inc mysql-test/include/have_32bit.inc mysql-test/include/have_64bit.inc mysql-test/include/index_merge1.inc mysql-test/include/linux_sys_vars.inc mysql-test/include/windows_sys_vars.inc mysql-test/lib/mtr_report.pm mysql-test/mysql-test-run.pl mysql-test/r/alter_table.result mysql-test/r/commit_1innodb.result mysql-test/r/create.result mysql-test/r/csv.result mysql-test/r/ctype_ucs.result mysql-test/r/date_formats.result mysql-test/r/events_bugs.result mysql-test/r/events_scheduling.result mysql-test/r/fulltext.result mysql-test/r/func_if.result mysql-test/r/func_in.result mysql-test/r/func_str.result mysql-test/r/func_time.result mysql-test/r/grant.result mysql-test/r/index_merge_myisam.result mysql-test/r/information_schema.result mysql-test/r/innodb-autoinc.result mysql-test/r/innodb.result mysql-test/r/innodb_mysql.result mysql-test/r/log_bin_trust_function_creators_func.result mysql-test/r/log_state.result mysql-test/r/myisampack.result mysql-test/r/mysql.result mysql-test/r/mysqlcheck.result mysql-test/r/partition_datatype.result mysql-test/r/partition_mgm.result mysql-test/r/partition_pruning.result mysql-test/r/query_cache.result mysql-test/r/read_buffer_size_basic.result mysql-test/r/read_rnd_buffer_size_basic.result mysql-test/r/rpl_init_slave_func.result mysql-test/r/select.result mysql-test/r/status.result mysql-test/r/strict.result mysql-test/r/temp_table.result mysql-test/r/type_bit.result mysql-test/r/type_date.result mysql-test/r/type_float.result mysql-test/r/warnings_engine_disabled.result mysql-test/r/xml.result mysql-test/suite/binlog/r/binlog_database.result mysql-test/suite/binlog/r/binlog_index.result mysql-test/suite/binlog/r/binlog_innodb.result mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result mysql-test/suite/binlog/t/binlog_innodb.test mysql-test/suite/funcs_1/r/is_columns_is.result mysql-test/suite/funcs_1/r/is_engines.result mysql-test/suite/funcs_1/r/storedproc.result mysql-test/suite/funcs_1/storedproc/param_check.inc mysql-test/suite/funcs_2/t/disabled.def mysql-test/suite/ndb/t/disabled.def mysql-test/suite/parts/r/partition_bit_innodb.result mysql-test/suite/parts/r/partition_bit_myisam.result mysql-test/suite/parts/r/partition_special_innodb.result mysql-test/suite/parts/t/disabled.def mysql-test/suite/parts/t/partition_special_innodb.test mysql-test/suite/parts/t/partition_value_innodb.test mysql-test/suite/parts/t/partition_value_myisam.test mysql-test/suite/parts/t/partition_value_ndb.test mysql-test/suite/rpl/r/rpl_auto_increment.result mysql-test/suite/rpl/r/rpl_packet.result mysql-test/suite/rpl/r/rpl_row_create_table.result mysql-test/suite/rpl/r/rpl_slave_skip.result mysql-test/suite/rpl/r/rpl_trigger.result mysql-test/suite/rpl/t/disabled.def mysql-test/suite/rpl/t/rpl_packet.test mysql-test/suite/rpl/t/rpl_row_create_table.test mysql-test/suite/rpl/t/rpl_slave_skip.test mysql-test/suite/rpl/t/rpl_trigger.test mysql-test/suite/rpl_ndb/t/disabled.def mysql-test/suite/sys_vars/inc/key_buffer_size_basic.inc mysql-test/suite/sys_vars/inc/sort_buffer_size_basic.inc mysql-test/suite/sys_vars/r/key_buffer_size_basic_32.result mysql-test/suite/sys_vars/r/key_buffer_size_basic_64.result mysql-test/suite/sys_vars/r/sort_buffer_size_basic_32.result mysql-test/suite/sys_vars/r/sort_buffer_size_basic_64.result mysql-test/t/alter_table.test mysql-test/t/create.test mysql-test/t/csv.test mysql-test/t/ctype_ucs.test mysql-test/t/date_formats.test mysql-test/t/disabled.def mysql-test/t/events_bugs.test mysql-test/t/events_scheduling.test mysql-test/t/fulltext.test mysql-test/t/func_if.test mysql-test/t/func_in.test mysql-test/t/func_str.test mysql-test/t/func_time.test mysql-test/t/grant.test mysql-test/t/information_schema.test mysql-test/t/innodb-autoinc.test mysql-test/t/innodb.test mysql-test/t/innodb_mysql.test mysql-test/t/log_bin_trust_function_creators_func.test mysql-test/t/log_state.test mysql-test/t/myisam_data_pointer_size_func.test mysql-test/t/myisampack.test mysql-test/t/mysql.test mysql-test/t/mysqlcheck.test mysql-test/t/partition_innodb_stmt.test mysql-test/t/partition_mgm.test mysql-test/t/partition_pruning.test mysql-test/t/query_cache.test mysql-test/t/rpl_init_slave_func.test mysql-test/t/select.test mysql-test/t/status.test mysql-test/t/strict.test mysql-test/t/temp_table.test mysql-test/t/type_bit.test mysql-test/t/type_date.test mysql-test/t/type_float.test mysql-test/t/warnings_engine_disabled.test mysql-test/t/xml.test mysys/my_getopt.c mysys/my_init.c scripts/mysql_install_db.sh sql-common/my_time.c sql/field.cc sql/field.h sql/filesort.cc sql/ha_partition.cc sql/ha_partition.h sql/item.cc sql/item_cmpfunc.cc sql/item_func.h sql/item_strfunc.cc sql/item_sum.cc sql/item_timefunc.cc sql/item_timefunc.h sql/log.cc sql/log.h sql/log_event.cc sql/log_event.h sql/mysql_priv.h sql/mysqld.cc sql/opt_range.cc sql/partition_info.cc sql/repl_failsafe.cc sql/rpl_constants.h sql/set_var.cc sql/slave.cc sql/spatial.h sql/sql_acl.cc sql/sql_base.cc sql/sql_binlog.cc sql/sql_class.h sql/sql_cursor.cc sql/sql_delete.cc sql/sql_lex.cc sql/sql_lex.h sql/sql_locale.cc sql/sql_parse.cc sql/sql_partition.cc sql/sql_plugin.cc sql/sql_plugin.h sql/sql_profile.cc sql/sql_repl.cc sql/sql_select.cc sql/sql_select.h sql/sql_show.cc sql/sql_table.cc sql/sql_trigger.cc sql/sql_trigger.h sql/table.cc sql/table.h sql/unireg.cc storage/csv/ha_tina.cc storage/federated/ha_federated.cc storage/heap/ha_heap.cc storage/innobase/Makefile.am storage/innobase/btr/btr0sea.c storage/innobase/buf/buf0lru.c storage/innobase/dict/dict0dict.c storage/innobase/dict/dict0mem.c storage/innobase/handler/ha_innodb.cc storage/innobase/handler/ha_innodb.h storage/innobase/include/btr0sea.h storage/innobase/include/dict0dict.h storage/innobase/include/dict0mem.h storage/innobase/include/ha_prototypes.h storage/innobase/include/lock0lock.h storage/innobase/include/row0mysql.h storage/innobase/include/sync0sync.ic storage/innobase/include/ut0ut.h storage/innobase/lock/lock0lock.c storage/innobase/os/os0file.c storage/innobase/plug.in storage/innobase/row/row0mysql.c storage/innobase/row/row0sel.c storage/innobase/srv/srv0srv.c storage/innobase/srv/srv0start.c storage/innobase/ut/ut0ut.c storage/myisam/ft_boolean_search.c strings/ctype.c strings/xml.c tests/mysql_client_test.c win/configure.js mysql-test/suite/funcs_1/t/is_coll_char_set_appl.test ------------------------------------------------------------------------ r4165 | calvin | 2009-02-12 01:34:27 +0200 (Thu, 12 Feb 2009) | 1 line Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: minor non-functional changes. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4263 | vasil | 2009-02-20 15:00:46 +0200 (Fri, 20 Feb 2009) | 4 lines branches/zip: Add a ChangeLog entry for a change in r4262. ------------------------------------------------------------------------ r4265 | marko | 2009-02-20 22:31:03 +0200 (Fri, 20 Feb 2009) | 5 lines branches/zip: Make innodb_use_sys_malloc=ON the default. Replace srv_use_sys_malloc with UNIV_LIKELY(srv_use_sys_malloc) to improve branch prediction in the default case. Approved by Ken over the IM. ------------------------------------------------------------------------ r4266 | vasil | 2009-02-20 23:29:32 +0200 (Fri, 20 Feb 2009) | 7 lines branches/zip: Add a sentence at the top of COPYING.Google to clarify that this license does not apply to the whole InnoDB. Suggested by: Ken ------------------------------------------------------------------------ r4268 | marko | 2009-02-23 12:43:51 +0200 (Mon, 23 Feb 2009) | 9 lines branches/zip: Initialize ut_list_mutex at startup. Without this fix, ut_list_mutex would be used uninitialized when innodb_use_sys_malloc=1. This fix addresses Issue #181. ut_mem_block_list_init(): Rename to ut_mem_init() and make public. ut_malloc_low(), ut_free_all_mem(): Add ut_a(ut_mem_block_list_inited). mem_init(): Call ut_mem_init(). ------------------------------------------------------------------------ r4269 | marko | 2009-02-23 15:09:49 +0200 (Mon, 23 Feb 2009) | 7 lines branches/zip: When freeing an uncompressed BLOB page, tolerate garbage in FIL_PAGE_TYPE. (Bug #43043, Issue #182) btr_check_blob_fil_page_type(): New function. btr_free_externally_stored_field(), btr_copy_blob_prefix(): Call btr_check_blob_fil_page_type() to check FIL_PAGE_TYPE. ------------------------------------------------------------------------ r4272 | marko | 2009-02-23 23:10:18 +0200 (Mon, 23 Feb 2009) | 8 lines branches/zip: Adjust the fix of Issue #182 in r4269 per Inaam's suggestion. btr_check_blob_fil_page_type(): Replace the parameter const char* op with ibool read. Do not print anything about page type mismatch when reading a BLOB page in Antelope format. Print space id before page number. ------------------------------------------------------------------------ r4273 | marko | 2009-02-24 00:11:11 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: ut_mem_init(): Add the assertion !ut_mem_block_list_inited. ------------------------------------------------------------------------ r4274 | marko | 2009-02-24 00:14:38 +0200 (Tue, 24 Feb 2009) | 12 lines branches/zip: Fix bugs in the fix of Issue #181. Tested inside and outside Valgrind, with innodb_use_sys_malloc set to 0 and 1. mem_init(): Invoke ut_mem_init() before mem_pool_create(), because the latter one will invoke ut_malloc(). srv_general_init(): Do not initialize the memory subsystem (mem_init()). innobase_init(): Initialize the memory subsystem (mem_init()) before calling srv_parse_data_file_paths_and_sizes(), which needs ut_malloc(). Call ut_free_all_mem() in error handling to clean up after the mem_init(). ------------------------------------------------------------------------ r4280 | marko | 2009-02-24 15:14:59 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: Remove unused function os_mem_alloc_nocache(). ------------------------------------------------------------------------ r4281 | marko | 2009-02-24 16:02:48 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: Remove the unused function dict_index_get_type(). ------------------------------------------------------------------------ r4283 | marko | 2009-02-24 23:06:56 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: srv0start.c: Remove unnecessary #include "mem0pool.h". ------------------------------------------------------------------------ r4284 | marko | 2009-02-24 23:26:38 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: mem0mem.c: Remove unnecessary #include "mach0data.h". ------------------------------------------------------------------------ r4288 | vasil | 2009-02-25 10:48:07 +0200 (Wed, 25 Feb 2009) | 21 lines branches/zip: Merge revisions 4261:4287 from branches/5.1: ------------------------------------------------------------------------ r4287 | sunny | 2009-02-25 05:32:01 +0200 (Wed, 25 Feb 2009) | 10 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Fix Bug#42714 AUTO_INCREMENT errors in 5.1.31. There are two changes to the autoinc handling. 1. To fix the immediate problem from the bug report, we must ensure that the value written to the table is always less than the max value stored in dict_table_t. 2. The second related change is that according to MySQL documentation when the offset is greater than the increment, we should ignore the offset. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4289 | vasil | 2009-02-25 10:53:51 +0200 (Wed, 25 Feb 2009) | 4 lines branches/zip: Add ChangeLog entry for the fix in r4288. ------------------------------------------------------------------------ r4290 | vasil | 2009-02-25 11:05:44 +0200 (Wed, 25 Feb 2009) | 11 lines branches/zip: Make ChangeLog entries for bugs in bugs.mysql.com in the form: Fix Bug#12345 bug title (for bugs after 1.0.2 was released and the ChangeLog published) There is no need to bloat the ChangeLog with information that is available via bugs.mysql.com. Discussed with: Marko ------------------------------------------------------------------------ r4291 | vasil | 2009-02-25 11:08:32 +0200 (Wed, 25 Feb 2009) | 4 lines branches/zip: Fix Bug synopsis and remove explanation ------------------------------------------------------------------------ r4292 | marko | 2009-02-25 12:09:15 +0200 (Wed, 25 Feb 2009) | 25 lines branches/zip: Correct the initialization of the memory subsystem once again, to finally put Issue #181 to rest. Revert some parts of r4274. It is best not to call ut_malloc() before srv_general_init(). mem_init(): Do not call ut_mem_init(). srv_general_init(): Initialize the memory subsystem in two phases: first ut_mem_init(), then mem_init(). This is because os_sync_init() and sync_init() depend on ut_mem_init() and mem_init() depends on os_sync_init() or sync_init(). srv_parse_data_file_paths_and_sizes(), srv_parse_log_group_home_dirs(): Remove the output parameters. Assign to the global variables directly. Allocate memory with malloc() instead of ut_malloc(), because these functions will be called before srv_general_init(). srv_free_paths_and_sizes(): New function, for cleaning up after srv_parse_data_file_paths_and_sizes() and srv_parse_log_group_home_dirs(). rb://92 approved by Sunny Bains ------------------------------------------------------------------------ r4297 | vasil | 2009-02-25 17:19:19 +0200 (Wed, 25 Feb 2009) | 4 lines branches/zip: White-space cleanup in the ChangeLog ------------------------------------------------------------------------ r4301 | vasil | 2009-02-25 21:33:32 +0200 (Wed, 25 Feb 2009) | 5 lines branches/zip: Do not output the commands that restore the environment because they depend on the state of the environment before the test starts executing. ------------------------------------------------------------------------ r4315 | vasil | 2009-02-26 09:21:20 +0200 (Thu, 26 Feb 2009) | 5 lines branches/zip: Apply any necessary patches to the mysql tree at the end of setup.sh This step was previously done manually (and sometimes forgotten). ------------------------------------------------------------------------ r4319 | marko | 2009-02-26 23:27:51 +0200 (Thu, 26 Feb 2009) | 6 lines branches/zip: btr_check_blob_fil_page_type(): Do not report FIL_PAGE_TYPE mismatch even when purging a BLOB. Heavy users may have large data files created with MySQL 5.0 or earlier, and they don not want to have the error log flooded with such messages. This fixes Issue #182. ------------------------------------------------------------------------ r4320 | inaam | 2009-02-27 02:13:19 +0200 (Fri, 27 Feb 2009) | 8 lines branches/zip This is to revert the changes made to the plug.in (r4251) as a fix for issue# 178. Changes to plug.in will not propogate to a plugin installation unless autotools are rerun which is unacceptable. A fix for issue# 178 will be committed in a separate commit. ------------------------------------------------------------------------ r4321 | inaam | 2009-02-27 02:16:46 +0200 (Fri, 27 Feb 2009) | 6 lines branches/zip This is a fix for issue#178. Instead of using UNIV_LINUX which is defined through CFLAGS we use compiler generated define __linux__ that is effective for both .c and .cc files. ------------------------------------------------------------------------ r4324 | vasil | 2009-02-27 13:27:18 +0200 (Fri, 27 Feb 2009) | 39 lines branches/zip: Add FreeBSD to the list of the operating systems that have sizeof(pthread_t) == sizeof(void*) (i.e. word size). On FreeBSD pthread_t is defined like: /usr/include/sys/_pthreadtypes.h: typedef struct pthread *pthread_t; I did the following tests (per Inaam's recommendation): a) appropriate version of GCC is available on that platform (4.1.2 or higher for atomics to be available) On FreeBSD 6.x the default compiler is 3.4.6, on FreeBSD 7.x the default one is 4.2.1. One can always install the version of choice from the ports collection. If gcc 3.x is used then HAVE_GCC_ATOMIC_BUILTINS will not be defined and thus the change I am committing will make no difference. b) find out if sizeof(pthread_t) == sizeof(long) On 32 bit both are 4 bytes, on 64 bit both are 8 bytes. c) find out the compiler generated platform define (e.g.: __aix, __sunos__ etc.) The macro is __FreeBSD__. d) patch univ.i with the appropriate platform define e) build the mysql f) ensure it is using atomic builtins (look at the err.log message at system startup. It should say we are using atomics for both mutexes and rw-locks) g) do sanity testing (keeping in view the smp changes) I ran the mysql-test suite. All tests pass. ------------------------------------------------------------------------ r4353 | vasil | 2009-03-05 09:27:29 +0200 (Thu, 05 Mar 2009) | 6 lines branches/zip: As suggested by Ken, print a message that says that the Google SMP patch (GCC atomics) is disabled if it is. Also extend the message when the patch is partially enabled to make it clear that it is partially enabled. ------------------------------------------------------------------------ r4356 | vasil | 2009-03-05 13:49:51 +0200 (Thu, 05 Mar 2009) | 4 lines branches/zip: Fix typo made in r4353. ------------------------------------------------------------------------ r4357 | vasil | 2009-03-05 16:38:59 +0200 (Thu, 05 Mar 2009) | 23 lines branches/zip: Implement a check whether pthread_t objects can be used by GCC atomic builtin functions. This check is implemented in plug.in and defines the macro HAVE_ATOMIC_PTHREAD_T. This macro is checked in univ.i and the relevant part of the code enabled (the one that uses GCC atomics against pthread_t objects). In addition to this, the same program that is compiled as part of the plug.in check is added in ut/ut0auxconf.c. In the InnoDB Plugin source archives that are shipped to the users, a generated Makefile.in is added. That Makefile.in will be modified to compile ut/ut0auxconf.c and define the macro HAVE_ATOMIC_PTHREAD_T if the compilation succeeds. I.e. Makefile.in will emulate the work that is done by plug.in. This is done in order to make the check happen and HAVE_ATOMIC_PTHREAD_T eventually defined without regenerating MySQL's ./configure from ./storage/innobase/plug.in. The point is not to ask users to install the autotools and regenerate ./configure. rb://95 Approved by: Marko ------------------------------------------------------------------------ r4360 | vasil | 2009-03-05 22:23:17 +0200 (Thu, 05 Mar 2009) | 21 lines branches/zip: Merge revisions 4287:4357 from branches/5.1: ------------------------------------------------------------------------ r4325 | sunny | 2009-03-02 02:28:52 +0200 (Mon, 02 Mar 2009) | 10 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Bug#43203: Overflow from auto incrementing causes server segv It was not a SIGSEGV but an assertion failure. The assertion was checking the invariant that *first_value passed in by MySQL doesn't contain a value that is greater than the max value for that type. The assertion has been changed to a check and if the value is greater than the max we report a generic AUTOINC failure. rb://93 Approved by Heikki ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4361 | vasil | 2009-03-05 22:27:54 +0200 (Thu, 05 Mar 2009) | 30 lines branches/zip: Merge revision 4358 from branches/5.1 (resolving a conflict): ------------------------------------------------------------------------ r4358 | vasil | 2009-03-05 21:21:10 +0200 (Thu, 05 Mar 2009) | 21 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: Merge a change from MySQL: ------------------------------------------------------------ revno: 2728.19.1 committer: Alfranio Correia <alfranio.correia@sun.com> branch nick: mysql-5.1-bugteam timestamp: Tue 2009-02-03 11:36:46 +0000 message: BUG#42445 Warning messages in innobase/handler/ha_innodb.cc There was a type casting problem in the storage/innobase/handler/ha_innodb.cc, (int ha_innobase::write_row(...)). Innobase uses has an internal error variable of type 'ulint' while mysql uses an 'int'. To fix the problem the function manipulates an error variable of type 'ulint' and only casts it into 'int' when needs to return the value. modified: storage/innobase/handler/ha_innodb.cc ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4362 | vasil | 2009-03-05 22:29:07 +0200 (Thu, 05 Mar 2009) | 23 lines branches/zip: Merge revision 4359 from branches/5.1: ------------------------------------------------------------------------ r4359 | vasil | 2009-03-05 21:42:01 +0200 (Thu, 05 Mar 2009) | 14 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: Merge a change from MySQL: ------------------------------------------------------------ revno: 2747 committer: Timothy Smith <timothy.smith@sun.com> branch nick: 51 timestamp: Fri 2009-01-16 17:49:07 +0100 message: Add another cast to ignore int/ulong difference in error types, silence warning on Win64 modified: storage/innobase/handler/ha_innodb.cc ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4363 | vasil | 2009-03-05 22:31:37 +0200 (Thu, 05 Mar 2009) | 4 lines branches/zip: Add ChangeLog entry for the bugfix in c4360. ------------------------------------------------------------------------ r4378 | calvin | 2009-03-09 10:10:17 +0200 (Mon, 09 Mar 2009) | 7 lines branches/zip: remove compile flag MYSQL_SERVER for dynamic plugin The dynamic plugin on Windows used to be built with MYSQL_SERVER compile flag, while it is not the case for other platforms. r3797 assumed MYSQL_SERVER was not defined for dynamic plugin, which introduced the engine crash during dropping a database. ------------------------------------------------------------------------ r4396 | marko | 2009-03-12 09:22:27 +0200 (Thu, 12 Mar 2009) | 3 lines branches/zip: btr_store_big_rec_extern_fields(): Initialize FIL_PAGE_TYPE in a separate redo log entry. This will make ibbackup --apply-log debugging easier. ------------------------------------------------------------------------ r4397 | marko | 2009-03-12 09:26:11 +0200 (Thu, 12 Mar 2009) | 3 lines branches/zip: trx_sys_create_doublewrite_buf(): As the dummy change, initialize FIL_PAGE_TYPE. This will make it easier to write the debug assertions for ibbackup --apply-log. ------------------------------------------------------------------------ r4401 | marko | 2009-03-12 10:26:40 +0200 (Thu, 12 Mar 2009) | 19 lines branches/zip: Merge revisions 4359:4400 from branches/5.1: ------------------------------------------------------------------------ r4399 | marko | 2009-03-12 09:38:05 +0200 (Thu, 12 Mar 2009) | 2 lines branches/5.1: row_sel_get_clust_rec_for_mysql(): Store the cursor position also for unlock_row(). (Bug #39320) ------------------------------------------------------------------------ r4400 | marko | 2009-03-12 10:06:44 +0200 (Thu, 12 Mar 2009) | 5 lines branches/5.1: Fix a bug in multi-table semi-consistent reads. Remember the acquired record locks per table handle (row_prebuilt_t) rather than per transaction (trx_t), so that unlock_row should successfully unlock all non-matching rows in multi-table operations. This deficiency was found while investigating Bug #39320. ------------------------------------------------------------------------ These were submitted as rb://94 and rb://96 and approved by Heikki Tuuri. ------------------------------------------------------------------------ r4455 | marko | 2009-03-16 11:43:34 +0200 (Mon, 16 Mar 2009) | 2 lines branches/zip: UT_LIST_VALIDATE(): Add the parameter ASSERTION and adjust all callers. ------------------------------------------------------------------------ r4456 | marko | 2009-03-16 12:59:25 +0200 (Mon, 16 Mar 2009) | 6 lines branches/zip: UT_LIST_VALIDATE(): Assert that the link is non-NULL before dereferencing it. In this way, ut_list_node_313 will be pointing to the last non-NULL list item at the time of the assertion failure. (gcc-4.3.2 -O3 seems to optimize the common subexpressions and make the variable NULL, though.) ------------------------------------------------------------------------ r4457 | marko | 2009-03-16 14:12:02 +0200 (Mon, 16 Mar 2009) | 2 lines branches/zip: sync_thread_add_level(): Make the assertions about level == SYNC_BUF_BLOCK more readable. ------------------------------------------------------------------------ r4461 | vasil | 2009-03-17 09:38:19 +0200 (Tue, 17 Mar 2009) | 6 lines branches/zip: Remove mysql-test/patches/bug32625.diff because that bug was fixed in the mysql repository (1 year and 4 months after sending them the simple patch!). See http://bugs.mysql.com/32625 ------------------------------------------------------------------------ r4465 | marko | 2009-03-17 12:34:19 +0200 (Tue, 17 Mar 2009) | 1 line branches/zip: buf0buddy.c: Add and adjust some debug assertions. ------------------------------------------------------------------------ r4473 | vasil | 2009-03-17 15:50:30 +0200 (Tue, 17 Mar 2009) | 5 lines branches/zip: Increment the InnoDB Plugin version from 1.0.3 to 1.0.4 now that 1.0.3 has been released. ------------------------------------------------------------------------ r4478 | vasil | 2009-03-18 11:53:53 +0200 (Wed, 18 Mar 2009) | 5 lines branches/zip: Remove mysql-test/patches/bug41893.diff because that bug has been fixed in the MySQL repository, see http://bugs.mysql.com/41893. ------------------------------------------------------------------------ r4479 | marko | 2009-03-18 12:43:54 +0200 (Wed, 18 Mar 2009) | 2 lines branches/zip: buf_LRU_block_remove_hashed_page(): Add some debug assertions. ------------------------------------------------------------------------ r4480 | marko | 2009-03-18 14:32:13 +0200 (Wed, 18 Mar 2009) | 1 line branches/zip: buf_buddy_free_low(): Correct the function comment. ------------------------------------------------------------------------ r4482 | marko | 2009-03-19 15:23:32 +0200 (Thu, 19 Mar 2009) | 12 lines branches/zip: Merge revisions 4400:4481 from branches/5.1: ------------------------------------------------------------------------ r4481 | marko | 2009-03-19 15:01:48 +0200 (Thu, 19 Mar 2009) | 6 lines branches/5.1: row_unlock_for_mysql(): Do not unlock records that were modified by the current transaction. This bug was introduced or unmasked in r4400. rb://97 approved by Heikki Tuuri ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4490 | marko | 2009-03-20 12:33:33 +0200 (Fri, 20 Mar 2009) | 4 lines branches/zip: Non-functional change for reducing dependencies in InnoDB Hot Backup: Replace srv_sys->dummy_ind1 and srv_sys->dummy_ind2 with dict_ind_redundant and dict_ind_compact, initialized in dict_init(). ------------------------------------------------------------------------ r4491 | marko | 2009-03-20 12:45:18 +0200 (Fri, 20 Mar 2009) | 2 lines branches/zip: Add const qualifiers or in/out comments to some function parameters in log0log. ------------------------------------------------------------------------ r4492 | marko | 2009-03-20 12:52:14 +0200 (Fri, 20 Mar 2009) | 5 lines branches/zip: page_validate(): Always report the space id and the name of the index. In Hot Backup, do not invoke comparison functions, as MySQL collations will be unavailable. ------------------------------------------------------------------------ r4493 | marko | 2009-03-20 13:24:06 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: Replace fil_get_space_for_id_low() with fil_space_get_by_id(). ------------------------------------------------------------------------ r4494 | marko | 2009-03-20 13:51:35 +0200 (Fri, 20 Mar 2009) | 3 lines branches/zip: fil0fil.c: Refer to fil_system directly, not via local vars. This eliminates some "unused variable" warnings when building InnoDB Hot Backup in such a way that all mutex operations are no-ops. ------------------------------------------------------------------------ r4495 | marko | 2009-03-20 14:15:52 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: innobase_get_at_most_n_mbchars(): Declare in ha_prototypes.h. ------------------------------------------------------------------------ r4496 | marko | 2009-03-20 14:48:26 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: recv_recover_page(): Remove compile-time constant parameters. ------------------------------------------------------------------------ r4497 | marko | 2009-03-20 14:56:19 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: recv_sys_init(): Remove a compile-time constant parameter. ------------------------------------------------------------------------ r4498 | marko | 2009-03-20 15:08:05 +0200 (Fri, 20 Mar 2009) | 4 lines branches/zip: Non-functional change: Add const qualifiers. log_block_checksum_is_ok_or_old_format(), recv_sys_add_to_parsing_buf(): The log block is read-only. Make it const. ------------------------------------------------------------------------ r4499 | marko | 2009-03-20 15:10:25 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: recv_scan_log_recs(): Remove a compile-time constant parameter. ------------------------------------------------------------------------ r4500 | marko | 2009-03-20 15:47:17 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: fil_init(): Add the parameter hash_size. ------------------------------------------------------------------------ r4501 | vasil | 2009-03-20 16:50:41 +0200 (Fri, 20 Mar 2009) | 4 lines branches/zip: Add any entry about the release of 1.0.3 in the ChangeLog. ------------------------------------------------------------------------ r4515 | marko | 2009-03-23 10:49:53 +0200 (Mon, 23 Mar 2009) | 1 line branches/zip: hash_table_t: adaptive: Remove from UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4516 | marko | 2009-03-23 10:57:16 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Define and use ASSERT_HASH_MUTEX_OWN. Make it a no-op in UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4517 | marko | 2009-03-23 11:07:20 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Define and use PAGE_ZIP_MATCH. In UNIV_HOTBACKUP builds, assume fixed allocation. ------------------------------------------------------------------------ r4521 | marko | 2009-03-23 12:05:47 +0200 (Mon, 23 Mar 2009) | 1 line branches/zip: buf_page_print(): Clean up the code #ifdef UNIV_HOTBACKUP. ------------------------------------------------------------------------ r4522 | marko | 2009-03-23 12:20:50 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Exclude some operating system interface code from UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4523 | marko | 2009-03-23 13:00:43 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Remove the remaining references to hash_table_t::adapive from UNIV_HOTBACKUP builds. This should have been done in r4515. ------------------------------------------------------------------------ r4524 | marko | 2009-03-23 14:05:18 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Enclose recv_recovery_from_backup_on and recv_recovery_from_backup_is_on() in #ifdef UNIV_LOG_ARCHIVE. ------------------------------------------------------------------------ r4525 | marko | 2009-03-23 14:57:45 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: recv_parse_or_apply_log_rec_body(): Add debug assertions ensuring that FIL_PAGE_TYPE makes sense when applying log records. ------------------------------------------------------------------------ r4526 | marko | 2009-03-23 16:21:34 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Remove unneeded definitions and dependencies from UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4527 | calvin | 2009-03-23 23:15:33 +0200 (Mon, 23 Mar 2009) | 5 lines branches/zip: adjust build files on Windows Adjust the patch positions based on the latest MySQL source. Also add the patches to the .bat files for vs9. ------------------------------------------------------------------------
17 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
branches/innodb+: Merge revisions 4150:4528 from branches/zip: ------------------------------------------------------------------------ r4152 | marko | 2009-02-10 12:52:27 +0200 (Tue, 10 Feb 2009) | 12 lines branches/zip: When innodb_use_sys_malloc is set, ignore innodb_additional_mem_pool_size, because nothing will be allocated from mem_comm_pool. mem_pool_create(): Remove the assertion about size. The function will work with any size. However, an assertion would fail in ut_malloc_low() when size==0. mem_init(): When srv_use_sys_malloc is set, pass size=1 to mem_pool_create(). mem0mem.c: Add #include "srv0srv.h" that is needed by mem0dbg.c. ------------------------------------------------------------------------ r4153 | vasil | 2009-02-10 22:58:17 +0200 (Tue, 10 Feb 2009) | 14 lines branches/zip: (followup to r4145) Non-functional change: Change the os_atomic_increment() and os_compare_and_swap() functions to macros to avoid artificial limitations on the types of those functions' arguments. As a consequence typecasts from the source code can be removed. Also remove Google's copyright from os0sync.ic because that file no longer contains code from Google. Approved by: Marko (rb://88), also ok from Inaam via IM ------------------------------------------------------------------------ r4163 | marko | 2009-02-12 00:14:19 +0200 (Thu, 12 Feb 2009) | 4 lines branches/zip: Make innodb_thread_concurrency=0 the default. The old default was 8. ------------------------------------------------------------------------ r4169 | calvin | 2009-02-12 10:37:10 +0200 (Thu, 12 Feb 2009) | 3 lines branches/zip: Adjust the result file of innodb_thread_concurrency_basic test. The default value of innodb_thread_concurrency is changed to 0 (from 8) via r4163. ------------------------------------------------------------------------ r4174 | vasil | 2009-02-12 17:38:27 +0200 (Thu, 12 Feb 2009) | 4 lines branches/zip: Fix pathname of the file to patch. ------------------------------------------------------------------------ r4176 | vasil | 2009-02-13 10:06:31 +0200 (Fri, 13 Feb 2009) | 7 lines branches/zip: Fix the failing mysql-test partition_innodb, which failed only if run after innodb_trx_weight (or other test that would leave LATEST DEADLOCK ERROR into the output of SHOW ENGINE INNODB STATUS). Find further explanation for the failure at the top of the added patch partition_innodb.diff. ------------------------------------------------------------------------ r4198 | vasil | 2009-02-17 09:06:07 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: Add the full text of the GPLv2 license into the root directory of the plugin. In previous releases this file was copied from an external source (https://svn.innodb.com/svn/plugin/trunk/support/COPYING) "manually" when creating the source and binary archives. It is less confusing to have this present in the root directory of the SVN branch. ------------------------------------------------------------------------ r4199 | vasil | 2009-02-17 09:11:58 +0200 (Tue, 17 Feb 2009) | 4 lines branches/zip: Add Google's license into COPYING.Google. ------------------------------------------------------------------------ r4200 | vasil | 2009-02-17 09:56:33 +0200 (Tue, 17 Feb 2009) | 11 lines branches/zip: To the files touched by the Google patch from c4144 (excluding include/os0sync.ic because later we removed Google code from that file): * Remove the Google license * Remove old Innobase copyright lines * Add a reference to the Google license and to the GPLv2 license at the top, as recommended by the lawyers at Oracle Legal. ------------------------------------------------------------------------ r4201 | vasil | 2009-02-17 10:12:02 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 1/28] ------------------------------------------------------------------------ r4202 | vasil | 2009-02-17 10:15:06 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 2/28] ------------------------------------------------------------------------ r4203 | vasil | 2009-02-17 10:25:45 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 3/28] ------------------------------------------------------------------------ r4204 | vasil | 2009-02-17 10:55:41 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 4/28] ------------------------------------------------------------------------ r4205 | vasil | 2009-02-17 10:59:22 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 5/28] ------------------------------------------------------------------------ r4206 | vasil | 2009-02-17 11:02:27 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 6/28] ------------------------------------------------------------------------ r4207 | vasil | 2009-02-17 11:04:28 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 7/28] ------------------------------------------------------------------------ r4208 | vasil | 2009-02-17 11:06:49 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 8/28] ------------------------------------------------------------------------ r4209 | vasil | 2009-02-17 11:10:18 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 9/28] ------------------------------------------------------------------------ r4210 | vasil | 2009-02-17 11:12:41 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 10/28] ------------------------------------------------------------------------ r4211 | vasil | 2009-02-17 11:14:40 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 11/28] ------------------------------------------------------------------------ r4212 | vasil | 2009-02-17 11:18:35 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 12/28] ------------------------------------------------------------------------ r4213 | vasil | 2009-02-17 11:24:40 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 13/28] ------------------------------------------------------------------------ r4214 | vasil | 2009-02-17 11:27:31 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 13/28] ------------------------------------------------------------------------ r4215 | vasil | 2009-02-17 11:29:55 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 15/28] ------------------------------------------------------------------------ r4216 | vasil | 2009-02-17 11:33:38 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 16/28] ------------------------------------------------------------------------ r4217 | vasil | 2009-02-17 11:36:44 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 17/28] ------------------------------------------------------------------------ r4218 | vasil | 2009-02-17 11:39:11 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 18/28] ------------------------------------------------------------------------ r4219 | vasil | 2009-02-17 11:41:24 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 19/28] ------------------------------------------------------------------------ r4220 | vasil | 2009-02-17 11:43:50 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 20/28] ------------------------------------------------------------------------ r4221 | vasil | 2009-02-17 11:46:52 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 21/28] ------------------------------------------------------------------------ r4222 | vasil | 2009-02-17 11:50:12 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 22/28] ------------------------------------------------------------------------ r4223 | vasil | 2009-02-17 11:53:58 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 23/28] ------------------------------------------------------------------------ r4224 | vasil | 2009-02-17 12:01:41 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 24/28] ------------------------------------------------------------------------ r4225 | vasil | 2009-02-17 12:05:45 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 25/28] ------------------------------------------------------------------------ r4226 | vasil | 2009-02-17 12:09:16 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 26/28] ------------------------------------------------------------------------ r4227 | vasil | 2009-02-17 12:12:56 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 27/28] ------------------------------------------------------------------------ r4228 | vasil | 2009-02-17 12:14:04 +0200 (Tue, 17 Feb 2009) | 8 lines branches/zip: * Remove old Innobase copyright lines from C source files * Add a reference to the GPLv2 license as recommended by the lawyers at Oracle Legal [Step 28/28] ------------------------------------------------------------------------ r4229 | vasil | 2009-02-17 12:30:55 +0200 (Tue, 17 Feb 2009) | 4 lines branches/zip: Add the copyright notice to the non C files. ------------------------------------------------------------------------ r4231 | marko | 2009-02-17 14:26:53 +0200 (Tue, 17 Feb 2009) | 12 lines Minor cleanup of the Google SMP patch. sync_array_object_signalled(): Add a (void) cast to eliminate a gcc warning about the return value of os_atomic_increment() being ignored. rw_lock_create_func(): Properly indent the preprocessor directives. rw_lock_x_lock_low(), rw_lock_x_lock_func_nowait(): Split lines correctly. rw_lock_set_writer_id_and_recursion_flag(): Silence a Valgrind warning. Do not mix statements and variable declarations. ------------------------------------------------------------------------ r4232 | marko | 2009-02-17 14:59:54 +0200 (Tue, 17 Feb 2009) | 3 lines branches/zip: When assigning lock->recursive = FALSE, also flag lock->writer_thread invalid, so that Valgrind will catch more errors. This is related to Issue #175. ------------------------------------------------------------------------ r4242 | marko | 2009-02-18 17:01:09 +0200 (Wed, 18 Feb 2009) | 2 lines branches/zip: UT_DBG_STOP: Use do{} while(0) to silence a g++-4.3.2 warning about a while(0); statement. This should fix (part of) Issue #176. ------------------------------------------------------------------------ r4243 | marko | 2009-02-18 17:04:03 +0200 (Wed, 18 Feb 2009) | 3 lines branches/zip: buf_buddy_get_slot(): Fix a gcc 4.3.2 warning about an empty body of a "for" statement. This fixes part of Issue #176. ------------------------------------------------------------------------ r4244 | marko | 2009-02-18 17:25:45 +0200 (Wed, 18 Feb 2009) | 11 lines branches/zip: Protect ut_total_allocated_memory with ut_list_mutex. Unprotected updates to ut_total_allocated_memory in os_mem_alloc_large() and os_mem_free_large(), called during fast index creation, may corrupt the variable and cause assertion failures. Also, add UNIV_MEM_ALLOC() and UNIV_MEM_FREE() instrumentation around os_mem_alloc_large() and os_mem_free_large(), so that Valgrind can detect more errors. rb://90 approved by Heikki Tuuri. This addresses Issue #177. ------------------------------------------------------------------------ r4248 | marko | 2009-02-19 11:52:39 +0200 (Thu, 19 Feb 2009) | 2 lines branches/zip: page_zip_set_size(): Fix a g++ 4.3.2 warning about an empty body in a "for" statement. This closes Issue #176. ------------------------------------------------------------------------ r4251 | inaam | 2009-02-19 15:46:27 +0200 (Thu, 19 Feb 2009) | 8 lines branches/zip: Issue #178 rb://91 Change plug.in to have same CXXFLAGS as CFLAGS. This is to ensure that both .c and .cc files get compiled with same flags. To fix the issue where UNIV_LINUX was defined only in .c files. Approved by: Marko ------------------------------------------------------------------------ r4258 | vasil | 2009-02-20 11:52:19 +0200 (Fri, 20 Feb 2009) | 7 lines branches/zip: Cleanup in ChangeLog: * Wrap lines at 78 characters * Changed files are listed alphabetically * White-space cleanup ------------------------------------------------------------------------ r4259 | vasil | 2009-02-20 11:59:42 +0200 (Fri, 20 Feb 2009) | 6 lines branches/zip: ChangeLog: Remove include/os0sync.ic from the entry about the google patch, this file was modified later to not include Google's code. ------------------------------------------------------------------------ r4262 | vasil | 2009-02-20 14:56:59 +0200 (Fri, 20 Feb 2009) | 373 lines branches/zip: Merge revisions 4035:4261 from branches/5.1: ------------------------------------------------------------------------ r4065 | sunny | 2009-01-29 16:01:36 +0200 (Thu, 29 Jan 2009) | 8 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: In the last round of AUTOINC cleanup we assumed that AUTOINC is only defined for integer columns. This caused an assertion failure when we checked for the maximum value of a column type. We now calculate the max value for floating-point autoinc columns too. Fix Bug#42400 - InnoDB autoinc code can't handle floating-point columns rb://84 and Mantis issue://162 ------------------------------------------------------------------------ r4111 | sunny | 2009-02-03 22:06:52 +0200 (Tue, 03 Feb 2009) | 2 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: Add the ULL suffix otherwise there is an overflow. ------------------------------------------------------------------------ r4128 | vasil | 2009-02-08 21:36:45 +0200 (Sun, 08 Feb 2009) | 18 lines Changed paths: M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Merge a change from MySQL: ------------------------------------------------------------ revno: 2709.20.31 committer: Timothy Smith <timothy.smith@sun.com> branch nick: 51 timestamp: Fri 2008-12-19 01:28:51 +0100 message: Disable part of innodb-autoinc.test, because the MySQL server asserts when compiled --with-debug, due to bug 39828, "autoinc wraps around when offset and increment > 1". This change should be reverted when that bug is fixed (and a a few other minor changes to the test as described in comments). modified: mysql-test/r/innodb-autoinc.result mysql-test/t/innodb-autoinc.test ------------------------------------------------------------------------ r4129 | vasil | 2009-02-08 21:54:25 +0200 (Sun, 08 Feb 2009) | 310 lines Changed paths: M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Merge a change from MySQL: [looks like the changes to innodb-autoinc.test were made as part of the following huge merge, but we are merging only changes to that file] ------------------------------------------------------------ revno: 2546.47.1 committer: Luis Soares <luis.soares@sun.com> branch nick: 5.1-rpl timestamp: Fri 2009-01-23 13:22:05 +0100 message: merge: 5.1 -> 5.1-rpl conflicts: Text conflict in client/mysqltest.cc Text conflict in mysql-test/include/wait_until_connected_again.inc Text conflict in mysql-test/lib/mtr_report.pm Text conflict in mysql-test/mysql-test-run.pl Text conflict in mysql-test/r/events_bugs.result Text conflict in mysql-test/r/log_state.result Text conflict in mysql-test/r/myisam_data_pointer_size_func.result Text conflict in mysql-test/r/mysqlcheck.result Text conflict in mysql-test/r/query_cache.result Text conflict in mysql-test/r/status.result Text conflict in mysql-test/suite/binlog/r/binlog_index.result Text conflict in mysql-test/suite/binlog/r/binlog_innodb.result Text conflict in mysql-test/suite/rpl/r/rpl_packet.result Text conflict in mysql-test/suite/rpl/t/rpl_packet.test Text conflict in mysql-test/t/disabled.def Text conflict in mysql-test/t/events_bugs.test Text conflict in mysql-test/t/log_state.test Text conflict in mysql-test/t/myisam_data_pointer_size_func.test Text conflict in mysql-test/t/mysqlcheck.test Text conflict in mysql-test/t/query_cache.test Text conflict in mysql-test/t/rpl_init_slave_func.test Text conflict in mysql-test/t/status.test removed: mysql-test/suite/parts/r/partition_bit_ndb.result mysql-test/suite/parts/t/partition_bit_ndb.test mysql-test/suite/parts/t/partition_sessions.test mysql-test/suite/sys_vars/inc/tmp_table_size_basic.inc mysql-test/suite/sys_vars/r/tmp_table_size_basic_32.result mysql-test/suite/sys_vars/r/tmp_table_size_basic_64.result mysql-test/suite/sys_vars/t/tmp_table_size_basic_32.test mysql-test/suite/sys_vars/t/tmp_table_size_basic_64.test mysql-test/t/log_bin_trust_function_creators_func-master.opt mysql-test/t/rpl_init_slave_func-slave.opt added: mysql-test/include/check_events_off.inc mysql-test/include/cleanup_fake_relay_log.inc mysql-test/include/have_simple_parser.inc mysql-test/include/no_running_event_scheduler.inc mysql-test/include/no_running_events.inc mysql-test/include/running_event_scheduler.inc mysql-test/include/setup_fake_relay_log.inc mysql-test/include/wait_condition_sp.inc mysql-test/r/fulltext_plugin.result mysql-test/r/have_simple_parser.require mysql-test/r/innodb_bug38231.result mysql-test/r/innodb_bug39438.result mysql-test/r/innodb_mysql_rbk.result mysql-test/r/partition_innodb_semi_consistent.result mysql-test/r/query_cache_28249.result mysql-test/r/status2.result mysql-test/std_data/bug40482-bin.000001 mysql-test/suite/binlog/r/binlog_innodb_row.result mysql-test/suite/binlog/t/binlog_innodb_row.test mysql-test/suite/rpl/r/rpl_binlog_corruption.result mysql-test/suite/rpl/t/rpl_binlog_corruption-master.opt mysql-test/suite/rpl/t/rpl_binlog_corruption.test mysql-test/suite/sys_vars/r/tmp_table_size_basic.result mysql-test/suite/sys_vars/t/tmp_table_size_basic.test mysql-test/t/fulltext_plugin-master.opt mysql-test/t/fulltext_plugin.test mysql-test/t/innodb_bug38231.test mysql-test/t/innodb_bug39438-master.opt mysql-test/t/innodb_bug39438.test mysql-test/t/innodb_mysql_rbk-master.opt mysql-test/t/innodb_mysql_rbk.test mysql-test/t/partition_innodb_semi_consistent-master.opt mysql-test/t/partition_innodb_semi_consistent.test mysql-test/t/query_cache_28249.test mysql-test/t/status2.test renamed: mysql-test/suite/funcs_1/r/is_collation_character_set_applicability.result => mysql-test/suite/funcs_1/r/is_coll_char_set_appl.result mysql-test/suite/funcs_1/t/is_collation_character_set_applicability.test => mysql-test/suite/funcs_1/t/is_coll_char_set_appl.test modified: .bzr-mysql/default.conf CMakeLists.txt client/mysql.cc client/mysql_upgrade.c client/mysqlcheck.c client/mysqltest.cc configure.in extra/resolve_stack_dump.c extra/yassl/include/openssl/ssl.h include/config-win.h include/m_ctype.h include/my_global.h mysql-test/extra/binlog_tests/database.test mysql-test/extra/rpl_tests/rpl_auto_increment.test mysql-test/include/commit.inc mysql-test/include/have_32bit.inc mysql-test/include/have_64bit.inc mysql-test/include/index_merge1.inc mysql-test/include/linux_sys_vars.inc mysql-test/include/windows_sys_vars.inc mysql-test/lib/mtr_report.pm mysql-test/mysql-test-run.pl mysql-test/r/alter_table.result mysql-test/r/commit_1innodb.result mysql-test/r/create.result mysql-test/r/csv.result mysql-test/r/ctype_ucs.result mysql-test/r/date_formats.result mysql-test/r/events_bugs.result mysql-test/r/events_scheduling.result mysql-test/r/fulltext.result mysql-test/r/func_if.result mysql-test/r/func_in.result mysql-test/r/func_str.result mysql-test/r/func_time.result mysql-test/r/grant.result mysql-test/r/index_merge_myisam.result mysql-test/r/information_schema.result mysql-test/r/innodb-autoinc.result mysql-test/r/innodb.result mysql-test/r/innodb_mysql.result mysql-test/r/log_bin_trust_function_creators_func.result mysql-test/r/log_state.result mysql-test/r/myisampack.result mysql-test/r/mysql.result mysql-test/r/mysqlcheck.result mysql-test/r/partition_datatype.result mysql-test/r/partition_mgm.result mysql-test/r/partition_pruning.result mysql-test/r/query_cache.result mysql-test/r/read_buffer_size_basic.result mysql-test/r/read_rnd_buffer_size_basic.result mysql-test/r/rpl_init_slave_func.result mysql-test/r/select.result mysql-test/r/status.result mysql-test/r/strict.result mysql-test/r/temp_table.result mysql-test/r/type_bit.result mysql-test/r/type_date.result mysql-test/r/type_float.result mysql-test/r/warnings_engine_disabled.result mysql-test/r/xml.result mysql-test/suite/binlog/r/binlog_database.result mysql-test/suite/binlog/r/binlog_index.result mysql-test/suite/binlog/r/binlog_innodb.result mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result mysql-test/suite/binlog/t/binlog_innodb.test mysql-test/suite/funcs_1/r/is_columns_is.result mysql-test/suite/funcs_1/r/is_engines.result mysql-test/suite/funcs_1/r/storedproc.result mysql-test/suite/funcs_1/storedproc/param_check.inc mysql-test/suite/funcs_2/t/disabled.def mysql-test/suite/ndb/t/disabled.def mysql-test/suite/parts/r/partition_bit_innodb.result mysql-test/suite/parts/r/partition_bit_myisam.result mysql-test/suite/parts/r/partition_special_innodb.result mysql-test/suite/parts/t/disabled.def mysql-test/suite/parts/t/partition_special_innodb.test mysql-test/suite/parts/t/partition_value_innodb.test mysql-test/suite/parts/t/partition_value_myisam.test mysql-test/suite/parts/t/partition_value_ndb.test mysql-test/suite/rpl/r/rpl_auto_increment.result mysql-test/suite/rpl/r/rpl_packet.result mysql-test/suite/rpl/r/rpl_row_create_table.result mysql-test/suite/rpl/r/rpl_slave_skip.result mysql-test/suite/rpl/r/rpl_trigger.result mysql-test/suite/rpl/t/disabled.def mysql-test/suite/rpl/t/rpl_packet.test mysql-test/suite/rpl/t/rpl_row_create_table.test mysql-test/suite/rpl/t/rpl_slave_skip.test mysql-test/suite/rpl/t/rpl_trigger.test mysql-test/suite/rpl_ndb/t/disabled.def mysql-test/suite/sys_vars/inc/key_buffer_size_basic.inc mysql-test/suite/sys_vars/inc/sort_buffer_size_basic.inc mysql-test/suite/sys_vars/r/key_buffer_size_basic_32.result mysql-test/suite/sys_vars/r/key_buffer_size_basic_64.result mysql-test/suite/sys_vars/r/sort_buffer_size_basic_32.result mysql-test/suite/sys_vars/r/sort_buffer_size_basic_64.result mysql-test/t/alter_table.test mysql-test/t/create.test mysql-test/t/csv.test mysql-test/t/ctype_ucs.test mysql-test/t/date_formats.test mysql-test/t/disabled.def mysql-test/t/events_bugs.test mysql-test/t/events_scheduling.test mysql-test/t/fulltext.test mysql-test/t/func_if.test mysql-test/t/func_in.test mysql-test/t/func_str.test mysql-test/t/func_time.test mysql-test/t/grant.test mysql-test/t/information_schema.test mysql-test/t/innodb-autoinc.test mysql-test/t/innodb.test mysql-test/t/innodb_mysql.test mysql-test/t/log_bin_trust_function_creators_func.test mysql-test/t/log_state.test mysql-test/t/myisam_data_pointer_size_func.test mysql-test/t/myisampack.test mysql-test/t/mysql.test mysql-test/t/mysqlcheck.test mysql-test/t/partition_innodb_stmt.test mysql-test/t/partition_mgm.test mysql-test/t/partition_pruning.test mysql-test/t/query_cache.test mysql-test/t/rpl_init_slave_func.test mysql-test/t/select.test mysql-test/t/status.test mysql-test/t/strict.test mysql-test/t/temp_table.test mysql-test/t/type_bit.test mysql-test/t/type_date.test mysql-test/t/type_float.test mysql-test/t/warnings_engine_disabled.test mysql-test/t/xml.test mysys/my_getopt.c mysys/my_init.c scripts/mysql_install_db.sh sql-common/my_time.c sql/field.cc sql/field.h sql/filesort.cc sql/ha_partition.cc sql/ha_partition.h sql/item.cc sql/item_cmpfunc.cc sql/item_func.h sql/item_strfunc.cc sql/item_sum.cc sql/item_timefunc.cc sql/item_timefunc.h sql/log.cc sql/log.h sql/log_event.cc sql/log_event.h sql/mysql_priv.h sql/mysqld.cc sql/opt_range.cc sql/partition_info.cc sql/repl_failsafe.cc sql/rpl_constants.h sql/set_var.cc sql/slave.cc sql/spatial.h sql/sql_acl.cc sql/sql_base.cc sql/sql_binlog.cc sql/sql_class.h sql/sql_cursor.cc sql/sql_delete.cc sql/sql_lex.cc sql/sql_lex.h sql/sql_locale.cc sql/sql_parse.cc sql/sql_partition.cc sql/sql_plugin.cc sql/sql_plugin.h sql/sql_profile.cc sql/sql_repl.cc sql/sql_select.cc sql/sql_select.h sql/sql_show.cc sql/sql_table.cc sql/sql_trigger.cc sql/sql_trigger.h sql/table.cc sql/table.h sql/unireg.cc storage/csv/ha_tina.cc storage/federated/ha_federated.cc storage/heap/ha_heap.cc storage/innobase/Makefile.am storage/innobase/btr/btr0sea.c storage/innobase/buf/buf0lru.c storage/innobase/dict/dict0dict.c storage/innobase/dict/dict0mem.c storage/innobase/handler/ha_innodb.cc storage/innobase/handler/ha_innodb.h storage/innobase/include/btr0sea.h storage/innobase/include/dict0dict.h storage/innobase/include/dict0mem.h storage/innobase/include/ha_prototypes.h storage/innobase/include/lock0lock.h storage/innobase/include/row0mysql.h storage/innobase/include/sync0sync.ic storage/innobase/include/ut0ut.h storage/innobase/lock/lock0lock.c storage/innobase/os/os0file.c storage/innobase/plug.in storage/innobase/row/row0mysql.c storage/innobase/row/row0sel.c storage/innobase/srv/srv0srv.c storage/innobase/srv/srv0start.c storage/innobase/ut/ut0ut.c storage/myisam/ft_boolean_search.c strings/ctype.c strings/xml.c tests/mysql_client_test.c win/configure.js mysql-test/suite/funcs_1/t/is_coll_char_set_appl.test ------------------------------------------------------------------------ r4165 | calvin | 2009-02-12 01:34:27 +0200 (Thu, 12 Feb 2009) | 1 line Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: minor non-functional changes. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4263 | vasil | 2009-02-20 15:00:46 +0200 (Fri, 20 Feb 2009) | 4 lines branches/zip: Add a ChangeLog entry for a change in r4262. ------------------------------------------------------------------------ r4265 | marko | 2009-02-20 22:31:03 +0200 (Fri, 20 Feb 2009) | 5 lines branches/zip: Make innodb_use_sys_malloc=ON the default. Replace srv_use_sys_malloc with UNIV_LIKELY(srv_use_sys_malloc) to improve branch prediction in the default case. Approved by Ken over the IM. ------------------------------------------------------------------------ r4266 | vasil | 2009-02-20 23:29:32 +0200 (Fri, 20 Feb 2009) | 7 lines branches/zip: Add a sentence at the top of COPYING.Google to clarify that this license does not apply to the whole InnoDB. Suggested by: Ken ------------------------------------------------------------------------ r4268 | marko | 2009-02-23 12:43:51 +0200 (Mon, 23 Feb 2009) | 9 lines branches/zip: Initialize ut_list_mutex at startup. Without this fix, ut_list_mutex would be used uninitialized when innodb_use_sys_malloc=1. This fix addresses Issue #181. ut_mem_block_list_init(): Rename to ut_mem_init() and make public. ut_malloc_low(), ut_free_all_mem(): Add ut_a(ut_mem_block_list_inited). mem_init(): Call ut_mem_init(). ------------------------------------------------------------------------ r4269 | marko | 2009-02-23 15:09:49 +0200 (Mon, 23 Feb 2009) | 7 lines branches/zip: When freeing an uncompressed BLOB page, tolerate garbage in FIL_PAGE_TYPE. (Bug #43043, Issue #182) btr_check_blob_fil_page_type(): New function. btr_free_externally_stored_field(), btr_copy_blob_prefix(): Call btr_check_blob_fil_page_type() to check FIL_PAGE_TYPE. ------------------------------------------------------------------------ r4272 | marko | 2009-02-23 23:10:18 +0200 (Mon, 23 Feb 2009) | 8 lines branches/zip: Adjust the fix of Issue #182 in r4269 per Inaam's suggestion. btr_check_blob_fil_page_type(): Replace the parameter const char* op with ibool read. Do not print anything about page type mismatch when reading a BLOB page in Antelope format. Print space id before page number. ------------------------------------------------------------------------ r4273 | marko | 2009-02-24 00:11:11 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: ut_mem_init(): Add the assertion !ut_mem_block_list_inited. ------------------------------------------------------------------------ r4274 | marko | 2009-02-24 00:14:38 +0200 (Tue, 24 Feb 2009) | 12 lines branches/zip: Fix bugs in the fix of Issue #181. Tested inside and outside Valgrind, with innodb_use_sys_malloc set to 0 and 1. mem_init(): Invoke ut_mem_init() before mem_pool_create(), because the latter one will invoke ut_malloc(). srv_general_init(): Do not initialize the memory subsystem (mem_init()). innobase_init(): Initialize the memory subsystem (mem_init()) before calling srv_parse_data_file_paths_and_sizes(), which needs ut_malloc(). Call ut_free_all_mem() in error handling to clean up after the mem_init(). ------------------------------------------------------------------------ r4280 | marko | 2009-02-24 15:14:59 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: Remove unused function os_mem_alloc_nocache(). ------------------------------------------------------------------------ r4281 | marko | 2009-02-24 16:02:48 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: Remove the unused function dict_index_get_type(). ------------------------------------------------------------------------ r4283 | marko | 2009-02-24 23:06:56 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: srv0start.c: Remove unnecessary #include "mem0pool.h". ------------------------------------------------------------------------ r4284 | marko | 2009-02-24 23:26:38 +0200 (Tue, 24 Feb 2009) | 1 line branches/zip: mem0mem.c: Remove unnecessary #include "mach0data.h". ------------------------------------------------------------------------ r4288 | vasil | 2009-02-25 10:48:07 +0200 (Wed, 25 Feb 2009) | 21 lines branches/zip: Merge revisions 4261:4287 from branches/5.1: ------------------------------------------------------------------------ r4287 | sunny | 2009-02-25 05:32:01 +0200 (Wed, 25 Feb 2009) | 10 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Fix Bug#42714 AUTO_INCREMENT errors in 5.1.31. There are two changes to the autoinc handling. 1. To fix the immediate problem from the bug report, we must ensure that the value written to the table is always less than the max value stored in dict_table_t. 2. The second related change is that according to MySQL documentation when the offset is greater than the increment, we should ignore the offset. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4289 | vasil | 2009-02-25 10:53:51 +0200 (Wed, 25 Feb 2009) | 4 lines branches/zip: Add ChangeLog entry for the fix in r4288. ------------------------------------------------------------------------ r4290 | vasil | 2009-02-25 11:05:44 +0200 (Wed, 25 Feb 2009) | 11 lines branches/zip: Make ChangeLog entries for bugs in bugs.mysql.com in the form: Fix Bug#12345 bug title (for bugs after 1.0.2 was released and the ChangeLog published) There is no need to bloat the ChangeLog with information that is available via bugs.mysql.com. Discussed with: Marko ------------------------------------------------------------------------ r4291 | vasil | 2009-02-25 11:08:32 +0200 (Wed, 25 Feb 2009) | 4 lines branches/zip: Fix Bug synopsis and remove explanation ------------------------------------------------------------------------ r4292 | marko | 2009-02-25 12:09:15 +0200 (Wed, 25 Feb 2009) | 25 lines branches/zip: Correct the initialization of the memory subsystem once again, to finally put Issue #181 to rest. Revert some parts of r4274. It is best not to call ut_malloc() before srv_general_init(). mem_init(): Do not call ut_mem_init(). srv_general_init(): Initialize the memory subsystem in two phases: first ut_mem_init(), then mem_init(). This is because os_sync_init() and sync_init() depend on ut_mem_init() and mem_init() depends on os_sync_init() or sync_init(). srv_parse_data_file_paths_and_sizes(), srv_parse_log_group_home_dirs(): Remove the output parameters. Assign to the global variables directly. Allocate memory with malloc() instead of ut_malloc(), because these functions will be called before srv_general_init(). srv_free_paths_and_sizes(): New function, for cleaning up after srv_parse_data_file_paths_and_sizes() and srv_parse_log_group_home_dirs(). rb://92 approved by Sunny Bains ------------------------------------------------------------------------ r4297 | vasil | 2009-02-25 17:19:19 +0200 (Wed, 25 Feb 2009) | 4 lines branches/zip: White-space cleanup in the ChangeLog ------------------------------------------------------------------------ r4301 | vasil | 2009-02-25 21:33:32 +0200 (Wed, 25 Feb 2009) | 5 lines branches/zip: Do not output the commands that restore the environment because they depend on the state of the environment before the test starts executing. ------------------------------------------------------------------------ r4315 | vasil | 2009-02-26 09:21:20 +0200 (Thu, 26 Feb 2009) | 5 lines branches/zip: Apply any necessary patches to the mysql tree at the end of setup.sh This step was previously done manually (and sometimes forgotten). ------------------------------------------------------------------------ r4319 | marko | 2009-02-26 23:27:51 +0200 (Thu, 26 Feb 2009) | 6 lines branches/zip: btr_check_blob_fil_page_type(): Do not report FIL_PAGE_TYPE mismatch even when purging a BLOB. Heavy users may have large data files created with MySQL 5.0 or earlier, and they don not want to have the error log flooded with such messages. This fixes Issue #182. ------------------------------------------------------------------------ r4320 | inaam | 2009-02-27 02:13:19 +0200 (Fri, 27 Feb 2009) | 8 lines branches/zip This is to revert the changes made to the plug.in (r4251) as a fix for issue# 178. Changes to plug.in will not propogate to a plugin installation unless autotools are rerun which is unacceptable. A fix for issue# 178 will be committed in a separate commit. ------------------------------------------------------------------------ r4321 | inaam | 2009-02-27 02:16:46 +0200 (Fri, 27 Feb 2009) | 6 lines branches/zip This is a fix for issue#178. Instead of using UNIV_LINUX which is defined through CFLAGS we use compiler generated define __linux__ that is effective for both .c and .cc files. ------------------------------------------------------------------------ r4324 | vasil | 2009-02-27 13:27:18 +0200 (Fri, 27 Feb 2009) | 39 lines branches/zip: Add FreeBSD to the list of the operating systems that have sizeof(pthread_t) == sizeof(void*) (i.e. word size). On FreeBSD pthread_t is defined like: /usr/include/sys/_pthreadtypes.h: typedef struct pthread *pthread_t; I did the following tests (per Inaam's recommendation): a) appropriate version of GCC is available on that platform (4.1.2 or higher for atomics to be available) On FreeBSD 6.x the default compiler is 3.4.6, on FreeBSD 7.x the default one is 4.2.1. One can always install the version of choice from the ports collection. If gcc 3.x is used then HAVE_GCC_ATOMIC_BUILTINS will not be defined and thus the change I am committing will make no difference. b) find out if sizeof(pthread_t) == sizeof(long) On 32 bit both are 4 bytes, on 64 bit both are 8 bytes. c) find out the compiler generated platform define (e.g.: __aix, __sunos__ etc.) The macro is __FreeBSD__. d) patch univ.i with the appropriate platform define e) build the mysql f) ensure it is using atomic builtins (look at the err.log message at system startup. It should say we are using atomics for both mutexes and rw-locks) g) do sanity testing (keeping in view the smp changes) I ran the mysql-test suite. All tests pass. ------------------------------------------------------------------------ r4353 | vasil | 2009-03-05 09:27:29 +0200 (Thu, 05 Mar 2009) | 6 lines branches/zip: As suggested by Ken, print a message that says that the Google SMP patch (GCC atomics) is disabled if it is. Also extend the message when the patch is partially enabled to make it clear that it is partially enabled. ------------------------------------------------------------------------ r4356 | vasil | 2009-03-05 13:49:51 +0200 (Thu, 05 Mar 2009) | 4 lines branches/zip: Fix typo made in r4353. ------------------------------------------------------------------------ r4357 | vasil | 2009-03-05 16:38:59 +0200 (Thu, 05 Mar 2009) | 23 lines branches/zip: Implement a check whether pthread_t objects can be used by GCC atomic builtin functions. This check is implemented in plug.in and defines the macro HAVE_ATOMIC_PTHREAD_T. This macro is checked in univ.i and the relevant part of the code enabled (the one that uses GCC atomics against pthread_t objects). In addition to this, the same program that is compiled as part of the plug.in check is added in ut/ut0auxconf.c. In the InnoDB Plugin source archives that are shipped to the users, a generated Makefile.in is added. That Makefile.in will be modified to compile ut/ut0auxconf.c and define the macro HAVE_ATOMIC_PTHREAD_T if the compilation succeeds. I.e. Makefile.in will emulate the work that is done by plug.in. This is done in order to make the check happen and HAVE_ATOMIC_PTHREAD_T eventually defined without regenerating MySQL's ./configure from ./storage/innobase/plug.in. The point is not to ask users to install the autotools and regenerate ./configure. rb://95 Approved by: Marko ------------------------------------------------------------------------ r4360 | vasil | 2009-03-05 22:23:17 +0200 (Thu, 05 Mar 2009) | 21 lines branches/zip: Merge revisions 4287:4357 from branches/5.1: ------------------------------------------------------------------------ r4325 | sunny | 2009-03-02 02:28:52 +0200 (Mon, 02 Mar 2009) | 10 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/mysql-test/innodb-autoinc.result M /branches/5.1/mysql-test/innodb-autoinc.test branches/5.1: Bug#43203: Overflow from auto incrementing causes server segv It was not a SIGSEGV but an assertion failure. The assertion was checking the invariant that *first_value passed in by MySQL doesn't contain a value that is greater than the max value for that type. The assertion has been changed to a check and if the value is greater than the max we report a generic AUTOINC failure. rb://93 Approved by Heikki ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4361 | vasil | 2009-03-05 22:27:54 +0200 (Thu, 05 Mar 2009) | 30 lines branches/zip: Merge revision 4358 from branches/5.1 (resolving a conflict): ------------------------------------------------------------------------ r4358 | vasil | 2009-03-05 21:21:10 +0200 (Thu, 05 Mar 2009) | 21 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: Merge a change from MySQL: ------------------------------------------------------------ revno: 2728.19.1 committer: Alfranio Correia <alfranio.correia@sun.com> branch nick: mysql-5.1-bugteam timestamp: Tue 2009-02-03 11:36:46 +0000 message: BUG#42445 Warning messages in innobase/handler/ha_innodb.cc There was a type casting problem in the storage/innobase/handler/ha_innodb.cc, (int ha_innobase::write_row(...)). Innobase uses has an internal error variable of type 'ulint' while mysql uses an 'int'. To fix the problem the function manipulates an error variable of type 'ulint' and only casts it into 'int' when needs to return the value. modified: storage/innobase/handler/ha_innodb.cc ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4362 | vasil | 2009-03-05 22:29:07 +0200 (Thu, 05 Mar 2009) | 23 lines branches/zip: Merge revision 4359 from branches/5.1: ------------------------------------------------------------------------ r4359 | vasil | 2009-03-05 21:42:01 +0200 (Thu, 05 Mar 2009) | 14 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: Merge a change from MySQL: ------------------------------------------------------------ revno: 2747 committer: Timothy Smith <timothy.smith@sun.com> branch nick: 51 timestamp: Fri 2009-01-16 17:49:07 +0100 message: Add another cast to ignore int/ulong difference in error types, silence warning on Win64 modified: storage/innobase/handler/ha_innodb.cc ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4363 | vasil | 2009-03-05 22:31:37 +0200 (Thu, 05 Mar 2009) | 4 lines branches/zip: Add ChangeLog entry for the bugfix in c4360. ------------------------------------------------------------------------ r4378 | calvin | 2009-03-09 10:10:17 +0200 (Mon, 09 Mar 2009) | 7 lines branches/zip: remove compile flag MYSQL_SERVER for dynamic plugin The dynamic plugin on Windows used to be built with MYSQL_SERVER compile flag, while it is not the case for other platforms. r3797 assumed MYSQL_SERVER was not defined for dynamic plugin, which introduced the engine crash during dropping a database. ------------------------------------------------------------------------ r4396 | marko | 2009-03-12 09:22:27 +0200 (Thu, 12 Mar 2009) | 3 lines branches/zip: btr_store_big_rec_extern_fields(): Initialize FIL_PAGE_TYPE in a separate redo log entry. This will make ibbackup --apply-log debugging easier. ------------------------------------------------------------------------ r4397 | marko | 2009-03-12 09:26:11 +0200 (Thu, 12 Mar 2009) | 3 lines branches/zip: trx_sys_create_doublewrite_buf(): As the dummy change, initialize FIL_PAGE_TYPE. This will make it easier to write the debug assertions for ibbackup --apply-log. ------------------------------------------------------------------------ r4401 | marko | 2009-03-12 10:26:40 +0200 (Thu, 12 Mar 2009) | 19 lines branches/zip: Merge revisions 4359:4400 from branches/5.1: ------------------------------------------------------------------------ r4399 | marko | 2009-03-12 09:38:05 +0200 (Thu, 12 Mar 2009) | 2 lines branches/5.1: row_sel_get_clust_rec_for_mysql(): Store the cursor position also for unlock_row(). (Bug #39320) ------------------------------------------------------------------------ r4400 | marko | 2009-03-12 10:06:44 +0200 (Thu, 12 Mar 2009) | 5 lines branches/5.1: Fix a bug in multi-table semi-consistent reads. Remember the acquired record locks per table handle (row_prebuilt_t) rather than per transaction (trx_t), so that unlock_row should successfully unlock all non-matching rows in multi-table operations. This deficiency was found while investigating Bug #39320. ------------------------------------------------------------------------ These were submitted as rb://94 and rb://96 and approved by Heikki Tuuri. ------------------------------------------------------------------------ r4455 | marko | 2009-03-16 11:43:34 +0200 (Mon, 16 Mar 2009) | 2 lines branches/zip: UT_LIST_VALIDATE(): Add the parameter ASSERTION and adjust all callers. ------------------------------------------------------------------------ r4456 | marko | 2009-03-16 12:59:25 +0200 (Mon, 16 Mar 2009) | 6 lines branches/zip: UT_LIST_VALIDATE(): Assert that the link is non-NULL before dereferencing it. In this way, ut_list_node_313 will be pointing to the last non-NULL list item at the time of the assertion failure. (gcc-4.3.2 -O3 seems to optimize the common subexpressions and make the variable NULL, though.) ------------------------------------------------------------------------ r4457 | marko | 2009-03-16 14:12:02 +0200 (Mon, 16 Mar 2009) | 2 lines branches/zip: sync_thread_add_level(): Make the assertions about level == SYNC_BUF_BLOCK more readable. ------------------------------------------------------------------------ r4461 | vasil | 2009-03-17 09:38:19 +0200 (Tue, 17 Mar 2009) | 6 lines branches/zip: Remove mysql-test/patches/bug32625.diff because that bug was fixed in the mysql repository (1 year and 4 months after sending them the simple patch!). See http://bugs.mysql.com/32625 ------------------------------------------------------------------------ r4465 | marko | 2009-03-17 12:34:19 +0200 (Tue, 17 Mar 2009) | 1 line branches/zip: buf0buddy.c: Add and adjust some debug assertions. ------------------------------------------------------------------------ r4473 | vasil | 2009-03-17 15:50:30 +0200 (Tue, 17 Mar 2009) | 5 lines branches/zip: Increment the InnoDB Plugin version from 1.0.3 to 1.0.4 now that 1.0.3 has been released. ------------------------------------------------------------------------ r4478 | vasil | 2009-03-18 11:53:53 +0200 (Wed, 18 Mar 2009) | 5 lines branches/zip: Remove mysql-test/patches/bug41893.diff because that bug has been fixed in the MySQL repository, see http://bugs.mysql.com/41893. ------------------------------------------------------------------------ r4479 | marko | 2009-03-18 12:43:54 +0200 (Wed, 18 Mar 2009) | 2 lines branches/zip: buf_LRU_block_remove_hashed_page(): Add some debug assertions. ------------------------------------------------------------------------ r4480 | marko | 2009-03-18 14:32:13 +0200 (Wed, 18 Mar 2009) | 1 line branches/zip: buf_buddy_free_low(): Correct the function comment. ------------------------------------------------------------------------ r4482 | marko | 2009-03-19 15:23:32 +0200 (Thu, 19 Mar 2009) | 12 lines branches/zip: Merge revisions 4400:4481 from branches/5.1: ------------------------------------------------------------------------ r4481 | marko | 2009-03-19 15:01:48 +0200 (Thu, 19 Mar 2009) | 6 lines branches/5.1: row_unlock_for_mysql(): Do not unlock records that were modified by the current transaction. This bug was introduced or unmasked in r4400. rb://97 approved by Heikki Tuuri ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4490 | marko | 2009-03-20 12:33:33 +0200 (Fri, 20 Mar 2009) | 4 lines branches/zip: Non-functional change for reducing dependencies in InnoDB Hot Backup: Replace srv_sys->dummy_ind1 and srv_sys->dummy_ind2 with dict_ind_redundant and dict_ind_compact, initialized in dict_init(). ------------------------------------------------------------------------ r4491 | marko | 2009-03-20 12:45:18 +0200 (Fri, 20 Mar 2009) | 2 lines branches/zip: Add const qualifiers or in/out comments to some function parameters in log0log. ------------------------------------------------------------------------ r4492 | marko | 2009-03-20 12:52:14 +0200 (Fri, 20 Mar 2009) | 5 lines branches/zip: page_validate(): Always report the space id and the name of the index. In Hot Backup, do not invoke comparison functions, as MySQL collations will be unavailable. ------------------------------------------------------------------------ r4493 | marko | 2009-03-20 13:24:06 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: Replace fil_get_space_for_id_low() with fil_space_get_by_id(). ------------------------------------------------------------------------ r4494 | marko | 2009-03-20 13:51:35 +0200 (Fri, 20 Mar 2009) | 3 lines branches/zip: fil0fil.c: Refer to fil_system directly, not via local vars. This eliminates some "unused variable" warnings when building InnoDB Hot Backup in such a way that all mutex operations are no-ops. ------------------------------------------------------------------------ r4495 | marko | 2009-03-20 14:15:52 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: innobase_get_at_most_n_mbchars(): Declare in ha_prototypes.h. ------------------------------------------------------------------------ r4496 | marko | 2009-03-20 14:48:26 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: recv_recover_page(): Remove compile-time constant parameters. ------------------------------------------------------------------------ r4497 | marko | 2009-03-20 14:56:19 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: recv_sys_init(): Remove a compile-time constant parameter. ------------------------------------------------------------------------ r4498 | marko | 2009-03-20 15:08:05 +0200 (Fri, 20 Mar 2009) | 4 lines branches/zip: Non-functional change: Add const qualifiers. log_block_checksum_is_ok_or_old_format(), recv_sys_add_to_parsing_buf(): The log block is read-only. Make it const. ------------------------------------------------------------------------ r4499 | marko | 2009-03-20 15:10:25 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: recv_scan_log_recs(): Remove a compile-time constant parameter. ------------------------------------------------------------------------ r4500 | marko | 2009-03-20 15:47:17 +0200 (Fri, 20 Mar 2009) | 1 line branches/zip: fil_init(): Add the parameter hash_size. ------------------------------------------------------------------------ r4501 | vasil | 2009-03-20 16:50:41 +0200 (Fri, 20 Mar 2009) | 4 lines branches/zip: Add any entry about the release of 1.0.3 in the ChangeLog. ------------------------------------------------------------------------ r4515 | marko | 2009-03-23 10:49:53 +0200 (Mon, 23 Mar 2009) | 1 line branches/zip: hash_table_t: adaptive: Remove from UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4516 | marko | 2009-03-23 10:57:16 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Define and use ASSERT_HASH_MUTEX_OWN. Make it a no-op in UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4517 | marko | 2009-03-23 11:07:20 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Define and use PAGE_ZIP_MATCH. In UNIV_HOTBACKUP builds, assume fixed allocation. ------------------------------------------------------------------------ r4521 | marko | 2009-03-23 12:05:47 +0200 (Mon, 23 Mar 2009) | 1 line branches/zip: buf_page_print(): Clean up the code #ifdef UNIV_HOTBACKUP. ------------------------------------------------------------------------ r4522 | marko | 2009-03-23 12:20:50 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Exclude some operating system interface code from UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4523 | marko | 2009-03-23 13:00:43 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Remove the remaining references to hash_table_t::adapive from UNIV_HOTBACKUP builds. This should have been done in r4515. ------------------------------------------------------------------------ r4524 | marko | 2009-03-23 14:05:18 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Enclose recv_recovery_from_backup_on and recv_recovery_from_backup_is_on() in #ifdef UNIV_LOG_ARCHIVE. ------------------------------------------------------------------------ r4525 | marko | 2009-03-23 14:57:45 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: recv_parse_or_apply_log_rec_body(): Add debug assertions ensuring that FIL_PAGE_TYPE makes sense when applying log records. ------------------------------------------------------------------------ r4526 | marko | 2009-03-23 16:21:34 +0200 (Mon, 23 Mar 2009) | 2 lines branches/zip: Remove unneeded definitions and dependencies from UNIV_HOTBACKUP builds. ------------------------------------------------------------------------ r4527 | calvin | 2009-03-23 23:15:33 +0200 (Mon, 23 Mar 2009) | 5 lines branches/zip: adjust build files on Windows Adjust the patch positions based on the latest MySQL source. Also add the patches to the .bat files for vs9. ------------------------------------------------------------------------
17 years ago
20 years ago
20 years ago
20 years ago
20 years ago
11 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
20 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
20 years ago
20 years ago
20 years ago
MDEV-24258 Merge dict_sys.mutex into dict_sys.latch In the parent commit, dict_sys.latch could theoretically have been replaced with a mutex. But, we can do better and merge dict_sys.mutex into dict_sys.latch. Generally, every occurrence of dict_sys.mutex_lock() will be replaced with dict_sys.lock(). The PERFORMANCE_SCHEMA instrumentation for dict_sys_mutex will be removed along with dict_sys.mutex. The dict_sys.latch will remain instrumented as dict_operation_lock. Some use of dict_sys.lock() will be replaced with dict_sys.freeze(), which we will reintroduce for the new shared mode. Most notably, concurrent table lookups are possible as long as the tables are present in the dict_sys cache. In particular, this will allow more concurrency among InnoDB purge workers. Because dict_sys.mutex will no longer 'throttle' the threads that purge InnoDB transaction history, a performance degradation may be observed unless innodb_purge_threads=1. The table cache eviction policy will become FIFO-like, similar to what happened to fil_system.LRU in commit 45ed9dd957eebc7fc84feb2509f4aa6baa908a95. The name of the list dict_sys.table_LRU will become somewhat misleading; that list contains tables that may be evicted, even though the eviction policy no longer is least-recently-used but first-in-first-out. (Note: Tables can never be evicted as long as locks exist on them or the tables are in use by some thread.) As demonstrated by the test perfschema.sxlock_func, there will be less contention on dict_sys.latch, because some previous use of exclusive latches will be replaced with shared latches. fts_parse_sql_no_dict_lock(): Replaced with pars_sql(). fts_get_table_name_prefix(): Merged to fts_optimize_create(). dict_stats_update_transient_for_index(): Deduplicated some code. ha_innobase::info_low(), dict_stats_stop_bg(): Use a combination of dict_sys.latch and table->stats_mutex_lock() to cover the changes of BG_STAT_SHOULD_QUIT, because the flag is being read in dict_stats_update_persistent() while not holding dict_sys.latch. row_discard_tablespace_for_mysql(): Protect stats_bg_flag by exclusive dict_sys.latch, like most other code does. row_quiesce_table_has_fts_index(): Remove unnecessary mutex acquisition. FLUSH TABLES...FOR EXPORT is protected by MDL. row_import::set_root_by_heuristic(): Remove unnecessary mutex acquisition. ALTER TABLE...IMPORT TABLESPACE is protected by MDL. row_ins_sec_index_entry_low(): Replace a call to dict_set_corrupted_index_cache_only(). Reads of index->type were not really protected by dict_sys.mutex, and writes (flagging an index corrupted) should be extremely rare. dict_stats_process_entry_from_defrag_pool(): Only freeze the dictionary, do not lock it exclusively. dict_stats_wait_bg_to_stop_using_table(), DICT_BG_YIELD: Remove trx. We can simply invoke dict_sys.unlock() and dict_sys.lock() directly. dict_acquire_mdl_shared()<trylock=false>: Assert that dict_sys.latch is only held in shared more, not exclusive mode. Only acquire it in exclusive mode if the table needs to be loaded to the cache. dict_sys_t::acquire(): Remove. Relocating elements in dict_sys.table_LRU would require holding an exclusive latch, which we want to avoid for performance reasons. dict_sys_t::allow_eviction(): Add the table first to dict_sys.table_LRU, to compensate for the removal of dict_sys_t::acquire(). This function is only invoked by INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS. dict_table_open_on_id(), dict_table_open_on_name(): If dict_locked=false, try to acquire dict_sys.latch in shared mode. Only acquire the latch in exclusive mode if the table is not found in the cache. Reviewed by: Thirunarayanan Balathandayuthapani
4 years ago
MDEV-24258 Merge dict_sys.mutex into dict_sys.latch In the parent commit, dict_sys.latch could theoretically have been replaced with a mutex. But, we can do better and merge dict_sys.mutex into dict_sys.latch. Generally, every occurrence of dict_sys.mutex_lock() will be replaced with dict_sys.lock(). The PERFORMANCE_SCHEMA instrumentation for dict_sys_mutex will be removed along with dict_sys.mutex. The dict_sys.latch will remain instrumented as dict_operation_lock. Some use of dict_sys.lock() will be replaced with dict_sys.freeze(), which we will reintroduce for the new shared mode. Most notably, concurrent table lookups are possible as long as the tables are present in the dict_sys cache. In particular, this will allow more concurrency among InnoDB purge workers. Because dict_sys.mutex will no longer 'throttle' the threads that purge InnoDB transaction history, a performance degradation may be observed unless innodb_purge_threads=1. The table cache eviction policy will become FIFO-like, similar to what happened to fil_system.LRU in commit 45ed9dd957eebc7fc84feb2509f4aa6baa908a95. The name of the list dict_sys.table_LRU will become somewhat misleading; that list contains tables that may be evicted, even though the eviction policy no longer is least-recently-used but first-in-first-out. (Note: Tables can never be evicted as long as locks exist on them or the tables are in use by some thread.) As demonstrated by the test perfschema.sxlock_func, there will be less contention on dict_sys.latch, because some previous use of exclusive latches will be replaced with shared latches. fts_parse_sql_no_dict_lock(): Replaced with pars_sql(). fts_get_table_name_prefix(): Merged to fts_optimize_create(). dict_stats_update_transient_for_index(): Deduplicated some code. ha_innobase::info_low(), dict_stats_stop_bg(): Use a combination of dict_sys.latch and table->stats_mutex_lock() to cover the changes of BG_STAT_SHOULD_QUIT, because the flag is being read in dict_stats_update_persistent() while not holding dict_sys.latch. row_discard_tablespace_for_mysql(): Protect stats_bg_flag by exclusive dict_sys.latch, like most other code does. row_quiesce_table_has_fts_index(): Remove unnecessary mutex acquisition. FLUSH TABLES...FOR EXPORT is protected by MDL. row_import::set_root_by_heuristic(): Remove unnecessary mutex acquisition. ALTER TABLE...IMPORT TABLESPACE is protected by MDL. row_ins_sec_index_entry_low(): Replace a call to dict_set_corrupted_index_cache_only(). Reads of index->type were not really protected by dict_sys.mutex, and writes (flagging an index corrupted) should be extremely rare. dict_stats_process_entry_from_defrag_pool(): Only freeze the dictionary, do not lock it exclusively. dict_stats_wait_bg_to_stop_using_table(), DICT_BG_YIELD: Remove trx. We can simply invoke dict_sys.unlock() and dict_sys.lock() directly. dict_acquire_mdl_shared()<trylock=false>: Assert that dict_sys.latch is only held in shared more, not exclusive mode. Only acquire it in exclusive mode if the table needs to be loaded to the cache. dict_sys_t::acquire(): Remove. Relocating elements in dict_sys.table_LRU would require holding an exclusive latch, which we want to avoid for performance reasons. dict_sys_t::allow_eviction(): Add the table first to dict_sys.table_LRU, to compensate for the removal of dict_sys_t::acquire(). This function is only invoked by INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS. dict_table_open_on_id(), dict_table_open_on_name(): If dict_locked=false, try to acquire dict_sys.latch in shared mode. Only acquire the latch in exclusive mode if the table is not found in the cache. Reviewed by: Thirunarayanan Balathandayuthapani
4 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
10 years ago
20 years ago
20 years ago
20 years ago
branches/zip: Initialize dfield_t::ext as soon as possible. This should fix the bugs introduced in r1591. row_rec_to_index_entry_low(): Clear "n_ext". Do not allow it to be NULL. Add const qualifier to dict_index_t*. row_rec_to_index_entry(): Add the parameters "offsets" and "n_ext". btr_cur_optimistic_update(): Add an assertion that there are no externally stored columns. Remove the unreachable call to btr_cur_unmark_extern_fields() and the preceding unnecessary call to rec_get_offsets(). btr_push_update_extern_fields(): Remove the parameters index, offsets. Only report the additional externally stored columns of the update vector. row_build(), trx_undo_rec_get_partial_row(): Flag externally stored columns also with dfield_set_ext(). rec_copy_prefix_to_dtuple(): Assert that there are no externally stored columns in the prefix. row_build_row_ref(): Note and assert that the index is a secondary index, and assert that there are no externally stored columns. row_build_row_ref_fast(): Assert that there are no externally stored columns. rec_offs_get_n_alloc(): Expose the function. row_build_row_ref_in_tuple(): Assert that there are no externally stored columns in a record of a secondary index. row_build_row_ref_from_row(): Assert that there are no externally stored columns. row_upd_check_references_constraints(): Add the parameter offsets, to avoid a redundant call to rec_get_offsets(). row_upd_del_mark_clust_rec(): Add the parameter offsets. Remove duplicated code. row_ins_index_entry_set_vals(): Copy the external storage flag. sel_pop_prefetched_row(): Assert that there are no externally stored columns. row_scan_and_check_index(): Copy offsets to a temporary heap across the invocation of row_rec_to_index_entry().
18 years ago
20 years ago
20 years ago
20 years ago
branches/zip: Initialize dfield_t::ext as soon as possible. This should fix the bugs introduced in r1591. row_rec_to_index_entry_low(): Clear "n_ext". Do not allow it to be NULL. Add const qualifier to dict_index_t*. row_rec_to_index_entry(): Add the parameters "offsets" and "n_ext". btr_cur_optimistic_update(): Add an assertion that there are no externally stored columns. Remove the unreachable call to btr_cur_unmark_extern_fields() and the preceding unnecessary call to rec_get_offsets(). btr_push_update_extern_fields(): Remove the parameters index, offsets. Only report the additional externally stored columns of the update vector. row_build(), trx_undo_rec_get_partial_row(): Flag externally stored columns also with dfield_set_ext(). rec_copy_prefix_to_dtuple(): Assert that there are no externally stored columns in the prefix. row_build_row_ref(): Note and assert that the index is a secondary index, and assert that there are no externally stored columns. row_build_row_ref_fast(): Assert that there are no externally stored columns. rec_offs_get_n_alloc(): Expose the function. row_build_row_ref_in_tuple(): Assert that there are no externally stored columns in a record of a secondary index. row_build_row_ref_from_row(): Assert that there are no externally stored columns. row_upd_check_references_constraints(): Add the parameter offsets, to avoid a redundant call to rec_get_offsets(). row_upd_del_mark_clust_rec(): Add the parameter offsets. Remove duplicated code. row_ins_index_entry_set_vals(): Copy the external storage flag. sel_pop_prefetched_row(): Assert that there are no externally stored columns. row_scan_and_check_index(): Copy offsets to a temporary heap across the invocation of row_rec_to_index_entry().
18 years ago
20 years ago
20 years ago
20 years ago
11 years ago
20 years ago
MDEV-25919: Lock tables before acquiring dict_sys.latch In commit 1bd681c8b3c5213ce1f7976940a7dc38b48a0d39 (MDEV-25506 part 3) we introduced a "fake instant timeout" when a transaction would wait for a table or record lock while holding dict_sys.latch. This prevented a deadlock of the server but could cause bogus errors for operations on the InnoDB persistent statistics tables. A better fix is to ensure that whenever a transaction is being executed in the InnoDB internal SQL parser (which will for now require dict_sys.latch to be held), it will already have acquired all locks that could be required for the execution. So, we will acquire the following locks upfront, before acquiring dict_sys.latch: (1) MDL on the affected user table (acquired by the SQL layer) (2) If applicable (not for RENAME TABLE): InnoDB table lock (3) If persistent statistics are going to be modified: (3.a) MDL_SHARED on mysql.innodb_table_stats, mysql.innodb_index_stats (3.b) exclusive table locks on the statistics tables (4) Exclusive table locks on the InnoDB data dictionary tables (not needed in ANALYZE TABLE and the like) Note: Acquiring exclusive locks on the statistics tables may cause more locking conflicts between concurrent DDL operations. Notably, RENAME TABLE will lock the statistics tables even if no persistent statistics are enabled for the table. DROP DATABASE will only acquire locks on statistics tables if persistent statistics are enabled for the tables on which the SQL layer is invoking ha_innobase::delete_table(). For any "garbage collection" in innodb_drop_database(), a timeout while acquiring locks on the statistics tables will result in any statistics not being deleted for any tables that the SQL layer did not know about. If innodb_defragment=ON, information may be written to the statistics tables even for tables for which InnoDB persistent statistics are disabled. But, DROP TABLE will no longer attempt to delete that information if persistent statistics are not enabled for the table. This change should also fix the hangs related to InnoDB persistent statistics and STATS_AUTO_RECALC (MDEV-15020) as well as a bug that running ALTER TABLE on the statistics tables concurrently with running ALTER TABLE on InnoDB tables could cause trouble. lock_rec_enqueue_waiting(), lock_table_enqueue_waiting(): Do not issue a fake instant timeout error when the transaction is holding dict_sys.latch. Instead, assert that the dict_sys.latch is never being held here. lock_sys_tables(): A new function to acquire exclusive locks on all dictionary tables, in case DROP TABLE or similar operation is being executed. Locking non-hard-coded tables is optional to avoid a crash in row_merge_drop_temp_indexes(). The SYS_VIRTUAL table was introduced in MySQL 5.7 and MariaDB Server 10.2. Normally, we require all these dictionary tables to exist before executing any DDL, but the function row_merge_drop_temp_indexes() is an exception. When upgrading from MariaDB Server 10.1 or MySQL 5.6 or earlier, the table SYS_VIRTUAL would not exist at this point. ha_innobase::commit_inplace_alter_table(): Invoke log_write_up_to() while not holding dict_sys.latch. dict_sys_t::remove(), dict_table_close(): No longer try to drop index stubs that were left behind by aborted online ADD INDEX. Such indexes should be dropped from the InnoDB data dictionary by row_merge_drop_indexes() as part of the failed DDL operation. Stubs for aborted indexes may only be left behind in the data dictionary cache. dict_stats_fetch_from_ps(): Use a normal read-only transaction. ha_innobase::delete_table(), ha_innobase::truncate(), fts_lock_table(): While waiting for purge to stop using the table, do not hold dict_sys.latch. ha_innobase::delete_table(): Implement a work-around for the rollback of ALTER TABLE...ADD PARTITION. MDL_EXCLUSIVE would not be held if ALTER TABLE hits lock_wait_timeout while trying to upgrade the MDL due to a conflicting LOCK TABLES, such as in the first ALTER TABLE in the test case of Bug#53676 in parts.partition_special_innodb. Therefore, we must explicitly stop purge, because it would not be stopped by MDL. dict_stats_func(), btr_defragment_chunk(): Allocate a THD so that we can acquire MDL on the InnoDB persistent statistics tables. mysqltest_embedded: Invoke ha_pre_shutdown() before free_used_memory() in order to avoid ASAN heap-use-after-free related to acquire_thd(). trx_t::dict_operation_lock_mode: Changed the type to bool. row_mysql_lock_data_dictionary(), row_mysql_unlock_data_dictionary(): Implemented as macros. rollback_inplace_alter_table(): Apply an infinite timeout to lock waits. innodb_thd_increment_pending_ops(): Wrapper for thd_increment_pending_ops(). Never attempt async operation for InnoDB background threads, such as the trx_t::commit() in dict_stats_process_entry_from_recalc_pool(). lock_sys_t::cancel(trx_t*): Make dictionary transactions immune to KILL. lock_wait(): Make dictionary transactions immune to KILL, and to lock wait timeout when waiting for locks on dictionary tables. parts.partition_special_innodb: Use lock_wait_timeout=0 to instantly get ER_LOCK_WAIT_TIMEOUT. main.mdl: Filter out MDL on InnoDB persistent statistics tables Reviewed by: Thirunarayanan Balathandayuthapani
4 years ago
20 years ago
20 years ago
MDEV-25919 preparation: Various cleanup que_eval_sql(): Remove the parameter lock_dict. The only caller with lock_dict=true was dict_stats_exec_sql(), which will now explicitly invoke dict_sys.lock() and dict_sys.unlock() by itself. row_import_cleanup(): Do not unnecessarily lock the dictionary. Concurrent access to the table during ALTER TABLE...IMPORT TABLESPACE is prevented by MDL and the fact that there cannot exist any undo log or change buffer records that would refer to the table or tablespace. row_import_for_mysql(): Do not unnecessarily lock the dictionary while accessing fil_system. Thanks to MDL_EXCLUSIVE that was acquired by the SQL layer, only one IMPORT may be in effect for the table name. row_quiesce_set_state(): Do not unnecessarily lock the dictionary. The dict_table_t::quiesce state is documented to be protected by all index latches, which we are acquiring. dict_table_close(): Introduce a simpler variant with fewer parameters. dict_table_close(): Reduce the amount of calls. We can simply invoke dict_table_t::release() on startup or in DDL operations, or when the table is inaccessible. In none of these cases, there is no need to invalidate the InnoDB persistent statistics. pars_info_t::graph_owns_us: Remove (unused). pars_info_free(): Define inline. fts_delete(), trx_t::evict_table(), row_prebuilt_free(), row_rename_table_for_mysql(): Simplify. row_mysql_lock_data_dictionary(): Remove some references; use dict_sys.lock() and dict_sys.unlock() instead. row_mysql_lock_table(): Remove. Use lock_table_for_trx() instead. ha_innobase::check_if_supported_inplace_alter(), row_create_table_for_mysql(): Simply assert dict_sys.sys_tables_exist(). In commit 49e2c8f0a6fefdeac50925f758090d6bd099768d and commit 1bd681c8b3c5213ce1f7976940a7dc38b48a0d39 srv_start() actually guarantees that the system tables will exist, or the server is in read-only mode, or startup will fail. Reviewed by: Thirunarayanan Balathandayuthapani
4 years ago
20 years ago
20 years ago
MDEV-25919: Lock tables before acquiring dict_sys.latch In commit 1bd681c8b3c5213ce1f7976940a7dc38b48a0d39 (MDEV-25506 part 3) we introduced a "fake instant timeout" when a transaction would wait for a table or record lock while holding dict_sys.latch. This prevented a deadlock of the server but could cause bogus errors for operations on the InnoDB persistent statistics tables. A better fix is to ensure that whenever a transaction is being executed in the InnoDB internal SQL parser (which will for now require dict_sys.latch to be held), it will already have acquired all locks that could be required for the execution. So, we will acquire the following locks upfront, before acquiring dict_sys.latch: (1) MDL on the affected user table (acquired by the SQL layer) (2) If applicable (not for RENAME TABLE): InnoDB table lock (3) If persistent statistics are going to be modified: (3.a) MDL_SHARED on mysql.innodb_table_stats, mysql.innodb_index_stats (3.b) exclusive table locks on the statistics tables (4) Exclusive table locks on the InnoDB data dictionary tables (not needed in ANALYZE TABLE and the like) Note: Acquiring exclusive locks on the statistics tables may cause more locking conflicts between concurrent DDL operations. Notably, RENAME TABLE will lock the statistics tables even if no persistent statistics are enabled for the table. DROP DATABASE will only acquire locks on statistics tables if persistent statistics are enabled for the tables on which the SQL layer is invoking ha_innobase::delete_table(). For any "garbage collection" in innodb_drop_database(), a timeout while acquiring locks on the statistics tables will result in any statistics not being deleted for any tables that the SQL layer did not know about. If innodb_defragment=ON, information may be written to the statistics tables even for tables for which InnoDB persistent statistics are disabled. But, DROP TABLE will no longer attempt to delete that information if persistent statistics are not enabled for the table. This change should also fix the hangs related to InnoDB persistent statistics and STATS_AUTO_RECALC (MDEV-15020) as well as a bug that running ALTER TABLE on the statistics tables concurrently with running ALTER TABLE on InnoDB tables could cause trouble. lock_rec_enqueue_waiting(), lock_table_enqueue_waiting(): Do not issue a fake instant timeout error when the transaction is holding dict_sys.latch. Instead, assert that the dict_sys.latch is never being held here. lock_sys_tables(): A new function to acquire exclusive locks on all dictionary tables, in case DROP TABLE or similar operation is being executed. Locking non-hard-coded tables is optional to avoid a crash in row_merge_drop_temp_indexes(). The SYS_VIRTUAL table was introduced in MySQL 5.7 and MariaDB Server 10.2. Normally, we require all these dictionary tables to exist before executing any DDL, but the function row_merge_drop_temp_indexes() is an exception. When upgrading from MariaDB Server 10.1 or MySQL 5.6 or earlier, the table SYS_VIRTUAL would not exist at this point. ha_innobase::commit_inplace_alter_table(): Invoke log_write_up_to() while not holding dict_sys.latch. dict_sys_t::remove(), dict_table_close(): No longer try to drop index stubs that were left behind by aborted online ADD INDEX. Such indexes should be dropped from the InnoDB data dictionary by row_merge_drop_indexes() as part of the failed DDL operation. Stubs for aborted indexes may only be left behind in the data dictionary cache. dict_stats_fetch_from_ps(): Use a normal read-only transaction. ha_innobase::delete_table(), ha_innobase::truncate(), fts_lock_table(): While waiting for purge to stop using the table, do not hold dict_sys.latch. ha_innobase::delete_table(): Implement a work-around for the rollback of ALTER TABLE...ADD PARTITION. MDL_EXCLUSIVE would not be held if ALTER TABLE hits lock_wait_timeout while trying to upgrade the MDL due to a conflicting LOCK TABLES, such as in the first ALTER TABLE in the test case of Bug#53676 in parts.partition_special_innodb. Therefore, we must explicitly stop purge, because it would not be stopped by MDL. dict_stats_func(), btr_defragment_chunk(): Allocate a THD so that we can acquire MDL on the InnoDB persistent statistics tables. mysqltest_embedded: Invoke ha_pre_shutdown() before free_used_memory() in order to avoid ASAN heap-use-after-free related to acquire_thd(). trx_t::dict_operation_lock_mode: Changed the type to bool. row_mysql_lock_data_dictionary(), row_mysql_unlock_data_dictionary(): Implemented as macros. rollback_inplace_alter_table(): Apply an infinite timeout to lock waits. innodb_thd_increment_pending_ops(): Wrapper for thd_increment_pending_ops(). Never attempt async operation for InnoDB background threads, such as the trx_t::commit() in dict_stats_process_entry_from_recalc_pool(). lock_sys_t::cancel(trx_t*): Make dictionary transactions immune to KILL. lock_wait(): Make dictionary transactions immune to KILL, and to lock wait timeout when waiting for locks on dictionary tables. parts.partition_special_innodb: Use lock_wait_timeout=0 to instantly get ER_LOCK_WAIT_TIMEOUT. main.mdl: Filter out MDL on InnoDB persistent statistics tables Reviewed by: Thirunarayanan Balathandayuthapani
4 years ago
MDEV-25919 preparation: Various cleanup que_eval_sql(): Remove the parameter lock_dict. The only caller with lock_dict=true was dict_stats_exec_sql(), which will now explicitly invoke dict_sys.lock() and dict_sys.unlock() by itself. row_import_cleanup(): Do not unnecessarily lock the dictionary. Concurrent access to the table during ALTER TABLE...IMPORT TABLESPACE is prevented by MDL and the fact that there cannot exist any undo log or change buffer records that would refer to the table or tablespace. row_import_for_mysql(): Do not unnecessarily lock the dictionary while accessing fil_system. Thanks to MDL_EXCLUSIVE that was acquired by the SQL layer, only one IMPORT may be in effect for the table name. row_quiesce_set_state(): Do not unnecessarily lock the dictionary. The dict_table_t::quiesce state is documented to be protected by all index latches, which we are acquiring. dict_table_close(): Introduce a simpler variant with fewer parameters. dict_table_close(): Reduce the amount of calls. We can simply invoke dict_table_t::release() on startup or in DDL operations, or when the table is inaccessible. In none of these cases, there is no need to invalidate the InnoDB persistent statistics. pars_info_t::graph_owns_us: Remove (unused). pars_info_free(): Define inline. fts_delete(), trx_t::evict_table(), row_prebuilt_free(), row_rename_table_for_mysql(): Simplify. row_mysql_lock_data_dictionary(): Remove some references; use dict_sys.lock() and dict_sys.unlock() instead. row_mysql_lock_table(): Remove. Use lock_table_for_trx() instead. ha_innobase::check_if_supported_inplace_alter(), row_create_table_for_mysql(): Simply assert dict_sys.sys_tables_exist(). In commit 49e2c8f0a6fefdeac50925f758090d6bd099768d and commit 1bd681c8b3c5213ce1f7976940a7dc38b48a0d39 srv_start() actually guarantees that the system tables will exist, or the server is in read-only mode, or startup will fail. Reviewed by: Thirunarayanan Balathandayuthapani
4 years ago
20 years ago
20 years ago
MDEV-13498 DELETE with CASCADE constraints takes long time / MDEV-13246 MDEV-13498 is a performance regression that was introduced in MariaDB 10.2.2 by commit fec844aca88e1c6b9c36bb0b811e92d9d023ffb9 which introduced some Galera-specific conditions that were being evaluated even if the write-set replication was not enabled. MDEV-13246 Stale rows despite ON DELETE CASCADE constraint is a correctness regression that was introduced by the same commit. Especially the subcondition !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE) which is equivalent to !parent || que_node_get_type(parent) != QUE_NODE_UPDATE makes little sense. If parent==NULL, the evaluation would proceed to the std::find() expression, which would dereference parent. Because no SIGSEGV was observed related to this, we can conclude that parent!=NULL always holds. But then, the condition would be equivalent to que_node_get_type(parent) != QUE_NODE_UPDATE which would not make sense either, because the std::find() expression is actually assuming the opposite when casting parent to upd_node_t*. It looks like this condition never worked properly, or that it was never properly tested, or both. wsrep_must_process_fk(): Helper function to check if FOREIGN KEY constraints need to be processed. Only evaluate the costly std::find() expression when write-set replication is enabled. Also, rely on operator<<(std::ostream&, const id_name_t&) and operator<<(std::ostream&, const table_name_t&) for pretty-printing index and table names. row_upd_sec_index_entry(): Add !wsrep_thd_is_BF() to the condition. This is applying part of "Galera MW-369 FK fixes" https://github.com/codership/mysql-wsrep/commit/f37b79c6dab101310a45a9e8cb23c0f98716da52 that is described by the following part of the commit comment: additionally: skipping wsrep_row_upd_check_foreign_constraint if thd has BF, essentially is applier or replaying This FK check would be needed only for populating parent row FK keys in write set, so no use for appliers
8 years ago
MDEV-13498 DELETE with CASCADE constraints takes long time / MDEV-13246 MDEV-13498 is a performance regression that was introduced in MariaDB 10.2.2 by commit fec844aca88e1c6b9c36bb0b811e92d9d023ffb9 which introduced some Galera-specific conditions that were being evaluated even if the write-set replication was not enabled. MDEV-13246 Stale rows despite ON DELETE CASCADE constraint is a correctness regression that was introduced by the same commit. Especially the subcondition !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE) which is equivalent to !parent || que_node_get_type(parent) != QUE_NODE_UPDATE makes little sense. If parent==NULL, the evaluation would proceed to the std::find() expression, which would dereference parent. Because no SIGSEGV was observed related to this, we can conclude that parent!=NULL always holds. But then, the condition would be equivalent to que_node_get_type(parent) != QUE_NODE_UPDATE which would not make sense either, because the std::find() expression is actually assuming the opposite when casting parent to upd_node_t*. It looks like this condition never worked properly, or that it was never properly tested, or both. wsrep_must_process_fk(): Helper function to check if FOREIGN KEY constraints need to be processed. Only evaluate the costly std::find() expression when write-set replication is enabled. Also, rely on operator<<(std::ostream&, const id_name_t&) and operator<<(std::ostream&, const table_name_t&) for pretty-printing index and table names. row_upd_sec_index_entry(): Add !wsrep_thd_is_BF() to the condition. This is applying part of "Galera MW-369 FK fixes" https://github.com/codership/mysql-wsrep/commit/f37b79c6dab101310a45a9e8cb23c0f98716da52 that is described by the following part of the commit comment: additionally: skipping wsrep_row_upd_check_foreign_constraint if thd has BF, essentially is applier or replaying This FK check would be needed only for populating parent row FK keys in write set, so no use for appliers
8 years ago
MDEV-13498 DELETE with CASCADE constraints takes long time / MDEV-13246 MDEV-13498 is a performance regression that was introduced in MariaDB 10.2.2 by commit fec844aca88e1c6b9c36bb0b811e92d9d023ffb9 which introduced some Galera-specific conditions that were being evaluated even if the write-set replication was not enabled. MDEV-13246 Stale rows despite ON DELETE CASCADE constraint is a correctness regression that was introduced by the same commit. Especially the subcondition !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE) which is equivalent to !parent || que_node_get_type(parent) != QUE_NODE_UPDATE makes little sense. If parent==NULL, the evaluation would proceed to the std::find() expression, which would dereference parent. Because no SIGSEGV was observed related to this, we can conclude that parent!=NULL always holds. But then, the condition would be equivalent to que_node_get_type(parent) != QUE_NODE_UPDATE which would not make sense either, because the std::find() expression is actually assuming the opposite when casting parent to upd_node_t*. It looks like this condition never worked properly, or that it was never properly tested, or both. wsrep_must_process_fk(): Helper function to check if FOREIGN KEY constraints need to be processed. Only evaluate the costly std::find() expression when write-set replication is enabled. Also, rely on operator<<(std::ostream&, const id_name_t&) and operator<<(std::ostream&, const table_name_t&) for pretty-printing index and table names. row_upd_sec_index_entry(): Add !wsrep_thd_is_BF() to the condition. This is applying part of "Galera MW-369 FK fixes" https://github.com/codership/mysql-wsrep/commit/f37b79c6dab101310a45a9e8cb23c0f98716da52 that is described by the following part of the commit comment: additionally: skipping wsrep_row_upd_check_foreign_constraint if thd has BF, essentially is applier or replaying This FK check would be needed only for populating parent row FK keys in write set, so no use for appliers
8 years ago
MDEV-13498 DELETE with CASCADE constraints takes long time / MDEV-13246 MDEV-13498 is a performance regression that was introduced in MariaDB 10.2.2 by commit fec844aca88e1c6b9c36bb0b811e92d9d023ffb9 which introduced some Galera-specific conditions that were being evaluated even if the write-set replication was not enabled. MDEV-13246 Stale rows despite ON DELETE CASCADE constraint is a correctness regression that was introduced by the same commit. Especially the subcondition !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE) which is equivalent to !parent || que_node_get_type(parent) != QUE_NODE_UPDATE makes little sense. If parent==NULL, the evaluation would proceed to the std::find() expression, which would dereference parent. Because no SIGSEGV was observed related to this, we can conclude that parent!=NULL always holds. But then, the condition would be equivalent to que_node_get_type(parent) != QUE_NODE_UPDATE which would not make sense either, because the std::find() expression is actually assuming the opposite when casting parent to upd_node_t*. It looks like this condition never worked properly, or that it was never properly tested, or both. wsrep_must_process_fk(): Helper function to check if FOREIGN KEY constraints need to be processed. Only evaluate the costly std::find() expression when write-set replication is enabled. Also, rely on operator<<(std::ostream&, const id_name_t&) and operator<<(std::ostream&, const table_name_t&) for pretty-printing index and table names. row_upd_sec_index_entry(): Add !wsrep_thd_is_BF() to the condition. This is applying part of "Galera MW-369 FK fixes" https://github.com/codership/mysql-wsrep/commit/f37b79c6dab101310a45a9e8cb23c0f98716da52 that is described by the following part of the commit comment: additionally: skipping wsrep_row_upd_check_foreign_constraint if thd has BF, essentially is applier or replaying This FK check would be needed only for populating parent row FK keys in write set, so no use for appliers
8 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
20 years ago
20 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
20 years ago
20 years ago
MDEV-11415 Remove excessive undo logging during ALTER TABLE…ALGORITHM=COPY If a crash occurs during ALTER TABLE…ALGORITHM=COPY, InnoDB would spend a lot of time rolling back writes to the intermediate copy of the table. To reduce the amount of busy work done, a work-around was introduced in commit fd069e2bb36a3c1c1f26d65dd298b07e6d83ac8b in MySQL 4.1.8 and 5.0.2, to commit the transaction after every 10,000 inserted rows. A proper fix would have been to disable the undo logging altogether and to simply drop the intermediate copy of the table on subsequent server startup. This is what happens in MariaDB 10.3 with MDEV-14717,MDEV-14585. In MariaDB 10.2, the intermediate copy of the table would be left behind with a name starting with the string #sql. This is a backport of a bug fix from MySQL 8.0.0 to MariaDB, contributed by jixianliang <271365745@qq.com>. Unlike recent MySQL, MariaDB supports ALTER IGNORE. For that operation InnoDB must for now keep the undo logging enabled, so that the latest row can be rolled back in case of an error. In Galera cluster, the LOAD DATA statement will retain the existing behaviour and commit the transaction after every 10,000 rows if the parameter wsrep_load_data_splitting=ON is set. The logic to do so (the wsrep_load_data_split() function and the call handler::extra(HA_EXTRA_FAKE_START_STMT)) are joint work by Ji Xianliang and Marko Mäkelä. The original fix: Author: Thirunarayanan Balathandayuthapani <thirunarayanan.balathandayuth@oracle.com> Date: Wed Dec 2 16:09:15 2015 +0530 Bug#17479594 AVOID INTERMEDIATE COMMIT WHILE DOING ALTER TABLE ALGORITHM=COPY Problem: During ALTER TABLE, we commit and restart the transaction for every 10,000 rows, so that the rollback after recovery would not take so long. Fix: Suppress the undo logging during copy alter operation. If fts_index is present then insert directly into fts auxiliary table rather than doing at commit time. ha_innobase::num_write_row: Remove the variable. ha_innobase::write_row(): Remove the hack for committing every 10000 rows. row_lock_table_for_mysql(): Remove the extra 2 parameters. lock_get_src_table(), lock_is_table_exclusive(): Remove. Reviewed-by: Marko Mäkelä <marko.makela@oracle.com> Reviewed-by: Shaohua Wang <shaohua.wang@oracle.com> Reviewed-by: Jon Olav Hauglid <jon.hauglid@oracle.com>
8 years ago
20 years ago
20 years ago
MDEV-11369 Instant ADD COLUMN for InnoDB For InnoDB tables, adding, dropping and reordering columns has required a rebuild of the table and all its indexes. Since MySQL 5.6 (and MariaDB 10.0) this has been supported online (LOCK=NONE), allowing concurrent modification of the tables. This work revises the InnoDB ROW_FORMAT=REDUNDANT, ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC so that columns can be appended instantaneously, with only minor changes performed to the table structure. The counter innodb_instant_alter_column in INFORMATION_SCHEMA.GLOBAL_STATUS is incremented whenever a table rebuild operation is converted into an instant ADD COLUMN operation. ROW_FORMAT=COMPRESSED tables will not support instant ADD COLUMN. Some usability limitations will be addressed in subsequent work: MDEV-13134 Introduce ALTER TABLE attributes ALGORITHM=NOCOPY and ALGORITHM=INSTANT MDEV-14016 Allow instant ADD COLUMN, ADD INDEX, LOCK=NONE The format of the clustered index (PRIMARY KEY) is changed as follows: (1) The FIL_PAGE_TYPE of the root page will be FIL_PAGE_TYPE_INSTANT, and a new field PAGE_INSTANT will contain the original number of fields in the clustered index ('core' fields). If instant ADD COLUMN has not been used or the table becomes empty, or the very first instant ADD COLUMN operation is rolled back, the fields PAGE_INSTANT and FIL_PAGE_TYPE will be reset to 0 and FIL_PAGE_INDEX. (2) A special 'default row' record is inserted into the leftmost leaf, between the page infimum and the first user record. This record is distinguished by the REC_INFO_MIN_REC_FLAG, and it is otherwise in the same format as records that contain values for the instantly added columns. This 'default row' always has the same number of fields as the clustered index according to the table definition. The values of 'core' fields are to be ignored. For other fields, the 'default row' will contain the default values as they were during the ALTER TABLE statement. (If the column default values are changed later, those values will only be stored in the .frm file. The 'default row' will contain the original evaluated values, which must be the same for every row.) The 'default row' must be completely hidden from higher-level access routines. Assertions have been added to ensure that no 'default row' is ever present in the adaptive hash index or in locked records. The 'default row' is never delete-marked. (3) In clustered index leaf page records, the number of fields must reside between the number of 'core' fields (dict_index_t::n_core_fields introduced in this work) and dict_index_t::n_fields. If the number of fields is less than dict_index_t::n_fields, the missing fields are replaced with the column value of the 'default row'. Note: The number of fields in the record may shrink if some of the last instantly added columns are updated to the value that is in the 'default row'. The function btr_cur_trim() implements this 'compression' on update and rollback; dtuple::trim() implements it on insert. (4) In ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC records, the new status value REC_STATUS_COLUMNS_ADDED will indicate the presence of a new record header that will encode n_fields-n_core_fields-1 in 1 or 2 bytes. (In ROW_FORMAT=REDUNDANT records, the record header always explicitly encodes the number of fields.) We introduce the undo log record type TRX_UNDO_INSERT_DEFAULT for covering the insert of the 'default row' record when instant ADD COLUMN is used for the first time. Subsequent instant ADD COLUMN can use TRX_UNDO_UPD_EXIST_REC. This is joint work with Vin Chen (陈福荣) from Tencent. The design that was discussed in April 2017 would not have allowed import or export of data files, because instead of the 'default row' it would have introduced a data dictionary table. The test rpl.rpl_alter_instant is exactly as contributed in pull request #408. The test innodb.instant_alter is based on a contributed test. The redo log record format changes for ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPACT are as contributed. (With this change present, crash recovery from MariaDB 10.3.1 will fail in spectacular ways!) Also the semantics of higher-level redo log records that modify the PAGE_INSTANT field is changed. The redo log format version identifier was already changed to LOG_HEADER_FORMAT_CURRENT=103 in MariaDB 10.3.1. Everything else has been rewritten by me. Thanks to Elena Stepanova, the code has been tested extensively. When rolling back an instant ADD COLUMN operation, we must empty the PAGE_FREE list after deleting or shortening the 'default row' record, by calling either btr_page_empty() or btr_page_reorganize(). We must know the size of each entry in the PAGE_FREE list. If rollback left a freed copy of the 'default row' in the PAGE_FREE list, we would be unable to determine its size (if it is in ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC) because it would contain more fields than the rolled-back definition of the clustered index. UNIV_SQL_DEFAULT: A new special constant that designates an instantly added column that is not present in the clustered index record. len_is_stored(): Check if a length is an actual length. There are two magic length values: UNIV_SQL_DEFAULT, UNIV_SQL_NULL. dict_col_t::def_val: The 'default row' value of the column. If the column is not added instantly, def_val.len will be UNIV_SQL_DEFAULT. dict_col_t: Add the accessors is_virtual(), is_nullable(), is_instant(), instant_value(). dict_col_t::remove_instant(): Remove the 'instant ADD' status of a column. dict_col_t::name(const dict_table_t& table): Replaces dict_table_get_col_name(). dict_index_t::n_core_fields: The original number of fields. For secondary indexes and if instant ADD COLUMN has not been used, this will be equal to dict_index_t::n_fields. dict_index_t::n_core_null_bytes: Number of bytes needed to represent the null flags; usually equal to UT_BITS_IN_BYTES(n_nullable). dict_index_t::NO_CORE_NULL_BYTES: Magic value signalling that n_core_null_bytes was not initialized yet from the clustered index root page. dict_index_t: Add the accessors is_instant(), is_clust(), get_n_nullable(), instant_field_value(). dict_index_t::instant_add_field(): Adjust clustered index metadata for instant ADD COLUMN. dict_index_t::remove_instant(): Remove the 'instant ADD' status of a clustered index when the table becomes empty, or the very first instant ADD COLUMN operation is rolled back. dict_table_t: Add the accessors is_instant(), is_temporary(), supports_instant(). dict_table_t::instant_add_column(): Adjust metadata for instant ADD COLUMN. dict_table_t::rollback_instant(): Adjust metadata on the rollback of instant ADD COLUMN. prepare_inplace_alter_table_dict(): First create the ctx->new_table, and only then decide if the table really needs to be rebuilt. We must split the creation of table or index metadata from the creation of the dictionary table records and the creation of the data. In this way, we can transform a table-rebuilding operation into an instant ADD COLUMN operation. Dictionary objects will only be added to cache when table rebuilding or index creation is needed. The ctx->instant_table will never be added to cache. dict_table_t::add_to_cache(): Modified and renamed from dict_table_add_to_cache(). Do not modify the table metadata. Let the callers invoke dict_table_add_system_columns() and if needed, set can_be_evicted. dict_create_sys_tables_tuple(), dict_create_table_step(): Omit the system columns (which will now exist in the dict_table_t object already at this point). dict_create_table_step(): Expect the callers to invoke dict_table_add_system_columns(). pars_create_table(): Before creating the table creation execution graph, invoke dict_table_add_system_columns(). row_create_table_for_mysql(): Expect all callers to invoke dict_table_add_system_columns(). create_index_dict(): Replaces row_merge_create_index_graph(). innodb_update_n_cols(): Renamed from innobase_update_n_virtual(). Call my_error() if an error occurs. btr_cur_instant_init(), btr_cur_instant_init_low(), btr_cur_instant_root_init(): Load additional metadata from the clustered index and set dict_index_t::n_core_null_bytes. This is invoked when table metadata is first loaded into the data dictionary. dict_boot(): Initialize n_core_null_bytes for the four hard-coded dictionary tables. dict_create_index_step(): Initialize n_core_null_bytes. This is executed as part of CREATE TABLE. dict_index_build_internal_clust(): Initialize n_core_null_bytes to NO_CORE_NULL_BYTES if table->supports_instant(). row_create_index_for_mysql(): Initialize n_core_null_bytes for CREATE TEMPORARY TABLE. commit_cache_norebuild(): Call the code to rename or enlarge columns in the cache only if instant ADD COLUMN is not being used. (Instant ADD COLUMN would copy all column metadata from instant_table to old_table, including the names and lengths.) PAGE_INSTANT: A new 13-bit field for storing dict_index_t::n_core_fields. This is repurposing the 16-bit field PAGE_DIRECTION, of which only the least significant 3 bits were used. The original byte containing PAGE_DIRECTION will be accessible via the new constant PAGE_DIRECTION_B. page_get_instant(), page_set_instant(): Accessors for the PAGE_INSTANT. page_ptr_get_direction(), page_get_direction(), page_ptr_set_direction(): Accessors for PAGE_DIRECTION. page_direction_reset(): Reset PAGE_DIRECTION, PAGE_N_DIRECTION. page_direction_increment(): Increment PAGE_N_DIRECTION and set PAGE_DIRECTION. rec_get_offsets(): Use the 'leaf' parameter for non-debug purposes, and assume that heap_no is always set. Initialize all dict_index_t::n_fields for ROW_FORMAT=REDUNDANT records, even if the record contains fewer fields. rec_offs_make_valid(): Add the parameter 'leaf'. rec_copy_prefix_to_dtuple(): Assert that the tuple is only built on the core fields. Instant ADD COLUMN only applies to the clustered index, and we should never build a search key that has more than the PRIMARY KEY and possibly DB_TRX_ID,DB_ROLL_PTR. All these columns are always present. dict_index_build_data_tuple(): Remove assertions that would be duplicated in rec_copy_prefix_to_dtuple(). rec_init_offsets(): Support ROW_FORMAT=REDUNDANT records whose number of fields is between n_core_fields and n_fields. cmp_rec_rec_with_match(): Implement the comparison between two MIN_REC_FLAG records. trx_t::in_rollback: Make the field available in non-debug builds. trx_start_for_ddl_low(): Remove dangerous error-tolerance. A dictionary transaction must be flagged as such before it has generated any undo log records. This is because trx_undo_assign_undo() will mark the transaction as a dictionary transaction in the undo log header right before the very first undo log record is being written. btr_index_rec_validate(): Account for instant ADD COLUMN row_undo_ins_remove_clust_rec(): On the rollback of an insert into SYS_COLUMNS, revert instant ADD COLUMN in the cache by removing the last column from the table and the clustered index. row_search_on_row_ref(), row_undo_mod_parse_undo_rec(), row_undo_mod(), trx_undo_update_rec_get_update(): Handle the 'default row' as a special case. dtuple_t::trim(index): Omit a redundant suffix of an index tuple right before insert or update. After instant ADD COLUMN, if the last fields of a clustered index tuple match the 'default row', there is no need to store them. While trimming the entry, we must hold a page latch, so that the table cannot be emptied and the 'default row' be deleted. btr_cur_optimistic_update(), btr_cur_pessimistic_update(), row_upd_clust_rec_by_insert(), row_ins_clust_index_entry_low(): Invoke dtuple_t::trim() if needed. row_ins_clust_index_entry(): Restore dtuple_t::n_fields after calling row_ins_clust_index_entry_low(). rec_get_converted_size(), rec_get_converted_size_comp(): Allow the number of fields to be between n_core_fields and n_fields. Do not support infimum,supremum. They are never supposed to be stored in dtuple_t, because page creation nowadays uses a lower-level method for initializing them. rec_convert_dtuple_to_rec_comp(): Assign the status bits based on the number of fields. btr_cur_trim(): In an update, trim the index entry as needed. For the 'default row', handle rollback specially. For user records, omit fields that match the 'default row'. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): Skip locking and adaptive hash index for the 'default row'. row_log_table_apply_convert_mrec(): Replace 'default row' values if needed. In the temporary file that is applied by row_log_table_apply(), we must identify whether the records contain the extra header for instantly added columns. For now, we will allocate an additional byte for this for ROW_T_INSERT and ROW_T_UPDATE records when the source table has been subject to instant ADD COLUMN. The ROW_T_DELETE records are fine, as they will be converted and will only contain 'core' columns (PRIMARY KEY and some system columns) that are converted from dtuple_t. rec_get_converted_size_temp(), rec_init_offsets_temp(), rec_convert_dtuple_to_temp(): Add the parameter 'status'. REC_INFO_DEFAULT_ROW = REC_INFO_MIN_REC_FLAG | REC_STATUS_COLUMNS_ADDED: An info_bits constant for distinguishing the 'default row' record. rec_comp_status_t: An enum of the status bit values. rec_leaf_format: An enum that replaces the bool parameter of rec_init_offsets_comp_ordinary().
8 years ago
20 years ago
branches/innodb+: Merge revisions 4660:5090 from branches/zip: ------------------------------------------------------------------------ r4670 | vasil | 2009-04-07 09:35:23 +0300 (Tue, 07 Apr 2009) | 11 lines branches/zip: Fix Bug#43660 SHOW INDEXES/ANALYZE does NOT update cardinality for indexes of InnoDB table by replacing the pseudo random number generator with a better one (LCG). This also fixes Mantis Issue#212. Approved by: Heikki (rb://110) ------------------------------------------------------------------------ r4671 | vasil | 2009-04-07 09:37:31 +0300 (Tue, 07 Apr 2009) | 4 lines branches/zip: Add ChangeLog entry for r4670. ------------------------------------------------------------------------ r4673 | marko | 2009-04-07 15:45:28 +0300 (Tue, 07 Apr 2009) | 4 lines branches/zip: Allow in-place updates of UTF-8 CHAR columns from or to NULL in ROW_FORMAT=REDUNDANT. (Bug #44032) rb://107 approved by Heikki Tuuri. ------------------------------------------------------------------------ r4677 | marko | 2009-04-07 16:19:31 +0300 (Tue, 07 Apr 2009) | 1 line branches/zip: Adjust r4673 as in the merge to branches/6.0 -r4676. ------------------------------------------------------------------------ r4678 | inaam | 2009-04-07 18:45:37 +0300 (Tue, 07 Apr 2009) | 12 lines branches/zip Enable atomics on solaris (using the libc functions as defined in atomic.h) if GCC atomic builtins are not present. There still remains some work to be done (by Vasil?). This patch makes changes to plug.in to check pthread_t size and presence of atomic functions when running on solaris. The same has to become a part of the generated Makefile.in when we bake our source. Reviewed by: Heikki rb://106 ------------------------------------------------------------------------ r4687 | vasil | 2009-04-08 13:08:59 +0300 (Wed, 08 Apr 2009) | 4 lines branches/zip: Whitespace fixup in the ChangeLog ------------------------------------------------------------------------ r4688 | vasil | 2009-04-08 13:11:15 +0300 (Wed, 08 Apr 2009) | 4 lines branches/zip: Add ChangeLog entry for r4678. ------------------------------------------------------------------------ r4689 | marko | 2009-04-08 14:24:49 +0300 (Wed, 08 Apr 2009) | 5 lines branches/zip: Hide unnecessarily visible globals. dict_ind_redundant, dict_ind_compact: Declare these UNIV_INTERN. innodb_hton_ptr: Declare static. We do not attempt to access the built-in InnoDB any more. trx_roll_savepoints_free(): Declare UNIV_INTERN. ------------------------------------------------------------------------ r4700 | calvin | 2009-04-11 00:37:10 +0300 (Sat, 11 Apr 2009) | 9 lines branches/zip: Rewrite CMakeLists.txt CMakeLists.txt is completely rewritten: - To replace the one written by mysql - Print out some useful information, such as system name, directory, generator used, win64, Microsoft compiler, etc. - Remove one workaround for mysqld.lib location. User does not need to specify a build type ------------------------------------------------------------------------ r4702 | calvin | 2009-04-13 18:16:44 +0300 (Mon, 13 Apr 2009) | 3 lines branches/zip: delete the original CMakeLists.txt A new version will be committed, suggested by Ken. ------------------------------------------------------------------------ r4703 | calvin | 2009-04-13 18:20:45 +0300 (Mon, 13 Apr 2009) | 9 lines branches/zip: new CMakeLists.txt CMakeLists.txt is completely rewritten with enhancements: - Print out useful information, such as system name, directory, generator used, win64, Microsoft compiler, etc. - Remove one workaround for mysqld.lib location. User does not need to specify a build type when invoking MSVC generator. ------------------------------------------------------------------------ r4706 | vasil | 2009-04-14 14:32:11 +0300 (Tue, 14 Apr 2009) | 5 lines branches/zip: When using the random function, first take the modulus by the number of pages and then typecast to ulint. ------------------------------------------------------------------------ r4707 | calvin | 2009-04-14 17:47:31 +0300 (Tue, 14 Apr 2009) | 13 lines branches/zip: remove statically linked libraries from mysql To make zlib and strings dynamically linked; mysqld will export additional functions required by InnoDB. Since the symbols will be resolved dynamically during runtime, wdl_load_mapfile() is no longer able to make any function calls to ones in mysqld. As the result, strtoull() (from strings.lib) is replaced with _strtoui64(). rb://111 Approved by: Marko ------------------------------------------------------------------------ r4712 | vasil | 2009-04-15 12:26:32 +0300 (Wed, 15 Apr 2009) | 157 lines branches/zip: Merge revisions 4481:4710 from branches/5.1: (resolving conflict in r4574, r4575 and skipping r4699 and r4705 because analogous changes to r4699 and r4705 were already made to branches/zip) ------------------------------------------------------------------------ r4573 | vasil | 2009-03-30 14:17:13 +0300 (Mon, 30 Mar 2009) | 4 lines Changed paths: M /branches/5.1/mysql-test/innodb.test branches/5.1: Fix email address from dev@innodb.com to innodb_dev_ww@oracle.com ------------------------------------------------------------------------ r4574 | vasil | 2009-03-30 14:27:08 +0300 (Mon, 30 Mar 2009) | 38 lines Changed paths: M /branches/5.1/Makefile.am M /branches/5.1/mysql-test/innodb.test branches/5.1: Restore the state of INNODB_THREAD_CONCURRENCY to silence this warning: TEST RESULT TIME (ms) ------------------------------------------------------------ worker[1] Using MTR_BUILD_THREAD 250, with reserved ports 12500..12509 main.innodb [ pass ] 8803 MTR's internal check of the test case 'main.innodb' failed. This means that the test case does not preserve the state that existed before the test case was executed. Most likely the test case did not do a proper clean-up. This is the diff of the states of the servers before and after the test case was executed: mysqltest: Logging to '/tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.log'. mysqltest: Results saved in '/tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.result'. mysqltest: Connecting to server localhost:12500 (socket /tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/mysqld.1.sock) as 'root', connection 'default', attempt 0 ... mysqltest: ... Connected. mysqltest: Start processing test commands from './include/check-testcase.test' ... mysqltest: ... Done processing test commands. --- /tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.result 2009-03-30 14:12:31.000000000 +0300 +++ /tmp/autotest.sh-20090330_033000-5.1.5Hg8CY/mysql-5.1/mysql-test/var/tmp/check-mysqld_1.reject 2009-03-30 14:12:41.000000000 +0300 @@ -99,7 +99,7 @@ INNODB_SUPPORT_XA ON INNODB_SYNC_SPIN_LOOPS 20 INNODB_TABLE_LOCKS ON -INNODB_THREAD_CONCURRENCY 8 +INNODB_THREAD_CONCURRENCY 16 INNODB_THREAD_SLEEP_DELAY 10000 INSERT_ID 0 INTERACTIVE_TIMEOUT 28800 mysqltest: Result content mismatch not ok ------------------------------------------------------------------------ r4575 | vasil | 2009-03-30 15:55:31 +0300 (Mon, 30 Mar 2009) | 8 lines Changed paths: M /branches/5.1/mysql-test/innodb.result M /branches/5.1/mysql-test/innodb.test branches/5.1: Fix Bug#43309 Test main.innodb can't be run twice Make the innodb mysql-test more flexible by inspecting how much a variable of interest has changed since the start of the test. Do not assume the variables have zero values at the start of the test. ------------------------------------------------------------------------ r4576 | vasil | 2009-03-30 16:25:10 +0300 (Mon, 30 Mar 2009) | 4 lines Changed paths: M /branches/5.1/Makefile.am branches/5.1: Revert a change to Makefile.am that I committed accidentally in c4574. ------------------------------------------------------------------------ r4659 | vasil | 2009-04-06 15:34:51 +0300 (Mon, 06 Apr 2009) | 6 lines Changed paths: M /branches/5.1/mysql-test/innodb.test branches/5.1: Followup to r4575 and the fix of Bug#43309 Test main.innodb can't be run twice: Add an explanatory comment, as suggested by Patrick Crews in the bug report. ------------------------------------------------------------------------ r4699 | vasil | 2009-04-09 14:01:52 +0300 (Thu, 09 Apr 2009) | 15 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/include/srv0srv.h M /branches/5.1/page/page0cur.c M /branches/5.1/srv/srv0srv.c branches/5.1: Fix Bug#43660 SHOW INDEXES/ANALYZE does NOT update cardinality for indexes of InnoDB table by replacing the PRNG that is used to pick random pages with a better one. This is based on r4670 but also adds a new configuration option and enables the fix only if this option is changed. Please skip the present revision when merging. Approved by: Heikki (via email) ------------------------------------------------------------------------ r4705 | vasil | 2009-04-14 14:30:13 +0300 (Tue, 14 Apr 2009) | 5 lines Changed paths: M /branches/5.1/page/page0cur.c branches/5.1: When using the random function, first take the modulus by the number of pages and then typecast to ulint. ------------------------------------------------------------------------ r4710 | vasil | 2009-04-15 11:55:18 +0300 (Wed, 15 Apr 2009) | 25 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc branches/5.1: Merge a change from MySQL (looks like this is against 5.0 but they later merged it to 5.1): ------------------------------------------------------------ revno: 1810.3846.1 committer: Alexey Botchkov <holyfoot@mysql.com> branch nick: 31435 timestamp: Tue 2008-11-11 14:42:32 +0400 message: Bug#31435 ha_innodb.cc:3983: ulint convert_search_mode_to_innobase(ha_rkey_function): Asse I think we don't need to issue an error statement in the convert_search_mode_to_innobase(). Returning the PAGE_CUR_UNSUPP value is enough as allows to handle this case depending on the requirements. per-file comments: sql/ha_innodb.cc Bug#31435 ha_innodb.cc:3983: ulint convert_search_mode_to_innobase(ha_rkey_function): Asse no error issued in convert_search_mode_to_innobase. ha_innobase::records_in_range() returns HA_POS_ERROR if search mode isn't supported. modified: sql/ha_innodb.cc ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4713 | vasil | 2009-04-15 12:36:16 +0300 (Wed, 15 Apr 2009) | 4 lines branches/zip: Add missing ChangeLog entries ------------------------------------------------------------------------ r4714 | vasil | 2009-04-15 12:36:57 +0300 (Wed, 15 Apr 2009) | 4 lines branches/zip: Fix typo in the ChangeLog ------------------------------------------------------------------------ r4715 | vasil | 2009-04-15 12:39:04 +0300 (Wed, 15 Apr 2009) | 4 lines branches/zip: Whitespace cleanup in ChangeLog ------------------------------------------------------------------------ r4716 | vasil | 2009-04-15 21:36:06 +0300 (Wed, 15 Apr 2009) | 4 lines branches/zip: Add ChangeLog entry for r4543. ------------------------------------------------------------------------ r4717 | calvin | 2009-04-16 01:22:35 +0300 (Thu, 16 Apr 2009) | 18 lines branches/zip: Use the Windows Interlocked functions for atomic memory access Mapping the atomic operations to Windows Interlocked functions: os_compare_and_swap_* to InterlockedCompareExchange(64) os_atomic_increment_* to InterlockedExchangeAdd(64) os_atomic_test_and_set_byte to InterlockedExchange In this patch, the legacy code under UNIV_CAN_USE_X86_ASSEMBLER is removed all together, and add HAVE_WINDOWS_ATOMICS and INNODB_RW_LOCKS_USE_ATOMICS to CMakeLists.txt This is to address mantis issue#194. rb://113 Approved by: Marko ------------------------------------------------------------------------ r4720 | vasil | 2009-04-16 09:44:48 +0300 (Thu, 16 Apr 2009) | 4 lines branches/zip: Add ChangeLog entry for r4717. ------------------------------------------------------------------------ r4721 | marko | 2009-04-16 10:32:09 +0300 (Thu, 16 Apr 2009) | 2 lines branches/zip: row_scan_and_check_index(): Initialize prebuilt->index_usable. This should have been done in r4631. Spotted by Michael. ------------------------------------------------------------------------ r4728 | marko | 2009-04-16 16:02:27 +0300 (Thu, 16 Apr 2009) | 3 lines branches/zip: univ.i: Define REFMAN as the base URL of the MySQL Reference Manual and use it in every string. This fixes Issue #221. ------------------------------------------------------------------------ r4733 | calvin | 2009-04-17 08:13:20 +0300 (Fri, 17 Apr 2009) | 6 lines branches/zip: minor changes to CMakeLists.txt All are non-functional changes: - should check for long (not int), spotted by Sunny - comment out the project definition, avoiding to generate another .sln file. ------------------------------------------------------------------------ r4748 | vasil | 2009-04-18 00:50:09 +0300 (Sat, 18 Apr 2009) | 118 lines branches/zip: Merge revisions 4710:4746 from branches/5.1: ------------------------------------------------------------------------ r4746 | vasil | 2009-04-18 00:32:08 +0300 (Sat, 18 Apr 2009) | 110 lines Changed paths: M /branches/5.1/handler/ha_innodb.cc M /branches/5.1/include/pars0pars.h branches/5.1: Merge a change from MySQL: ------------------------------------------------------------ revno: 2728.10.2 committer: Ignacio Galarza <iggy@mysql.com> branch nick: mysql-5.1-bugteam-bug29125 timestamp: Fri 2009-02-13 11:41:47 -0500 message: Bug#29125 Windows Server X64: so many compiler warnings - Remove bothersome warning messages. This change focuses on the warnings that are covered by the ignore file: support-files/compiler_warnings.supp. - Strings are guaranteed to be max uint in length modified: client/mysql_upgrade.c client/mysqladmin.cc client/mysqlbinlog.cc client/mysqlcheck.c client/mysqldump.c client/mysqlslap.c client/mysqltest.cc client/sql_string.cc extra/comp_err.c extra/yassl/src/buffer.cpp extra/yassl/taocrypt/include/block.hpp extra/yassl/taocrypt/src/algebra.cpp extra/yassl/taocrypt/src/asn.cpp include/config-win.h libmysql/libmysql.c mysys/array.c mysys/base64.c mysys/charset.c mysys/checksum.c mysys/default.c mysys/default_modify.c mysys/hash.c mysys/mf_keycache.c mysys/mf_tempdir.c mysys/my_append.c mysys/my_compress.c mysys/my_conio.c mysys/my_copy.c mysys/my_getwd.c mysys/my_pread.c mysys/my_quick.c mysys/my_read.c mysys/safemalloc.c mysys/string.c server-tools/instance-manager/buffer.cc server-tools/instance-manager/instance.cc server-tools/instance-manager/options.cc server-tools/instance-manager/parse.h sql-common/client.c sql-common/my_user.c sql/event_data_objects.cc sql/event_parse_data.cc sql/events.cc sql/gen_lex_hash.cc sql/item.h sql/item_func.cc sql/item_strfunc.cc sql/item_timefunc.cc sql/lock.cc sql/log_event.cc sql/log_event.h sql/log_event_old.cc sql/net_serv.cc sql/sp_head.h sql/spatial.h sql/sql_class.h sql/sql_connect.cc sql/sql_crypt.cc sql/sql_error.cc sql/sql_insert.cc sql/sql_lex.cc sql/sql_lex.h sql/sql_load.cc sql/sql_prepare.cc sql/sql_profile.cc sql/sql_repl.cc sql/sql_servers.cc sql/sql_string.cc sql/sql_table.cc sql/sql_trigger.cc sql/sql_udf.cc sql/sql_view.cc sql/udf_example.c sql/uniques.cc storage/archive/azio.c storage/archive/azlib.h storage/csv/ha_tina.cc storage/csv/ha_tina.h storage/csv/transparent_file.h storage/federated/ha_federated.cc storage/federated/ha_federated.h storage/heap/hp_write.c storage/innobase/handler/ha_innodb.cc storage/innobase/include/pars0pars.h storage/myisam/ha_myisam.cc storage/myisam/mi_check.c storage/myisam/mi_packrec.c storage/myisam/mi_search.c storage/myisam/rt_index.c storage/myisammrg/ha_myisammrg.cc strings/ctype.c strings/my_vsnprintf.c tests/bug25714.c tests/mysql_client_test.c ------------------------------------------------------------------------ r4749 | vasil | 2009-04-18 00:58:08 +0300 (Sat, 18 Apr 2009) | 4 lines branches/zip: Add ChangeLog entry for t4748. ------------------------------------------------------------------------ r4751 | vasil | 2009-04-18 01:29:16 +0300 (Sat, 18 Apr 2009) | 4 lines branches/zip: Silence warning about unused variables. ------------------------------------------------------------------------ r4752 | vasil | 2009-04-18 01:30:37 +0300 (Sat, 18 Apr 2009) | 4 lines branches/zip: Include the needed header for memset(). ------------------------------------------------------------------------ r4753 | vasil | 2009-04-18 01:31:34 +0300 (Sat, 18 Apr 2009) | 4 lines branches/zip: Silence a compiler warning. ------------------------------------------------------------------------ r4756 | vasil | 2009-04-18 02:19:03 +0300 (Sat, 18 Apr 2009) | 5 lines branches/zip: Rename the aux config program and give it a more specific name because more are coming. ------------------------------------------------------------------------ r4757 | vasil | 2009-04-18 02:22:33 +0300 (Sat, 18 Apr 2009) | 4 lines branches/zip: Add comment and copyright notice to the aux config program. ------------------------------------------------------------------------ r4758 | vasil | 2009-04-18 02:40:47 +0300 (Sat, 18 Apr 2009) | 5 lines branches/zip: Add aux config programs to emulate the newly added checks in plug.in (from r4678). ------------------------------------------------------------------------ r4830 | marko | 2009-04-20 16:11:38 +0300 (Mon, 20 Apr 2009) | 6 lines branches/zip: Cosmetic fixes. row_unlock_for_mysql(): Add a const qualifier to read-only rec_t*. Use dict_index_is_clust(). CMakeLists.txt: svn propset svn:eol-style native. ------------------------------------------------------------------------ r4893 | marko | 2009-04-23 09:32:36 +0300 (Thu, 23 Apr 2009) | 11 lines branches/zip: Introduce the logical type names trx_id_t, roll_ptr_t, and undo_no_t. Each type is still defined as dulint. This is an initial step towards replacing dulint with a 64-bit data type. Because modern compilers have no trouble supporting 64-bit arithmetics even on 32-bit targets, the dulint struct is a relic that should go. The last remaining major use of dulint is dictionary IDs (table, index, and row ids). rb://114 approved by Sunny Bains ------------------------------------------------------------------------ r4894 | marko | 2009-04-23 10:21:07 +0300 (Thu, 23 Apr 2009) | 1 line branches/zip: ChangeLog: Document r4893. ------------------------------------------------------------------------ r4895 | marko | 2009-04-23 10:22:06 +0300 (Thu, 23 Apr 2009) | 1 line branches/zip: ChangeLog: Add the missing include/ to two files. ------------------------------------------------------------------------ r4896 | marko | 2009-04-23 10:37:40 +0300 (Thu, 23 Apr 2009) | 4 lines branches/zip: row_scan_and_check_index(): Improve the diagnostics, by reporting errors from row_search_for_mysql() in the error log. The errors will still be ignored by CHECK TABLE. This is somewhat related to Issue #211. ------------------------------------------------------------------------ r4897 | marko | 2009-04-23 10:40:34 +0300 (Thu, 23 Apr 2009) | 2 lines branches/zip: row_scan_and_check_index(): Check row_merge_is_index_usable() earlier, to make the logic clearer. ------------------------------------------------------------------------ r4898 | marko | 2009-04-23 15:15:07 +0300 (Thu, 23 Apr 2009) | 4 lines branches/zip: Correct a misleading comment. PAGE_MAX_TRX_ID will be updated in ibuf_insert_low() and updated from the insert buffer tree page to the secondary index tree page during the insert buffer merge. ------------------------------------------------------------------------ r4915 | marko | 2009-04-27 13:40:20 +0300 (Mon, 27 Apr 2009) | 2 lines branches/zip: row_scan_and_check_index(): Add some comments on prebuilt->index_usable, as suggested by Michael. ------------------------------------------------------------------------ r4921 | marko | 2009-04-29 11:51:25 +0300 (Wed, 29 Apr 2009) | 2 lines branches/zip: btr_cur_optimistic_insert(): Remove a redundant condition. The insert buffer tree is a clustered index. ------------------------------------------------------------------------ r4922 | marko | 2009-04-29 23:23:27 +0300 (Wed, 29 Apr 2009) | 22 lines branches/zip: Distinguish temporary tables in MLOG_FILE_CREATE. This addresses Mantis Issue #23 in InnoDB Hot Backup and some of MySQL Bug #41609. In MLOG_FILE_CREATE, we need to distinguish temporary tables, so that InnoDB Hot Backup can work correctly. It turns out that we can do this easily, by using a bit of the previously unused parameter for page number. (The page number parameter of MLOG_FILE_CREATE has been written as 0 ever since MySQL 4.1, which introduced MLOG_FILE_CREATE.) MLOG_FILE_FLAG_TEMP: A flag for indicating a temporary table in the page number parameter of MLOG_FILE_ operations. fil_op_write_log(): Add the parameter log_flags. fil_op_log_parse_or_replay(): Add the parameter log_flags. Do not replay MLOG_FILE_CREATE when MLOG_FILE_FLAG_TEMP is set in log_flags. This only affects ibbackup --apply-log. InnoDB itself never replays file operations. rb://117 approved by Heikki Tuuri ------------------------------------------------------------------------ r4977 | marko | 2009-05-13 15:49:38 +0300 (Wed, 13 May 2009) | 12 lines branches/zip: Merge revisions 4746:4976 from branches/5.1: ------------------------------------------------------------------------ r4976 | marko | 2009-05-13 15:44:54 +0300 (Wed, 13 May 2009) | 6 lines branches/5.1: Display DB_ROLL_PTR in the COLUMNS section of the innodb_table_monitor output. It was accidentally omitted due to an off-by-one loop condition. (Bug #44320) rb://116 approved by Heikki Tuuri ------------------------------------------------------------------------ ------------------------------------------------------------------------ r4978 | vasil | 2009-05-13 16:21:55 +0300 (Wed, 13 May 2009) | 4 lines branches/zip: Add ChangeLog entry for r4977. ------------------------------------------------------------------------ r4995 | marko | 2009-05-14 15:31:43 +0300 (Thu, 14 May 2009) | 24 lines branches/zip: Merge revisions 4976:4994 from branches/5.1: ------------------------------------------------------------------------ r4994 | marko | 2009-05-14 15:04:55 +0300 (Thu, 14 May 2009) | 18 lines branches/5.1: Prevent a race condition in innobase_commit() by ensuring that innodb_commit_concurrency>0 remains constant at run time. (Bug #42101) srv_commit_concurrency: Make this a static variable in ha_innodb.cc. innobase_commit_concurrency_validate(): Check that innodb_commit_concurrency is not changed from or to 0 at run time. This is needed, because innobase_commit() assumes that innodb_commit_concurrency>0 remains constant. Without this limitation, the checks for innodb_commit_concurrency>0 in innobase_commit() should be removed and that function would have to acquire and release commit_cond_m at least twice per invocation. Normally, innodb_commit_concurrency=0, and introducing the mutex operations would mean significant overhead. innodb_bug42101.test, innodb_bug42101-nonzero.test: Test cases. rb://123 approved by Heikki Tuuri ------------------------------------------------------------------------ ------------------------------------------------------------------------ r5000 | vasil | 2009-05-14 20:13:41 +0300 (Thu, 14 May 2009) | 4 lines branches/zip: Add ChangeLog entry for r4994. ------------------------------------------------------------------------ r5026 | marko | 2009-05-18 16:29:51 +0300 (Mon, 18 May 2009) | 1 line branches/zip: buf_validate(): Add missing out: comment. ------------------------------------------------------------------------ r5027 | marko | 2009-05-18 16:36:10 +0300 (Mon, 18 May 2009) | 1 line branches/zip: Add some missing out: comments to buf0buf.h, buf0buf.c. ------------------------------------------------------------------------ r5028 | marko | 2009-05-18 16:40:07 +0300 (Mon, 18 May 2009) | 11 lines branches/zip: When executing an optimistic update by delete-and-insert, correctly estimate the free space on the compressed page by page_zip_available(..., create=TRUE). This was reported as Issue #231. btr_cur_update_alloc_zip(): Add the parameter ibool create and pass it to page_zip_available(). The parameter was previously passed as 0. btr_cur_optimistic_update(): Pass create=TRUE to btr_cur_update_alloc_zip(). rb://120 approved by Heikki Tuuri ------------------------------------------------------------------------ r5030 | marko | 2009-05-19 10:04:04 +0300 (Tue, 19 May 2009) | 2 lines branches/zip: os_thread_get_curr_id(), os_thread_get_curr(): Add missing out: comments. ------------------------------------------------------------------------ r5031 | marko | 2009-05-19 10:30:02 +0300 (Tue, 19 May 2009) | 1 line branches/zip: Add missing out: comments to nullary functions. ------------------------------------------------------------------------ r5033 | marko | 2009-05-19 11:00:51 +0300 (Tue, 19 May 2009) | 1 line branches/zip: Remove bogus out: comments of functions returning void. ------------------------------------------------------------------------ r5034 | marko | 2009-05-19 12:41:32 +0300 (Tue, 19 May 2009) | 1 line branches/zip: row_update_prebuilt_trx(): Correct bogus comment. ------------------------------------------------------------------------ r5035 | marko | 2009-05-19 13:04:58 +0300 (Tue, 19 May 2009) | 3 lines branches/zip: ut0auxconf_have_solaris_atomics.c: Get the function declarations from <atomic.h>. Call the functions with proper arguments. ------------------------------------------------------------------------ r5036 | marko | 2009-05-19 13:05:50 +0300 (Tue, 19 May 2009) | 1 line branches/zip: Add proper comments to some file page accessors. ------------------------------------------------------------------------ r5037 | marko | 2009-05-19 13:08:16 +0300 (Tue, 19 May 2009) | 1 line branches/zip: Fix a typo that was introduced in r5036. ------------------------------------------------------------------------ r5038 | marko | 2009-05-19 22:59:07 +0300 (Tue, 19 May 2009) | 30 lines branches/zip: Write PAGE_MAX_TRX_ID to the redo log. Otherwise, transactions that are started before the rollback of incomplete transactions has finished may have an inconsistent view of the secondary indexes. dict_index_is_sec_or_ibuf(): Auxiliary function for controlling updates and checks of PAGE_MAX_TRX_ID: check whether an index is a secondary index or the insert buffer tree. page_set_max_trx_id(), page_update_max_trx_id(), lock_rec_insert_check_and_lock(), lock_sec_rec_modify_check_and_lock(), btr_cur_ins_lock_and_undo(), btr_cur_upd_lock_and_undo(): Add the parameter mtr. page_set_max_trx_id(): Allow mtr to be NULL. When mtr==NULL, do not attempt to write to the redo log. This only occurs when creating a page or reorganizing a compressed page. In these cases, the PAGE_MAX_TRX_ID will be set correctly during the application of redo log records, even though there is no explicit log record about it. btr_discard_only_page_on_level(): Preserve PAGE_MAX_TRX_ID. This function should be unreachable, though. btr_cur_pessimistic_update(): Update PAGE_MAX_TRX_ID. Add some assertions for checking that PAGE_MAX_TRX_ID is set on all secondary index leaf pages. rb://115 tested by Michael, fixes Issue #211 ------------------------------------------------------------------------ r5039 | marko | 2009-05-19 23:13:12 +0300 (Tue, 19 May 2009) | 1 line branches/zip: ib_wqueue_wait(): Add decorative comment. ------------------------------------------------------------------------ r5041 | marko | 2009-05-20 08:42:12 +0300 (Wed, 20 May 2009) | 1 line branches/zip: Add missing function comments. ------------------------------------------------------------------------ r5042 | marko | 2009-05-20 08:46:01 +0300 (Wed, 20 May 2009) | 1 line branches/zip: sync0rw.ic: Remove an extra ; that was added in r5041. ------------------------------------------------------------------------ r5044 | marko | 2009-05-20 11:11:58 +0300 (Wed, 20 May 2009) | 2 lines branches/zip: mlog_parse_index(): Correct a parameter comment and add a const qualifier that was missing. ------------------------------------------------------------------------ r5045 | marko | 2009-05-20 11:37:08 +0300 (Wed, 20 May 2009) | 1 line branches/zip: fil0fil.c: Correct some comments. ------------------------------------------------------------------------ r5046 | marko | 2009-05-20 12:19:40 +0300 (Wed, 20 May 2009) | 1 line branches/zip: Fix some function comments. ------------------------------------------------------------------------ r5047 | marko | 2009-05-20 12:26:49 +0300 (Wed, 20 May 2009) | 1 line branches/zip: ut_snprintf(): Fix the function comments. ------------------------------------------------------------------------ r5048 | marko | 2009-05-20 12:28:44 +0300 (Wed, 20 May 2009) | 3 lines branches/zip: inno_bcmp(): Remove this memcmp replacement. srv0start.c does not (any longer) call memcmp. srv_parse_megabytes(): Add a function comment. ------------------------------------------------------------------------ r5052 | marko | 2009-05-20 12:32:37 +0300 (Wed, 20 May 2009) | 1 line branches/zip: ib_vector_is_empty(): Fix the function comment. ------------------------------------------------------------------------ r5054 | marko | 2009-05-20 12:35:33 +0300 (Wed, 20 May 2009) | 1 line branches/zip: page_cur_lcg_prng(): Add missing parameter list. ------------------------------------------------------------------------ r5057 | marko | 2009-05-20 12:45:17 +0300 (Wed, 20 May 2009) | 1 line branches/zip: Remove bogus in: comments from struct members. ------------------------------------------------------------------------ r5058 | marko | 2009-05-20 13:06:03 +0300 (Wed, 20 May 2009) | 1 line branches/zip: Clean up some function comments. ------------------------------------------------------------------------ r5060 | marko | 2009-05-20 14:06:59 +0300 (Wed, 20 May 2009) | 1 line branches/zip: Clean up some comments. ------------------------------------------------------------------------ r5061 | marko | 2009-05-20 14:07:49 +0300 (Wed, 20 May 2009) | 2 lines branches/zip: innodb_export_status(): Remove the return(0), now that the function was declared void in r5060. ------------------------------------------------------------------------ r5062 | marko | 2009-05-20 14:45:03 +0300 (Wed, 20 May 2009) | 1 line branches/zip: ha_innodb.cc: Clean up some comments. ------------------------------------------------------------------------ r5063 | marko | 2009-05-20 16:10:17 +0300 (Wed, 20 May 2009) | 1 line branches/zip: ut_dulint_sort(): Write proper comments. ------------------------------------------------------------------------ r5064 | marko | 2009-05-20 16:17:26 +0300 (Wed, 20 May 2009) | 2 lines branches/zip: innobase_end(), innobase_flush_logs(): Document the function parameters. ------------------------------------------------------------------------ r5065 | marko | 2009-05-20 23:17:43 +0300 (Wed, 20 May 2009) | 1 line branches/zip: ha_innodb.cc: Add some missing function comments. ------------------------------------------------------------------------ r5066 | marko | 2009-05-21 00:51:23 +0300 (Thu, 21 May 2009) | 2 lines branches/zip: Fix some function comments. ------------------------------------------------------------------------ r5070 | vasil | 2009-05-21 08:27:00 +0300 (Thu, 21 May 2009) | 4 lines branches/zip: Whitespace fixup. ------------------------------------------------------------------------
17 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
20 years ago
20 years ago
20 years ago
MDEV-11369 Instant ADD COLUMN for InnoDB For InnoDB tables, adding, dropping and reordering columns has required a rebuild of the table and all its indexes. Since MySQL 5.6 (and MariaDB 10.0) this has been supported online (LOCK=NONE), allowing concurrent modification of the tables. This work revises the InnoDB ROW_FORMAT=REDUNDANT, ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC so that columns can be appended instantaneously, with only minor changes performed to the table structure. The counter innodb_instant_alter_column in INFORMATION_SCHEMA.GLOBAL_STATUS is incremented whenever a table rebuild operation is converted into an instant ADD COLUMN operation. ROW_FORMAT=COMPRESSED tables will not support instant ADD COLUMN. Some usability limitations will be addressed in subsequent work: MDEV-13134 Introduce ALTER TABLE attributes ALGORITHM=NOCOPY and ALGORITHM=INSTANT MDEV-14016 Allow instant ADD COLUMN, ADD INDEX, LOCK=NONE The format of the clustered index (PRIMARY KEY) is changed as follows: (1) The FIL_PAGE_TYPE of the root page will be FIL_PAGE_TYPE_INSTANT, and a new field PAGE_INSTANT will contain the original number of fields in the clustered index ('core' fields). If instant ADD COLUMN has not been used or the table becomes empty, or the very first instant ADD COLUMN operation is rolled back, the fields PAGE_INSTANT and FIL_PAGE_TYPE will be reset to 0 and FIL_PAGE_INDEX. (2) A special 'default row' record is inserted into the leftmost leaf, between the page infimum and the first user record. This record is distinguished by the REC_INFO_MIN_REC_FLAG, and it is otherwise in the same format as records that contain values for the instantly added columns. This 'default row' always has the same number of fields as the clustered index according to the table definition. The values of 'core' fields are to be ignored. For other fields, the 'default row' will contain the default values as they were during the ALTER TABLE statement. (If the column default values are changed later, those values will only be stored in the .frm file. The 'default row' will contain the original evaluated values, which must be the same for every row.) The 'default row' must be completely hidden from higher-level access routines. Assertions have been added to ensure that no 'default row' is ever present in the adaptive hash index or in locked records. The 'default row' is never delete-marked. (3) In clustered index leaf page records, the number of fields must reside between the number of 'core' fields (dict_index_t::n_core_fields introduced in this work) and dict_index_t::n_fields. If the number of fields is less than dict_index_t::n_fields, the missing fields are replaced with the column value of the 'default row'. Note: The number of fields in the record may shrink if some of the last instantly added columns are updated to the value that is in the 'default row'. The function btr_cur_trim() implements this 'compression' on update and rollback; dtuple::trim() implements it on insert. (4) In ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC records, the new status value REC_STATUS_COLUMNS_ADDED will indicate the presence of a new record header that will encode n_fields-n_core_fields-1 in 1 or 2 bytes. (In ROW_FORMAT=REDUNDANT records, the record header always explicitly encodes the number of fields.) We introduce the undo log record type TRX_UNDO_INSERT_DEFAULT for covering the insert of the 'default row' record when instant ADD COLUMN is used for the first time. Subsequent instant ADD COLUMN can use TRX_UNDO_UPD_EXIST_REC. This is joint work with Vin Chen (陈福荣) from Tencent. The design that was discussed in April 2017 would not have allowed import or export of data files, because instead of the 'default row' it would have introduced a data dictionary table. The test rpl.rpl_alter_instant is exactly as contributed in pull request #408. The test innodb.instant_alter is based on a contributed test. The redo log record format changes for ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPACT are as contributed. (With this change present, crash recovery from MariaDB 10.3.1 will fail in spectacular ways!) Also the semantics of higher-level redo log records that modify the PAGE_INSTANT field is changed. The redo log format version identifier was already changed to LOG_HEADER_FORMAT_CURRENT=103 in MariaDB 10.3.1. Everything else has been rewritten by me. Thanks to Elena Stepanova, the code has been tested extensively. When rolling back an instant ADD COLUMN operation, we must empty the PAGE_FREE list after deleting or shortening the 'default row' record, by calling either btr_page_empty() or btr_page_reorganize(). We must know the size of each entry in the PAGE_FREE list. If rollback left a freed copy of the 'default row' in the PAGE_FREE list, we would be unable to determine its size (if it is in ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC) because it would contain more fields than the rolled-back definition of the clustered index. UNIV_SQL_DEFAULT: A new special constant that designates an instantly added column that is not present in the clustered index record. len_is_stored(): Check if a length is an actual length. There are two magic length values: UNIV_SQL_DEFAULT, UNIV_SQL_NULL. dict_col_t::def_val: The 'default row' value of the column. If the column is not added instantly, def_val.len will be UNIV_SQL_DEFAULT. dict_col_t: Add the accessors is_virtual(), is_nullable(), is_instant(), instant_value(). dict_col_t::remove_instant(): Remove the 'instant ADD' status of a column. dict_col_t::name(const dict_table_t& table): Replaces dict_table_get_col_name(). dict_index_t::n_core_fields: The original number of fields. For secondary indexes and if instant ADD COLUMN has not been used, this will be equal to dict_index_t::n_fields. dict_index_t::n_core_null_bytes: Number of bytes needed to represent the null flags; usually equal to UT_BITS_IN_BYTES(n_nullable). dict_index_t::NO_CORE_NULL_BYTES: Magic value signalling that n_core_null_bytes was not initialized yet from the clustered index root page. dict_index_t: Add the accessors is_instant(), is_clust(), get_n_nullable(), instant_field_value(). dict_index_t::instant_add_field(): Adjust clustered index metadata for instant ADD COLUMN. dict_index_t::remove_instant(): Remove the 'instant ADD' status of a clustered index when the table becomes empty, or the very first instant ADD COLUMN operation is rolled back. dict_table_t: Add the accessors is_instant(), is_temporary(), supports_instant(). dict_table_t::instant_add_column(): Adjust metadata for instant ADD COLUMN. dict_table_t::rollback_instant(): Adjust metadata on the rollback of instant ADD COLUMN. prepare_inplace_alter_table_dict(): First create the ctx->new_table, and only then decide if the table really needs to be rebuilt. We must split the creation of table or index metadata from the creation of the dictionary table records and the creation of the data. In this way, we can transform a table-rebuilding operation into an instant ADD COLUMN operation. Dictionary objects will only be added to cache when table rebuilding or index creation is needed. The ctx->instant_table will never be added to cache. dict_table_t::add_to_cache(): Modified and renamed from dict_table_add_to_cache(). Do not modify the table metadata. Let the callers invoke dict_table_add_system_columns() and if needed, set can_be_evicted. dict_create_sys_tables_tuple(), dict_create_table_step(): Omit the system columns (which will now exist in the dict_table_t object already at this point). dict_create_table_step(): Expect the callers to invoke dict_table_add_system_columns(). pars_create_table(): Before creating the table creation execution graph, invoke dict_table_add_system_columns(). row_create_table_for_mysql(): Expect all callers to invoke dict_table_add_system_columns(). create_index_dict(): Replaces row_merge_create_index_graph(). innodb_update_n_cols(): Renamed from innobase_update_n_virtual(). Call my_error() if an error occurs. btr_cur_instant_init(), btr_cur_instant_init_low(), btr_cur_instant_root_init(): Load additional metadata from the clustered index and set dict_index_t::n_core_null_bytes. This is invoked when table metadata is first loaded into the data dictionary. dict_boot(): Initialize n_core_null_bytes for the four hard-coded dictionary tables. dict_create_index_step(): Initialize n_core_null_bytes. This is executed as part of CREATE TABLE. dict_index_build_internal_clust(): Initialize n_core_null_bytes to NO_CORE_NULL_BYTES if table->supports_instant(). row_create_index_for_mysql(): Initialize n_core_null_bytes for CREATE TEMPORARY TABLE. commit_cache_norebuild(): Call the code to rename or enlarge columns in the cache only if instant ADD COLUMN is not being used. (Instant ADD COLUMN would copy all column metadata from instant_table to old_table, including the names and lengths.) PAGE_INSTANT: A new 13-bit field for storing dict_index_t::n_core_fields. This is repurposing the 16-bit field PAGE_DIRECTION, of which only the least significant 3 bits were used. The original byte containing PAGE_DIRECTION will be accessible via the new constant PAGE_DIRECTION_B. page_get_instant(), page_set_instant(): Accessors for the PAGE_INSTANT. page_ptr_get_direction(), page_get_direction(), page_ptr_set_direction(): Accessors for PAGE_DIRECTION. page_direction_reset(): Reset PAGE_DIRECTION, PAGE_N_DIRECTION. page_direction_increment(): Increment PAGE_N_DIRECTION and set PAGE_DIRECTION. rec_get_offsets(): Use the 'leaf' parameter for non-debug purposes, and assume that heap_no is always set. Initialize all dict_index_t::n_fields for ROW_FORMAT=REDUNDANT records, even if the record contains fewer fields. rec_offs_make_valid(): Add the parameter 'leaf'. rec_copy_prefix_to_dtuple(): Assert that the tuple is only built on the core fields. Instant ADD COLUMN only applies to the clustered index, and we should never build a search key that has more than the PRIMARY KEY and possibly DB_TRX_ID,DB_ROLL_PTR. All these columns are always present. dict_index_build_data_tuple(): Remove assertions that would be duplicated in rec_copy_prefix_to_dtuple(). rec_init_offsets(): Support ROW_FORMAT=REDUNDANT records whose number of fields is between n_core_fields and n_fields. cmp_rec_rec_with_match(): Implement the comparison between two MIN_REC_FLAG records. trx_t::in_rollback: Make the field available in non-debug builds. trx_start_for_ddl_low(): Remove dangerous error-tolerance. A dictionary transaction must be flagged as such before it has generated any undo log records. This is because trx_undo_assign_undo() will mark the transaction as a dictionary transaction in the undo log header right before the very first undo log record is being written. btr_index_rec_validate(): Account for instant ADD COLUMN row_undo_ins_remove_clust_rec(): On the rollback of an insert into SYS_COLUMNS, revert instant ADD COLUMN in the cache by removing the last column from the table and the clustered index. row_search_on_row_ref(), row_undo_mod_parse_undo_rec(), row_undo_mod(), trx_undo_update_rec_get_update(): Handle the 'default row' as a special case. dtuple_t::trim(index): Omit a redundant suffix of an index tuple right before insert or update. After instant ADD COLUMN, if the last fields of a clustered index tuple match the 'default row', there is no need to store them. While trimming the entry, we must hold a page latch, so that the table cannot be emptied and the 'default row' be deleted. btr_cur_optimistic_update(), btr_cur_pessimistic_update(), row_upd_clust_rec_by_insert(), row_ins_clust_index_entry_low(): Invoke dtuple_t::trim() if needed. row_ins_clust_index_entry(): Restore dtuple_t::n_fields after calling row_ins_clust_index_entry_low(). rec_get_converted_size(), rec_get_converted_size_comp(): Allow the number of fields to be between n_core_fields and n_fields. Do not support infimum,supremum. They are never supposed to be stored in dtuple_t, because page creation nowadays uses a lower-level method for initializing them. rec_convert_dtuple_to_rec_comp(): Assign the status bits based on the number of fields. btr_cur_trim(): In an update, trim the index entry as needed. For the 'default row', handle rollback specially. For user records, omit fields that match the 'default row'. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): Skip locking and adaptive hash index for the 'default row'. row_log_table_apply_convert_mrec(): Replace 'default row' values if needed. In the temporary file that is applied by row_log_table_apply(), we must identify whether the records contain the extra header for instantly added columns. For now, we will allocate an additional byte for this for ROW_T_INSERT and ROW_T_UPDATE records when the source table has been subject to instant ADD COLUMN. The ROW_T_DELETE records are fine, as they will be converted and will only contain 'core' columns (PRIMARY KEY and some system columns) that are converted from dtuple_t. rec_get_converted_size_temp(), rec_init_offsets_temp(), rec_convert_dtuple_to_temp(): Add the parameter 'status'. REC_INFO_DEFAULT_ROW = REC_INFO_MIN_REC_FLAG | REC_STATUS_COLUMNS_ADDED: An info_bits constant for distinguishing the 'default row' record. rec_comp_status_t: An enum of the status bit values. rec_leaf_format: An enum that replaces the bool parameter of rec_init_offsets_comp_ordinary().
8 years ago
MDEV-11415 Remove excessive undo logging during ALTER TABLE…ALGORITHM=COPY If a crash occurs during ALTER TABLE…ALGORITHM=COPY, InnoDB would spend a lot of time rolling back writes to the intermediate copy of the table. To reduce the amount of busy work done, a work-around was introduced in commit fd069e2bb36a3c1c1f26d65dd298b07e6d83ac8b in MySQL 4.1.8 and 5.0.2, to commit the transaction after every 10,000 inserted rows. A proper fix would have been to disable the undo logging altogether and to simply drop the intermediate copy of the table on subsequent server startup. This is what happens in MariaDB 10.3 with MDEV-14717,MDEV-14585. In MariaDB 10.2, the intermediate copy of the table would be left behind with a name starting with the string #sql. This is a backport of a bug fix from MySQL 8.0.0 to MariaDB, contributed by jixianliang <271365745@qq.com>. Unlike recent MySQL, MariaDB supports ALTER IGNORE. For that operation InnoDB must for now keep the undo logging enabled, so that the latest row can be rolled back in case of an error. In Galera cluster, the LOAD DATA statement will retain the existing behaviour and commit the transaction after every 10,000 rows if the parameter wsrep_load_data_splitting=ON is set. The logic to do so (the wsrep_load_data_split() function and the call handler::extra(HA_EXTRA_FAKE_START_STMT)) are joint work by Ji Xianliang and Marko Mäkelä. The original fix: Author: Thirunarayanan Balathandayuthapani <thirunarayanan.balathandayuth@oracle.com> Date: Wed Dec 2 16:09:15 2015 +0530 Bug#17479594 AVOID INTERMEDIATE COMMIT WHILE DOING ALTER TABLE ALGORITHM=COPY Problem: During ALTER TABLE, we commit and restart the transaction for every 10,000 rows, so that the rollback after recovery would not take so long. Fix: Suppress the undo logging during copy alter operation. If fts_index is present then insert directly into fts auxiliary table rather than doing at commit time. ha_innobase::num_write_row: Remove the variable. ha_innobase::write_row(): Remove the hack for committing every 10000 rows. row_lock_table_for_mysql(): Remove the extra 2 parameters. lock_get_src_table(), lock_is_table_exclusive(): Remove. Reviewed-by: Marko Mäkelä <marko.makela@oracle.com> Reviewed-by: Shaohua Wang <shaohua.wang@oracle.com> Reviewed-by: Jon Olav Hauglid <jon.hauglid@oracle.com>
8 years ago
20 years ago
MDEV-21907: InnoDB: Enable -Wconversion on clang and GCC The -Wconversion in GCC seems to be stricter than in clang. GCC at least since version 4.4.7 issues truncation warnings for assignments to bitfields, while clang 10 appears to only issue warnings when the sizes in bytes rounded to the nearest integer powers of 2 are different. Before GCC 10.0.0, -Wconversion required more casts and would not allow some operations, such as x<<=1 or x+=1 on a data type that is narrower than int. GCC 5 (but not GCC 4, GCC 6, or any later version) is complaining about x|=y even when x and y are compatible types that are narrower than int. Hence, we must rewrite some x|=y as x=static_cast<byte>(x|y) or similar, or we must disable -Wconversion. In GCC 6 and later, the warning for assigning wider to bitfields that are narrower than 8, 16, or 32 bits can be suppressed by applying a bitwise & with the exact bitmask of the bitfield. For older GCC, we must disable -Wconversion for GCC 4 or 5 in such cases. The bitwise negation operator appears to promote short integers to a wider type, and hence we must add explicit truncation casts around them. Microsoft Visual C does not allow a static_cast to truncate a constant, such as static_cast<byte>(1) truncating int. Hence, we will use the constructor-style cast byte(~1) for such cases. This has been tested at least with GCC 4.8.5, 5.4.0, 7.4.0, 9.2.1, 10.0.0, clang 9.0.1, 10.0.0, and MSVC 14.22.27905 (Microsoft Visual Studio 2019) on 64-bit and 32-bit targets (IA-32, AMD64, POWER 8, POWER 9, ARMv8).
6 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
20 years ago
20 years ago
MDEV-11415 Remove excessive undo logging during ALTER TABLE…ALGORITHM=COPY If a crash occurs during ALTER TABLE…ALGORITHM=COPY, InnoDB would spend a lot of time rolling back writes to the intermediate copy of the table. To reduce the amount of busy work done, a work-around was introduced in commit fd069e2bb36a3c1c1f26d65dd298b07e6d83ac8b in MySQL 4.1.8 and 5.0.2, to commit the transaction after every 10,000 inserted rows. A proper fix would have been to disable the undo logging altogether and to simply drop the intermediate copy of the table on subsequent server startup. This is what happens in MariaDB 10.3 with MDEV-14717,MDEV-14585. In MariaDB 10.2, the intermediate copy of the table would be left behind with a name starting with the string #sql. This is a backport of a bug fix from MySQL 8.0.0 to MariaDB, contributed by jixianliang <271365745@qq.com>. Unlike recent MySQL, MariaDB supports ALTER IGNORE. For that operation InnoDB must for now keep the undo logging enabled, so that the latest row can be rolled back in case of an error. In Galera cluster, the LOAD DATA statement will retain the existing behaviour and commit the transaction after every 10,000 rows if the parameter wsrep_load_data_splitting=ON is set. The logic to do so (the wsrep_load_data_split() function and the call handler::extra(HA_EXTRA_FAKE_START_STMT)) are joint work by Ji Xianliang and Marko Mäkelä. The original fix: Author: Thirunarayanan Balathandayuthapani <thirunarayanan.balathandayuth@oracle.com> Date: Wed Dec 2 16:09:15 2015 +0530 Bug#17479594 AVOID INTERMEDIATE COMMIT WHILE DOING ALTER TABLE ALGORITHM=COPY Problem: During ALTER TABLE, we commit and restart the transaction for every 10,000 rows, so that the rollback after recovery would not take so long. Fix: Suppress the undo logging during copy alter operation. If fts_index is present then insert directly into fts auxiliary table rather than doing at commit time. ha_innobase::num_write_row: Remove the variable. ha_innobase::write_row(): Remove the hack for committing every 10000 rows. row_lock_table_for_mysql(): Remove the extra 2 parameters. lock_get_src_table(), lock_is_table_exclusive(): Remove. Reviewed-by: Marko Mäkelä <marko.makela@oracle.com> Reviewed-by: Shaohua Wang <shaohua.wang@oracle.com> Reviewed-by: Jon Olav Hauglid <jon.hauglid@oracle.com>
8 years ago
20 years ago
20 years ago
20 years ago
MDEV-21907: InnoDB: Enable -Wconversion on clang and GCC The -Wconversion in GCC seems to be stricter than in clang. GCC at least since version 4.4.7 issues truncation warnings for assignments to bitfields, while clang 10 appears to only issue warnings when the sizes in bytes rounded to the nearest integer powers of 2 are different. Before GCC 10.0.0, -Wconversion required more casts and would not allow some operations, such as x<<=1 or x+=1 on a data type that is narrower than int. GCC 5 (but not GCC 4, GCC 6, or any later version) is complaining about x|=y even when x and y are compatible types that are narrower than int. Hence, we must rewrite some x|=y as x=static_cast<byte>(x|y) or similar, or we must disable -Wconversion. In GCC 6 and later, the warning for assigning wider to bitfields that are narrower than 8, 16, or 32 bits can be suppressed by applying a bitwise & with the exact bitmask of the bitfield. For older GCC, we must disable -Wconversion for GCC 4 or 5 in such cases. The bitwise negation operator appears to promote short integers to a wider type, and hence we must add explicit truncation casts around them. Microsoft Visual C does not allow a static_cast to truncate a constant, such as static_cast<byte>(1) truncating int. Hence, we will use the constructor-style cast byte(~1) for such cases. This has been tested at least with GCC 4.8.5, 5.4.0, 7.4.0, 9.2.1, 10.0.0, clang 9.0.1, 10.0.0, and MSVC 14.22.27905 (Microsoft Visual Studio 2019) on 64-bit and 32-bit targets (IA-32, AMD64, POWER 8, POWER 9, ARMv8).
6 years ago
20 years ago
20 years ago
20 years ago
MDEV-21907: InnoDB: Enable -Wconversion on clang and GCC The -Wconversion in GCC seems to be stricter than in clang. GCC at least since version 4.4.7 issues truncation warnings for assignments to bitfields, while clang 10 appears to only issue warnings when the sizes in bytes rounded to the nearest integer powers of 2 are different. Before GCC 10.0.0, -Wconversion required more casts and would not allow some operations, such as x<<=1 or x+=1 on a data type that is narrower than int. GCC 5 (but not GCC 4, GCC 6, or any later version) is complaining about x|=y even when x and y are compatible types that are narrower than int. Hence, we must rewrite some x|=y as x=static_cast<byte>(x|y) or similar, or we must disable -Wconversion. In GCC 6 and later, the warning for assigning wider to bitfields that are narrower than 8, 16, or 32 bits can be suppressed by applying a bitwise & with the exact bitmask of the bitfield. For older GCC, we must disable -Wconversion for GCC 4 or 5 in such cases. The bitwise negation operator appears to promote short integers to a wider type, and hence we must add explicit truncation casts around them. Microsoft Visual C does not allow a static_cast to truncate a constant, such as static_cast<byte>(1) truncating int. Hence, we will use the constructor-style cast byte(~1) for such cases. This has been tested at least with GCC 4.8.5, 5.4.0, 7.4.0, 9.2.1, 10.0.0, clang 9.0.1, 10.0.0, and MSVC 14.22.27905 (Microsoft Visual Studio 2019) on 64-bit and 32-bit targets (IA-32, AMD64, POWER 8, POWER 9, ARMv8).
6 years ago
MDEV-21907: InnoDB: Enable -Wconversion on clang and GCC The -Wconversion in GCC seems to be stricter than in clang. GCC at least since version 4.4.7 issues truncation warnings for assignments to bitfields, while clang 10 appears to only issue warnings when the sizes in bytes rounded to the nearest integer powers of 2 are different. Before GCC 10.0.0, -Wconversion required more casts and would not allow some operations, such as x<<=1 or x+=1 on a data type that is narrower than int. GCC 5 (but not GCC 4, GCC 6, or any later version) is complaining about x|=y even when x and y are compatible types that are narrower than int. Hence, we must rewrite some x|=y as x=static_cast<byte>(x|y) or similar, or we must disable -Wconversion. In GCC 6 and later, the warning for assigning wider to bitfields that are narrower than 8, 16, or 32 bits can be suppressed by applying a bitwise & with the exact bitmask of the bitfield. For older GCC, we must disable -Wconversion for GCC 4 or 5 in such cases. The bitwise negation operator appears to promote short integers to a wider type, and hence we must add explicit truncation casts around them. Microsoft Visual C does not allow a static_cast to truncate a constant, such as static_cast<byte>(1) truncating int. Hence, we will use the constructor-style cast byte(~1) for such cases. This has been tested at least with GCC 4.8.5, 5.4.0, 7.4.0, 9.2.1, 10.0.0, clang 9.0.1, 10.0.0, and MSVC 14.22.27905 (Microsoft Visual Studio 2019) on 64-bit and 32-bit targets (IA-32, AMD64, POWER 8, POWER 9, ARMv8).
6 years ago
20 years ago
20 years ago
MDEV-15662 Instant DROP COLUMN or changing the order of columns Allow ADD COLUMN anywhere in a table, not only adding as the last column. Allow instant DROP COLUMN and instant changing the order of columns. The added columns will always be added last in clustered index records. In new records, instantly dropped columns will be stored as NULL or empty when possible. Information about dropped and reordered columns will be written in a metadata BLOB (mblob), which is stored before the first 'user' field in the hidden metadata record at the start of the clustered index. The presence of mblob is indicated by setting the delete-mark flag in the metadata record. The metadata BLOB stores the number of clustered index fields, followed by an array of column information for each field. For dropped columns, we store the NOT NULL flag, the fixed length, and for variable-length columns, whether the maximum length exceeded 255 bytes. For non-dropped columns, we store the column position. Unlike with MDEV-11369, when a table becomes empty, it cannot be converted back to the canonical format. The reason for this is that other threads may hold cached objects such as row_prebuilt_t::ins_node that could refer to dropped or reordered index fields. For instant DROP COLUMN and ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC, we must store the n_core_null_bytes in the root page, so that the chain of node pointer records can be followed in order to reach the leftmost leaf page where the metadata record is located. If the mblob is present, we will zero-initialize the strings "infimum" and "supremum" in the root page, and use the last byte of "supremum" for storing the number of null bytes (which are allocated but useless on node pointer pages). This is necessary for btr_cur_instant_init_metadata() to be able to navigate to the mblob. If the PRIMARY KEY contains any variable-length column and some nullable columns were instantly dropped, the dict_index_t::n_nullable in the data dictionary could be smaller than it actually is in the non-leaf pages. Because of this, the non-leaf pages could use more bytes for the null flags than the data dictionary expects, and we could be reading the lengths of the variable-length columns from the wrong offset, and thus reading the child page number from wrong place. This is the result of two design mistakes that involve unnecessary storage of data: First, it is nonsense to store any data fields for the leftmost node pointer records, because the comparisons would be resolved by the MIN_REC_FLAG alone. Second, there cannot be any null fields in the clustered index node pointer fields, but we nevertheless reserve space for all the null flags. Limitations (future work): MDEV-17459 Allow instant ALTER TABLE even if FULLTEXT INDEX exists MDEV-17468 Avoid table rebuild on operations on generated columns MDEV-17494 Refuse ALGORITHM=INSTANT when the row size is too large btr_page_reorganize_low(): Preserve any metadata in the root page. Call lock_move_reorganize_page() only after restoring the "infimum" and "supremum" records, to avoid a memcmp() assertion failure. dict_col_t::DROPPED: Magic value for dict_col_t::ind. dict_col_t::clear_instant(): Renamed from dict_col_t::remove_instant(). Do not assert that the column was instantly added, because we sometimes call this unconditionally for all columns. Convert an instantly added column to a "core column". The old name remove_instant() could be mistaken to refer to "instant DROP COLUMN". dict_col_t::is_added(): Rename from dict_col_t::is_instant(). dtype_t::metadata_blob_init(): Initialize the mblob data type. dtuple_t::is_metadata(), dtuple_t::is_alter_metadata(), upd_t::is_metadata(), upd_t::is_alter_metadata(): Check if info_bits refer to a metadata record. dict_table_t::instant: Metadata about dropped or reordered columns. dict_table_t::prepare_instant(): Prepare ha_innobase_inplace_ctx::instant_table for instant ALTER TABLE. innobase_instant_try() will pass this to dict_table_t::instant_column(). On rollback, dict_table_t::rollback_instant() will be called. dict_table_t::instant_column(): Renamed from instant_add_column(). Add the parameter col_map so that columns can be reordered. Copy and adjust v_cols[] as well. dict_table_t::find(): Find an old column based on a new column number. dict_table_t::serialise_columns(), dict_table_t::deserialise_columns(): Convert the mblob. dict_index_t::instant_metadata(): Create the metadata record for instant ALTER TABLE. Invoke dict_table_t::serialise_columns(). dict_index_t::reconstruct_fields(): Invoked by dict_table_t::deserialise_columns(). dict_index_t::clear_instant_alter(): Move the fields for the dropped columns to the end, and sort the surviving index fields in ascending order of column position. ha_innobase::check_if_supported_inplace_alter(): Do not allow adding a FTS_DOC_ID column if a hidden FTS_DOC_ID column exists due to FULLTEXT INDEX. (This always required ALGORITHM=COPY.) instant_alter_column_possible(): Add a parameter for InnoDB table, to check for additional conditions, such as the maximum number of index fields. ha_innobase_inplace_ctx::first_alter_pos: The first column whose position is affected by instant ADD, DROP, or changing the order of columns. innobase_build_col_map(): Skip added virtual columns. prepare_inplace_add_virtual(): Correctly compute num_to_add_vcol. Remove some unnecessary code. Note that the call to innodb_base_col_setup() should be executed later. commit_try_norebuild(): If ctx->is_instant(), let the virtual columns be added or dropped by innobase_instant_try(). innobase_instant_try(): Fill in a zero default value for the hidden column FTS_DOC_ID (to reduce the work needed in MDEV-17459). If any columns were dropped or reordered (or added not last), delete any SYS_COLUMNS records for the following columns, and insert SYS_COLUMNS records for all subsequent stored columns as well as for all virtual columns. If any virtual column is dropped, rewrite all virtual column metadata. Use a shortcut only for adding virtual columns. This is because innobase_drop_virtual_try() assumes that the dropped virtual columns still exist in ctx->old_table. innodb_update_cols(): Renamed from innodb_update_n_cols(). innobase_add_one_virtual(), innobase_insert_sys_virtual(): Change the return type to bool, and invoke my_error() when detecting an error. innodb_insert_sys_columns(): Insert a record into SYS_COLUMNS. Refactored from innobase_add_one_virtual() and innobase_instant_add_col(). innobase_instant_add_col(): Replace the parameter dfield with type. innobase_instant_drop_cols(): Drop matching columns from SYS_COLUMNS and all columns from SYS_VIRTUAL. innobase_add_virtual_try(), innobase_drop_virtual_try(): Let the caller invoke innodb_update_cols(). innobase_rename_column_try(): Skip dropped columns. commit_cache_norebuild(): Update table->fts->doc_col. dict_mem_table_col_rename_low(): Skip dropped columns. trx_undo_rec_get_partial_row(): Skip dropped columns. trx_undo_update_rec_get_update(): Handle the metadata BLOB correctly. trx_undo_page_report_modify(): Avoid out-of-bounds access to record fields. Log metadata records consistently. Apparently, the first fields of a clustered index may be updated in an update_undo vector when the index is ID_IND of SYS_FOREIGN, as part of renaming the table during ALTER TABLE. Normally, updates of the PRIMARY KEY should be logged as delete-mark and an insert. row_undo_mod_parse_undo_rec(), row_purge_parse_undo_rec(): Use trx_undo_metadata. row_undo_mod_clust_low(): On metadata rollback, roll back the root page too. row_undo_mod_clust(): Relax an assertion. The delete-mark flag was repurposed for ALTER TABLE metadata records. row_rec_to_index_entry_impl(): Add the template parameter mblob and the optional parameter info_bits for specifying the desired new info bits. For the metadata tuple, allow conversion between the original format (ADD COLUMN only) and the generic format (with hidden BLOB). Add the optional parameter "pad" to determine whether the tuple should be padded to the index fields (on ALTER TABLE it should), or whether it should remain at its original size (on rollback). row_build_index_entry_low(): Clean up the code, removing redundant variables and conditions. For instantly dropped columns, generate a dummy value that is NULL, the empty string, or a fixed length of NUL bytes, depending on the type of the dropped column. row_upd_clust_rec_by_insert_inherit_func(): On the update of PRIMARY KEY of a record that contained a dropped column whose value was stored externally, we will be inserting a dummy NULL or empty string value to the field of the dropped column. The externally stored column would eventually be dropped when purge removes the delete-marked record for the old PRIMARY KEY value. btr_index_rec_validate(): Recognize the metadata record. btr_discard_only_page_on_level(): Preserve the generic instant ALTER TABLE metadata. btr_set_instant(): Replaces page_set_instant(). This sets a clustered index root page to the appropriate format, or upgrades from the MDEV-11369 instant ADD COLUMN to generic ALTER TABLE format. btr_cur_instant_init_low(): Read and validate the metadata BLOB page before reconstructing the dictionary information based on it. btr_cur_instant_init_metadata(): Do not read any lengths from the metadata record header before reading the BLOB. At this point, we would not actually know how many nullable fields the metadata record contains. btr_cur_instant_root_init(): Initialize n_core_null_bytes in one of two possible ways. btr_cur_trim(): Handle the mblob record. row_metadata_to_tuple(): Convert a metadata record to a data tuple, based on the new info_bits of the metadata record. btr_cur_pessimistic_update(): Invoke row_metadata_to_tuple() if needed. Invoke dtuple_convert_big_rec() for metadata records if the record is too large, or if the mblob is not yet marked as externally stored. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): When the last user record is deleted, do not delete the generic instant ALTER TABLE metadata record. Only delete MDEV-11369 instant ADD COLUMN metadata records. btr_cur_optimistic_insert(): Avoid unnecessary computation of rec_size. btr_pcur_store_position(): Allow a logically empty page to contain a metadata record for generic ALTER TABLE. REC_INFO_DEFAULT_ROW_ADD: Renamed from REC_INFO_DEFAULT_ROW. This is for the old instant ADD COLUMN (MDEV-11369) only. REC_INFO_DEFAULT_ROW_ALTER: The more generic metadata record, with additional information for dropped or reordered columns. rec_info_bits_valid(): Remove. The only case when this would fail is when the record is the generic ALTER TABLE metadata record. rec_is_alter_metadata(): Check if a record is the metadata record for instant ALTER TABLE (other than ADD COLUMN). NOTE: This function must not be invoked on node pointer records, because the delete-mark flag in those records may be set (it is garbage), and then a debug assertion could fail because index->is_instant() does not necessarily hold. rec_is_add_metadata(): Check if a record is MDEV-11369 ADD COLUMN metadata record (not more generic instant ALTER TABLE). rec_get_converted_size_comp_prefix_low(): Assume that the metadata field will be stored externally. In dtuple_convert_big_rec() during the rec_get_converted_size() call, it would not be there yet. rec_get_converted_size_comp(): Replace status,fields,n_fields with tuple. rec_init_offsets_comp_ordinary(), rec_get_converted_size_comp_prefix_low(), rec_convert_dtuple_to_rec_comp(): Add template<bool mblob = false>. With mblob=true, process a record with a metadata BLOB. rec_copy_prefix_to_buf(): Assert that no fields beyond the key and system columns are being copied. Exclude the metadata BLOB field. rec_convert_dtuple_to_metadata_comp(): Convert an alter metadata tuple into a record. row_upd_index_replace_metadata(): Apply an update vector to an alter_metadata tuple. row_log_allocate(): Replace dict_index_t::is_instant() with a more appropriate condition that ignores dict_table_t::instant. Only a table on which the MDEV-11369 ADD COLUMN was performed can "lose its instantness" when it becomes empty. After instant DROP COLUMN or reordering columns, we cannot simply convert the table to the canonical format, because the data dictionary cache and all possibly existing references to it from other client connection threads would have to be adjusted. row_quiesce_write_index_fields(): Do not crash when the table contains an instantly dropped column. Thanks to Thirunarayanan Balathandayuthapani for discussing the design and implementing an initial prototype of this. Thanks to Matthias Leich for testing.
7 years ago
MDEV-15662 Instant DROP COLUMN or changing the order of columns Allow ADD COLUMN anywhere in a table, not only adding as the last column. Allow instant DROP COLUMN and instant changing the order of columns. The added columns will always be added last in clustered index records. In new records, instantly dropped columns will be stored as NULL or empty when possible. Information about dropped and reordered columns will be written in a metadata BLOB (mblob), which is stored before the first 'user' field in the hidden metadata record at the start of the clustered index. The presence of mblob is indicated by setting the delete-mark flag in the metadata record. The metadata BLOB stores the number of clustered index fields, followed by an array of column information for each field. For dropped columns, we store the NOT NULL flag, the fixed length, and for variable-length columns, whether the maximum length exceeded 255 bytes. For non-dropped columns, we store the column position. Unlike with MDEV-11369, when a table becomes empty, it cannot be converted back to the canonical format. The reason for this is that other threads may hold cached objects such as row_prebuilt_t::ins_node that could refer to dropped or reordered index fields. For instant DROP COLUMN and ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC, we must store the n_core_null_bytes in the root page, so that the chain of node pointer records can be followed in order to reach the leftmost leaf page where the metadata record is located. If the mblob is present, we will zero-initialize the strings "infimum" and "supremum" in the root page, and use the last byte of "supremum" for storing the number of null bytes (which are allocated but useless on node pointer pages). This is necessary for btr_cur_instant_init_metadata() to be able to navigate to the mblob. If the PRIMARY KEY contains any variable-length column and some nullable columns were instantly dropped, the dict_index_t::n_nullable in the data dictionary could be smaller than it actually is in the non-leaf pages. Because of this, the non-leaf pages could use more bytes for the null flags than the data dictionary expects, and we could be reading the lengths of the variable-length columns from the wrong offset, and thus reading the child page number from wrong place. This is the result of two design mistakes that involve unnecessary storage of data: First, it is nonsense to store any data fields for the leftmost node pointer records, because the comparisons would be resolved by the MIN_REC_FLAG alone. Second, there cannot be any null fields in the clustered index node pointer fields, but we nevertheless reserve space for all the null flags. Limitations (future work): MDEV-17459 Allow instant ALTER TABLE even if FULLTEXT INDEX exists MDEV-17468 Avoid table rebuild on operations on generated columns MDEV-17494 Refuse ALGORITHM=INSTANT when the row size is too large btr_page_reorganize_low(): Preserve any metadata in the root page. Call lock_move_reorganize_page() only after restoring the "infimum" and "supremum" records, to avoid a memcmp() assertion failure. dict_col_t::DROPPED: Magic value for dict_col_t::ind. dict_col_t::clear_instant(): Renamed from dict_col_t::remove_instant(). Do not assert that the column was instantly added, because we sometimes call this unconditionally for all columns. Convert an instantly added column to a "core column". The old name remove_instant() could be mistaken to refer to "instant DROP COLUMN". dict_col_t::is_added(): Rename from dict_col_t::is_instant(). dtype_t::metadata_blob_init(): Initialize the mblob data type. dtuple_t::is_metadata(), dtuple_t::is_alter_metadata(), upd_t::is_metadata(), upd_t::is_alter_metadata(): Check if info_bits refer to a metadata record. dict_table_t::instant: Metadata about dropped or reordered columns. dict_table_t::prepare_instant(): Prepare ha_innobase_inplace_ctx::instant_table for instant ALTER TABLE. innobase_instant_try() will pass this to dict_table_t::instant_column(). On rollback, dict_table_t::rollback_instant() will be called. dict_table_t::instant_column(): Renamed from instant_add_column(). Add the parameter col_map so that columns can be reordered. Copy and adjust v_cols[] as well. dict_table_t::find(): Find an old column based on a new column number. dict_table_t::serialise_columns(), dict_table_t::deserialise_columns(): Convert the mblob. dict_index_t::instant_metadata(): Create the metadata record for instant ALTER TABLE. Invoke dict_table_t::serialise_columns(). dict_index_t::reconstruct_fields(): Invoked by dict_table_t::deserialise_columns(). dict_index_t::clear_instant_alter(): Move the fields for the dropped columns to the end, and sort the surviving index fields in ascending order of column position. ha_innobase::check_if_supported_inplace_alter(): Do not allow adding a FTS_DOC_ID column if a hidden FTS_DOC_ID column exists due to FULLTEXT INDEX. (This always required ALGORITHM=COPY.) instant_alter_column_possible(): Add a parameter for InnoDB table, to check for additional conditions, such as the maximum number of index fields. ha_innobase_inplace_ctx::first_alter_pos: The first column whose position is affected by instant ADD, DROP, or changing the order of columns. innobase_build_col_map(): Skip added virtual columns. prepare_inplace_add_virtual(): Correctly compute num_to_add_vcol. Remove some unnecessary code. Note that the call to innodb_base_col_setup() should be executed later. commit_try_norebuild(): If ctx->is_instant(), let the virtual columns be added or dropped by innobase_instant_try(). innobase_instant_try(): Fill in a zero default value for the hidden column FTS_DOC_ID (to reduce the work needed in MDEV-17459). If any columns were dropped or reordered (or added not last), delete any SYS_COLUMNS records for the following columns, and insert SYS_COLUMNS records for all subsequent stored columns as well as for all virtual columns. If any virtual column is dropped, rewrite all virtual column metadata. Use a shortcut only for adding virtual columns. This is because innobase_drop_virtual_try() assumes that the dropped virtual columns still exist in ctx->old_table. innodb_update_cols(): Renamed from innodb_update_n_cols(). innobase_add_one_virtual(), innobase_insert_sys_virtual(): Change the return type to bool, and invoke my_error() when detecting an error. innodb_insert_sys_columns(): Insert a record into SYS_COLUMNS. Refactored from innobase_add_one_virtual() and innobase_instant_add_col(). innobase_instant_add_col(): Replace the parameter dfield with type. innobase_instant_drop_cols(): Drop matching columns from SYS_COLUMNS and all columns from SYS_VIRTUAL. innobase_add_virtual_try(), innobase_drop_virtual_try(): Let the caller invoke innodb_update_cols(). innobase_rename_column_try(): Skip dropped columns. commit_cache_norebuild(): Update table->fts->doc_col. dict_mem_table_col_rename_low(): Skip dropped columns. trx_undo_rec_get_partial_row(): Skip dropped columns. trx_undo_update_rec_get_update(): Handle the metadata BLOB correctly. trx_undo_page_report_modify(): Avoid out-of-bounds access to record fields. Log metadata records consistently. Apparently, the first fields of a clustered index may be updated in an update_undo vector when the index is ID_IND of SYS_FOREIGN, as part of renaming the table during ALTER TABLE. Normally, updates of the PRIMARY KEY should be logged as delete-mark and an insert. row_undo_mod_parse_undo_rec(), row_purge_parse_undo_rec(): Use trx_undo_metadata. row_undo_mod_clust_low(): On metadata rollback, roll back the root page too. row_undo_mod_clust(): Relax an assertion. The delete-mark flag was repurposed for ALTER TABLE metadata records. row_rec_to_index_entry_impl(): Add the template parameter mblob and the optional parameter info_bits for specifying the desired new info bits. For the metadata tuple, allow conversion between the original format (ADD COLUMN only) and the generic format (with hidden BLOB). Add the optional parameter "pad" to determine whether the tuple should be padded to the index fields (on ALTER TABLE it should), or whether it should remain at its original size (on rollback). row_build_index_entry_low(): Clean up the code, removing redundant variables and conditions. For instantly dropped columns, generate a dummy value that is NULL, the empty string, or a fixed length of NUL bytes, depending on the type of the dropped column. row_upd_clust_rec_by_insert_inherit_func(): On the update of PRIMARY KEY of a record that contained a dropped column whose value was stored externally, we will be inserting a dummy NULL or empty string value to the field of the dropped column. The externally stored column would eventually be dropped when purge removes the delete-marked record for the old PRIMARY KEY value. btr_index_rec_validate(): Recognize the metadata record. btr_discard_only_page_on_level(): Preserve the generic instant ALTER TABLE metadata. btr_set_instant(): Replaces page_set_instant(). This sets a clustered index root page to the appropriate format, or upgrades from the MDEV-11369 instant ADD COLUMN to generic ALTER TABLE format. btr_cur_instant_init_low(): Read and validate the metadata BLOB page before reconstructing the dictionary information based on it. btr_cur_instant_init_metadata(): Do not read any lengths from the metadata record header before reading the BLOB. At this point, we would not actually know how many nullable fields the metadata record contains. btr_cur_instant_root_init(): Initialize n_core_null_bytes in one of two possible ways. btr_cur_trim(): Handle the mblob record. row_metadata_to_tuple(): Convert a metadata record to a data tuple, based on the new info_bits of the metadata record. btr_cur_pessimistic_update(): Invoke row_metadata_to_tuple() if needed. Invoke dtuple_convert_big_rec() for metadata records if the record is too large, or if the mblob is not yet marked as externally stored. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): When the last user record is deleted, do not delete the generic instant ALTER TABLE metadata record. Only delete MDEV-11369 instant ADD COLUMN metadata records. btr_cur_optimistic_insert(): Avoid unnecessary computation of rec_size. btr_pcur_store_position(): Allow a logically empty page to contain a metadata record for generic ALTER TABLE. REC_INFO_DEFAULT_ROW_ADD: Renamed from REC_INFO_DEFAULT_ROW. This is for the old instant ADD COLUMN (MDEV-11369) only. REC_INFO_DEFAULT_ROW_ALTER: The more generic metadata record, with additional information for dropped or reordered columns. rec_info_bits_valid(): Remove. The only case when this would fail is when the record is the generic ALTER TABLE metadata record. rec_is_alter_metadata(): Check if a record is the metadata record for instant ALTER TABLE (other than ADD COLUMN). NOTE: This function must not be invoked on node pointer records, because the delete-mark flag in those records may be set (it is garbage), and then a debug assertion could fail because index->is_instant() does not necessarily hold. rec_is_add_metadata(): Check if a record is MDEV-11369 ADD COLUMN metadata record (not more generic instant ALTER TABLE). rec_get_converted_size_comp_prefix_low(): Assume that the metadata field will be stored externally. In dtuple_convert_big_rec() during the rec_get_converted_size() call, it would not be there yet. rec_get_converted_size_comp(): Replace status,fields,n_fields with tuple. rec_init_offsets_comp_ordinary(), rec_get_converted_size_comp_prefix_low(), rec_convert_dtuple_to_rec_comp(): Add template<bool mblob = false>. With mblob=true, process a record with a metadata BLOB. rec_copy_prefix_to_buf(): Assert that no fields beyond the key and system columns are being copied. Exclude the metadata BLOB field. rec_convert_dtuple_to_metadata_comp(): Convert an alter metadata tuple into a record. row_upd_index_replace_metadata(): Apply an update vector to an alter_metadata tuple. row_log_allocate(): Replace dict_index_t::is_instant() with a more appropriate condition that ignores dict_table_t::instant. Only a table on which the MDEV-11369 ADD COLUMN was performed can "lose its instantness" when it becomes empty. After instant DROP COLUMN or reordering columns, we cannot simply convert the table to the canonical format, because the data dictionary cache and all possibly existing references to it from other client connection threads would have to be adjusted. row_quiesce_write_index_fields(): Do not crash when the table contains an instantly dropped column. Thanks to Thirunarayanan Balathandayuthapani for discussing the design and implementing an initial prototype of this. Thanks to Matthias Leich for testing.
7 years ago
MDEV-15662 Instant DROP COLUMN or changing the order of columns Allow ADD COLUMN anywhere in a table, not only adding as the last column. Allow instant DROP COLUMN and instant changing the order of columns. The added columns will always be added last in clustered index records. In new records, instantly dropped columns will be stored as NULL or empty when possible. Information about dropped and reordered columns will be written in a metadata BLOB (mblob), which is stored before the first 'user' field in the hidden metadata record at the start of the clustered index. The presence of mblob is indicated by setting the delete-mark flag in the metadata record. The metadata BLOB stores the number of clustered index fields, followed by an array of column information for each field. For dropped columns, we store the NOT NULL flag, the fixed length, and for variable-length columns, whether the maximum length exceeded 255 bytes. For non-dropped columns, we store the column position. Unlike with MDEV-11369, when a table becomes empty, it cannot be converted back to the canonical format. The reason for this is that other threads may hold cached objects such as row_prebuilt_t::ins_node that could refer to dropped or reordered index fields. For instant DROP COLUMN and ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC, we must store the n_core_null_bytes in the root page, so that the chain of node pointer records can be followed in order to reach the leftmost leaf page where the metadata record is located. If the mblob is present, we will zero-initialize the strings "infimum" and "supremum" in the root page, and use the last byte of "supremum" for storing the number of null bytes (which are allocated but useless on node pointer pages). This is necessary for btr_cur_instant_init_metadata() to be able to navigate to the mblob. If the PRIMARY KEY contains any variable-length column and some nullable columns were instantly dropped, the dict_index_t::n_nullable in the data dictionary could be smaller than it actually is in the non-leaf pages. Because of this, the non-leaf pages could use more bytes for the null flags than the data dictionary expects, and we could be reading the lengths of the variable-length columns from the wrong offset, and thus reading the child page number from wrong place. This is the result of two design mistakes that involve unnecessary storage of data: First, it is nonsense to store any data fields for the leftmost node pointer records, because the comparisons would be resolved by the MIN_REC_FLAG alone. Second, there cannot be any null fields in the clustered index node pointer fields, but we nevertheless reserve space for all the null flags. Limitations (future work): MDEV-17459 Allow instant ALTER TABLE even if FULLTEXT INDEX exists MDEV-17468 Avoid table rebuild on operations on generated columns MDEV-17494 Refuse ALGORITHM=INSTANT when the row size is too large btr_page_reorganize_low(): Preserve any metadata in the root page. Call lock_move_reorganize_page() only after restoring the "infimum" and "supremum" records, to avoid a memcmp() assertion failure. dict_col_t::DROPPED: Magic value for dict_col_t::ind. dict_col_t::clear_instant(): Renamed from dict_col_t::remove_instant(). Do not assert that the column was instantly added, because we sometimes call this unconditionally for all columns. Convert an instantly added column to a "core column". The old name remove_instant() could be mistaken to refer to "instant DROP COLUMN". dict_col_t::is_added(): Rename from dict_col_t::is_instant(). dtype_t::metadata_blob_init(): Initialize the mblob data type. dtuple_t::is_metadata(), dtuple_t::is_alter_metadata(), upd_t::is_metadata(), upd_t::is_alter_metadata(): Check if info_bits refer to a metadata record. dict_table_t::instant: Metadata about dropped or reordered columns. dict_table_t::prepare_instant(): Prepare ha_innobase_inplace_ctx::instant_table for instant ALTER TABLE. innobase_instant_try() will pass this to dict_table_t::instant_column(). On rollback, dict_table_t::rollback_instant() will be called. dict_table_t::instant_column(): Renamed from instant_add_column(). Add the parameter col_map so that columns can be reordered. Copy and adjust v_cols[] as well. dict_table_t::find(): Find an old column based on a new column number. dict_table_t::serialise_columns(), dict_table_t::deserialise_columns(): Convert the mblob. dict_index_t::instant_metadata(): Create the metadata record for instant ALTER TABLE. Invoke dict_table_t::serialise_columns(). dict_index_t::reconstruct_fields(): Invoked by dict_table_t::deserialise_columns(). dict_index_t::clear_instant_alter(): Move the fields for the dropped columns to the end, and sort the surviving index fields in ascending order of column position. ha_innobase::check_if_supported_inplace_alter(): Do not allow adding a FTS_DOC_ID column if a hidden FTS_DOC_ID column exists due to FULLTEXT INDEX. (This always required ALGORITHM=COPY.) instant_alter_column_possible(): Add a parameter for InnoDB table, to check for additional conditions, such as the maximum number of index fields. ha_innobase_inplace_ctx::first_alter_pos: The first column whose position is affected by instant ADD, DROP, or changing the order of columns. innobase_build_col_map(): Skip added virtual columns. prepare_inplace_add_virtual(): Correctly compute num_to_add_vcol. Remove some unnecessary code. Note that the call to innodb_base_col_setup() should be executed later. commit_try_norebuild(): If ctx->is_instant(), let the virtual columns be added or dropped by innobase_instant_try(). innobase_instant_try(): Fill in a zero default value for the hidden column FTS_DOC_ID (to reduce the work needed in MDEV-17459). If any columns were dropped or reordered (or added not last), delete any SYS_COLUMNS records for the following columns, and insert SYS_COLUMNS records for all subsequent stored columns as well as for all virtual columns. If any virtual column is dropped, rewrite all virtual column metadata. Use a shortcut only for adding virtual columns. This is because innobase_drop_virtual_try() assumes that the dropped virtual columns still exist in ctx->old_table. innodb_update_cols(): Renamed from innodb_update_n_cols(). innobase_add_one_virtual(), innobase_insert_sys_virtual(): Change the return type to bool, and invoke my_error() when detecting an error. innodb_insert_sys_columns(): Insert a record into SYS_COLUMNS. Refactored from innobase_add_one_virtual() and innobase_instant_add_col(). innobase_instant_add_col(): Replace the parameter dfield with type. innobase_instant_drop_cols(): Drop matching columns from SYS_COLUMNS and all columns from SYS_VIRTUAL. innobase_add_virtual_try(), innobase_drop_virtual_try(): Let the caller invoke innodb_update_cols(). innobase_rename_column_try(): Skip dropped columns. commit_cache_norebuild(): Update table->fts->doc_col. dict_mem_table_col_rename_low(): Skip dropped columns. trx_undo_rec_get_partial_row(): Skip dropped columns. trx_undo_update_rec_get_update(): Handle the metadata BLOB correctly. trx_undo_page_report_modify(): Avoid out-of-bounds access to record fields. Log metadata records consistently. Apparently, the first fields of a clustered index may be updated in an update_undo vector when the index is ID_IND of SYS_FOREIGN, as part of renaming the table during ALTER TABLE. Normally, updates of the PRIMARY KEY should be logged as delete-mark and an insert. row_undo_mod_parse_undo_rec(), row_purge_parse_undo_rec(): Use trx_undo_metadata. row_undo_mod_clust_low(): On metadata rollback, roll back the root page too. row_undo_mod_clust(): Relax an assertion. The delete-mark flag was repurposed for ALTER TABLE metadata records. row_rec_to_index_entry_impl(): Add the template parameter mblob and the optional parameter info_bits for specifying the desired new info bits. For the metadata tuple, allow conversion between the original format (ADD COLUMN only) and the generic format (with hidden BLOB). Add the optional parameter "pad" to determine whether the tuple should be padded to the index fields (on ALTER TABLE it should), or whether it should remain at its original size (on rollback). row_build_index_entry_low(): Clean up the code, removing redundant variables and conditions. For instantly dropped columns, generate a dummy value that is NULL, the empty string, or a fixed length of NUL bytes, depending on the type of the dropped column. row_upd_clust_rec_by_insert_inherit_func(): On the update of PRIMARY KEY of a record that contained a dropped column whose value was stored externally, we will be inserting a dummy NULL or empty string value to the field of the dropped column. The externally stored column would eventually be dropped when purge removes the delete-marked record for the old PRIMARY KEY value. btr_index_rec_validate(): Recognize the metadata record. btr_discard_only_page_on_level(): Preserve the generic instant ALTER TABLE metadata. btr_set_instant(): Replaces page_set_instant(). This sets a clustered index root page to the appropriate format, or upgrades from the MDEV-11369 instant ADD COLUMN to generic ALTER TABLE format. btr_cur_instant_init_low(): Read and validate the metadata BLOB page before reconstructing the dictionary information based on it. btr_cur_instant_init_metadata(): Do not read any lengths from the metadata record header before reading the BLOB. At this point, we would not actually know how many nullable fields the metadata record contains. btr_cur_instant_root_init(): Initialize n_core_null_bytes in one of two possible ways. btr_cur_trim(): Handle the mblob record. row_metadata_to_tuple(): Convert a metadata record to a data tuple, based on the new info_bits of the metadata record. btr_cur_pessimistic_update(): Invoke row_metadata_to_tuple() if needed. Invoke dtuple_convert_big_rec() for metadata records if the record is too large, or if the mblob is not yet marked as externally stored. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): When the last user record is deleted, do not delete the generic instant ALTER TABLE metadata record. Only delete MDEV-11369 instant ADD COLUMN metadata records. btr_cur_optimistic_insert(): Avoid unnecessary computation of rec_size. btr_pcur_store_position(): Allow a logically empty page to contain a metadata record for generic ALTER TABLE. REC_INFO_DEFAULT_ROW_ADD: Renamed from REC_INFO_DEFAULT_ROW. This is for the old instant ADD COLUMN (MDEV-11369) only. REC_INFO_DEFAULT_ROW_ALTER: The more generic metadata record, with additional information for dropped or reordered columns. rec_info_bits_valid(): Remove. The only case when this would fail is when the record is the generic ALTER TABLE metadata record. rec_is_alter_metadata(): Check if a record is the metadata record for instant ALTER TABLE (other than ADD COLUMN). NOTE: This function must not be invoked on node pointer records, because the delete-mark flag in those records may be set (it is garbage), and then a debug assertion could fail because index->is_instant() does not necessarily hold. rec_is_add_metadata(): Check if a record is MDEV-11369 ADD COLUMN metadata record (not more generic instant ALTER TABLE). rec_get_converted_size_comp_prefix_low(): Assume that the metadata field will be stored externally. In dtuple_convert_big_rec() during the rec_get_converted_size() call, it would not be there yet. rec_get_converted_size_comp(): Replace status,fields,n_fields with tuple. rec_init_offsets_comp_ordinary(), rec_get_converted_size_comp_prefix_low(), rec_convert_dtuple_to_rec_comp(): Add template<bool mblob = false>. With mblob=true, process a record with a metadata BLOB. rec_copy_prefix_to_buf(): Assert that no fields beyond the key and system columns are being copied. Exclude the metadata BLOB field. rec_convert_dtuple_to_metadata_comp(): Convert an alter metadata tuple into a record. row_upd_index_replace_metadata(): Apply an update vector to an alter_metadata tuple. row_log_allocate(): Replace dict_index_t::is_instant() with a more appropriate condition that ignores dict_table_t::instant. Only a table on which the MDEV-11369 ADD COLUMN was performed can "lose its instantness" when it becomes empty. After instant DROP COLUMN or reordering columns, we cannot simply convert the table to the canonical format, because the data dictionary cache and all possibly existing references to it from other client connection threads would have to be adjusted. row_quiesce_write_index_fields(): Do not crash when the table contains an instantly dropped column. Thanks to Thirunarayanan Balathandayuthapani for discussing the design and implementing an initial prototype of this. Thanks to Matthias Leich for testing.
7 years ago
MDEV-11369 Instant ADD COLUMN for InnoDB For InnoDB tables, adding, dropping and reordering columns has required a rebuild of the table and all its indexes. Since MySQL 5.6 (and MariaDB 10.0) this has been supported online (LOCK=NONE), allowing concurrent modification of the tables. This work revises the InnoDB ROW_FORMAT=REDUNDANT, ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC so that columns can be appended instantaneously, with only minor changes performed to the table structure. The counter innodb_instant_alter_column in INFORMATION_SCHEMA.GLOBAL_STATUS is incremented whenever a table rebuild operation is converted into an instant ADD COLUMN operation. ROW_FORMAT=COMPRESSED tables will not support instant ADD COLUMN. Some usability limitations will be addressed in subsequent work: MDEV-13134 Introduce ALTER TABLE attributes ALGORITHM=NOCOPY and ALGORITHM=INSTANT MDEV-14016 Allow instant ADD COLUMN, ADD INDEX, LOCK=NONE The format of the clustered index (PRIMARY KEY) is changed as follows: (1) The FIL_PAGE_TYPE of the root page will be FIL_PAGE_TYPE_INSTANT, and a new field PAGE_INSTANT will contain the original number of fields in the clustered index ('core' fields). If instant ADD COLUMN has not been used or the table becomes empty, or the very first instant ADD COLUMN operation is rolled back, the fields PAGE_INSTANT and FIL_PAGE_TYPE will be reset to 0 and FIL_PAGE_INDEX. (2) A special 'default row' record is inserted into the leftmost leaf, between the page infimum and the first user record. This record is distinguished by the REC_INFO_MIN_REC_FLAG, and it is otherwise in the same format as records that contain values for the instantly added columns. This 'default row' always has the same number of fields as the clustered index according to the table definition. The values of 'core' fields are to be ignored. For other fields, the 'default row' will contain the default values as they were during the ALTER TABLE statement. (If the column default values are changed later, those values will only be stored in the .frm file. The 'default row' will contain the original evaluated values, which must be the same for every row.) The 'default row' must be completely hidden from higher-level access routines. Assertions have been added to ensure that no 'default row' is ever present in the adaptive hash index or in locked records. The 'default row' is never delete-marked. (3) In clustered index leaf page records, the number of fields must reside between the number of 'core' fields (dict_index_t::n_core_fields introduced in this work) and dict_index_t::n_fields. If the number of fields is less than dict_index_t::n_fields, the missing fields are replaced with the column value of the 'default row'. Note: The number of fields in the record may shrink if some of the last instantly added columns are updated to the value that is in the 'default row'. The function btr_cur_trim() implements this 'compression' on update and rollback; dtuple::trim() implements it on insert. (4) In ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC records, the new status value REC_STATUS_COLUMNS_ADDED will indicate the presence of a new record header that will encode n_fields-n_core_fields-1 in 1 or 2 bytes. (In ROW_FORMAT=REDUNDANT records, the record header always explicitly encodes the number of fields.) We introduce the undo log record type TRX_UNDO_INSERT_DEFAULT for covering the insert of the 'default row' record when instant ADD COLUMN is used for the first time. Subsequent instant ADD COLUMN can use TRX_UNDO_UPD_EXIST_REC. This is joint work with Vin Chen (陈福荣) from Tencent. The design that was discussed in April 2017 would not have allowed import or export of data files, because instead of the 'default row' it would have introduced a data dictionary table. The test rpl.rpl_alter_instant is exactly as contributed in pull request #408. The test innodb.instant_alter is based on a contributed test. The redo log record format changes for ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPACT are as contributed. (With this change present, crash recovery from MariaDB 10.3.1 will fail in spectacular ways!) Also the semantics of higher-level redo log records that modify the PAGE_INSTANT field is changed. The redo log format version identifier was already changed to LOG_HEADER_FORMAT_CURRENT=103 in MariaDB 10.3.1. Everything else has been rewritten by me. Thanks to Elena Stepanova, the code has been tested extensively. When rolling back an instant ADD COLUMN operation, we must empty the PAGE_FREE list after deleting or shortening the 'default row' record, by calling either btr_page_empty() or btr_page_reorganize(). We must know the size of each entry in the PAGE_FREE list. If rollback left a freed copy of the 'default row' in the PAGE_FREE list, we would be unable to determine its size (if it is in ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC) because it would contain more fields than the rolled-back definition of the clustered index. UNIV_SQL_DEFAULT: A new special constant that designates an instantly added column that is not present in the clustered index record. len_is_stored(): Check if a length is an actual length. There are two magic length values: UNIV_SQL_DEFAULT, UNIV_SQL_NULL. dict_col_t::def_val: The 'default row' value of the column. If the column is not added instantly, def_val.len will be UNIV_SQL_DEFAULT. dict_col_t: Add the accessors is_virtual(), is_nullable(), is_instant(), instant_value(). dict_col_t::remove_instant(): Remove the 'instant ADD' status of a column. dict_col_t::name(const dict_table_t& table): Replaces dict_table_get_col_name(). dict_index_t::n_core_fields: The original number of fields. For secondary indexes and if instant ADD COLUMN has not been used, this will be equal to dict_index_t::n_fields. dict_index_t::n_core_null_bytes: Number of bytes needed to represent the null flags; usually equal to UT_BITS_IN_BYTES(n_nullable). dict_index_t::NO_CORE_NULL_BYTES: Magic value signalling that n_core_null_bytes was not initialized yet from the clustered index root page. dict_index_t: Add the accessors is_instant(), is_clust(), get_n_nullable(), instant_field_value(). dict_index_t::instant_add_field(): Adjust clustered index metadata for instant ADD COLUMN. dict_index_t::remove_instant(): Remove the 'instant ADD' status of a clustered index when the table becomes empty, or the very first instant ADD COLUMN operation is rolled back. dict_table_t: Add the accessors is_instant(), is_temporary(), supports_instant(). dict_table_t::instant_add_column(): Adjust metadata for instant ADD COLUMN. dict_table_t::rollback_instant(): Adjust metadata on the rollback of instant ADD COLUMN. prepare_inplace_alter_table_dict(): First create the ctx->new_table, and only then decide if the table really needs to be rebuilt. We must split the creation of table or index metadata from the creation of the dictionary table records and the creation of the data. In this way, we can transform a table-rebuilding operation into an instant ADD COLUMN operation. Dictionary objects will only be added to cache when table rebuilding or index creation is needed. The ctx->instant_table will never be added to cache. dict_table_t::add_to_cache(): Modified and renamed from dict_table_add_to_cache(). Do not modify the table metadata. Let the callers invoke dict_table_add_system_columns() and if needed, set can_be_evicted. dict_create_sys_tables_tuple(), dict_create_table_step(): Omit the system columns (which will now exist in the dict_table_t object already at this point). dict_create_table_step(): Expect the callers to invoke dict_table_add_system_columns(). pars_create_table(): Before creating the table creation execution graph, invoke dict_table_add_system_columns(). row_create_table_for_mysql(): Expect all callers to invoke dict_table_add_system_columns(). create_index_dict(): Replaces row_merge_create_index_graph(). innodb_update_n_cols(): Renamed from innobase_update_n_virtual(). Call my_error() if an error occurs. btr_cur_instant_init(), btr_cur_instant_init_low(), btr_cur_instant_root_init(): Load additional metadata from the clustered index and set dict_index_t::n_core_null_bytes. This is invoked when table metadata is first loaded into the data dictionary. dict_boot(): Initialize n_core_null_bytes for the four hard-coded dictionary tables. dict_create_index_step(): Initialize n_core_null_bytes. This is executed as part of CREATE TABLE. dict_index_build_internal_clust(): Initialize n_core_null_bytes to NO_CORE_NULL_BYTES if table->supports_instant(). row_create_index_for_mysql(): Initialize n_core_null_bytes for CREATE TEMPORARY TABLE. commit_cache_norebuild(): Call the code to rename or enlarge columns in the cache only if instant ADD COLUMN is not being used. (Instant ADD COLUMN would copy all column metadata from instant_table to old_table, including the names and lengths.) PAGE_INSTANT: A new 13-bit field for storing dict_index_t::n_core_fields. This is repurposing the 16-bit field PAGE_DIRECTION, of which only the least significant 3 bits were used. The original byte containing PAGE_DIRECTION will be accessible via the new constant PAGE_DIRECTION_B. page_get_instant(), page_set_instant(): Accessors for the PAGE_INSTANT. page_ptr_get_direction(), page_get_direction(), page_ptr_set_direction(): Accessors for PAGE_DIRECTION. page_direction_reset(): Reset PAGE_DIRECTION, PAGE_N_DIRECTION. page_direction_increment(): Increment PAGE_N_DIRECTION and set PAGE_DIRECTION. rec_get_offsets(): Use the 'leaf' parameter for non-debug purposes, and assume that heap_no is always set. Initialize all dict_index_t::n_fields for ROW_FORMAT=REDUNDANT records, even if the record contains fewer fields. rec_offs_make_valid(): Add the parameter 'leaf'. rec_copy_prefix_to_dtuple(): Assert that the tuple is only built on the core fields. Instant ADD COLUMN only applies to the clustered index, and we should never build a search key that has more than the PRIMARY KEY and possibly DB_TRX_ID,DB_ROLL_PTR. All these columns are always present. dict_index_build_data_tuple(): Remove assertions that would be duplicated in rec_copy_prefix_to_dtuple(). rec_init_offsets(): Support ROW_FORMAT=REDUNDANT records whose number of fields is between n_core_fields and n_fields. cmp_rec_rec_with_match(): Implement the comparison between two MIN_REC_FLAG records. trx_t::in_rollback: Make the field available in non-debug builds. trx_start_for_ddl_low(): Remove dangerous error-tolerance. A dictionary transaction must be flagged as such before it has generated any undo log records. This is because trx_undo_assign_undo() will mark the transaction as a dictionary transaction in the undo log header right before the very first undo log record is being written. btr_index_rec_validate(): Account for instant ADD COLUMN row_undo_ins_remove_clust_rec(): On the rollback of an insert into SYS_COLUMNS, revert instant ADD COLUMN in the cache by removing the last column from the table and the clustered index. row_search_on_row_ref(), row_undo_mod_parse_undo_rec(), row_undo_mod(), trx_undo_update_rec_get_update(): Handle the 'default row' as a special case. dtuple_t::trim(index): Omit a redundant suffix of an index tuple right before insert or update. After instant ADD COLUMN, if the last fields of a clustered index tuple match the 'default row', there is no need to store them. While trimming the entry, we must hold a page latch, so that the table cannot be emptied and the 'default row' be deleted. btr_cur_optimistic_update(), btr_cur_pessimistic_update(), row_upd_clust_rec_by_insert(), row_ins_clust_index_entry_low(): Invoke dtuple_t::trim() if needed. row_ins_clust_index_entry(): Restore dtuple_t::n_fields after calling row_ins_clust_index_entry_low(). rec_get_converted_size(), rec_get_converted_size_comp(): Allow the number of fields to be between n_core_fields and n_fields. Do not support infimum,supremum. They are never supposed to be stored in dtuple_t, because page creation nowadays uses a lower-level method for initializing them. rec_convert_dtuple_to_rec_comp(): Assign the status bits based on the number of fields. btr_cur_trim(): In an update, trim the index entry as needed. For the 'default row', handle rollback specially. For user records, omit fields that match the 'default row'. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): Skip locking and adaptive hash index for the 'default row'. row_log_table_apply_convert_mrec(): Replace 'default row' values if needed. In the temporary file that is applied by row_log_table_apply(), we must identify whether the records contain the extra header for instantly added columns. For now, we will allocate an additional byte for this for ROW_T_INSERT and ROW_T_UPDATE records when the source table has been subject to instant ADD COLUMN. The ROW_T_DELETE records are fine, as they will be converted and will only contain 'core' columns (PRIMARY KEY and some system columns) that are converted from dtuple_t. rec_get_converted_size_temp(), rec_init_offsets_temp(), rec_convert_dtuple_to_temp(): Add the parameter 'status'. REC_INFO_DEFAULT_ROW = REC_INFO_MIN_REC_FLAG | REC_STATUS_COLUMNS_ADDED: An info_bits constant for distinguishing the 'default row' record. rec_comp_status_t: An enum of the status bit values. rec_leaf_format: An enum that replaces the bool parameter of rec_init_offsets_comp_ordinary().
8 years ago
20 years ago
MDEV-11369 Instant ADD COLUMN for InnoDB For InnoDB tables, adding, dropping and reordering columns has required a rebuild of the table and all its indexes. Since MySQL 5.6 (and MariaDB 10.0) this has been supported online (LOCK=NONE), allowing concurrent modification of the tables. This work revises the InnoDB ROW_FORMAT=REDUNDANT, ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC so that columns can be appended instantaneously, with only minor changes performed to the table structure. The counter innodb_instant_alter_column in INFORMATION_SCHEMA.GLOBAL_STATUS is incremented whenever a table rebuild operation is converted into an instant ADD COLUMN operation. ROW_FORMAT=COMPRESSED tables will not support instant ADD COLUMN. Some usability limitations will be addressed in subsequent work: MDEV-13134 Introduce ALTER TABLE attributes ALGORITHM=NOCOPY and ALGORITHM=INSTANT MDEV-14016 Allow instant ADD COLUMN, ADD INDEX, LOCK=NONE The format of the clustered index (PRIMARY KEY) is changed as follows: (1) The FIL_PAGE_TYPE of the root page will be FIL_PAGE_TYPE_INSTANT, and a new field PAGE_INSTANT will contain the original number of fields in the clustered index ('core' fields). If instant ADD COLUMN has not been used or the table becomes empty, or the very first instant ADD COLUMN operation is rolled back, the fields PAGE_INSTANT and FIL_PAGE_TYPE will be reset to 0 and FIL_PAGE_INDEX. (2) A special 'default row' record is inserted into the leftmost leaf, between the page infimum and the first user record. This record is distinguished by the REC_INFO_MIN_REC_FLAG, and it is otherwise in the same format as records that contain values for the instantly added columns. This 'default row' always has the same number of fields as the clustered index according to the table definition. The values of 'core' fields are to be ignored. For other fields, the 'default row' will contain the default values as they were during the ALTER TABLE statement. (If the column default values are changed later, those values will only be stored in the .frm file. The 'default row' will contain the original evaluated values, which must be the same for every row.) The 'default row' must be completely hidden from higher-level access routines. Assertions have been added to ensure that no 'default row' is ever present in the adaptive hash index or in locked records. The 'default row' is never delete-marked. (3) In clustered index leaf page records, the number of fields must reside between the number of 'core' fields (dict_index_t::n_core_fields introduced in this work) and dict_index_t::n_fields. If the number of fields is less than dict_index_t::n_fields, the missing fields are replaced with the column value of the 'default row'. Note: The number of fields in the record may shrink if some of the last instantly added columns are updated to the value that is in the 'default row'. The function btr_cur_trim() implements this 'compression' on update and rollback; dtuple::trim() implements it on insert. (4) In ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC records, the new status value REC_STATUS_COLUMNS_ADDED will indicate the presence of a new record header that will encode n_fields-n_core_fields-1 in 1 or 2 bytes. (In ROW_FORMAT=REDUNDANT records, the record header always explicitly encodes the number of fields.) We introduce the undo log record type TRX_UNDO_INSERT_DEFAULT for covering the insert of the 'default row' record when instant ADD COLUMN is used for the first time. Subsequent instant ADD COLUMN can use TRX_UNDO_UPD_EXIST_REC. This is joint work with Vin Chen (陈福荣) from Tencent. The design that was discussed in April 2017 would not have allowed import or export of data files, because instead of the 'default row' it would have introduced a data dictionary table. The test rpl.rpl_alter_instant is exactly as contributed in pull request #408. The test innodb.instant_alter is based on a contributed test. The redo log record format changes for ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPACT are as contributed. (With this change present, crash recovery from MariaDB 10.3.1 will fail in spectacular ways!) Also the semantics of higher-level redo log records that modify the PAGE_INSTANT field is changed. The redo log format version identifier was already changed to LOG_HEADER_FORMAT_CURRENT=103 in MariaDB 10.3.1. Everything else has been rewritten by me. Thanks to Elena Stepanova, the code has been tested extensively. When rolling back an instant ADD COLUMN operation, we must empty the PAGE_FREE list after deleting or shortening the 'default row' record, by calling either btr_page_empty() or btr_page_reorganize(). We must know the size of each entry in the PAGE_FREE list. If rollback left a freed copy of the 'default row' in the PAGE_FREE list, we would be unable to determine its size (if it is in ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC) because it would contain more fields than the rolled-back definition of the clustered index. UNIV_SQL_DEFAULT: A new special constant that designates an instantly added column that is not present in the clustered index record. len_is_stored(): Check if a length is an actual length. There are two magic length values: UNIV_SQL_DEFAULT, UNIV_SQL_NULL. dict_col_t::def_val: The 'default row' value of the column. If the column is not added instantly, def_val.len will be UNIV_SQL_DEFAULT. dict_col_t: Add the accessors is_virtual(), is_nullable(), is_instant(), instant_value(). dict_col_t::remove_instant(): Remove the 'instant ADD' status of a column. dict_col_t::name(const dict_table_t& table): Replaces dict_table_get_col_name(). dict_index_t::n_core_fields: The original number of fields. For secondary indexes and if instant ADD COLUMN has not been used, this will be equal to dict_index_t::n_fields. dict_index_t::n_core_null_bytes: Number of bytes needed to represent the null flags; usually equal to UT_BITS_IN_BYTES(n_nullable). dict_index_t::NO_CORE_NULL_BYTES: Magic value signalling that n_core_null_bytes was not initialized yet from the clustered index root page. dict_index_t: Add the accessors is_instant(), is_clust(), get_n_nullable(), instant_field_value(). dict_index_t::instant_add_field(): Adjust clustered index metadata for instant ADD COLUMN. dict_index_t::remove_instant(): Remove the 'instant ADD' status of a clustered index when the table becomes empty, or the very first instant ADD COLUMN operation is rolled back. dict_table_t: Add the accessors is_instant(), is_temporary(), supports_instant(). dict_table_t::instant_add_column(): Adjust metadata for instant ADD COLUMN. dict_table_t::rollback_instant(): Adjust metadata on the rollback of instant ADD COLUMN. prepare_inplace_alter_table_dict(): First create the ctx->new_table, and only then decide if the table really needs to be rebuilt. We must split the creation of table or index metadata from the creation of the dictionary table records and the creation of the data. In this way, we can transform a table-rebuilding operation into an instant ADD COLUMN operation. Dictionary objects will only be added to cache when table rebuilding or index creation is needed. The ctx->instant_table will never be added to cache. dict_table_t::add_to_cache(): Modified and renamed from dict_table_add_to_cache(). Do not modify the table metadata. Let the callers invoke dict_table_add_system_columns() and if needed, set can_be_evicted. dict_create_sys_tables_tuple(), dict_create_table_step(): Omit the system columns (which will now exist in the dict_table_t object already at this point). dict_create_table_step(): Expect the callers to invoke dict_table_add_system_columns(). pars_create_table(): Before creating the table creation execution graph, invoke dict_table_add_system_columns(). row_create_table_for_mysql(): Expect all callers to invoke dict_table_add_system_columns(). create_index_dict(): Replaces row_merge_create_index_graph(). innodb_update_n_cols(): Renamed from innobase_update_n_virtual(). Call my_error() if an error occurs. btr_cur_instant_init(), btr_cur_instant_init_low(), btr_cur_instant_root_init(): Load additional metadata from the clustered index and set dict_index_t::n_core_null_bytes. This is invoked when table metadata is first loaded into the data dictionary. dict_boot(): Initialize n_core_null_bytes for the four hard-coded dictionary tables. dict_create_index_step(): Initialize n_core_null_bytes. This is executed as part of CREATE TABLE. dict_index_build_internal_clust(): Initialize n_core_null_bytes to NO_CORE_NULL_BYTES if table->supports_instant(). row_create_index_for_mysql(): Initialize n_core_null_bytes for CREATE TEMPORARY TABLE. commit_cache_norebuild(): Call the code to rename or enlarge columns in the cache only if instant ADD COLUMN is not being used. (Instant ADD COLUMN would copy all column metadata from instant_table to old_table, including the names and lengths.) PAGE_INSTANT: A new 13-bit field for storing dict_index_t::n_core_fields. This is repurposing the 16-bit field PAGE_DIRECTION, of which only the least significant 3 bits were used. The original byte containing PAGE_DIRECTION will be accessible via the new constant PAGE_DIRECTION_B. page_get_instant(), page_set_instant(): Accessors for the PAGE_INSTANT. page_ptr_get_direction(), page_get_direction(), page_ptr_set_direction(): Accessors for PAGE_DIRECTION. page_direction_reset(): Reset PAGE_DIRECTION, PAGE_N_DIRECTION. page_direction_increment(): Increment PAGE_N_DIRECTION and set PAGE_DIRECTION. rec_get_offsets(): Use the 'leaf' parameter for non-debug purposes, and assume that heap_no is always set. Initialize all dict_index_t::n_fields for ROW_FORMAT=REDUNDANT records, even if the record contains fewer fields. rec_offs_make_valid(): Add the parameter 'leaf'. rec_copy_prefix_to_dtuple(): Assert that the tuple is only built on the core fields. Instant ADD COLUMN only applies to the clustered index, and we should never build a search key that has more than the PRIMARY KEY and possibly DB_TRX_ID,DB_ROLL_PTR. All these columns are always present. dict_index_build_data_tuple(): Remove assertions that would be duplicated in rec_copy_prefix_to_dtuple(). rec_init_offsets(): Support ROW_FORMAT=REDUNDANT records whose number of fields is between n_core_fields and n_fields. cmp_rec_rec_with_match(): Implement the comparison between two MIN_REC_FLAG records. trx_t::in_rollback: Make the field available in non-debug builds. trx_start_for_ddl_low(): Remove dangerous error-tolerance. A dictionary transaction must be flagged as such before it has generated any undo log records. This is because trx_undo_assign_undo() will mark the transaction as a dictionary transaction in the undo log header right before the very first undo log record is being written. btr_index_rec_validate(): Account for instant ADD COLUMN row_undo_ins_remove_clust_rec(): On the rollback of an insert into SYS_COLUMNS, revert instant ADD COLUMN in the cache by removing the last column from the table and the clustered index. row_search_on_row_ref(), row_undo_mod_parse_undo_rec(), row_undo_mod(), trx_undo_update_rec_get_update(): Handle the 'default row' as a special case. dtuple_t::trim(index): Omit a redundant suffix of an index tuple right before insert or update. After instant ADD COLUMN, if the last fields of a clustered index tuple match the 'default row', there is no need to store them. While trimming the entry, we must hold a page latch, so that the table cannot be emptied and the 'default row' be deleted. btr_cur_optimistic_update(), btr_cur_pessimistic_update(), row_upd_clust_rec_by_insert(), row_ins_clust_index_entry_low(): Invoke dtuple_t::trim() if needed. row_ins_clust_index_entry(): Restore dtuple_t::n_fields after calling row_ins_clust_index_entry_low(). rec_get_converted_size(), rec_get_converted_size_comp(): Allow the number of fields to be between n_core_fields and n_fields. Do not support infimum,supremum. They are never supposed to be stored in dtuple_t, because page creation nowadays uses a lower-level method for initializing them. rec_convert_dtuple_to_rec_comp(): Assign the status bits based on the number of fields. btr_cur_trim(): In an update, trim the index entry as needed. For the 'default row', handle rollback specially. For user records, omit fields that match the 'default row'. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): Skip locking and adaptive hash index for the 'default row'. row_log_table_apply_convert_mrec(): Replace 'default row' values if needed. In the temporary file that is applied by row_log_table_apply(), we must identify whether the records contain the extra header for instantly added columns. For now, we will allocate an additional byte for this for ROW_T_INSERT and ROW_T_UPDATE records when the source table has been subject to instant ADD COLUMN. The ROW_T_DELETE records are fine, as they will be converted and will only contain 'core' columns (PRIMARY KEY and some system columns) that are converted from dtuple_t. rec_get_converted_size_temp(), rec_init_offsets_temp(), rec_convert_dtuple_to_temp(): Add the parameter 'status'. REC_INFO_DEFAULT_ROW = REC_INFO_MIN_REC_FLAG | REC_STATUS_COLUMNS_ADDED: An info_bits constant for distinguishing the 'default row' record. rec_comp_status_t: An enum of the status bit values. rec_leaf_format: An enum that replaces the bool parameter of rec_init_offsets_comp_ordinary().
8 years ago
20 years ago
MDEV-11415 Remove excessive undo logging during ALTER TABLE…ALGORITHM=COPY If a crash occurs during ALTER TABLE…ALGORITHM=COPY, InnoDB would spend a lot of time rolling back writes to the intermediate copy of the table. To reduce the amount of busy work done, a work-around was introduced in commit fd069e2bb36a3c1c1f26d65dd298b07e6d83ac8b in MySQL 4.1.8 and 5.0.2, to commit the transaction after every 10,000 inserted rows. A proper fix would have been to disable the undo logging altogether and to simply drop the intermediate copy of the table on subsequent server startup. This is what happens in MariaDB 10.3 with MDEV-14717,MDEV-14585. In MariaDB 10.2, the intermediate copy of the table would be left behind with a name starting with the string #sql. This is a backport of a bug fix from MySQL 8.0.0 to MariaDB, contributed by jixianliang <271365745@qq.com>. Unlike recent MySQL, MariaDB supports ALTER IGNORE. For that operation InnoDB must for now keep the undo logging enabled, so that the latest row can be rolled back in case of an error. In Galera cluster, the LOAD DATA statement will retain the existing behaviour and commit the transaction after every 10,000 rows if the parameter wsrep_load_data_splitting=ON is set. The logic to do so (the wsrep_load_data_split() function and the call handler::extra(HA_EXTRA_FAKE_START_STMT)) are joint work by Ji Xianliang and Marko Mäkelä. The original fix: Author: Thirunarayanan Balathandayuthapani <thirunarayanan.balathandayuth@oracle.com> Date: Wed Dec 2 16:09:15 2015 +0530 Bug#17479594 AVOID INTERMEDIATE COMMIT WHILE DOING ALTER TABLE ALGORITHM=COPY Problem: During ALTER TABLE, we commit and restart the transaction for every 10,000 rows, so that the rollback after recovery would not take so long. Fix: Suppress the undo logging during copy alter operation. If fts_index is present then insert directly into fts auxiliary table rather than doing at commit time. ha_innobase::num_write_row: Remove the variable. ha_innobase::write_row(): Remove the hack for committing every 10000 rows. row_lock_table_for_mysql(): Remove the extra 2 parameters. lock_get_src_table(), lock_is_table_exclusive(): Remove. Reviewed-by: Marko Mäkelä <marko.makela@oracle.com> Reviewed-by: Shaohua Wang <shaohua.wang@oracle.com> Reviewed-by: Jon Olav Hauglid <jon.hauglid@oracle.com>
8 years ago
MDEV-15662 Instant DROP COLUMN or changing the order of columns Allow ADD COLUMN anywhere in a table, not only adding as the last column. Allow instant DROP COLUMN and instant changing the order of columns. The added columns will always be added last in clustered index records. In new records, instantly dropped columns will be stored as NULL or empty when possible. Information about dropped and reordered columns will be written in a metadata BLOB (mblob), which is stored before the first 'user' field in the hidden metadata record at the start of the clustered index. The presence of mblob is indicated by setting the delete-mark flag in the metadata record. The metadata BLOB stores the number of clustered index fields, followed by an array of column information for each field. For dropped columns, we store the NOT NULL flag, the fixed length, and for variable-length columns, whether the maximum length exceeded 255 bytes. For non-dropped columns, we store the column position. Unlike with MDEV-11369, when a table becomes empty, it cannot be converted back to the canonical format. The reason for this is that other threads may hold cached objects such as row_prebuilt_t::ins_node that could refer to dropped or reordered index fields. For instant DROP COLUMN and ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC, we must store the n_core_null_bytes in the root page, so that the chain of node pointer records can be followed in order to reach the leftmost leaf page where the metadata record is located. If the mblob is present, we will zero-initialize the strings "infimum" and "supremum" in the root page, and use the last byte of "supremum" for storing the number of null bytes (which are allocated but useless on node pointer pages). This is necessary for btr_cur_instant_init_metadata() to be able to navigate to the mblob. If the PRIMARY KEY contains any variable-length column and some nullable columns were instantly dropped, the dict_index_t::n_nullable in the data dictionary could be smaller than it actually is in the non-leaf pages. Because of this, the non-leaf pages could use more bytes for the null flags than the data dictionary expects, and we could be reading the lengths of the variable-length columns from the wrong offset, and thus reading the child page number from wrong place. This is the result of two design mistakes that involve unnecessary storage of data: First, it is nonsense to store any data fields for the leftmost node pointer records, because the comparisons would be resolved by the MIN_REC_FLAG alone. Second, there cannot be any null fields in the clustered index node pointer fields, but we nevertheless reserve space for all the null flags. Limitations (future work): MDEV-17459 Allow instant ALTER TABLE even if FULLTEXT INDEX exists MDEV-17468 Avoid table rebuild on operations on generated columns MDEV-17494 Refuse ALGORITHM=INSTANT when the row size is too large btr_page_reorganize_low(): Preserve any metadata in the root page. Call lock_move_reorganize_page() only after restoring the "infimum" and "supremum" records, to avoid a memcmp() assertion failure. dict_col_t::DROPPED: Magic value for dict_col_t::ind. dict_col_t::clear_instant(): Renamed from dict_col_t::remove_instant(). Do not assert that the column was instantly added, because we sometimes call this unconditionally for all columns. Convert an instantly added column to a "core column". The old name remove_instant() could be mistaken to refer to "instant DROP COLUMN". dict_col_t::is_added(): Rename from dict_col_t::is_instant(). dtype_t::metadata_blob_init(): Initialize the mblob data type. dtuple_t::is_metadata(), dtuple_t::is_alter_metadata(), upd_t::is_metadata(), upd_t::is_alter_metadata(): Check if info_bits refer to a metadata record. dict_table_t::instant: Metadata about dropped or reordered columns. dict_table_t::prepare_instant(): Prepare ha_innobase_inplace_ctx::instant_table for instant ALTER TABLE. innobase_instant_try() will pass this to dict_table_t::instant_column(). On rollback, dict_table_t::rollback_instant() will be called. dict_table_t::instant_column(): Renamed from instant_add_column(). Add the parameter col_map so that columns can be reordered. Copy and adjust v_cols[] as well. dict_table_t::find(): Find an old column based on a new column number. dict_table_t::serialise_columns(), dict_table_t::deserialise_columns(): Convert the mblob. dict_index_t::instant_metadata(): Create the metadata record for instant ALTER TABLE. Invoke dict_table_t::serialise_columns(). dict_index_t::reconstruct_fields(): Invoked by dict_table_t::deserialise_columns(). dict_index_t::clear_instant_alter(): Move the fields for the dropped columns to the end, and sort the surviving index fields in ascending order of column position. ha_innobase::check_if_supported_inplace_alter(): Do not allow adding a FTS_DOC_ID column if a hidden FTS_DOC_ID column exists due to FULLTEXT INDEX. (This always required ALGORITHM=COPY.) instant_alter_column_possible(): Add a parameter for InnoDB table, to check for additional conditions, such as the maximum number of index fields. ha_innobase_inplace_ctx::first_alter_pos: The first column whose position is affected by instant ADD, DROP, or changing the order of columns. innobase_build_col_map(): Skip added virtual columns. prepare_inplace_add_virtual(): Correctly compute num_to_add_vcol. Remove some unnecessary code. Note that the call to innodb_base_col_setup() should be executed later. commit_try_norebuild(): If ctx->is_instant(), let the virtual columns be added or dropped by innobase_instant_try(). innobase_instant_try(): Fill in a zero default value for the hidden column FTS_DOC_ID (to reduce the work needed in MDEV-17459). If any columns were dropped or reordered (or added not last), delete any SYS_COLUMNS records for the following columns, and insert SYS_COLUMNS records for all subsequent stored columns as well as for all virtual columns. If any virtual column is dropped, rewrite all virtual column metadata. Use a shortcut only for adding virtual columns. This is because innobase_drop_virtual_try() assumes that the dropped virtual columns still exist in ctx->old_table. innodb_update_cols(): Renamed from innodb_update_n_cols(). innobase_add_one_virtual(), innobase_insert_sys_virtual(): Change the return type to bool, and invoke my_error() when detecting an error. innodb_insert_sys_columns(): Insert a record into SYS_COLUMNS. Refactored from innobase_add_one_virtual() and innobase_instant_add_col(). innobase_instant_add_col(): Replace the parameter dfield with type. innobase_instant_drop_cols(): Drop matching columns from SYS_COLUMNS and all columns from SYS_VIRTUAL. innobase_add_virtual_try(), innobase_drop_virtual_try(): Let the caller invoke innodb_update_cols(). innobase_rename_column_try(): Skip dropped columns. commit_cache_norebuild(): Update table->fts->doc_col. dict_mem_table_col_rename_low(): Skip dropped columns. trx_undo_rec_get_partial_row(): Skip dropped columns. trx_undo_update_rec_get_update(): Handle the metadata BLOB correctly. trx_undo_page_report_modify(): Avoid out-of-bounds access to record fields. Log metadata records consistently. Apparently, the first fields of a clustered index may be updated in an update_undo vector when the index is ID_IND of SYS_FOREIGN, as part of renaming the table during ALTER TABLE. Normally, updates of the PRIMARY KEY should be logged as delete-mark and an insert. row_undo_mod_parse_undo_rec(), row_purge_parse_undo_rec(): Use trx_undo_metadata. row_undo_mod_clust_low(): On metadata rollback, roll back the root page too. row_undo_mod_clust(): Relax an assertion. The delete-mark flag was repurposed for ALTER TABLE metadata records. row_rec_to_index_entry_impl(): Add the template parameter mblob and the optional parameter info_bits for specifying the desired new info bits. For the metadata tuple, allow conversion between the original format (ADD COLUMN only) and the generic format (with hidden BLOB). Add the optional parameter "pad" to determine whether the tuple should be padded to the index fields (on ALTER TABLE it should), or whether it should remain at its original size (on rollback). row_build_index_entry_low(): Clean up the code, removing redundant variables and conditions. For instantly dropped columns, generate a dummy value that is NULL, the empty string, or a fixed length of NUL bytes, depending on the type of the dropped column. row_upd_clust_rec_by_insert_inherit_func(): On the update of PRIMARY KEY of a record that contained a dropped column whose value was stored externally, we will be inserting a dummy NULL or empty string value to the field of the dropped column. The externally stored column would eventually be dropped when purge removes the delete-marked record for the old PRIMARY KEY value. btr_index_rec_validate(): Recognize the metadata record. btr_discard_only_page_on_level(): Preserve the generic instant ALTER TABLE metadata. btr_set_instant(): Replaces page_set_instant(). This sets a clustered index root page to the appropriate format, or upgrades from the MDEV-11369 instant ADD COLUMN to generic ALTER TABLE format. btr_cur_instant_init_low(): Read and validate the metadata BLOB page before reconstructing the dictionary information based on it. btr_cur_instant_init_metadata(): Do not read any lengths from the metadata record header before reading the BLOB. At this point, we would not actually know how many nullable fields the metadata record contains. btr_cur_instant_root_init(): Initialize n_core_null_bytes in one of two possible ways. btr_cur_trim(): Handle the mblob record. row_metadata_to_tuple(): Convert a metadata record to a data tuple, based on the new info_bits of the metadata record. btr_cur_pessimistic_update(): Invoke row_metadata_to_tuple() if needed. Invoke dtuple_convert_big_rec() for metadata records if the record is too large, or if the mblob is not yet marked as externally stored. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): When the last user record is deleted, do not delete the generic instant ALTER TABLE metadata record. Only delete MDEV-11369 instant ADD COLUMN metadata records. btr_cur_optimistic_insert(): Avoid unnecessary computation of rec_size. btr_pcur_store_position(): Allow a logically empty page to contain a metadata record for generic ALTER TABLE. REC_INFO_DEFAULT_ROW_ADD: Renamed from REC_INFO_DEFAULT_ROW. This is for the old instant ADD COLUMN (MDEV-11369) only. REC_INFO_DEFAULT_ROW_ALTER: The more generic metadata record, with additional information for dropped or reordered columns. rec_info_bits_valid(): Remove. The only case when this would fail is when the record is the generic ALTER TABLE metadata record. rec_is_alter_metadata(): Check if a record is the metadata record for instant ALTER TABLE (other than ADD COLUMN). NOTE: This function must not be invoked on node pointer records, because the delete-mark flag in those records may be set (it is garbage), and then a debug assertion could fail because index->is_instant() does not necessarily hold. rec_is_add_metadata(): Check if a record is MDEV-11369 ADD COLUMN metadata record (not more generic instant ALTER TABLE). rec_get_converted_size_comp_prefix_low(): Assume that the metadata field will be stored externally. In dtuple_convert_big_rec() during the rec_get_converted_size() call, it would not be there yet. rec_get_converted_size_comp(): Replace status,fields,n_fields with tuple. rec_init_offsets_comp_ordinary(), rec_get_converted_size_comp_prefix_low(), rec_convert_dtuple_to_rec_comp(): Add template<bool mblob = false>. With mblob=true, process a record with a metadata BLOB. rec_copy_prefix_to_buf(): Assert that no fields beyond the key and system columns are being copied. Exclude the metadata BLOB field. rec_convert_dtuple_to_metadata_comp(): Convert an alter metadata tuple into a record. row_upd_index_replace_metadata(): Apply an update vector to an alter_metadata tuple. row_log_allocate(): Replace dict_index_t::is_instant() with a more appropriate condition that ignores dict_table_t::instant. Only a table on which the MDEV-11369 ADD COLUMN was performed can "lose its instantness" when it becomes empty. After instant DROP COLUMN or reordering columns, we cannot simply convert the table to the canonical format, because the data dictionary cache and all possibly existing references to it from other client connection threads would have to be adjusted. row_quiesce_write_index_fields(): Do not crash when the table contains an instantly dropped column. Thanks to Thirunarayanan Balathandayuthapani for discussing the design and implementing an initial prototype of this. Thanks to Matthias Leich for testing.
7 years ago
MDEV-11415 Remove excessive undo logging during ALTER TABLE…ALGORITHM=COPY If a crash occurs during ALTER TABLE…ALGORITHM=COPY, InnoDB would spend a lot of time rolling back writes to the intermediate copy of the table. To reduce the amount of busy work done, a work-around was introduced in commit fd069e2bb36a3c1c1f26d65dd298b07e6d83ac8b in MySQL 4.1.8 and 5.0.2, to commit the transaction after every 10,000 inserted rows. A proper fix would have been to disable the undo logging altogether and to simply drop the intermediate copy of the table on subsequent server startup. This is what happens in MariaDB 10.3 with MDEV-14717,MDEV-14585. In MariaDB 10.2, the intermediate copy of the table would be left behind with a name starting with the string #sql. This is a backport of a bug fix from MySQL 8.0.0 to MariaDB, contributed by jixianliang <271365745@qq.com>. Unlike recent MySQL, MariaDB supports ALTER IGNORE. For that operation InnoDB must for now keep the undo logging enabled, so that the latest row can be rolled back in case of an error. In Galera cluster, the LOAD DATA statement will retain the existing behaviour and commit the transaction after every 10,000 rows if the parameter wsrep_load_data_splitting=ON is set. The logic to do so (the wsrep_load_data_split() function and the call handler::extra(HA_EXTRA_FAKE_START_STMT)) are joint work by Ji Xianliang and Marko Mäkelä. The original fix: Author: Thirunarayanan Balathandayuthapani <thirunarayanan.balathandayuth@oracle.com> Date: Wed Dec 2 16:09:15 2015 +0530 Bug#17479594 AVOID INTERMEDIATE COMMIT WHILE DOING ALTER TABLE ALGORITHM=COPY Problem: During ALTER TABLE, we commit and restart the transaction for every 10,000 rows, so that the rollback after recovery would not take so long. Fix: Suppress the undo logging during copy alter operation. If fts_index is present then insert directly into fts auxiliary table rather than doing at commit time. ha_innobase::num_write_row: Remove the variable. ha_innobase::write_row(): Remove the hack for committing every 10000 rows. row_lock_table_for_mysql(): Remove the extra 2 parameters. lock_get_src_table(), lock_is_table_exclusive(): Remove. Reviewed-by: Marko Mäkelä <marko.makela@oracle.com> Reviewed-by: Shaohua Wang <shaohua.wang@oracle.com> Reviewed-by: Jon Olav Hauglid <jon.hauglid@oracle.com>
8 years ago
20 years ago
MDEV-21907: InnoDB: Enable -Wconversion on clang and GCC The -Wconversion in GCC seems to be stricter than in clang. GCC at least since version 4.4.7 issues truncation warnings for assignments to bitfields, while clang 10 appears to only issue warnings when the sizes in bytes rounded to the nearest integer powers of 2 are different. Before GCC 10.0.0, -Wconversion required more casts and would not allow some operations, such as x<<=1 or x+=1 on a data type that is narrower than int. GCC 5 (but not GCC 4, GCC 6, or any later version) is complaining about x|=y even when x and y are compatible types that are narrower than int. Hence, we must rewrite some x|=y as x=static_cast<byte>(x|y) or similar, or we must disable -Wconversion. In GCC 6 and later, the warning for assigning wider to bitfields that are narrower than 8, 16, or 32 bits can be suppressed by applying a bitwise & with the exact bitmask of the bitfield. For older GCC, we must disable -Wconversion for GCC 4 or 5 in such cases. The bitwise negation operator appears to promote short integers to a wider type, and hence we must add explicit truncation casts around them. Microsoft Visual C does not allow a static_cast to truncate a constant, such as static_cast<byte>(1) truncating int. Hence, we will use the constructor-style cast byte(~1) for such cases. This has been tested at least with GCC 4.8.5, 5.4.0, 7.4.0, 9.2.1, 10.0.0, clang 9.0.1, 10.0.0, and MSVC 14.22.27905 (Microsoft Visual Studio 2019) on 64-bit and 32-bit targets (IA-32, AMD64, POWER 8, POWER 9, ARMv8).
6 years ago
20 years ago
20 years ago
MDEV-11415 Remove excessive undo logging during ALTER TABLE…ALGORITHM=COPY If a crash occurs during ALTER TABLE…ALGORITHM=COPY, InnoDB would spend a lot of time rolling back writes to the intermediate copy of the table. To reduce the amount of busy work done, a work-around was introduced in commit fd069e2bb36a3c1c1f26d65dd298b07e6d83ac8b in MySQL 4.1.8 and 5.0.2, to commit the transaction after every 10,000 inserted rows. A proper fix would have been to disable the undo logging altogether and to simply drop the intermediate copy of the table on subsequent server startup. This is what happens in MariaDB 10.3 with MDEV-14717,MDEV-14585. In MariaDB 10.2, the intermediate copy of the table would be left behind with a name starting with the string #sql. This is a backport of a bug fix from MySQL 8.0.0 to MariaDB, contributed by jixianliang <271365745@qq.com>. Unlike recent MySQL, MariaDB supports ALTER IGNORE. For that operation InnoDB must for now keep the undo logging enabled, so that the latest row can be rolled back in case of an error. In Galera cluster, the LOAD DATA statement will retain the existing behaviour and commit the transaction after every 10,000 rows if the parameter wsrep_load_data_splitting=ON is set. The logic to do so (the wsrep_load_data_split() function and the call handler::extra(HA_EXTRA_FAKE_START_STMT)) are joint work by Ji Xianliang and Marko Mäkelä. The original fix: Author: Thirunarayanan Balathandayuthapani <thirunarayanan.balathandayuth@oracle.com> Date: Wed Dec 2 16:09:15 2015 +0530 Bug#17479594 AVOID INTERMEDIATE COMMIT WHILE DOING ALTER TABLE ALGORITHM=COPY Problem: During ALTER TABLE, we commit and restart the transaction for every 10,000 rows, so that the rollback after recovery would not take so long. Fix: Suppress the undo logging during copy alter operation. If fts_index is present then insert directly into fts auxiliary table rather than doing at commit time. ha_innobase::num_write_row: Remove the variable. ha_innobase::write_row(): Remove the hack for committing every 10000 rows. row_lock_table_for_mysql(): Remove the extra 2 parameters. lock_get_src_table(), lock_is_table_exclusive(): Remove. Reviewed-by: Marko Mäkelä <marko.makela@oracle.com> Reviewed-by: Shaohua Wang <shaohua.wang@oracle.com> Reviewed-by: Jon Olav Hauglid <jon.hauglid@oracle.com>
8 years ago
MDEV-15250 UPSERT during ALTER TABLE results in 'Duplicate entry' error for alter - InnoDB DDL results in `Duplicate entry' if concurrent DML throws duplicate key error. The following scenario explains the problem connection con1: ALTER TABLE t1 FORCE; connection con2: INSERT INTO t1(pk, uk) VALUES (2, 2), (3, 2); In connection con2, InnoDB throws the 'DUPLICATE KEY' error because of unique index. Alter operation will throw the error when applying the concurrent DML log. - Inserting the duplicate key for unique index logs the insert operation for online ALTER TABLE. When insertion fails, transaction does rollback and it leads to logging of delete operation for online ALTER TABLE. While applying the insert log entries, alter operation encounters 'DUPLICATE KEY' error. - To avoid the above fake duplicate scenario, InnoDB should not write any log for online ALTER TABLE before DML transaction commit. - User thread which does DML can apply the online log if InnoDB ran out of online log and index is marked as completed. Set online log error if apply phase encountered any error. It can also clear all other indexes log, marks the newly added indexes as corrupted. - Removed the old online code which was a part of DML operations commit_inplace_alter_table() : Does apply the online log for the last batch of secondary index log and does frees the log for the completed index. trx_t::apply_online_log: Set to true while writing the undo log if the modified table has active DDL trx_t::apply_log(): Apply the DML changes to online DDL tables dict_table_t::is_active_ddl(): Returns true if the table has an active DDL dict_index_t::online_log_make_dummy(): Assign dummy value for clustered index online log to indicate the secondary indexes are being rebuild. dict_index_t::online_log_is_dummy(): Check whether the online log has dummy value ha_innobase_inplace_ctx::log_failure(): Handle the apply log failure for online DDL transaction row_log_mark_other_online_index_abort(): Clear out all other online index log after encountering the error during row_log_apply() row_log_get_error(): Get the error happened during row_log_apply() row_log_online_op(): Does apply the online log if index is completed and ran out of memory. Returns false if apply log fails UndorecApplier: Introduced a class to maintain the undo log record, latched undo buffer page, parse the undo log record, maintain the undo record type, info bits and update vector UndorecApplier::get_old_rec(): Get the correct version of the clustered index record that was modified by the current undo log record UndorecApplier::clear_undo_rec(): Clear the undo log related information after applying the undo log record UndorecApplier::log_update(): Handle the update, delete undo log and apply it on online indexes UndorecApplier::log_insert(): Handle the insert undo log and apply it on online indexes UndorecApplier::is_same(): Check whether the given roll pointer is generated by the current undo log record information trx_t::rollback_low(): Set apply_online_log for the transaction after partially rollbacked transaction has any active DDL prepare_inplace_alter_table_dict(): After allocating the online log, InnoDB does create fulltext common tables. Fulltext index doesn't allow the index to be online. So removed the dead code of online log removal Thanks to Marko Mäkelä for providing the initial prototype and Matthias Leich for testing the issue patiently.
4 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
20 years ago
20 years ago
MDEV-11415 Remove excessive undo logging during ALTER TABLE…ALGORITHM=COPY If a crash occurs during ALTER TABLE…ALGORITHM=COPY, InnoDB would spend a lot of time rolling back writes to the intermediate copy of the table. To reduce the amount of busy work done, a work-around was introduced in commit fd069e2bb36a3c1c1f26d65dd298b07e6d83ac8b in MySQL 4.1.8 and 5.0.2, to commit the transaction after every 10,000 inserted rows. A proper fix would have been to disable the undo logging altogether and to simply drop the intermediate copy of the table on subsequent server startup. This is what happens in MariaDB 10.3 with MDEV-14717,MDEV-14585. In MariaDB 10.2, the intermediate copy of the table would be left behind with a name starting with the string #sql. This is a backport of a bug fix from MySQL 8.0.0 to MariaDB, contributed by jixianliang <271365745@qq.com>. Unlike recent MySQL, MariaDB supports ALTER IGNORE. For that operation InnoDB must for now keep the undo logging enabled, so that the latest row can be rolled back in case of an error. In Galera cluster, the LOAD DATA statement will retain the existing behaviour and commit the transaction after every 10,000 rows if the parameter wsrep_load_data_splitting=ON is set. The logic to do so (the wsrep_load_data_split() function and the call handler::extra(HA_EXTRA_FAKE_START_STMT)) are joint work by Ji Xianliang and Marko Mäkelä. The original fix: Author: Thirunarayanan Balathandayuthapani <thirunarayanan.balathandayuth@oracle.com> Date: Wed Dec 2 16:09:15 2015 +0530 Bug#17479594 AVOID INTERMEDIATE COMMIT WHILE DOING ALTER TABLE ALGORITHM=COPY Problem: During ALTER TABLE, we commit and restart the transaction for every 10,000 rows, so that the rollback after recovery would not take so long. Fix: Suppress the undo logging during copy alter operation. If fts_index is present then insert directly into fts auxiliary table rather than doing at commit time. ha_innobase::num_write_row: Remove the variable. ha_innobase::write_row(): Remove the hack for committing every 10000 rows. row_lock_table_for_mysql(): Remove the extra 2 parameters. lock_get_src_table(), lock_is_table_exclusive(): Remove. Reviewed-by: Marko Mäkelä <marko.makela@oracle.com> Reviewed-by: Shaohua Wang <shaohua.wang@oracle.com> Reviewed-by: Jon Olav Hauglid <jon.hauglid@oracle.com>
8 years ago
20 years ago
20 years ago
20 years ago
20 years ago
MDEV-21907: InnoDB: Enable -Wconversion on clang and GCC The -Wconversion in GCC seems to be stricter than in clang. GCC at least since version 4.4.7 issues truncation warnings for assignments to bitfields, while clang 10 appears to only issue warnings when the sizes in bytes rounded to the nearest integer powers of 2 are different. Before GCC 10.0.0, -Wconversion required more casts and would not allow some operations, such as x<<=1 or x+=1 on a data type that is narrower than int. GCC 5 (but not GCC 4, GCC 6, or any later version) is complaining about x|=y even when x and y are compatible types that are narrower than int. Hence, we must rewrite some x|=y as x=static_cast<byte>(x|y) or similar, or we must disable -Wconversion. In GCC 6 and later, the warning for assigning wider to bitfields that are narrower than 8, 16, or 32 bits can be suppressed by applying a bitwise & with the exact bitmask of the bitfield. For older GCC, we must disable -Wconversion for GCC 4 or 5 in such cases. The bitwise negation operator appears to promote short integers to a wider type, and hence we must add explicit truncation casts around them. Microsoft Visual C does not allow a static_cast to truncate a constant, such as static_cast<byte>(1) truncating int. Hence, we will use the constructor-style cast byte(~1) for such cases. This has been tested at least with GCC 4.8.5, 5.4.0, 7.4.0, 9.2.1, 10.0.0, clang 9.0.1, 10.0.0, and MSVC 14.22.27905 (Microsoft Visual Studio 2019) on 64-bit and 32-bit targets (IA-32, AMD64, POWER 8, POWER 9, ARMv8).
6 years ago
20 years ago
20 years ago
20 years ago
MDEV-20377: Make WITH_MSAN more usable MemorySanitizer (clang -fsanitize=memory) requires that all code be compiled with instrumentation enabled. The only exception is the C runtime library. Failure to use instrumented libraries will cause bogus messages about memory being uninitialized. In WITH_MSAN builds, we must avoid calling getservbyname(), because even though it is a standard library function, it is not instrumented, not even in clang 10. Note: Before MariaDB Server 10.5, ./mtr will typically fail due to the old PCRE library, which was updated in MDEV-14024. The following cmake options were tested on 10.5 in commit 94d0bb4dbeb28a94d1f87fdd55f4297ff3df0157: cmake \ -DCMAKE_C_FLAGS='-march=native -O2' \ -DCMAKE_CXX_FLAGS='-stdlib=libc++ -march=native -O2' \ -DWITH_EMBEDDED_SERVER=OFF -DWITH_UNIT_TESTS=OFF -DCMAKE_BUILD_TYPE=Debug \ -DWITH_INNODB_{BZIP2,LZ4,LZMA,LZO,SNAPPY}=OFF \ -DPLUGIN_{ARCHIVE,TOKUDB,MROONGA,OQGRAPH,ROCKSDB,CONNECT,SPIDER}=NO \ -DWITH_SAFEMALLOC=OFF \ -DWITH_{ZLIB,SSL,PCRE}=bundled \ -DHAVE_LIBAIO_H=0 \ -DWITH_MSAN=ON MEM_MAKE_DEFINED(): An alias for VALGRIND_MAKE_MEM_DEFINED() and __msan_unpoison(). MEM_GET_VBITS(), MEM_SET_VBITS(): Aliases for VALGRIND_GET_VBITS(), VALGRIND_SET_VBITS(), __msan_copy_shadow(). InnoDB: Replace the UNIV_MEM_ macros with corresponding MEM_ macros. ut_crc32_8_hw(), ut_crc32_64_low_hw(): Use the compiler built-in functions instead of inline assembler when building WITH_MSAN. This will require at least -msse4.2 when building for IA-32 or AMD64. The inline assembler would not be instrumented, and would thus cause bogus failures.
5 years ago
MDEV-23399: Performance regression with write workloads The buffer pool refactoring in MDEV-15053 and MDEV-22871 shifted the performance bottleneck to the page flushing. The configuration parameters will be changed as follows: innodb_lru_flush_size=32 (new: how many pages to flush on LRU eviction) innodb_lru_scan_depth=1536 (old: 1024) innodb_max_dirty_pages_pct=90 (old: 75) innodb_max_dirty_pages_pct_lwm=75 (old: 0) Note: The parameter innodb_lru_scan_depth will only affect LRU eviction of buffer pool pages when a new page is being allocated. The page cleaner thread will no longer evict any pages. It used to guarantee that some pages will remain free in the buffer pool. Now, we perform that eviction 'on demand' in buf_LRU_get_free_block(). The parameter innodb_lru_scan_depth(srv_LRU_scan_depth) is used as follows: * When the buffer pool is being shrunk in buf_pool_t::withdraw_blocks() * As a buf_pool.free limit in buf_LRU_list_batch() for terminating the flushing that is initiated e.g., by buf_LRU_get_free_block() The parameter also used to serve as an initial limit for unzip_LRU eviction (evicting uncompressed page frames while retaining ROW_FORMAT=COMPRESSED pages), but now we will use a hard-coded limit of 100 or unlimited for invoking buf_LRU_scan_and_free_block(). The status variables will be changed as follows: innodb_buffer_pool_pages_flushed: This includes also the count of innodb_buffer_pool_pages_LRU_flushed and should work reliably, updated one by one in buf_flush_page() to give more real-time statistics. The function buf_flush_stats(), which we are removing, was not called in every code path. For both counters, we will use regular variables that are incremented in a critical section of buf_pool.mutex. Note that show_innodb_vars() directly links to the variables, and reads of the counters will *not* be protected by buf_pool.mutex, so you cannot get a consistent snapshot of both variables. The following INFORMATION_SCHEMA.INNODB_METRICS counters will be removed, because the page cleaner no longer deals with writing or evicting least recently used pages, and because the single-page writes have been removed: * buffer_LRU_batch_flush_avg_time_slot * buffer_LRU_batch_flush_avg_time_thread * buffer_LRU_batch_flush_avg_time_est * buffer_LRU_batch_flush_avg_pass * buffer_LRU_single_flush_scanned * buffer_LRU_single_flush_num_scan * buffer_LRU_single_flush_scanned_per_call When moving to a single buffer pool instance in MDEV-15058, we missed some opportunity to simplify the buf_flush_page_cleaner thread. It was unnecessarily using a mutex and some complex data structures, even though we always have a single page cleaner thread. Furthermore, the buf_flush_page_cleaner thread had separate 'recovery' and 'shutdown' modes where it was waiting to be triggered by some other thread, adding unnecessary latency and potential for hangs in relatively rarely executed startup or shutdown code. The page cleaner was also running two kinds of batches in an interleaved fashion: "LRU flush" (writing out some least recently used pages and evicting them on write completion) and the normal batches that aim to increase the MIN(oldest_modification) in the buffer pool, to help the log checkpoint advance. The buf_pool.flush_list flushing was being blocked by buf_block_t::lock for no good reason. Furthermore, if the FIL_PAGE_LSN of a page is ahead of log_sys.get_flushed_lsn(), that is, what has been persistently written to the redo log, we would trigger a log flush and then resume the page flushing. This would unnecessarily limit the performance of the page cleaner thread and trigger the infamous messages "InnoDB: page_cleaner: 1000ms intended loop took 4450ms. The settings might not be optimal" that were suppressed in commit d1ab89037a518fcffbc50c24e4bd94e4ec33aed0 unless log_warnings>2. Our revised algorithm will make log_sys.get_flushed_lsn() advance at the start of buf_flush_lists(), and then execute a 'best effort' to write out all pages. The flush batches will skip pages that were modified since the log was written, or are are currently exclusively locked. The MDEV-13670 message "page_cleaner: 1000ms intended loop took" message will be removed, because by design, the buf_flush_page_cleaner() should not be blocked during a batch for extended periods of time. We will remove the single-page flushing altogether. Related to this, the debug parameter innodb_doublewrite_batch_size will be removed, because all of the doublewrite buffer will be used for flushing batches. If a page needs to be evicted from the buffer pool and all 100 least recently used pages in the buffer pool have unflushed changes, buf_LRU_get_free_block() will execute buf_flush_lists() to write out and evict innodb_lru_flush_size pages. At most one thread will execute buf_flush_lists() in buf_LRU_get_free_block(); other threads will wait for that LRU flushing batch to finish. To improve concurrency, we will replace the InnoDB ib_mutex_t and os_event_t native mutexes and condition variables in this area of code. Most notably, this means that the buffer pool mutex (buf_pool.mutex) is no longer instrumented via any InnoDB interfaces. It will continue to be instrumented via PERFORMANCE_SCHEMA. For now, both buf_pool.flush_list_mutex and buf_pool.mutex will be declared with MY_MUTEX_INIT_FAST (PTHREAD_MUTEX_ADAPTIVE_NP). The critical sections of buf_pool.flush_list_mutex should be shorter than those for buf_pool.mutex, because in the worst case, they cover a linear scan of buf_pool.flush_list, while the worst case of a critical section of buf_pool.mutex covers a linear scan of the potentially much longer buf_pool.LRU list. mysql_mutex_is_owner(), safe_mutex_is_owner(): New predicate, usable with SAFE_MUTEX. Some InnoDB debug assertions need this predicate instead of mysql_mutex_assert_owner() or mysql_mutex_assert_not_owner(). buf_pool_t::n_flush_LRU, buf_pool_t::n_flush_list: Replaces buf_pool_t::init_flush[] and buf_pool_t::n_flush[]. The number of active flush operations. buf_pool_t::mutex, buf_pool_t::flush_list_mutex: Use mysql_mutex_t instead of ib_mutex_t, to have native mutexes with PERFORMANCE_SCHEMA and SAFE_MUTEX instrumentation. buf_pool_t::done_flush_LRU: Condition variable for !n_flush_LRU. buf_pool_t::done_flush_list: Condition variable for !n_flush_list. buf_pool_t::do_flush_list: Condition variable to wake up the buf_flush_page_cleaner when a log checkpoint needs to be written or the server is being shut down. Replaces buf_flush_event. We will keep using timed waits (the page cleaner thread will wake _at least_ once per second), because the calculations for innodb_adaptive_flushing depend on fixed time intervals. buf_dblwr: Allocate statically, and move all code to member functions. Use a native mutex and condition variable. Remove code to deal with single-page flushing. buf_dblwr_check_block(): Make the check debug-only. We were spending a significant amount of execution time in page_simple_validate_new(). flush_counters_t::unzip_LRU_evicted: Remove. IORequest: Make more members const. FIXME: m_fil_node should be removed. buf_flush_sync_lsn: Protect by std::atomic, not page_cleaner.mutex (which we are removing). page_cleaner_slot_t, page_cleaner_t: Remove many redundant members. pc_request_flush_slot(): Replaces pc_request() and pc_flush_slot(). recv_writer_thread: Remove. Recovery works just fine without it, if we simply invoke buf_flush_sync() at the end of each batch in recv_sys_t::apply(). recv_recovery_from_checkpoint_finish(): Remove. We can simply call recv_sys.debug_free() directly. srv_started_redo: Replaces srv_start_state. SRV_SHUTDOWN_FLUSH_PHASE: Remove. logs_empty_and_mark_files_at_shutdown() can communicate with the normal page cleaner loop via the new function flush_buffer_pool(). buf_flush_remove(): Assert that the calling thread is holding buf_pool.flush_list_mutex. This removes unnecessary mutex operations from buf_flush_remove_pages() and buf_flush_dirty_pages(), which replace buf_LRU_flush_or_remove_pages(). buf_flush_lists(): Renamed from buf_flush_batch(), with simplified interface. Return the number of flushed pages. Clarified comments and renamed min_n to max_n. Identify LRU batch by lsn=0. Merge all the functions buf_flush_start(), buf_flush_batch(), buf_flush_end() directly to this function, which was their only caller, and remove 2 unnecessary buf_pool.mutex release/re-acquisition that we used to perform around the buf_flush_batch() call. At the start, if not all log has been durably written, wait for a background task to do it, or start a new task to do it. This allows the log write to run concurrently with our page flushing batch. Any pages that were skipped due to too recent FIL_PAGE_LSN or due to them being latched by a writer should be flushed during the next batch, unless there are further modifications to those pages. It is possible that a page that we must flush due to small oldest_modification also carries a recent FIL_PAGE_LSN or is being constantly modified. In the worst case, all writers would then end up waiting in log_free_check() to allow the flushing and the checkpoint to complete. buf_do_flush_list_batch(): Clarify comments, and rename min_n to max_n. Cache the last looked up tablespace. If neighbor flushing is not applicable, invoke buf_flush_page() directly, avoiding a page lookup in between. buf_flush_space(): Auxiliary function to look up a tablespace for page flushing. buf_flush_page(): Defer the computation of space->full_crc32(). Never call log_write_up_to(), but instead skip persistent pages whose latest modification (FIL_PAGE_LSN) is newer than the redo log. Also skip pages on which we cannot acquire a shared latch without waiting. buf_flush_try_neighbors(): Do not bother checking buf_fix_count because buf_flush_page() will no longer wait for the page latch. Take the tablespace as a parameter, and only execute this function when innodb_flush_neighbors>0. Avoid repeated calls of page_id_t::fold(). buf_flush_relocate_on_flush_list(): Declare as cold, and push down a condition from the callers. buf_flush_check_neighbor(): Take id.fold() as a parameter. buf_flush_sync(): Ensure that the buf_pool.flush_list is empty, because the flushing batch will skip pages whose modifications have not yet been written to the log or were latched for modification. buf_free_from_unzip_LRU_list_batch(): Remove redundant local variables. buf_flush_LRU_list_batch(): Let the caller buf_do_LRU_batch() initialize the counters, and report n->evicted. Cache the last looked up tablespace. If neighbor flushing is not applicable, invoke buf_flush_page() directly, avoiding a page lookup in between. buf_do_LRU_batch(): Return the number of pages flushed. buf_LRU_free_page(): Only release and re-acquire buf_pool.mutex if adaptive hash index entries are pointing to the block. buf_LRU_get_free_block(): Do not wake up the page cleaner, because it will no longer perform any useful work for us, and we do not want it to compete for I/O while buf_flush_lists(innodb_lru_flush_size, 0) writes out and evicts at most innodb_lru_flush_size pages. (The function buf_do_LRU_batch() may complete after writing fewer pages if more than innodb_lru_scan_depth pages end up in buf_pool.free list.) Eliminate some mutex release-acquire cycles, and wait for the LRU flush batch to complete before rescanning. buf_LRU_check_size_of_non_data_objects(): Simplify the code. buf_page_write_complete(): Remove the parameter evict, and always evict pages that were part of an LRU flush. buf_page_create(): Take a pre-allocated page as a parameter. buf_pool_t::free_block(): Free a pre-allocated block. recv_sys_t::recover_low(), recv_sys_t::apply(): Preallocate the block while not holding recv_sys.mutex. During page allocation, we may initiate a page flush, which in turn may initiate a log flush, which would require acquiring log_sys.mutex, which should always be acquired before recv_sys.mutex in order to avoid deadlocks. Therefore, we must not be holding recv_sys.mutex while allocating a buffer pool block. BtrBulk::logFreeCheck(): Skip a redundant condition. row_undo_step(): Do not invoke srv_inc_activity_count() for every row that is being rolled back. It should suffice to invoke the function in trx_flush_log_if_needed() during trx_t::commit_in_memory() when the rollback completes. sync_check_enable(): Remove. We will enable innodb_sync_debug from the very beginning. Reviewed by: Vladislav Vaintroub
5 years ago
20 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
MDEV-11415 Remove excessive undo logging during ALTER TABLE…ALGORITHM=COPY If a crash occurs during ALTER TABLE…ALGORITHM=COPY, InnoDB would spend a lot of time rolling back writes to the intermediate copy of the table. To reduce the amount of busy work done, a work-around was introduced in commit fd069e2bb36a3c1c1f26d65dd298b07e6d83ac8b in MySQL 4.1.8 and 5.0.2, to commit the transaction after every 10,000 inserted rows. A proper fix would have been to disable the undo logging altogether and to simply drop the intermediate copy of the table on subsequent server startup. This is what happens in MariaDB 10.3 with MDEV-14717,MDEV-14585. In MariaDB 10.2, the intermediate copy of the table would be left behind with a name starting with the string #sql. This is a backport of a bug fix from MySQL 8.0.0 to MariaDB, contributed by jixianliang <271365745@qq.com>. Unlike recent MySQL, MariaDB supports ALTER IGNORE. For that operation InnoDB must for now keep the undo logging enabled, so that the latest row can be rolled back in case of an error. In Galera cluster, the LOAD DATA statement will retain the existing behaviour and commit the transaction after every 10,000 rows if the parameter wsrep_load_data_splitting=ON is set. The logic to do so (the wsrep_load_data_split() function and the call handler::extra(HA_EXTRA_FAKE_START_STMT)) are joint work by Ji Xianliang and Marko Mäkelä. The original fix: Author: Thirunarayanan Balathandayuthapani <thirunarayanan.balathandayuth@oracle.com> Date: Wed Dec 2 16:09:15 2015 +0530 Bug#17479594 AVOID INTERMEDIATE COMMIT WHILE DOING ALTER TABLE ALGORITHM=COPY Problem: During ALTER TABLE, we commit and restart the transaction for every 10,000 rows, so that the rollback after recovery would not take so long. Fix: Suppress the undo logging during copy alter operation. If fts_index is present then insert directly into fts auxiliary table rather than doing at commit time. ha_innobase::num_write_row: Remove the variable. ha_innobase::write_row(): Remove the hack for committing every 10000 rows. row_lock_table_for_mysql(): Remove the extra 2 parameters. lock_get_src_table(), lock_is_table_exclusive(): Remove. Reviewed-by: Marko Mäkelä <marko.makela@oracle.com> Reviewed-by: Shaohua Wang <shaohua.wang@oracle.com> Reviewed-by: Jon Olav Hauglid <jon.hauglid@oracle.com>
8 years ago
MDEV-11415 Remove excessive undo logging during ALTER TABLE…ALGORITHM=COPY If a crash occurs during ALTER TABLE…ALGORITHM=COPY, InnoDB would spend a lot of time rolling back writes to the intermediate copy of the table. To reduce the amount of busy work done, a work-around was introduced in commit fd069e2bb36a3c1c1f26d65dd298b07e6d83ac8b in MySQL 4.1.8 and 5.0.2, to commit the transaction after every 10,000 inserted rows. A proper fix would have been to disable the undo logging altogether and to simply drop the intermediate copy of the table on subsequent server startup. This is what happens in MariaDB 10.3 with MDEV-14717,MDEV-14585. In MariaDB 10.2, the intermediate copy of the table would be left behind with a name starting with the string #sql. This is a backport of a bug fix from MySQL 8.0.0 to MariaDB, contributed by jixianliang <271365745@qq.com>. Unlike recent MySQL, MariaDB supports ALTER IGNORE. For that operation InnoDB must for now keep the undo logging enabled, so that the latest row can be rolled back in case of an error. In Galera cluster, the LOAD DATA statement will retain the existing behaviour and commit the transaction after every 10,000 rows if the parameter wsrep_load_data_splitting=ON is set. The logic to do so (the wsrep_load_data_split() function and the call handler::extra(HA_EXTRA_FAKE_START_STMT)) are joint work by Ji Xianliang and Marko Mäkelä. The original fix: Author: Thirunarayanan Balathandayuthapani <thirunarayanan.balathandayuth@oracle.com> Date: Wed Dec 2 16:09:15 2015 +0530 Bug#17479594 AVOID INTERMEDIATE COMMIT WHILE DOING ALTER TABLE ALGORITHM=COPY Problem: During ALTER TABLE, we commit and restart the transaction for every 10,000 rows, so that the rollback after recovery would not take so long. Fix: Suppress the undo logging during copy alter operation. If fts_index is present then insert directly into fts auxiliary table rather than doing at commit time. ha_innobase::num_write_row: Remove the variable. ha_innobase::write_row(): Remove the hack for committing every 10000 rows. row_lock_table_for_mysql(): Remove the extra 2 parameters. lock_get_src_table(), lock_is_table_exclusive(): Remove. Reviewed-by: Marko Mäkelä <marko.makela@oracle.com> Reviewed-by: Shaohua Wang <shaohua.wang@oracle.com> Reviewed-by: Jon Olav Hauglid <jon.hauglid@oracle.com>
8 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
MDEV-11369 Instant ADD COLUMN for InnoDB For InnoDB tables, adding, dropping and reordering columns has required a rebuild of the table and all its indexes. Since MySQL 5.6 (and MariaDB 10.0) this has been supported online (LOCK=NONE), allowing concurrent modification of the tables. This work revises the InnoDB ROW_FORMAT=REDUNDANT, ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC so that columns can be appended instantaneously, with only minor changes performed to the table structure. The counter innodb_instant_alter_column in INFORMATION_SCHEMA.GLOBAL_STATUS is incremented whenever a table rebuild operation is converted into an instant ADD COLUMN operation. ROW_FORMAT=COMPRESSED tables will not support instant ADD COLUMN. Some usability limitations will be addressed in subsequent work: MDEV-13134 Introduce ALTER TABLE attributes ALGORITHM=NOCOPY and ALGORITHM=INSTANT MDEV-14016 Allow instant ADD COLUMN, ADD INDEX, LOCK=NONE The format of the clustered index (PRIMARY KEY) is changed as follows: (1) The FIL_PAGE_TYPE of the root page will be FIL_PAGE_TYPE_INSTANT, and a new field PAGE_INSTANT will contain the original number of fields in the clustered index ('core' fields). If instant ADD COLUMN has not been used or the table becomes empty, or the very first instant ADD COLUMN operation is rolled back, the fields PAGE_INSTANT and FIL_PAGE_TYPE will be reset to 0 and FIL_PAGE_INDEX. (2) A special 'default row' record is inserted into the leftmost leaf, between the page infimum and the first user record. This record is distinguished by the REC_INFO_MIN_REC_FLAG, and it is otherwise in the same format as records that contain values for the instantly added columns. This 'default row' always has the same number of fields as the clustered index according to the table definition. The values of 'core' fields are to be ignored. For other fields, the 'default row' will contain the default values as they were during the ALTER TABLE statement. (If the column default values are changed later, those values will only be stored in the .frm file. The 'default row' will contain the original evaluated values, which must be the same for every row.) The 'default row' must be completely hidden from higher-level access routines. Assertions have been added to ensure that no 'default row' is ever present in the adaptive hash index or in locked records. The 'default row' is never delete-marked. (3) In clustered index leaf page records, the number of fields must reside between the number of 'core' fields (dict_index_t::n_core_fields introduced in this work) and dict_index_t::n_fields. If the number of fields is less than dict_index_t::n_fields, the missing fields are replaced with the column value of the 'default row'. Note: The number of fields in the record may shrink if some of the last instantly added columns are updated to the value that is in the 'default row'. The function btr_cur_trim() implements this 'compression' on update and rollback; dtuple::trim() implements it on insert. (4) In ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC records, the new status value REC_STATUS_COLUMNS_ADDED will indicate the presence of a new record header that will encode n_fields-n_core_fields-1 in 1 or 2 bytes. (In ROW_FORMAT=REDUNDANT records, the record header always explicitly encodes the number of fields.) We introduce the undo log record type TRX_UNDO_INSERT_DEFAULT for covering the insert of the 'default row' record when instant ADD COLUMN is used for the first time. Subsequent instant ADD COLUMN can use TRX_UNDO_UPD_EXIST_REC. This is joint work with Vin Chen (陈福荣) from Tencent. The design that was discussed in April 2017 would not have allowed import or export of data files, because instead of the 'default row' it would have introduced a data dictionary table. The test rpl.rpl_alter_instant is exactly as contributed in pull request #408. The test innodb.instant_alter is based on a contributed test. The redo log record format changes for ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPACT are as contributed. (With this change present, crash recovery from MariaDB 10.3.1 will fail in spectacular ways!) Also the semantics of higher-level redo log records that modify the PAGE_INSTANT field is changed. The redo log format version identifier was already changed to LOG_HEADER_FORMAT_CURRENT=103 in MariaDB 10.3.1. Everything else has been rewritten by me. Thanks to Elena Stepanova, the code has been tested extensively. When rolling back an instant ADD COLUMN operation, we must empty the PAGE_FREE list after deleting or shortening the 'default row' record, by calling either btr_page_empty() or btr_page_reorganize(). We must know the size of each entry in the PAGE_FREE list. If rollback left a freed copy of the 'default row' in the PAGE_FREE list, we would be unable to determine its size (if it is in ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC) because it would contain more fields than the rolled-back definition of the clustered index. UNIV_SQL_DEFAULT: A new special constant that designates an instantly added column that is not present in the clustered index record. len_is_stored(): Check if a length is an actual length. There are two magic length values: UNIV_SQL_DEFAULT, UNIV_SQL_NULL. dict_col_t::def_val: The 'default row' value of the column. If the column is not added instantly, def_val.len will be UNIV_SQL_DEFAULT. dict_col_t: Add the accessors is_virtual(), is_nullable(), is_instant(), instant_value(). dict_col_t::remove_instant(): Remove the 'instant ADD' status of a column. dict_col_t::name(const dict_table_t& table): Replaces dict_table_get_col_name(). dict_index_t::n_core_fields: The original number of fields. For secondary indexes and if instant ADD COLUMN has not been used, this will be equal to dict_index_t::n_fields. dict_index_t::n_core_null_bytes: Number of bytes needed to represent the null flags; usually equal to UT_BITS_IN_BYTES(n_nullable). dict_index_t::NO_CORE_NULL_BYTES: Magic value signalling that n_core_null_bytes was not initialized yet from the clustered index root page. dict_index_t: Add the accessors is_instant(), is_clust(), get_n_nullable(), instant_field_value(). dict_index_t::instant_add_field(): Adjust clustered index metadata for instant ADD COLUMN. dict_index_t::remove_instant(): Remove the 'instant ADD' status of a clustered index when the table becomes empty, or the very first instant ADD COLUMN operation is rolled back. dict_table_t: Add the accessors is_instant(), is_temporary(), supports_instant(). dict_table_t::instant_add_column(): Adjust metadata for instant ADD COLUMN. dict_table_t::rollback_instant(): Adjust metadata on the rollback of instant ADD COLUMN. prepare_inplace_alter_table_dict(): First create the ctx->new_table, and only then decide if the table really needs to be rebuilt. We must split the creation of table or index metadata from the creation of the dictionary table records and the creation of the data. In this way, we can transform a table-rebuilding operation into an instant ADD COLUMN operation. Dictionary objects will only be added to cache when table rebuilding or index creation is needed. The ctx->instant_table will never be added to cache. dict_table_t::add_to_cache(): Modified and renamed from dict_table_add_to_cache(). Do not modify the table metadata. Let the callers invoke dict_table_add_system_columns() and if needed, set can_be_evicted. dict_create_sys_tables_tuple(), dict_create_table_step(): Omit the system columns (which will now exist in the dict_table_t object already at this point). dict_create_table_step(): Expect the callers to invoke dict_table_add_system_columns(). pars_create_table(): Before creating the table creation execution graph, invoke dict_table_add_system_columns(). row_create_table_for_mysql(): Expect all callers to invoke dict_table_add_system_columns(). create_index_dict(): Replaces row_merge_create_index_graph(). innodb_update_n_cols(): Renamed from innobase_update_n_virtual(). Call my_error() if an error occurs. btr_cur_instant_init(), btr_cur_instant_init_low(), btr_cur_instant_root_init(): Load additional metadata from the clustered index and set dict_index_t::n_core_null_bytes. This is invoked when table metadata is first loaded into the data dictionary. dict_boot(): Initialize n_core_null_bytes for the four hard-coded dictionary tables. dict_create_index_step(): Initialize n_core_null_bytes. This is executed as part of CREATE TABLE. dict_index_build_internal_clust(): Initialize n_core_null_bytes to NO_CORE_NULL_BYTES if table->supports_instant(). row_create_index_for_mysql(): Initialize n_core_null_bytes for CREATE TEMPORARY TABLE. commit_cache_norebuild(): Call the code to rename or enlarge columns in the cache only if instant ADD COLUMN is not being used. (Instant ADD COLUMN would copy all column metadata from instant_table to old_table, including the names and lengths.) PAGE_INSTANT: A new 13-bit field for storing dict_index_t::n_core_fields. This is repurposing the 16-bit field PAGE_DIRECTION, of which only the least significant 3 bits were used. The original byte containing PAGE_DIRECTION will be accessible via the new constant PAGE_DIRECTION_B. page_get_instant(), page_set_instant(): Accessors for the PAGE_INSTANT. page_ptr_get_direction(), page_get_direction(), page_ptr_set_direction(): Accessors for PAGE_DIRECTION. page_direction_reset(): Reset PAGE_DIRECTION, PAGE_N_DIRECTION. page_direction_increment(): Increment PAGE_N_DIRECTION and set PAGE_DIRECTION. rec_get_offsets(): Use the 'leaf' parameter for non-debug purposes, and assume that heap_no is always set. Initialize all dict_index_t::n_fields for ROW_FORMAT=REDUNDANT records, even if the record contains fewer fields. rec_offs_make_valid(): Add the parameter 'leaf'. rec_copy_prefix_to_dtuple(): Assert that the tuple is only built on the core fields. Instant ADD COLUMN only applies to the clustered index, and we should never build a search key that has more than the PRIMARY KEY and possibly DB_TRX_ID,DB_ROLL_PTR. All these columns are always present. dict_index_build_data_tuple(): Remove assertions that would be duplicated in rec_copy_prefix_to_dtuple(). rec_init_offsets(): Support ROW_FORMAT=REDUNDANT records whose number of fields is between n_core_fields and n_fields. cmp_rec_rec_with_match(): Implement the comparison between two MIN_REC_FLAG records. trx_t::in_rollback: Make the field available in non-debug builds. trx_start_for_ddl_low(): Remove dangerous error-tolerance. A dictionary transaction must be flagged as such before it has generated any undo log records. This is because trx_undo_assign_undo() will mark the transaction as a dictionary transaction in the undo log header right before the very first undo log record is being written. btr_index_rec_validate(): Account for instant ADD COLUMN row_undo_ins_remove_clust_rec(): On the rollback of an insert into SYS_COLUMNS, revert instant ADD COLUMN in the cache by removing the last column from the table and the clustered index. row_search_on_row_ref(), row_undo_mod_parse_undo_rec(), row_undo_mod(), trx_undo_update_rec_get_update(): Handle the 'default row' as a special case. dtuple_t::trim(index): Omit a redundant suffix of an index tuple right before insert or update. After instant ADD COLUMN, if the last fields of a clustered index tuple match the 'default row', there is no need to store them. While trimming the entry, we must hold a page latch, so that the table cannot be emptied and the 'default row' be deleted. btr_cur_optimistic_update(), btr_cur_pessimistic_update(), row_upd_clust_rec_by_insert(), row_ins_clust_index_entry_low(): Invoke dtuple_t::trim() if needed. row_ins_clust_index_entry(): Restore dtuple_t::n_fields after calling row_ins_clust_index_entry_low(). rec_get_converted_size(), rec_get_converted_size_comp(): Allow the number of fields to be between n_core_fields and n_fields. Do not support infimum,supremum. They are never supposed to be stored in dtuple_t, because page creation nowadays uses a lower-level method for initializing them. rec_convert_dtuple_to_rec_comp(): Assign the status bits based on the number of fields. btr_cur_trim(): In an update, trim the index entry as needed. For the 'default row', handle rollback specially. For user records, omit fields that match the 'default row'. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): Skip locking and adaptive hash index for the 'default row'. row_log_table_apply_convert_mrec(): Replace 'default row' values if needed. In the temporary file that is applied by row_log_table_apply(), we must identify whether the records contain the extra header for instantly added columns. For now, we will allocate an additional byte for this for ROW_T_INSERT and ROW_T_UPDATE records when the source table has been subject to instant ADD COLUMN. The ROW_T_DELETE records are fine, as they will be converted and will only contain 'core' columns (PRIMARY KEY and some system columns) that are converted from dtuple_t. rec_get_converted_size_temp(), rec_init_offsets_temp(), rec_convert_dtuple_to_temp(): Add the parameter 'status'. REC_INFO_DEFAULT_ROW = REC_INFO_MIN_REC_FLAG | REC_STATUS_COLUMNS_ADDED: An info_bits constant for distinguishing the 'default row' record. rec_comp_status_t: An enum of the status bit values. rec_leaf_format: An enum that replaces the bool parameter of rec_init_offsets_comp_ordinary().
8 years ago
20 years ago
MDEV-11369 Instant ADD COLUMN for InnoDB For InnoDB tables, adding, dropping and reordering columns has required a rebuild of the table and all its indexes. Since MySQL 5.6 (and MariaDB 10.0) this has been supported online (LOCK=NONE), allowing concurrent modification of the tables. This work revises the InnoDB ROW_FORMAT=REDUNDANT, ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC so that columns can be appended instantaneously, with only minor changes performed to the table structure. The counter innodb_instant_alter_column in INFORMATION_SCHEMA.GLOBAL_STATUS is incremented whenever a table rebuild operation is converted into an instant ADD COLUMN operation. ROW_FORMAT=COMPRESSED tables will not support instant ADD COLUMN. Some usability limitations will be addressed in subsequent work: MDEV-13134 Introduce ALTER TABLE attributes ALGORITHM=NOCOPY and ALGORITHM=INSTANT MDEV-14016 Allow instant ADD COLUMN, ADD INDEX, LOCK=NONE The format of the clustered index (PRIMARY KEY) is changed as follows: (1) The FIL_PAGE_TYPE of the root page will be FIL_PAGE_TYPE_INSTANT, and a new field PAGE_INSTANT will contain the original number of fields in the clustered index ('core' fields). If instant ADD COLUMN has not been used or the table becomes empty, or the very first instant ADD COLUMN operation is rolled back, the fields PAGE_INSTANT and FIL_PAGE_TYPE will be reset to 0 and FIL_PAGE_INDEX. (2) A special 'default row' record is inserted into the leftmost leaf, between the page infimum and the first user record. This record is distinguished by the REC_INFO_MIN_REC_FLAG, and it is otherwise in the same format as records that contain values for the instantly added columns. This 'default row' always has the same number of fields as the clustered index according to the table definition. The values of 'core' fields are to be ignored. For other fields, the 'default row' will contain the default values as they were during the ALTER TABLE statement. (If the column default values are changed later, those values will only be stored in the .frm file. The 'default row' will contain the original evaluated values, which must be the same for every row.) The 'default row' must be completely hidden from higher-level access routines. Assertions have been added to ensure that no 'default row' is ever present in the adaptive hash index or in locked records. The 'default row' is never delete-marked. (3) In clustered index leaf page records, the number of fields must reside between the number of 'core' fields (dict_index_t::n_core_fields introduced in this work) and dict_index_t::n_fields. If the number of fields is less than dict_index_t::n_fields, the missing fields are replaced with the column value of the 'default row'. Note: The number of fields in the record may shrink if some of the last instantly added columns are updated to the value that is in the 'default row'. The function btr_cur_trim() implements this 'compression' on update and rollback; dtuple::trim() implements it on insert. (4) In ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC records, the new status value REC_STATUS_COLUMNS_ADDED will indicate the presence of a new record header that will encode n_fields-n_core_fields-1 in 1 or 2 bytes. (In ROW_FORMAT=REDUNDANT records, the record header always explicitly encodes the number of fields.) We introduce the undo log record type TRX_UNDO_INSERT_DEFAULT for covering the insert of the 'default row' record when instant ADD COLUMN is used for the first time. Subsequent instant ADD COLUMN can use TRX_UNDO_UPD_EXIST_REC. This is joint work with Vin Chen (陈福荣) from Tencent. The design that was discussed in April 2017 would not have allowed import or export of data files, because instead of the 'default row' it would have introduced a data dictionary table. The test rpl.rpl_alter_instant is exactly as contributed in pull request #408. The test innodb.instant_alter is based on a contributed test. The redo log record format changes for ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPACT are as contributed. (With this change present, crash recovery from MariaDB 10.3.1 will fail in spectacular ways!) Also the semantics of higher-level redo log records that modify the PAGE_INSTANT field is changed. The redo log format version identifier was already changed to LOG_HEADER_FORMAT_CURRENT=103 in MariaDB 10.3.1. Everything else has been rewritten by me. Thanks to Elena Stepanova, the code has been tested extensively. When rolling back an instant ADD COLUMN operation, we must empty the PAGE_FREE list after deleting or shortening the 'default row' record, by calling either btr_page_empty() or btr_page_reorganize(). We must know the size of each entry in the PAGE_FREE list. If rollback left a freed copy of the 'default row' in the PAGE_FREE list, we would be unable to determine its size (if it is in ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC) because it would contain more fields than the rolled-back definition of the clustered index. UNIV_SQL_DEFAULT: A new special constant that designates an instantly added column that is not present in the clustered index record. len_is_stored(): Check if a length is an actual length. There are two magic length values: UNIV_SQL_DEFAULT, UNIV_SQL_NULL. dict_col_t::def_val: The 'default row' value of the column. If the column is not added instantly, def_val.len will be UNIV_SQL_DEFAULT. dict_col_t: Add the accessors is_virtual(), is_nullable(), is_instant(), instant_value(). dict_col_t::remove_instant(): Remove the 'instant ADD' status of a column. dict_col_t::name(const dict_table_t& table): Replaces dict_table_get_col_name(). dict_index_t::n_core_fields: The original number of fields. For secondary indexes and if instant ADD COLUMN has not been used, this will be equal to dict_index_t::n_fields. dict_index_t::n_core_null_bytes: Number of bytes needed to represent the null flags; usually equal to UT_BITS_IN_BYTES(n_nullable). dict_index_t::NO_CORE_NULL_BYTES: Magic value signalling that n_core_null_bytes was not initialized yet from the clustered index root page. dict_index_t: Add the accessors is_instant(), is_clust(), get_n_nullable(), instant_field_value(). dict_index_t::instant_add_field(): Adjust clustered index metadata for instant ADD COLUMN. dict_index_t::remove_instant(): Remove the 'instant ADD' status of a clustered index when the table becomes empty, or the very first instant ADD COLUMN operation is rolled back. dict_table_t: Add the accessors is_instant(), is_temporary(), supports_instant(). dict_table_t::instant_add_column(): Adjust metadata for instant ADD COLUMN. dict_table_t::rollback_instant(): Adjust metadata on the rollback of instant ADD COLUMN. prepare_inplace_alter_table_dict(): First create the ctx->new_table, and only then decide if the table really needs to be rebuilt. We must split the creation of table or index metadata from the creation of the dictionary table records and the creation of the data. In this way, we can transform a table-rebuilding operation into an instant ADD COLUMN operation. Dictionary objects will only be added to cache when table rebuilding or index creation is needed. The ctx->instant_table will never be added to cache. dict_table_t::add_to_cache(): Modified and renamed from dict_table_add_to_cache(). Do not modify the table metadata. Let the callers invoke dict_table_add_system_columns() and if needed, set can_be_evicted. dict_create_sys_tables_tuple(), dict_create_table_step(): Omit the system columns (which will now exist in the dict_table_t object already at this point). dict_create_table_step(): Expect the callers to invoke dict_table_add_system_columns(). pars_create_table(): Before creating the table creation execution graph, invoke dict_table_add_system_columns(). row_create_table_for_mysql(): Expect all callers to invoke dict_table_add_system_columns(). create_index_dict(): Replaces row_merge_create_index_graph(). innodb_update_n_cols(): Renamed from innobase_update_n_virtual(). Call my_error() if an error occurs. btr_cur_instant_init(), btr_cur_instant_init_low(), btr_cur_instant_root_init(): Load additional metadata from the clustered index and set dict_index_t::n_core_null_bytes. This is invoked when table metadata is first loaded into the data dictionary. dict_boot(): Initialize n_core_null_bytes for the four hard-coded dictionary tables. dict_create_index_step(): Initialize n_core_null_bytes. This is executed as part of CREATE TABLE. dict_index_build_internal_clust(): Initialize n_core_null_bytes to NO_CORE_NULL_BYTES if table->supports_instant(). row_create_index_for_mysql(): Initialize n_core_null_bytes for CREATE TEMPORARY TABLE. commit_cache_norebuild(): Call the code to rename or enlarge columns in the cache only if instant ADD COLUMN is not being used. (Instant ADD COLUMN would copy all column metadata from instant_table to old_table, including the names and lengths.) PAGE_INSTANT: A new 13-bit field for storing dict_index_t::n_core_fields. This is repurposing the 16-bit field PAGE_DIRECTION, of which only the least significant 3 bits were used. The original byte containing PAGE_DIRECTION will be accessible via the new constant PAGE_DIRECTION_B. page_get_instant(), page_set_instant(): Accessors for the PAGE_INSTANT. page_ptr_get_direction(), page_get_direction(), page_ptr_set_direction(): Accessors for PAGE_DIRECTION. page_direction_reset(): Reset PAGE_DIRECTION, PAGE_N_DIRECTION. page_direction_increment(): Increment PAGE_N_DIRECTION and set PAGE_DIRECTION. rec_get_offsets(): Use the 'leaf' parameter for non-debug purposes, and assume that heap_no is always set. Initialize all dict_index_t::n_fields for ROW_FORMAT=REDUNDANT records, even if the record contains fewer fields. rec_offs_make_valid(): Add the parameter 'leaf'. rec_copy_prefix_to_dtuple(): Assert that the tuple is only built on the core fields. Instant ADD COLUMN only applies to the clustered index, and we should never build a search key that has more than the PRIMARY KEY and possibly DB_TRX_ID,DB_ROLL_PTR. All these columns are always present. dict_index_build_data_tuple(): Remove assertions that would be duplicated in rec_copy_prefix_to_dtuple(). rec_init_offsets(): Support ROW_FORMAT=REDUNDANT records whose number of fields is between n_core_fields and n_fields. cmp_rec_rec_with_match(): Implement the comparison between two MIN_REC_FLAG records. trx_t::in_rollback: Make the field available in non-debug builds. trx_start_for_ddl_low(): Remove dangerous error-tolerance. A dictionary transaction must be flagged as such before it has generated any undo log records. This is because trx_undo_assign_undo() will mark the transaction as a dictionary transaction in the undo log header right before the very first undo log record is being written. btr_index_rec_validate(): Account for instant ADD COLUMN row_undo_ins_remove_clust_rec(): On the rollback of an insert into SYS_COLUMNS, revert instant ADD COLUMN in the cache by removing the last column from the table and the clustered index. row_search_on_row_ref(), row_undo_mod_parse_undo_rec(), row_undo_mod(), trx_undo_update_rec_get_update(): Handle the 'default row' as a special case. dtuple_t::trim(index): Omit a redundant suffix of an index tuple right before insert or update. After instant ADD COLUMN, if the last fields of a clustered index tuple match the 'default row', there is no need to store them. While trimming the entry, we must hold a page latch, so that the table cannot be emptied and the 'default row' be deleted. btr_cur_optimistic_update(), btr_cur_pessimistic_update(), row_upd_clust_rec_by_insert(), row_ins_clust_index_entry_low(): Invoke dtuple_t::trim() if needed. row_ins_clust_index_entry(): Restore dtuple_t::n_fields after calling row_ins_clust_index_entry_low(). rec_get_converted_size(), rec_get_converted_size_comp(): Allow the number of fields to be between n_core_fields and n_fields. Do not support infimum,supremum. They are never supposed to be stored in dtuple_t, because page creation nowadays uses a lower-level method for initializing them. rec_convert_dtuple_to_rec_comp(): Assign the status bits based on the number of fields. btr_cur_trim(): In an update, trim the index entry as needed. For the 'default row', handle rollback specially. For user records, omit fields that match the 'default row'. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): Skip locking and adaptive hash index for the 'default row'. row_log_table_apply_convert_mrec(): Replace 'default row' values if needed. In the temporary file that is applied by row_log_table_apply(), we must identify whether the records contain the extra header for instantly added columns. For now, we will allocate an additional byte for this for ROW_T_INSERT and ROW_T_UPDATE records when the source table has been subject to instant ADD COLUMN. The ROW_T_DELETE records are fine, as they will be converted and will only contain 'core' columns (PRIMARY KEY and some system columns) that are converted from dtuple_t. rec_get_converted_size_temp(), rec_init_offsets_temp(), rec_convert_dtuple_to_temp(): Add the parameter 'status'. REC_INFO_DEFAULT_ROW = REC_INFO_MIN_REC_FLAG | REC_STATUS_COLUMNS_ADDED: An info_bits constant for distinguishing the 'default row' record. rec_comp_status_t: An enum of the status bit values. rec_leaf_format: An enum that replaces the bool parameter of rec_init_offsets_comp_ordinary().
8 years ago
20 years ago
MDEV-11369 Instant ADD COLUMN for InnoDB For InnoDB tables, adding, dropping and reordering columns has required a rebuild of the table and all its indexes. Since MySQL 5.6 (and MariaDB 10.0) this has been supported online (LOCK=NONE), allowing concurrent modification of the tables. This work revises the InnoDB ROW_FORMAT=REDUNDANT, ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC so that columns can be appended instantaneously, with only minor changes performed to the table structure. The counter innodb_instant_alter_column in INFORMATION_SCHEMA.GLOBAL_STATUS is incremented whenever a table rebuild operation is converted into an instant ADD COLUMN operation. ROW_FORMAT=COMPRESSED tables will not support instant ADD COLUMN. Some usability limitations will be addressed in subsequent work: MDEV-13134 Introduce ALTER TABLE attributes ALGORITHM=NOCOPY and ALGORITHM=INSTANT MDEV-14016 Allow instant ADD COLUMN, ADD INDEX, LOCK=NONE The format of the clustered index (PRIMARY KEY) is changed as follows: (1) The FIL_PAGE_TYPE of the root page will be FIL_PAGE_TYPE_INSTANT, and a new field PAGE_INSTANT will contain the original number of fields in the clustered index ('core' fields). If instant ADD COLUMN has not been used or the table becomes empty, or the very first instant ADD COLUMN operation is rolled back, the fields PAGE_INSTANT and FIL_PAGE_TYPE will be reset to 0 and FIL_PAGE_INDEX. (2) A special 'default row' record is inserted into the leftmost leaf, between the page infimum and the first user record. This record is distinguished by the REC_INFO_MIN_REC_FLAG, and it is otherwise in the same format as records that contain values for the instantly added columns. This 'default row' always has the same number of fields as the clustered index according to the table definition. The values of 'core' fields are to be ignored. For other fields, the 'default row' will contain the default values as they were during the ALTER TABLE statement. (If the column default values are changed later, those values will only be stored in the .frm file. The 'default row' will contain the original evaluated values, which must be the same for every row.) The 'default row' must be completely hidden from higher-level access routines. Assertions have been added to ensure that no 'default row' is ever present in the adaptive hash index or in locked records. The 'default row' is never delete-marked. (3) In clustered index leaf page records, the number of fields must reside between the number of 'core' fields (dict_index_t::n_core_fields introduced in this work) and dict_index_t::n_fields. If the number of fields is less than dict_index_t::n_fields, the missing fields are replaced with the column value of the 'default row'. Note: The number of fields in the record may shrink if some of the last instantly added columns are updated to the value that is in the 'default row'. The function btr_cur_trim() implements this 'compression' on update and rollback; dtuple::trim() implements it on insert. (4) In ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC records, the new status value REC_STATUS_COLUMNS_ADDED will indicate the presence of a new record header that will encode n_fields-n_core_fields-1 in 1 or 2 bytes. (In ROW_FORMAT=REDUNDANT records, the record header always explicitly encodes the number of fields.) We introduce the undo log record type TRX_UNDO_INSERT_DEFAULT for covering the insert of the 'default row' record when instant ADD COLUMN is used for the first time. Subsequent instant ADD COLUMN can use TRX_UNDO_UPD_EXIST_REC. This is joint work with Vin Chen (陈福荣) from Tencent. The design that was discussed in April 2017 would not have allowed import or export of data files, because instead of the 'default row' it would have introduced a data dictionary table. The test rpl.rpl_alter_instant is exactly as contributed in pull request #408. The test innodb.instant_alter is based on a contributed test. The redo log record format changes for ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPACT are as contributed. (With this change present, crash recovery from MariaDB 10.3.1 will fail in spectacular ways!) Also the semantics of higher-level redo log records that modify the PAGE_INSTANT field is changed. The redo log format version identifier was already changed to LOG_HEADER_FORMAT_CURRENT=103 in MariaDB 10.3.1. Everything else has been rewritten by me. Thanks to Elena Stepanova, the code has been tested extensively. When rolling back an instant ADD COLUMN operation, we must empty the PAGE_FREE list after deleting or shortening the 'default row' record, by calling either btr_page_empty() or btr_page_reorganize(). We must know the size of each entry in the PAGE_FREE list. If rollback left a freed copy of the 'default row' in the PAGE_FREE list, we would be unable to determine its size (if it is in ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC) because it would contain more fields than the rolled-back definition of the clustered index. UNIV_SQL_DEFAULT: A new special constant that designates an instantly added column that is not present in the clustered index record. len_is_stored(): Check if a length is an actual length. There are two magic length values: UNIV_SQL_DEFAULT, UNIV_SQL_NULL. dict_col_t::def_val: The 'default row' value of the column. If the column is not added instantly, def_val.len will be UNIV_SQL_DEFAULT. dict_col_t: Add the accessors is_virtual(), is_nullable(), is_instant(), instant_value(). dict_col_t::remove_instant(): Remove the 'instant ADD' status of a column. dict_col_t::name(const dict_table_t& table): Replaces dict_table_get_col_name(). dict_index_t::n_core_fields: The original number of fields. For secondary indexes and if instant ADD COLUMN has not been used, this will be equal to dict_index_t::n_fields. dict_index_t::n_core_null_bytes: Number of bytes needed to represent the null flags; usually equal to UT_BITS_IN_BYTES(n_nullable). dict_index_t::NO_CORE_NULL_BYTES: Magic value signalling that n_core_null_bytes was not initialized yet from the clustered index root page. dict_index_t: Add the accessors is_instant(), is_clust(), get_n_nullable(), instant_field_value(). dict_index_t::instant_add_field(): Adjust clustered index metadata for instant ADD COLUMN. dict_index_t::remove_instant(): Remove the 'instant ADD' status of a clustered index when the table becomes empty, or the very first instant ADD COLUMN operation is rolled back. dict_table_t: Add the accessors is_instant(), is_temporary(), supports_instant(). dict_table_t::instant_add_column(): Adjust metadata for instant ADD COLUMN. dict_table_t::rollback_instant(): Adjust metadata on the rollback of instant ADD COLUMN. prepare_inplace_alter_table_dict(): First create the ctx->new_table, and only then decide if the table really needs to be rebuilt. We must split the creation of table or index metadata from the creation of the dictionary table records and the creation of the data. In this way, we can transform a table-rebuilding operation into an instant ADD COLUMN operation. Dictionary objects will only be added to cache when table rebuilding or index creation is needed. The ctx->instant_table will never be added to cache. dict_table_t::add_to_cache(): Modified and renamed from dict_table_add_to_cache(). Do not modify the table metadata. Let the callers invoke dict_table_add_system_columns() and if needed, set can_be_evicted. dict_create_sys_tables_tuple(), dict_create_table_step(): Omit the system columns (which will now exist in the dict_table_t object already at this point). dict_create_table_step(): Expect the callers to invoke dict_table_add_system_columns(). pars_create_table(): Before creating the table creation execution graph, invoke dict_table_add_system_columns(). row_create_table_for_mysql(): Expect all callers to invoke dict_table_add_system_columns(). create_index_dict(): Replaces row_merge_create_index_graph(). innodb_update_n_cols(): Renamed from innobase_update_n_virtual(). Call my_error() if an error occurs. btr_cur_instant_init(), btr_cur_instant_init_low(), btr_cur_instant_root_init(): Load additional metadata from the clustered index and set dict_index_t::n_core_null_bytes. This is invoked when table metadata is first loaded into the data dictionary. dict_boot(): Initialize n_core_null_bytes for the four hard-coded dictionary tables. dict_create_index_step(): Initialize n_core_null_bytes. This is executed as part of CREATE TABLE. dict_index_build_internal_clust(): Initialize n_core_null_bytes to NO_CORE_NULL_BYTES if table->supports_instant(). row_create_index_for_mysql(): Initialize n_core_null_bytes for CREATE TEMPORARY TABLE. commit_cache_norebuild(): Call the code to rename or enlarge columns in the cache only if instant ADD COLUMN is not being used. (Instant ADD COLUMN would copy all column metadata from instant_table to old_table, including the names and lengths.) PAGE_INSTANT: A new 13-bit field for storing dict_index_t::n_core_fields. This is repurposing the 16-bit field PAGE_DIRECTION, of which only the least significant 3 bits were used. The original byte containing PAGE_DIRECTION will be accessible via the new constant PAGE_DIRECTION_B. page_get_instant(), page_set_instant(): Accessors for the PAGE_INSTANT. page_ptr_get_direction(), page_get_direction(), page_ptr_set_direction(): Accessors for PAGE_DIRECTION. page_direction_reset(): Reset PAGE_DIRECTION, PAGE_N_DIRECTION. page_direction_increment(): Increment PAGE_N_DIRECTION and set PAGE_DIRECTION. rec_get_offsets(): Use the 'leaf' parameter for non-debug purposes, and assume that heap_no is always set. Initialize all dict_index_t::n_fields for ROW_FORMAT=REDUNDANT records, even if the record contains fewer fields. rec_offs_make_valid(): Add the parameter 'leaf'. rec_copy_prefix_to_dtuple(): Assert that the tuple is only built on the core fields. Instant ADD COLUMN only applies to the clustered index, and we should never build a search key that has more than the PRIMARY KEY and possibly DB_TRX_ID,DB_ROLL_PTR. All these columns are always present. dict_index_build_data_tuple(): Remove assertions that would be duplicated in rec_copy_prefix_to_dtuple(). rec_init_offsets(): Support ROW_FORMAT=REDUNDANT records whose number of fields is between n_core_fields and n_fields. cmp_rec_rec_with_match(): Implement the comparison between two MIN_REC_FLAG records. trx_t::in_rollback: Make the field available in non-debug builds. trx_start_for_ddl_low(): Remove dangerous error-tolerance. A dictionary transaction must be flagged as such before it has generated any undo log records. This is because trx_undo_assign_undo() will mark the transaction as a dictionary transaction in the undo log header right before the very first undo log record is being written. btr_index_rec_validate(): Account for instant ADD COLUMN row_undo_ins_remove_clust_rec(): On the rollback of an insert into SYS_COLUMNS, revert instant ADD COLUMN in the cache by removing the last column from the table and the clustered index. row_search_on_row_ref(), row_undo_mod_parse_undo_rec(), row_undo_mod(), trx_undo_update_rec_get_update(): Handle the 'default row' as a special case. dtuple_t::trim(index): Omit a redundant suffix of an index tuple right before insert or update. After instant ADD COLUMN, if the last fields of a clustered index tuple match the 'default row', there is no need to store them. While trimming the entry, we must hold a page latch, so that the table cannot be emptied and the 'default row' be deleted. btr_cur_optimistic_update(), btr_cur_pessimistic_update(), row_upd_clust_rec_by_insert(), row_ins_clust_index_entry_low(): Invoke dtuple_t::trim() if needed. row_ins_clust_index_entry(): Restore dtuple_t::n_fields after calling row_ins_clust_index_entry_low(). rec_get_converted_size(), rec_get_converted_size_comp(): Allow the number of fields to be between n_core_fields and n_fields. Do not support infimum,supremum. They are never supposed to be stored in dtuple_t, because page creation nowadays uses a lower-level method for initializing them. rec_convert_dtuple_to_rec_comp(): Assign the status bits based on the number of fields. btr_cur_trim(): In an update, trim the index entry as needed. For the 'default row', handle rollback specially. For user records, omit fields that match the 'default row'. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): Skip locking and adaptive hash index for the 'default row'. row_log_table_apply_convert_mrec(): Replace 'default row' values if needed. In the temporary file that is applied by row_log_table_apply(), we must identify whether the records contain the extra header for instantly added columns. For now, we will allocate an additional byte for this for ROW_T_INSERT and ROW_T_UPDATE records when the source table has been subject to instant ADD COLUMN. The ROW_T_DELETE records are fine, as they will be converted and will only contain 'core' columns (PRIMARY KEY and some system columns) that are converted from dtuple_t. rec_get_converted_size_temp(), rec_init_offsets_temp(), rec_convert_dtuple_to_temp(): Add the parameter 'status'. REC_INFO_DEFAULT_ROW = REC_INFO_MIN_REC_FLAG | REC_STATUS_COLUMNS_ADDED: An info_bits constant for distinguishing the 'default row' record. rec_comp_status_t: An enum of the status bit values. rec_leaf_format: An enum that replaces the bool parameter of rec_init_offsets_comp_ordinary().
8 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
branches/zip: Initialize dfield_t::ext as soon as possible. This should fix the bugs introduced in r1591. row_rec_to_index_entry_low(): Clear "n_ext". Do not allow it to be NULL. Add const qualifier to dict_index_t*. row_rec_to_index_entry(): Add the parameters "offsets" and "n_ext". btr_cur_optimistic_update(): Add an assertion that there are no externally stored columns. Remove the unreachable call to btr_cur_unmark_extern_fields() and the preceding unnecessary call to rec_get_offsets(). btr_push_update_extern_fields(): Remove the parameters index, offsets. Only report the additional externally stored columns of the update vector. row_build(), trx_undo_rec_get_partial_row(): Flag externally stored columns also with dfield_set_ext(). rec_copy_prefix_to_dtuple(): Assert that there are no externally stored columns in the prefix. row_build_row_ref(): Note and assert that the index is a secondary index, and assert that there are no externally stored columns. row_build_row_ref_fast(): Assert that there are no externally stored columns. rec_offs_get_n_alloc(): Expose the function. row_build_row_ref_in_tuple(): Assert that there are no externally stored columns in a record of a secondary index. row_build_row_ref_from_row(): Assert that there are no externally stored columns. row_upd_check_references_constraints(): Add the parameter offsets, to avoid a redundant call to rec_get_offsets(). row_upd_del_mark_clust_rec(): Add the parameter offsets. Remove duplicated code. row_ins_index_entry_set_vals(): Copy the external storage flag. sel_pop_prefetched_row(): Assert that there are no externally stored columns. row_scan_and_check_index(): Copy offsets to a temporary heap across the invocation of row_rec_to_index_entry().
18 years ago
20 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
10 years ago
20 years ago
20 years ago
20 years ago
20 years ago
MDEV-15250 UPSERT during ALTER TABLE results in 'Duplicate entry' error for alter - InnoDB DDL results in `Duplicate entry' if concurrent DML throws duplicate key error. The following scenario explains the problem connection con1: ALTER TABLE t1 FORCE; connection con2: INSERT INTO t1(pk, uk) VALUES (2, 2), (3, 2); In connection con2, InnoDB throws the 'DUPLICATE KEY' error because of unique index. Alter operation will throw the error when applying the concurrent DML log. - Inserting the duplicate key for unique index logs the insert operation for online ALTER TABLE. When insertion fails, transaction does rollback and it leads to logging of delete operation for online ALTER TABLE. While applying the insert log entries, alter operation encounters 'DUPLICATE KEY' error. - To avoid the above fake duplicate scenario, InnoDB should not write any log for online ALTER TABLE before DML transaction commit. - User thread which does DML can apply the online log if InnoDB ran out of online log and index is marked as completed. Set online log error if apply phase encountered any error. It can also clear all other indexes log, marks the newly added indexes as corrupted. - Removed the old online code which was a part of DML operations commit_inplace_alter_table() : Does apply the online log for the last batch of secondary index log and does frees the log for the completed index. trx_t::apply_online_log: Set to true while writing the undo log if the modified table has active DDL trx_t::apply_log(): Apply the DML changes to online DDL tables dict_table_t::is_active_ddl(): Returns true if the table has an active DDL dict_index_t::online_log_make_dummy(): Assign dummy value for clustered index online log to indicate the secondary indexes are being rebuild. dict_index_t::online_log_is_dummy(): Check whether the online log has dummy value ha_innobase_inplace_ctx::log_failure(): Handle the apply log failure for online DDL transaction row_log_mark_other_online_index_abort(): Clear out all other online index log after encountering the error during row_log_apply() row_log_get_error(): Get the error happened during row_log_apply() row_log_online_op(): Does apply the online log if index is completed and ran out of memory. Returns false if apply log fails UndorecApplier: Introduced a class to maintain the undo log record, latched undo buffer page, parse the undo log record, maintain the undo record type, info bits and update vector UndorecApplier::get_old_rec(): Get the correct version of the clustered index record that was modified by the current undo log record UndorecApplier::clear_undo_rec(): Clear the undo log related information after applying the undo log record UndorecApplier::log_update(): Handle the update, delete undo log and apply it on online indexes UndorecApplier::log_insert(): Handle the insert undo log and apply it on online indexes UndorecApplier::is_same(): Check whether the given roll pointer is generated by the current undo log record information trx_t::rollback_low(): Set apply_online_log for the transaction after partially rollbacked transaction has any active DDL prepare_inplace_alter_table_dict(): After allocating the online log, InnoDB does create fulltext common tables. Fulltext index doesn't allow the index to be online. So removed the dead code of online log removal Thanks to Marko Mäkelä for providing the initial prototype and Matthias Leich for testing the issue patiently.
4 years ago
20 years ago
20 years ago
MDEV-13637 InnoDB change buffer housekeeping can cause redo log overrun and possibly deadlocks The function ibuf_remove_free_page() may be called while the caller is holding several mutexes or rw-locks. Because of this, this housekeeping loop may cause performance glitches for operations that involve tables that are stored in the InnoDB system tablespace. Also deadlocks might be possible. The worst impact of all is that due to the mutexes being held, calls to log_free_check() had to be skipped during this housekeeping. This means that the cyclic InnoDB redo log may be overwritten. If the system crashes during this, it would be unable to recover. The entry point to the problematic code is ibuf_free_excess_pages(). It would make sense to call it before acquiring any mutexes or rw-locks, in any 'pessimistic' operation that involves the system tablespace. fseg_create_general(), fseg_alloc_free_page_general(): Do not call ibuf_free_excess_pages() while potentially holding some latches. ibuf_remove_free_page(): Do call log_free_check(), like every operation that is about to generate redo log should do. ibuf_free_excess_pages(): Remove some assertions that are replaced by stricter assertions in the log_free_check() that is now called by ibuf_remove_free_page(). row_mtr_start(): New function, to perform necessary preparations when starting a mini-transaction for row operations. For pessimistic operations on secondary indexes that are located in the system tablespace, this includes calling ibuf_free_excess_pages(). row_undo_ins_remove_sec_low(), row_undo_mod_del_mark_or_remove_sec_low(), row_undo_mod_del_unmark_sec_and_undo_update(): Call row_mtr_start(). row_ins_sec_index_entry(): Call ibuf_free_excess_pages() if the operation may involve allocating pages and change buffering in the system tablespace. row_upd_sec_index_entry(): Slightly refactor the code. The delete-marking of the old entry is done in-place. It could be change-buffered, but the old code should be unlikely to have invoked ibuf_free_excess_pages() in this case.
8 years ago
MDEV-13637 InnoDB change buffer housekeeping can cause redo log overrun and possibly deadlocks The function ibuf_remove_free_page() may be called while the caller is holding several mutexes or rw-locks. Because of this, this housekeeping loop may cause performance glitches for operations that involve tables that are stored in the InnoDB system tablespace. Also deadlocks might be possible. The worst impact of all is that due to the mutexes being held, calls to log_free_check() had to be skipped during this housekeeping. This means that the cyclic InnoDB redo log may be overwritten. If the system crashes during this, it would be unable to recover. The entry point to the problematic code is ibuf_free_excess_pages(). It would make sense to call it before acquiring any mutexes or rw-locks, in any 'pessimistic' operation that involves the system tablespace. fseg_create_general(), fseg_alloc_free_page_general(): Do not call ibuf_free_excess_pages() while potentially holding some latches. ibuf_remove_free_page(): Do call log_free_check(), like every operation that is about to generate redo log should do. ibuf_free_excess_pages(): Remove some assertions that are replaced by stricter assertions in the log_free_check() that is now called by ibuf_remove_free_page(). row_mtr_start(): New function, to perform necessary preparations when starting a mini-transaction for row operations. For pessimistic operations on secondary indexes that are located in the system tablespace, this includes calling ibuf_free_excess_pages(). row_undo_ins_remove_sec_low(), row_undo_mod_del_mark_or_remove_sec_low(), row_undo_mod_del_unmark_sec_and_undo_update(): Call row_mtr_start(). row_ins_sec_index_entry(): Call ibuf_free_excess_pages() if the operation may involve allocating pages and change buffering in the system tablespace. row_upd_sec_index_entry(): Slightly refactor the code. The delete-marking of the old entry is done in-place. It could be change-buffered, but the old code should be unlikely to have invoked ibuf_free_excess_pages() in this case.
8 years ago
MDEV-15250 UPSERT during ALTER TABLE results in 'Duplicate entry' error for alter - InnoDB DDL results in `Duplicate entry' if concurrent DML throws duplicate key error. The following scenario explains the problem connection con1: ALTER TABLE t1 FORCE; connection con2: INSERT INTO t1(pk, uk) VALUES (2, 2), (3, 2); In connection con2, InnoDB throws the 'DUPLICATE KEY' error because of unique index. Alter operation will throw the error when applying the concurrent DML log. - Inserting the duplicate key for unique index logs the insert operation for online ALTER TABLE. When insertion fails, transaction does rollback and it leads to logging of delete operation for online ALTER TABLE. While applying the insert log entries, alter operation encounters 'DUPLICATE KEY' error. - To avoid the above fake duplicate scenario, InnoDB should not write any log for online ALTER TABLE before DML transaction commit. - User thread which does DML can apply the online log if InnoDB ran out of online log and index is marked as completed. Set online log error if apply phase encountered any error. It can also clear all other indexes log, marks the newly added indexes as corrupted. - Removed the old online code which was a part of DML operations commit_inplace_alter_table() : Does apply the online log for the last batch of secondary index log and does frees the log for the completed index. trx_t::apply_online_log: Set to true while writing the undo log if the modified table has active DDL trx_t::apply_log(): Apply the DML changes to online DDL tables dict_table_t::is_active_ddl(): Returns true if the table has an active DDL dict_index_t::online_log_make_dummy(): Assign dummy value for clustered index online log to indicate the secondary indexes are being rebuild. dict_index_t::online_log_is_dummy(): Check whether the online log has dummy value ha_innobase_inplace_ctx::log_failure(): Handle the apply log failure for online DDL transaction row_log_mark_other_online_index_abort(): Clear out all other online index log after encountering the error during row_log_apply() row_log_get_error(): Get the error happened during row_log_apply() row_log_online_op(): Does apply the online log if index is completed and ran out of memory. Returns false if apply log fails UndorecApplier: Introduced a class to maintain the undo log record, latched undo buffer page, parse the undo log record, maintain the undo record type, info bits and update vector UndorecApplier::get_old_rec(): Get the correct version of the clustered index record that was modified by the current undo log record UndorecApplier::clear_undo_rec(): Clear the undo log related information after applying the undo log record UndorecApplier::log_update(): Handle the update, delete undo log and apply it on online indexes UndorecApplier::log_insert(): Handle the insert undo log and apply it on online indexes UndorecApplier::is_same(): Check whether the given roll pointer is generated by the current undo log record information trx_t::rollback_low(): Set apply_online_log for the transaction after partially rollbacked transaction has any active DDL prepare_inplace_alter_table_dict(): After allocating the online log, InnoDB does create fulltext common tables. Fulltext index doesn't allow the index to be online. So removed the dead code of online log removal Thanks to Marko Mäkelä for providing the initial prototype and Matthias Leich for testing the issue patiently.
4 years ago
MDEV-13637 InnoDB change buffer housekeeping can cause redo log overrun and possibly deadlocks The function ibuf_remove_free_page() may be called while the caller is holding several mutexes or rw-locks. Because of this, this housekeeping loop may cause performance glitches for operations that involve tables that are stored in the InnoDB system tablespace. Also deadlocks might be possible. The worst impact of all is that due to the mutexes being held, calls to log_free_check() had to be skipped during this housekeeping. This means that the cyclic InnoDB redo log may be overwritten. If the system crashes during this, it would be unable to recover. The entry point to the problematic code is ibuf_free_excess_pages(). It would make sense to call it before acquiring any mutexes or rw-locks, in any 'pessimistic' operation that involves the system tablespace. fseg_create_general(), fseg_alloc_free_page_general(): Do not call ibuf_free_excess_pages() while potentially holding some latches. ibuf_remove_free_page(): Do call log_free_check(), like every operation that is about to generate redo log should do. ibuf_free_excess_pages(): Remove some assertions that are replaced by stricter assertions in the log_free_check() that is now called by ibuf_remove_free_page(). row_mtr_start(): New function, to perform necessary preparations when starting a mini-transaction for row operations. For pessimistic operations on secondary indexes that are located in the system tablespace, this includes calling ibuf_free_excess_pages(). row_undo_ins_remove_sec_low(), row_undo_mod_del_mark_or_remove_sec_low(), row_undo_mod_del_unmark_sec_and_undo_update(): Call row_mtr_start(). row_ins_sec_index_entry(): Call ibuf_free_excess_pages() if the operation may involve allocating pages and change buffering in the system tablespace. row_upd_sec_index_entry(): Slightly refactor the code. The delete-marking of the old entry is done in-place. It could be change-buffered, but the old code should be unlikely to have invoked ibuf_free_excess_pages() in this case.
8 years ago
MDEV-13637 InnoDB change buffer housekeeping can cause redo log overrun and possibly deadlocks The function ibuf_remove_free_page() may be called while the caller is holding several mutexes or rw-locks. Because of this, this housekeeping loop may cause performance glitches for operations that involve tables that are stored in the InnoDB system tablespace. Also deadlocks might be possible. The worst impact of all is that due to the mutexes being held, calls to log_free_check() had to be skipped during this housekeeping. This means that the cyclic InnoDB redo log may be overwritten. If the system crashes during this, it would be unable to recover. The entry point to the problematic code is ibuf_free_excess_pages(). It would make sense to call it before acquiring any mutexes or rw-locks, in any 'pessimistic' operation that involves the system tablespace. fseg_create_general(), fseg_alloc_free_page_general(): Do not call ibuf_free_excess_pages() while potentially holding some latches. ibuf_remove_free_page(): Do call log_free_check(), like every operation that is about to generate redo log should do. ibuf_free_excess_pages(): Remove some assertions that are replaced by stricter assertions in the log_free_check() that is now called by ibuf_remove_free_page(). row_mtr_start(): New function, to perform necessary preparations when starting a mini-transaction for row operations. For pessimistic operations on secondary indexes that are located in the system tablespace, this includes calling ibuf_free_excess_pages(). row_undo_ins_remove_sec_low(), row_undo_mod_del_mark_or_remove_sec_low(), row_undo_mod_del_unmark_sec_and_undo_update(): Call row_mtr_start(). row_ins_sec_index_entry(): Call ibuf_free_excess_pages() if the operation may involve allocating pages and change buffering in the system tablespace. row_upd_sec_index_entry(): Slightly refactor the code. The delete-marking of the old entry is done in-place. It could be change-buffered, but the old code should be unlikely to have invoked ibuf_free_excess_pages() in this case.
8 years ago
MDEV-10139 Support for InnoDB SEQUENCE objects We introduce a NO_ROLLBACK flag for InnoDB tables. This flag only works for tables that have a single index. Apart from undo logging, this flag will also prevent locking and the assignment of DB_ROW_ID or DB_TRX_ID, and imply READ UNCOMMITTED isolation. It is assumed that the SQL layer is guaranteeing mutual exclusion. After the initial insert of the single record during CREATE SEQUENCE, InnoDB will be updating the single record in-place. This is crash-safe thanks to the redo log. (That is, after a crash after CREATE SEQUENCE was committed, the effect of sequence operations will be observable fully or not at all.) When it comes to the durability of the updates of SEQUENCE in InnoDB, there is a clear analogy to MDEV-6076 Persistent AUTO_INCREMENT. The updates would be made persistent by the InnoDB redo log flush at transaction commit or rollback (or XA PREPARE), provided that innodb_log_flush_at_trx_commit=1. Similar to AUTO_INCREMENT, it is possible that the update of a SEQUENCE in a middle of transaction becomes durable before the COMMIT/ROLLBACK of the transaction, in case the InnoDB redo log is being flushed as a result of the a commit or rollback of some other transaction, or as a result of a redo log checkpoint that can be initiated at any time by operations that are writing redo log. dict_table_t::no_rollback(): Check if the table does not support rollback. BTR_NO_ROLLBACK: Logging and locking flags for no_rollback() tables. DICT_TF_BITS: Add the NO_ROLLBACK flag. row_ins_step(): Assign 0 to DB_ROW_ID and DB_TRX_ID, and skip any locking for no-rollback tables. There will be only a single row in no-rollback tables (or there must be a proper PRIMARY KEY). row_search_mvcc(): Execute the READ UNCOMMITTED code path for no-rollback tables. ha_innobase::external_lock(), ha_innobase::store_lock(): Block CREATE/DROP SEQUENCE in innodb_read_only mode. This probably has no effect for CREATE SEQUENCE, because already ha_innobase::create() should have been called (and refused) before external_lock() or store_lock() is called. ha_innobase::store_lock(): For CREATE SEQUENCE, do not acquire any InnoDB locks, even though TL_WRITE is being requested. (This is just a performance optimization.) innobase_copy_frm_flags_from_create_info(), row_drop_table_for_mysql(): Disable persistent statistics for no_rollback tables.
9 years ago
MDEV-15250 UPSERT during ALTER TABLE results in 'Duplicate entry' error for alter - InnoDB DDL results in `Duplicate entry' if concurrent DML throws duplicate key error. The following scenario explains the problem connection con1: ALTER TABLE t1 FORCE; connection con2: INSERT INTO t1(pk, uk) VALUES (2, 2), (3, 2); In connection con2, InnoDB throws the 'DUPLICATE KEY' error because of unique index. Alter operation will throw the error when applying the concurrent DML log. - Inserting the duplicate key for unique index logs the insert operation for online ALTER TABLE. When insertion fails, transaction does rollback and it leads to logging of delete operation for online ALTER TABLE. While applying the insert log entries, alter operation encounters 'DUPLICATE KEY' error. - To avoid the above fake duplicate scenario, InnoDB should not write any log for online ALTER TABLE before DML transaction commit. - User thread which does DML can apply the online log if InnoDB ran out of online log and index is marked as completed. Set online log error if apply phase encountered any error. It can also clear all other indexes log, marks the newly added indexes as corrupted. - Removed the old online code which was a part of DML operations commit_inplace_alter_table() : Does apply the online log for the last batch of secondary index log and does frees the log for the completed index. trx_t::apply_online_log: Set to true while writing the undo log if the modified table has active DDL trx_t::apply_log(): Apply the DML changes to online DDL tables dict_table_t::is_active_ddl(): Returns true if the table has an active DDL dict_index_t::online_log_make_dummy(): Assign dummy value for clustered index online log to indicate the secondary indexes are being rebuild. dict_index_t::online_log_is_dummy(): Check whether the online log has dummy value ha_innobase_inplace_ctx::log_failure(): Handle the apply log failure for online DDL transaction row_log_mark_other_online_index_abort(): Clear out all other online index log after encountering the error during row_log_apply() row_log_get_error(): Get the error happened during row_log_apply() row_log_online_op(): Does apply the online log if index is completed and ran out of memory. Returns false if apply log fails UndorecApplier: Introduced a class to maintain the undo log record, latched undo buffer page, parse the undo log record, maintain the undo record type, info bits and update vector UndorecApplier::get_old_rec(): Get the correct version of the clustered index record that was modified by the current undo log record UndorecApplier::clear_undo_rec(): Clear the undo log related information after applying the undo log record UndorecApplier::log_update(): Handle the update, delete undo log and apply it on online indexes UndorecApplier::log_insert(): Handle the insert undo log and apply it on online indexes UndorecApplier::is_same(): Check whether the given roll pointer is generated by the current undo log record information trx_t::rollback_low(): Set apply_online_log for the transaction after partially rollbacked transaction has any active DDL prepare_inplace_alter_table_dict(): After allocating the online log, InnoDB does create fulltext common tables. Fulltext index doesn't allow the index to be online. So removed the dead code of online log removal Thanks to Marko Mäkelä for providing the initial prototype and Matthias Leich for testing the issue patiently.
4 years ago
20 years ago
branches/innodb+: Clean up the buffering of purges. Instead of traversing the index B-tree twice (first in BTR_WATCH_LEAF mode and then in BTR_DELETE mode), let BTR_DELETE take care of checking that the record can be purged, and either buffering or performing the purge. row_purge_poss_sec(): New function, to check if it is possible to purge a secondary index record. Refactored from row_purge_remove_sec_if_poss_low(). row_purge_remove_sec_if_poss_nonbuffered(): Rename to row_purge_remove_sec_if_poss_tree(). Remove the parameter mode (always use BTR_MODIFY_TREE). Use row_purge_poss_sec(). row_purge_remove_sec_if_poss_low(): Rename to row_purge_remove_sec_if_poss_leaf(). Remove the parameter mode (always use BTR_MODIFY_LEAF). Let row_search_index_entry() do all the hard work. btr_cur_t: Add purge_node, which will be needed by btr_cur_search_to_nth_level() for BTR_DELETE. Replace the flag value BTR_CUR_ABORTED with BTR_CUR_DELETE_REF and BTR_CUR_DELETE_FAILED. enum row_search_result, row_search_index_entry(): Replace ROW_NOT_IN_POOL with ROW_NOT_DELETED_REF and ROW_NOT_DELETED. btr_cur_search_to_nth_level(): Remove BTR_WATCH_LEAF. As a side effect, the adaptive hash index can be used in purge as well. If BTR_DELETE cannot be buffered, attempt btr_cur_optimistic_delete(). Either way, check row_purge_poss_sec(). Move the code to set cursor->ibuf_count to get rid of another if (height == 0) check. Eliminate the label loop_end. Do not call ibuf_should_try() twice. ibuf_should_try(): Now that the successful calls to this function will be halved, halve the magic constant that ibuf_flush_count will be compared to, accordingly. The changes regarding ibuf_should_try() were merged from branches/zip r3515. rb://60 approved by Heikki over IM
17 years ago
MDEV-13498 DELETE with CASCADE constraints takes long time / MDEV-13246 MDEV-13498 is a performance regression that was introduced in MariaDB 10.2.2 by commit fec844aca88e1c6b9c36bb0b811e92d9d023ffb9 which introduced some Galera-specific conditions that were being evaluated even if the write-set replication was not enabled. MDEV-13246 Stale rows despite ON DELETE CASCADE constraint is a correctness regression that was introduced by the same commit. Especially the subcondition !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE) which is equivalent to !parent || que_node_get_type(parent) != QUE_NODE_UPDATE makes little sense. If parent==NULL, the evaluation would proceed to the std::find() expression, which would dereference parent. Because no SIGSEGV was observed related to this, we can conclude that parent!=NULL always holds. But then, the condition would be equivalent to que_node_get_type(parent) != QUE_NODE_UPDATE which would not make sense either, because the std::find() expression is actually assuming the opposite when casting parent to upd_node_t*. It looks like this condition never worked properly, or that it was never properly tested, or both. wsrep_must_process_fk(): Helper function to check if FOREIGN KEY constraints need to be processed. Only evaluate the costly std::find() expression when write-set replication is enabled. Also, rely on operator<<(std::ostream&, const id_name_t&) and operator<<(std::ostream&, const table_name_t&) for pretty-printing index and table names. row_upd_sec_index_entry(): Add !wsrep_thd_is_BF() to the condition. This is applying part of "Galera MW-369 FK fixes" https://github.com/codership/mysql-wsrep/commit/f37b79c6dab101310a45a9e8cb23c0f98716da52 that is described by the following part of the commit comment: additionally: skipping wsrep_row_upd_check_foreign_constraint if thd has BF, essentially is applier or replaying This FK check would be needed only for populating parent row FK keys in write set, so no use for appliers
8 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
MDEV-20812 Unexpected ER_ROW_IS_REFERENCED_2 upon DELETE from versioned table with FK MDEV-16210 original case was wrongly allowed versioned DELETE from referenced table where reference is by non-primary key. InnoDB UPDATE has optimization for new rows not changing its clustered index position. In this case InnoDB doesn't update all secondary indexes and misses the one holding the referenced key. The fix was to disable this optimization for versioned DELETE. In case of versioned DELETE we forcely update all secondary indexes and therefore check them for constraints. But the above fix raised another problem with versioned DELETE on foreign table side. In case when there was no corresponding record in referenced table (illegal foreign reference can be done with "set foreign_key_checks=off") there was spurious constraint check (because versioned DELETE is actually UPDATE) and hence the operation failed with constraint error. MDEV-16210 tried to fix the above problem by checking foreign table instead of referenced table and that at least was illegal. Constraint check is done by row_ins_check_foreign_constraint() no matter what kind of table is checked, referenced or foreign (controlled by check_ref argument). Referenced table is checked by row_upd_check_references_constraints(). Foreign table is checked by row_ins_check_foreign_constraints(). Current fix rolls back the wrong fix for the above problem and disables referenced table check for DELETE on foreign side by introducing `check_foreign` argument which when set to *false* skips row_ins_check_foreign_constraints() call.
6 years ago
20 years ago
20 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
10 years ago
20 years ago
20 years ago
20 years ago
20 years ago
MDEV-15662 Instant DROP COLUMN or changing the order of columns Allow ADD COLUMN anywhere in a table, not only adding as the last column. Allow instant DROP COLUMN and instant changing the order of columns. The added columns will always be added last in clustered index records. In new records, instantly dropped columns will be stored as NULL or empty when possible. Information about dropped and reordered columns will be written in a metadata BLOB (mblob), which is stored before the first 'user' field in the hidden metadata record at the start of the clustered index. The presence of mblob is indicated by setting the delete-mark flag in the metadata record. The metadata BLOB stores the number of clustered index fields, followed by an array of column information for each field. For dropped columns, we store the NOT NULL flag, the fixed length, and for variable-length columns, whether the maximum length exceeded 255 bytes. For non-dropped columns, we store the column position. Unlike with MDEV-11369, when a table becomes empty, it cannot be converted back to the canonical format. The reason for this is that other threads may hold cached objects such as row_prebuilt_t::ins_node that could refer to dropped or reordered index fields. For instant DROP COLUMN and ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC, we must store the n_core_null_bytes in the root page, so that the chain of node pointer records can be followed in order to reach the leftmost leaf page where the metadata record is located. If the mblob is present, we will zero-initialize the strings "infimum" and "supremum" in the root page, and use the last byte of "supremum" for storing the number of null bytes (which are allocated but useless on node pointer pages). This is necessary for btr_cur_instant_init_metadata() to be able to navigate to the mblob. If the PRIMARY KEY contains any variable-length column and some nullable columns were instantly dropped, the dict_index_t::n_nullable in the data dictionary could be smaller than it actually is in the non-leaf pages. Because of this, the non-leaf pages could use more bytes for the null flags than the data dictionary expects, and we could be reading the lengths of the variable-length columns from the wrong offset, and thus reading the child page number from wrong place. This is the result of two design mistakes that involve unnecessary storage of data: First, it is nonsense to store any data fields for the leftmost node pointer records, because the comparisons would be resolved by the MIN_REC_FLAG alone. Second, there cannot be any null fields in the clustered index node pointer fields, but we nevertheless reserve space for all the null flags. Limitations (future work): MDEV-17459 Allow instant ALTER TABLE even if FULLTEXT INDEX exists MDEV-17468 Avoid table rebuild on operations on generated columns MDEV-17494 Refuse ALGORITHM=INSTANT when the row size is too large btr_page_reorganize_low(): Preserve any metadata in the root page. Call lock_move_reorganize_page() only after restoring the "infimum" and "supremum" records, to avoid a memcmp() assertion failure. dict_col_t::DROPPED: Magic value for dict_col_t::ind. dict_col_t::clear_instant(): Renamed from dict_col_t::remove_instant(). Do not assert that the column was instantly added, because we sometimes call this unconditionally for all columns. Convert an instantly added column to a "core column". The old name remove_instant() could be mistaken to refer to "instant DROP COLUMN". dict_col_t::is_added(): Rename from dict_col_t::is_instant(). dtype_t::metadata_blob_init(): Initialize the mblob data type. dtuple_t::is_metadata(), dtuple_t::is_alter_metadata(), upd_t::is_metadata(), upd_t::is_alter_metadata(): Check if info_bits refer to a metadata record. dict_table_t::instant: Metadata about dropped or reordered columns. dict_table_t::prepare_instant(): Prepare ha_innobase_inplace_ctx::instant_table for instant ALTER TABLE. innobase_instant_try() will pass this to dict_table_t::instant_column(). On rollback, dict_table_t::rollback_instant() will be called. dict_table_t::instant_column(): Renamed from instant_add_column(). Add the parameter col_map so that columns can be reordered. Copy and adjust v_cols[] as well. dict_table_t::find(): Find an old column based on a new column number. dict_table_t::serialise_columns(), dict_table_t::deserialise_columns(): Convert the mblob. dict_index_t::instant_metadata(): Create the metadata record for instant ALTER TABLE. Invoke dict_table_t::serialise_columns(). dict_index_t::reconstruct_fields(): Invoked by dict_table_t::deserialise_columns(). dict_index_t::clear_instant_alter(): Move the fields for the dropped columns to the end, and sort the surviving index fields in ascending order of column position. ha_innobase::check_if_supported_inplace_alter(): Do not allow adding a FTS_DOC_ID column if a hidden FTS_DOC_ID column exists due to FULLTEXT INDEX. (This always required ALGORITHM=COPY.) instant_alter_column_possible(): Add a parameter for InnoDB table, to check for additional conditions, such as the maximum number of index fields. ha_innobase_inplace_ctx::first_alter_pos: The first column whose position is affected by instant ADD, DROP, or changing the order of columns. innobase_build_col_map(): Skip added virtual columns. prepare_inplace_add_virtual(): Correctly compute num_to_add_vcol. Remove some unnecessary code. Note that the call to innodb_base_col_setup() should be executed later. commit_try_norebuild(): If ctx->is_instant(), let the virtual columns be added or dropped by innobase_instant_try(). innobase_instant_try(): Fill in a zero default value for the hidden column FTS_DOC_ID (to reduce the work needed in MDEV-17459). If any columns were dropped or reordered (or added not last), delete any SYS_COLUMNS records for the following columns, and insert SYS_COLUMNS records for all subsequent stored columns as well as for all virtual columns. If any virtual column is dropped, rewrite all virtual column metadata. Use a shortcut only for adding virtual columns. This is because innobase_drop_virtual_try() assumes that the dropped virtual columns still exist in ctx->old_table. innodb_update_cols(): Renamed from innodb_update_n_cols(). innobase_add_one_virtual(), innobase_insert_sys_virtual(): Change the return type to bool, and invoke my_error() when detecting an error. innodb_insert_sys_columns(): Insert a record into SYS_COLUMNS. Refactored from innobase_add_one_virtual() and innobase_instant_add_col(). innobase_instant_add_col(): Replace the parameter dfield with type. innobase_instant_drop_cols(): Drop matching columns from SYS_COLUMNS and all columns from SYS_VIRTUAL. innobase_add_virtual_try(), innobase_drop_virtual_try(): Let the caller invoke innodb_update_cols(). innobase_rename_column_try(): Skip dropped columns. commit_cache_norebuild(): Update table->fts->doc_col. dict_mem_table_col_rename_low(): Skip dropped columns. trx_undo_rec_get_partial_row(): Skip dropped columns. trx_undo_update_rec_get_update(): Handle the metadata BLOB correctly. trx_undo_page_report_modify(): Avoid out-of-bounds access to record fields. Log metadata records consistently. Apparently, the first fields of a clustered index may be updated in an update_undo vector when the index is ID_IND of SYS_FOREIGN, as part of renaming the table during ALTER TABLE. Normally, updates of the PRIMARY KEY should be logged as delete-mark and an insert. row_undo_mod_parse_undo_rec(), row_purge_parse_undo_rec(): Use trx_undo_metadata. row_undo_mod_clust_low(): On metadata rollback, roll back the root page too. row_undo_mod_clust(): Relax an assertion. The delete-mark flag was repurposed for ALTER TABLE metadata records. row_rec_to_index_entry_impl(): Add the template parameter mblob and the optional parameter info_bits for specifying the desired new info bits. For the metadata tuple, allow conversion between the original format (ADD COLUMN only) and the generic format (with hidden BLOB). Add the optional parameter "pad" to determine whether the tuple should be padded to the index fields (on ALTER TABLE it should), or whether it should remain at its original size (on rollback). row_build_index_entry_low(): Clean up the code, removing redundant variables and conditions. For instantly dropped columns, generate a dummy value that is NULL, the empty string, or a fixed length of NUL bytes, depending on the type of the dropped column. row_upd_clust_rec_by_insert_inherit_func(): On the update of PRIMARY KEY of a record that contained a dropped column whose value was stored externally, we will be inserting a dummy NULL or empty string value to the field of the dropped column. The externally stored column would eventually be dropped when purge removes the delete-marked record for the old PRIMARY KEY value. btr_index_rec_validate(): Recognize the metadata record. btr_discard_only_page_on_level(): Preserve the generic instant ALTER TABLE metadata. btr_set_instant(): Replaces page_set_instant(). This sets a clustered index root page to the appropriate format, or upgrades from the MDEV-11369 instant ADD COLUMN to generic ALTER TABLE format. btr_cur_instant_init_low(): Read and validate the metadata BLOB page before reconstructing the dictionary information based on it. btr_cur_instant_init_metadata(): Do not read any lengths from the metadata record header before reading the BLOB. At this point, we would not actually know how many nullable fields the metadata record contains. btr_cur_instant_root_init(): Initialize n_core_null_bytes in one of two possible ways. btr_cur_trim(): Handle the mblob record. row_metadata_to_tuple(): Convert a metadata record to a data tuple, based on the new info_bits of the metadata record. btr_cur_pessimistic_update(): Invoke row_metadata_to_tuple() if needed. Invoke dtuple_convert_big_rec() for metadata records if the record is too large, or if the mblob is not yet marked as externally stored. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): When the last user record is deleted, do not delete the generic instant ALTER TABLE metadata record. Only delete MDEV-11369 instant ADD COLUMN metadata records. btr_cur_optimistic_insert(): Avoid unnecessary computation of rec_size. btr_pcur_store_position(): Allow a logically empty page to contain a metadata record for generic ALTER TABLE. REC_INFO_DEFAULT_ROW_ADD: Renamed from REC_INFO_DEFAULT_ROW. This is for the old instant ADD COLUMN (MDEV-11369) only. REC_INFO_DEFAULT_ROW_ALTER: The more generic metadata record, with additional information for dropped or reordered columns. rec_info_bits_valid(): Remove. The only case when this would fail is when the record is the generic ALTER TABLE metadata record. rec_is_alter_metadata(): Check if a record is the metadata record for instant ALTER TABLE (other than ADD COLUMN). NOTE: This function must not be invoked on node pointer records, because the delete-mark flag in those records may be set (it is garbage), and then a debug assertion could fail because index->is_instant() does not necessarily hold. rec_is_add_metadata(): Check if a record is MDEV-11369 ADD COLUMN metadata record (not more generic instant ALTER TABLE). rec_get_converted_size_comp_prefix_low(): Assume that the metadata field will be stored externally. In dtuple_convert_big_rec() during the rec_get_converted_size() call, it would not be there yet. rec_get_converted_size_comp(): Replace status,fields,n_fields with tuple. rec_init_offsets_comp_ordinary(), rec_get_converted_size_comp_prefix_low(), rec_convert_dtuple_to_rec_comp(): Add template<bool mblob = false>. With mblob=true, process a record with a metadata BLOB. rec_copy_prefix_to_buf(): Assert that no fields beyond the key and system columns are being copied. Exclude the metadata BLOB field. rec_convert_dtuple_to_metadata_comp(): Convert an alter metadata tuple into a record. row_upd_index_replace_metadata(): Apply an update vector to an alter_metadata tuple. row_log_allocate(): Replace dict_index_t::is_instant() with a more appropriate condition that ignores dict_table_t::instant. Only a table on which the MDEV-11369 ADD COLUMN was performed can "lose its instantness" when it becomes empty. After instant DROP COLUMN or reordering columns, we cannot simply convert the table to the canonical format, because the data dictionary cache and all possibly existing references to it from other client connection threads would have to be adjusted. row_quiesce_write_index_fields(): Do not crash when the table contains an instantly dropped column. Thanks to Thirunarayanan Balathandayuthapani for discussing the design and implementing an initial prototype of this. Thanks to Matthias Leich for testing.
7 years ago
MDEV-15662 Instant DROP COLUMN or changing the order of columns Allow ADD COLUMN anywhere in a table, not only adding as the last column. Allow instant DROP COLUMN and instant changing the order of columns. The added columns will always be added last in clustered index records. In new records, instantly dropped columns will be stored as NULL or empty when possible. Information about dropped and reordered columns will be written in a metadata BLOB (mblob), which is stored before the first 'user' field in the hidden metadata record at the start of the clustered index. The presence of mblob is indicated by setting the delete-mark flag in the metadata record. The metadata BLOB stores the number of clustered index fields, followed by an array of column information for each field. For dropped columns, we store the NOT NULL flag, the fixed length, and for variable-length columns, whether the maximum length exceeded 255 bytes. For non-dropped columns, we store the column position. Unlike with MDEV-11369, when a table becomes empty, it cannot be converted back to the canonical format. The reason for this is that other threads may hold cached objects such as row_prebuilt_t::ins_node that could refer to dropped or reordered index fields. For instant DROP COLUMN and ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC, we must store the n_core_null_bytes in the root page, so that the chain of node pointer records can be followed in order to reach the leftmost leaf page where the metadata record is located. If the mblob is present, we will zero-initialize the strings "infimum" and "supremum" in the root page, and use the last byte of "supremum" for storing the number of null bytes (which are allocated but useless on node pointer pages). This is necessary for btr_cur_instant_init_metadata() to be able to navigate to the mblob. If the PRIMARY KEY contains any variable-length column and some nullable columns were instantly dropped, the dict_index_t::n_nullable in the data dictionary could be smaller than it actually is in the non-leaf pages. Because of this, the non-leaf pages could use more bytes for the null flags than the data dictionary expects, and we could be reading the lengths of the variable-length columns from the wrong offset, and thus reading the child page number from wrong place. This is the result of two design mistakes that involve unnecessary storage of data: First, it is nonsense to store any data fields for the leftmost node pointer records, because the comparisons would be resolved by the MIN_REC_FLAG alone. Second, there cannot be any null fields in the clustered index node pointer fields, but we nevertheless reserve space for all the null flags. Limitations (future work): MDEV-17459 Allow instant ALTER TABLE even if FULLTEXT INDEX exists MDEV-17468 Avoid table rebuild on operations on generated columns MDEV-17494 Refuse ALGORITHM=INSTANT when the row size is too large btr_page_reorganize_low(): Preserve any metadata in the root page. Call lock_move_reorganize_page() only after restoring the "infimum" and "supremum" records, to avoid a memcmp() assertion failure. dict_col_t::DROPPED: Magic value for dict_col_t::ind. dict_col_t::clear_instant(): Renamed from dict_col_t::remove_instant(). Do not assert that the column was instantly added, because we sometimes call this unconditionally for all columns. Convert an instantly added column to a "core column". The old name remove_instant() could be mistaken to refer to "instant DROP COLUMN". dict_col_t::is_added(): Rename from dict_col_t::is_instant(). dtype_t::metadata_blob_init(): Initialize the mblob data type. dtuple_t::is_metadata(), dtuple_t::is_alter_metadata(), upd_t::is_metadata(), upd_t::is_alter_metadata(): Check if info_bits refer to a metadata record. dict_table_t::instant: Metadata about dropped or reordered columns. dict_table_t::prepare_instant(): Prepare ha_innobase_inplace_ctx::instant_table for instant ALTER TABLE. innobase_instant_try() will pass this to dict_table_t::instant_column(). On rollback, dict_table_t::rollback_instant() will be called. dict_table_t::instant_column(): Renamed from instant_add_column(). Add the parameter col_map so that columns can be reordered. Copy and adjust v_cols[] as well. dict_table_t::find(): Find an old column based on a new column number. dict_table_t::serialise_columns(), dict_table_t::deserialise_columns(): Convert the mblob. dict_index_t::instant_metadata(): Create the metadata record for instant ALTER TABLE. Invoke dict_table_t::serialise_columns(). dict_index_t::reconstruct_fields(): Invoked by dict_table_t::deserialise_columns(). dict_index_t::clear_instant_alter(): Move the fields for the dropped columns to the end, and sort the surviving index fields in ascending order of column position. ha_innobase::check_if_supported_inplace_alter(): Do not allow adding a FTS_DOC_ID column if a hidden FTS_DOC_ID column exists due to FULLTEXT INDEX. (This always required ALGORITHM=COPY.) instant_alter_column_possible(): Add a parameter for InnoDB table, to check for additional conditions, such as the maximum number of index fields. ha_innobase_inplace_ctx::first_alter_pos: The first column whose position is affected by instant ADD, DROP, or changing the order of columns. innobase_build_col_map(): Skip added virtual columns. prepare_inplace_add_virtual(): Correctly compute num_to_add_vcol. Remove some unnecessary code. Note that the call to innodb_base_col_setup() should be executed later. commit_try_norebuild(): If ctx->is_instant(), let the virtual columns be added or dropped by innobase_instant_try(). innobase_instant_try(): Fill in a zero default value for the hidden column FTS_DOC_ID (to reduce the work needed in MDEV-17459). If any columns were dropped or reordered (or added not last), delete any SYS_COLUMNS records for the following columns, and insert SYS_COLUMNS records for all subsequent stored columns as well as for all virtual columns. If any virtual column is dropped, rewrite all virtual column metadata. Use a shortcut only for adding virtual columns. This is because innobase_drop_virtual_try() assumes that the dropped virtual columns still exist in ctx->old_table. innodb_update_cols(): Renamed from innodb_update_n_cols(). innobase_add_one_virtual(), innobase_insert_sys_virtual(): Change the return type to bool, and invoke my_error() when detecting an error. innodb_insert_sys_columns(): Insert a record into SYS_COLUMNS. Refactored from innobase_add_one_virtual() and innobase_instant_add_col(). innobase_instant_add_col(): Replace the parameter dfield with type. innobase_instant_drop_cols(): Drop matching columns from SYS_COLUMNS and all columns from SYS_VIRTUAL. innobase_add_virtual_try(), innobase_drop_virtual_try(): Let the caller invoke innodb_update_cols(). innobase_rename_column_try(): Skip dropped columns. commit_cache_norebuild(): Update table->fts->doc_col. dict_mem_table_col_rename_low(): Skip dropped columns. trx_undo_rec_get_partial_row(): Skip dropped columns. trx_undo_update_rec_get_update(): Handle the metadata BLOB correctly. trx_undo_page_report_modify(): Avoid out-of-bounds access to record fields. Log metadata records consistently. Apparently, the first fields of a clustered index may be updated in an update_undo vector when the index is ID_IND of SYS_FOREIGN, as part of renaming the table during ALTER TABLE. Normally, updates of the PRIMARY KEY should be logged as delete-mark and an insert. row_undo_mod_parse_undo_rec(), row_purge_parse_undo_rec(): Use trx_undo_metadata. row_undo_mod_clust_low(): On metadata rollback, roll back the root page too. row_undo_mod_clust(): Relax an assertion. The delete-mark flag was repurposed for ALTER TABLE metadata records. row_rec_to_index_entry_impl(): Add the template parameter mblob and the optional parameter info_bits for specifying the desired new info bits. For the metadata tuple, allow conversion between the original format (ADD COLUMN only) and the generic format (with hidden BLOB). Add the optional parameter "pad" to determine whether the tuple should be padded to the index fields (on ALTER TABLE it should), or whether it should remain at its original size (on rollback). row_build_index_entry_low(): Clean up the code, removing redundant variables and conditions. For instantly dropped columns, generate a dummy value that is NULL, the empty string, or a fixed length of NUL bytes, depending on the type of the dropped column. row_upd_clust_rec_by_insert_inherit_func(): On the update of PRIMARY KEY of a record that contained a dropped column whose value was stored externally, we will be inserting a dummy NULL or empty string value to the field of the dropped column. The externally stored column would eventually be dropped when purge removes the delete-marked record for the old PRIMARY KEY value. btr_index_rec_validate(): Recognize the metadata record. btr_discard_only_page_on_level(): Preserve the generic instant ALTER TABLE metadata. btr_set_instant(): Replaces page_set_instant(). This sets a clustered index root page to the appropriate format, or upgrades from the MDEV-11369 instant ADD COLUMN to generic ALTER TABLE format. btr_cur_instant_init_low(): Read and validate the metadata BLOB page before reconstructing the dictionary information based on it. btr_cur_instant_init_metadata(): Do not read any lengths from the metadata record header before reading the BLOB. At this point, we would not actually know how many nullable fields the metadata record contains. btr_cur_instant_root_init(): Initialize n_core_null_bytes in one of two possible ways. btr_cur_trim(): Handle the mblob record. row_metadata_to_tuple(): Convert a metadata record to a data tuple, based on the new info_bits of the metadata record. btr_cur_pessimistic_update(): Invoke row_metadata_to_tuple() if needed. Invoke dtuple_convert_big_rec() for metadata records if the record is too large, or if the mblob is not yet marked as externally stored. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): When the last user record is deleted, do not delete the generic instant ALTER TABLE metadata record. Only delete MDEV-11369 instant ADD COLUMN metadata records. btr_cur_optimistic_insert(): Avoid unnecessary computation of rec_size. btr_pcur_store_position(): Allow a logically empty page to contain a metadata record for generic ALTER TABLE. REC_INFO_DEFAULT_ROW_ADD: Renamed from REC_INFO_DEFAULT_ROW. This is for the old instant ADD COLUMN (MDEV-11369) only. REC_INFO_DEFAULT_ROW_ALTER: The more generic metadata record, with additional information for dropped or reordered columns. rec_info_bits_valid(): Remove. The only case when this would fail is when the record is the generic ALTER TABLE metadata record. rec_is_alter_metadata(): Check if a record is the metadata record for instant ALTER TABLE (other than ADD COLUMN). NOTE: This function must not be invoked on node pointer records, because the delete-mark flag in those records may be set (it is garbage), and then a debug assertion could fail because index->is_instant() does not necessarily hold. rec_is_add_metadata(): Check if a record is MDEV-11369 ADD COLUMN metadata record (not more generic instant ALTER TABLE). rec_get_converted_size_comp_prefix_low(): Assume that the metadata field will be stored externally. In dtuple_convert_big_rec() during the rec_get_converted_size() call, it would not be there yet. rec_get_converted_size_comp(): Replace status,fields,n_fields with tuple. rec_init_offsets_comp_ordinary(), rec_get_converted_size_comp_prefix_low(), rec_convert_dtuple_to_rec_comp(): Add template<bool mblob = false>. With mblob=true, process a record with a metadata BLOB. rec_copy_prefix_to_buf(): Assert that no fields beyond the key and system columns are being copied. Exclude the metadata BLOB field. rec_convert_dtuple_to_metadata_comp(): Convert an alter metadata tuple into a record. row_upd_index_replace_metadata(): Apply an update vector to an alter_metadata tuple. row_log_allocate(): Replace dict_index_t::is_instant() with a more appropriate condition that ignores dict_table_t::instant. Only a table on which the MDEV-11369 ADD COLUMN was performed can "lose its instantness" when it becomes empty. After instant DROP COLUMN or reordering columns, we cannot simply convert the table to the canonical format, because the data dictionary cache and all possibly existing references to it from other client connection threads would have to be adjusted. row_quiesce_write_index_fields(): Do not crash when the table contains an instantly dropped column. Thanks to Thirunarayanan Balathandayuthapani for discussing the design and implementing an initial prototype of this. Thanks to Matthias Leich for testing.
7 years ago
MDEV-15662 Instant DROP COLUMN or changing the order of columns Allow ADD COLUMN anywhere in a table, not only adding as the last column. Allow instant DROP COLUMN and instant changing the order of columns. The added columns will always be added last in clustered index records. In new records, instantly dropped columns will be stored as NULL or empty when possible. Information about dropped and reordered columns will be written in a metadata BLOB (mblob), which is stored before the first 'user' field in the hidden metadata record at the start of the clustered index. The presence of mblob is indicated by setting the delete-mark flag in the metadata record. The metadata BLOB stores the number of clustered index fields, followed by an array of column information for each field. For dropped columns, we store the NOT NULL flag, the fixed length, and for variable-length columns, whether the maximum length exceeded 255 bytes. For non-dropped columns, we store the column position. Unlike with MDEV-11369, when a table becomes empty, it cannot be converted back to the canonical format. The reason for this is that other threads may hold cached objects such as row_prebuilt_t::ins_node that could refer to dropped or reordered index fields. For instant DROP COLUMN and ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC, we must store the n_core_null_bytes in the root page, so that the chain of node pointer records can be followed in order to reach the leftmost leaf page where the metadata record is located. If the mblob is present, we will zero-initialize the strings "infimum" and "supremum" in the root page, and use the last byte of "supremum" for storing the number of null bytes (which are allocated but useless on node pointer pages). This is necessary for btr_cur_instant_init_metadata() to be able to navigate to the mblob. If the PRIMARY KEY contains any variable-length column and some nullable columns were instantly dropped, the dict_index_t::n_nullable in the data dictionary could be smaller than it actually is in the non-leaf pages. Because of this, the non-leaf pages could use more bytes for the null flags than the data dictionary expects, and we could be reading the lengths of the variable-length columns from the wrong offset, and thus reading the child page number from wrong place. This is the result of two design mistakes that involve unnecessary storage of data: First, it is nonsense to store any data fields for the leftmost node pointer records, because the comparisons would be resolved by the MIN_REC_FLAG alone. Second, there cannot be any null fields in the clustered index node pointer fields, but we nevertheless reserve space for all the null flags. Limitations (future work): MDEV-17459 Allow instant ALTER TABLE even if FULLTEXT INDEX exists MDEV-17468 Avoid table rebuild on operations on generated columns MDEV-17494 Refuse ALGORITHM=INSTANT when the row size is too large btr_page_reorganize_low(): Preserve any metadata in the root page. Call lock_move_reorganize_page() only after restoring the "infimum" and "supremum" records, to avoid a memcmp() assertion failure. dict_col_t::DROPPED: Magic value for dict_col_t::ind. dict_col_t::clear_instant(): Renamed from dict_col_t::remove_instant(). Do not assert that the column was instantly added, because we sometimes call this unconditionally for all columns. Convert an instantly added column to a "core column". The old name remove_instant() could be mistaken to refer to "instant DROP COLUMN". dict_col_t::is_added(): Rename from dict_col_t::is_instant(). dtype_t::metadata_blob_init(): Initialize the mblob data type. dtuple_t::is_metadata(), dtuple_t::is_alter_metadata(), upd_t::is_metadata(), upd_t::is_alter_metadata(): Check if info_bits refer to a metadata record. dict_table_t::instant: Metadata about dropped or reordered columns. dict_table_t::prepare_instant(): Prepare ha_innobase_inplace_ctx::instant_table for instant ALTER TABLE. innobase_instant_try() will pass this to dict_table_t::instant_column(). On rollback, dict_table_t::rollback_instant() will be called. dict_table_t::instant_column(): Renamed from instant_add_column(). Add the parameter col_map so that columns can be reordered. Copy and adjust v_cols[] as well. dict_table_t::find(): Find an old column based on a new column number. dict_table_t::serialise_columns(), dict_table_t::deserialise_columns(): Convert the mblob. dict_index_t::instant_metadata(): Create the metadata record for instant ALTER TABLE. Invoke dict_table_t::serialise_columns(). dict_index_t::reconstruct_fields(): Invoked by dict_table_t::deserialise_columns(). dict_index_t::clear_instant_alter(): Move the fields for the dropped columns to the end, and sort the surviving index fields in ascending order of column position. ha_innobase::check_if_supported_inplace_alter(): Do not allow adding a FTS_DOC_ID column if a hidden FTS_DOC_ID column exists due to FULLTEXT INDEX. (This always required ALGORITHM=COPY.) instant_alter_column_possible(): Add a parameter for InnoDB table, to check for additional conditions, such as the maximum number of index fields. ha_innobase_inplace_ctx::first_alter_pos: The first column whose position is affected by instant ADD, DROP, or changing the order of columns. innobase_build_col_map(): Skip added virtual columns. prepare_inplace_add_virtual(): Correctly compute num_to_add_vcol. Remove some unnecessary code. Note that the call to innodb_base_col_setup() should be executed later. commit_try_norebuild(): If ctx->is_instant(), let the virtual columns be added or dropped by innobase_instant_try(). innobase_instant_try(): Fill in a zero default value for the hidden column FTS_DOC_ID (to reduce the work needed in MDEV-17459). If any columns were dropped or reordered (or added not last), delete any SYS_COLUMNS records for the following columns, and insert SYS_COLUMNS records for all subsequent stored columns as well as for all virtual columns. If any virtual column is dropped, rewrite all virtual column metadata. Use a shortcut only for adding virtual columns. This is because innobase_drop_virtual_try() assumes that the dropped virtual columns still exist in ctx->old_table. innodb_update_cols(): Renamed from innodb_update_n_cols(). innobase_add_one_virtual(), innobase_insert_sys_virtual(): Change the return type to bool, and invoke my_error() when detecting an error. innodb_insert_sys_columns(): Insert a record into SYS_COLUMNS. Refactored from innobase_add_one_virtual() and innobase_instant_add_col(). innobase_instant_add_col(): Replace the parameter dfield with type. innobase_instant_drop_cols(): Drop matching columns from SYS_COLUMNS and all columns from SYS_VIRTUAL. innobase_add_virtual_try(), innobase_drop_virtual_try(): Let the caller invoke innodb_update_cols(). innobase_rename_column_try(): Skip dropped columns. commit_cache_norebuild(): Update table->fts->doc_col. dict_mem_table_col_rename_low(): Skip dropped columns. trx_undo_rec_get_partial_row(): Skip dropped columns. trx_undo_update_rec_get_update(): Handle the metadata BLOB correctly. trx_undo_page_report_modify(): Avoid out-of-bounds access to record fields. Log metadata records consistently. Apparently, the first fields of a clustered index may be updated in an update_undo vector when the index is ID_IND of SYS_FOREIGN, as part of renaming the table during ALTER TABLE. Normally, updates of the PRIMARY KEY should be logged as delete-mark and an insert. row_undo_mod_parse_undo_rec(), row_purge_parse_undo_rec(): Use trx_undo_metadata. row_undo_mod_clust_low(): On metadata rollback, roll back the root page too. row_undo_mod_clust(): Relax an assertion. The delete-mark flag was repurposed for ALTER TABLE metadata records. row_rec_to_index_entry_impl(): Add the template parameter mblob and the optional parameter info_bits for specifying the desired new info bits. For the metadata tuple, allow conversion between the original format (ADD COLUMN only) and the generic format (with hidden BLOB). Add the optional parameter "pad" to determine whether the tuple should be padded to the index fields (on ALTER TABLE it should), or whether it should remain at its original size (on rollback). row_build_index_entry_low(): Clean up the code, removing redundant variables and conditions. For instantly dropped columns, generate a dummy value that is NULL, the empty string, or a fixed length of NUL bytes, depending on the type of the dropped column. row_upd_clust_rec_by_insert_inherit_func(): On the update of PRIMARY KEY of a record that contained a dropped column whose value was stored externally, we will be inserting a dummy NULL or empty string value to the field of the dropped column. The externally stored column would eventually be dropped when purge removes the delete-marked record for the old PRIMARY KEY value. btr_index_rec_validate(): Recognize the metadata record. btr_discard_only_page_on_level(): Preserve the generic instant ALTER TABLE metadata. btr_set_instant(): Replaces page_set_instant(). This sets a clustered index root page to the appropriate format, or upgrades from the MDEV-11369 instant ADD COLUMN to generic ALTER TABLE format. btr_cur_instant_init_low(): Read and validate the metadata BLOB page before reconstructing the dictionary information based on it. btr_cur_instant_init_metadata(): Do not read any lengths from the metadata record header before reading the BLOB. At this point, we would not actually know how many nullable fields the metadata record contains. btr_cur_instant_root_init(): Initialize n_core_null_bytes in one of two possible ways. btr_cur_trim(): Handle the mblob record. row_metadata_to_tuple(): Convert a metadata record to a data tuple, based on the new info_bits of the metadata record. btr_cur_pessimistic_update(): Invoke row_metadata_to_tuple() if needed. Invoke dtuple_convert_big_rec() for metadata records if the record is too large, or if the mblob is not yet marked as externally stored. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): When the last user record is deleted, do not delete the generic instant ALTER TABLE metadata record. Only delete MDEV-11369 instant ADD COLUMN metadata records. btr_cur_optimistic_insert(): Avoid unnecessary computation of rec_size. btr_pcur_store_position(): Allow a logically empty page to contain a metadata record for generic ALTER TABLE. REC_INFO_DEFAULT_ROW_ADD: Renamed from REC_INFO_DEFAULT_ROW. This is for the old instant ADD COLUMN (MDEV-11369) only. REC_INFO_DEFAULT_ROW_ALTER: The more generic metadata record, with additional information for dropped or reordered columns. rec_info_bits_valid(): Remove. The only case when this would fail is when the record is the generic ALTER TABLE metadata record. rec_is_alter_metadata(): Check if a record is the metadata record for instant ALTER TABLE (other than ADD COLUMN). NOTE: This function must not be invoked on node pointer records, because the delete-mark flag in those records may be set (it is garbage), and then a debug assertion could fail because index->is_instant() does not necessarily hold. rec_is_add_metadata(): Check if a record is MDEV-11369 ADD COLUMN metadata record (not more generic instant ALTER TABLE). rec_get_converted_size_comp_prefix_low(): Assume that the metadata field will be stored externally. In dtuple_convert_big_rec() during the rec_get_converted_size() call, it would not be there yet. rec_get_converted_size_comp(): Replace status,fields,n_fields with tuple. rec_init_offsets_comp_ordinary(), rec_get_converted_size_comp_prefix_low(), rec_convert_dtuple_to_rec_comp(): Add template<bool mblob = false>. With mblob=true, process a record with a metadata BLOB. rec_copy_prefix_to_buf(): Assert that no fields beyond the key and system columns are being copied. Exclude the metadata BLOB field. rec_convert_dtuple_to_metadata_comp(): Convert an alter metadata tuple into a record. row_upd_index_replace_metadata(): Apply an update vector to an alter_metadata tuple. row_log_allocate(): Replace dict_index_t::is_instant() with a more appropriate condition that ignores dict_table_t::instant. Only a table on which the MDEV-11369 ADD COLUMN was performed can "lose its instantness" when it becomes empty. After instant DROP COLUMN or reordering columns, we cannot simply convert the table to the canonical format, because the data dictionary cache and all possibly existing references to it from other client connection threads would have to be adjusted. row_quiesce_write_index_fields(): Do not crash when the table contains an instantly dropped column. Thanks to Thirunarayanan Balathandayuthapani for discussing the design and implementing an initial prototype of this. Thanks to Matthias Leich for testing.
7 years ago
MDEV-15662 Instant DROP COLUMN or changing the order of columns Allow ADD COLUMN anywhere in a table, not only adding as the last column. Allow instant DROP COLUMN and instant changing the order of columns. The added columns will always be added last in clustered index records. In new records, instantly dropped columns will be stored as NULL or empty when possible. Information about dropped and reordered columns will be written in a metadata BLOB (mblob), which is stored before the first 'user' field in the hidden metadata record at the start of the clustered index. The presence of mblob is indicated by setting the delete-mark flag in the metadata record. The metadata BLOB stores the number of clustered index fields, followed by an array of column information for each field. For dropped columns, we store the NOT NULL flag, the fixed length, and for variable-length columns, whether the maximum length exceeded 255 bytes. For non-dropped columns, we store the column position. Unlike with MDEV-11369, when a table becomes empty, it cannot be converted back to the canonical format. The reason for this is that other threads may hold cached objects such as row_prebuilt_t::ins_node that could refer to dropped or reordered index fields. For instant DROP COLUMN and ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC, we must store the n_core_null_bytes in the root page, so that the chain of node pointer records can be followed in order to reach the leftmost leaf page where the metadata record is located. If the mblob is present, we will zero-initialize the strings "infimum" and "supremum" in the root page, and use the last byte of "supremum" for storing the number of null bytes (which are allocated but useless on node pointer pages). This is necessary for btr_cur_instant_init_metadata() to be able to navigate to the mblob. If the PRIMARY KEY contains any variable-length column and some nullable columns were instantly dropped, the dict_index_t::n_nullable in the data dictionary could be smaller than it actually is in the non-leaf pages. Because of this, the non-leaf pages could use more bytes for the null flags than the data dictionary expects, and we could be reading the lengths of the variable-length columns from the wrong offset, and thus reading the child page number from wrong place. This is the result of two design mistakes that involve unnecessary storage of data: First, it is nonsense to store any data fields for the leftmost node pointer records, because the comparisons would be resolved by the MIN_REC_FLAG alone. Second, there cannot be any null fields in the clustered index node pointer fields, but we nevertheless reserve space for all the null flags. Limitations (future work): MDEV-17459 Allow instant ALTER TABLE even if FULLTEXT INDEX exists MDEV-17468 Avoid table rebuild on operations on generated columns MDEV-17494 Refuse ALGORITHM=INSTANT when the row size is too large btr_page_reorganize_low(): Preserve any metadata in the root page. Call lock_move_reorganize_page() only after restoring the "infimum" and "supremum" records, to avoid a memcmp() assertion failure. dict_col_t::DROPPED: Magic value for dict_col_t::ind. dict_col_t::clear_instant(): Renamed from dict_col_t::remove_instant(). Do not assert that the column was instantly added, because we sometimes call this unconditionally for all columns. Convert an instantly added column to a "core column". The old name remove_instant() could be mistaken to refer to "instant DROP COLUMN". dict_col_t::is_added(): Rename from dict_col_t::is_instant(). dtype_t::metadata_blob_init(): Initialize the mblob data type. dtuple_t::is_metadata(), dtuple_t::is_alter_metadata(), upd_t::is_metadata(), upd_t::is_alter_metadata(): Check if info_bits refer to a metadata record. dict_table_t::instant: Metadata about dropped or reordered columns. dict_table_t::prepare_instant(): Prepare ha_innobase_inplace_ctx::instant_table for instant ALTER TABLE. innobase_instant_try() will pass this to dict_table_t::instant_column(). On rollback, dict_table_t::rollback_instant() will be called. dict_table_t::instant_column(): Renamed from instant_add_column(). Add the parameter col_map so that columns can be reordered. Copy and adjust v_cols[] as well. dict_table_t::find(): Find an old column based on a new column number. dict_table_t::serialise_columns(), dict_table_t::deserialise_columns(): Convert the mblob. dict_index_t::instant_metadata(): Create the metadata record for instant ALTER TABLE. Invoke dict_table_t::serialise_columns(). dict_index_t::reconstruct_fields(): Invoked by dict_table_t::deserialise_columns(). dict_index_t::clear_instant_alter(): Move the fields for the dropped columns to the end, and sort the surviving index fields in ascending order of column position. ha_innobase::check_if_supported_inplace_alter(): Do not allow adding a FTS_DOC_ID column if a hidden FTS_DOC_ID column exists due to FULLTEXT INDEX. (This always required ALGORITHM=COPY.) instant_alter_column_possible(): Add a parameter for InnoDB table, to check for additional conditions, such as the maximum number of index fields. ha_innobase_inplace_ctx::first_alter_pos: The first column whose position is affected by instant ADD, DROP, or changing the order of columns. innobase_build_col_map(): Skip added virtual columns. prepare_inplace_add_virtual(): Correctly compute num_to_add_vcol. Remove some unnecessary code. Note that the call to innodb_base_col_setup() should be executed later. commit_try_norebuild(): If ctx->is_instant(), let the virtual columns be added or dropped by innobase_instant_try(). innobase_instant_try(): Fill in a zero default value for the hidden column FTS_DOC_ID (to reduce the work needed in MDEV-17459). If any columns were dropped or reordered (or added not last), delete any SYS_COLUMNS records for the following columns, and insert SYS_COLUMNS records for all subsequent stored columns as well as for all virtual columns. If any virtual column is dropped, rewrite all virtual column metadata. Use a shortcut only for adding virtual columns. This is because innobase_drop_virtual_try() assumes that the dropped virtual columns still exist in ctx->old_table. innodb_update_cols(): Renamed from innodb_update_n_cols(). innobase_add_one_virtual(), innobase_insert_sys_virtual(): Change the return type to bool, and invoke my_error() when detecting an error. innodb_insert_sys_columns(): Insert a record into SYS_COLUMNS. Refactored from innobase_add_one_virtual() and innobase_instant_add_col(). innobase_instant_add_col(): Replace the parameter dfield with type. innobase_instant_drop_cols(): Drop matching columns from SYS_COLUMNS and all columns from SYS_VIRTUAL. innobase_add_virtual_try(), innobase_drop_virtual_try(): Let the caller invoke innodb_update_cols(). innobase_rename_column_try(): Skip dropped columns. commit_cache_norebuild(): Update table->fts->doc_col. dict_mem_table_col_rename_low(): Skip dropped columns. trx_undo_rec_get_partial_row(): Skip dropped columns. trx_undo_update_rec_get_update(): Handle the metadata BLOB correctly. trx_undo_page_report_modify(): Avoid out-of-bounds access to record fields. Log metadata records consistently. Apparently, the first fields of a clustered index may be updated in an update_undo vector when the index is ID_IND of SYS_FOREIGN, as part of renaming the table during ALTER TABLE. Normally, updates of the PRIMARY KEY should be logged as delete-mark and an insert. row_undo_mod_parse_undo_rec(), row_purge_parse_undo_rec(): Use trx_undo_metadata. row_undo_mod_clust_low(): On metadata rollback, roll back the root page too. row_undo_mod_clust(): Relax an assertion. The delete-mark flag was repurposed for ALTER TABLE metadata records. row_rec_to_index_entry_impl(): Add the template parameter mblob and the optional parameter info_bits for specifying the desired new info bits. For the metadata tuple, allow conversion between the original format (ADD COLUMN only) and the generic format (with hidden BLOB). Add the optional parameter "pad" to determine whether the tuple should be padded to the index fields (on ALTER TABLE it should), or whether it should remain at its original size (on rollback). row_build_index_entry_low(): Clean up the code, removing redundant variables and conditions. For instantly dropped columns, generate a dummy value that is NULL, the empty string, or a fixed length of NUL bytes, depending on the type of the dropped column. row_upd_clust_rec_by_insert_inherit_func(): On the update of PRIMARY KEY of a record that contained a dropped column whose value was stored externally, we will be inserting a dummy NULL or empty string value to the field of the dropped column. The externally stored column would eventually be dropped when purge removes the delete-marked record for the old PRIMARY KEY value. btr_index_rec_validate(): Recognize the metadata record. btr_discard_only_page_on_level(): Preserve the generic instant ALTER TABLE metadata. btr_set_instant(): Replaces page_set_instant(). This sets a clustered index root page to the appropriate format, or upgrades from the MDEV-11369 instant ADD COLUMN to generic ALTER TABLE format. btr_cur_instant_init_low(): Read and validate the metadata BLOB page before reconstructing the dictionary information based on it. btr_cur_instant_init_metadata(): Do not read any lengths from the metadata record header before reading the BLOB. At this point, we would not actually know how many nullable fields the metadata record contains. btr_cur_instant_root_init(): Initialize n_core_null_bytes in one of two possible ways. btr_cur_trim(): Handle the mblob record. row_metadata_to_tuple(): Convert a metadata record to a data tuple, based on the new info_bits of the metadata record. btr_cur_pessimistic_update(): Invoke row_metadata_to_tuple() if needed. Invoke dtuple_convert_big_rec() for metadata records if the record is too large, or if the mblob is not yet marked as externally stored. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): When the last user record is deleted, do not delete the generic instant ALTER TABLE metadata record. Only delete MDEV-11369 instant ADD COLUMN metadata records. btr_cur_optimistic_insert(): Avoid unnecessary computation of rec_size. btr_pcur_store_position(): Allow a logically empty page to contain a metadata record for generic ALTER TABLE. REC_INFO_DEFAULT_ROW_ADD: Renamed from REC_INFO_DEFAULT_ROW. This is for the old instant ADD COLUMN (MDEV-11369) only. REC_INFO_DEFAULT_ROW_ALTER: The more generic metadata record, with additional information for dropped or reordered columns. rec_info_bits_valid(): Remove. The only case when this would fail is when the record is the generic ALTER TABLE metadata record. rec_is_alter_metadata(): Check if a record is the metadata record for instant ALTER TABLE (other than ADD COLUMN). NOTE: This function must not be invoked on node pointer records, because the delete-mark flag in those records may be set (it is garbage), and then a debug assertion could fail because index->is_instant() does not necessarily hold. rec_is_add_metadata(): Check if a record is MDEV-11369 ADD COLUMN metadata record (not more generic instant ALTER TABLE). rec_get_converted_size_comp_prefix_low(): Assume that the metadata field will be stored externally. In dtuple_convert_big_rec() during the rec_get_converted_size() call, it would not be there yet. rec_get_converted_size_comp(): Replace status,fields,n_fields with tuple. rec_init_offsets_comp_ordinary(), rec_get_converted_size_comp_prefix_low(), rec_convert_dtuple_to_rec_comp(): Add template<bool mblob = false>. With mblob=true, process a record with a metadata BLOB. rec_copy_prefix_to_buf(): Assert that no fields beyond the key and system columns are being copied. Exclude the metadata BLOB field. rec_convert_dtuple_to_metadata_comp(): Convert an alter metadata tuple into a record. row_upd_index_replace_metadata(): Apply an update vector to an alter_metadata tuple. row_log_allocate(): Replace dict_index_t::is_instant() with a more appropriate condition that ignores dict_table_t::instant. Only a table on which the MDEV-11369 ADD COLUMN was performed can "lose its instantness" when it becomes empty. After instant DROP COLUMN or reordering columns, we cannot simply convert the table to the canonical format, because the data dictionary cache and all possibly existing references to it from other client connection threads would have to be adjusted. row_quiesce_write_index_fields(): Do not crash when the table contains an instantly dropped column. Thanks to Thirunarayanan Balathandayuthapani for discussing the design and implementing an initial prototype of this. Thanks to Matthias Leich for testing.
7 years ago
MDEV-21907: InnoDB: Enable -Wconversion on clang and GCC The -Wconversion in GCC seems to be stricter than in clang. GCC at least since version 4.4.7 issues truncation warnings for assignments to bitfields, while clang 10 appears to only issue warnings when the sizes in bytes rounded to the nearest integer powers of 2 are different. Before GCC 10.0.0, -Wconversion required more casts and would not allow some operations, such as x<<=1 or x+=1 on a data type that is narrower than int. GCC 5 (but not GCC 4, GCC 6, or any later version) is complaining about x|=y even when x and y are compatible types that are narrower than int. Hence, we must rewrite some x|=y as x=static_cast<byte>(x|y) or similar, or we must disable -Wconversion. In GCC 6 and later, the warning for assigning wider to bitfields that are narrower than 8, 16, or 32 bits can be suppressed by applying a bitwise & with the exact bitmask of the bitfield. For older GCC, we must disable -Wconversion for GCC 4 or 5 in such cases. The bitwise negation operator appears to promote short integers to a wider type, and hence we must add explicit truncation casts around them. Microsoft Visual C does not allow a static_cast to truncate a constant, such as static_cast<byte>(1) truncating int. Hence, we will use the constructor-style cast byte(~1) for such cases. This has been tested at least with GCC 4.8.5, 5.4.0, 7.4.0, 9.2.1, 10.0.0, clang 9.0.1, 10.0.0, and MSVC 14.22.27905 (Microsoft Visual Studio 2019) on 64-bit and 32-bit targets (IA-32, AMD64, POWER 8, POWER 9, ARMv8).
6 years ago
MDEV-15662 Instant DROP COLUMN or changing the order of columns Allow ADD COLUMN anywhere in a table, not only adding as the last column. Allow instant DROP COLUMN and instant changing the order of columns. The added columns will always be added last in clustered index records. In new records, instantly dropped columns will be stored as NULL or empty when possible. Information about dropped and reordered columns will be written in a metadata BLOB (mblob), which is stored before the first 'user' field in the hidden metadata record at the start of the clustered index. The presence of mblob is indicated by setting the delete-mark flag in the metadata record. The metadata BLOB stores the number of clustered index fields, followed by an array of column information for each field. For dropped columns, we store the NOT NULL flag, the fixed length, and for variable-length columns, whether the maximum length exceeded 255 bytes. For non-dropped columns, we store the column position. Unlike with MDEV-11369, when a table becomes empty, it cannot be converted back to the canonical format. The reason for this is that other threads may hold cached objects such as row_prebuilt_t::ins_node that could refer to dropped or reordered index fields. For instant DROP COLUMN and ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC, we must store the n_core_null_bytes in the root page, so that the chain of node pointer records can be followed in order to reach the leftmost leaf page where the metadata record is located. If the mblob is present, we will zero-initialize the strings "infimum" and "supremum" in the root page, and use the last byte of "supremum" for storing the number of null bytes (which are allocated but useless on node pointer pages). This is necessary for btr_cur_instant_init_metadata() to be able to navigate to the mblob. If the PRIMARY KEY contains any variable-length column and some nullable columns were instantly dropped, the dict_index_t::n_nullable in the data dictionary could be smaller than it actually is in the non-leaf pages. Because of this, the non-leaf pages could use more bytes for the null flags than the data dictionary expects, and we could be reading the lengths of the variable-length columns from the wrong offset, and thus reading the child page number from wrong place. This is the result of two design mistakes that involve unnecessary storage of data: First, it is nonsense to store any data fields for the leftmost node pointer records, because the comparisons would be resolved by the MIN_REC_FLAG alone. Second, there cannot be any null fields in the clustered index node pointer fields, but we nevertheless reserve space for all the null flags. Limitations (future work): MDEV-17459 Allow instant ALTER TABLE even if FULLTEXT INDEX exists MDEV-17468 Avoid table rebuild on operations on generated columns MDEV-17494 Refuse ALGORITHM=INSTANT when the row size is too large btr_page_reorganize_low(): Preserve any metadata in the root page. Call lock_move_reorganize_page() only after restoring the "infimum" and "supremum" records, to avoid a memcmp() assertion failure. dict_col_t::DROPPED: Magic value for dict_col_t::ind. dict_col_t::clear_instant(): Renamed from dict_col_t::remove_instant(). Do not assert that the column was instantly added, because we sometimes call this unconditionally for all columns. Convert an instantly added column to a "core column". The old name remove_instant() could be mistaken to refer to "instant DROP COLUMN". dict_col_t::is_added(): Rename from dict_col_t::is_instant(). dtype_t::metadata_blob_init(): Initialize the mblob data type. dtuple_t::is_metadata(), dtuple_t::is_alter_metadata(), upd_t::is_metadata(), upd_t::is_alter_metadata(): Check if info_bits refer to a metadata record. dict_table_t::instant: Metadata about dropped or reordered columns. dict_table_t::prepare_instant(): Prepare ha_innobase_inplace_ctx::instant_table for instant ALTER TABLE. innobase_instant_try() will pass this to dict_table_t::instant_column(). On rollback, dict_table_t::rollback_instant() will be called. dict_table_t::instant_column(): Renamed from instant_add_column(). Add the parameter col_map so that columns can be reordered. Copy and adjust v_cols[] as well. dict_table_t::find(): Find an old column based on a new column number. dict_table_t::serialise_columns(), dict_table_t::deserialise_columns(): Convert the mblob. dict_index_t::instant_metadata(): Create the metadata record for instant ALTER TABLE. Invoke dict_table_t::serialise_columns(). dict_index_t::reconstruct_fields(): Invoked by dict_table_t::deserialise_columns(). dict_index_t::clear_instant_alter(): Move the fields for the dropped columns to the end, and sort the surviving index fields in ascending order of column position. ha_innobase::check_if_supported_inplace_alter(): Do not allow adding a FTS_DOC_ID column if a hidden FTS_DOC_ID column exists due to FULLTEXT INDEX. (This always required ALGORITHM=COPY.) instant_alter_column_possible(): Add a parameter for InnoDB table, to check for additional conditions, such as the maximum number of index fields. ha_innobase_inplace_ctx::first_alter_pos: The first column whose position is affected by instant ADD, DROP, or changing the order of columns. innobase_build_col_map(): Skip added virtual columns. prepare_inplace_add_virtual(): Correctly compute num_to_add_vcol. Remove some unnecessary code. Note that the call to innodb_base_col_setup() should be executed later. commit_try_norebuild(): If ctx->is_instant(), let the virtual columns be added or dropped by innobase_instant_try(). innobase_instant_try(): Fill in a zero default value for the hidden column FTS_DOC_ID (to reduce the work needed in MDEV-17459). If any columns were dropped or reordered (or added not last), delete any SYS_COLUMNS records for the following columns, and insert SYS_COLUMNS records for all subsequent stored columns as well as for all virtual columns. If any virtual column is dropped, rewrite all virtual column metadata. Use a shortcut only for adding virtual columns. This is because innobase_drop_virtual_try() assumes that the dropped virtual columns still exist in ctx->old_table. innodb_update_cols(): Renamed from innodb_update_n_cols(). innobase_add_one_virtual(), innobase_insert_sys_virtual(): Change the return type to bool, and invoke my_error() when detecting an error. innodb_insert_sys_columns(): Insert a record into SYS_COLUMNS. Refactored from innobase_add_one_virtual() and innobase_instant_add_col(). innobase_instant_add_col(): Replace the parameter dfield with type. innobase_instant_drop_cols(): Drop matching columns from SYS_COLUMNS and all columns from SYS_VIRTUAL. innobase_add_virtual_try(), innobase_drop_virtual_try(): Let the caller invoke innodb_update_cols(). innobase_rename_column_try(): Skip dropped columns. commit_cache_norebuild(): Update table->fts->doc_col. dict_mem_table_col_rename_low(): Skip dropped columns. trx_undo_rec_get_partial_row(): Skip dropped columns. trx_undo_update_rec_get_update(): Handle the metadata BLOB correctly. trx_undo_page_report_modify(): Avoid out-of-bounds access to record fields. Log metadata records consistently. Apparently, the first fields of a clustered index may be updated in an update_undo vector when the index is ID_IND of SYS_FOREIGN, as part of renaming the table during ALTER TABLE. Normally, updates of the PRIMARY KEY should be logged as delete-mark and an insert. row_undo_mod_parse_undo_rec(), row_purge_parse_undo_rec(): Use trx_undo_metadata. row_undo_mod_clust_low(): On metadata rollback, roll back the root page too. row_undo_mod_clust(): Relax an assertion. The delete-mark flag was repurposed for ALTER TABLE metadata records. row_rec_to_index_entry_impl(): Add the template parameter mblob and the optional parameter info_bits for specifying the desired new info bits. For the metadata tuple, allow conversion between the original format (ADD COLUMN only) and the generic format (with hidden BLOB). Add the optional parameter "pad" to determine whether the tuple should be padded to the index fields (on ALTER TABLE it should), or whether it should remain at its original size (on rollback). row_build_index_entry_low(): Clean up the code, removing redundant variables and conditions. For instantly dropped columns, generate a dummy value that is NULL, the empty string, or a fixed length of NUL bytes, depending on the type of the dropped column. row_upd_clust_rec_by_insert_inherit_func(): On the update of PRIMARY KEY of a record that contained a dropped column whose value was stored externally, we will be inserting a dummy NULL or empty string value to the field of the dropped column. The externally stored column would eventually be dropped when purge removes the delete-marked record for the old PRIMARY KEY value. btr_index_rec_validate(): Recognize the metadata record. btr_discard_only_page_on_level(): Preserve the generic instant ALTER TABLE metadata. btr_set_instant(): Replaces page_set_instant(). This sets a clustered index root page to the appropriate format, or upgrades from the MDEV-11369 instant ADD COLUMN to generic ALTER TABLE format. btr_cur_instant_init_low(): Read and validate the metadata BLOB page before reconstructing the dictionary information based on it. btr_cur_instant_init_metadata(): Do not read any lengths from the metadata record header before reading the BLOB. At this point, we would not actually know how many nullable fields the metadata record contains. btr_cur_instant_root_init(): Initialize n_core_null_bytes in one of two possible ways. btr_cur_trim(): Handle the mblob record. row_metadata_to_tuple(): Convert a metadata record to a data tuple, based on the new info_bits of the metadata record. btr_cur_pessimistic_update(): Invoke row_metadata_to_tuple() if needed. Invoke dtuple_convert_big_rec() for metadata records if the record is too large, or if the mblob is not yet marked as externally stored. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): When the last user record is deleted, do not delete the generic instant ALTER TABLE metadata record. Only delete MDEV-11369 instant ADD COLUMN metadata records. btr_cur_optimistic_insert(): Avoid unnecessary computation of rec_size. btr_pcur_store_position(): Allow a logically empty page to contain a metadata record for generic ALTER TABLE. REC_INFO_DEFAULT_ROW_ADD: Renamed from REC_INFO_DEFAULT_ROW. This is for the old instant ADD COLUMN (MDEV-11369) only. REC_INFO_DEFAULT_ROW_ALTER: The more generic metadata record, with additional information for dropped or reordered columns. rec_info_bits_valid(): Remove. The only case when this would fail is when the record is the generic ALTER TABLE metadata record. rec_is_alter_metadata(): Check if a record is the metadata record for instant ALTER TABLE (other than ADD COLUMN). NOTE: This function must not be invoked on node pointer records, because the delete-mark flag in those records may be set (it is garbage), and then a debug assertion could fail because index->is_instant() does not necessarily hold. rec_is_add_metadata(): Check if a record is MDEV-11369 ADD COLUMN metadata record (not more generic instant ALTER TABLE). rec_get_converted_size_comp_prefix_low(): Assume that the metadata field will be stored externally. In dtuple_convert_big_rec() during the rec_get_converted_size() call, it would not be there yet. rec_get_converted_size_comp(): Replace status,fields,n_fields with tuple. rec_init_offsets_comp_ordinary(), rec_get_converted_size_comp_prefix_low(), rec_convert_dtuple_to_rec_comp(): Add template<bool mblob = false>. With mblob=true, process a record with a metadata BLOB. rec_copy_prefix_to_buf(): Assert that no fields beyond the key and system columns are being copied. Exclude the metadata BLOB field. rec_convert_dtuple_to_metadata_comp(): Convert an alter metadata tuple into a record. row_upd_index_replace_metadata(): Apply an update vector to an alter_metadata tuple. row_log_allocate(): Replace dict_index_t::is_instant() with a more appropriate condition that ignores dict_table_t::instant. Only a table on which the MDEV-11369 ADD COLUMN was performed can "lose its instantness" when it becomes empty. After instant DROP COLUMN or reordering columns, we cannot simply convert the table to the canonical format, because the data dictionary cache and all possibly existing references to it from other client connection threads would have to be adjusted. row_quiesce_write_index_fields(): Do not crash when the table contains an instantly dropped column. Thanks to Thirunarayanan Balathandayuthapani for discussing the design and implementing an initial prototype of this. Thanks to Matthias Leich for testing.
7 years ago
MDEV-11369 Instant ADD COLUMN for InnoDB For InnoDB tables, adding, dropping and reordering columns has required a rebuild of the table and all its indexes. Since MySQL 5.6 (and MariaDB 10.0) this has been supported online (LOCK=NONE), allowing concurrent modification of the tables. This work revises the InnoDB ROW_FORMAT=REDUNDANT, ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC so that columns can be appended instantaneously, with only minor changes performed to the table structure. The counter innodb_instant_alter_column in INFORMATION_SCHEMA.GLOBAL_STATUS is incremented whenever a table rebuild operation is converted into an instant ADD COLUMN operation. ROW_FORMAT=COMPRESSED tables will not support instant ADD COLUMN. Some usability limitations will be addressed in subsequent work: MDEV-13134 Introduce ALTER TABLE attributes ALGORITHM=NOCOPY and ALGORITHM=INSTANT MDEV-14016 Allow instant ADD COLUMN, ADD INDEX, LOCK=NONE The format of the clustered index (PRIMARY KEY) is changed as follows: (1) The FIL_PAGE_TYPE of the root page will be FIL_PAGE_TYPE_INSTANT, and a new field PAGE_INSTANT will contain the original number of fields in the clustered index ('core' fields). If instant ADD COLUMN has not been used or the table becomes empty, or the very first instant ADD COLUMN operation is rolled back, the fields PAGE_INSTANT and FIL_PAGE_TYPE will be reset to 0 and FIL_PAGE_INDEX. (2) A special 'default row' record is inserted into the leftmost leaf, between the page infimum and the first user record. This record is distinguished by the REC_INFO_MIN_REC_FLAG, and it is otherwise in the same format as records that contain values for the instantly added columns. This 'default row' always has the same number of fields as the clustered index according to the table definition. The values of 'core' fields are to be ignored. For other fields, the 'default row' will contain the default values as they were during the ALTER TABLE statement. (If the column default values are changed later, those values will only be stored in the .frm file. The 'default row' will contain the original evaluated values, which must be the same for every row.) The 'default row' must be completely hidden from higher-level access routines. Assertions have been added to ensure that no 'default row' is ever present in the adaptive hash index or in locked records. The 'default row' is never delete-marked. (3) In clustered index leaf page records, the number of fields must reside between the number of 'core' fields (dict_index_t::n_core_fields introduced in this work) and dict_index_t::n_fields. If the number of fields is less than dict_index_t::n_fields, the missing fields are replaced with the column value of the 'default row'. Note: The number of fields in the record may shrink if some of the last instantly added columns are updated to the value that is in the 'default row'. The function btr_cur_trim() implements this 'compression' on update and rollback; dtuple::trim() implements it on insert. (4) In ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC records, the new status value REC_STATUS_COLUMNS_ADDED will indicate the presence of a new record header that will encode n_fields-n_core_fields-1 in 1 or 2 bytes. (In ROW_FORMAT=REDUNDANT records, the record header always explicitly encodes the number of fields.) We introduce the undo log record type TRX_UNDO_INSERT_DEFAULT for covering the insert of the 'default row' record when instant ADD COLUMN is used for the first time. Subsequent instant ADD COLUMN can use TRX_UNDO_UPD_EXIST_REC. This is joint work with Vin Chen (陈福荣) from Tencent. The design that was discussed in April 2017 would not have allowed import or export of data files, because instead of the 'default row' it would have introduced a data dictionary table. The test rpl.rpl_alter_instant is exactly as contributed in pull request #408. The test innodb.instant_alter is based on a contributed test. The redo log record format changes for ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPACT are as contributed. (With this change present, crash recovery from MariaDB 10.3.1 will fail in spectacular ways!) Also the semantics of higher-level redo log records that modify the PAGE_INSTANT field is changed. The redo log format version identifier was already changed to LOG_HEADER_FORMAT_CURRENT=103 in MariaDB 10.3.1. Everything else has been rewritten by me. Thanks to Elena Stepanova, the code has been tested extensively. When rolling back an instant ADD COLUMN operation, we must empty the PAGE_FREE list after deleting or shortening the 'default row' record, by calling either btr_page_empty() or btr_page_reorganize(). We must know the size of each entry in the PAGE_FREE list. If rollback left a freed copy of the 'default row' in the PAGE_FREE list, we would be unable to determine its size (if it is in ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC) because it would contain more fields than the rolled-back definition of the clustered index. UNIV_SQL_DEFAULT: A new special constant that designates an instantly added column that is not present in the clustered index record. len_is_stored(): Check if a length is an actual length. There are two magic length values: UNIV_SQL_DEFAULT, UNIV_SQL_NULL. dict_col_t::def_val: The 'default row' value of the column. If the column is not added instantly, def_val.len will be UNIV_SQL_DEFAULT. dict_col_t: Add the accessors is_virtual(), is_nullable(), is_instant(), instant_value(). dict_col_t::remove_instant(): Remove the 'instant ADD' status of a column. dict_col_t::name(const dict_table_t& table): Replaces dict_table_get_col_name(). dict_index_t::n_core_fields: The original number of fields. For secondary indexes and if instant ADD COLUMN has not been used, this will be equal to dict_index_t::n_fields. dict_index_t::n_core_null_bytes: Number of bytes needed to represent the null flags; usually equal to UT_BITS_IN_BYTES(n_nullable). dict_index_t::NO_CORE_NULL_BYTES: Magic value signalling that n_core_null_bytes was not initialized yet from the clustered index root page. dict_index_t: Add the accessors is_instant(), is_clust(), get_n_nullable(), instant_field_value(). dict_index_t::instant_add_field(): Adjust clustered index metadata for instant ADD COLUMN. dict_index_t::remove_instant(): Remove the 'instant ADD' status of a clustered index when the table becomes empty, or the very first instant ADD COLUMN operation is rolled back. dict_table_t: Add the accessors is_instant(), is_temporary(), supports_instant(). dict_table_t::instant_add_column(): Adjust metadata for instant ADD COLUMN. dict_table_t::rollback_instant(): Adjust metadata on the rollback of instant ADD COLUMN. prepare_inplace_alter_table_dict(): First create the ctx->new_table, and only then decide if the table really needs to be rebuilt. We must split the creation of table or index metadata from the creation of the dictionary table records and the creation of the data. In this way, we can transform a table-rebuilding operation into an instant ADD COLUMN operation. Dictionary objects will only be added to cache when table rebuilding or index creation is needed. The ctx->instant_table will never be added to cache. dict_table_t::add_to_cache(): Modified and renamed from dict_table_add_to_cache(). Do not modify the table metadata. Let the callers invoke dict_table_add_system_columns() and if needed, set can_be_evicted. dict_create_sys_tables_tuple(), dict_create_table_step(): Omit the system columns (which will now exist in the dict_table_t object already at this point). dict_create_table_step(): Expect the callers to invoke dict_table_add_system_columns(). pars_create_table(): Before creating the table creation execution graph, invoke dict_table_add_system_columns(). row_create_table_for_mysql(): Expect all callers to invoke dict_table_add_system_columns(). create_index_dict(): Replaces row_merge_create_index_graph(). innodb_update_n_cols(): Renamed from innobase_update_n_virtual(). Call my_error() if an error occurs. btr_cur_instant_init(), btr_cur_instant_init_low(), btr_cur_instant_root_init(): Load additional metadata from the clustered index and set dict_index_t::n_core_null_bytes. This is invoked when table metadata is first loaded into the data dictionary. dict_boot(): Initialize n_core_null_bytes for the four hard-coded dictionary tables. dict_create_index_step(): Initialize n_core_null_bytes. This is executed as part of CREATE TABLE. dict_index_build_internal_clust(): Initialize n_core_null_bytes to NO_CORE_NULL_BYTES if table->supports_instant(). row_create_index_for_mysql(): Initialize n_core_null_bytes for CREATE TEMPORARY TABLE. commit_cache_norebuild(): Call the code to rename or enlarge columns in the cache only if instant ADD COLUMN is not being used. (Instant ADD COLUMN would copy all column metadata from instant_table to old_table, including the names and lengths.) PAGE_INSTANT: A new 13-bit field for storing dict_index_t::n_core_fields. This is repurposing the 16-bit field PAGE_DIRECTION, of which only the least significant 3 bits were used. The original byte containing PAGE_DIRECTION will be accessible via the new constant PAGE_DIRECTION_B. page_get_instant(), page_set_instant(): Accessors for the PAGE_INSTANT. page_ptr_get_direction(), page_get_direction(), page_ptr_set_direction(): Accessors for PAGE_DIRECTION. page_direction_reset(): Reset PAGE_DIRECTION, PAGE_N_DIRECTION. page_direction_increment(): Increment PAGE_N_DIRECTION and set PAGE_DIRECTION. rec_get_offsets(): Use the 'leaf' parameter for non-debug purposes, and assume that heap_no is always set. Initialize all dict_index_t::n_fields for ROW_FORMAT=REDUNDANT records, even if the record contains fewer fields. rec_offs_make_valid(): Add the parameter 'leaf'. rec_copy_prefix_to_dtuple(): Assert that the tuple is only built on the core fields. Instant ADD COLUMN only applies to the clustered index, and we should never build a search key that has more than the PRIMARY KEY and possibly DB_TRX_ID,DB_ROLL_PTR. All these columns are always present. dict_index_build_data_tuple(): Remove assertions that would be duplicated in rec_copy_prefix_to_dtuple(). rec_init_offsets(): Support ROW_FORMAT=REDUNDANT records whose number of fields is between n_core_fields and n_fields. cmp_rec_rec_with_match(): Implement the comparison between two MIN_REC_FLAG records. trx_t::in_rollback: Make the field available in non-debug builds. trx_start_for_ddl_low(): Remove dangerous error-tolerance. A dictionary transaction must be flagged as such before it has generated any undo log records. This is because trx_undo_assign_undo() will mark the transaction as a dictionary transaction in the undo log header right before the very first undo log record is being written. btr_index_rec_validate(): Account for instant ADD COLUMN row_undo_ins_remove_clust_rec(): On the rollback of an insert into SYS_COLUMNS, revert instant ADD COLUMN in the cache by removing the last column from the table and the clustered index. row_search_on_row_ref(), row_undo_mod_parse_undo_rec(), row_undo_mod(), trx_undo_update_rec_get_update(): Handle the 'default row' as a special case. dtuple_t::trim(index): Omit a redundant suffix of an index tuple right before insert or update. After instant ADD COLUMN, if the last fields of a clustered index tuple match the 'default row', there is no need to store them. While trimming the entry, we must hold a page latch, so that the table cannot be emptied and the 'default row' be deleted. btr_cur_optimistic_update(), btr_cur_pessimistic_update(), row_upd_clust_rec_by_insert(), row_ins_clust_index_entry_low(): Invoke dtuple_t::trim() if needed. row_ins_clust_index_entry(): Restore dtuple_t::n_fields after calling row_ins_clust_index_entry_low(). rec_get_converted_size(), rec_get_converted_size_comp(): Allow the number of fields to be between n_core_fields and n_fields. Do not support infimum,supremum. They are never supposed to be stored in dtuple_t, because page creation nowadays uses a lower-level method for initializing them. rec_convert_dtuple_to_rec_comp(): Assign the status bits based on the number of fields. btr_cur_trim(): In an update, trim the index entry as needed. For the 'default row', handle rollback specially. For user records, omit fields that match the 'default row'. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): Skip locking and adaptive hash index for the 'default row'. row_log_table_apply_convert_mrec(): Replace 'default row' values if needed. In the temporary file that is applied by row_log_table_apply(), we must identify whether the records contain the extra header for instantly added columns. For now, we will allocate an additional byte for this for ROW_T_INSERT and ROW_T_UPDATE records when the source table has been subject to instant ADD COLUMN. The ROW_T_DELETE records are fine, as they will be converted and will only contain 'core' columns (PRIMARY KEY and some system columns) that are converted from dtuple_t. rec_get_converted_size_temp(), rec_init_offsets_temp(), rec_convert_dtuple_to_temp(): Add the parameter 'status'. REC_INFO_DEFAULT_ROW = REC_INFO_MIN_REC_FLAG | REC_STATUS_COLUMNS_ADDED: An info_bits constant for distinguishing the 'default row' record. rec_comp_status_t: An enum of the status bit values. rec_leaf_format: An enum that replaces the bool parameter of rec_init_offsets_comp_ordinary().
8 years ago
MDEV-21907: InnoDB: Enable -Wconversion on clang and GCC The -Wconversion in GCC seems to be stricter than in clang. GCC at least since version 4.4.7 issues truncation warnings for assignments to bitfields, while clang 10 appears to only issue warnings when the sizes in bytes rounded to the nearest integer powers of 2 are different. Before GCC 10.0.0, -Wconversion required more casts and would not allow some operations, such as x<<=1 or x+=1 on a data type that is narrower than int. GCC 5 (but not GCC 4, GCC 6, or any later version) is complaining about x|=y even when x and y are compatible types that are narrower than int. Hence, we must rewrite some x|=y as x=static_cast<byte>(x|y) or similar, or we must disable -Wconversion. In GCC 6 and later, the warning for assigning wider to bitfields that are narrower than 8, 16, or 32 bits can be suppressed by applying a bitwise & with the exact bitmask of the bitfield. For older GCC, we must disable -Wconversion for GCC 4 or 5 in such cases. The bitwise negation operator appears to promote short integers to a wider type, and hence we must add explicit truncation casts around them. Microsoft Visual C does not allow a static_cast to truncate a constant, such as static_cast<byte>(1) truncating int. Hence, we will use the constructor-style cast byte(~1) for such cases. This has been tested at least with GCC 4.8.5, 5.4.0, 7.4.0, 9.2.1, 10.0.0, clang 9.0.1, 10.0.0, and MSVC 14.22.27905 (Microsoft Visual Studio 2019) on 64-bit and 32-bit targets (IA-32, AMD64, POWER 8, POWER 9, ARMv8).
6 years ago
MDEV-12288 Reset DB_TRX_ID when the history is removed, to speed up MVCC Let InnoDB purge reset DB_TRX_ID,DB_ROLL_PTR when the history is removed. [TODO: It appears that the resetting is not taking place as often as it could be. We should test that a simple INSERT should eventually cause row_purge_reset_trx_id() to be invoked unless DROP TABLE is invoked soon enough.] The InnoDB clustered index record system columns DB_TRX_ID,DB_ROLL_PTR are used by multi-versioning. After the history is no longer needed, these columns can safely be reset to 0 and 1<<55 (to indicate a fresh insert). When a reader sees 0 in the DB_TRX_ID column, it can instantly determine that the record is present the read view. There is no need to acquire the transaction system mutex to check if the transaction exists, because writes can never be conducted by a transaction whose ID is 0. The persistent InnoDB undo log used to be split into two parts: insert_undo and update_undo. The insert_undo log was discarded at transaction commit or rollback, and the update_undo log was processed by the purge subsystem. As part of this change, we will only generate a single undo log for new transactions, and the purge subsystem will reset the DB_TRX_ID whenever a clustered index record is touched. That is, all persistent undo log will be preserved at transaction commit or rollback, to be removed by purge. The InnoDB redo log format is changed in two ways: We remove the redo log record type MLOG_UNDO_HDR_REUSE, and we introduce the MLOG_ZIP_WRITE_TRX_ID record for updating the DB_TRX_ID,DB_ROLL_PTR in a ROW_FORMAT=COMPRESSED table. This is also changing the format of persistent InnoDB data files: undo log and clustered index leaf page records. It will still be possible via import and export to exchange data files with earlier versions of MariaDB. The change to clustered index leaf page records is simple: we allow DB_TRX_ID to be 0. When it comes to the undo log, we must be able to upgrade from earlier MariaDB versions after a clean shutdown (no redo log to apply). While it would be nice to perform a slow shutdown (innodb_fast_shutdown=0) before an upgrade, to empty the undo logs, we cannot assume that this has been done. So, separate insert_undo log may exist for recovered uncommitted transactions. These transactions may be automatically rolled back, or they may be in XA PREPARE state, in which case InnoDB will preserve the transaction until an explicit XA COMMIT or XA ROLLBACK. Upgrade has been tested by starting up MariaDB 10.2 with ./mysql-test-run --manual-gdb innodb.read_only_recovery and then starting up this patched server with and without --innodb-read-only. trx_undo_ptr_t::undo: Renamed from update_undo. trx_undo_ptr_t::old_insert: Renamed from insert_undo. trx_rseg_t::undo_list: Renamed from update_undo_list. trx_rseg_t::undo_cached: Merged from update_undo_cached and insert_undo_cached. trx_rseg_t::old_insert_list: Renamed from insert_undo_list. row_purge_reset_trx_id(): New function to reset the columns. This will be called for all undo processing in purge that does not remove the clustered index record. trx_undo_update_rec_get_update(): Allow trx_id=0 when copying the old DB_TRX_ID of the record to the undo log. ReadView::changes_visible(): Allow id==0. (Return true for it. This is what speeds up the MVCC.) row_vers_impl_x_locked_low(), row_vers_build_for_semi_consistent_read(): Implement a fast path for DB_TRX_ID=0. Always initialize the TRX_UNDO_PAGE_TYPE to 0. Remove undo->type. MLOG_UNDO_HDR_REUSE: Remove. This changes the redo log format! innobase_start_or_create_for_mysql(): Set srv_undo_sources before starting any transactions. The parsing of the MLOG_ZIP_WRITE_TRX_ID record was successfully tested by running the following: ./mtr --parallel=auto --mysqld=--debug=d,ib_log innodb_zip.bug56680 grep MLOG_ZIP_WRITE_TRX_ID var/*/log/mysqld.1.err
8 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
10 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
MDEV-20950 Reduce size of record offsets offset_t: this is a type which represents one record offset. It's unsigned short int. a lot of functions: replace ulint with offset_t btr_pcur_restore_position_func(), page_validate(), row_ins_scan_sec_index_for_duplicate(), row_upd_clust_rec_by_insert_inherit_func(), row_vers_impl_x_locked_low(), trx_undo_prev_version_build(): allocate record offsets on the stack instead of waiting for rec_get_offsets() to allocate it from mem_heap_t. So, reducing memory allocations. RECORD_OFFSET, INDEX_OFFSET: now it's less convenient to store pointers in offset_t* array. One pointer occupies now several offset_t. And those constant are start indexes into array to places where to store pointer values REC_OFFS_HEADER_SIZE: adjusted for the new reality REC_OFFS_NORMAL_SIZE: increase size from 100 to 300 which means less heap allocations. And sizeof(offset_t[REC_OFFS_NORMAL_SIZE]) now is 600 bytes which is smaller than previous 800 bytes. REC_OFFS_SEC_INDEX_SIZE: adjusted for the new reality rem0rec.h, rem0rec.ic, rem0rec.cc: various arguments, return values and local variables types were changed to fix numerous integer conversions issues. enum field_type_t: offset types concept was introduces which replaces old offset flags stuff. Like in earlier version, 2 upper bits are used to store offset type. And this enum represents those types. REC_OFFS_SQL_NULL, REC_OFFS_MASK: removed get_type(), set_type(), get_value(), combine(): these are convenience functions to work with offsets and it's types rec_offs_base()[0]: still uses an old scheme with flags REC_OFFS_COMPACT and REC_OFFS_EXTERNAL rec_offs_base()[i]: these have type offset_t now. Two upper bits contains type.
6 years ago
20 years ago
MDEV-11369 Instant ADD COLUMN for InnoDB For InnoDB tables, adding, dropping and reordering columns has required a rebuild of the table and all its indexes. Since MySQL 5.6 (and MariaDB 10.0) this has been supported online (LOCK=NONE), allowing concurrent modification of the tables. This work revises the InnoDB ROW_FORMAT=REDUNDANT, ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC so that columns can be appended instantaneously, with only minor changes performed to the table structure. The counter innodb_instant_alter_column in INFORMATION_SCHEMA.GLOBAL_STATUS is incremented whenever a table rebuild operation is converted into an instant ADD COLUMN operation. ROW_FORMAT=COMPRESSED tables will not support instant ADD COLUMN. Some usability limitations will be addressed in subsequent work: MDEV-13134 Introduce ALTER TABLE attributes ALGORITHM=NOCOPY and ALGORITHM=INSTANT MDEV-14016 Allow instant ADD COLUMN, ADD INDEX, LOCK=NONE The format of the clustered index (PRIMARY KEY) is changed as follows: (1) The FIL_PAGE_TYPE of the root page will be FIL_PAGE_TYPE_INSTANT, and a new field PAGE_INSTANT will contain the original number of fields in the clustered index ('core' fields). If instant ADD COLUMN has not been used or the table becomes empty, or the very first instant ADD COLUMN operation is rolled back, the fields PAGE_INSTANT and FIL_PAGE_TYPE will be reset to 0 and FIL_PAGE_INDEX. (2) A special 'default row' record is inserted into the leftmost leaf, between the page infimum and the first user record. This record is distinguished by the REC_INFO_MIN_REC_FLAG, and it is otherwise in the same format as records that contain values for the instantly added columns. This 'default row' always has the same number of fields as the clustered index according to the table definition. The values of 'core' fields are to be ignored. For other fields, the 'default row' will contain the default values as they were during the ALTER TABLE statement. (If the column default values are changed later, those values will only be stored in the .frm file. The 'default row' will contain the original evaluated values, which must be the same for every row.) The 'default row' must be completely hidden from higher-level access routines. Assertions have been added to ensure that no 'default row' is ever present in the adaptive hash index or in locked records. The 'default row' is never delete-marked. (3) In clustered index leaf page records, the number of fields must reside between the number of 'core' fields (dict_index_t::n_core_fields introduced in this work) and dict_index_t::n_fields. If the number of fields is less than dict_index_t::n_fields, the missing fields are replaced with the column value of the 'default row'. Note: The number of fields in the record may shrink if some of the last instantly added columns are updated to the value that is in the 'default row'. The function btr_cur_trim() implements this 'compression' on update and rollback; dtuple::trim() implements it on insert. (4) In ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC records, the new status value REC_STATUS_COLUMNS_ADDED will indicate the presence of a new record header that will encode n_fields-n_core_fields-1 in 1 or 2 bytes. (In ROW_FORMAT=REDUNDANT records, the record header always explicitly encodes the number of fields.) We introduce the undo log record type TRX_UNDO_INSERT_DEFAULT for covering the insert of the 'default row' record when instant ADD COLUMN is used for the first time. Subsequent instant ADD COLUMN can use TRX_UNDO_UPD_EXIST_REC. This is joint work with Vin Chen (陈福荣) from Tencent. The design that was discussed in April 2017 would not have allowed import or export of data files, because instead of the 'default row' it would have introduced a data dictionary table. The test rpl.rpl_alter_instant is exactly as contributed in pull request #408. The test innodb.instant_alter is based on a contributed test. The redo log record format changes for ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPACT are as contributed. (With this change present, crash recovery from MariaDB 10.3.1 will fail in spectacular ways!) Also the semantics of higher-level redo log records that modify the PAGE_INSTANT field is changed. The redo log format version identifier was already changed to LOG_HEADER_FORMAT_CURRENT=103 in MariaDB 10.3.1. Everything else has been rewritten by me. Thanks to Elena Stepanova, the code has been tested extensively. When rolling back an instant ADD COLUMN operation, we must empty the PAGE_FREE list after deleting or shortening the 'default row' record, by calling either btr_page_empty() or btr_page_reorganize(). We must know the size of each entry in the PAGE_FREE list. If rollback left a freed copy of the 'default row' in the PAGE_FREE list, we would be unable to determine its size (if it is in ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC) because it would contain more fields than the rolled-back definition of the clustered index. UNIV_SQL_DEFAULT: A new special constant that designates an instantly added column that is not present in the clustered index record. len_is_stored(): Check if a length is an actual length. There are two magic length values: UNIV_SQL_DEFAULT, UNIV_SQL_NULL. dict_col_t::def_val: The 'default row' value of the column. If the column is not added instantly, def_val.len will be UNIV_SQL_DEFAULT. dict_col_t: Add the accessors is_virtual(), is_nullable(), is_instant(), instant_value(). dict_col_t::remove_instant(): Remove the 'instant ADD' status of a column. dict_col_t::name(const dict_table_t& table): Replaces dict_table_get_col_name(). dict_index_t::n_core_fields: The original number of fields. For secondary indexes and if instant ADD COLUMN has not been used, this will be equal to dict_index_t::n_fields. dict_index_t::n_core_null_bytes: Number of bytes needed to represent the null flags; usually equal to UT_BITS_IN_BYTES(n_nullable). dict_index_t::NO_CORE_NULL_BYTES: Magic value signalling that n_core_null_bytes was not initialized yet from the clustered index root page. dict_index_t: Add the accessors is_instant(), is_clust(), get_n_nullable(), instant_field_value(). dict_index_t::instant_add_field(): Adjust clustered index metadata for instant ADD COLUMN. dict_index_t::remove_instant(): Remove the 'instant ADD' status of a clustered index when the table becomes empty, or the very first instant ADD COLUMN operation is rolled back. dict_table_t: Add the accessors is_instant(), is_temporary(), supports_instant(). dict_table_t::instant_add_column(): Adjust metadata for instant ADD COLUMN. dict_table_t::rollback_instant(): Adjust metadata on the rollback of instant ADD COLUMN. prepare_inplace_alter_table_dict(): First create the ctx->new_table, and only then decide if the table really needs to be rebuilt. We must split the creation of table or index metadata from the creation of the dictionary table records and the creation of the data. In this way, we can transform a table-rebuilding operation into an instant ADD COLUMN operation. Dictionary objects will only be added to cache when table rebuilding or index creation is needed. The ctx->instant_table will never be added to cache. dict_table_t::add_to_cache(): Modified and renamed from dict_table_add_to_cache(). Do not modify the table metadata. Let the callers invoke dict_table_add_system_columns() and if needed, set can_be_evicted. dict_create_sys_tables_tuple(), dict_create_table_step(): Omit the system columns (which will now exist in the dict_table_t object already at this point). dict_create_table_step(): Expect the callers to invoke dict_table_add_system_columns(). pars_create_table(): Before creating the table creation execution graph, invoke dict_table_add_system_columns(). row_create_table_for_mysql(): Expect all callers to invoke dict_table_add_system_columns(). create_index_dict(): Replaces row_merge_create_index_graph(). innodb_update_n_cols(): Renamed from innobase_update_n_virtual(). Call my_error() if an error occurs. btr_cur_instant_init(), btr_cur_instant_init_low(), btr_cur_instant_root_init(): Load additional metadata from the clustered index and set dict_index_t::n_core_null_bytes. This is invoked when table metadata is first loaded into the data dictionary. dict_boot(): Initialize n_core_null_bytes for the four hard-coded dictionary tables. dict_create_index_step(): Initialize n_core_null_bytes. This is executed as part of CREATE TABLE. dict_index_build_internal_clust(): Initialize n_core_null_bytes to NO_CORE_NULL_BYTES if table->supports_instant(). row_create_index_for_mysql(): Initialize n_core_null_bytes for CREATE TEMPORARY TABLE. commit_cache_norebuild(): Call the code to rename or enlarge columns in the cache only if instant ADD COLUMN is not being used. (Instant ADD COLUMN would copy all column metadata from instant_table to old_table, including the names and lengths.) PAGE_INSTANT: A new 13-bit field for storing dict_index_t::n_core_fields. This is repurposing the 16-bit field PAGE_DIRECTION, of which only the least significant 3 bits were used. The original byte containing PAGE_DIRECTION will be accessible via the new constant PAGE_DIRECTION_B. page_get_instant(), page_set_instant(): Accessors for the PAGE_INSTANT. page_ptr_get_direction(), page_get_direction(), page_ptr_set_direction(): Accessors for PAGE_DIRECTION. page_direction_reset(): Reset PAGE_DIRECTION, PAGE_N_DIRECTION. page_direction_increment(): Increment PAGE_N_DIRECTION and set PAGE_DIRECTION. rec_get_offsets(): Use the 'leaf' parameter for non-debug purposes, and assume that heap_no is always set. Initialize all dict_index_t::n_fields for ROW_FORMAT=REDUNDANT records, even if the record contains fewer fields. rec_offs_make_valid(): Add the parameter 'leaf'. rec_copy_prefix_to_dtuple(): Assert that the tuple is only built on the core fields. Instant ADD COLUMN only applies to the clustered index, and we should never build a search key that has more than the PRIMARY KEY and possibly DB_TRX_ID,DB_ROLL_PTR. All these columns are always present. dict_index_build_data_tuple(): Remove assertions that would be duplicated in rec_copy_prefix_to_dtuple(). rec_init_offsets(): Support ROW_FORMAT=REDUNDANT records whose number of fields is between n_core_fields and n_fields. cmp_rec_rec_with_match(): Implement the comparison between two MIN_REC_FLAG records. trx_t::in_rollback: Make the field available in non-debug builds. trx_start_for_ddl_low(): Remove dangerous error-tolerance. A dictionary transaction must be flagged as such before it has generated any undo log records. This is because trx_undo_assign_undo() will mark the transaction as a dictionary transaction in the undo log header right before the very first undo log record is being written. btr_index_rec_validate(): Account for instant ADD COLUMN row_undo_ins_remove_clust_rec(): On the rollback of an insert into SYS_COLUMNS, revert instant ADD COLUMN in the cache by removing the last column from the table and the clustered index. row_search_on_row_ref(), row_undo_mod_parse_undo_rec(), row_undo_mod(), trx_undo_update_rec_get_update(): Handle the 'default row' as a special case. dtuple_t::trim(index): Omit a redundant suffix of an index tuple right before insert or update. After instant ADD COLUMN, if the last fields of a clustered index tuple match the 'default row', there is no need to store them. While trimming the entry, we must hold a page latch, so that the table cannot be emptied and the 'default row' be deleted. btr_cur_optimistic_update(), btr_cur_pessimistic_update(), row_upd_clust_rec_by_insert(), row_ins_clust_index_entry_low(): Invoke dtuple_t::trim() if needed. row_ins_clust_index_entry(): Restore dtuple_t::n_fields after calling row_ins_clust_index_entry_low(). rec_get_converted_size(), rec_get_converted_size_comp(): Allow the number of fields to be between n_core_fields and n_fields. Do not support infimum,supremum. They are never supposed to be stored in dtuple_t, because page creation nowadays uses a lower-level method for initializing them. rec_convert_dtuple_to_rec_comp(): Assign the status bits based on the number of fields. btr_cur_trim(): In an update, trim the index entry as needed. For the 'default row', handle rollback specially. For user records, omit fields that match the 'default row'. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): Skip locking and adaptive hash index for the 'default row'. row_log_table_apply_convert_mrec(): Replace 'default row' values if needed. In the temporary file that is applied by row_log_table_apply(), we must identify whether the records contain the extra header for instantly added columns. For now, we will allocate an additional byte for this for ROW_T_INSERT and ROW_T_UPDATE records when the source table has been subject to instant ADD COLUMN. The ROW_T_DELETE records are fine, as they will be converted and will only contain 'core' columns (PRIMARY KEY and some system columns) that are converted from dtuple_t. rec_get_converted_size_temp(), rec_init_offsets_temp(), rec_convert_dtuple_to_temp(): Add the parameter 'status'. REC_INFO_DEFAULT_ROW = REC_INFO_MIN_REC_FLAG | REC_STATUS_COLUMNS_ADDED: An info_bits constant for distinguishing the 'default row' record. rec_comp_status_t: An enum of the status bit values. rec_leaf_format: An enum that replaces the bool parameter of rec_init_offsets_comp_ordinary().
8 years ago
20 years ago
MDEV-15662 Instant DROP COLUMN or changing the order of columns Allow ADD COLUMN anywhere in a table, not only adding as the last column. Allow instant DROP COLUMN and instant changing the order of columns. The added columns will always be added last in clustered index records. In new records, instantly dropped columns will be stored as NULL or empty when possible. Information about dropped and reordered columns will be written in a metadata BLOB (mblob), which is stored before the first 'user' field in the hidden metadata record at the start of the clustered index. The presence of mblob is indicated by setting the delete-mark flag in the metadata record. The metadata BLOB stores the number of clustered index fields, followed by an array of column information for each field. For dropped columns, we store the NOT NULL flag, the fixed length, and for variable-length columns, whether the maximum length exceeded 255 bytes. For non-dropped columns, we store the column position. Unlike with MDEV-11369, when a table becomes empty, it cannot be converted back to the canonical format. The reason for this is that other threads may hold cached objects such as row_prebuilt_t::ins_node that could refer to dropped or reordered index fields. For instant DROP COLUMN and ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC, we must store the n_core_null_bytes in the root page, so that the chain of node pointer records can be followed in order to reach the leftmost leaf page where the metadata record is located. If the mblob is present, we will zero-initialize the strings "infimum" and "supremum" in the root page, and use the last byte of "supremum" for storing the number of null bytes (which are allocated but useless on node pointer pages). This is necessary for btr_cur_instant_init_metadata() to be able to navigate to the mblob. If the PRIMARY KEY contains any variable-length column and some nullable columns were instantly dropped, the dict_index_t::n_nullable in the data dictionary could be smaller than it actually is in the non-leaf pages. Because of this, the non-leaf pages could use more bytes for the null flags than the data dictionary expects, and we could be reading the lengths of the variable-length columns from the wrong offset, and thus reading the child page number from wrong place. This is the result of two design mistakes that involve unnecessary storage of data: First, it is nonsense to store any data fields for the leftmost node pointer records, because the comparisons would be resolved by the MIN_REC_FLAG alone. Second, there cannot be any null fields in the clustered index node pointer fields, but we nevertheless reserve space for all the null flags. Limitations (future work): MDEV-17459 Allow instant ALTER TABLE even if FULLTEXT INDEX exists MDEV-17468 Avoid table rebuild on operations on generated columns MDEV-17494 Refuse ALGORITHM=INSTANT when the row size is too large btr_page_reorganize_low(): Preserve any metadata in the root page. Call lock_move_reorganize_page() only after restoring the "infimum" and "supremum" records, to avoid a memcmp() assertion failure. dict_col_t::DROPPED: Magic value for dict_col_t::ind. dict_col_t::clear_instant(): Renamed from dict_col_t::remove_instant(). Do not assert that the column was instantly added, because we sometimes call this unconditionally for all columns. Convert an instantly added column to a "core column". The old name remove_instant() could be mistaken to refer to "instant DROP COLUMN". dict_col_t::is_added(): Rename from dict_col_t::is_instant(). dtype_t::metadata_blob_init(): Initialize the mblob data type. dtuple_t::is_metadata(), dtuple_t::is_alter_metadata(), upd_t::is_metadata(), upd_t::is_alter_metadata(): Check if info_bits refer to a metadata record. dict_table_t::instant: Metadata about dropped or reordered columns. dict_table_t::prepare_instant(): Prepare ha_innobase_inplace_ctx::instant_table for instant ALTER TABLE. innobase_instant_try() will pass this to dict_table_t::instant_column(). On rollback, dict_table_t::rollback_instant() will be called. dict_table_t::instant_column(): Renamed from instant_add_column(). Add the parameter col_map so that columns can be reordered. Copy and adjust v_cols[] as well. dict_table_t::find(): Find an old column based on a new column number. dict_table_t::serialise_columns(), dict_table_t::deserialise_columns(): Convert the mblob. dict_index_t::instant_metadata(): Create the metadata record for instant ALTER TABLE. Invoke dict_table_t::serialise_columns(). dict_index_t::reconstruct_fields(): Invoked by dict_table_t::deserialise_columns(). dict_index_t::clear_instant_alter(): Move the fields for the dropped columns to the end, and sort the surviving index fields in ascending order of column position. ha_innobase::check_if_supported_inplace_alter(): Do not allow adding a FTS_DOC_ID column if a hidden FTS_DOC_ID column exists due to FULLTEXT INDEX. (This always required ALGORITHM=COPY.) instant_alter_column_possible(): Add a parameter for InnoDB table, to check for additional conditions, such as the maximum number of index fields. ha_innobase_inplace_ctx::first_alter_pos: The first column whose position is affected by instant ADD, DROP, or changing the order of columns. innobase_build_col_map(): Skip added virtual columns. prepare_inplace_add_virtual(): Correctly compute num_to_add_vcol. Remove some unnecessary code. Note that the call to innodb_base_col_setup() should be executed later. commit_try_norebuild(): If ctx->is_instant(), let the virtual columns be added or dropped by innobase_instant_try(). innobase_instant_try(): Fill in a zero default value for the hidden column FTS_DOC_ID (to reduce the work needed in MDEV-17459). If any columns were dropped or reordered (or added not last), delete any SYS_COLUMNS records for the following columns, and insert SYS_COLUMNS records for all subsequent stored columns as well as for all virtual columns. If any virtual column is dropped, rewrite all virtual column metadata. Use a shortcut only for adding virtual columns. This is because innobase_drop_virtual_try() assumes that the dropped virtual columns still exist in ctx->old_table. innodb_update_cols(): Renamed from innodb_update_n_cols(). innobase_add_one_virtual(), innobase_insert_sys_virtual(): Change the return type to bool, and invoke my_error() when detecting an error. innodb_insert_sys_columns(): Insert a record into SYS_COLUMNS. Refactored from innobase_add_one_virtual() and innobase_instant_add_col(). innobase_instant_add_col(): Replace the parameter dfield with type. innobase_instant_drop_cols(): Drop matching columns from SYS_COLUMNS and all columns from SYS_VIRTUAL. innobase_add_virtual_try(), innobase_drop_virtual_try(): Let the caller invoke innodb_update_cols(). innobase_rename_column_try(): Skip dropped columns. commit_cache_norebuild(): Update table->fts->doc_col. dict_mem_table_col_rename_low(): Skip dropped columns. trx_undo_rec_get_partial_row(): Skip dropped columns. trx_undo_update_rec_get_update(): Handle the metadata BLOB correctly. trx_undo_page_report_modify(): Avoid out-of-bounds access to record fields. Log metadata records consistently. Apparently, the first fields of a clustered index may be updated in an update_undo vector when the index is ID_IND of SYS_FOREIGN, as part of renaming the table during ALTER TABLE. Normally, updates of the PRIMARY KEY should be logged as delete-mark and an insert. row_undo_mod_parse_undo_rec(), row_purge_parse_undo_rec(): Use trx_undo_metadata. row_undo_mod_clust_low(): On metadata rollback, roll back the root page too. row_undo_mod_clust(): Relax an assertion. The delete-mark flag was repurposed for ALTER TABLE metadata records. row_rec_to_index_entry_impl(): Add the template parameter mblob and the optional parameter info_bits for specifying the desired new info bits. For the metadata tuple, allow conversion between the original format (ADD COLUMN only) and the generic format (with hidden BLOB). Add the optional parameter "pad" to determine whether the tuple should be padded to the index fields (on ALTER TABLE it should), or whether it should remain at its original size (on rollback). row_build_index_entry_low(): Clean up the code, removing redundant variables and conditions. For instantly dropped columns, generate a dummy value that is NULL, the empty string, or a fixed length of NUL bytes, depending on the type of the dropped column. row_upd_clust_rec_by_insert_inherit_func(): On the update of PRIMARY KEY of a record that contained a dropped column whose value was stored externally, we will be inserting a dummy NULL or empty string value to the field of the dropped column. The externally stored column would eventually be dropped when purge removes the delete-marked record for the old PRIMARY KEY value. btr_index_rec_validate(): Recognize the metadata record. btr_discard_only_page_on_level(): Preserve the generic instant ALTER TABLE metadata. btr_set_instant(): Replaces page_set_instant(). This sets a clustered index root page to the appropriate format, or upgrades from the MDEV-11369 instant ADD COLUMN to generic ALTER TABLE format. btr_cur_instant_init_low(): Read and validate the metadata BLOB page before reconstructing the dictionary information based on it. btr_cur_instant_init_metadata(): Do not read any lengths from the metadata record header before reading the BLOB. At this point, we would not actually know how many nullable fields the metadata record contains. btr_cur_instant_root_init(): Initialize n_core_null_bytes in one of two possible ways. btr_cur_trim(): Handle the mblob record. row_metadata_to_tuple(): Convert a metadata record to a data tuple, based on the new info_bits of the metadata record. btr_cur_pessimistic_update(): Invoke row_metadata_to_tuple() if needed. Invoke dtuple_convert_big_rec() for metadata records if the record is too large, or if the mblob is not yet marked as externally stored. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): When the last user record is deleted, do not delete the generic instant ALTER TABLE metadata record. Only delete MDEV-11369 instant ADD COLUMN metadata records. btr_cur_optimistic_insert(): Avoid unnecessary computation of rec_size. btr_pcur_store_position(): Allow a logically empty page to contain a metadata record for generic ALTER TABLE. REC_INFO_DEFAULT_ROW_ADD: Renamed from REC_INFO_DEFAULT_ROW. This is for the old instant ADD COLUMN (MDEV-11369) only. REC_INFO_DEFAULT_ROW_ALTER: The more generic metadata record, with additional information for dropped or reordered columns. rec_info_bits_valid(): Remove. The only case when this would fail is when the record is the generic ALTER TABLE metadata record. rec_is_alter_metadata(): Check if a record is the metadata record for instant ALTER TABLE (other than ADD COLUMN). NOTE: This function must not be invoked on node pointer records, because the delete-mark flag in those records may be set (it is garbage), and then a debug assertion could fail because index->is_instant() does not necessarily hold. rec_is_add_metadata(): Check if a record is MDEV-11369 ADD COLUMN metadata record (not more generic instant ALTER TABLE). rec_get_converted_size_comp_prefix_low(): Assume that the metadata field will be stored externally. In dtuple_convert_big_rec() during the rec_get_converted_size() call, it would not be there yet. rec_get_converted_size_comp(): Replace status,fields,n_fields with tuple. rec_init_offsets_comp_ordinary(), rec_get_converted_size_comp_prefix_low(), rec_convert_dtuple_to_rec_comp(): Add template<bool mblob = false>. With mblob=true, process a record with a metadata BLOB. rec_copy_prefix_to_buf(): Assert that no fields beyond the key and system columns are being copied. Exclude the metadata BLOB field. rec_convert_dtuple_to_metadata_comp(): Convert an alter metadata tuple into a record. row_upd_index_replace_metadata(): Apply an update vector to an alter_metadata tuple. row_log_allocate(): Replace dict_index_t::is_instant() with a more appropriate condition that ignores dict_table_t::instant. Only a table on which the MDEV-11369 ADD COLUMN was performed can "lose its instantness" when it becomes empty. After instant DROP COLUMN or reordering columns, we cannot simply convert the table to the canonical format, because the data dictionary cache and all possibly existing references to it from other client connection threads would have to be adjusted. row_quiesce_write_index_fields(): Do not crash when the table contains an instantly dropped column. Thanks to Thirunarayanan Balathandayuthapani for discussing the design and implementing an initial prototype of this. Thanks to Matthias Leich for testing.
7 years ago
20 years ago
20 years ago
20 years ago
MDEV-15662 Instant DROP COLUMN or changing the order of columns Allow ADD COLUMN anywhere in a table, not only adding as the last column. Allow instant DROP COLUMN and instant changing the order of columns. The added columns will always be added last in clustered index records. In new records, instantly dropped columns will be stored as NULL or empty when possible. Information about dropped and reordered columns will be written in a metadata BLOB (mblob), which is stored before the first 'user' field in the hidden metadata record at the start of the clustered index. The presence of mblob is indicated by setting the delete-mark flag in the metadata record. The metadata BLOB stores the number of clustered index fields, followed by an array of column information for each field. For dropped columns, we store the NOT NULL flag, the fixed length, and for variable-length columns, whether the maximum length exceeded 255 bytes. For non-dropped columns, we store the column position. Unlike with MDEV-11369, when a table becomes empty, it cannot be converted back to the canonical format. The reason for this is that other threads may hold cached objects such as row_prebuilt_t::ins_node that could refer to dropped or reordered index fields. For instant DROP COLUMN and ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC, we must store the n_core_null_bytes in the root page, so that the chain of node pointer records can be followed in order to reach the leftmost leaf page where the metadata record is located. If the mblob is present, we will zero-initialize the strings "infimum" and "supremum" in the root page, and use the last byte of "supremum" for storing the number of null bytes (which are allocated but useless on node pointer pages). This is necessary for btr_cur_instant_init_metadata() to be able to navigate to the mblob. If the PRIMARY KEY contains any variable-length column and some nullable columns were instantly dropped, the dict_index_t::n_nullable in the data dictionary could be smaller than it actually is in the non-leaf pages. Because of this, the non-leaf pages could use more bytes for the null flags than the data dictionary expects, and we could be reading the lengths of the variable-length columns from the wrong offset, and thus reading the child page number from wrong place. This is the result of two design mistakes that involve unnecessary storage of data: First, it is nonsense to store any data fields for the leftmost node pointer records, because the comparisons would be resolved by the MIN_REC_FLAG alone. Second, there cannot be any null fields in the clustered index node pointer fields, but we nevertheless reserve space for all the null flags. Limitations (future work): MDEV-17459 Allow instant ALTER TABLE even if FULLTEXT INDEX exists MDEV-17468 Avoid table rebuild on operations on generated columns MDEV-17494 Refuse ALGORITHM=INSTANT when the row size is too large btr_page_reorganize_low(): Preserve any metadata in the root page. Call lock_move_reorganize_page() only after restoring the "infimum" and "supremum" records, to avoid a memcmp() assertion failure. dict_col_t::DROPPED: Magic value for dict_col_t::ind. dict_col_t::clear_instant(): Renamed from dict_col_t::remove_instant(). Do not assert that the column was instantly added, because we sometimes call this unconditionally for all columns. Convert an instantly added column to a "core column". The old name remove_instant() could be mistaken to refer to "instant DROP COLUMN". dict_col_t::is_added(): Rename from dict_col_t::is_instant(). dtype_t::metadata_blob_init(): Initialize the mblob data type. dtuple_t::is_metadata(), dtuple_t::is_alter_metadata(), upd_t::is_metadata(), upd_t::is_alter_metadata(): Check if info_bits refer to a metadata record. dict_table_t::instant: Metadata about dropped or reordered columns. dict_table_t::prepare_instant(): Prepare ha_innobase_inplace_ctx::instant_table for instant ALTER TABLE. innobase_instant_try() will pass this to dict_table_t::instant_column(). On rollback, dict_table_t::rollback_instant() will be called. dict_table_t::instant_column(): Renamed from instant_add_column(). Add the parameter col_map so that columns can be reordered. Copy and adjust v_cols[] as well. dict_table_t::find(): Find an old column based on a new column number. dict_table_t::serialise_columns(), dict_table_t::deserialise_columns(): Convert the mblob. dict_index_t::instant_metadata(): Create the metadata record for instant ALTER TABLE. Invoke dict_table_t::serialise_columns(). dict_index_t::reconstruct_fields(): Invoked by dict_table_t::deserialise_columns(). dict_index_t::clear_instant_alter(): Move the fields for the dropped columns to the end, and sort the surviving index fields in ascending order of column position. ha_innobase::check_if_supported_inplace_alter(): Do not allow adding a FTS_DOC_ID column if a hidden FTS_DOC_ID column exists due to FULLTEXT INDEX. (This always required ALGORITHM=COPY.) instant_alter_column_possible(): Add a parameter for InnoDB table, to check for additional conditions, such as the maximum number of index fields. ha_innobase_inplace_ctx::first_alter_pos: The first column whose position is affected by instant ADD, DROP, or changing the order of columns. innobase_build_col_map(): Skip added virtual columns. prepare_inplace_add_virtual(): Correctly compute num_to_add_vcol. Remove some unnecessary code. Note that the call to innodb_base_col_setup() should be executed later. commit_try_norebuild(): If ctx->is_instant(), let the virtual columns be added or dropped by innobase_instant_try(). innobase_instant_try(): Fill in a zero default value for the hidden column FTS_DOC_ID (to reduce the work needed in MDEV-17459). If any columns were dropped or reordered (or added not last), delete any SYS_COLUMNS records for the following columns, and insert SYS_COLUMNS records for all subsequent stored columns as well as for all virtual columns. If any virtual column is dropped, rewrite all virtual column metadata. Use a shortcut only for adding virtual columns. This is because innobase_drop_virtual_try() assumes that the dropped virtual columns still exist in ctx->old_table. innodb_update_cols(): Renamed from innodb_update_n_cols(). innobase_add_one_virtual(), innobase_insert_sys_virtual(): Change the return type to bool, and invoke my_error() when detecting an error. innodb_insert_sys_columns(): Insert a record into SYS_COLUMNS. Refactored from innobase_add_one_virtual() and innobase_instant_add_col(). innobase_instant_add_col(): Replace the parameter dfield with type. innobase_instant_drop_cols(): Drop matching columns from SYS_COLUMNS and all columns from SYS_VIRTUAL. innobase_add_virtual_try(), innobase_drop_virtual_try(): Let the caller invoke innodb_update_cols(). innobase_rename_column_try(): Skip dropped columns. commit_cache_norebuild(): Update table->fts->doc_col. dict_mem_table_col_rename_low(): Skip dropped columns. trx_undo_rec_get_partial_row(): Skip dropped columns. trx_undo_update_rec_get_update(): Handle the metadata BLOB correctly. trx_undo_page_report_modify(): Avoid out-of-bounds access to record fields. Log metadata records consistently. Apparently, the first fields of a clustered index may be updated in an update_undo vector when the index is ID_IND of SYS_FOREIGN, as part of renaming the table during ALTER TABLE. Normally, updates of the PRIMARY KEY should be logged as delete-mark and an insert. row_undo_mod_parse_undo_rec(), row_purge_parse_undo_rec(): Use trx_undo_metadata. row_undo_mod_clust_low(): On metadata rollback, roll back the root page too. row_undo_mod_clust(): Relax an assertion. The delete-mark flag was repurposed for ALTER TABLE metadata records. row_rec_to_index_entry_impl(): Add the template parameter mblob and the optional parameter info_bits for specifying the desired new info bits. For the metadata tuple, allow conversion between the original format (ADD COLUMN only) and the generic format (with hidden BLOB). Add the optional parameter "pad" to determine whether the tuple should be padded to the index fields (on ALTER TABLE it should), or whether it should remain at its original size (on rollback). row_build_index_entry_low(): Clean up the code, removing redundant variables and conditions. For instantly dropped columns, generate a dummy value that is NULL, the empty string, or a fixed length of NUL bytes, depending on the type of the dropped column. row_upd_clust_rec_by_insert_inherit_func(): On the update of PRIMARY KEY of a record that contained a dropped column whose value was stored externally, we will be inserting a dummy NULL or empty string value to the field of the dropped column. The externally stored column would eventually be dropped when purge removes the delete-marked record for the old PRIMARY KEY value. btr_index_rec_validate(): Recognize the metadata record. btr_discard_only_page_on_level(): Preserve the generic instant ALTER TABLE metadata. btr_set_instant(): Replaces page_set_instant(). This sets a clustered index root page to the appropriate format, or upgrades from the MDEV-11369 instant ADD COLUMN to generic ALTER TABLE format. btr_cur_instant_init_low(): Read and validate the metadata BLOB page before reconstructing the dictionary information based on it. btr_cur_instant_init_metadata(): Do not read any lengths from the metadata record header before reading the BLOB. At this point, we would not actually know how many nullable fields the metadata record contains. btr_cur_instant_root_init(): Initialize n_core_null_bytes in one of two possible ways. btr_cur_trim(): Handle the mblob record. row_metadata_to_tuple(): Convert a metadata record to a data tuple, based on the new info_bits of the metadata record. btr_cur_pessimistic_update(): Invoke row_metadata_to_tuple() if needed. Invoke dtuple_convert_big_rec() for metadata records if the record is too large, or if the mblob is not yet marked as externally stored. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): When the last user record is deleted, do not delete the generic instant ALTER TABLE metadata record. Only delete MDEV-11369 instant ADD COLUMN metadata records. btr_cur_optimistic_insert(): Avoid unnecessary computation of rec_size. btr_pcur_store_position(): Allow a logically empty page to contain a metadata record for generic ALTER TABLE. REC_INFO_DEFAULT_ROW_ADD: Renamed from REC_INFO_DEFAULT_ROW. This is for the old instant ADD COLUMN (MDEV-11369) only. REC_INFO_DEFAULT_ROW_ALTER: The more generic metadata record, with additional information for dropped or reordered columns. rec_info_bits_valid(): Remove. The only case when this would fail is when the record is the generic ALTER TABLE metadata record. rec_is_alter_metadata(): Check if a record is the metadata record for instant ALTER TABLE (other than ADD COLUMN). NOTE: This function must not be invoked on node pointer records, because the delete-mark flag in those records may be set (it is garbage), and then a debug assertion could fail because index->is_instant() does not necessarily hold. rec_is_add_metadata(): Check if a record is MDEV-11369 ADD COLUMN metadata record (not more generic instant ALTER TABLE). rec_get_converted_size_comp_prefix_low(): Assume that the metadata field will be stored externally. In dtuple_convert_big_rec() during the rec_get_converted_size() call, it would not be there yet. rec_get_converted_size_comp(): Replace status,fields,n_fields with tuple. rec_init_offsets_comp_ordinary(), rec_get_converted_size_comp_prefix_low(), rec_convert_dtuple_to_rec_comp(): Add template<bool mblob = false>. With mblob=true, process a record with a metadata BLOB. rec_copy_prefix_to_buf(): Assert that no fields beyond the key and system columns are being copied. Exclude the metadata BLOB field. rec_convert_dtuple_to_metadata_comp(): Convert an alter metadata tuple into a record. row_upd_index_replace_metadata(): Apply an update vector to an alter_metadata tuple. row_log_allocate(): Replace dict_index_t::is_instant() with a more appropriate condition that ignores dict_table_t::instant. Only a table on which the MDEV-11369 ADD COLUMN was performed can "lose its instantness" when it becomes empty. After instant DROP COLUMN or reordering columns, we cannot simply convert the table to the canonical format, because the data dictionary cache and all possibly existing references to it from other client connection threads would have to be adjusted. row_quiesce_write_index_fields(): Do not crash when the table contains an instantly dropped column. Thanks to Thirunarayanan Balathandayuthapani for discussing the design and implementing an initial prototype of this. Thanks to Matthias Leich for testing.
7 years ago
12 years ago
20 years ago
branches/zip: Initialize dfield_t::ext as soon as possible. This should fix the bugs introduced in r1591. row_rec_to_index_entry_low(): Clear "n_ext". Do not allow it to be NULL. Add const qualifier to dict_index_t*. row_rec_to_index_entry(): Add the parameters "offsets" and "n_ext". btr_cur_optimistic_update(): Add an assertion that there are no externally stored columns. Remove the unreachable call to btr_cur_unmark_extern_fields() and the preceding unnecessary call to rec_get_offsets(). btr_push_update_extern_fields(): Remove the parameters index, offsets. Only report the additional externally stored columns of the update vector. row_build(), trx_undo_rec_get_partial_row(): Flag externally stored columns also with dfield_set_ext(). rec_copy_prefix_to_dtuple(): Assert that there are no externally stored columns in the prefix. row_build_row_ref(): Note and assert that the index is a secondary index, and assert that there are no externally stored columns. row_build_row_ref_fast(): Assert that there are no externally stored columns. rec_offs_get_n_alloc(): Expose the function. row_build_row_ref_in_tuple(): Assert that there are no externally stored columns in a record of a secondary index. row_build_row_ref_from_row(): Assert that there are no externally stored columns. row_upd_check_references_constraints(): Add the parameter offsets, to avoid a redundant call to rec_get_offsets(). row_upd_del_mark_clust_rec(): Add the parameter offsets. Remove duplicated code. row_ins_index_entry_set_vals(): Copy the external storage flag. sel_pop_prefetched_row(): Assert that there are no externally stored columns. row_scan_and_check_index(): Copy offsets to a temporary heap across the invocation of row_rec_to_index_entry().
18 years ago
20 years ago
20 years ago
MDEV-13498 DELETE with CASCADE constraints takes long time / MDEV-13246 MDEV-13498 is a performance regression that was introduced in MariaDB 10.2.2 by commit fec844aca88e1c6b9c36bb0b811e92d9d023ffb9 which introduced some Galera-specific conditions that were being evaluated even if the write-set replication was not enabled. MDEV-13246 Stale rows despite ON DELETE CASCADE constraint is a correctness regression that was introduced by the same commit. Especially the subcondition !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE) which is equivalent to !parent || que_node_get_type(parent) != QUE_NODE_UPDATE makes little sense. If parent==NULL, the evaluation would proceed to the std::find() expression, which would dereference parent. Because no SIGSEGV was observed related to this, we can conclude that parent!=NULL always holds. But then, the condition would be equivalent to que_node_get_type(parent) != QUE_NODE_UPDATE which would not make sense either, because the std::find() expression is actually assuming the opposite when casting parent to upd_node_t*. It looks like this condition never worked properly, or that it was never properly tested, or both. wsrep_must_process_fk(): Helper function to check if FOREIGN KEY constraints need to be processed. Only evaluate the costly std::find() expression when write-set replication is enabled. Also, rely on operator<<(std::ostream&, const id_name_t&) and operator<<(std::ostream&, const table_name_t&) for pretty-printing index and table names. row_upd_sec_index_entry(): Add !wsrep_thd_is_BF() to the condition. This is applying part of "Galera MW-369 FK fixes" https://github.com/codership/mysql-wsrep/commit/f37b79c6dab101310a45a9e8cb23c0f98716da52 that is described by the following part of the commit comment: additionally: skipping wsrep_row_upd_check_foreign_constraint if thd has BF, essentially is applier or replaying This FK check would be needed only for populating parent row FK keys in write set, so no use for appliers
8 years ago
MDEV-13498 DELETE with CASCADE constraints takes long time / MDEV-13246 MDEV-13498 is a performance regression that was introduced in MariaDB 10.2.2 by commit fec844aca88e1c6b9c36bb0b811e92d9d023ffb9 which introduced some Galera-specific conditions that were being evaluated even if the write-set replication was not enabled. MDEV-13246 Stale rows despite ON DELETE CASCADE constraint is a correctness regression that was introduced by the same commit. Especially the subcondition !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE) which is equivalent to !parent || que_node_get_type(parent) != QUE_NODE_UPDATE makes little sense. If parent==NULL, the evaluation would proceed to the std::find() expression, which would dereference parent. Because no SIGSEGV was observed related to this, we can conclude that parent!=NULL always holds. But then, the condition would be equivalent to que_node_get_type(parent) != QUE_NODE_UPDATE which would not make sense either, because the std::find() expression is actually assuming the opposite when casting parent to upd_node_t*. It looks like this condition never worked properly, or that it was never properly tested, or both. wsrep_must_process_fk(): Helper function to check if FOREIGN KEY constraints need to be processed. Only evaluate the costly std::find() expression when write-set replication is enabled. Also, rely on operator<<(std::ostream&, const id_name_t&) and operator<<(std::ostream&, const table_name_t&) for pretty-printing index and table names. row_upd_sec_index_entry(): Add !wsrep_thd_is_BF() to the condition. This is applying part of "Galera MW-369 FK fixes" https://github.com/codership/mysql-wsrep/commit/f37b79c6dab101310a45a9e8cb23c0f98716da52 that is described by the following part of the commit comment: additionally: skipping wsrep_row_upd_check_foreign_constraint if thd has BF, essentially is applier or replaying This FK check would be needed only for populating parent row FK keys in write set, so no use for appliers
8 years ago
20 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
10 years ago
20 years ago
20 years ago
20 years ago
MDEV-11415 Remove excessive undo logging during ALTER TABLE…ALGORITHM=COPY If a crash occurs during ALTER TABLE…ALGORITHM=COPY, InnoDB would spend a lot of time rolling back writes to the intermediate copy of the table. To reduce the amount of busy work done, a work-around was introduced in commit fd069e2bb36a3c1c1f26d65dd298b07e6d83ac8b in MySQL 4.1.8 and 5.0.2, to commit the transaction after every 10,000 inserted rows. A proper fix would have been to disable the undo logging altogether and to simply drop the intermediate copy of the table on subsequent server startup. This is what happens in MariaDB 10.3 with MDEV-14717,MDEV-14585. In MariaDB 10.2, the intermediate copy of the table would be left behind with a name starting with the string #sql. This is a backport of a bug fix from MySQL 8.0.0 to MariaDB, contributed by jixianliang <271365745@qq.com>. Unlike recent MySQL, MariaDB supports ALTER IGNORE. For that operation InnoDB must for now keep the undo logging enabled, so that the latest row can be rolled back in case of an error. In Galera cluster, the LOAD DATA statement will retain the existing behaviour and commit the transaction after every 10,000 rows if the parameter wsrep_load_data_splitting=ON is set. The logic to do so (the wsrep_load_data_split() function and the call handler::extra(HA_EXTRA_FAKE_START_STMT)) are joint work by Ji Xianliang and Marko Mäkelä. The original fix: Author: Thirunarayanan Balathandayuthapani <thirunarayanan.balathandayuth@oracle.com> Date: Wed Dec 2 16:09:15 2015 +0530 Bug#17479594 AVOID INTERMEDIATE COMMIT WHILE DOING ALTER TABLE ALGORITHM=COPY Problem: During ALTER TABLE, we commit and restart the transaction for every 10,000 rows, so that the rollback after recovery would not take so long. Fix: Suppress the undo logging during copy alter operation. If fts_index is present then insert directly into fts auxiliary table rather than doing at commit time. ha_innobase::num_write_row: Remove the variable. ha_innobase::write_row(): Remove the hack for committing every 10000 rows. row_lock_table_for_mysql(): Remove the extra 2 parameters. lock_get_src_table(), lock_is_table_exclusive(): Remove. Reviewed-by: Marko Mäkelä <marko.makela@oracle.com> Reviewed-by: Shaohua Wang <shaohua.wang@oracle.com> Reviewed-by: Jon Olav Hauglid <jon.hauglid@oracle.com>
8 years ago
20 years ago
20 years ago
20 years ago
MDEV-15250 UPSERT during ALTER TABLE results in 'Duplicate entry' error for alter - InnoDB DDL results in `Duplicate entry' if concurrent DML throws duplicate key error. The following scenario explains the problem connection con1: ALTER TABLE t1 FORCE; connection con2: INSERT INTO t1(pk, uk) VALUES (2, 2), (3, 2); In connection con2, InnoDB throws the 'DUPLICATE KEY' error because of unique index. Alter operation will throw the error when applying the concurrent DML log. - Inserting the duplicate key for unique index logs the insert operation for online ALTER TABLE. When insertion fails, transaction does rollback and it leads to logging of delete operation for online ALTER TABLE. While applying the insert log entries, alter operation encounters 'DUPLICATE KEY' error. - To avoid the above fake duplicate scenario, InnoDB should not write any log for online ALTER TABLE before DML transaction commit. - User thread which does DML can apply the online log if InnoDB ran out of online log and index is marked as completed. Set online log error if apply phase encountered any error. It can also clear all other indexes log, marks the newly added indexes as corrupted. - Removed the old online code which was a part of DML operations commit_inplace_alter_table() : Does apply the online log for the last batch of secondary index log and does frees the log for the completed index. trx_t::apply_online_log: Set to true while writing the undo log if the modified table has active DDL trx_t::apply_log(): Apply the DML changes to online DDL tables dict_table_t::is_active_ddl(): Returns true if the table has an active DDL dict_index_t::online_log_make_dummy(): Assign dummy value for clustered index online log to indicate the secondary indexes are being rebuild. dict_index_t::online_log_is_dummy(): Check whether the online log has dummy value ha_innobase_inplace_ctx::log_failure(): Handle the apply log failure for online DDL transaction row_log_mark_other_online_index_abort(): Clear out all other online index log after encountering the error during row_log_apply() row_log_get_error(): Get the error happened during row_log_apply() row_log_online_op(): Does apply the online log if index is completed and ran out of memory. Returns false if apply log fails UndorecApplier: Introduced a class to maintain the undo log record, latched undo buffer page, parse the undo log record, maintain the undo record type, info bits and update vector UndorecApplier::get_old_rec(): Get the correct version of the clustered index record that was modified by the current undo log record UndorecApplier::clear_undo_rec(): Clear the undo log related information after applying the undo log record UndorecApplier::log_update(): Handle the update, delete undo log and apply it on online indexes UndorecApplier::log_insert(): Handle the insert undo log and apply it on online indexes UndorecApplier::is_same(): Check whether the given roll pointer is generated by the current undo log record information trx_t::rollback_low(): Set apply_online_log for the transaction after partially rollbacked transaction has any active DDL prepare_inplace_alter_table_dict(): After allocating the online log, InnoDB does create fulltext common tables. Fulltext index doesn't allow the index to be online. So removed the dead code of online log removal Thanks to Marko Mäkelä for providing the initial prototype and Matthias Leich for testing the issue patiently.
4 years ago
20 years ago
MDEV-15053 Reduce buf_pool_t::mutex contention User-visible changes: The INFORMATION_SCHEMA views INNODB_BUFFER_PAGE and INNODB_BUFFER_PAGE_LRU will report a dummy value FLUSH_TYPE=0 and will no longer report the PAGE_STATE value READY_FOR_USE. We will remove some fields from buf_page_t and move much code to member functions of buf_pool_t and buf_page_t, so that the access rules of data members can be enforced consistently. Evicting or adding pages in buf_pool.LRU will remain covered by buf_pool.mutex. Evicting or adding pages in buf_pool.page_hash will remain covered by both buf_pool.mutex and the buf_pool.page_hash X-latch. After this fix, buf_pool.page_hash lookups can entirely avoid acquiring buf_pool.mutex, only relying on buf_pool.hash_lock_get() S-latch. Similarly, buf_flush_check_neighbors() can will rely solely on buf_pool.mutex, no buf_pool.page_hash latch at all. The buf_pool.mutex is rather contended in I/O heavy benchmarks, especially when the workload does not fit in the buffer pool. The first attempt to alleviate the contention was the buf_pool_t::mutex split in commit 4ed7082eefe56b3e97e0edefb3df76dd7ef5e858 which introduced buf_block_t::mutex, which we are now removing. Later, multiple instances of buf_pool_t were introduced in commit c18084f71b02ea707c6461353e6cfc15d7553bc6 and recently removed by us in commit 1a6f708ec594ac0ae2dd30db926ab07b100fa24b (MDEV-15058). UNIV_BUF_DEBUG: Remove. This option to enable some buffer pool related debugging in otherwise non-debug builds has not been used for years. Instead, we have been using UNIV_DEBUG, which is enabled in CMAKE_BUILD_TYPE=Debug. buf_block_t::mutex, buf_pool_t::zip_mutex: Remove. We can mainly rely on std::atomic and the buf_pool.page_hash latches, and in some cases depend on buf_pool.mutex or buf_pool.flush_list_mutex just like before. We must always release buf_block_t::lock before invoking unfix() or io_unfix(), to prevent a glitch where a block that was added to the buf_pool.free list would apper X-latched. See commit c5883debd6ef440a037011c11873b396923e93c5 how this glitch was finally caught in a debug environment. We move some buf_pool_t::page_hash specific code from the ha and hash modules to buf_pool, for improved readability. buf_pool_t::close(): Assert that all blocks are clean, except on aborted startup or crash-like shutdown. buf_pool_t::validate(): No longer attempt to validate n_flush[] against the number of BUF_IO_WRITE fixed blocks, because buf_page_t::flush_type no longer exists. buf_pool_t::watch_set(): Replaces buf_pool_watch_set(). Reduce mutex contention by separating the buf_pool.watch[] allocation and the insert into buf_pool.page_hash. buf_pool_t::page_hash_lock<bool exclusive>(): Acquire a buf_pool.page_hash latch. Replaces and extends buf_page_hash_lock_s_confirm() and buf_page_hash_lock_x_confirm(). buf_pool_t::READ_AHEAD_PAGES: Renamed from BUF_READ_AHEAD_PAGES. buf_pool_t::curr_size, old_size, read_ahead_area, n_pend_reads: Use Atomic_counter. buf_pool_t::running_out(): Replaces buf_LRU_buf_pool_running_out(). buf_pool_t::LRU_remove(): Remove a block from the LRU list and return its predecessor. Incorporates buf_LRU_adjust_hp(), which was removed. buf_page_get_gen(): Remove a redundant call of fsp_is_system_temporary(), for mode == BUF_GET_IF_IN_POOL_OR_WATCH, which is only used by BTR_DELETE_OP (purge), which is never invoked on temporary tables. buf_free_from_unzip_LRU_list_batch(): Avoid redundant assignments. buf_LRU_free_from_unzip_LRU_list(): Simplify the loop condition. buf_LRU_free_page(): Clarify the function comment. buf_flush_check_neighbor(), buf_flush_check_neighbors(): Rewrite the construction of the page hash range. We will hold the buf_pool.mutex for up to buf_pool.read_ahead_area (at most 64) consecutive lookups of buf_pool.page_hash. buf_flush_page_and_try_neighbors(): Remove. Merge to its only callers, and remove redundant operations in buf_flush_LRU_list_batch(). buf_read_ahead_random(), buf_read_ahead_linear(): Rewrite. Do not acquire buf_pool.mutex, and iterate directly with page_id_t. ut_2_power_up(): Remove. my_round_up_to_next_power() is inlined and avoids any loops. fil_page_get_prev(), fil_page_get_next(), fil_addr_is_null(): Remove. buf_flush_page(): Add a fil_space_t* parameter. Minimize the buf_pool.mutex hold time. buf_pool.n_flush[] is no longer updated atomically with the io_fix, and we will protect most buf_block_t fields with buf_block_t::lock. The function buf_flush_write_block_low() is removed and merged here. buf_page_init_for_read(): Use static linkage. Initialize the newly allocated block and acquire the exclusive buf_block_t::lock while not holding any mutex. IORequest::IORequest(): Remove the body. We only need to invoke set_punch_hole() in buf_flush_page() and nowhere else. buf_page_t::flush_type: Remove. Replaced by IORequest::flush_type. This field is only used during a fil_io() call. That function already takes IORequest as a parameter, so we had better introduce for the rarely changing field. buf_block_t::init(): Replaces buf_page_init(). buf_page_t::init(): Replaces buf_page_init_low(). buf_block_t::initialise(): Initialise many fields, but keep the buf_page_t::state(). Both buf_pool_t::validate() and buf_page_optimistic_get() requires that buf_page_t::in_file() be protected atomically with buf_page_t::in_page_hash and buf_page_t::in_LRU_list. buf_page_optimistic_get(): Now that buf_block_t::mutex no longer exists, we must check buf_page_t::io_fix() after acquiring the buf_pool.page_hash lock, to detect whether buf_page_init_for_read() has been initiated. We will also check the io_fix() before acquiring hash_lock in order to avoid unnecessary computation. The field buf_block_t::modify_clock (protected by buf_block_t::lock) allows buf_page_optimistic_get() to validate the block. buf_page_t::real_size: Remove. It was only used while flushing pages of page_compressed tables. buf_page_encrypt(): Add an output parameter that allows us ot eliminate buf_page_t::real_size. Replace a condition with debug assertion. buf_page_should_punch_hole(): Remove. buf_dblwr_t::add_to_batch(): Replaces buf_dblwr_add_to_batch(). Add the parameter size (to replace buf_page_t::real_size). buf_dblwr_t::write_single_page(): Replaces buf_dblwr_write_single_page(). Add the parameter size (to replace buf_page_t::real_size). fil_system_t::detach(): Replaces fil_space_detach(). Ensure that fil_validate() will not be violated even if fil_system.mutex is released and reacquired. fil_node_t::complete_io(): Renamed from fil_node_complete_io(). fil_node_t::close_to_free(): Replaces fil_node_close_to_free(). Avoid invoking fil_node_t::close() because fil_system.n_open has already been decremented in fil_space_t::detach(). BUF_BLOCK_READY_FOR_USE: Remove. Directly use BUF_BLOCK_MEMORY. BUF_BLOCK_ZIP_DIRTY: Remove. Directly use BUF_BLOCK_ZIP_PAGE, and distinguish dirty pages by buf_page_t::oldest_modification(). BUF_BLOCK_POOL_WATCH: Remove. Use BUF_BLOCK_NOT_USED instead. This state was only being used for buf_page_t that are in buf_pool.watch. buf_pool_t::watch[]: Remove pointer indirection. buf_page_t::in_flush_list: Remove. It was set if and only if buf_page_t::oldest_modification() is nonzero. buf_page_decrypt_after_read(), buf_corrupt_page_release(), buf_page_check_corrupt(): Change the const fil_space_t* parameter to const fil_node_t& so that we can report the correct file name. buf_page_monitor(): Declare as an ATTRIBUTE_COLD global function. buf_page_io_complete(): Split to buf_page_read_complete() and buf_page_write_complete(). buf_dblwr_t::in_use: Remove. buf_dblwr_t::buf_block_array: Add IORequest::flush_t. buf_dblwr_sync_datafiles(): Remove. It was a useless wrapper of os_aio_wait_until_no_pending_writes(). buf_flush_write_complete(): Declare static, not global. Add the parameter IORequest::flush_t. buf_flush_freed_page(): Simplify the code. recv_sys_t::flush_lru: Renamed from flush_type and changed to bool. fil_read(), fil_write(): Replaced with direct use of fil_io(). fil_buffering_disabled(): Remove. Check srv_file_flush_method directly. fil_mutex_enter_and_prepare_for_io(): Return the resolved fil_space_t* to avoid a duplicated lookup in the caller. fil_report_invalid_page_access(): Clean up the parameters. fil_io(): Return fil_io_t, which comprises fil_node_t and error code. Always invoke fil_space_t::acquire_for_io() and let either the sync=true caller or fil_aio_callback() invoke fil_space_t::release_for_io(). fil_aio_callback(): Rewrite to replace buf_page_io_complete(). fil_check_pending_operations(): Remove a parameter, and remove some redundant lookups. fil_node_close_to_free(): Wait for n_pending==0. Because we no longer do an extra lookup of the tablespace between fil_io() and the completion of the operation, we must give fil_node_t::complete_io() a chance to decrement the counter. fil_close_tablespace(): Remove unused parameter trx, and document that this is only invoked during the error handling of IMPORT TABLESPACE. row_import_discard_changes(): Merged with the only caller, row_import_cleanup(). Do not lock up the data dictionary while invoking fil_close_tablespace(). logs_empty_and_mark_files_at_shutdown(): Do not invoke fil_close_all_files(), to avoid a !needs_flush assertion failure on fil_node_t::close(). innodb_shutdown(): Invoke os_aio_free() before fil_close_all_files(). fil_close_all_files(): Invoke fil_flush_file_spaces() to ensure proper durability. thread_pool::unbind(): Fix a crash that would occur on Windows after srv_thread_pool->disable_aio() and os_file_close(). This fix was submitted by Vladislav Vaintroub. Thanks to Matthias Leich and Axel Schwenke for extensive testing, Vladislav Vaintroub for helpful comments, and Eugene Kosov for a review.
6 years ago
20 years ago
20 years ago
MDEV-20605 Awaken transaction can miss inserted by other transaction records due to wrong persistent cursor restoration sel_restore_position_for_mysql() moves forward persistent cursor position after btr_pcur_restore_position() call if cursor relative position is BTR_PCUR_ON and the cursor points to the record with NOT the same field values as in a stored record(and some other not important for this case conditions). It was done because btr_pcur_restore_position() sets page_cur_mode_t mode to PAGE_CUR_LE for cursor->rel_pos == BTR_PCUR_ON before opening cursor. So we are searching for the record less or equal to stored one. And if the found record is not equal to stored one, then it is less and we need to move cursor forward. But there can be a situation when the stored record was purged, but the new one with the same key but different value was inserted while row_search_mvcc() was suspended. In this case, when the thread is awaken, it will invoke sel_restore_position_for_mysql(), which, in turns, invoke btr_pcur_restore_position(), which will return false because found record don't match stored record, and sel_restore_position_for_mysql() will move forward cursor position. The above can lead to the case when awaken row_search_mvcc() do not see records inserted by other transactions while it slept. The mtr test case shows the example how it can be. The fix is to return special value from persistent cursor restoring function which would notify its caller that uniq fields of restored record and stored record are the same, and in this case sel_restore_position_for_mysql() don't move cursor forward. Delete-marked records are correctly processed in row_search_mvcc(). Non-unique secondary indexes are "uniquified" by adding the PK, the index->n_uniq should then be index->n_fields. So there is no need in additional checks in the fix. If transaction's readview can't see the changes made in secondary index record, it requests clustered index record in row_search_mvcc() to check its transaction id and get the correspondent record version. After this row_search_mvcc() commits mtr to preserve clustered index latching order, and starts mtr. Between those mtr commit and start secondary index pages are unlatched, and purge has the ability to remove stored in the cursor record, what causes rows duplication in result set for non-locking reads, as cursor position is restored to the previously visited record. To solve this the changes are just switched off for non-locking reads, it's quite simple solution, besides the changes don't make sense for non-locking reads. The more complex and effective from performance perspective solution is to create mtr savepoint before clustered record requesting and rolling back to that savepoint after that. See MDEV-27557. One more solution is to have per-record transaction id for secondary indexes. See MDEV-17598. If any of those is implemented, just remove select_lock_type argument in sel_restore_position_for_mysql().
4 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
10 years ago
20 years ago
branches/zip: Initialize dfield_t::ext as soon as possible. This should fix the bugs introduced in r1591. row_rec_to_index_entry_low(): Clear "n_ext". Do not allow it to be NULL. Add const qualifier to dict_index_t*. row_rec_to_index_entry(): Add the parameters "offsets" and "n_ext". btr_cur_optimistic_update(): Add an assertion that there are no externally stored columns. Remove the unreachable call to btr_cur_unmark_extern_fields() and the preceding unnecessary call to rec_get_offsets(). btr_push_update_extern_fields(): Remove the parameters index, offsets. Only report the additional externally stored columns of the update vector. row_build(), trx_undo_rec_get_partial_row(): Flag externally stored columns also with dfield_set_ext(). rec_copy_prefix_to_dtuple(): Assert that there are no externally stored columns in the prefix. row_build_row_ref(): Note and assert that the index is a secondary index, and assert that there are no externally stored columns. row_build_row_ref_fast(): Assert that there are no externally stored columns. rec_offs_get_n_alloc(): Expose the function. row_build_row_ref_in_tuple(): Assert that there are no externally stored columns in a record of a secondary index. row_build_row_ref_from_row(): Assert that there are no externally stored columns. row_upd_check_references_constraints(): Add the parameter offsets, to avoid a redundant call to rec_get_offsets(). row_upd_del_mark_clust_rec(): Add the parameter offsets. Remove duplicated code. row_ins_index_entry_set_vals(): Copy the external storage flag. sel_pop_prefetched_row(): Assert that there are no externally stored columns. row_scan_and_check_index(): Copy offsets to a temporary heap across the invocation of row_rec_to_index_entry().
18 years ago
20 years ago
20 years ago
MDEV-13498 DELETE with CASCADE constraints takes long time / MDEV-13246 MDEV-13498 is a performance regression that was introduced in MariaDB 10.2.2 by commit fec844aca88e1c6b9c36bb0b811e92d9d023ffb9 which introduced some Galera-specific conditions that were being evaluated even if the write-set replication was not enabled. MDEV-13246 Stale rows despite ON DELETE CASCADE constraint is a correctness regression that was introduced by the same commit. Especially the subcondition !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE) which is equivalent to !parent || que_node_get_type(parent) != QUE_NODE_UPDATE makes little sense. If parent==NULL, the evaluation would proceed to the std::find() expression, which would dereference parent. Because no SIGSEGV was observed related to this, we can conclude that parent!=NULL always holds. But then, the condition would be equivalent to que_node_get_type(parent) != QUE_NODE_UPDATE which would not make sense either, because the std::find() expression is actually assuming the opposite when casting parent to upd_node_t*. It looks like this condition never worked properly, or that it was never properly tested, or both. wsrep_must_process_fk(): Helper function to check if FOREIGN KEY constraints need to be processed. Only evaluate the costly std::find() expression when write-set replication is enabled. Also, rely on operator<<(std::ostream&, const id_name_t&) and operator<<(std::ostream&, const table_name_t&) for pretty-printing index and table names. row_upd_sec_index_entry(): Add !wsrep_thd_is_BF() to the condition. This is applying part of "Galera MW-369 FK fixes" https://github.com/codership/mysql-wsrep/commit/f37b79c6dab101310a45a9e8cb23c0f98716da52 that is described by the following part of the commit comment: additionally: skipping wsrep_row_upd_check_foreign_constraint if thd has BF, essentially is applier or replaying This FK check would be needed only for populating parent row FK keys in write set, so no use for appliers
8 years ago
20 years ago
20 years ago
MDEV-13498 DELETE with CASCADE constraints takes long time / MDEV-13246 MDEV-13498 is a performance regression that was introduced in MariaDB 10.2.2 by commit fec844aca88e1c6b9c36bb0b811e92d9d023ffb9 which introduced some Galera-specific conditions that were being evaluated even if the write-set replication was not enabled. MDEV-13246 Stale rows despite ON DELETE CASCADE constraint is a correctness regression that was introduced by the same commit. Especially the subcondition !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE) which is equivalent to !parent || que_node_get_type(parent) != QUE_NODE_UPDATE makes little sense. If parent==NULL, the evaluation would proceed to the std::find() expression, which would dereference parent. Because no SIGSEGV was observed related to this, we can conclude that parent!=NULL always holds. But then, the condition would be equivalent to que_node_get_type(parent) != QUE_NODE_UPDATE which would not make sense either, because the std::find() expression is actually assuming the opposite when casting parent to upd_node_t*. It looks like this condition never worked properly, or that it was never properly tested, or both. wsrep_must_process_fk(): Helper function to check if FOREIGN KEY constraints need to be processed. Only evaluate the costly std::find() expression when write-set replication is enabled. Also, rely on operator<<(std::ostream&, const id_name_t&) and operator<<(std::ostream&, const table_name_t&) for pretty-printing index and table names. row_upd_sec_index_entry(): Add !wsrep_thd_is_BF() to the condition. This is applying part of "Galera MW-369 FK fixes" https://github.com/codership/mysql-wsrep/commit/f37b79c6dab101310a45a9e8cb23c0f98716da52 that is described by the following part of the commit comment: additionally: skipping wsrep_row_upd_check_foreign_constraint if thd has BF, essentially is applier or replaying This FK check would be needed only for populating parent row FK keys in write set, so no use for appliers
8 years ago
20 years ago
MDEV-13498 DELETE with CASCADE constraints takes long time / MDEV-13246 MDEV-13498 is a performance regression that was introduced in MariaDB 10.2.2 by commit fec844aca88e1c6b9c36bb0b811e92d9d023ffb9 which introduced some Galera-specific conditions that were being evaluated even if the write-set replication was not enabled. MDEV-13246 Stale rows despite ON DELETE CASCADE constraint is a correctness regression that was introduced by the same commit. Especially the subcondition !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE) which is equivalent to !parent || que_node_get_type(parent) != QUE_NODE_UPDATE makes little sense. If parent==NULL, the evaluation would proceed to the std::find() expression, which would dereference parent. Because no SIGSEGV was observed related to this, we can conclude that parent!=NULL always holds. But then, the condition would be equivalent to que_node_get_type(parent) != QUE_NODE_UPDATE which would not make sense either, because the std::find() expression is actually assuming the opposite when casting parent to upd_node_t*. It looks like this condition never worked properly, or that it was never properly tested, or both. wsrep_must_process_fk(): Helper function to check if FOREIGN KEY constraints need to be processed. Only evaluate the costly std::find() expression when write-set replication is enabled. Also, rely on operator<<(std::ostream&, const id_name_t&) and operator<<(std::ostream&, const table_name_t&) for pretty-printing index and table names. row_upd_sec_index_entry(): Add !wsrep_thd_is_BF() to the condition. This is applying part of "Galera MW-369 FK fixes" https://github.com/codership/mysql-wsrep/commit/f37b79c6dab101310a45a9e8cb23c0f98716da52 that is described by the following part of the commit comment: additionally: skipping wsrep_row_upd_check_foreign_constraint if thd has BF, essentially is applier or replaying This FK check would be needed only for populating parent row FK keys in write set, so no use for appliers
8 years ago
MDEV-13498 DELETE with CASCADE constraints takes long time / MDEV-13246 MDEV-13498 is a performance regression that was introduced in MariaDB 10.2.2 by commit fec844aca88e1c6b9c36bb0b811e92d9d023ffb9 which introduced some Galera-specific conditions that were being evaluated even if the write-set replication was not enabled. MDEV-13246 Stale rows despite ON DELETE CASCADE constraint is a correctness regression that was introduced by the same commit. Especially the subcondition !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE) which is equivalent to !parent || que_node_get_type(parent) != QUE_NODE_UPDATE makes little sense. If parent==NULL, the evaluation would proceed to the std::find() expression, which would dereference parent. Because no SIGSEGV was observed related to this, we can conclude that parent!=NULL always holds. But then, the condition would be equivalent to que_node_get_type(parent) != QUE_NODE_UPDATE which would not make sense either, because the std::find() expression is actually assuming the opposite when casting parent to upd_node_t*. It looks like this condition never worked properly, or that it was never properly tested, or both. wsrep_must_process_fk(): Helper function to check if FOREIGN KEY constraints need to be processed. Only evaluate the costly std::find() expression when write-set replication is enabled. Also, rely on operator<<(std::ostream&, const id_name_t&) and operator<<(std::ostream&, const table_name_t&) for pretty-printing index and table names. row_upd_sec_index_entry(): Add !wsrep_thd_is_BF() to the condition. This is applying part of "Galera MW-369 FK fixes" https://github.com/codership/mysql-wsrep/commit/f37b79c6dab101310a45a9e8cb23c0f98716da52 that is described by the following part of the commit comment: additionally: skipping wsrep_row_upd_check_foreign_constraint if thd has BF, essentially is applier or replaying This FK check would be needed only for populating parent row FK keys in write set, so no use for appliers
8 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
10 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
MDEV-10139 Support for InnoDB SEQUENCE objects We introduce a NO_ROLLBACK flag for InnoDB tables. This flag only works for tables that have a single index. Apart from undo logging, this flag will also prevent locking and the assignment of DB_ROW_ID or DB_TRX_ID, and imply READ UNCOMMITTED isolation. It is assumed that the SQL layer is guaranteeing mutual exclusion. After the initial insert of the single record during CREATE SEQUENCE, InnoDB will be updating the single record in-place. This is crash-safe thanks to the redo log. (That is, after a crash after CREATE SEQUENCE was committed, the effect of sequence operations will be observable fully or not at all.) When it comes to the durability of the updates of SEQUENCE in InnoDB, there is a clear analogy to MDEV-6076 Persistent AUTO_INCREMENT. The updates would be made persistent by the InnoDB redo log flush at transaction commit or rollback (or XA PREPARE), provided that innodb_log_flush_at_trx_commit=1. Similar to AUTO_INCREMENT, it is possible that the update of a SEQUENCE in a middle of transaction becomes durable before the COMMIT/ROLLBACK of the transaction, in case the InnoDB redo log is being flushed as a result of the a commit or rollback of some other transaction, or as a result of a redo log checkpoint that can be initiated at any time by operations that are writing redo log. dict_table_t::no_rollback(): Check if the table does not support rollback. BTR_NO_ROLLBACK: Logging and locking flags for no_rollback() tables. DICT_TF_BITS: Add the NO_ROLLBACK flag. row_ins_step(): Assign 0 to DB_ROW_ID and DB_TRX_ID, and skip any locking for no-rollback tables. There will be only a single row in no-rollback tables (or there must be a proper PRIMARY KEY). row_search_mvcc(): Execute the READ UNCOMMITTED code path for no-rollback tables. ha_innobase::external_lock(), ha_innobase::store_lock(): Block CREATE/DROP SEQUENCE in innodb_read_only mode. This probably has no effect for CREATE SEQUENCE, because already ha_innobase::create() should have been called (and refused) before external_lock() or store_lock() is called. ha_innobase::store_lock(): For CREATE SEQUENCE, do not acquire any InnoDB locks, even though TL_WRITE is being requested. (This is just a performance optimization.) innobase_copy_frm_flags_from_create_info(), row_drop_table_for_mysql(): Disable persistent statistics for no_rollback tables.
9 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
MDEV-11369 Instant ADD COLUMN for InnoDB For InnoDB tables, adding, dropping and reordering columns has required a rebuild of the table and all its indexes. Since MySQL 5.6 (and MariaDB 10.0) this has been supported online (LOCK=NONE), allowing concurrent modification of the tables. This work revises the InnoDB ROW_FORMAT=REDUNDANT, ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC so that columns can be appended instantaneously, with only minor changes performed to the table structure. The counter innodb_instant_alter_column in INFORMATION_SCHEMA.GLOBAL_STATUS is incremented whenever a table rebuild operation is converted into an instant ADD COLUMN operation. ROW_FORMAT=COMPRESSED tables will not support instant ADD COLUMN. Some usability limitations will be addressed in subsequent work: MDEV-13134 Introduce ALTER TABLE attributes ALGORITHM=NOCOPY and ALGORITHM=INSTANT MDEV-14016 Allow instant ADD COLUMN, ADD INDEX, LOCK=NONE The format of the clustered index (PRIMARY KEY) is changed as follows: (1) The FIL_PAGE_TYPE of the root page will be FIL_PAGE_TYPE_INSTANT, and a new field PAGE_INSTANT will contain the original number of fields in the clustered index ('core' fields). If instant ADD COLUMN has not been used or the table becomes empty, or the very first instant ADD COLUMN operation is rolled back, the fields PAGE_INSTANT and FIL_PAGE_TYPE will be reset to 0 and FIL_PAGE_INDEX. (2) A special 'default row' record is inserted into the leftmost leaf, between the page infimum and the first user record. This record is distinguished by the REC_INFO_MIN_REC_FLAG, and it is otherwise in the same format as records that contain values for the instantly added columns. This 'default row' always has the same number of fields as the clustered index according to the table definition. The values of 'core' fields are to be ignored. For other fields, the 'default row' will contain the default values as they were during the ALTER TABLE statement. (If the column default values are changed later, those values will only be stored in the .frm file. The 'default row' will contain the original evaluated values, which must be the same for every row.) The 'default row' must be completely hidden from higher-level access routines. Assertions have been added to ensure that no 'default row' is ever present in the adaptive hash index or in locked records. The 'default row' is never delete-marked. (3) In clustered index leaf page records, the number of fields must reside between the number of 'core' fields (dict_index_t::n_core_fields introduced in this work) and dict_index_t::n_fields. If the number of fields is less than dict_index_t::n_fields, the missing fields are replaced with the column value of the 'default row'. Note: The number of fields in the record may shrink if some of the last instantly added columns are updated to the value that is in the 'default row'. The function btr_cur_trim() implements this 'compression' on update and rollback; dtuple::trim() implements it on insert. (4) In ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC records, the new status value REC_STATUS_COLUMNS_ADDED will indicate the presence of a new record header that will encode n_fields-n_core_fields-1 in 1 or 2 bytes. (In ROW_FORMAT=REDUNDANT records, the record header always explicitly encodes the number of fields.) We introduce the undo log record type TRX_UNDO_INSERT_DEFAULT for covering the insert of the 'default row' record when instant ADD COLUMN is used for the first time. Subsequent instant ADD COLUMN can use TRX_UNDO_UPD_EXIST_REC. This is joint work with Vin Chen (陈福荣) from Tencent. The design that was discussed in April 2017 would not have allowed import or export of data files, because instead of the 'default row' it would have introduced a data dictionary table. The test rpl.rpl_alter_instant is exactly as contributed in pull request #408. The test innodb.instant_alter is based on a contributed test. The redo log record format changes for ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPACT are as contributed. (With this change present, crash recovery from MariaDB 10.3.1 will fail in spectacular ways!) Also the semantics of higher-level redo log records that modify the PAGE_INSTANT field is changed. The redo log format version identifier was already changed to LOG_HEADER_FORMAT_CURRENT=103 in MariaDB 10.3.1. Everything else has been rewritten by me. Thanks to Elena Stepanova, the code has been tested extensively. When rolling back an instant ADD COLUMN operation, we must empty the PAGE_FREE list after deleting or shortening the 'default row' record, by calling either btr_page_empty() or btr_page_reorganize(). We must know the size of each entry in the PAGE_FREE list. If rollback left a freed copy of the 'default row' in the PAGE_FREE list, we would be unable to determine its size (if it is in ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC) because it would contain more fields than the rolled-back definition of the clustered index. UNIV_SQL_DEFAULT: A new special constant that designates an instantly added column that is not present in the clustered index record. len_is_stored(): Check if a length is an actual length. There are two magic length values: UNIV_SQL_DEFAULT, UNIV_SQL_NULL. dict_col_t::def_val: The 'default row' value of the column. If the column is not added instantly, def_val.len will be UNIV_SQL_DEFAULT. dict_col_t: Add the accessors is_virtual(), is_nullable(), is_instant(), instant_value(). dict_col_t::remove_instant(): Remove the 'instant ADD' status of a column. dict_col_t::name(const dict_table_t& table): Replaces dict_table_get_col_name(). dict_index_t::n_core_fields: The original number of fields. For secondary indexes and if instant ADD COLUMN has not been used, this will be equal to dict_index_t::n_fields. dict_index_t::n_core_null_bytes: Number of bytes needed to represent the null flags; usually equal to UT_BITS_IN_BYTES(n_nullable). dict_index_t::NO_CORE_NULL_BYTES: Magic value signalling that n_core_null_bytes was not initialized yet from the clustered index root page. dict_index_t: Add the accessors is_instant(), is_clust(), get_n_nullable(), instant_field_value(). dict_index_t::instant_add_field(): Adjust clustered index metadata for instant ADD COLUMN. dict_index_t::remove_instant(): Remove the 'instant ADD' status of a clustered index when the table becomes empty, or the very first instant ADD COLUMN operation is rolled back. dict_table_t: Add the accessors is_instant(), is_temporary(), supports_instant(). dict_table_t::instant_add_column(): Adjust metadata for instant ADD COLUMN. dict_table_t::rollback_instant(): Adjust metadata on the rollback of instant ADD COLUMN. prepare_inplace_alter_table_dict(): First create the ctx->new_table, and only then decide if the table really needs to be rebuilt. We must split the creation of table or index metadata from the creation of the dictionary table records and the creation of the data. In this way, we can transform a table-rebuilding operation into an instant ADD COLUMN operation. Dictionary objects will only be added to cache when table rebuilding or index creation is needed. The ctx->instant_table will never be added to cache. dict_table_t::add_to_cache(): Modified and renamed from dict_table_add_to_cache(). Do not modify the table metadata. Let the callers invoke dict_table_add_system_columns() and if needed, set can_be_evicted. dict_create_sys_tables_tuple(), dict_create_table_step(): Omit the system columns (which will now exist in the dict_table_t object already at this point). dict_create_table_step(): Expect the callers to invoke dict_table_add_system_columns(). pars_create_table(): Before creating the table creation execution graph, invoke dict_table_add_system_columns(). row_create_table_for_mysql(): Expect all callers to invoke dict_table_add_system_columns(). create_index_dict(): Replaces row_merge_create_index_graph(). innodb_update_n_cols(): Renamed from innobase_update_n_virtual(). Call my_error() if an error occurs. btr_cur_instant_init(), btr_cur_instant_init_low(), btr_cur_instant_root_init(): Load additional metadata from the clustered index and set dict_index_t::n_core_null_bytes. This is invoked when table metadata is first loaded into the data dictionary. dict_boot(): Initialize n_core_null_bytes for the four hard-coded dictionary tables. dict_create_index_step(): Initialize n_core_null_bytes. This is executed as part of CREATE TABLE. dict_index_build_internal_clust(): Initialize n_core_null_bytes to NO_CORE_NULL_BYTES if table->supports_instant(). row_create_index_for_mysql(): Initialize n_core_null_bytes for CREATE TEMPORARY TABLE. commit_cache_norebuild(): Call the code to rename or enlarge columns in the cache only if instant ADD COLUMN is not being used. (Instant ADD COLUMN would copy all column metadata from instant_table to old_table, including the names and lengths.) PAGE_INSTANT: A new 13-bit field for storing dict_index_t::n_core_fields. This is repurposing the 16-bit field PAGE_DIRECTION, of which only the least significant 3 bits were used. The original byte containing PAGE_DIRECTION will be accessible via the new constant PAGE_DIRECTION_B. page_get_instant(), page_set_instant(): Accessors for the PAGE_INSTANT. page_ptr_get_direction(), page_get_direction(), page_ptr_set_direction(): Accessors for PAGE_DIRECTION. page_direction_reset(): Reset PAGE_DIRECTION, PAGE_N_DIRECTION. page_direction_increment(): Increment PAGE_N_DIRECTION and set PAGE_DIRECTION. rec_get_offsets(): Use the 'leaf' parameter for non-debug purposes, and assume that heap_no is always set. Initialize all dict_index_t::n_fields for ROW_FORMAT=REDUNDANT records, even if the record contains fewer fields. rec_offs_make_valid(): Add the parameter 'leaf'. rec_copy_prefix_to_dtuple(): Assert that the tuple is only built on the core fields. Instant ADD COLUMN only applies to the clustered index, and we should never build a search key that has more than the PRIMARY KEY and possibly DB_TRX_ID,DB_ROLL_PTR. All these columns are always present. dict_index_build_data_tuple(): Remove assertions that would be duplicated in rec_copy_prefix_to_dtuple(). rec_init_offsets(): Support ROW_FORMAT=REDUNDANT records whose number of fields is between n_core_fields and n_fields. cmp_rec_rec_with_match(): Implement the comparison between two MIN_REC_FLAG records. trx_t::in_rollback: Make the field available in non-debug builds. trx_start_for_ddl_low(): Remove dangerous error-tolerance. A dictionary transaction must be flagged as such before it has generated any undo log records. This is because trx_undo_assign_undo() will mark the transaction as a dictionary transaction in the undo log header right before the very first undo log record is being written. btr_index_rec_validate(): Account for instant ADD COLUMN row_undo_ins_remove_clust_rec(): On the rollback of an insert into SYS_COLUMNS, revert instant ADD COLUMN in the cache by removing the last column from the table and the clustered index. row_search_on_row_ref(), row_undo_mod_parse_undo_rec(), row_undo_mod(), trx_undo_update_rec_get_update(): Handle the 'default row' as a special case. dtuple_t::trim(index): Omit a redundant suffix of an index tuple right before insert or update. After instant ADD COLUMN, if the last fields of a clustered index tuple match the 'default row', there is no need to store them. While trimming the entry, we must hold a page latch, so that the table cannot be emptied and the 'default row' be deleted. btr_cur_optimistic_update(), btr_cur_pessimistic_update(), row_upd_clust_rec_by_insert(), row_ins_clust_index_entry_low(): Invoke dtuple_t::trim() if needed. row_ins_clust_index_entry(): Restore dtuple_t::n_fields after calling row_ins_clust_index_entry_low(). rec_get_converted_size(), rec_get_converted_size_comp(): Allow the number of fields to be between n_core_fields and n_fields. Do not support infimum,supremum. They are never supposed to be stored in dtuple_t, because page creation nowadays uses a lower-level method for initializing them. rec_convert_dtuple_to_rec_comp(): Assign the status bits based on the number of fields. btr_cur_trim(): In an update, trim the index entry as needed. For the 'default row', handle rollback specially. For user records, omit fields that match the 'default row'. btr_cur_optimistic_delete_func(), btr_cur_pessimistic_delete(): Skip locking and adaptive hash index for the 'default row'. row_log_table_apply_convert_mrec(): Replace 'default row' values if needed. In the temporary file that is applied by row_log_table_apply(), we must identify whether the records contain the extra header for instantly added columns. For now, we will allocate an additional byte for this for ROW_T_INSERT and ROW_T_UPDATE records when the source table has been subject to instant ADD COLUMN. The ROW_T_DELETE records are fine, as they will be converted and will only contain 'core' columns (PRIMARY KEY and some system columns) that are converted from dtuple_t. rec_get_converted_size_temp(), rec_init_offsets_temp(), rec_convert_dtuple_to_temp(): Add the parameter 'status'. REC_INFO_DEFAULT_ROW = REC_INFO_MIN_REC_FLAG | REC_STATUS_COLUMNS_ADDED: An info_bits constant for distinguishing the 'default row' record. rec_comp_status_t: An enum of the status bit values. rec_leaf_format: An enum that replaces the bool parameter of rec_init_offsets_comp_ordinary().
8 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
20 years ago
MDEV-21907: InnoDB: Enable -Wconversion on clang and GCC The -Wconversion in GCC seems to be stricter than in clang. GCC at least since version 4.4.7 issues truncation warnings for assignments to bitfields, while clang 10 appears to only issue warnings when the sizes in bytes rounded to the nearest integer powers of 2 are different. Before GCC 10.0.0, -Wconversion required more casts and would not allow some operations, such as x<<=1 or x+=1 on a data type that is narrower than int. GCC 5 (but not GCC 4, GCC 6, or any later version) is complaining about x|=y even when x and y are compatible types that are narrower than int. Hence, we must rewrite some x|=y as x=static_cast<byte>(x|y) or similar, or we must disable -Wconversion. In GCC 6 and later, the warning for assigning wider to bitfields that are narrower than 8, 16, or 32 bits can be suppressed by applying a bitwise & with the exact bitmask of the bitfield. For older GCC, we must disable -Wconversion for GCC 4 or 5 in such cases. The bitwise negation operator appears to promote short integers to a wider type, and hence we must add explicit truncation casts around them. Microsoft Visual C does not allow a static_cast to truncate a constant, such as static_cast<byte>(1) truncating int. Hence, we will use the constructor-style cast byte(~1) for such cases. This has been tested at least with GCC 4.8.5, 5.4.0, 7.4.0, 9.2.1, 10.0.0, clang 9.0.1, 10.0.0, and MSVC 14.22.27905 (Microsoft Visual Studio 2019) on 64-bit and 32-bit targets (IA-32, AMD64, POWER 8, POWER 9, ARMv8).
6 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
MDEV-15250 UPSERT during ALTER TABLE results in 'Duplicate entry' error for alter - InnoDB DDL results in `Duplicate entry' if concurrent DML throws duplicate key error. The following scenario explains the problem connection con1: ALTER TABLE t1 FORCE; connection con2: INSERT INTO t1(pk, uk) VALUES (2, 2), (3, 2); In connection con2, InnoDB throws the 'DUPLICATE KEY' error because of unique index. Alter operation will throw the error when applying the concurrent DML log. - Inserting the duplicate key for unique index logs the insert operation for online ALTER TABLE. When insertion fails, transaction does rollback and it leads to logging of delete operation for online ALTER TABLE. While applying the insert log entries, alter operation encounters 'DUPLICATE KEY' error. - To avoid the above fake duplicate scenario, InnoDB should not write any log for online ALTER TABLE before DML transaction commit. - User thread which does DML can apply the online log if InnoDB ran out of online log and index is marked as completed. Set online log error if apply phase encountered any error. It can also clear all other indexes log, marks the newly added indexes as corrupted. - Removed the old online code which was a part of DML operations commit_inplace_alter_table() : Does apply the online log for the last batch of secondary index log and does frees the log for the completed index. trx_t::apply_online_log: Set to true while writing the undo log if the modified table has active DDL trx_t::apply_log(): Apply the DML changes to online DDL tables dict_table_t::is_active_ddl(): Returns true if the table has an active DDL dict_index_t::online_log_make_dummy(): Assign dummy value for clustered index online log to indicate the secondary indexes are being rebuild. dict_index_t::online_log_is_dummy(): Check whether the online log has dummy value ha_innobase_inplace_ctx::log_failure(): Handle the apply log failure for online DDL transaction row_log_mark_other_online_index_abort(): Clear out all other online index log after encountering the error during row_log_apply() row_log_get_error(): Get the error happened during row_log_apply() row_log_online_op(): Does apply the online log if index is completed and ran out of memory. Returns false if apply log fails UndorecApplier: Introduced a class to maintain the undo log record, latched undo buffer page, parse the undo log record, maintain the undo record type, info bits and update vector UndorecApplier::get_old_rec(): Get the correct version of the clustered index record that was modified by the current undo log record UndorecApplier::clear_undo_rec(): Clear the undo log related information after applying the undo log record UndorecApplier::log_update(): Handle the update, delete undo log and apply it on online indexes UndorecApplier::log_insert(): Handle the insert undo log and apply it on online indexes UndorecApplier::is_same(): Check whether the given roll pointer is generated by the current undo log record information trx_t::rollback_low(): Set apply_online_log for the transaction after partially rollbacked transaction has any active DDL prepare_inplace_alter_table_dict(): After allocating the online log, InnoDB does create fulltext common tables. Fulltext index doesn't allow the index to be online. So removed the dead code of online log removal Thanks to Marko Mäkelä for providing the initial prototype and Matthias Leich for testing the issue patiently.
4 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
branches/innodb+: Merge revisions 5091:5143 from branches/zip: ------------------------------------------------------------------------ r5092 | marko | 2009-05-25 09:54:17 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Adjust some function comments after r5091. ------------------------------------------------------------------------ r5100 | marko | 2009-05-25 12:09:45 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Split some long lines that were introduced in r5091. ------------------------------------------------------------------------ r5101 | marko | 2009-05-25 12:42:47 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Introduce the macro TEMP_INDEX_PREFIX_STR. This is to avoid triggering an error in Doxygen. ------------------------------------------------------------------------ r5102 | marko | 2009-05-25 13:47:14 +0300 (Mon, 25 May 2009) | 1 line branches/zip: Add missing file comments. ------------------------------------------------------------------------ r5103 | marko | 2009-05-25 13:52:29 +0300 (Mon, 25 May 2009) | 10 lines branches/zip: Add @file comments, and convert decorative /********************************* comments to Doxygen /** style like this: /*****************************//** This conversion was performed by the following command: perl -i -e 'while(<ARGV>){if (m|^/\*{30}\**$|) { s|\*{4}$|//**| if ++$com>1; $_ .= "\@file $ARGV\n" if $com==2} print; if(eof){$.=0;undef $com}}' */*[ch] include/univ.i ------------------------------------------------------------------------ r5104 | marko | 2009-05-25 14:39:07 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Revert ut0auxconf_* to r5102, that is, make Doxygen ignore these test programs. ------------------------------------------------------------------------ r5105 | marko | 2009-05-25 14:52:20 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Enclose some #error checks inside #ifndef DOXYGEN to prevent bogus Doxygen errors. ------------------------------------------------------------------------ r5106 | marko | 2009-05-25 16:09:24 +0300 (Mon, 25 May 2009) | 2 lines branches/zip: Add some Doxygen comments, mainly to structs, typedefs, macros and global variables. Many more to go. ------------------------------------------------------------------------ r5108 | marko | 2009-05-26 00:32:35 +0300 (Tue, 26 May 2009) | 2 lines branches/zip: lexyy.c: Remove the inadvertently added @file directive. There is nothing for Doxygen to see in this file, move along. ------------------------------------------------------------------------ r5125 | marko | 2009-05-26 16:28:49 +0300 (Tue, 26 May 2009) | 3 lines branches/zip: Add some Doxygen comments for many structs, typedefs, #defines and global variables. Many are still missing. ------------------------------------------------------------------------ r5134 | marko | 2009-05-27 09:08:43 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add some Doxygen @return comments. ------------------------------------------------------------------------ r5139 | marko | 2009-05-27 10:01:40 +0300 (Wed, 27 May 2009) | 1 line branches/zip: Add Doxyfile. ------------------------------------------------------------------------ r5143 | marko | 2009-05-27 10:57:25 +0300 (Wed, 27 May 2009) | 3 lines branches/zip: buf0buf.h, Doxyfile: Fix the Doxygen translation. @defgroup is for source code modules, not for field groups. Tell Doxygen to expand the UT_LIST declarations. ------------------------------------------------------------------------
17 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
  1. /*****************************************************************************
  2. Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
  3. Copyright (c) 2015, 2022, MariaDB Corporation.
  4. This program is free software; you can redistribute it and/or modify it under
  5. the terms of the GNU General Public License as published by the Free Software
  6. Foundation; version 2 of the License.
  7. This program is distributed in the hope that it will be useful, but WITHOUT
  8. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License along with
  11. this program; if not, write to the Free Software Foundation, Inc.,
  12. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
  13. *****************************************************************************/
  14. /**************************************************//**
  15. @file row/row0upd.cc
  16. Update of a row
  17. Created 12/27/1996 Heikki Tuuri
  18. *******************************************************/
  19. #include "row0upd.h"
  20. #include "dict0dict.h"
  21. #include "dict0mem.h"
  22. #include "trx0undo.h"
  23. #include "rem0rec.h"
  24. #include "dict0boot.h"
  25. #include "dict0crea.h"
  26. #include "mach0data.h"
  27. #include "btr0btr.h"
  28. #include "btr0cur.h"
  29. #include "que0que.h"
  30. #include "row0ext.h"
  31. #include "row0ins.h"
  32. #include "row0log.h"
  33. #include "row0row.h"
  34. #include "row0sel.h"
  35. #include "rem0cmp.h"
  36. #include "lock0lock.h"
  37. #include "log0log.h"
  38. #include "pars0sym.h"
  39. #include "eval0eval.h"
  40. #include "buf0lru.h"
  41. #include "trx0rec.h"
  42. #include "fts0fts.h"
  43. #include "fts0types.h"
  44. #include <algorithm>
  45. #include <mysql/plugin.h>
  46. #include <mysql/service_wsrep.h>
  47. #ifdef WITH_WSREP
  48. #include "log.h"
  49. #include "wsrep.h"
  50. #endif /* WITH_WSREP */
  51. /* What kind of latch and lock can we assume when the control comes to
  52. -------------------------------------------------------------------
  53. an update node?
  54. --------------
  55. Efficiency of massive updates would require keeping an x-latch on a
  56. clustered index page through many updates, and not setting an explicit
  57. x-lock on clustered index records, as they anyway will get an implicit
  58. x-lock when they are updated. A problem is that the read nodes in the
  59. graph should know that they must keep the latch when passing the control
  60. up to the update node, and not set any record lock on the record which
  61. will be updated. Another problem occurs if the execution is stopped,
  62. as the kernel switches to another query thread, or the transaction must
  63. wait for a lock. Then we should be able to release the latch and, maybe,
  64. acquire an explicit x-lock on the record.
  65. Because this seems too complicated, we conclude that the less
  66. efficient solution of releasing all the latches when the control is
  67. transferred to another node, and acquiring explicit x-locks, is better. */
  68. /* How is a delete performed? If there is a delete without an
  69. explicit cursor, i.e., a searched delete, there are at least
  70. two different situations:
  71. the implicit select cursor may run on (1) the clustered index or
  72. on (2) a secondary index. The delete is performed by setting
  73. the delete bit in the record and substituting the id of the
  74. deleting transaction for the original trx id, and substituting a
  75. new roll ptr for previous roll ptr. The old trx id and roll ptr
  76. are saved in the undo log record. Thus, no physical changes occur
  77. in the index tree structure at the time of the delete. Only
  78. when the undo log is purged, the index records will be physically
  79. deleted from the index trees.
  80. The query graph executing a searched delete would consist of
  81. a delete node which has as a subtree a select subgraph.
  82. The select subgraph should return a (persistent) cursor
  83. in the clustered index, placed on page which is x-latched.
  84. The delete node should look for all secondary index records for
  85. this clustered index entry and mark them as deleted. When is
  86. the x-latch freed? The most efficient way for performing a
  87. searched delete is obviously to keep the x-latch for several
  88. steps of query graph execution. */
  89. /*************************************************************************
  90. IMPORTANT NOTE: Any operation that generates redo MUST check that there
  91. is enough space in the redo log before for that operation. This is
  92. done by calling log_free_check(). The reason for checking the
  93. availability of the redo log space before the start of the operation is
  94. that we MUST not hold any synchonization objects when performing the
  95. check.
  96. If you make a change in this module make sure that no codepath is
  97. introduced where a call to log_free_check() is bypassed. */
  98. /***********************************************************//**
  99. Checks if an update vector changes some of the first ordering fields of an
  100. index record. This is only used in foreign key checks and we can assume
  101. that index does not contain column prefixes.
  102. @return TRUE if changes */
  103. static
  104. ibool
  105. row_upd_changes_first_fields_binary(
  106. /*================================*/
  107. dtuple_t* entry, /*!< in: old value of index entry */
  108. dict_index_t* index, /*!< in: index of entry */
  109. const upd_t* update, /*!< in: update vector for the row */
  110. ulint n); /*!< in: how many first fields to check */
  111. /*********************************************************************//**
  112. Checks if index currently is mentioned as a referenced index in a foreign
  113. key constraint.
  114. @return true if referenced */
  115. static
  116. bool
  117. row_upd_index_is_referenced(
  118. /*========================*/
  119. dict_index_t* index, /*!< in: index */
  120. trx_t* trx) /*!< in: transaction */
  121. {
  122. dict_table_t *table= index->table;
  123. /* The pointers in table->referenced_set are safe to dereference
  124. thanks to the SQL layer having acquired MDL on all (grand)parent tables. */
  125. dict_foreign_set::iterator end= table->referenced_set.end();
  126. return end != std::find_if(table->referenced_set.begin(), end,
  127. dict_foreign_with_index(index));
  128. }
  129. #ifdef WITH_WSREP
  130. static
  131. bool
  132. wsrep_row_upd_index_is_foreign(
  133. /*========================*/
  134. dict_index_t* index, /*!< in: index */
  135. trx_t* trx) /*!< in: transaction */
  136. {
  137. if (!trx->is_wsrep())
  138. return false;
  139. dict_table_t *table= index->table;
  140. if (table->foreign_set.empty())
  141. return false;
  142. /* No MDL protects dereferencing the members of table->foreign_set. */
  143. const bool no_lock= !trx->dict_operation_lock_mode;
  144. if (no_lock)
  145. dict_sys.freeze(SRW_LOCK_CALL);
  146. auto end= table->foreign_set.end();
  147. const bool is_referenced= end !=
  148. std::find_if(table->foreign_set.begin(), end,
  149. [index](const dict_foreign_t* f)
  150. {return f->foreign_index == index;});
  151. if (no_lock)
  152. dict_sys.unfreeze();
  153. return is_referenced;
  154. }
  155. #endif /* WITH_WSREP */
  156. /*********************************************************************//**
  157. Checks if possible foreign key constraints hold after a delete of the record
  158. under pcur.
  159. NOTE that this function will temporarily commit mtr and lose the
  160. pcur position!
  161. @return DB_SUCCESS or an error code */
  162. static MY_ATTRIBUTE((nonnull, warn_unused_result))
  163. dberr_t
  164. row_upd_check_references_constraints(
  165. /*=================================*/
  166. upd_node_t* node, /*!< in: row update node */
  167. btr_pcur_t* pcur, /*!< in: cursor positioned on a record; NOTE: the
  168. cursor position is lost in this function! */
  169. dict_table_t* table, /*!< in: table in question */
  170. dict_index_t* index, /*!< in: index of the cursor */
  171. rec_offs* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */
  172. que_thr_t* thr, /*!< in: query thread */
  173. mtr_t* mtr) /*!< in: mtr */
  174. {
  175. dict_foreign_t* foreign;
  176. mem_heap_t* heap;
  177. dtuple_t* entry;
  178. const rec_t* rec;
  179. dberr_t err;
  180. DBUG_ENTER("row_upd_check_references_constraints");
  181. if (table->referenced_set.empty()) {
  182. DBUG_RETURN(DB_SUCCESS);
  183. }
  184. rec = btr_pcur_get_rec(pcur);
  185. ut_ad(rec_offs_validate(rec, index, offsets));
  186. heap = mem_heap_create(500);
  187. entry = row_rec_to_index_entry(rec, index, offsets, heap);
  188. mtr_commit(mtr);
  189. DEBUG_SYNC_C("foreign_constraint_check_for_update");
  190. mtr->start();
  191. DEBUG_SYNC_C_IF_THD(thr_get_trx(thr)->mysql_thd,
  192. "foreign_constraint_check_for_insert");
  193. for (dict_foreign_set::iterator it = table->referenced_set.begin();
  194. it != table->referenced_set.end();
  195. ++it) {
  196. foreign = *it;
  197. /* Note that we may have an update which updates the index
  198. record, but does NOT update the first fields which are
  199. referenced in a foreign key constraint. Then the update does
  200. NOT break the constraint. */
  201. if (foreign->referenced_index == index
  202. && (node->is_delete
  203. || row_upd_changes_first_fields_binary(
  204. entry, index, node->update,
  205. foreign->n_fields))) {
  206. dict_table_t* foreign_table = foreign->foreign_table;
  207. dict_table_t* ref_table = NULL;
  208. if (foreign_table == NULL) {
  209. ref_table = dict_table_open_on_name(
  210. foreign->foreign_table_name_lookup,
  211. false, DICT_ERR_IGNORE_NONE);
  212. }
  213. err = row_ins_check_foreign_constraint(
  214. FALSE, foreign, table, entry, thr);
  215. if (ref_table) {
  216. dict_table_close(ref_table);
  217. }
  218. if (err != DB_SUCCESS) {
  219. goto func_exit;
  220. }
  221. }
  222. }
  223. err = DB_SUCCESS;
  224. func_exit:
  225. mem_heap_free(heap);
  226. DEBUG_SYNC_C("foreign_constraint_check_for_update_done");
  227. DBUG_RETURN(err);
  228. }
  229. #ifdef WITH_WSREP
  230. static
  231. dberr_t
  232. wsrep_row_upd_check_foreign_constraints(
  233. /*=================================*/
  234. upd_node_t* node, /*!< in: row update node */
  235. btr_pcur_t* pcur, /*!< in: cursor positioned on a record; NOTE: the
  236. cursor position is lost in this function! */
  237. dict_table_t* table, /*!< in: table in question */
  238. dict_index_t* index, /*!< in: index of the cursor */
  239. rec_offs* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */
  240. que_thr_t* thr, /*!< in: query thread */
  241. mtr_t* mtr) /*!< in: mtr */
  242. {
  243. dict_foreign_t* foreign;
  244. mem_heap_t* heap;
  245. dtuple_t* entry;
  246. const rec_t* rec;
  247. dberr_t err;
  248. ibool opened = FALSE;
  249. if (table->foreign_set.empty()) {
  250. return(DB_SUCCESS);
  251. }
  252. /* TODO: make native slave thread bail out here */
  253. rec = btr_pcur_get_rec(pcur);
  254. ut_ad(rec_offs_validate(rec, index, offsets));
  255. heap = mem_heap_create(500);
  256. entry = row_rec_to_index_entry(rec, index, offsets, heap);
  257. mtr_commit(mtr);
  258. mtr_start(mtr);
  259. for (dict_foreign_set::iterator it = table->foreign_set.begin();
  260. it != table->foreign_set.end();
  261. ++it) {
  262. foreign = *it;
  263. /* Note that we may have an update which updates the index
  264. record, but does NOT update the first fields which are
  265. referenced in a foreign key constraint. Then the update does
  266. NOT break the constraint. */
  267. if (foreign->foreign_index == index
  268. && (node->is_delete
  269. || row_upd_changes_first_fields_binary(
  270. entry, index, node->update,
  271. foreign->n_fields))) {
  272. if (foreign->referenced_table == NULL) {
  273. foreign->referenced_table =
  274. dict_table_open_on_name(
  275. foreign->referenced_table_name_lookup,
  276. false, DICT_ERR_IGNORE_NONE);
  277. opened = (foreign->referenced_table) ? TRUE : FALSE;
  278. }
  279. /* NOTE that if the thread ends up waiting for a lock
  280. we will release dict_sys.latch temporarily!
  281. But the counter on the table protects 'foreign' from
  282. being dropped while the check is running. */
  283. err = row_ins_check_foreign_constraint(
  284. TRUE, foreign, table, entry, thr);
  285. if (foreign->referenced_table) {
  286. if (opened) {
  287. dict_table_close(foreign->referenced_table);
  288. opened = FALSE;
  289. }
  290. }
  291. if (err != DB_SUCCESS) {
  292. goto func_exit;
  293. }
  294. }
  295. }
  296. err = DB_SUCCESS;
  297. func_exit:
  298. mem_heap_free(heap);
  299. return(err);
  300. }
  301. /** Determine if a FOREIGN KEY constraint needs to be processed.
  302. @param[in] node query node
  303. @param[in] trx transaction
  304. @return whether the node cannot be ignored */
  305. inline bool wsrep_must_process_fk(const upd_node_t* node, const trx_t* trx)
  306. {
  307. if (!trx->is_wsrep()) {
  308. return false;
  309. }
  310. return que_node_get_type(node->common.parent) != QUE_NODE_UPDATE
  311. || static_cast<upd_node_t*>(node->common.parent)->cascade_node
  312. != node;
  313. }
  314. #endif /* WITH_WSREP */
  315. /*********************************************************************//**
  316. Creates an update node for a query graph.
  317. @return own: update node */
  318. upd_node_t*
  319. upd_node_create(
  320. /*============*/
  321. mem_heap_t* heap) /*!< in: mem heap where created */
  322. {
  323. upd_node_t* node;
  324. node = static_cast<upd_node_t*>(
  325. mem_heap_zalloc(heap, sizeof(upd_node_t)));
  326. node->common.type = QUE_NODE_UPDATE;
  327. node->state = UPD_NODE_UPDATE_CLUSTERED;
  328. node->heap = mem_heap_create(128);
  329. node->magic_n = UPD_NODE_MAGIC_N;
  330. return(node);
  331. }
  332. /***********************************************************//**
  333. Returns TRUE if row update changes size of some field in index or if some
  334. field to be updated is stored externally in rec or update.
  335. @return TRUE if the update changes the size of some field in index or
  336. the field is external in rec or update */
  337. ibool
  338. row_upd_changes_field_size_or_external(
  339. /*===================================*/
  340. dict_index_t* index, /*!< in: index */
  341. const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
  342. const upd_t* update) /*!< in: update vector */
  343. {
  344. const upd_field_t* upd_field;
  345. const dfield_t* new_val;
  346. ulint old_len;
  347. ulint new_len;
  348. ulint n_fields;
  349. ulint i;
  350. ut_ad(rec_offs_validate(NULL, index, offsets));
  351. ut_ad(!index->table->skip_alter_undo);
  352. n_fields = upd_get_n_fields(update);
  353. for (i = 0; i < n_fields; i++) {
  354. upd_field = upd_get_nth_field(update, i);
  355. /* We should ignore virtual field if the index is not
  356. a virtual index */
  357. if (upd_fld_is_virtual_col(upd_field)
  358. && !index->has_virtual()) {
  359. continue;
  360. }
  361. new_val = &(upd_field->new_val);
  362. if (dfield_is_ext(new_val)) {
  363. return(TRUE);
  364. }
  365. new_len = dfield_get_len(new_val);
  366. ut_ad(new_len != UNIV_SQL_DEFAULT);
  367. if (dfield_is_null(new_val) && !rec_offs_comp(offsets)) {
  368. new_len = dict_col_get_sql_null_size(
  369. dict_index_get_nth_col(index,
  370. upd_field->field_no),
  371. 0);
  372. }
  373. if (rec_offs_nth_default(offsets, upd_field->field_no)) {
  374. /* This is an instantly added column that is
  375. at the initial default value. */
  376. return(TRUE);
  377. }
  378. if (rec_offs_comp(offsets)
  379. && rec_offs_nth_sql_null(offsets, upd_field->field_no)) {
  380. /* Note that in the compact table format, for a
  381. variable length field, an SQL NULL will use zero
  382. bytes in the offset array at the start of the physical
  383. record, but a zero-length value (empty string) will
  384. use one byte! Thus, we cannot use update-in-place
  385. if we update an SQL NULL varchar to an empty string! */
  386. old_len = UNIV_SQL_NULL;
  387. } else {
  388. old_len = rec_offs_nth_size(offsets,
  389. upd_field->field_no);
  390. }
  391. if (old_len != new_len
  392. || rec_offs_nth_extern(offsets, upd_field->field_no)) {
  393. return(TRUE);
  394. }
  395. }
  396. return(FALSE);
  397. }
  398. /***********************************************************//**
  399. Returns true if row update contains disowned external fields.
  400. @return true if the update contains disowned external fields. */
  401. bool
  402. row_upd_changes_disowned_external(
  403. /*==============================*/
  404. const upd_t* update) /*!< in: update vector */
  405. {
  406. const upd_field_t* upd_field;
  407. const dfield_t* new_val;
  408. ulint new_len;
  409. ulint n_fields;
  410. ulint i;
  411. n_fields = upd_get_n_fields(update);
  412. for (i = 0; i < n_fields; i++) {
  413. const byte* field_ref;
  414. upd_field = upd_get_nth_field(update, i);
  415. new_val = &(upd_field->new_val);
  416. new_len = dfield_get_len(new_val);
  417. if (!dfield_is_ext(new_val)) {
  418. continue;
  419. }
  420. ut_ad(new_len >= BTR_EXTERN_FIELD_REF_SIZE);
  421. field_ref = static_cast<const byte*>(dfield_get_data(new_val))
  422. + new_len - BTR_EXTERN_FIELD_REF_SIZE;
  423. if (field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG) {
  424. return(true);
  425. }
  426. }
  427. return(false);
  428. }
  429. /***************************************************************//**
  430. Builds an update vector from those fields which in a secondary index entry
  431. differ from a record that has the equal ordering fields. NOTE: we compare
  432. the fields as binary strings!
  433. @return own: update vector of differing fields */
  434. upd_t*
  435. row_upd_build_sec_rec_difference_binary(
  436. /*====================================*/
  437. const rec_t* rec, /*!< in: secondary index record */
  438. dict_index_t* index, /*!< in: index */
  439. const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */
  440. const dtuple_t* entry, /*!< in: entry to insert */
  441. mem_heap_t* heap) /*!< in: memory heap from which allocated */
  442. {
  443. upd_field_t* upd_field;
  444. const dfield_t* dfield;
  445. const byte* data;
  446. ulint len;
  447. upd_t* update;
  448. ulint n_diff;
  449. /* This function is used only for a secondary index */
  450. ut_a(!dict_index_is_clust(index));
  451. ut_ad(rec_offs_validate(rec, index, offsets));
  452. ut_ad(rec_offs_n_fields(offsets) == dtuple_get_n_fields(entry));
  453. ut_ad(!rec_offs_any_extern(offsets));
  454. ut_ad(!rec_offs_any_default(offsets));
  455. ut_ad(!index->table->skip_alter_undo);
  456. update = upd_create(dtuple_get_n_fields(entry), heap);
  457. n_diff = 0;
  458. for (uint16_t i = 0; i < dtuple_get_n_fields(entry); i++) {
  459. data = rec_get_nth_field(rec, offsets, i, &len);
  460. dfield = dtuple_get_nth_field(entry, i);
  461. /* NOTE that it may be that len != dfield_get_len(dfield) if we
  462. are updating in a character set and collation where strings of
  463. different length can be equal in an alphabetical comparison,
  464. and also in the case where we have a column prefix index
  465. and the last characters in the index field are spaces; the
  466. latter case probably caused the assertion failures reported at
  467. row0upd.cc line 713 in versions 4.0.14 - 4.0.16. */
  468. /* NOTE: we compare the fields as binary strings!
  469. (No collation) */
  470. if (!dfield_data_is_binary_equal(dfield, len, data)) {
  471. upd_field = upd_get_nth_field(update, n_diff);
  472. dfield_copy(&(upd_field->new_val), dfield);
  473. upd_field_set_field_no(upd_field, i, index);
  474. n_diff++;
  475. }
  476. }
  477. update->n_fields = n_diff;
  478. return(update);
  479. }
  480. /** Builds an update vector from those fields, excluding the roll ptr and
  481. trx id fields, which in an index entry differ from a record that has
  482. the equal ordering fields. NOTE: we compare the fields as binary strings!
  483. @param[in] index clustered index
  484. @param[in] entry clustered index entry to insert
  485. @param[in] rec clustered index record
  486. @param[in] offsets rec_get_offsets(rec,index), or NULL
  487. @param[in] no_sys skip the system columns
  488. DB_TRX_ID and DB_ROLL_PTR
  489. @param[in] trx transaction (for diagnostics),
  490. or NULL
  491. @param[in] heap memory heap from which allocated
  492. @param[in] mysql_table NULL, or mysql table object when
  493. user thread invokes dml
  494. @param[out] error error number in case of failure
  495. @return own: update vector of differing fields, excluding roll ptr and
  496. trx id,if error is not equal to DB_SUCCESS, return NULL */
  497. upd_t*
  498. row_upd_build_difference_binary(
  499. dict_index_t* index,
  500. const dtuple_t* entry,
  501. const rec_t* rec,
  502. const rec_offs* offsets,
  503. bool no_sys,
  504. trx_t* trx,
  505. mem_heap_t* heap,
  506. TABLE* mysql_table,
  507. dberr_t* error)
  508. {
  509. ulint len;
  510. upd_t* update;
  511. ulint n_diff;
  512. rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
  513. const ulint n_v_fld = dtuple_get_n_v_fields(entry);
  514. rec_offs_init(offsets_);
  515. /* This function is used only for a clustered index */
  516. ut_a(dict_index_is_clust(index));
  517. ut_ad(!index->table->skip_alter_undo);
  518. ut_ad(entry->n_fields <= index->n_fields);
  519. ut_ad(entry->n_fields >= index->n_core_fields);
  520. update = upd_create(index->n_fields + n_v_fld, heap);
  521. n_diff = 0;
  522. if (!offsets) {
  523. offsets = rec_get_offsets(rec, index, offsets_,
  524. index->n_core_fields,
  525. ULINT_UNDEFINED, &heap);
  526. } else {
  527. ut_ad(rec_offs_validate(rec, index, offsets));
  528. }
  529. for (uint16_t i = 0; i < entry->n_fields; i++) {
  530. const byte* data = rec_get_nth_cfield(rec, index, offsets, i,
  531. &len);
  532. const dfield_t* dfield = dtuple_get_nth_field(entry, i);
  533. /* NOTE: we compare the fields as binary strings!
  534. (No collation) */
  535. if (no_sys && (i == index->db_trx_id()
  536. || i == index->db_roll_ptr())) {
  537. continue;
  538. }
  539. if (!dfield_is_ext(dfield)
  540. != !rec_offs_nth_extern(offsets, i)
  541. || !dfield_data_is_binary_equal(dfield, len, data)) {
  542. upd_field_t* uf = upd_get_nth_field(update, n_diff++);
  543. dfield_copy(&uf->new_val, dfield);
  544. upd_field_set_field_no(uf, i, index);
  545. }
  546. }
  547. for (uint16_t i = static_cast<uint16_t>(entry->n_fields);
  548. i < index->n_fields; i++) {
  549. upd_field_t* uf = upd_get_nth_field(update, n_diff++);
  550. const dict_col_t* col = dict_index_get_nth_col(index, i);
  551. /* upd_create() zero-initialized uf */
  552. uf->new_val.data = const_cast<byte*>(col->instant_value(&len));
  553. uf->new_val.len = static_cast<unsigned>(len);
  554. dict_col_copy_type(col, &uf->new_val.type);
  555. upd_field_set_field_no(uf, i, index);
  556. }
  557. /* Check the virtual columns updates. Even if there is no non-virtual
  558. column (base columns) change, we will still need to build the
  559. indexed virtual column value so that undo log would log them (
  560. for purge/mvcc purpose) */
  561. if (n_v_fld > 0) {
  562. row_ext_t* ext;
  563. THD* thd;
  564. if (trx == NULL) {
  565. thd = current_thd;
  566. } else {
  567. thd = trx->mysql_thd;
  568. }
  569. ut_ad(!update->old_vrow);
  570. ib_vcol_row vc(NULL);
  571. uchar *record = vc.record(thd, index, &mysql_table);
  572. for (uint16_t i = 0; i < n_v_fld; i++) {
  573. const dict_v_col_t* col
  574. = dict_table_get_nth_v_col(index->table, i);
  575. if (!col->m_col.ord_part) {
  576. continue;
  577. }
  578. if (update->old_vrow == NULL) {
  579. update->old_vrow = row_build(
  580. ROW_COPY_POINTERS, index, rec, offsets,
  581. index->table, NULL, NULL, &ext, heap);
  582. }
  583. dfield_t* vfield = innobase_get_computed_value(
  584. update->old_vrow, col, index,
  585. &vc.heap, heap, NULL, thd, mysql_table, record,
  586. NULL, NULL);
  587. if (vfield == NULL) {
  588. *error = DB_COMPUTE_VALUE_FAILED;
  589. return(NULL);
  590. }
  591. const dfield_t* dfield = dtuple_get_nth_v_field(
  592. entry, i);
  593. if (!dfield_data_is_binary_equal(
  594. dfield, vfield->len,
  595. static_cast<byte*>(vfield->data))) {
  596. upd_field_t* uf = upd_get_nth_field(update,
  597. n_diff++);
  598. uf->old_v_val = static_cast<dfield_t*>(
  599. mem_heap_alloc(heap,
  600. sizeof *uf->old_v_val));
  601. dfield_copy(uf->old_v_val, vfield);
  602. dfield_copy(&uf->new_val, dfield);
  603. upd_field_set_v_field_no(uf, i, index);
  604. }
  605. }
  606. }
  607. update->n_fields = n_diff;
  608. ut_ad(update->validate());
  609. return(update);
  610. }
  611. /** Fetch a prefix of an externally stored column.
  612. This is similar to row_ext_lookup(), but the row_ext_t holds the old values
  613. of the column and must not be poisoned with the new values.
  614. @param[in] data 'internally' stored part of the field
  615. containing also the reference to the external part
  616. @param[in] local_len length of data, in bytes
  617. @param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
  618. @param[in,out] len input - length of prefix to
  619. fetch; output: fetched length of the prefix
  620. @param[in,out] heap heap where to allocate
  621. @return BLOB prefix
  622. @retval NULL if the record is incomplete (should only happen
  623. in row_vers_vc_matches_cluster() executed concurrently with another purge) */
  624. static
  625. byte*
  626. row_upd_ext_fetch(
  627. const byte* data,
  628. ulint local_len,
  629. ulint zip_size,
  630. ulint* len,
  631. mem_heap_t* heap)
  632. {
  633. byte* buf = static_cast<byte*>(mem_heap_alloc(heap, *len));
  634. *len = btr_copy_externally_stored_field_prefix(
  635. buf, *len, zip_size, data, local_len);
  636. return *len ? buf : NULL;
  637. }
  638. /** Replaces the new column value stored in the update vector in
  639. the given index entry field.
  640. @param[in,out] dfield data field of the index entry
  641. @param[in] field index field
  642. @param[in] col field->col
  643. @param[in] uf update field
  644. @param[in,out] heap memory heap for allocating and copying
  645. the new value
  646. @param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
  647. @return whether the previous version was built successfully */
  648. MY_ATTRIBUTE((nonnull, warn_unused_result))
  649. static
  650. bool
  651. row_upd_index_replace_new_col_val(
  652. dfield_t* dfield,
  653. const dict_field_t* field,
  654. const dict_col_t* col,
  655. const upd_field_t* uf,
  656. mem_heap_t* heap,
  657. ulint zip_size)
  658. {
  659. ulint len;
  660. const byte* data;
  661. dfield_copy_data(dfield, &uf->new_val);
  662. if (dfield_is_null(dfield)) {
  663. return true;
  664. }
  665. len = dfield_get_len(dfield);
  666. data = static_cast<const byte*>(dfield_get_data(dfield));
  667. if (field->prefix_len > 0) {
  668. ibool fetch_ext = dfield_is_ext(dfield)
  669. && len < (ulint) field->prefix_len
  670. + BTR_EXTERN_FIELD_REF_SIZE;
  671. if (fetch_ext) {
  672. ulint l = len;
  673. len = field->prefix_len;
  674. data = row_upd_ext_fetch(data, l, zip_size,
  675. &len, heap);
  676. if (UNIV_UNLIKELY(!data)) {
  677. return false;
  678. }
  679. }
  680. len = dtype_get_at_most_n_mbchars(col->prtype,
  681. col->mbminlen, col->mbmaxlen,
  682. field->prefix_len, len,
  683. (const char*) data);
  684. dfield_set_data(dfield, data, len);
  685. if (!fetch_ext) {
  686. dfield_dup(dfield, heap);
  687. }
  688. return true;
  689. }
  690. switch (uf->orig_len) {
  691. byte* buf;
  692. case BTR_EXTERN_FIELD_REF_SIZE:
  693. /* Restore the original locally stored
  694. part of the column. In the undo log,
  695. InnoDB writes a longer prefix of externally
  696. stored columns, so that column prefixes
  697. in secondary indexes can be reconstructed. */
  698. dfield_set_data(dfield,
  699. data + len - BTR_EXTERN_FIELD_REF_SIZE,
  700. BTR_EXTERN_FIELD_REF_SIZE);
  701. dfield_set_ext(dfield);
  702. /* fall through */
  703. case 0:
  704. dfield_dup(dfield, heap);
  705. break;
  706. default:
  707. /* Reconstruct the original locally
  708. stored part of the column. The data
  709. will have to be copied. */
  710. ut_a(uf->orig_len > BTR_EXTERN_FIELD_REF_SIZE);
  711. buf = static_cast<byte*>(mem_heap_alloc(heap, uf->orig_len));
  712. /* Copy the locally stored prefix. */
  713. memcpy(buf, data,
  714. unsigned(uf->orig_len) - BTR_EXTERN_FIELD_REF_SIZE);
  715. /* Copy the BLOB pointer. */
  716. memcpy(buf + uf->orig_len - BTR_EXTERN_FIELD_REF_SIZE,
  717. data + len - BTR_EXTERN_FIELD_REF_SIZE,
  718. BTR_EXTERN_FIELD_REF_SIZE);
  719. dfield_set_data(dfield, buf, uf->orig_len);
  720. dfield_set_ext(dfield);
  721. break;
  722. }
  723. return true;
  724. }
  725. /** Apply an update vector to an metadata entry.
  726. @param[in,out] entry clustered index metadata record to be updated
  727. @param[in] index index of the entry
  728. @param[in] update update vector built for the entry
  729. @param[in,out] heap memory heap for copying off-page columns */
  730. static
  731. void
  732. row_upd_index_replace_metadata(
  733. dtuple_t* entry,
  734. const dict_index_t* index,
  735. const upd_t* update,
  736. mem_heap_t* heap)
  737. {
  738. ut_ad(!index->table->skip_alter_undo);
  739. ut_ad(update->is_alter_metadata());
  740. ut_ad(entry->info_bits == update->info_bits);
  741. ut_ad(entry->n_fields == ulint(index->n_fields) + 1);
  742. const ulint zip_size = index->table->space->zip_size();
  743. const ulint first = index->first_user_field();
  744. ut_d(bool found_mblob = false);
  745. for (ulint i = upd_get_n_fields(update); i--; ) {
  746. const upd_field_t* uf = upd_get_nth_field(update, i);
  747. ut_ad(!upd_fld_is_virtual_col(uf));
  748. ut_ad(uf->field_no >= first - 2);
  749. ulint f = uf->field_no;
  750. dfield_t* dfield = dtuple_get_nth_field(entry, f);
  751. if (f == first) {
  752. ut_d(found_mblob = true);
  753. ut_ad(!dfield_is_null(&uf->new_val));
  754. ut_ad(dfield_is_ext(dfield));
  755. ut_ad(dfield_get_len(dfield) == FIELD_REF_SIZE);
  756. ut_ad(!dfield_is_null(dfield));
  757. dfield_set_data(dfield, uf->new_val.data,
  758. uf->new_val.len);
  759. if (dfield_is_ext(&uf->new_val)) {
  760. dfield_set_ext(dfield);
  761. }
  762. continue;
  763. }
  764. f -= f > first;
  765. const dict_field_t* field = dict_index_get_nth_field(index, f);
  766. if (!row_upd_index_replace_new_col_val(dfield, field,
  767. field->col,
  768. uf, heap, zip_size)) {
  769. ut_error;
  770. }
  771. }
  772. ut_ad(found_mblob);
  773. }
  774. /** Apply an update vector to an index entry.
  775. @param[in,out] entry index entry to be updated; the clustered index record
  776. must be covered by a lock or a page latch to prevent
  777. deletion (rollback or purge)
  778. @param[in] index index of the entry
  779. @param[in] update update vector built for the entry
  780. @param[in,out] heap memory heap for copying off-page columns */
  781. void
  782. row_upd_index_replace_new_col_vals_index_pos(
  783. dtuple_t* entry,
  784. const dict_index_t* index,
  785. const upd_t* update,
  786. mem_heap_t* heap)
  787. {
  788. ut_ad(!index->table->skip_alter_undo);
  789. ut_ad(!entry->is_metadata() || entry->info_bits == update->info_bits);
  790. if (UNIV_UNLIKELY(entry->is_alter_metadata())) {
  791. row_upd_index_replace_metadata(entry, index, update, heap);
  792. return;
  793. }
  794. const ulint zip_size = index->table->space->zip_size();
  795. dtuple_set_info_bits(entry, update->info_bits);
  796. for (uint16_t i = index->n_fields; i--; ) {
  797. const dict_field_t* field;
  798. const dict_col_t* col;
  799. const upd_field_t* uf;
  800. field = dict_index_get_nth_field(index, i);
  801. col = dict_field_get_col(field);
  802. if (col->is_virtual()) {
  803. const dict_v_col_t* vcol = reinterpret_cast<
  804. const dict_v_col_t*>(
  805. col);
  806. uf = upd_get_field_by_field_no(
  807. update, vcol->v_pos, true);
  808. } else {
  809. uf = upd_get_field_by_field_no(
  810. update, i, false);
  811. }
  812. if (uf && UNIV_UNLIKELY(!row_upd_index_replace_new_col_val(
  813. dtuple_get_nth_field(entry, i),
  814. field, col, uf, heap,
  815. zip_size))) {
  816. ut_error;
  817. }
  818. }
  819. }
  820. /** Replace the new column values stored in the update vector,
  821. during trx_undo_prev_version_build().
  822. @param entry clustered index tuple where the values are replaced
  823. (the clustered index leaf page latch must be held)
  824. @param index clustered index
  825. @param update update vector for the clustered index
  826. @param heap memory heap for allocating and copying values
  827. @return whether the previous version was built successfully */
  828. bool
  829. row_upd_index_replace_new_col_vals(dtuple_t *entry, const dict_index_t &index,
  830. const upd_t *update, mem_heap_t *heap)
  831. {
  832. ut_ad(index.is_primary());
  833. const ulint zip_size= index.table->space->zip_size();
  834. ut_ad(!index.table->skip_alter_undo);
  835. dtuple_set_info_bits(entry, update->info_bits);
  836. for (ulint i= 0; i < index.n_fields; i++)
  837. {
  838. const dict_field_t *field= &index.fields[i];
  839. const dict_col_t* col= dict_field_get_col(field);
  840. const upd_field_t *uf;
  841. if (col->is_virtual())
  842. {
  843. const dict_v_col_t *vcol= reinterpret_cast<const dict_v_col_t*>(col);
  844. uf= upd_get_field_by_field_no(update, vcol->v_pos, true);
  845. }
  846. else
  847. uf= upd_get_field_by_field_no(update, static_cast<uint16_t>
  848. (dict_col_get_clust_pos(col, &index)),
  849. false);
  850. if (!uf)
  851. continue;
  852. if (!row_upd_index_replace_new_col_val(dtuple_get_nth_field(entry, i),
  853. field, col, uf, heap, zip_size))
  854. return false;
  855. }
  856. return true;
  857. }
  858. /** Replaces the virtual column values stored in the update vector.
  859. @param[in,out] row row whose column to be set
  860. @param[in] field data to set
  861. @param[in] len data length
  862. @param[in] vcol virtual column info */
  863. static
  864. void
  865. row_upd_set_vcol_data(
  866. dtuple_t* row,
  867. const byte* field,
  868. ulint len,
  869. dict_v_col_t* vcol)
  870. {
  871. dfield_t* dfield = dtuple_get_nth_v_field(row, vcol->v_pos);
  872. if (dfield_get_type(dfield)->mtype == DATA_MISSING) {
  873. dict_col_copy_type(&vcol->m_col, dfield_get_type(dfield));
  874. dfield_set_data(dfield, field, len);
  875. }
  876. }
  877. /** Replaces the virtual column values stored in a dtuple with that of
  878. a update vector.
  879. @param[in,out] row row whose column to be updated
  880. @param[in] table table
  881. @param[in] update an update vector built for the clustered index
  882. @param[in] upd_new update to new or old value
  883. @param[in,out] undo_row undo row (if needs to be updated)
  884. @param[in] ptr remaining part in update undo log */
  885. void
  886. row_upd_replace_vcol(
  887. dtuple_t* row,
  888. const dict_table_t* table,
  889. const upd_t* update,
  890. bool upd_new,
  891. dtuple_t* undo_row,
  892. const byte* ptr)
  893. {
  894. ulint col_no;
  895. ulint i;
  896. ulint n_cols;
  897. ut_ad(!table->skip_alter_undo);
  898. n_cols = dtuple_get_n_v_fields(row);
  899. for (col_no = 0; col_no < n_cols; col_no++) {
  900. dfield_t* dfield;
  901. const dict_v_col_t* col
  902. = dict_table_get_nth_v_col(table, col_no);
  903. /* If there is no index on the column, do not bother for
  904. value update */
  905. if (!col->m_col.ord_part) {
  906. continue;
  907. }
  908. dfield = dtuple_get_nth_v_field(row, col_no);
  909. for (i = 0; i < upd_get_n_fields(update); i++) {
  910. const upd_field_t* upd_field
  911. = upd_get_nth_field(update, i);
  912. if (!upd_fld_is_virtual_col(upd_field)
  913. || upd_field->field_no != col->v_pos) {
  914. continue;
  915. }
  916. if (upd_new) {
  917. dfield_copy_data(dfield, &upd_field->new_val);
  918. } else {
  919. dfield_copy_data(dfield, upd_field->old_v_val);
  920. }
  921. dfield->type = upd_field->new_val.type;
  922. break;
  923. }
  924. }
  925. bool first_v_col = true;
  926. bool is_undo_log = true;
  927. /* We will read those unchanged (but indexed) virtual columns in */
  928. if (ptr != NULL) {
  929. const byte* end_ptr;
  930. end_ptr = ptr + mach_read_from_2(ptr);
  931. ptr += 2;
  932. while (ptr != end_ptr) {
  933. const byte* field;
  934. uint32_t field_no, len, orig_len;
  935. field_no = mach_read_next_compressed(&ptr);
  936. const bool is_v = (field_no >= REC_MAX_N_FIELDS);
  937. if (is_v) {
  938. ptr = trx_undo_read_v_idx(
  939. table, ptr, first_v_col, &is_undo_log,
  940. &field_no);
  941. first_v_col = false;
  942. }
  943. ptr = trx_undo_rec_get_col_val(
  944. ptr, &field, &len, &orig_len);
  945. if (field_no == FIL_NULL) {
  946. ut_ad(is_v);
  947. continue;
  948. }
  949. if (is_v) {
  950. dict_v_col_t* vcol = dict_table_get_nth_v_col(
  951. table, field_no);
  952. row_upd_set_vcol_data(row, field, len, vcol);
  953. if (undo_row) {
  954. row_upd_set_vcol_data(
  955. undo_row, field, len, vcol);
  956. }
  957. }
  958. ut_ad(ptr<= end_ptr);
  959. }
  960. }
  961. }
  962. /***********************************************************//**
  963. Replaces the new column values stored in the update vector. */
  964. void
  965. row_upd_replace(
  966. /*============*/
  967. dtuple_t* row, /*!< in/out: row where replaced,
  968. indexed by col_no;
  969. the clustered index record must be
  970. covered by a lock or a page latch to
  971. prevent deletion (rollback or purge) */
  972. row_ext_t** ext, /*!< out, own: NULL, or externally
  973. stored column prefixes */
  974. const dict_index_t* index, /*!< in: clustered index */
  975. const upd_t* update, /*!< in: an update vector built for the
  976. clustered index */
  977. mem_heap_t* heap) /*!< in: memory heap */
  978. {
  979. ulint col_no;
  980. ulint i;
  981. ulint n_cols;
  982. ulint n_ext_cols;
  983. ulint* ext_cols;
  984. const dict_table_t* table;
  985. ut_ad(row);
  986. ut_ad(ext);
  987. ut_ad(index);
  988. ut_ad(dict_index_is_clust(index));
  989. ut_ad(update);
  990. ut_ad(heap);
  991. ut_ad(update->validate());
  992. n_cols = dtuple_get_n_fields(row);
  993. table = index->table;
  994. ut_ad(n_cols == dict_table_get_n_cols(table));
  995. ext_cols = static_cast<ulint*>(
  996. mem_heap_alloc(heap, n_cols * sizeof *ext_cols));
  997. n_ext_cols = 0;
  998. dtuple_set_info_bits(row, update->info_bits);
  999. for (col_no = 0; col_no < n_cols; col_no++) {
  1000. const dict_col_t* col
  1001. = dict_table_get_nth_col(table, col_no);
  1002. const ulint clust_pos
  1003. = dict_col_get_clust_pos(col, index);
  1004. dfield_t* dfield;
  1005. if (UNIV_UNLIKELY(clust_pos == ULINT_UNDEFINED)) {
  1006. continue;
  1007. }
  1008. dfield = dtuple_get_nth_field(row, col_no);
  1009. for (i = 0; i < upd_get_n_fields(update); i++) {
  1010. const upd_field_t* upd_field
  1011. = upd_get_nth_field(update, i);
  1012. if (upd_field->field_no != clust_pos
  1013. || upd_fld_is_virtual_col(upd_field)) {
  1014. continue;
  1015. }
  1016. dfield_copy_data(dfield, &upd_field->new_val);
  1017. break;
  1018. }
  1019. if (dfield_is_ext(dfield) && col->ord_part) {
  1020. ext_cols[n_ext_cols++] = col_no;
  1021. }
  1022. }
  1023. if (n_ext_cols) {
  1024. *ext = row_ext_create(n_ext_cols, ext_cols, *table, row, heap);
  1025. } else {
  1026. *ext = NULL;
  1027. }
  1028. row_upd_replace_vcol(row, table, update, true, NULL, NULL);
  1029. }
  1030. /***********************************************************//**
  1031. Checks if an update vector changes an ordering field of an index record.
  1032. This function is fast if the update vector is short or the number of ordering
  1033. fields in the index is small. Otherwise, this can be quadratic.
  1034. NOTE: we compare the fields as binary strings!
  1035. @return TRUE if update vector changes an ordering field in the index record */
  1036. ibool
  1037. row_upd_changes_ord_field_binary_func(
  1038. /*==================================*/
  1039. dict_index_t* index, /*!< in: index of the record */
  1040. const upd_t* update, /*!< in: update vector for the row; NOTE: the
  1041. field numbers in this MUST be clustered index
  1042. positions! */
  1043. #ifdef UNIV_DEBUG
  1044. const que_thr_t*thr, /*!< in: query thread */
  1045. #endif /* UNIV_DEBUG */
  1046. const dtuple_t* row, /*!< in: old value of row, or NULL if the
  1047. row and the data values in update are not
  1048. known when this function is called, e.g., at
  1049. compile time */
  1050. const row_ext_t*ext, /*!< NULL, or prefixes of the externally
  1051. stored columns in the old row */
  1052. ulint flag) /*!< in: ROW_BUILD_NORMAL,
  1053. ROW_BUILD_FOR_PURGE or ROW_BUILD_FOR_UNDO */
  1054. {
  1055. ulint n_unique;
  1056. ulint i;
  1057. const dict_index_t* clust_index;
  1058. ut_ad(thr);
  1059. ut_ad(thr->graph);
  1060. ut_ad(thr->graph->trx);
  1061. ut_ad(!index->table->skip_alter_undo);
  1062. n_unique = dict_index_get_n_unique(index);
  1063. clust_index = dict_table_get_first_index(index->table);
  1064. for (i = 0; i < n_unique; i++) {
  1065. const dict_field_t* ind_field;
  1066. const dict_col_t* col;
  1067. ulint col_no;
  1068. const upd_field_t* upd_field;
  1069. const dfield_t* dfield;
  1070. dfield_t dfield_ext;
  1071. ulint dfield_len= 0;
  1072. const byte* buf;
  1073. bool is_virtual;
  1074. const dict_v_col_t* vcol = NULL;
  1075. ind_field = dict_index_get_nth_field(index, i);
  1076. col = dict_field_get_col(ind_field);
  1077. col_no = dict_col_get_no(col);
  1078. is_virtual = col->is_virtual();
  1079. if (is_virtual) {
  1080. vcol = reinterpret_cast<const dict_v_col_t*>(col);
  1081. upd_field = upd_get_field_by_field_no(
  1082. update, vcol->v_pos, true);
  1083. } else {
  1084. upd_field = upd_get_field_by_field_no(
  1085. update, static_cast<uint16_t>(
  1086. dict_col_get_clust_pos(
  1087. col, clust_index)),
  1088. false);
  1089. }
  1090. if (upd_field == NULL) {
  1091. continue;
  1092. }
  1093. if (row == NULL) {
  1094. ut_ad(ext == NULL);
  1095. return(TRUE);
  1096. }
  1097. if (is_virtual) {
  1098. dfield = dtuple_get_nth_v_field(
  1099. row, vcol->v_pos);
  1100. } else {
  1101. dfield = dtuple_get_nth_field(row, col_no);
  1102. }
  1103. /* For spatial index update, since the different geometry
  1104. data could generate same MBR, so, if the new index entry is
  1105. same as old entry, which means the MBR is not changed, we
  1106. don't need to do anything. */
  1107. if (dict_index_is_spatial(index) && i == 0) {
  1108. double mbr1[SPDIMS * 2];
  1109. double mbr2[SPDIMS * 2];
  1110. rtr_mbr_t* old_mbr;
  1111. rtr_mbr_t* new_mbr;
  1112. const uchar* dptr = NULL;
  1113. ulint flen = 0;
  1114. ulint dlen = 0;
  1115. mem_heap_t* temp_heap = NULL;
  1116. const dfield_t* new_field = &upd_field->new_val;
  1117. const ulint zip_size = ext
  1118. ? ext->zip_size
  1119. : index->table->space->zip_size();
  1120. ut_ad(dfield->data != NULL
  1121. && dfield->len > GEO_DATA_HEADER_SIZE);
  1122. ut_ad(dict_col_get_spatial_status(col) != SPATIAL_NONE);
  1123. /* Get the old mbr. */
  1124. if (dfield_is_ext(dfield)) {
  1125. /* For off-page stored data, we
  1126. need to read the whole field data. */
  1127. flen = dfield_get_len(dfield);
  1128. dptr = static_cast<const byte*>(
  1129. dfield_get_data(dfield));
  1130. temp_heap = mem_heap_create(1000);
  1131. dptr = btr_copy_externally_stored_field(
  1132. &dlen, dptr,
  1133. zip_size,
  1134. flen,
  1135. temp_heap);
  1136. } else {
  1137. dptr = static_cast<const uchar*>(dfield->data);
  1138. dlen = dfield->len;
  1139. }
  1140. rtree_mbr_from_wkb(dptr + GEO_DATA_HEADER_SIZE,
  1141. static_cast<uint>(dlen
  1142. - GEO_DATA_HEADER_SIZE),
  1143. SPDIMS, mbr1);
  1144. old_mbr = reinterpret_cast<rtr_mbr_t*>(mbr1);
  1145. /* Get the new mbr. */
  1146. if (dfield_is_ext(new_field)) {
  1147. if (flag == ROW_BUILD_FOR_UNDO
  1148. && dict_table_has_atomic_blobs(
  1149. index->table)) {
  1150. /* For ROW_FORMAT=DYNAMIC
  1151. or COMPRESSED, a prefix of
  1152. off-page records is stored
  1153. in the undo log record
  1154. (for any column prefix indexes).
  1155. For SPATIAL INDEX, we must
  1156. ignore this prefix. The
  1157. full column value is stored in
  1158. the BLOB.
  1159. For non-spatial index, we
  1160. would have already fetched a
  1161. necessary prefix of the BLOB,
  1162. available in the "ext" parameter.
  1163. Here, for SPATIAL INDEX, we are
  1164. fetching the full column, which is
  1165. potentially wasting a lot of I/O,
  1166. memory, and possibly involving a
  1167. concurrency problem, similar to ones
  1168. that existed before the introduction
  1169. of row_ext_t.
  1170. MDEV-11657 FIXME: write the MBR
  1171. directly to the undo log record,
  1172. and avoid recomputing it here! */
  1173. flen = BTR_EXTERN_FIELD_REF_SIZE;
  1174. ut_ad(dfield_get_len(new_field) >=
  1175. BTR_EXTERN_FIELD_REF_SIZE);
  1176. dptr = static_cast<const byte*>(
  1177. dfield_get_data(new_field))
  1178. + dfield_get_len(new_field)
  1179. - BTR_EXTERN_FIELD_REF_SIZE;
  1180. } else {
  1181. flen = dfield_get_len(new_field);
  1182. dptr = static_cast<const byte*>(
  1183. dfield_get_data(new_field));
  1184. }
  1185. if (temp_heap == NULL) {
  1186. temp_heap = mem_heap_create(1000);
  1187. }
  1188. dptr = btr_copy_externally_stored_field(
  1189. &dlen, dptr,
  1190. zip_size,
  1191. flen,
  1192. temp_heap);
  1193. } else {
  1194. dptr = static_cast<const byte*>(
  1195. upd_field->new_val.data);
  1196. dlen = upd_field->new_val.len;
  1197. }
  1198. rtree_mbr_from_wkb(dptr + GEO_DATA_HEADER_SIZE,
  1199. static_cast<uint>(dlen
  1200. - GEO_DATA_HEADER_SIZE),
  1201. SPDIMS, mbr2);
  1202. new_mbr = reinterpret_cast<rtr_mbr_t*>(mbr2);
  1203. if (temp_heap) {
  1204. mem_heap_free(temp_heap);
  1205. }
  1206. if (!MBR_EQUAL_CMP(old_mbr, new_mbr)) {
  1207. return(TRUE);
  1208. } else {
  1209. continue;
  1210. }
  1211. }
  1212. /* This treatment of column prefix indexes is loosely
  1213. based on row_build_index_entry(). */
  1214. if (UNIV_LIKELY(ind_field->prefix_len == 0)
  1215. || dfield_is_null(dfield)) {
  1216. /* do nothing special */
  1217. } else if (ext) {
  1218. /* Silence a compiler warning without
  1219. silencing a Valgrind error. */
  1220. dfield_len = 0;
  1221. MEM_UNDEFINED(&dfield_len, sizeof dfield_len);
  1222. /* See if the column is stored externally. */
  1223. buf = row_ext_lookup(ext, col_no, &dfield_len);
  1224. ut_ad(col->ord_part);
  1225. if (UNIV_LIKELY_NULL(buf)) {
  1226. if (UNIV_UNLIKELY(buf == field_ref_zero)) {
  1227. /* The externally stored field
  1228. was not written yet. This
  1229. record should only be seen by
  1230. trx_rollback_recovered()
  1231. when the server had crashed before
  1232. storing the field. */
  1233. ut_ad(thr->graph->trx->is_recovered);
  1234. ut_ad(thr->graph->trx
  1235. == trx_roll_crash_recv_trx);
  1236. return(TRUE);
  1237. }
  1238. goto copy_dfield;
  1239. }
  1240. } else if (dfield_is_ext(dfield)) {
  1241. dfield_len = dfield_get_len(dfield);
  1242. ut_a(dfield_len > BTR_EXTERN_FIELD_REF_SIZE);
  1243. dfield_len -= BTR_EXTERN_FIELD_REF_SIZE;
  1244. ut_a(dict_index_is_clust(index)
  1245. || ind_field->prefix_len <= dfield_len);
  1246. buf= static_cast<const byte*>(dfield_get_data(dfield));
  1247. copy_dfield:
  1248. ut_a(dfield_len > 0);
  1249. dfield_copy(&dfield_ext, dfield);
  1250. dfield_set_data(&dfield_ext, buf, dfield_len);
  1251. dfield = &dfield_ext;
  1252. }
  1253. if (!dfield_datas_are_binary_equal(
  1254. dfield, &upd_field->new_val,
  1255. ind_field->prefix_len)) {
  1256. return(TRUE);
  1257. }
  1258. }
  1259. return(FALSE);
  1260. }
  1261. /***********************************************************//**
  1262. Checks if an update vector changes an ordering field of an index record.
  1263. NOTE: we compare the fields as binary strings!
  1264. @return TRUE if update vector may change an ordering field in an index
  1265. record */
  1266. ibool
  1267. row_upd_changes_some_index_ord_field_binary(
  1268. /*========================================*/
  1269. const dict_table_t* table, /*!< in: table */
  1270. const upd_t* update) /*!< in: update vector for the row */
  1271. {
  1272. upd_field_t* upd_field;
  1273. dict_index_t* index;
  1274. ulint i;
  1275. index = dict_table_get_first_index(table);
  1276. for (i = 0; i < upd_get_n_fields(update); i++) {
  1277. upd_field = upd_get_nth_field(update, i);
  1278. if (upd_fld_is_virtual_col(upd_field)) {
  1279. if (dict_table_get_nth_v_col(index->table,
  1280. upd_field->field_no)
  1281. ->m_col.ord_part) {
  1282. return(TRUE);
  1283. }
  1284. } else {
  1285. if (dict_field_get_col(dict_index_get_nth_field(
  1286. index, upd_field->field_no))->ord_part) {
  1287. return(TRUE);
  1288. }
  1289. }
  1290. }
  1291. return(FALSE);
  1292. }
  1293. /***********************************************************//**
  1294. Checks if an FTS Doc ID column is affected by an UPDATE.
  1295. @return whether the Doc ID column is changed */
  1296. bool
  1297. row_upd_changes_doc_id(
  1298. /*===================*/
  1299. dict_table_t* table, /*!< in: table */
  1300. upd_field_t* upd_field) /*!< in: field to check */
  1301. {
  1302. ulint col_no;
  1303. dict_index_t* clust_index;
  1304. fts_t* fts = table->fts;
  1305. ut_ad(!table->skip_alter_undo);
  1306. clust_index = dict_table_get_first_index(table);
  1307. /* Convert from index-specific column number to table-global
  1308. column number. */
  1309. col_no = dict_index_get_nth_col_no(clust_index, upd_field->field_no);
  1310. return(col_no == fts->doc_col);
  1311. }
  1312. /***********************************************************//**
  1313. Checks if an FTS indexed column is affected by an UPDATE.
  1314. @return offset within fts_t::indexes if FTS indexed column updated else
  1315. ULINT_UNDEFINED */
  1316. ulint
  1317. row_upd_changes_fts_column(
  1318. /*=======================*/
  1319. dict_table_t* table, /*!< in: table */
  1320. upd_field_t* upd_field) /*!< in: field to check */
  1321. {
  1322. ulint col_no;
  1323. dict_index_t* clust_index;
  1324. fts_t* fts = table->fts;
  1325. ut_ad(!table->skip_alter_undo);
  1326. if (upd_fld_is_virtual_col(upd_field)) {
  1327. col_no = upd_field->field_no;
  1328. return(dict_table_is_fts_column(fts->indexes, col_no, true));
  1329. } else {
  1330. clust_index = dict_table_get_first_index(table);
  1331. /* Convert from index-specific column number to table-global
  1332. column number. */
  1333. col_no = dict_index_get_nth_col_no(clust_index,
  1334. upd_field->field_no);
  1335. return(dict_table_is_fts_column(fts->indexes, col_no, false));
  1336. }
  1337. }
  1338. /***********************************************************//**
  1339. Checks if an update vector changes some of the first ordering fields of an
  1340. index record. This is only used in foreign key checks and we can assume
  1341. that index does not contain column prefixes.
  1342. @return TRUE if changes */
  1343. static
  1344. ibool
  1345. row_upd_changes_first_fields_binary(
  1346. /*================================*/
  1347. dtuple_t* entry, /*!< in: index entry */
  1348. dict_index_t* index, /*!< in: index of entry */
  1349. const upd_t* update, /*!< in: update vector for the row */
  1350. ulint n) /*!< in: how many first fields to check */
  1351. {
  1352. ulint n_upd_fields;
  1353. ulint i, j;
  1354. dict_index_t* clust_index;
  1355. ut_ad(update && index);
  1356. ut_ad(n <= dict_index_get_n_fields(index));
  1357. n_upd_fields = upd_get_n_fields(update);
  1358. clust_index = dict_table_get_first_index(index->table);
  1359. for (i = 0; i < n; i++) {
  1360. const dict_field_t* ind_field;
  1361. const dict_col_t* col;
  1362. ulint col_pos;
  1363. ind_field = dict_index_get_nth_field(index, i);
  1364. col = dict_field_get_col(ind_field);
  1365. col_pos = dict_col_get_clust_pos(col, clust_index);
  1366. ut_a(ind_field->prefix_len == 0);
  1367. for (j = 0; j < n_upd_fields; j++) {
  1368. upd_field_t* upd_field
  1369. = upd_get_nth_field(update, j);
  1370. if (col_pos == upd_field->field_no
  1371. && !dfield_datas_are_binary_equal(
  1372. dtuple_get_nth_field(entry, i),
  1373. &upd_field->new_val, 0)) {
  1374. return(TRUE);
  1375. }
  1376. }
  1377. }
  1378. return(FALSE);
  1379. }
  1380. /*********************************************************************//**
  1381. Copies the column values from a record. */
  1382. UNIV_INLINE
  1383. void
  1384. row_upd_copy_columns(
  1385. /*=================*/
  1386. rec_t* rec, /*!< in: record in a clustered index */
  1387. const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */
  1388. const dict_index_t* index, /*!< in: index of rec */
  1389. sym_node_t* column) /*!< in: first column in a column list, or
  1390. NULL */
  1391. {
  1392. ut_ad(dict_index_is_clust(index));
  1393. const byte* data;
  1394. ulint len;
  1395. while (column) {
  1396. data = rec_get_nth_cfield(
  1397. rec, index, offsets,
  1398. column->field_nos[SYM_CLUST_FIELD_NO], &len);
  1399. eval_node_copy_and_alloc_val(column, data, len);
  1400. column = UT_LIST_GET_NEXT(col_var_list, column);
  1401. }
  1402. }
  1403. /*********************************************************************//**
  1404. Calculates the new values for fields to update. Note that row_upd_copy_columns
  1405. must have been called first. */
  1406. UNIV_INLINE
  1407. void
  1408. row_upd_eval_new_vals(
  1409. /*==================*/
  1410. upd_t* update) /*!< in/out: update vector */
  1411. {
  1412. que_node_t* exp;
  1413. upd_field_t* upd_field;
  1414. ulint n_fields;
  1415. ulint i;
  1416. n_fields = upd_get_n_fields(update);
  1417. for (i = 0; i < n_fields; i++) {
  1418. upd_field = upd_get_nth_field(update, i);
  1419. exp = upd_field->exp;
  1420. eval_exp(exp);
  1421. dfield_copy_data(&(upd_field->new_val), que_node_get_val(exp));
  1422. }
  1423. }
  1424. /** Stores to the heap the virtual columns that need for any indexes
  1425. @param[in,out] node row update node
  1426. @param[in] update an update vector if it is update
  1427. @param[in] thd mysql thread handle
  1428. @param[in,out] mysql_table mysql table object
  1429. @return true if success
  1430. false if virtual column value computation fails. */
  1431. static
  1432. bool
  1433. row_upd_store_v_row(
  1434. upd_node_t* node,
  1435. const upd_t* update,
  1436. THD* thd,
  1437. TABLE* mysql_table)
  1438. {
  1439. dict_index_t* index = dict_table_get_first_index(node->table);
  1440. ib_vcol_row vc(NULL);
  1441. for (ulint col_no = 0; col_no < dict_table_get_n_v_cols(node->table);
  1442. col_no++) {
  1443. const dict_v_col_t* col
  1444. = dict_table_get_nth_v_col(node->table, col_no);
  1445. if (col->m_col.ord_part) {
  1446. dfield_t* dfield
  1447. = dtuple_get_nth_v_field(node->row, col_no);
  1448. ulint n_upd
  1449. = update ? upd_get_n_fields(update) : 0;
  1450. ulint i = 0;
  1451. /* Check if the value is already in update vector */
  1452. for (i = 0; i < n_upd; i++) {
  1453. const upd_field_t* upd_field
  1454. = upd_get_nth_field(update, i);
  1455. if (!(upd_field->new_val.type.prtype
  1456. & DATA_VIRTUAL)
  1457. || upd_field->field_no != col->v_pos) {
  1458. continue;
  1459. }
  1460. dfield_copy_data(dfield, upd_field->old_v_val);
  1461. dfield_dup(dfield, node->heap);
  1462. break;
  1463. }
  1464. /* Not updated */
  1465. if (i >= n_upd) {
  1466. /* If this is an update, then the value
  1467. should be in update->old_vrow */
  1468. if (update) {
  1469. if (update->old_vrow == NULL) {
  1470. /* This only happens in
  1471. cascade update. And virtual
  1472. column can't be affected,
  1473. so it is Ok to set it to NULL */
  1474. dfield_set_null(dfield);
  1475. } else {
  1476. dfield_t* vfield
  1477. = dtuple_get_nth_v_field(
  1478. update->old_vrow,
  1479. col_no);
  1480. dfield_copy_data(dfield, vfield);
  1481. dfield_dup(dfield, node->heap);
  1482. }
  1483. } else {
  1484. uchar *record = vc.record(thd, index,
  1485. &mysql_table);
  1486. /* Need to compute, this happens when
  1487. deleting row */
  1488. dfield_t* vfield =
  1489. innobase_get_computed_value(
  1490. node->row, col, index,
  1491. &vc.heap, node->heap,
  1492. NULL, thd, mysql_table,
  1493. record, NULL, NULL);
  1494. if (vfield == NULL) {
  1495. return false;
  1496. }
  1497. }
  1498. }
  1499. }
  1500. }
  1501. return true;
  1502. }
  1503. /** Stores to the heap the row on which the node->pcur is positioned.
  1504. @param[in] node row update node
  1505. @param[in] thd mysql thread handle
  1506. @param[in,out] mysql_table NULL, or mysql table object when
  1507. user thread invokes dml
  1508. @return false if virtual column value computation fails
  1509. true otherwise. */
  1510. static
  1511. bool
  1512. row_upd_store_row(
  1513. upd_node_t* node,
  1514. THD* thd,
  1515. TABLE* mysql_table)
  1516. {
  1517. dict_index_t* clust_index;
  1518. rec_t* rec;
  1519. mem_heap_t* heap = NULL;
  1520. row_ext_t** ext;
  1521. rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
  1522. const rec_offs* offsets;
  1523. rec_offs_init(offsets_);
  1524. ut_ad(node->pcur->latch_mode != BTR_NO_LATCHES);
  1525. if (node->row != NULL) {
  1526. mem_heap_empty(node->heap);
  1527. }
  1528. clust_index = dict_table_get_first_index(node->table);
  1529. rec = btr_pcur_get_rec(node->pcur);
  1530. offsets = rec_get_offsets(rec, clust_index, offsets_,
  1531. clust_index->n_core_fields,
  1532. ULINT_UNDEFINED, &heap);
  1533. if (dict_table_has_atomic_blobs(node->table)) {
  1534. /* There is no prefix of externally stored columns in
  1535. the clustered index record. Build a cache of column
  1536. prefixes. */
  1537. ext = &node->ext;
  1538. } else {
  1539. /* REDUNDANT and COMPACT formats store a local
  1540. 768-byte prefix of each externally stored column.
  1541. No cache is needed. */
  1542. ext = NULL;
  1543. node->ext = NULL;
  1544. }
  1545. node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets,
  1546. NULL, NULL, NULL, ext, node->heap);
  1547. if (node->table->n_v_cols) {
  1548. bool ok = row_upd_store_v_row(node,
  1549. node->is_delete ? NULL : node->update,
  1550. thd, mysql_table);
  1551. if (!ok) {
  1552. return false;
  1553. }
  1554. }
  1555. if (node->is_delete == PLAIN_DELETE) {
  1556. node->upd_row = NULL;
  1557. node->upd_ext = NULL;
  1558. } else {
  1559. node->upd_row = dtuple_copy(node->row, node->heap);
  1560. row_upd_replace(node->upd_row, &node->upd_ext,
  1561. clust_index, node->update, node->heap);
  1562. }
  1563. if (UNIV_LIKELY_NULL(heap)) {
  1564. mem_heap_free(heap);
  1565. }
  1566. return true;
  1567. }
  1568. /***********************************************************//**
  1569. Updates a secondary index entry of a row.
  1570. @return DB_SUCCESS if operation successfully completed, else error
  1571. code or DB_LOCK_WAIT */
  1572. static MY_ATTRIBUTE((nonnull, warn_unused_result))
  1573. dberr_t
  1574. row_upd_sec_index_entry(
  1575. /*====================*/
  1576. upd_node_t* node, /*!< in: row update node */
  1577. que_thr_t* thr) /*!< in: query thread */
  1578. {
  1579. mtr_t mtr;
  1580. const rec_t* rec;
  1581. btr_pcur_t pcur;
  1582. mem_heap_t* heap;
  1583. dtuple_t* entry;
  1584. dict_index_t* index;
  1585. btr_cur_t* btr_cur;
  1586. dberr_t err = DB_SUCCESS;
  1587. trx_t* trx = thr_get_trx(thr);
  1588. ulint mode;
  1589. ulint flags;
  1590. enum row_search_result search_result;
  1591. ut_ad(trx->id != 0);
  1592. index = node->index;
  1593. if (!index->is_committed()) {
  1594. return DB_SUCCESS;
  1595. }
  1596. /* For secondary indexes, index->online_status==ONLINE_INDEX_COMPLETE
  1597. if index->is_committed(). */
  1598. ut_ad(!dict_index_is_online_ddl(index));
  1599. const bool referenced = row_upd_index_is_referenced(index, trx);
  1600. #ifdef WITH_WSREP
  1601. const bool foreign = wsrep_row_upd_index_is_foreign(index, trx);
  1602. #endif /* WITH_WSREP */
  1603. heap = mem_heap_create(1024);
  1604. /* Build old index entry */
  1605. entry = row_build_index_entry(node->row, node->ext, index, heap);
  1606. ut_a(entry);
  1607. log_free_check();
  1608. DEBUG_SYNC_C_IF_THD(trx->mysql_thd,
  1609. "before_row_upd_sec_index_entry");
  1610. mtr.start();
  1611. switch (index->table->space_id) {
  1612. case SRV_TMP_SPACE_ID:
  1613. mtr.set_log_mode(MTR_LOG_NO_REDO);
  1614. flags = BTR_NO_LOCKING_FLAG;
  1615. mode = index->is_spatial()
  1616. ? ulint(BTR_MODIFY_LEAF | BTR_RTREE_DELETE_MARK)
  1617. : ulint(BTR_MODIFY_LEAF);
  1618. break;
  1619. default:
  1620. index->set_modified(mtr);
  1621. /* fall through */
  1622. case IBUF_SPACE_ID:
  1623. flags = index->table->no_rollback() ? BTR_NO_ROLLBACK : 0;
  1624. /* We can only buffer delete-mark operations if there
  1625. are no foreign key constraints referring to the index. */
  1626. mode = index->is_spatial()
  1627. ? ulint(BTR_MODIFY_LEAF | BTR_RTREE_DELETE_MARK)
  1628. : referenced
  1629. ? ulint(BTR_MODIFY_LEAF) : ulint(BTR_DELETE_MARK_LEAF);
  1630. break;
  1631. }
  1632. /* Set the query thread, so that ibuf_insert_low() will be
  1633. able to invoke thd_get_trx(). */
  1634. btr_pcur_get_btr_cur(&pcur)->thr = thr;
  1635. search_result = row_search_index_entry(index, entry, mode,
  1636. &pcur, &mtr);
  1637. btr_cur = btr_pcur_get_btr_cur(&pcur);
  1638. rec = btr_cur_get_rec(btr_cur);
  1639. switch (search_result) {
  1640. case ROW_NOT_DELETED_REF: /* should only occur for BTR_DELETE */
  1641. ut_error;
  1642. break;
  1643. case ROW_BUFFERED:
  1644. /* Entry was delete marked already. */
  1645. break;
  1646. case ROW_NOT_FOUND:
  1647. if (dict_index_is_spatial(index) && btr_cur->rtr_info->fd_del) {
  1648. /* We found the record, but a delete marked */
  1649. break;
  1650. }
  1651. ib::error()
  1652. << "Record in index " << index->name
  1653. << " of table " << index->table->name
  1654. << " was not found on update: " << *entry
  1655. << " at: " << rec_index_print(rec, index);
  1656. #ifdef UNIV_DEBUG
  1657. mtr_commit(&mtr);
  1658. mtr_start(&mtr);
  1659. ut_ad(btr_validate_index(index, 0) == DB_SUCCESS);
  1660. ut_ad(0);
  1661. #endif /* UNIV_DEBUG */
  1662. break;
  1663. case ROW_FOUND:
  1664. ut_ad(err == DB_SUCCESS);
  1665. /* Delete mark the old index record; it can already be
  1666. delete marked if we return after a lock wait in
  1667. row_ins_sec_index_entry() below */
  1668. if (!rec_get_deleted_flag(
  1669. rec, dict_table_is_comp(index->table))) {
  1670. err = lock_sec_rec_modify_check_and_lock(
  1671. flags,
  1672. btr_cur_get_block(btr_cur),
  1673. btr_cur_get_rec(btr_cur), index, thr, &mtr);
  1674. if (err != DB_SUCCESS) {
  1675. break;
  1676. }
  1677. btr_rec_set_deleted<true>(btr_cur_get_block(btr_cur),
  1678. btr_cur_get_rec(btr_cur),
  1679. &mtr);
  1680. #ifdef WITH_WSREP
  1681. if (!referenced && foreign
  1682. && wsrep_must_process_fk(node, trx)
  1683. && !wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
  1684. rec_offs* offsets = rec_get_offsets(
  1685. rec, index, NULL, index->n_core_fields,
  1686. ULINT_UNDEFINED, &heap);
  1687. err = wsrep_row_upd_check_foreign_constraints(
  1688. node, &pcur, index->table,
  1689. index, offsets, thr, &mtr);
  1690. switch (err) {
  1691. case DB_SUCCESS:
  1692. case DB_NO_REFERENCED_ROW:
  1693. err = DB_SUCCESS;
  1694. break;
  1695. case DB_LOCK_WAIT:
  1696. case DB_DEADLOCK:
  1697. case DB_LOCK_WAIT_TIMEOUT:
  1698. WSREP_DEBUG("Foreign key check fail: "
  1699. "%s on table %s index %s query %s",
  1700. ut_strerr(err), index->name(), index->table->name.m_name,
  1701. wsrep_thd_query(trx->mysql_thd));
  1702. break;
  1703. default:
  1704. WSREP_ERROR("Foreign key check fail: "
  1705. "%s on table %s index %s query %s",
  1706. ut_strerr(err), index->name(), index->table->name.m_name,
  1707. wsrep_thd_query(trx->mysql_thd));
  1708. break;
  1709. }
  1710. }
  1711. #endif /* WITH_WSREP */
  1712. }
  1713. #ifdef WITH_WSREP
  1714. ut_ad(err == DB_SUCCESS || err == DB_LOCK_WAIT
  1715. || err == DB_DEADLOCK || err == DB_LOCK_WAIT_TIMEOUT);
  1716. #else
  1717. ut_ad(err == DB_SUCCESS);
  1718. #endif
  1719. if (referenced) {
  1720. rec_offs* offsets = rec_get_offsets(
  1721. rec, index, NULL, index->n_core_fields,
  1722. ULINT_UNDEFINED, &heap);
  1723. /* NOTE that the following call loses
  1724. the position of pcur ! */
  1725. err = row_upd_check_references_constraints(
  1726. node, &pcur, index->table,
  1727. index, offsets, thr, &mtr);
  1728. }
  1729. }
  1730. btr_pcur_close(&pcur);
  1731. mtr_commit(&mtr);
  1732. if (node->is_delete == PLAIN_DELETE || err != DB_SUCCESS) {
  1733. goto func_exit;
  1734. }
  1735. mem_heap_empty(heap);
  1736. DEBUG_SYNC_C_IF_THD(trx->mysql_thd,
  1737. "before_row_upd_sec_new_index_entry");
  1738. /* Build a new index entry */
  1739. entry = row_build_index_entry(node->upd_row, node->upd_ext,
  1740. index, heap);
  1741. ut_a(entry);
  1742. /* Insert new index entry */
  1743. err = row_ins_sec_index_entry(index, entry, thr, !node->is_delete);
  1744. func_exit:
  1745. mem_heap_free(heap);
  1746. return(err);
  1747. }
  1748. /***********************************************************//**
  1749. Updates the secondary index record if it is changed in the row update or
  1750. deletes it if this is a delete.
  1751. @return DB_SUCCESS if operation successfully completed, else error
  1752. code or DB_LOCK_WAIT */
  1753. static MY_ATTRIBUTE((nonnull, warn_unused_result))
  1754. dberr_t
  1755. row_upd_sec_step(
  1756. /*=============*/
  1757. upd_node_t* node, /*!< in: row update node */
  1758. que_thr_t* thr) /*!< in: query thread */
  1759. {
  1760. ut_ad((node->state == UPD_NODE_UPDATE_ALL_SEC)
  1761. || (node->state == UPD_NODE_UPDATE_SOME_SEC));
  1762. ut_ad(!dict_index_is_clust(node->index));
  1763. if (node->state == UPD_NODE_UPDATE_ALL_SEC
  1764. || row_upd_changes_ord_field_binary(node->index, node->update,
  1765. thr, node->row, node->ext)) {
  1766. return(row_upd_sec_index_entry(node, thr));
  1767. }
  1768. return(DB_SUCCESS);
  1769. }
  1770. #ifdef UNIV_DEBUG
  1771. # define row_upd_clust_rec_by_insert_inherit(rec,index,offsets,entry,update) \
  1772. row_upd_clust_rec_by_insert_inherit_func(rec,index,offsets,entry,update)
  1773. #else /* UNIV_DEBUG */
  1774. # define row_upd_clust_rec_by_insert_inherit(rec,index,offsets,entry,update) \
  1775. row_upd_clust_rec_by_insert_inherit_func(rec,entry,update)
  1776. #endif /* UNIV_DEBUG */
  1777. /*******************************************************************//**
  1778. Mark non-updated off-page columns inherited when the primary key is
  1779. updated. We must mark them as inherited in entry, so that they are not
  1780. freed in a rollback. A limited version of this function used to be
  1781. called btr_cur_mark_dtuple_inherited_extern().
  1782. @return whether any columns were inherited */
  1783. static
  1784. bool
  1785. row_upd_clust_rec_by_insert_inherit_func(
  1786. /*=====================================*/
  1787. const rec_t* rec, /*!< in: old record, or NULL */
  1788. #ifdef UNIV_DEBUG
  1789. dict_index_t* index, /*!< in: index, or NULL */
  1790. const rec_offs* offsets,/*!< in: rec_get_offsets(rec), or NULL */
  1791. #endif /* UNIV_DEBUG */
  1792. dtuple_t* entry, /*!< in/out: updated entry to be
  1793. inserted into the clustered index */
  1794. const upd_t* update) /*!< in: update vector */
  1795. {
  1796. bool inherit = false;
  1797. ut_ad(!rec == !offsets);
  1798. ut_ad(!rec == !index);
  1799. ut_ad(!rec || rec_offs_validate(rec, index, offsets));
  1800. ut_ad(!rec || rec_offs_any_extern(offsets));
  1801. for (uint16_t i = 0; i < dtuple_get_n_fields(entry); i++) {
  1802. dfield_t* dfield = dtuple_get_nth_field(entry, i);
  1803. byte* data;
  1804. ulint len;
  1805. ut_ad(!offsets
  1806. || !rec_offs_nth_extern(offsets, i)
  1807. == !dfield_is_ext(dfield)
  1808. || (!dict_index_get_nth_field(index, i)->name
  1809. && !dfield_is_ext(dfield)
  1810. && (dfield_is_null(dfield) || dfield->len == 0))
  1811. || upd_get_field_by_field_no(update, i, false));
  1812. if (!dfield_is_ext(dfield)
  1813. || upd_get_field_by_field_no(update, i, false)) {
  1814. continue;
  1815. }
  1816. #ifdef UNIV_DEBUG
  1817. if (UNIV_LIKELY(rec != NULL)) {
  1818. ut_ad(!rec_offs_nth_default(offsets, i));
  1819. const byte* rec_data
  1820. = rec_get_nth_field(rec, offsets, i, &len);
  1821. ut_ad(len == dfield_get_len(dfield));
  1822. ut_ad(len != UNIV_SQL_NULL);
  1823. ut_ad(len >= BTR_EXTERN_FIELD_REF_SIZE);
  1824. rec_data += len - BTR_EXTERN_FIELD_REF_SIZE;
  1825. /* The pointer must not be zero. */
  1826. ut_ad(memcmp(rec_data, field_ref_zero,
  1827. BTR_EXTERN_FIELD_REF_SIZE));
  1828. /* The BLOB must be owned. */
  1829. ut_ad(!(rec_data[BTR_EXTERN_LEN]
  1830. & BTR_EXTERN_OWNER_FLAG));
  1831. }
  1832. #endif /* UNIV_DEBUG */
  1833. len = dfield_get_len(dfield);
  1834. ut_a(len != UNIV_SQL_NULL);
  1835. ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
  1836. data = static_cast<byte*>(dfield_get_data(dfield));
  1837. data += len - BTR_EXTERN_FIELD_REF_SIZE;
  1838. /* The pointer must not be zero. */
  1839. ut_a(memcmp(data, field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE));
  1840. /* The BLOB must be owned, unless we are resuming from
  1841. a lock wait and we already had disowned the BLOB. */
  1842. ut_a(rec == NULL
  1843. || !(data[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG));
  1844. data[BTR_EXTERN_LEN] &= byte(~BTR_EXTERN_OWNER_FLAG);
  1845. data[BTR_EXTERN_LEN] |= BTR_EXTERN_INHERITED_FLAG;
  1846. /* The BTR_EXTERN_INHERITED_FLAG only matters in
  1847. rollback of a fresh insert. Purge will always free
  1848. the extern fields of a delete-marked row. */
  1849. inherit = true;
  1850. }
  1851. return(inherit);
  1852. }
  1853. /***********************************************************//**
  1854. Marks the clustered index record deleted and inserts the updated version
  1855. of the record to the index. This function should be used when the ordering
  1856. fields of the clustered index record change. This should be quite rare in
  1857. database applications.
  1858. @return DB_SUCCESS if operation successfully completed, else error
  1859. code or DB_LOCK_WAIT */
  1860. static MY_ATTRIBUTE((nonnull, warn_unused_result))
  1861. dberr_t
  1862. row_upd_clust_rec_by_insert(
  1863. /*========================*/
  1864. upd_node_t* node, /*!< in/out: row update node */
  1865. dict_index_t* index, /*!< in: clustered index of the record */
  1866. que_thr_t* thr, /*!< in: query thread */
  1867. bool referenced,/*!< in: whether index may be referenced in
  1868. a foreign key constraint */
  1869. #ifdef WITH_WSREP
  1870. bool foreign,/*!< in: whether this is a foreign key */
  1871. #endif
  1872. mtr_t* mtr) /*!< in/out: mini-transaction,
  1873. may be committed and restarted */
  1874. {
  1875. mem_heap_t* heap;
  1876. btr_pcur_t* pcur;
  1877. btr_cur_t* btr_cur;
  1878. trx_t* trx;
  1879. dict_table_t* table;
  1880. dtuple_t* entry;
  1881. dberr_t err;
  1882. rec_t* rec;
  1883. rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
  1884. rec_offs* offsets = offsets_;
  1885. ut_ad(dict_index_is_clust(index));
  1886. rec_offs_init(offsets_);
  1887. trx = thr_get_trx(thr);
  1888. table = node->table;
  1889. pcur = node->pcur;
  1890. btr_cur = btr_pcur_get_btr_cur(pcur);
  1891. heap = mem_heap_create(1000);
  1892. entry = row_build_index_entry_low(node->upd_row, node->upd_ext,
  1893. index, heap, ROW_BUILD_FOR_INSERT);
  1894. if (index->is_instant()) entry->trim(*index);
  1895. ut_ad(dtuple_get_info_bits(entry) == 0);
  1896. {
  1897. dfield_t* t = dtuple_get_nth_field(entry, index->db_trx_id());
  1898. ut_ad(t->len == DATA_TRX_ID_LEN);
  1899. trx_write_trx_id(static_cast<byte*>(t->data), trx->id);
  1900. }
  1901. switch (node->state) {
  1902. default:
  1903. ut_error;
  1904. case UPD_NODE_INSERT_CLUSTERED:
  1905. /* A lock wait occurred in row_ins_clust_index_entry() in
  1906. the previous invocation of this function. */
  1907. row_upd_clust_rec_by_insert_inherit(
  1908. NULL, NULL, NULL, entry, node->update);
  1909. break;
  1910. case UPD_NODE_UPDATE_CLUSTERED:
  1911. /* This is the first invocation of the function where
  1912. we update the primary key. Delete-mark the old record
  1913. in the clustered index and prepare to insert a new entry. */
  1914. rec = btr_cur_get_rec(btr_cur);
  1915. offsets = rec_get_offsets(rec, index, offsets,
  1916. index->n_core_fields,
  1917. ULINT_UNDEFINED, &heap);
  1918. ut_ad(page_rec_is_user_rec(rec));
  1919. if (rec_get_deleted_flag(rec, rec_offs_comp(offsets))) {
  1920. /* If the clustered index record is already delete
  1921. marked, then we are here after a DB_LOCK_WAIT.
  1922. Skip delete marking clustered index and disowning
  1923. its blobs. */
  1924. ut_ad(row_get_rec_trx_id(rec, index, offsets)
  1925. == trx->id);
  1926. ut_ad(!trx_undo_roll_ptr_is_insert(
  1927. row_get_rec_roll_ptr(rec, index,
  1928. offsets)));
  1929. goto check_fk;
  1930. }
  1931. err = btr_cur_del_mark_set_clust_rec(
  1932. btr_cur_get_block(btr_cur), rec, index, offsets,
  1933. thr, node->row, mtr);
  1934. if (err != DB_SUCCESS) {
  1935. goto err_exit;
  1936. }
  1937. /* If the the new row inherits externally stored
  1938. fields (off-page columns a.k.a. BLOBs) from the
  1939. delete-marked old record, mark them disowned by the
  1940. old record and owned by the new entry. */
  1941. if (rec_offs_any_extern(offsets)) {
  1942. if (row_upd_clust_rec_by_insert_inherit(
  1943. rec, index, offsets,
  1944. entry, node->update)) {
  1945. /* The blobs are disowned here, expecting the
  1946. insert down below to inherit them. But if the
  1947. insert fails, then this disown will be undone
  1948. when the operation is rolled back. */
  1949. btr_cur_disown_inherited_fields(
  1950. btr_cur_get_block(btr_cur),
  1951. rec, index, offsets, node->update,
  1952. mtr);
  1953. }
  1954. }
  1955. check_fk:
  1956. if (referenced) {
  1957. /* NOTE that the following call loses
  1958. the position of pcur ! */
  1959. err = row_upd_check_references_constraints(
  1960. node, pcur, table, index, offsets, thr, mtr);
  1961. if (err != DB_SUCCESS) {
  1962. goto err_exit;
  1963. }
  1964. #ifdef WITH_WSREP
  1965. } else if (foreign && wsrep_must_process_fk(node, trx)) {
  1966. err = wsrep_row_upd_check_foreign_constraints(
  1967. node, pcur, table, index, offsets, thr, mtr);
  1968. switch (err) {
  1969. case DB_SUCCESS:
  1970. case DB_NO_REFERENCED_ROW:
  1971. err = DB_SUCCESS;
  1972. break;
  1973. case DB_LOCK_WAIT:
  1974. case DB_DEADLOCK:
  1975. case DB_LOCK_WAIT_TIMEOUT:
  1976. WSREP_DEBUG("Foreign key check fail: "
  1977. "%s on table %s index %s query %s",
  1978. ut_strerr(err), index->name(), index->table->name.m_name,
  1979. wsrep_thd_query(trx->mysql_thd));
  1980. goto err_exit;
  1981. default:
  1982. WSREP_ERROR("Foreign key check fail: "
  1983. "%s on table %s index %s query %s",
  1984. ut_strerr(err), index->name(), index->table->name.m_name,
  1985. wsrep_thd_query(trx->mysql_thd));
  1986. goto err_exit;
  1987. }
  1988. #endif /* WITH_WSREP */
  1989. }
  1990. }
  1991. mtr->commit();
  1992. mtr->start();
  1993. node->state = UPD_NODE_INSERT_CLUSTERED;
  1994. err = row_ins_clust_index_entry(index, entry, thr,
  1995. dtuple_get_n_ext(entry));
  1996. err_exit:
  1997. mem_heap_free(heap);
  1998. return(err);
  1999. }
  2000. /***********************************************************//**
  2001. Updates a clustered index record of a row when the ordering fields do
  2002. not change.
  2003. @return DB_SUCCESS if operation successfully completed, else error
  2004. code or DB_LOCK_WAIT */
  2005. static MY_ATTRIBUTE((nonnull, warn_unused_result))
  2006. dberr_t
  2007. row_upd_clust_rec(
  2008. /*==============*/
  2009. ulint flags, /*!< in: undo logging and locking flags */
  2010. upd_node_t* node, /*!< in: row update node */
  2011. dict_index_t* index, /*!< in: clustered index */
  2012. rec_offs* offsets,/*!< in: rec_get_offsets() on node->pcur */
  2013. mem_heap_t** offsets_heap,
  2014. /*!< in/out: memory heap, can be emptied */
  2015. que_thr_t* thr, /*!< in: query thread */
  2016. mtr_t* mtr) /*!< in,out: mini-transaction; may be
  2017. committed and restarted here */
  2018. {
  2019. mem_heap_t* heap = NULL;
  2020. big_rec_t* big_rec = NULL;
  2021. btr_pcur_t* pcur;
  2022. btr_cur_t* btr_cur;
  2023. dberr_t err;
  2024. ut_ad(dict_index_is_clust(index));
  2025. ut_ad(!thr_get_trx(thr)->in_rollback);
  2026. ut_ad(!node->table->skip_alter_undo);
  2027. pcur = node->pcur;
  2028. btr_cur = btr_pcur_get_btr_cur(pcur);
  2029. ut_ad(btr_cur_get_index(btr_cur) == index);
  2030. ut_ad(!rec_get_deleted_flag(btr_cur_get_rec(btr_cur),
  2031. dict_table_is_comp(index->table)));
  2032. ut_ad(rec_offs_validate(btr_cur_get_rec(btr_cur), index, offsets));
  2033. /* Try optimistic updating of the record, keeping changes within
  2034. the page; we do not check locks because we assume the x-lock on the
  2035. record to update */
  2036. if (node->cmpl_info & UPD_NODE_NO_SIZE_CHANGE) {
  2037. err = btr_cur_update_in_place(
  2038. flags | BTR_NO_LOCKING_FLAG, btr_cur,
  2039. offsets, node->update,
  2040. node->cmpl_info, thr, thr_get_trx(thr)->id, mtr);
  2041. } else {
  2042. err = btr_cur_optimistic_update(
  2043. flags | BTR_NO_LOCKING_FLAG, btr_cur,
  2044. &offsets, offsets_heap, node->update,
  2045. node->cmpl_info, thr, thr_get_trx(thr)->id, mtr);
  2046. }
  2047. if (err == DB_SUCCESS) {
  2048. goto func_exit;
  2049. }
  2050. if (buf_pool.running_out()) {
  2051. err = DB_LOCK_TABLE_FULL;
  2052. goto func_exit;
  2053. }
  2054. /* We may have to modify the tree structure: do a pessimistic descent
  2055. down the index tree */
  2056. mtr->commit();
  2057. mtr->start();
  2058. if (index->table->is_temporary()) {
  2059. /* Disable locking, because temporary tables are never
  2060. shared between transactions or connections. */
  2061. flags |= BTR_NO_LOCKING_FLAG;
  2062. mtr->set_log_mode(MTR_LOG_NO_REDO);
  2063. } else {
  2064. index->set_modified(*mtr);
  2065. }
  2066. /* NOTE: this transaction has an s-lock or x-lock on the record and
  2067. therefore other transactions cannot modify the record when we have no
  2068. latch on the page. In addition, we assume that other query threads of
  2069. the same transaction do not modify the record in the meantime.
  2070. Therefore we can assert that the restoration of the cursor succeeds. */
  2071. ut_a(pcur->restore_position(BTR_MODIFY_TREE, mtr) ==
  2072. btr_pcur_t::SAME_ALL);
  2073. ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),
  2074. dict_table_is_comp(index->table)));
  2075. if (!heap) {
  2076. heap = mem_heap_create(1024);
  2077. }
  2078. err = btr_cur_pessimistic_update(
  2079. flags | BTR_NO_LOCKING_FLAG | BTR_KEEP_POS_FLAG, btr_cur,
  2080. &offsets, offsets_heap, heap, &big_rec,
  2081. node->update, node->cmpl_info,
  2082. thr, thr_get_trx(thr)->id, mtr);
  2083. if (big_rec) {
  2084. ut_a(err == DB_SUCCESS);
  2085. DEBUG_SYNC_C("before_row_upd_extern");
  2086. err = btr_store_big_rec_extern_fields(
  2087. pcur, offsets, big_rec, mtr, BTR_STORE_UPDATE);
  2088. DEBUG_SYNC_C("after_row_upd_extern");
  2089. }
  2090. func_exit:
  2091. if (heap) {
  2092. mem_heap_free(heap);
  2093. }
  2094. if (big_rec) {
  2095. dtuple_big_rec_free(big_rec);
  2096. }
  2097. return(err);
  2098. }
  2099. /***********************************************************//**
  2100. Delete marks a clustered index record.
  2101. @return DB_SUCCESS if operation successfully completed, else error code */
  2102. static MY_ATTRIBUTE((nonnull, warn_unused_result))
  2103. dberr_t
  2104. row_upd_del_mark_clust_rec(
  2105. /*=======================*/
  2106. upd_node_t* node, /*!< in: row update node */
  2107. dict_index_t* index, /*!< in: clustered index */
  2108. rec_offs* offsets,/*!< in/out: rec_get_offsets() for the
  2109. record under the cursor */
  2110. que_thr_t* thr, /*!< in: query thread */
  2111. bool referenced,
  2112. /*!< in: whether index may be referenced in
  2113. a foreign key constraint */
  2114. #ifdef WITH_WSREP
  2115. bool foreign,/*!< in: whether this is a foreign key */
  2116. #endif
  2117. mtr_t* mtr) /*!< in,out: mini-transaction;
  2118. will be committed and restarted */
  2119. {
  2120. btr_pcur_t* pcur;
  2121. btr_cur_t* btr_cur;
  2122. rec_t* rec;
  2123. trx_t* trx = thr_get_trx(thr);
  2124. ut_ad(dict_index_is_clust(index));
  2125. ut_ad(node->is_delete == PLAIN_DELETE);
  2126. pcur = node->pcur;
  2127. btr_cur = btr_pcur_get_btr_cur(pcur);
  2128. /* Store row because we have to build also the secondary index
  2129. entries */
  2130. if (!row_upd_store_row(node, trx->mysql_thd,
  2131. thr->prebuilt && thr->prebuilt->table == node->table
  2132. ? thr->prebuilt->m_mysql_table : NULL)) {
  2133. return DB_COMPUTE_VALUE_FAILED;
  2134. }
  2135. /* Mark the clustered index record deleted; we do not have to check
  2136. locks, because we assume that we have an x-lock on the record */
  2137. rec = btr_cur_get_rec(btr_cur);
  2138. dberr_t err = btr_cur_del_mark_set_clust_rec(
  2139. btr_cur_get_block(btr_cur), rec,
  2140. index, offsets, thr, node->row, mtr);
  2141. if (err != DB_SUCCESS) {
  2142. } else if (referenced) {
  2143. /* NOTE that the following call loses the position of pcur ! */
  2144. err = row_upd_check_references_constraints(
  2145. node, pcur, index->table, index, offsets, thr, mtr);
  2146. #ifdef WITH_WSREP
  2147. } else if (foreign && wsrep_must_process_fk(node, trx)) {
  2148. err = wsrep_row_upd_check_foreign_constraints(
  2149. node, pcur, index->table, index, offsets, thr, mtr);
  2150. switch (err) {
  2151. case DB_SUCCESS:
  2152. case DB_NO_REFERENCED_ROW:
  2153. err = DB_SUCCESS;
  2154. break;
  2155. case DB_LOCK_WAIT:
  2156. case DB_DEADLOCK:
  2157. case DB_LOCK_WAIT_TIMEOUT:
  2158. WSREP_DEBUG("Foreign key check fail: "
  2159. "%d on table %s index %s query %s",
  2160. err, index->name(), index->table->name.m_name,
  2161. wsrep_thd_query(trx->mysql_thd));
  2162. break;
  2163. default:
  2164. WSREP_ERROR("Foreign key check fail: "
  2165. "%d on table %s index %s query %s",
  2166. err, index->name(), index->table->name.m_name,
  2167. wsrep_thd_query(trx->mysql_thd));
  2168. break;
  2169. }
  2170. #endif /* WITH_WSREP */
  2171. }
  2172. return(err);
  2173. }
  2174. /***********************************************************//**
  2175. Updates the clustered index record.
  2176. @return DB_SUCCESS if operation successfully completed, DB_LOCK_WAIT
  2177. in case of a lock wait, else error code */
  2178. static MY_ATTRIBUTE((nonnull, warn_unused_result))
  2179. dberr_t
  2180. row_upd_clust_step(
  2181. /*===============*/
  2182. upd_node_t* node, /*!< in: row update node */
  2183. que_thr_t* thr) /*!< in: query thread */
  2184. {
  2185. dict_index_t* index;
  2186. btr_pcur_t* pcur;
  2187. dberr_t err;
  2188. mtr_t mtr;
  2189. rec_t* rec;
  2190. mem_heap_t* heap = NULL;
  2191. rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
  2192. rec_offs* offsets;
  2193. ulint flags;
  2194. trx_t* trx = thr_get_trx(thr);
  2195. rec_offs_init(offsets_);
  2196. index = dict_table_get_first_index(node->table);
  2197. const bool referenced = row_upd_index_is_referenced(index, trx);
  2198. #ifdef WITH_WSREP
  2199. const bool foreign = wsrep_row_upd_index_is_foreign(index, trx);
  2200. #endif
  2201. pcur = node->pcur;
  2202. /* We have to restore the cursor to its position */
  2203. mtr.start();
  2204. if (node->table->is_temporary()) {
  2205. /* Disable locking, because temporary tables are
  2206. private to the connection (no concurrent access). */
  2207. flags = node->table->no_rollback()
  2208. ? BTR_NO_ROLLBACK
  2209. : BTR_NO_LOCKING_FLAG;
  2210. /* Redo logging only matters for persistent tables. */
  2211. mtr.set_log_mode(MTR_LOG_NO_REDO);
  2212. } else {
  2213. flags = node->table->no_rollback() ? BTR_NO_ROLLBACK : 0;
  2214. index->set_modified(mtr);
  2215. }
  2216. /* If the restoration does not succeed, then the same
  2217. transaction has deleted the record on which the cursor was,
  2218. and that is an SQL error. If the restoration succeeds, it may
  2219. still be that the same transaction has successively deleted
  2220. and inserted a record with the same ordering fields, but in
  2221. that case we know that the transaction has at least an
  2222. implicit x-lock on the record. */
  2223. ut_a(pcur->rel_pos == BTR_PCUR_ON);
  2224. ulint mode;
  2225. DEBUG_SYNC_C_IF_THD(trx->mysql_thd, "innodb_row_upd_clust_step_enter");
  2226. if (dict_index_is_online_ddl(index)) {
  2227. ut_ad(node->table->id != DICT_INDEXES_ID);
  2228. mode = BTR_MODIFY_LEAF | BTR_ALREADY_S_LATCHED;
  2229. mtr_s_lock_index(index, &mtr);
  2230. } else {
  2231. mode = BTR_MODIFY_LEAF;
  2232. }
  2233. if (pcur->restore_position(mode, &mtr) != btr_pcur_t::SAME_ALL) {
  2234. err = DB_RECORD_NOT_FOUND;
  2235. goto exit_func;
  2236. }
  2237. rec = btr_pcur_get_rec(pcur);
  2238. offsets = rec_get_offsets(rec, index, offsets_, index->n_core_fields,
  2239. ULINT_UNDEFINED, &heap);
  2240. if (!flags && !node->has_clust_rec_x_lock) {
  2241. err = lock_clust_rec_modify_check_and_lock(
  2242. btr_pcur_get_block(pcur),
  2243. rec, index, offsets, thr);
  2244. if (err != DB_SUCCESS) {
  2245. goto exit_func;
  2246. }
  2247. }
  2248. ut_ad(index->table->no_rollback() || index->table->is_temporary()
  2249. || row_get_rec_trx_id(rec, index, offsets) == trx->id
  2250. || lock_trx_has_expl_x_lock(*trx, *index->table,
  2251. btr_pcur_get_block(pcur)->page.id(),
  2252. page_rec_get_heap_no(rec)));
  2253. if (node->is_delete == PLAIN_DELETE) {
  2254. err = row_upd_del_mark_clust_rec(
  2255. node, index, offsets, thr, referenced,
  2256. #ifdef WITH_WSREP
  2257. foreign,
  2258. #endif
  2259. &mtr);
  2260. goto all_done;
  2261. }
  2262. /* If the update is made for MySQL, we already have the update vector
  2263. ready, else we have to do some evaluation: */
  2264. if (UNIV_UNLIKELY(!node->in_mysql_interface)) {
  2265. /* Copy the necessary columns from clust_rec and calculate the
  2266. new values to set */
  2267. row_upd_copy_columns(rec, offsets, index,
  2268. UT_LIST_GET_FIRST(node->columns));
  2269. row_upd_eval_new_vals(node->update);
  2270. }
  2271. if (!node->is_delete && node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) {
  2272. err = row_upd_clust_rec(
  2273. flags, node, index, offsets, &heap, thr, &mtr);
  2274. goto exit_func;
  2275. }
  2276. if (!row_upd_store_row(node, trx->mysql_thd, thr->prebuilt
  2277. ? thr->prebuilt->m_mysql_table : NULL)) {
  2278. err = DB_COMPUTE_VALUE_FAILED;
  2279. goto exit_func;
  2280. }
  2281. if (row_upd_changes_ord_field_binary(index, node->update, thr,
  2282. node->row, node->ext)) {
  2283. /* Update causes an ordering field (ordering fields within
  2284. the B-tree) of the clustered index record to change: perform
  2285. the update by delete marking and inserting.
  2286. TODO! What to do to the 'Halloween problem', where an update
  2287. moves the record forward in index so that it is again
  2288. updated when the cursor arrives there? Solution: the
  2289. read operation must check the undo record undo number when
  2290. choosing records to update. MySQL solves now the problem
  2291. externally! */
  2292. err = row_upd_clust_rec_by_insert(
  2293. node, index, thr, referenced,
  2294. #ifdef WITH_WSREP
  2295. foreign,
  2296. #endif
  2297. &mtr);
  2298. all_done:
  2299. if (err == DB_SUCCESS) {
  2300. node->state = UPD_NODE_UPDATE_ALL_SEC;
  2301. success:
  2302. node->index = dict_table_get_next_index(index);
  2303. }
  2304. } else {
  2305. err = row_upd_clust_rec(
  2306. flags, node, index, offsets, &heap, thr, &mtr);
  2307. if (err == DB_SUCCESS) {
  2308. ut_ad(node->is_delete != PLAIN_DELETE);
  2309. node->state = node->is_delete
  2310. ? UPD_NODE_UPDATE_ALL_SEC
  2311. : UPD_NODE_UPDATE_SOME_SEC;
  2312. goto success;
  2313. }
  2314. }
  2315. exit_func:
  2316. mtr.commit();
  2317. if (UNIV_LIKELY_NULL(heap)) {
  2318. mem_heap_free(heap);
  2319. }
  2320. return err;
  2321. }
  2322. /***********************************************************//**
  2323. Updates the affected index records of a row. When the control is transferred
  2324. to this node, we assume that we have a persistent cursor which was on a
  2325. record, and the position of the cursor is stored in the cursor.
  2326. @return DB_SUCCESS if operation successfully completed, else error
  2327. code or DB_LOCK_WAIT */
  2328. static
  2329. dberr_t
  2330. row_upd(
  2331. /*====*/
  2332. upd_node_t* node, /*!< in: row update node */
  2333. que_thr_t* thr) /*!< in: query thread */
  2334. {
  2335. dberr_t err = DB_SUCCESS;
  2336. DBUG_ENTER("row_upd");
  2337. ut_ad(!thr_get_trx(thr)->in_rollback);
  2338. DBUG_PRINT("row_upd", ("table: %s", node->table->name.m_name));
  2339. DBUG_PRINT("row_upd", ("info bits in update vector: 0x%x",
  2340. node->update ? node->update->info_bits: 0));
  2341. DBUG_PRINT("row_upd", ("foreign_id: %s",
  2342. node->foreign ? node->foreign->id: "NULL"));
  2343. if (UNIV_LIKELY(node->in_mysql_interface)) {
  2344. /* We do not get the cmpl_info value from the MySQL
  2345. interpreter: we must calculate it on the fly: */
  2346. if (node->is_delete == PLAIN_DELETE
  2347. || row_upd_changes_some_index_ord_field_binary(
  2348. node->table, node->update)) {
  2349. node->cmpl_info = 0;
  2350. } else {
  2351. node->cmpl_info = UPD_NODE_NO_ORD_CHANGE;
  2352. }
  2353. }
  2354. switch (node->state) {
  2355. case UPD_NODE_UPDATE_CLUSTERED:
  2356. case UPD_NODE_INSERT_CLUSTERED:
  2357. log_free_check();
  2358. err = row_upd_clust_step(node, thr);
  2359. if (err != DB_SUCCESS) {
  2360. DBUG_RETURN(err);
  2361. }
  2362. }
  2363. DEBUG_SYNC_C_IF_THD(thr_get_trx(thr)->mysql_thd,
  2364. "after_row_upd_clust");
  2365. if (node->index == NULL
  2366. || (!node->is_delete
  2367. && (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE))) {
  2368. DBUG_RETURN(DB_SUCCESS);
  2369. }
  2370. DBUG_EXECUTE_IF("row_upd_skip_sec", node->index = NULL;);
  2371. do {
  2372. /* Skip corrupted index */
  2373. dict_table_skip_corrupt_index(node->index);
  2374. if (!node->index) {
  2375. break;
  2376. }
  2377. if (!(node->index->type & DICT_FTS)
  2378. && node->index->is_committed()) {
  2379. err = row_upd_sec_step(node, thr);
  2380. if (err != DB_SUCCESS) {
  2381. DBUG_RETURN(err);
  2382. }
  2383. }
  2384. node->index = dict_table_get_next_index(node->index);
  2385. } while (node->index != NULL);
  2386. ut_ad(err == DB_SUCCESS);
  2387. /* Do some cleanup */
  2388. if (node->row != NULL) {
  2389. node->row = NULL;
  2390. node->ext = NULL;
  2391. node->upd_row = NULL;
  2392. node->upd_ext = NULL;
  2393. mem_heap_empty(node->heap);
  2394. }
  2395. node->state = UPD_NODE_UPDATE_CLUSTERED;
  2396. DBUG_RETURN(err);
  2397. }
  2398. /***********************************************************//**
  2399. Updates a row in a table. This is a high-level function used in SQL execution
  2400. graphs.
  2401. @return query thread to run next or NULL */
  2402. que_thr_t*
  2403. row_upd_step(
  2404. /*=========*/
  2405. que_thr_t* thr) /*!< in: query thread */
  2406. {
  2407. upd_node_t* node;
  2408. sel_node_t* sel_node;
  2409. que_node_t* parent;
  2410. dberr_t err = DB_SUCCESS;
  2411. trx_t* trx;
  2412. DBUG_ENTER("row_upd_step");
  2413. ut_ad(thr);
  2414. trx = thr_get_trx(thr);
  2415. node = static_cast<upd_node_t*>(thr->run_node);
  2416. sel_node = node->select;
  2417. parent = que_node_get_parent(node);
  2418. ut_ad(que_node_get_type(node) == QUE_NODE_UPDATE);
  2419. if (thr->prev_node == parent) {
  2420. node->state = UPD_NODE_SET_IX_LOCK;
  2421. }
  2422. if (node->state == UPD_NODE_SET_IX_LOCK) {
  2423. if (!node->has_clust_rec_x_lock) {
  2424. /* It may be that the current session has not yet
  2425. started its transaction, or it has been committed: */
  2426. err = lock_table(node->table, LOCK_IX, thr);
  2427. if (err != DB_SUCCESS) {
  2428. goto error_handling;
  2429. }
  2430. }
  2431. node->state = UPD_NODE_UPDATE_CLUSTERED;
  2432. if (node->searched_update) {
  2433. /* Reset the cursor */
  2434. sel_node->state = SEL_NODE_OPEN;
  2435. /* Fetch a row to update */
  2436. thr->run_node = sel_node;
  2437. DBUG_RETURN(thr);
  2438. }
  2439. }
  2440. /* sel_node is NULL if we are in the MySQL interface */
  2441. if (sel_node && (sel_node->state != SEL_NODE_FETCH)) {
  2442. if (!node->searched_update) {
  2443. /* An explicit cursor should be positioned on a row
  2444. to update */
  2445. ut_error;
  2446. err = DB_ERROR;
  2447. goto error_handling;
  2448. }
  2449. ut_ad(sel_node->state == SEL_NODE_NO_MORE_ROWS);
  2450. /* No more rows to update, or the select node performed the
  2451. updates directly in-place */
  2452. thr->run_node = parent;
  2453. DBUG_RETURN(thr);
  2454. }
  2455. /* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */
  2456. err = row_upd(node, thr);
  2457. error_handling:
  2458. trx->error_state = err;
  2459. if (err != DB_SUCCESS) {
  2460. DBUG_RETURN(NULL);
  2461. }
  2462. /* DO THE TRIGGER ACTIONS HERE */
  2463. if (node->searched_update) {
  2464. /* Fetch next row to update */
  2465. thr->run_node = sel_node;
  2466. } else {
  2467. /* It was an explicit cursor update */
  2468. thr->run_node = parent;
  2469. }
  2470. node->state = UPD_NODE_UPDATE_CLUSTERED;
  2471. DBUG_RETURN(thr);
  2472. }
  2473. /** Write query start time as SQL field data to a buffer. Needed by InnoDB.
  2474. @param thd Thread object
  2475. @param buf Buffer to hold start time data */
  2476. void thd_get_query_start_data(THD *thd, char *buf);
  2477. /** Appends row_start or row_end field to update vector and sets a
  2478. CURRENT_TIMESTAMP/trx->id value to it.
  2479. Supposed to be called only by make_versioned_update() and
  2480. make_versioned_delete().
  2481. @param[in] trx transaction
  2482. @param[in] vers_sys_idx table->row_start or table->row_end */
  2483. void upd_node_t::vers_update_fields(const trx_t *trx, ulint idx)
  2484. {
  2485. ut_ad(in_mysql_interface); // otherwise needs to recalculate node->cmpl_info
  2486. ut_ad(idx == table->vers_start || idx == table->vers_end);
  2487. dict_index_t *clust_index= dict_table_get_first_index(table);
  2488. const dict_col_t *col= dict_table_get_nth_col(table, idx);
  2489. ulint field_no= dict_col_get_clust_pos(col, clust_index);
  2490. upd_field_t *ufield;
  2491. for (ulint i= 0; i < update->n_fields; ++i)
  2492. {
  2493. if (update->fields[i].field_no == field_no)
  2494. {
  2495. ufield= &update->fields[i];
  2496. goto skip_append;
  2497. }
  2498. }
  2499. /* row_create_update_node_for_mysql() pre-allocated this much.
  2500. At least one PK column always remains unchanged. */
  2501. ut_ad(update->n_fields < ulint(table->n_cols + table->n_v_cols));
  2502. update->n_fields++;
  2503. ufield= upd_get_nth_field(update, update->n_fields - 1);
  2504. upd_field_set_field_no(ufield, static_cast<uint16_t>(field_no), clust_index);
  2505. skip_append:
  2506. char *where= reinterpret_cast<char *>(update->vers_sys_value);
  2507. if (col->vers_native())
  2508. mach_write_to_8(where, trx->id);
  2509. else
  2510. thd_get_query_start_data(trx->mysql_thd, where);
  2511. dfield_set_data(&ufield->new_val, update->vers_sys_value, col->len);
  2512. for (ulint col_no= 0; col_no < dict_table_get_n_v_cols(table); col_no++)
  2513. {
  2514. const dict_v_col_t *v_col= dict_table_get_nth_v_col(table, col_no);
  2515. if (!v_col->m_col.ord_part)
  2516. continue;
  2517. for (ulint i= 0; i < unsigned(v_col->num_base); i++)
  2518. {
  2519. dict_col_t *base_col= v_col->base_col[i];
  2520. if (base_col->ind == col->ind)
  2521. {
  2522. /* Virtual column depends on system field value
  2523. which we updated above. Remove it from update
  2524. vector, so it is recalculated in
  2525. row_upd_store_v_row() (see !update branch). */
  2526. update->remove(v_col->v_pos);
  2527. break;
  2528. }
  2529. }
  2530. }
  2531. }