Description:
When gtid_mode=on and binary log is off, the server automatically inserts the transaction's GTID into mysql.gtid_executed within the transaction.
But if the GTID has already been inserted into the table by an explicit INSERT statement, the server crashes.
Explicit insert into mysql.gtid_executed is a strange and unsupported operation, but of course the server should not crash.
How to repeat:
==== .opt file ====
--skip-log-bin --gtid-mode=on --enforce-gtid-consistency
==== Test 1: GTID inserted before transaction ====
# Use the .opt file above.
--let $uuida=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
eval INSERT INTO mysql.gtid_executed VALUES ('$uuida', 1, 1);
eval SET GTID_NEXT = '$uuida:1';
CREATE TABLE t1 (a INT);
==== Test 2: GTID inserted within transaction ====
# Use the .opt file above.
--let $uuida=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
eval SET GTID_NEXT = '$uuida:1';
eval INSERT INTO mysql.gtid_executed VALUES ('$uuida', 1, 1);
==== Test 3: GTID inserted by concurrent transaction ====
# Use the .opt file above.
--connect (con2,127.0.0.1,root,,test,$MASTER_MYPORT,)
--let $uuida=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
eval SET GTID_NEXT = '$uuida:1';
--connection con2
eval INSERT INTO mysql.gtid_executed VALUES ('$uuida', 1, 1);
--connection default
CREATE TABLE t1 (a INT);
==== Stack trace ====
Thread 1 (Thread 0x7fbd046bb700 (LWP 27396)):
#0 0x00007fbd0c2d8f0c in pthread_kill () from /lib/x86_64-linux-gnu/libpthread.so.0
#1 0x0000000000e0ac91 in my_write_core (sig=6) at /home/sven/bzr/debug/trunk/mysys/stacktrace.c:246
#2 0x000000000081f494 in handle_fatal_signal (sig=6) at /home/sven/bzr/debug/trunk/sql/signal_handler.cc:219
#3 <signal handler called>
#4 0x00007fbd0b71cf77 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#5 0x00007fbd0b7205e8 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#6 0x00007fbd0b715d43 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#7 0x00007fbd0b715df2 in __assert_fail () from /lib/x86_64-linux-gnu/libc.so.6
#8 0x000000000088dfed in Ha_trx_info::is_trx_read_write (this=0x7fbcc00134b0) at /home/sven/bzr/debug/trunk/sql/transaction_info.h:108
#9 0x000000000087e126 in ha_check_and_coalesce_trx_read_only (thd=0x7fbcc0011f70, ha_list=0x7fbcc00134b0, all=false) at /home/sven/bzr/debug/trunk/sql/handler.cc:1332
#10 0x000000000087e4de in ha_commit_trans (thd=0x7fbcc0011f70, all=false, ignore_global_read_lock=false) at /home/sven/bzr/debug/trunk/sql/handler.cc:1466
#11 0x0000000000c10f87 in trans_commit_stmt (thd=0x7fbcc0011f70) at /home/sven/bzr/debug/trunk/sql/transaction.cc:367
#12 0x0000000000b32ffe in mysql_execute_command (thd=0x7fbcc0011f70) at /home/sven/bzr/debug/trunk/sql/sql_parse.cc:4857
#13 0x0000000000b347d1 in mysql_parse (thd=0x7fbcc0011f70, parser_state=0x7fbd046b9e80) at /home/sven/bzr/debug/trunk/sql/sql_parse.cc:5398
#14 0x0000000000b28e2b in dispatch_command (command=COM_QUERY, thd=0x7fbcc0011f70, packet=0x7fbcc0007761 "INSERT INTO mysql.gtid_executed VALUES ('aaaaaaaa-aaaa-aaaa-aaaa-", 'a' <repeats 12 times>, "', 1, 1)", packet_length=85) at /home/sven/bzr/debug/trunk/sql/sql_parse.cc:1247
#15 0x0000000000b27b7f in do_command (thd=0x7fbcc0011f70) at /home/sven/bzr/debug/trunk/sql/sql_parse.cc:834
#16 0x0000000000c39ce6 in handle_connection (arg=0x29da170) at /home/sven/bzr/debug/trunk/sql/conn_handler/connection_handler_per_thread.cc:298
#17 0x0000000001131d2b in pfs_spawn_thread (arg=0x29cedc0) at /home/sven/bzr/debug/trunk/storage/perfschema/pfs.cc:2072
#18 0x00007fbd0c2d3f6e in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
#19 0x00007fbd0b7e09cd in clone () from /lib/x86_64-linux-gnu/libc.so.6
Suggested fix:
This is a very strange thing for the user to do. It probably happens
because the automatic insertion of the GTID into the table does not
expect the duplicate key error.
Suggested fix:
- Make the code that automatically inserts a GTID into the table skip
the insert in case of a duplicate key error.
- Generate a warning whenever user manually inserts into the table.