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

Validation of new foreign key skipped if innodb_alter_copy_bulk=ON

Details

    Description

      When altering a table to add a new foreign key constraint, the referential integrity validation of existing rows is now skipped if innodb_alter_copy_bulk=ON, which is the default value for this new variable. This is a surprising behavior change, especially for a quarterly point release, so I assume it is unintentional.

      Setting innodb_alter_copy_bulk=OFF restores the old behavior (existing data is verified if session foreign_key_checks=ON).

      MariaDB [testing]> CREATE TABLE companies (
      -> id int unsigned not null auto_increment primary key,
      -> name varchar(30));
      Query OK, 0 rows affected (0.019 sec)

      MariaDB [testing]> CREATE TABLE websites (
      -> id int unsigned not null auto_increment primary key,
      -> url varchar(100) not null,
      -> company_id int unsigned not null);
      Query OK, 0 rows affected (0.012 sec)

      MariaDB [testing]> INSERT INTO websites (url, company_id) VALUES ('https://www.skeema.io', 123);
      Query OK, 1 row affected (0.011 sec)

      MariaDB [testing]> SELECT version(), @@global.innodb_alter_copy_bulk, @@session.foreign_key_checks;
      ------------------------------------------------------------------------------------

      version() @@global.innodb_alter_copy_bulk @@session.foreign_key_checks

      ------------------------------------------------------------------------------------

      10.11.9-MariaDB-ubu2204 1 1

      ------------------------------------------------------------------------------------
      1 row in set (0.003 sec)

      MariaDB [testing]> ALTER TABLE websites ADD CONSTRAINT foo FOREIGN KEY (company_id) REFERENCES companies (id);
      Query OK, 1 row affected (0.013 sec)
      Records: 1 Duplicates: 0 Warnings: 0

      MariaDB [testing]> SET GLOBAL innodb_alter_copy_bulk = 0;
      Query OK, 0 rows affected (0.001 sec)

      MariaDB [testing]> ALTER TABLE websites ADD CONSTRAINT bar FOREIGN KEY (company_id) REFERENCES companies (id);
      ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`testing`.`#sql-alter-1-3`, CONSTRAINT `bar` FOREIGN KEY (`company_id`) REFERENCES `companies` (`id`))
      MariaDB [testing]>

      Attachments

        Issue Links

          Activity

            evanelias Evan Elias created issue -
            evanelias Evan Elias made changes -
            Field Original Value New Value
            evanelias Evan Elias made changes -
            Description When altering a table to add a new foreign key constraint, the referential integrity validation of existing rows is now skipped if innodb_alter_copy_bulk=ON, which is the default value for this new variable. This is a surprising behavior change, especially for a quarterly point release, so I assume it is unintentional.

            Setting innodb_alter_copy_bulk=OFF restores the old behavior (existing data is verified if session foreign_key_checks=ON).


            {{MariaDB [testing]> CREATE TABLE companies (
                -> id int unsigned not null auto_increment primary key,
                -> name varchar(30));
            Query OK, 0 rows affected (0.019 sec)

            MariaDB [testing]> CREATE TABLE websites (
                -> id int unsigned not null auto_increment primary key,
                -> url varchar(100) not null,
                -> company_id int unsigned not null);
            Query OK, 0 rows affected (0.012 sec)

            MariaDB [testing]> INSERT INTO websites (url, company_id) VALUES ('https://www.skeema.io', 123);
            Query OK, 1 row affected (0.011 sec)

            MariaDB [testing]> SELECT version(), @@global.innodb_alter_copy_bulk, @@session.foreign_key_checks;
            +-------------------------+---------------------------------+------------------------------+
            | version() | @@global.innodb_alter_copy_bulk | @@session.foreign_key_checks |
            +-------------------------+---------------------------------+------------------------------+
            | 10.11.9-MariaDB-ubu2204 | 1 | 1 |
            +-------------------------+---------------------------------+------------------------------+
            1 row in set (0.003 sec)

            MariaDB [testing]> ALTER TABLE websites ADD CONSTRAINT foo FOREIGN KEY (company_id) REFERENCES companies (id);
            Query OK, 1 row affected (0.013 sec)
            Records: 1 Duplicates: 0 Warnings: 0

            MariaDB [testing]> SET GLOBAL innodb_alter_copy_bulk = 0;
            Query OK, 0 rows affected (0.001 sec)

            MariaDB [testing]> ALTER TABLE websites ADD CONSTRAINT bar FOREIGN KEY (company_id) REFERENCES companies (id);
            ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`testing`.`#sql-alter-1-3`, CONSTRAINT `bar` FOREIGN KEY (`company_id`) REFERENCES `companies` (`id`))
            MariaDB [testing]>
            }}
            When altering a table to add a new foreign key constraint, the referential integrity validation of existing rows is now skipped if innodb_alter_copy_bulk=ON, which is the default value for this new variable. This is a surprising behavior change, especially for a quarterly point release, so I assume it is unintentional.

            Setting innodb_alter_copy_bulk=OFF restores the old behavior (existing data is verified if session foreign_key_checks=ON).


            {{
            MariaDB [testing]> CREATE TABLE companies (
                -> id int unsigned not null auto_increment primary key,
                -> name varchar(30));
            Query OK, 0 rows affected (0.019 sec)

            MariaDB [testing]> CREATE TABLE websites (
                -> id int unsigned not null auto_increment primary key,
                -> url varchar(100) not null,
                -> company_id int unsigned not null);
            Query OK, 0 rows affected (0.012 sec)

            MariaDB [testing]> INSERT INTO websites (url, company_id) VALUES ('https://www.skeema.io', 123);
            Query OK, 1 row affected (0.011 sec)

            MariaDB [testing]> SELECT version(), @@global.innodb_alter_copy_bulk, @@session.foreign_key_checks;
            +-------------------------+---------------------------------+------------------------------+
            | version() | @@global.innodb_alter_copy_bulk | @@session.foreign_key_checks |
            +-------------------------+---------------------------------+------------------------------+
            | 10.11.9-MariaDB-ubu2204 | 1 | 1 |
            +-------------------------+---------------------------------+------------------------------+
            1 row in set (0.003 sec)

            MariaDB [testing]> ALTER TABLE websites ADD CONSTRAINT foo FOREIGN KEY (company_id) REFERENCES companies (id);
            Query OK, 1 row affected (0.013 sec)
            Records: 1 Duplicates: 0 Warnings: 0

            MariaDB [testing]> SET GLOBAL innodb_alter_copy_bulk = 0;
            Query OK, 0 rows affected (0.001 sec)

            MariaDB [testing]> ALTER TABLE websites ADD CONSTRAINT bar FOREIGN KEY (company_id) REFERENCES companies (id);
            ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`testing`.`#sql-alter-1-3`, CONSTRAINT `bar` FOREIGN KEY (`company_id`) REFERENCES `companies` (`id`))
            MariaDB [testing]>
            }}
            evanelias Evan Elias made changes -
            Description When altering a table to add a new foreign key constraint, the referential integrity validation of existing rows is now skipped if innodb_alter_copy_bulk=ON, which is the default value for this new variable. This is a surprising behavior change, especially for a quarterly point release, so I assume it is unintentional.

            Setting innodb_alter_copy_bulk=OFF restores the old behavior (existing data is verified if session foreign_key_checks=ON).


            {{
            MariaDB [testing]> CREATE TABLE companies (
                -> id int unsigned not null auto_increment primary key,
                -> name varchar(30));
            Query OK, 0 rows affected (0.019 sec)

            MariaDB [testing]> CREATE TABLE websites (
                -> id int unsigned not null auto_increment primary key,
                -> url varchar(100) not null,
                -> company_id int unsigned not null);
            Query OK, 0 rows affected (0.012 sec)

            MariaDB [testing]> INSERT INTO websites (url, company_id) VALUES ('https://www.skeema.io', 123);
            Query OK, 1 row affected (0.011 sec)

            MariaDB [testing]> SELECT version(), @@global.innodb_alter_copy_bulk, @@session.foreign_key_checks;
            +-------------------------+---------------------------------+------------------------------+
            | version() | @@global.innodb_alter_copy_bulk | @@session.foreign_key_checks |
            +-------------------------+---------------------------------+------------------------------+
            | 10.11.9-MariaDB-ubu2204 | 1 | 1 |
            +-------------------------+---------------------------------+------------------------------+
            1 row in set (0.003 sec)

            MariaDB [testing]> ALTER TABLE websites ADD CONSTRAINT foo FOREIGN KEY (company_id) REFERENCES companies (id);
            Query OK, 1 row affected (0.013 sec)
            Records: 1 Duplicates: 0 Warnings: 0

            MariaDB [testing]> SET GLOBAL innodb_alter_copy_bulk = 0;
            Query OK, 0 rows affected (0.001 sec)

            MariaDB [testing]> ALTER TABLE websites ADD CONSTRAINT bar FOREIGN KEY (company_id) REFERENCES companies (id);
            ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`testing`.`#sql-alter-1-3`, CONSTRAINT `bar` FOREIGN KEY (`company_id`) REFERENCES `companies` (`id`))
            MariaDB [testing]>
            }}
            When altering a table to add a new foreign key constraint, the referential integrity validation of existing rows is now skipped if innodb_alter_copy_bulk=ON, which is the default value for this new variable. This is a surprising behavior change, especially for a quarterly point release, so I assume it is unintentional.

            Setting innodb_alter_copy_bulk=OFF restores the old behavior (existing data is verified if session foreign_key_checks=ON).

            {quote}
            MariaDB [testing]> CREATE TABLE companies (
                -> id int unsigned not null auto_increment primary key,
                -> name varchar(30));
            Query OK, 0 rows affected (0.019 sec)

            MariaDB [testing]> CREATE TABLE websites (
                -> id int unsigned not null auto_increment primary key,
                -> url varchar(100) not null,
                -> company_id int unsigned not null);
            Query OK, 0 rows affected (0.012 sec)

            MariaDB [testing]> INSERT INTO websites (url, company_id) VALUES ('https://www.skeema.io', 123);
            Query OK, 1 row affected (0.011 sec)

            MariaDB [testing]> SELECT version(), @@global.innodb_alter_copy_bulk, @@session.foreign_key_checks;
            +-------------------------+---------------------------------+------------------------------+
            | version() | @@global.innodb_alter_copy_bulk | @@session.foreign_key_checks |
            +-------------------------+---------------------------------+------------------------------+
            | 10.11.9-MariaDB-ubu2204 | 1 | 1 |
            +-------------------------+---------------------------------+------------------------------+
            1 row in set (0.003 sec)

            MariaDB [testing]> ALTER TABLE websites ADD CONSTRAINT foo FOREIGN KEY (company_id) REFERENCES companies (id);
            Query OK, 1 row affected (0.013 sec)
            Records: 1 Duplicates: 0 Warnings: 0

            MariaDB [testing]> SET GLOBAL innodb_alter_copy_bulk = 0;
            Query OK, 0 rows affected (0.001 sec)

            MariaDB [testing]> ALTER TABLE websites ADD CONSTRAINT bar FOREIGN KEY (company_id) REFERENCES companies (id);
            ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`testing`.`#sql-alter-1-3`, CONSTRAINT `bar` FOREIGN KEY (`company_id`) REFERENCES `companies` (`id`))
            MariaDB [testing]>
            {quote}
            marko Marko Mäkelä made changes -
            Fix Version/s 10.11 [ 27614 ]
            Fix Version/s 11.2 [ 28603 ]
            Fix Version/s 11.4 [ 29301 ]
            Assignee Thirunarayanan Balathandayuthapani [ thiru ]
            Labels regression
            Priority Major [ 3 ] Critical [ 2 ]
            ralf.gebhardt Ralf Gebhardt made changes -
            thiru Thirunarayanan Balathandayuthapani made changes -
            Status Open [ 1 ] Confirmed [ 10101 ]
            thiru Thirunarayanan Balathandayuthapani made changes -
            Assignee Thirunarayanan Balathandayuthapani [ thiru ] Marko Mäkelä [ marko ]
            Status Confirmed [ 10101 ] In Review [ 10002 ]
            evanelias Evan Elias made changes -
            Affects Version/s 11.5.2 [ 29838 ]
            marko Marko Mäkelä made changes -
            Assignee Marko Mäkelä [ marko ] Thirunarayanan Balathandayuthapani [ thiru ]
            Status In Review [ 10002 ] Stalled [ 10000 ]
            marko Marko Mäkelä made changes -
            issue.field.resolutiondate 2024-08-23 09:12:31.0 2024-08-23 09:12:30.634
            marko Marko Mäkelä made changes -
            Fix Version/s 10.11.10 [ 29904 ]
            Fix Version/s 11.2.6 [ 29906 ]
            Fix Version/s 11.4.4 [ 29907 ]
            Fix Version/s 11.6.2 [ 29908 ]
            Fix Version/s 10.11 [ 27614 ]
            Fix Version/s 11.2 [ 28603 ]
            Fix Version/s 11.4 [ 29301 ]
            Resolution Fixed [ 1 ]
            Status Stalled [ 10000 ] Closed [ 6 ]

            The regression test caused some headache on merge to 11.6 due to MDEV-33655 having removed the option alter_algorithm.

            marko Marko Mäkelä added a comment - The regression test caused some headache on merge to 11.6 due to MDEV-33655 having removed the option alter_algorithm .
            marko Marko Mäkelä made changes -
            thiru Thirunarayanan Balathandayuthapani made changes -
            midenok Aleksey Midenkov made changes -
            Comment [ Why the test passes if it must fail on last alter?

            {code:sql}
            --echo #
            --echo # MDEV-34756 Validation of new foreign key skipped
            --echo # if innodb_alter_copy_bulk=ON
            --echo #
            CREATE TABLE t1(f1 INT NOT NULL PRIMARY KEY,
            f2 INT NOT NULL)ENGINE=InnoDB;
            CREATE TABLE t2(f1 INT NOT NULL PRIMARY KEY,
            f2 INT NOT NULL)ENGINE=InnoDB;
            --enable_info
            ALTER TABLE t2 ADD CONSTRAINT FOREIGN KEY(f1) REFERENCES t1(f1);
            --disable_info
            INSERT INTO t1 VALUES (1, 1);
            INSERT INTO t2 VALUES (1, 2);
            --replace_regex /#sql-alter-[0-9a-f-]*/#sql-alter/
            --error ER_NO_REFERENCED_ROW_2
            ALTER TABLE t2 ADD CONSTRAINT FOREIGN KEY(f2) REFERENCES t1(f1);
            INSERT INTO t1 VALUES(3, 1);
            --enable_info
            SET STATEMENT foreign_key_checks=0 FOR
            ALTER TABLE t2 ALGORITHM=COPY, ADD CONSTRAINT FOREIGN KEY(f2) REFERENCES t1(f1);
            ALTER TABLE t1 ALGORITHM=COPY, FORCE;
            ALTER TABLE t2 ALGORITHM=COPY, FORCE;
            --disable_info
            DROP TABLE t2, t1;
            {code}

            Also please don't append tiny test cases into slow tests. ]

            People

              thiru Thirunarayanan Balathandayuthapani
              evanelias Evan Elias
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start 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.