[MDEV-16263] mysql_client_test: test_mysql_insert_id fails Created: 2018-05-23  Updated: 2023-09-19

Status: Confirmed
Project: MariaDB Server
Component/s: Tests
Affects Version/s: 5.5.60, 10.2.14
Fix Version/s: 10.4

Type: Bug Priority: Minor
Reporter: Michal Schorm Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Fedora 27
RHEL 7



 Description   

Fedora - mariadb 10.2.14

#####################################
200 of (1/1): test_mysql_insert_id  
#####################################
 
 [MySQL-10.2.14-MariaDB][1062] Duplicate entry '12' for key 'PRIMARY'
 
 [MySQL-10.2.14-MariaDB][1062] Duplicate entry '12' for key 'PRIMARY'
 
 [MySQL-10.2.14-MariaDB][1062] Duplicate entry '12' for key 'PRIMARY'
 
 [MySQL-10.2.14-MariaDB][1062] Duplicate entry '12' for key 'PRIMARY'
/builddir/build/BUILD/mariadb-10.2.14/tests/mysql_client_test.c:15638: check failed: 'res == 20'
MySQL error 0: 
1

RHEL 7 - mariadb 5.5.60

#####################################
199 of (1/1): test_mysql_insert_id  
#####################################
 
 [MySQL-5.5.60-MariaDB][1062] Duplicate entry '12' for key 'PRIMARY'
 
 [MySQL-5.5.60-MariaDB][1062] Duplicate entry '12' for key 'PRIMARY'
 
 [MySQL-5.5.60-MariaDB][1062] Duplicate entry '12' for key 'PRIMARY'
 
 [MySQL-5.5.60-MariaDB][1062] Duplicate entry '12' for key 'PRIMARY'
/builddir/build/BUILD/mariadb-5.5.60/tests/mysql_client_test.c:15333: check failed: 'res == 20'
MySQL error 0: 
1

State of the table after the command
insert into t2 values (null,last_insert_id(300));

MariaDB [client_test_db]> select * from t2;
+----+------+
| f1 | f2   |
+----+------+
|  1 | a    |
|  2 | b    |
|  5 | c    |
|  6 | d    |
| 10 | a    |
| 11 | b    |
| 12 | a    |
| 13 | b    |
| 14 | a    |
| 15 | b    |
| 16 | a    |
| 17 | b    |
| 26 | 300  |
+----+------+


Clearly, the auto_increment bump on unsuccessful queries too.
Leading to the next value being 26 instead of 20.

If I print the res value it says 26, so the assumption in the comment about auto_increment priority is correct

  rc= mysql_query(mysql, "insert into t2 values (null,last_insert_id(300))");
  myquery(rc);
  res= mysql_insert_id(mysql);
  /*
    according to the manual, this might be 20 or 300, but it looks like
    auto_increment column takes priority over last_insert_id().
  */
  DIE_UNLESS(res == 20);



 Comments   
Comment by Elena Stepanova [ 2018-05-28 ]

I assume you are running the test directly, not via MTR.

The test is apparently maintained based on MTR runs only, it assumes that the tables are created as MyISAM by default, while when you run it directly, you probably have InnoDB. The test failure is easily reproducible with InnoDB.

In some cases, auto-increment does behave differently in MyISAM and InnoDB; in can even behave differently within InnoDB, depending on innodb_autoinc_lock_mode value. This particular failure is caused by the difference upon what InnoDB documentation calls "mixed-mode inserts" – those multi-row inserts which insert both explicit and auto-generated value. It is not related to the query being unsuccessful (although in this test this statement is supposed to be unsuccessful), but the difference is generic. In the default consecutive lock mode, as documented, "InnoDB allocates more auto-increment values than the number of rows to be inserted", while MyISAM does not. The table auto-increment diverges at this point, and the difference shows a couple statements later, when it's actually used and the result is checked. InnoDB with the traditional lock mode would pass there.

Further, assuming it passes this step, on 5.5-10.1 it will still fail in the same mysql_insert_id test a few steps later. That time it is due to the different behavior of UPDATE. Again, as documented, InnoDB up to and including 5.6 would not update table auto-increment value if you perform an UPDATE operation that changes an AUTO_INCREMENT column value to a value larger than the current maximum auto-increment value, while MyISAM would. Again, table values diverge, and the difference soon shows up in the test. This behavior has been changed/fixed in 10.2+ on the InnoDB side.

Non-default storage engine is not the only option that prevents the test from passing on a server started with all defaults. On 10.x it requires at least also higher value of max_allowed_packet (MTR configuration suggests 32,000,000). Also, the test assumes that there are no anonymous accounts in the system. MTR takes care of all of that, but if the test runs in a standalone mode, it's up to the user now.

Probably the test should be modified to be more resistant (self-contained), e.g. use explicit ENGINE= clauses, set max_allowed_packet when it's necessary, etc.

Comment by Daniel Black [ 2020-11-19 ]

Test branch: bb-10.2-danielblack-MDEV-16263-mysql_client_test-non-mtr-run

  • uses default_storage_engine=Aria for mysql_insert_id test. elenst is this too strict? MyiSAM and then Aria for 10.4+? Or alternately just select `default_storage_engine` and ensure its in the MyISAM/ARIA set?
  • checks for anon users on those tests, skips if they exist
  • skips a few other tests that have qa plugins and harder environments if its not MTR (by MTR_PERL).
  • ensure the packet size for test_big_packet

non mtr test

~/repos/build-mariadb-server-10.2 
$ ./tests/mysql_client_test -S /tmp/build-mariadb-server-10.2.sock -u root
 
....
...
#####################################
client_disconnect  
#####################################
 
 dropping the test database 'client_test_db' ...OK
 closing the connection ...OK
 
 
All '251' tests were successful (in '1' iterations)
  Total execution time: 2 SECS
 
!!! SUCCESS !!!

Comment by Daniel Black [ 2020-11-24 ]

elenst Is this acceptable as a fix? - https://github.com/MariaDB/server/commit/7f9c9dc11d1425e545c542d29dd4c4f4717accec

Generated at Thu Feb 08 08:27:36 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.