Bug #111849 | checkForServerUpgrade fails for INSERT INTO.SELECT FOR UPDATE routines | ||
---|---|---|---|
Submitted: | 21 Jul 2023 20:29 | Modified: | 3 Dec 2024 15:13 |
Reporter: | Marc Reilly | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | Shell Upgrade Checker | Severity: | S3 (Non-critical) |
Version: | 8.0 | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | checkForServerUpgrade, mysql shell, routinesSyntaxCheck |
[21 Jul 2023 20:29]
Marc Reilly
[21 Jul 2023 21:00]
Marc Reilly
Another (simple) example of a syntax that will fail checkForServerUpgrade, but succeeds in MySQL 8: delimiter // CREATE PROCEDURE test.test_proc() BEGIN create temporary table t3 select '1', '2'; select t3.1, t3.2 from t3; END// delimiter ; # checkForServerUpgrade fails MySQL JS > util.checkForServerUpgrade() The MySQL server at localhost:5743, version 5.7.43 - MySQL Community Server (GPL), will now be checked for compatibility issues for upgrade to MySQL 8.0.34... 1) Usage of old temporal type No issues found 2) MySQL 8.0 syntax check for routine-like objects The following objects did not pass a syntax check with the latest MySQL 8.0 grammar. A common reason is that they reference names that conflict with new reserved keywords. You must update these routine definitions and `quote` any such references before upgrading. More information: https://dev.mysql.com/doc/refman/en/keywords.html test.test_proc - at line 3,9: unexpected token '.1' . . . . Errors: 1 Warnings: 1 Notices: 2 ERROR: 1 errors were found. Please correct these issues before upgrading to avoid compatibility issues. # Running on 8.0.34 returns no error: mysql [localhost:8034] {msandbox} (test) > select @@version; +-----------+ | @@version | +-----------+ | 8.0.34 | +-----------+ 1 row in set (0.00 sec) mysql [localhost:8034] {msandbox} (test) > create temporary table t3 select '1', '2'; Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql [localhost:8034] {msandbox} (test) > select * from t3; +---+---+ | 1 | 2 | +---+---+ | 1 | 2 | +---+---+ 1 row in set (0.00 sec)
[21 Jul 2023 21:04]
Marc Reilly
Last comment is not a reserved word but can be overcome by adding `quotes` as suggested. INSERT SELECT FOR UPDATE is a bit more tricky.
[24 Jul 2023 12:44]
MySQL Verification Team
Hi Mr. Reilly, Thank you for your bug report. However, shell output is correct. 8.0 does not support INSERT INTO ..... SELECT .... FOR UPDATE or IN SHARE MODE. This is the only syntax that is supported: INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [PARTITION (partition_name [, partition_name] ...)] [(col_name [, col_name] ...)] { SELECT ... | TABLE table_name | VALUES row_constructor_list } [ON DUPLICATE KEY UPDATE assignment_list] Not a bug.
[24 Jul 2023 16:41]
Marc Reilly
Hi, Thanks for the update. This syntax works on every MySQL release since 5.5 without any error or warning. I tested versions : - 5.5.62(EOL - demonstration purposes only) - 5.6.51(EOL - demonstration purposes only) - 5.7.43 - 8.0.34 - 8.1.0 In **all** these releases INSERT..SELECT FOR UPDATE works without any error or warning in the mysql client. So if this is not a bug in the MySQL shell parser, can you confirm if this is a documentation bug or an engine bug? From my tests below, it seems the engine will handle this syntax without error. Shouldn't the engine return an error if the syntax is not supported? Thanks, Marc ``` create database if not exists test; use test; create table test(id int, val varchar(50)) engine=innodb; create table foo(id int, val varchar(50)) engine=innodb; insert into foo values(1,'ssss'),(2,'ssss'),(3,'cdaasxass'),(4,'cdacadc'); select @@version; INSERT INTO test(id, val) SELECT id, val FROM foo FOR UPDATE; ``` 8.1.0 ``` mysql [localhost:8100] {msandbox} (test) > select @@version; +-----------+ | @@version | +-----------+ | 8.1.0 | +-----------+ 1 row in set (0.00 sec) mysql [localhost:8100] {msandbox} (test) > INSERT INTO test(id, val) SELECT id, val FROM foo FOR UPDATE; Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 ``` 8.0.34 ``` mysql [localhost:8034] {msandbox} (test) > select @@version; +-----------+ | @@version | +-----------+ | 8.0.34 | +-----------+ 1 row in set (0.00 sec) mysql [localhost:8034] {msandbox} (test) > INSERT INTO test(id, val) SELECT id, val FROM foo FOR UPDATE; Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql [localhost:8034] {msandbox} (test) > ``` 5.7.43: ``` mysql [localhost:5743] {msandbox} (test) > select @@version; +-----------+ | @@version | +-----------+ | 5.7.43 | +-----------+ 1 row in set (0.00 sec) mysql [localhost:5743] {msandbox} (test) > INSERT INTO test(id, val) SELECT id, val FROM foo FOR UPDATE; Query OK, 4 rows affected (0.01 sec) Records: 4 Duplicates: 0 Warnings: 0 ``` 5.6.51 (EOL - demonstration purposes only) ``` mysql [localhost:5651] {msandbox} (test) > select @@version; +-----------+ | @@version | +-----------+ | 5.6.51 | +-----------+ 1 row in set (0.00 sec) mysql [localhost:5651] {msandbox} (test) > INSERT INTO test(id, val) SELECT id, val FROM foo FOR UPDATE; Query OK, 4 rows affected (0.01 sec) Records: 4 Duplicates: 0 Warnings: 0 ``` 5.5.62 (EOL - demonstration purposes only) ``` mysql [localhost:5562] {msandbox} (test) > select @@version; +-----------+ | @@version | +-----------+ | 5.5.62 | +-----------+ 1 row in set (0.00 sec) mysql [localhost:5562] {msandbox} (test) > INSERT INTO test(id, val) SELECT id, val FROM foo FOR UPDATE; Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 ``` ======================================= ======================================= Demonstration of INSERT... SELECT .. FOR UPDATE functionality ====== Example 1: Session 2 not blocked without for update in session 1: ====== Session 1 ``` mysql [localhost:8034] {msandbox} (test) > select @@version,@@transaction_isolation; +-----------+-------------------------+ | @@version | @@transaction_isolation | +-----------+-------------------------+ | 8.0.34 | READ-COMMITTED | +-----------+-------------------------+ 1 row in set (0.00 sec) mysql [localhost:8034] {msandbox} (test) > begin; Query OK, 0 rows affected (0.00 sec) mysql [localhost:8034] {msandbox} (test) > INSERT INTO test(id, val) SELECT id, val FROM foo where id=1; Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 ``` Session 2: ``` # ID 1 and 2 updated as expected- no FOR UPDATE in session 1 mysql [localhost:8034] {msandbox} (test) > update foo set val=122 WHERE ID=2; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql [localhost:8034] {msandbox} (test) > update foo set val=122 WHERE ID=1; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 ``` ====== Example 2: With select for update in session 1, session 2 is blocked when trying to change locked row: ====== Session 1: ``` mysql [localhost:8034] {msandbox} (test) > select @@version,@@transaction_isolation; +-----------+-------------------------+ | @@version | @@transaction_isolation | +-----------+-------------------------+ | 8.0.34 | READ-COMMITTED | +-----------+-------------------------+ 1 row in set (0.00 sec) mysql [localhost:8034] {msandbox} (test) > begin; Query OK, 0 rows affected (0.00 sec) mysql [localhost:8034] {msandbox} (test) > INSERT INTO test(id, val) SELECT id, val FROM foo where id=1 FOR UPDATE; Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 ``` Session 2: ``` # ID 2 succeeds mysql [localhost:8034] {msandbox} (test) > update foo set id=id+1; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction mysql [localhost:8034] {msandbox} (test) > # ID 1 times out as THE record is locked by session 1 INSERT..SELECT..FOR UPDATE mysql [localhost:8034] {msandbox} (test) > update foo set val=122 WHERE ID=1; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction ```
[24 Jul 2023 16:55]
Marc Reilly
TYPE IN "Example 2", should be: ====== Example 2: With select for update in session 1, session 2 is blocked when trying to change locked row: ====== Session 1: ``` mysql [localhost:8034] {msandbox} (test) > select @@version,@@transaction_isolation; +-----------+-------------------------+ | @@version | @@transaction_isolation | +-----------+-------------------------+ | 8.0.34 | READ-COMMITTED | +-----------+-------------------------+ 1 row in set (0.00 sec) mysql [localhost:8034] {msandbox} (test) > begin; Query OK, 0 rows affected (0.00 sec) mysql [localhost:8034] {msandbox} (test) > INSERT INTO test(id, val) SELECT id, val FROM foo where id=1 FOR UPDATE; Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 ``` Session 2: ``` # ID 2 succeeds mysql [localhost:8034] {msandbox} (test) > update foo set val=122 WHERE ID=2; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 # ID 1 times out as THE record is locked by session 1 `FOR UPDATE` mysql [localhost:8034] {msandbox} (test) > update foo set val=122 WHERE ID=1; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction ```
[25 Jul 2023 11:57]
MySQL Verification Team
Hi Mr. Reilly, You are correct. Although it was not supposed to be supported it is supported. This is now a verified bug for the MySQL Shell.
[18 Mar 2024 16:07]
Alexis Calderon
Has this issue been solved? I´m facing the same issue with MySQL 8.0.34
[19 Mar 2024 12:37]
MySQL Verification Team
Hi, No, this bug has not been resolved yet. When it is resolved, the information shall be posted to this page. So, just stay subscribe to this bug and you will get a mail when this issue is resolved.
[3 Dec 2024 14:39]
Marek Mlynarski
Posted by developer: Already fixed in the newest MySQL Shell (9.2.0) - changed syntax parser for routineSyntax check - now it properly accepts the "FOR UPDATE" syntax.
[3 Dec 2024 15:13]
MySQL Verification Team
Thank you, Marek, This bug is fixed now .......
[10 Jan 11:57]
Edward Gilmore
Added the following note to the MySQL Shell 9.2.0 release notes: The util.checkForServerUpgrade check, routineSyntax, is renamed to syntax and now uses the SQL version of the target server for the syntax checks. See Utility Checks.
[10 Jan 12:09]
MySQL Verification Team
Thank you , very much, Edward.