From 062ba0bd4a2da1fc720c7da8feb3f179a9be1583 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 3 Mar 2023 19:05:44 +0530 Subject: MDEV-30183 Assertion `!memcmp(rec_trx_id, old_pk_trx_id->data, 6 + 7)' failed in row_log_table_apply_update - This failure caused by commit 358921ce32203a9a8dd277a5ba7ac177c9e79e53 row_ins_duplicate_online() should consider if the record is an exact match of the tuple when number of matching fields equals with number of unique fields + DB_TRX_ID + DB_ROLL_PTR --- .../suite/innodb/r/online_table_rebuild.result | 20 ++++++++++++++++++ .../suite/innodb/t/online_table_rebuild.test | 24 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) (limited to 'mysql-test/suite') diff --git a/mysql-test/suite/innodb/r/online_table_rebuild.result b/mysql-test/suite/innodb/r/online_table_rebuild.result index d4bddbc5305..46d9780decb 100644 --- a/mysql-test/suite/innodb/r/online_table_rebuild.result +++ b/mysql-test/suite/innodb/r/online_table_rebuild.result @@ -43,5 +43,25 @@ t1 CREATE TABLE `t1` ( PRIMARY KEY (`f1`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci DROP TABLE t1; +# +# MDEV-30183 Assertion `!memcmp(rec_trx_id, old_pk_trx_id->data, +# 6 + 7)' failed in row_log_table_apply_update +# +set @old_sql_mode = @@sql_mode; +set @@sql_mode=""; +CREATE TABLE t1(col_int int, col_varchar varchar(500))ENGINE=InnoDB; +INSERT INTO t1(col_int) values(2560); +set debug_sync="row_log_table_apply1_before SIGNAL con1_begin WAIT_FOR con1_commit"; +ALTER TABLE t1 ADD PRIMARY KEY ( col_varchar); +connection con1; +SET DEBUG_SYNC="now WAIT_FOR con1_begin"; +UPDATE t1 SET col_int = 2178; +INSERT INTO t1(col_int) VALUES(3016); +UPDATE t1 set col_int=2802; +SET DEBUG_SYNC="now SIGNAL con1_commit"; +connection default; +ERROR 23000: Duplicate entry '' for key 'PRIMARY' +DROP TABLE t1; +SET @@sql_mode = @old_sql_mode; disconnect con1; SET DEBUG_SYNC=reset; diff --git a/mysql-test/suite/innodb/t/online_table_rebuild.test b/mysql-test/suite/innodb/t/online_table_rebuild.test index 1d34738703c..02e9639eae2 100644 --- a/mysql-test/suite/innodb/t/online_table_rebuild.test +++ b/mysql-test/suite/innodb/t/online_table_rebuild.test @@ -59,5 +59,29 @@ connection default; reap; SHOW CREATE TABLE t1; DROP TABLE t1; + +--echo # +--echo # MDEV-30183 Assertion `!memcmp(rec_trx_id, old_pk_trx_id->data, +--echo # 6 + 7)' failed in row_log_table_apply_update +--echo # +set @old_sql_mode = @@sql_mode; +set @@sql_mode=""; +CREATE TABLE t1(col_int int, col_varchar varchar(500))ENGINE=InnoDB; +INSERT INTO t1(col_int) values(2560); +set debug_sync="row_log_table_apply1_before SIGNAL con1_begin WAIT_FOR con1_commit"; +send ALTER TABLE t1 ADD PRIMARY KEY ( col_varchar); + +connection con1; +SET DEBUG_SYNC="now WAIT_FOR con1_begin"; +UPDATE t1 SET col_int = 2178; +INSERT INTO t1(col_int) VALUES(3016); +UPDATE t1 set col_int=2802; +SET DEBUG_SYNC="now SIGNAL con1_commit"; + +connection default; +--error ER_DUP_ENTRY +reap; +DROP TABLE t1; +SET @@sql_mode = @old_sql_mode; disconnect con1; SET DEBUG_SYNC=reset; -- cgit v1.2.1 From a55b951e6082a4ce9a1f2ed5ee176ea7dbbaf1f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 16 Mar 2023 17:19:58 +0200 Subject: MDEV-26827 Make page flushing even faster For more convenient monitoring of something that could greatly affect the volume of page writes, we add the status variable Innodb_buffer_pool_pages_split that was previously only available via information_schema.innodb_metrics as "innodb_page_splits". This was suggested by Axel Schwenke. buf_flush_page_count: Replaced with buf_pool.stat.n_pages_written. We protect buf_pool.stat (except n_page_gets) with buf_pool.mutex and remove unnecessary export_vars indirection. buf_pool.flush_list_bytes: Moved from buf_pool.stat.flush_list_bytes. Protected by buf_pool.flush_list_mutex. buf_pool_t::page_cleaner_status: Replaces buf_pool_t::n_flush_LRU_, buf_pool_t::n_flush_list_, and buf_pool_t::page_cleaner_is_idle. Protected by buf_pool.flush_list_mutex. We will exclusively broadcast buf_pool.done_flush_list by the buf_flush_page_cleaner thread, and only wait for it when communicating with buf_flush_page_cleaner. There is no need to keep a count of pending writes by the buf_pool.flush_list processing. A single flag suffices for that. Waits for page write completion can be performed by simply waiting on block->page.lock, or by invoking buf_dblwr.wait_for_page_writes(). buf_LRU_block_free_non_file_page(): Broadcast buf_pool.done_free and set buf_pool.try_LRU_scan when freeing a page. This would be executed also as part of buf_page_write_complete(). buf_page_write_complete(): Do not broadcast buf_pool.done_flush_list, and do not acquire buf_pool.mutex unless buf_pool.LRU eviction is needed. Let buf_dblwr count all writes to persistent pages and broadcast a condition variable when no outstanding writes remain. buf_flush_page_cleaner(): Prioritize LRU flushing and eviction right after "furious flushing" (lsn_limit). Simplify the conditions and reduce the hold time of buf_pool.flush_list_mutex. Refuse to shut down or sleep if buf_pool.ran_out(), that is, LRU eviction is needed. buf_pool_t::page_cleaner_wakeup(): Add the optional parameter for_LRU. buf_LRU_get_free_block(): Protect buf_lru_free_blocks_error_printed with buf_pool.mutex. Invoke buf_pool.page_cleaner_wakeup(true) to to ensure that buf_flush_page_cleaner() will process the LRU flush request. buf_do_LRU_batch(), buf_flush_list(), buf_flush_list_space(): Update buf_pool.stat.n_pages_written when submitting writes (while holding buf_pool.mutex), not when completing them. buf_page_t::flush(), buf_flush_discard_page(): Require that the page U-latch be acquired upfront, and remove buf_page_t::ready_for_flush(). buf_pool_t::delete_from_flush_list(): Remove the parameter "bool clear". buf_flush_page(): Count pending page writes via buf_dblwr. buf_flush_try_neighbors(): Take the block of page_id as a parameter. If the tablespace is dropped before our page has been written out, release the page U-latch. buf_pool_invalidate(): Let the caller ensure that there are no outstanding writes. buf_flush_wait_batch_end(false), buf_flush_wait_batch_end_acquiring_mutex(false): Replaced with buf_dblwr.wait_for_page_writes(). buf_flush_wait_LRU_batch_end(): Replaces buf_flush_wait_batch_end(true). buf_flush_list(): Remove some broadcast of buf_pool.done_flush_list. buf_flush_buffer_pool(): Invoke also buf_dblwr.wait_for_page_writes(). buf_pool_t::io_pending(), buf_pool_t::n_flush_list(): Remove. Outstanding writes are reflected by buf_dblwr.pending_writes(). buf_dblwr_t::init(): New function, to initialize the mutex and the condition variables, but not the backing store. buf_dblwr_t::is_created(): Replaces buf_dblwr_t::is_initialised(). buf_dblwr_t::pending_writes(), buf_dblwr_t::writes_pending: Keeps track of writes of persistent data pages. buf_flush_LRU(): Allow calls while LRU flushing may be in progress in another thread. Tested by Matthias Leich (correctness) and Axel Schwenke (performance) --- mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result | 2 +- mysql-test/suite/innodb/r/innodb_status_variables.result | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'mysql-test/suite') diff --git a/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result b/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result index 19b426009f2..9bdb546482e 100644 --- a/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result +++ b/mysql-test/suite/innodb/r/innodb_skip_innodb_is_tables.result @@ -199,7 +199,7 @@ compress_pages_page_decompressed compression 0 NULL NULL NULL 0 NULL NULL NULL N compress_pages_page_compression_error compression 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of page compression errors compress_pages_encrypted compression 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of pages encrypted compress_pages_decrypted compression 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of pages decrypted -index_page_splits index 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of index page splits +index_page_splits index 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of index page splits index_page_merge_attempts index 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of index page merge attempts index_page_merge_successful index 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of successful index page merges index_page_reorg_attempts index 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of index page reorganization attempts diff --git a/mysql-test/suite/innodb/r/innodb_status_variables.result b/mysql-test/suite/innodb/r/innodb_status_variables.result index a729dd0a8d4..5b8ca678795 100644 --- a/mysql-test/suite/innodb/r/innodb_status_variables.result +++ b/mysql-test/suite/innodb/r/innodb_status_variables.result @@ -23,6 +23,7 @@ INNODB_BUFFER_POOL_PAGES_OLD INNODB_BUFFER_POOL_PAGES_TOTAL INNODB_BUFFER_POOL_PAGES_LRU_FLUSHED INNODB_BUFFER_POOL_PAGES_LRU_FREED +INNODB_BUFFER_POOL_PAGES_SPLIT INNODB_BUFFER_POOL_READ_AHEAD_RND INNODB_BUFFER_POOL_READ_AHEAD INNODB_BUFFER_POOL_READ_AHEAD_EVICTED -- cgit v1.2.1