Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-38505

ERROR 1020 should be avoided when parent row receives unrelated update

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Major
    • Resolution: Unresolved
    • 10.6.24, 11.4.9, 11.8.5
    • None
    • None
    • Can result in unexpected behaviour

    Description

      With InnoDB snapshot isolation, concurrent updates to a parent row cause an ERROR 1020 when inserting a child row, even if the concurrent updates do not touch the columns referenced by the foreign key:

      -- Setup
      create table referenced_table (id int primary key, unrelated_column varchar(100));
      create table insert_issue (id int primary key, ref_id int references referenced_table (id));
      insert into referenced_table (id, unrelated_column) values (1, 'original value');
      commit;
       
      -- Transaction 1
      start transaction;
      select id from referenced_table where id = 1;
      -- continued later
       
      -- Transaction 2
      start transaction;
      update referenced_table set unrelated_column = 'updated value' where id = 1;
      commit;
       
      -- Transaction 1 (continued)
      insert into insert_issue (id, ref_id) values (1, 1);
      -- ERROR 1020 (HY000): Record has changed since last read in table 'insert_issue'
      -- (The error message references the wrong table, see MDEV-37825.)
      

      Note that Transaction 1 can still select the affected row in referenced_table at that point, just not reference it in a foreign key.

      This behavior seems overly restrictive and looks to be the cause of multiple ERROR 1020 occurrences we saw in production.

      According to marko, this error could likely be avoided by implementing deferred foreign key constraint checks. (MDEV-35957) He also simplified the test case for mysql-test:

      --source include/have_innodb.inc
       
      create table referenced_table (id int primary key, unrelated_column varchar(100)) engine=innodb;
      create table insert_issue (id int primary key, ref_id int references referenced_table (id)) engine=innodb;
       
      insert into referenced_table (id, unrelated_column) values (1, 'original value');
       
      start transaction with consistent snapshot;
       
      --connect con1,localhost,root
      update referenced_table set unrelated_column = 'updated value' where id = 1;
      --disconnect con1
       
      --connection default
      insert into insert_issue (id, ref_id) values (1, 1);
      drop table insert_issue,referenced_table;
      

      Context:

      Attachments

        Issue Links

          Activity

            People

              serg Sergei Golubchik
              gechterling Georg Echterling
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.