After the changes made in the scope of MDEV-515, this basic scenario will no longer work:
--source include/have_innodb.inc
createtable t1 (pk intprimarykey) engine=InnoDB;
start transaction;
insertinto t1 values (1);
--connect (con1,localhost,root,,)
insertinto t1 values (2);
The second INSERT, which in earlier versions is instant, will now hang until the first connection finishes the transaction (or will time out if it doesn't happen within the timeout interval).
While the locking change was clearly intentional and explicitly mentioned at least in the commit comment to MDEV-515 patch, I still file it as a bug, because I think the negative effect of this change may by far exceed the improvements that MDEV-515 introduces.
The scope of MDEV-515 is a performance improvement of a very big LOAD DATA or INSERT SELECT into an empty table – big enough to make this performance improvement significant from the practical perspective. While certainly important, it is still a rather specific use case, and the gain is limited to faster execution.
On the other hand, "create/empty a table and start using it concurrently" scenario above is as basic as it gets; and the loss can be not only in performance (in case the first transaction is reasonably fast and other ones are just delayed), but in more extreme cases, when the first transaction remains open for a long time, it can render the application non-functional – everything else will be failing with timeouts.
The problem can be happening anywhere within an application, both in business logic and deep in maintenance/service jobs.
It will represent as seemingly sporadic not reproducible weird delays and timeouts and will be nearly impossible to investigate – and even if the cause happens to be revealed, changing this logic in all existing applications won't be realistic.
I don't think that even a possibility to "opt-out" the new behavior would be sufficient, as users are generally not aware of details of the internal implementation of applications they use, as well as database admins if, for example, they maintain a shared hosting.
Attachments
Issue Links
blocks
MDEV-24993pymysql - executemany test failing - lock timeout - insert wait on non-indexed table
Closed
causes
MDEV-25297InnoDB: Failing assertion: trx->roll_limit <= trx->undo_no in trx_rollback_start
Closed
MDEV-25315Assertion `ptr' failed in ut_align_down | SIGSEGV in dict_table_t::not_redundant | Assertion `!lock_sys_t::get_first(receiver_cell, receiver_id, receiver_heap_no)' failed in lock_rec_move
Closed
MDEV-25401Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' failed in Diagnostics_area::set_ok_status on SAVEPOINT
Closed
MDEV-25496Assertion `trx->bulk_insert' failed in trx_undo_report_row_operation on INSERT
Closed
MDEV-25534Assertion `lock_table_has(trx, index->table, LOCK_IX)' failed in lock_rec_insert_check_and_lock on INSERT
Closed
MDEV-26121[Note] InnoDB: Resetting invalid page [page id: space=5, page number=3] type 17855 to 6.
I would propose new syntax to make the MDEV-515 ‘opt-in’ and also at the same time fix other limitations with it:
--echo # If any statement fails, the entire transaction will be rolled back.
START TRANSACTION ATOMIC;
This would have the following consequences:
The MDEV-515 optimization would only apply to operations between START TRANSACTION ATOMIC and COMMIT. More backward compatibility.
We would also make mysqldump emit this new syntax (version-conditionally) in order not to cause a regression for MDEV-515.
In a follow-up ticket, we could extend InnoDB so that multiple INSERT into the same initially empty table will be optimized.
Marko Mäkelä
added a comment - I would propose new syntax to make the MDEV-515 ‘opt-in’ and also at the same time fix other limitations with it:
--echo # If any statement fails, the entire transaction will be rolled back.
START TRANSACTION ATOMIC;
This would have the following consequences:
The MDEV-515 optimization would only apply to operations between START TRANSACTION ATOMIC and COMMIT . More backward compatibility.
We would also make mysqldump emit this new syntax (version-conditionally) in order not to cause a regression for MDEV-515 .
In a follow-up ticket, we could extend InnoDB so that multiple INSERT into the same initially empty table will be optimized.
MDEV-515 is very welcome . I agree the behaviour shown in this ticket is sub-optimal.
But we could make MDEV-515 trigger on LOAD DATA INFILE only , as no one would normally try to insert rows in a table where a LOAD DATA INFILE is happening . And if he does, then have him waiting.
Rick Pizzi (Inactive)
added a comment - - edited MDEV-515 is very welcome . I agree the behaviour shown in this ticket is sub-optimal.
But we could make MDEV-515 trigger on LOAD DATA INFILE only , as no one would normally try to insert rows in a table where a LOAD DATA INFILE is happening . And if he does, then have him waiting.
I agree that my original proposed syntax is somewhat weird, because transactions are expected to be kind of atomic. Maybe we could make it explicitly refer to the fact that only full and no partial rollback is supported:
START TRANSACTIONWITH ATOMIC ROLLBACK;
Like my original proposal, also this one would reuse existing reserved words.
Marko Mäkelä
added a comment - I agree that my original proposed syntax is somewhat weird, because transactions are expected to be kind of atomic. Maybe we could make it explicitly refer to the fact that only full and no partial rollback is supported:
START TRANSACTION WITH ATOMIC ROLLBACK ;
Like my original proposal, also this one would reuse existing reserved words.
For the purpose of this bug fix and extra optimizations aside, it would be enough to enable the new optimization only in auto-commit more or under LOCK TABLES.
Sergei Golubchik
added a comment - For the purpose of this bug fix and extra optimizations aside, it would be enough to enable the new optimization only in auto-commit more or under LOCK TABLES.
would be required to enable the table-level locking and undo logging of the INSERT statement. The settings are used by the scripts that are generated by mysqldump.
We could extend this approach further to allow subsequent INSERT statements in the same transaction to suppress row-level undo logging in the same transaction. That should make loads of mysqldump fast out of the box. I do not think that we really need to detect LOCK TABLES to enable this logic, because unique_checks=0 should never be set unless one really is sure that no duplicate keys are possible. (It allows the InnoDB change buffer to corrupt data when the change buffer merge of a duplicate key eventually occurs.)
Marko Mäkelä
added a comment - The following patch would make this feature ‘opt-in’:
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 65cb8321500..b652aa187e8 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -2660,6 +2660,7 @@ row_ins_clust_index_entry_low(
if (!(flags & BTR_NO_UNDO_LOG_FLAG)
&& page_is_empty(block->frame)
&& !entry->is_metadata() && !trx->duplicates
+ && !trx->check_unique_secondary && !trx->check_foreigns
&& !trx->ddl && !trx->internal
&& block->page.id().page_no() == index->page
&& !index->table->skip_alter_undo
That is, explicit
SET UNIQUE_CHECKS=0;
SET FOREIGN_KEY_CHECKS=0;
would be required to enable the table-level locking and undo logging of the INSERT statement. The settings are used by the scripts that are generated by mysqldump .
We could extend this approach further to allow subsequent INSERT statements in the same transaction to suppress row-level undo logging in the same transaction. That should make loads of mysqldump fast out of the box. I do not think that we really need to detect LOCK TABLES to enable this logic, because unique_checks=0 should never be set unless one really is sure that no duplicate keys are possible. (It allows the InnoDB change buffer to corrupt data when the change buffer merge of a duplicate key eventually occurs.)
I found out that the sysbench prepare scripts are usually running in autocommit mode without transaction boundaries. The following would enable the slightly faster insert (and remove the need of subsequent purge of INSERT history that was introduced in MDEV-12288):
Marko Mäkelä
added a comment - I found out that the sysbench prepare scripts are usually running in autocommit mode without transaction boundaries. The following would enable the slightly faster insert (and remove the need of subsequent purge of INSERT history that was introduced in MDEV-12288 ):
--- /usr/share/sysbench/oltp_update_index.lua 2020-06-05 16:47:03.000000000 +0300
+++ oltp_update_index.lua 2021-03-12 14:51:26.974791244 +0200
@@ -22,7 +22,9 @@
require("oltp_common")
function prepare_statements()
+ con:query("SET autocommit=0, unique_checks=0, foreign_key_checks=0")
prepare_index_updates()
+ con:query("SET autocommit=1, unique_checks=1, foreign_key_checks=1")
end
function event()
People
Marko Mäkelä
Elena Stepanova
Votes:
0Vote for this issue
Watchers:
7Start watching this issue
Dates
Created:
Updated:
Resolved:
Git Integration
Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.
{"report":{"fcp":2150.3999996185303,"ttfb":545.5999999046326,"pageVisibility":"visible","entityId":96749,"key":"jira.project.issue.view-issue","isInitial":true,"threshold":1000,"elementTimings":{},"userDeviceMemory":8,"userDeviceProcessors":64,"apdex":0.5,"journeyId":"1e8680c5-cca5-4ee3-b857-89676b4c0416","navigationType":0,"readyForUser":2305.0999999046326,"redirectCount":0,"resourceLoadedEnd":2775,"resourceLoadedStart":552.6999998092651,"resourceTiming":[{"duration":987.6999998092651,"initiatorType":"link","name":"https://jira.mariadb.org/s/2c21342762a6a02add1c328bed317ffd-CDN/lu2cib/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/css/_super/batch.css","startTime":552.6999998092651,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":552.6999998092651,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":1540.3999996185303,"responseStart":0,"secureConnectionStart":0},{"duration":987.5,"initiatorType":"link","name":"https://jira.mariadb.org/s/7ebd35e77e471bc30ff0eba799ebc151-CDN/lu2cib/820016/12ta74/494e4c556ecbb29f90a3d3b4f09cb99c/_/download/contextbatch/css/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.css?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&slack-enabled=true&whisper-enabled=true","startTime":553.0999999046326,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":553.0999999046326,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":1540.5999999046326,"responseStart":0,"secureConnectionStart":0},{"duration":1029.4000000953674,"initiatorType":"script","name":"https://jira.mariadb.org/s/0917945aaa57108d00c5076fea35e069-CDN/lu2cib/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/js/_super/batch.js?locale=en","startTime":553.2999997138977,"connectEnd":553.2999997138977,"connectStart":553.2999997138977,"domainLookupEnd":553.2999997138977,"domainLookupStart":553.2999997138977,"fetchStart":553.2999997138977,"redirectEnd":0,"redirectStart":0,"requestStart":553.2999997138977,"responseEnd":1582.6999998092651,"responseStart":1582.6999998092651,"secureConnectionStart":553.2999997138977},{"duration":1087.1000003814697,"initiatorType":"script","name":"https://jira.mariadb.org/s/2d8175ec2fa4c816e8023260bd8c1786-CDN/lu2cib/820016/12ta74/494e4c556ecbb29f90a3d3b4f09cb99c/_/download/contextbatch/js/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.js?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&locale=en&slack-enabled=true&whisper-enabled=true","startTime":553.3999996185303,"connectEnd":553.3999996185303,"connectStart":553.3999996185303,"domainLookupEnd":553.3999996185303,"domainLookupStart":553.3999996185303,"fetchStart":553.3999996185303,"redirectEnd":0,"redirectStart":0,"requestStart":553.3999996185303,"responseEnd":1640.5,"responseStart":1640.5,"secureConnectionStart":553.3999996185303},{"duration":1103.5,"initiatorType":"script","name":"https://jira.mariadb.org/s/a9324d6758d385eb45c462685ad88f1d-CDN/lu2cib/820016/12ta74/c92c0caa9a024ae85b0ebdbed7fb4bd7/_/download/contextbatch/js/atl.global,-_super/batch.js?locale=en","startTime":553.6999998092651,"connectEnd":553.6999998092651,"connectStart":553.6999998092651,"domainLookupEnd":553.6999998092651,"domainLookupStart":553.6999998092651,"fetchStart":553.6999998092651,"redirectEnd":0,"redirectStart":0,"requestStart":553.6999998092651,"responseEnd":1657.1999998092651,"responseStart":1657.1999998092651,"secureConnectionStart":553.6999998092651},{"duration":1103.9000000953674,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-en/jira.webresources:calendar-en.js","startTime":553.7999997138977,"connectEnd":553.7999997138977,"connectStart":553.7999997138977,"domainLookupEnd":553.7999997138977,"domainLookupStart":553.7999997138977,"fetchStart":553.7999997138977,"redirectEnd":0,"redirectStart":0,"requestStart":553.7999997138977,"responseEnd":1657.6999998092651,"responseStart":1657.6999998092651,"secureConnectionStart":553.7999997138977},{"duration":1134.5,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-localisation-moment/jira.webresources:calendar-localisation-moment.js","startTime":554,"connectEnd":554,"connectStart":554,"domainLookupEnd":554,"domainLookupStart":554,"fetchStart":554,"redirectEnd":0,"redirectStart":0,"requestStart":554,"responseEnd":1688.5,"responseStart":1688.5,"secureConnectionStart":554},{"duration":1245.5999999046326,"initiatorType":"link","name":"https://jira.mariadb.org/s/b04b06a02d1959df322d9cded3aeecc1-CDN/lu2cib/820016/12ta74/a2ff6aa845ffc9a1d22fe23d9ee791fc/_/download/contextbatch/css/jira.global.look-and-feel,-_super/batch.css","startTime":554.1999998092651,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":554.1999998092651,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":1799.7999997138977,"responseStart":0,"secureConnectionStart":0},{"duration":1135.2000002861023,"initiatorType":"script","name":"https://jira.mariadb.org/rest/api/1.0/shortcuts/820016/47140b6e0a9bc2e4913da06536125810/shortcuts.js?context=issuenavigation&context=issueaction","startTime":554.3999996185303,"connectEnd":554.3999996185303,"connectStart":554.3999996185303,"domainLookupEnd":554.3999996185303,"domainLookupStart":554.3999996185303,"fetchStart":554.3999996185303,"redirectEnd":0,"redirectStart":0,"requestStart":554.3999996185303,"responseEnd":1689.5999999046326,"responseStart":1689.5999999046326,"secureConnectionStart":554.3999996185303},{"duration":1245.3999996185303,"initiatorType":"link","name":"https://jira.mariadb.org/s/3ac36323ba5e4eb0af2aa7ac7211b4bb-CDN/lu2cib/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/css/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.css?jira.create.linked.issue=true","startTime":554.5,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":554.5,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":1799.8999996185303,"responseStart":0,"secureConnectionStart":0},{"duration":1166.0999999046326,"initiatorType":"script","name":"https://jira.mariadb.org/s/5d5e8fe91fbc506585e83ea3b62ccc4b-CDN/lu2cib/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/js/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.js?jira.create.linked.issue=true&locale=en","startTime":554.5999999046326,"connectEnd":554.5999999046326,"connectStart":554.5999999046326,"domainLookupEnd":554.5999999046326,"domainLookupStart":554.5999999046326,"fetchStart":554.5999999046326,"redirectEnd":0,"redirectStart":0,"requestStart":554.5999999046326,"responseEnd":1720.6999998092651,"responseStart":1720.6999998092651,"secureConnectionStart":554.5999999046326},{"duration":1773.5,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-js/jira.webresources:bigpipe-js.js","startTime":556.6999998092651,"connectEnd":556.6999998092651,"connectStart":556.6999998092651,"domainLookupEnd":556.6999998092651,"domainLookupStart":556.6999998092651,"fetchStart":556.6999998092651,"redirectEnd":0,"redirectStart":0,"requestStart":556.6999998092651,"responseEnd":2330.199999809265,"responseStart":2330.199999809265,"secureConnectionStart":556.6999998092651},{"duration":2218.2000002861023,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-init/jira.webresources:bigpipe-init.js","startTime":556.7999997138977,"connectEnd":556.7999997138977,"connectStart":556.7999997138977,"domainLookupEnd":556.7999997138977,"domainLookupStart":556.7999997138977,"fetchStart":556.7999997138977,"redirectEnd":0,"redirectStart":0,"requestStart":556.7999997138977,"responseEnd":2775,"responseStart":2775,"secureConnectionStart":556.7999997138977},{"duration":653.7000002861023,"initiatorType":"xmlhttprequest","name":"https://jira.mariadb.org/rest/webResources/1.0/resources","startTime":1814.2999997138977,"connectEnd":1814.2999997138977,"connectStart":1814.2999997138977,"domainLookupEnd":1814.2999997138977,"domainLookupStart":1814.2999997138977,"fetchStart":1814.2999997138977,"redirectEnd":0,"redirectStart":0,"requestStart":1814.2999997138977,"responseEnd":2468,"responseStart":2468,"secureConnectionStart":1814.2999997138977},{"duration":697.6999998092651,"initiatorType":"script","name":"https://www.google-analytics.com/analytics.js","startTime":2139.0999999046326,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":2139.0999999046326,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":2836.7999997138977,"responseStart":0,"secureConnectionStart":0}],"fetchStart":0,"domainLookupStart":0,"domainLookupEnd":0,"connectStart":0,"connectEnd":0,"requestStart":342,"responseStart":546,"responseEnd":548,"domLoading":550,"domInteractive":2845,"domContentLoadedEventStart":2845,"domContentLoadedEventEnd":2907,"domComplete":4039,"loadEventStart":4039,"loadEventEnd":4040,"userAgent":"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)","marks":[{"name":"bigPipe.sidebar-id.start","time":2800.7999997138977},{"name":"bigPipe.sidebar-id.end","time":2801.5999999046326},{"name":"bigPipe.activity-panel-pipe-id.start","time":2801.8999996185303},{"name":"bigPipe.activity-panel-pipe-id.end","time":2805.699999809265},{"name":"activityTabFullyLoaded","time":2976.5}],"measures":[],"correlationId":"df2a67ba125e93","effectiveType":"4g","downlink":10,"rtt":0,"serverDuration":139,"dbReadsTimeInMs":30,"dbConnsTimeInMs":41,"applicationHash":"9d11dbea5f4be3d4cc21f03a88dd11d8c8687422","experiments":[]}}
I would propose new syntax to make the
MDEV-515‘opt-in’ and also at the same time fix other limitations with it:--echo # If any statement fails, the entire transaction will be rolled back.
This would have the following consequences:
MDEV-515optimization would only apply to operations between START TRANSACTION ATOMIC and COMMIT. More backward compatibility.MDEV-515.