Browse Source

Aria will now register it's transactions

MDEV-22531 Remove maria::implicit_commit()
MDEV-22607 Assertion `ha_info->ht() != binlog_hton' failed in
           MYSQL_BIN_LOG::unlog_xa_prepare

From the handler point of view, Aria now looks like a transactional
engine. One effect of this is that we don't need to call
maria::implicit_commit() anymore.

This change also forces the server to call trans_commit_stmt() after doing
any read or writes to system tables.  This work will also make it easier
to later allow users to have system tables in other engines than Aria.

To handle the case that Aria doesn't support rollback, a new
handlerton flag, HTON_NO_ROLLBACK, was added to engines that has
transactions without rollback (for the moment only binlog and Aria).

Other things
- Moved freeing of MARIA_SHARE to a separate function as the MARIA_SHARE
  can be still part of a transaction even if the table has closed.
- Changed Aria checkpoint to use the new MARIA_SHARE free function. This
  fixes a possible memory leak when using S3 tables
- Changed testing of binlog_hton to instead test for HTON_NO_ROLLBACK
- Removed checking of has_transaction_manager() in handler.cc as we can
  assume that as the transaction was started by the engine, it does
  support transactions.
- Added new class 'start_new_trans' that can be used to start indepdendent
  sub transactions, for example while reading mysql.proc, using help or
  status tables etc.
- open_system_tables...() and open_proc_table_for_Read() doesn't anymore
  take a Open_tables_backup list. This is now handled by 'start_new_trans'.
- Split thd::has_transactions() to thd::has_transactions() and
  thd::has_transactions_and_rollback()
- Added handlerton code to free cached transactions objects.
  Needed by InnoDB.

squash! 2ed35999f2
bb-10.5-aria
Monty 6 years ago
parent
commit
4102f1589c
  1. 15
      mysql-test/include/commit.inc
  2. 37
      mysql-test/main/backup_lock.result
  3. 30
      mysql-test/main/backup_lock.test
  4. 19
      mysql-test/main/commit_1innodb.result
  5. 6
      mysql-test/main/warnings_debug.result
  6. 2
      mysql-test/main/warnings_debug.test
  7. 54
      mysql-test/main/xa_binlog.result
  8. 35
      mysql-test/main/xa_binlog.test
  9. 159
      mysql-test/suite/handler/aria.result
  10. 161
      mysql-test/suite/handler/handler.inc
  11. 159
      mysql-test/suite/handler/heap.result
  12. 338
      mysql-test/suite/handler/innodb.result
  13. 1
      mysql-test/suite/handler/innodb.test
  14. 159
      mysql-test/suite/handler/myisam.result
  15. 182
      mysql-test/suite/handler/savepoint.inc
  16. 5
      mysql-test/suite/maria/maria-connect.result
  17. 1
      mysql-test/suite/maria/maria-connect.test
  18. 186
      mysql-test/suite/maria/rollback.result
  19. 51
      mysql-test/suite/maria/rollback.test
  20. 19
      mysql-test/suite/maria/transaction.result
  21. 26
      mysql-test/suite/maria/transaction.test
  22. 956
      mysql-test/suite/perfschema/r/event_aggregate.result
  23. 652
      mysql-test/suite/perfschema/r/event_aggregate_no_a.result
  24. 556
      mysql-test/suite/perfschema/r/event_aggregate_no_a_no_h.result
  25. 332
      mysql-test/suite/perfschema/r/event_aggregate_no_a_no_u.result
  26. 236
      mysql-test/suite/perfschema/r/event_aggregate_no_a_no_u_no_h.result
  27. 860
      mysql-test/suite/perfschema/r/event_aggregate_no_h.result
  28. 636
      mysql-test/suite/perfschema/r/event_aggregate_no_u.result
  29. 540
      mysql-test/suite/perfschema/r/event_aggregate_no_u_no_h.result
  30. 208
      mysql-test/suite/perfschema/r/transaction_nested_events.result
  31. 4
      mysql-test/suite/perfschema/t/transaction_nested_events.test
  32. 83
      sql/event_db_repository.cc
  33. 2
      sql/event_scheduler.cc
  34. 6
      sql/ha_partition.cc
  35. 27
      sql/handler.cc
  36. 42
      sql/handler.h
  37. 35
      sql/log.cc
  38. 2
      sql/log_event_server.cc
  39. 2
      sql/share/errmsg-utf8.txt
  40. 72
      sql/sp.cc
  41. 2
      sql/sp.h
  42. 59
      sql/sql_base.cc
  43. 5
      sql/sql_base.h
  44. 90
      sql/sql_class.cc
  45. 37
      sql/sql_class.h
  46. 6
      sql/sql_delete.cc
  47. 11
      sql/sql_help.cc
  48. 12
      sql/sql_insert.cc
  49. 4
      sql/sql_load.cc
  50. 60
      sql/sql_parse.cc
  51. 3
      sql/sql_sequence.cc
  52. 13
      sql/sql_show.cc
  53. 87
      sql/sql_statistics.cc
  54. 4
      sql/sql_trigger.cc
  55. 2
      sql/sql_truncate.cc
  56. 8
      sql/sql_update.cc
  57. 13
      sql/transaction.cc
  58. 13
      sql/tztime.cc
  59. 95
      storage/maria/ha_maria.cc
  60. 5
      storage/maria/ma_checkpoint.c
  61. 64
      storage/maria/ma_close.c
  62. 4
      storage/maria/ma_open.c
  63. 22
      storage/maria/ma_state.c
  64. 13
      storage/maria/maria_def.h
  65. 2
      storage/spider/spd_db_conn.cc
  66. 17
      storage/spider/spd_sys_table.cc
  67. 41
      storage/spider/spd_table.cc

15
mysql-test/include/commit.inc

@ -405,6 +405,11 @@ end|
delimiter ;|
--echo # Reset Handler_commit and Handler_prepare counters
flush status;
--echo #
--echo # Count of reading of p_verify_status_increment() from mysql.proc
call p_verify_status_increment(2, 0, 2, 0);
--echo #
--echo # 1. Read-only statement: SELECT
--echo #
@ -562,7 +567,7 @@ begin
return 2;
end|
delimiter ;|
call p_verify_status_increment(0, 0, 0, 0);
call p_verify_status_increment(4, 0, 4, 0);
--echo # 16. A function changes non-trans-table.
--echo #
@ -571,7 +576,7 @@ call p_verify_status_increment(0, 0, 0, 0);
--echo # the binary log.
--echo #
select f1();
call p_verify_status_increment(1, 0, 1, 0);
call p_verify_status_increment(3, 0, 3, 0);
commit;
call p_verify_status_increment(1, 0, 1, 0);
@ -650,7 +655,7 @@ call p_verify_status_increment(0, 0, 0, 0);
--echo # 24. DDL: TRUNCATE TEMPORARY TABLE
--echo
truncate table t2;
call p_verify_status_increment(4, 0, 4, 0);
call p_verify_status_increment(2, 0, 2, 0);
commit;
--echo # There is nothing left to commit
call p_verify_status_increment(0, 0, 0, 0);
@ -763,7 +768,7 @@ call p_verify_status_increment(0, 0, 0, 0);
truncate table t3;
call p_verify_status_increment(2, 0, 2, 0);
create view v1 as select * from t2;
call p_verify_status_increment(2, 0, 2, 0);
call p_verify_status_increment(4, 0, 4, 0);
check table t1;
call p_verify_status_increment(2, 0, 2, 0);
--echo # Sic: after this bug is fixed, CHECK leaves no pending transaction
@ -774,7 +779,7 @@ call p_verify_status_increment(6, 0, 6, 0);
commit;
call p_verify_status_increment(0, 0, 0, 0);
drop view v1;
call p_verify_status_increment(0, 0, 0, 0);
call p_verify_status_increment(2, 0, 2, 0);
--echo #
--echo # Cleanup

37
mysql-test/main/backup_lock.result

@ -193,23 +193,51 @@ SET GLOBAL lock_wait_timeout=0;
CREATE TABLE t_permanent_innodb (col1 INT) ENGINE = InnoDB;
CREATE TABLE t_permanent_myisam (col1 INT) ENGINE = MyISAM;
CREATE TABLE t_permanent_aria (col1 INT) ENGINE = Aria transactional=1;
CREATE TABLE t_permanent_aria2 (col1 INT) ENGINE = Aria transactional=0;
INSERT INTO t_permanent_innodb SET col1 = 1;
INSERT INTO t_permanent_myisam SET col1 = 1;
INSERT INTO t_permanent_aria SET col1 = 1;
INSERT INTO t_permanent_aria2 SET col1 = 1;
CREATE TABLE t_con1_innodb (col1 INT) ENGINE = InnoDB;
CREATE TABLE t_con1_myisam (col1 INT) ENGINE = MyISAM;
connect con1,localhost,root,,;
SET AUTOCOMMIT = 0;
connection default;
BACKUP STAGE START;
BACKUP STAGE FLUSH;
BACKUP STAGE BLOCK_DDL;
BACKUP STAGE BLOCK_COMMIT;
connection con1;
SET AUTOCOMMIT = 1;
UPDATE t_permanent_aria SET col1 = 1;
UPDATE t_permanent_innodb SET col1 = 1;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
UPDATE t_permanent_innodb SET col1 = 8;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
UPDATE t_permanent_myisam SET col1 = 8;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
UPDATE t_permanent_aria SET col1 = 8;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
UPDATE t_permanent_aria2 SET col1 = 8;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
select * from t_permanent_innodb;
col1
1
select * from t_permanent_myisam;
col1
1
select * from t_permanent_aria;
col1
8
select * from t_permanent_aria2;
col1
1
SET AUTOCOMMIT = 0;
UPDATE t_permanent_innodb SET col1 = 9;
UPDATE t_permanent_aria SET col1 = 9;
UPDATE t_permanent_myisam SET col1 = 9;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
UPDATE t_permanent_aria2 SET col1 = 9;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
DROP TABLE t_con1_innodb;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
DROP TABLE t_con1_myisam;
@ -224,8 +252,11 @@ col1
1
select * from t_permanent_aria;
col1
8
DROP TABLE t_permanent_myisam, t_permanent_innodb, t_permanent_aria;
9
select * from t_permanent_aria2;
col1
1
DROP TABLE t_permanent_myisam, t_permanent_innodb, t_permanent_aria, t_permanent_aria2;
DROP TABLE t_con1_innodb, t_con1_myisam;
disconnect con1;
set global lock_wait_timeout=default;

30
mysql-test/main/backup_lock.test

@ -252,15 +252,16 @@ SET GLOBAL lock_wait_timeout=0;
CREATE TABLE t_permanent_innodb (col1 INT) ENGINE = InnoDB;
CREATE TABLE t_permanent_myisam (col1 INT) ENGINE = MyISAM;
CREATE TABLE t_permanent_aria (col1 INT) ENGINE = Aria transactional=1;
CREATE TABLE t_permanent_aria2 (col1 INT) ENGINE = Aria transactional=0;
INSERT INTO t_permanent_innodb SET col1 = 1;
INSERT INTO t_permanent_myisam SET col1 = 1;
INSERT INTO t_permanent_aria SET col1 = 1;
INSERT INTO t_permanent_aria2 SET col1 = 1;
CREATE TABLE t_con1_innodb (col1 INT) ENGINE = InnoDB;
CREATE TABLE t_con1_myisam (col1 INT) ENGINE = MyISAM;
--connect(con1,localhost,root,,)
SET AUTOCOMMIT = 0;
--connection default
BACKUP STAGE START;
@ -269,10 +270,34 @@ BACKUP STAGE BLOCK_DDL;
BACKUP STAGE BLOCK_COMMIT;
--connection con1
SET AUTOCOMMIT = 1;
# These should work as values are not changed
UPDATE t_permanent_aria SET col1 = 1;
--error ER_LOCK_WAIT_TIMEOUT
UPDATE t_permanent_innodb SET col1 = 1;
--error ER_LOCK_WAIT_TIMEOUT
UPDATE t_permanent_innodb SET col1 = 8;
--error ER_LOCK_WAIT_TIMEOUT
UPDATE t_permanent_myisam SET col1 = 8;
--error ER_LOCK_WAIT_TIMEOUT
UPDATE t_permanent_aria SET col1 = 8;
--error ER_LOCK_WAIT_TIMEOUT
UPDATE t_permanent_aria2 SET col1 = 8;
select * from t_permanent_innodb;
select * from t_permanent_myisam;
select * from t_permanent_aria;
select * from t_permanent_aria2;
SET AUTOCOMMIT = 0;
UPDATE t_permanent_innodb SET col1 = 9;
UPDATE t_permanent_aria SET col1 = 9;
--error ER_LOCK_WAIT_TIMEOUT
UPDATE t_permanent_myisam SET col1 = 9;
--error ER_LOCK_WAIT_TIMEOUT
UPDATE t_permanent_aria2 SET col1 = 9;
--error ER_LOCK_WAIT_TIMEOUT
DROP TABLE t_con1_innodb;
@ -286,8 +311,9 @@ BACKUP STAGE END;
select * from t_permanent_innodb;
select * from t_permanent_myisam;
select * from t_permanent_aria;
select * from t_permanent_aria2;
DROP TABLE t_permanent_myisam, t_permanent_innodb, t_permanent_aria;
DROP TABLE t_permanent_myisam, t_permanent_innodb, t_permanent_aria, t_permanent_aria2;
DROP TABLE t_con1_innodb, t_con1_myisam;
--disconnect con1
set global lock_wait_timeout=default;

19
mysql-test/main/commit_1innodb.result

@ -385,6 +385,11 @@ end if;
end|
# Reset Handler_commit and Handler_prepare counters
flush status;
#
# Count of reading of p_verify_status_increment() from mysql.proc
call p_verify_status_increment(2, 0, 2, 0);
SUCCESS
#
# 1. Read-only statement: SELECT
#
@ -568,7 +573,7 @@ begin
insert t2 set a=2;
return 2;
end|
call p_verify_status_increment(0, 0, 0, 0);
call p_verify_status_increment(4, 0, 4, 0);
SUCCESS
# 16. A function changes non-trans-table.
@ -580,7 +585,7 @@ SUCCESS
select f1();
f1()
2
call p_verify_status_increment(1, 0, 1, 0);
call p_verify_status_increment(3, 0, 3, 0);
SUCCESS
commit;
@ -688,9 +693,9 @@ SUCCESS
# 24. DDL: TRUNCATE TEMPORARY TABLE
truncate table t2;
call p_verify_status_increment(4, 0, 4, 0);
ERROR
Expected commit increment: 4 actual: 2
call p_verify_status_increment(2, 0, 2, 0);
SUCCESS
commit;
# There is nothing left to commit
call p_verify_status_increment(0, 0, 0, 0);
@ -855,7 +860,7 @@ call p_verify_status_increment(2, 0, 2, 0);
SUCCESS
create view v1 as select * from t2;
call p_verify_status_increment(2, 0, 2, 0);
call p_verify_status_increment(4, 0, 4, 0);
SUCCESS
check table t1;
@ -882,7 +887,7 @@ call p_verify_status_increment(0, 0, 0, 0);
SUCCESS
drop view v1;
call p_verify_status_increment(0, 0, 0, 0);
call p_verify_status_increment(2, 0, 2, 0);
SUCCESS
#

6
mysql-test/main/warnings_debug.result

@ -5,8 +5,12 @@ SET SESSION debug_dbug="+d,warn_during_ha_commit_trans";
INSERT INTO t1 VALUES (1);
Warnings:
Warning 1196 Some non-transactional changed tables couldn't be rolled back
Warning 1196 Some non-transactional changed tables couldn't be rolled back
Warning 1196 Some non-transactional changed tables couldn't be rolled back
SHOW WARNINGS;
Level Code Message
Warning 1196 Some non-transactional changed tables couldn't be rolled back
drop table t1;
Warning 1196 Some non-transactional changed tables couldn't be rolled back
Warning 1196 Some non-transactional changed tables couldn't be rolled back
SET debug_dbug= @saved_dbug;
drop table t1;

2
mysql-test/main/warnings_debug.test

@ -17,5 +17,5 @@ INSERT INTO t1 VALUES (1);
# packet. Show the warnings manually also.
SHOW WARNINGS;
drop table t1;
SET debug_dbug= @saved_dbug;
drop table t1;

54
mysql-test/main/xa_binlog.result

@ -18,7 +18,33 @@ a
1
2
3
SHOW BINLOG EVENTS LIMIT 3,12;
DROP TABLE t1;
CREATE TABLE t1 (a INT) ENGINE=Aria;
INSERT INTO t1 VALUES (1),(2);
XA BEGIN 'x';
DELETE FROM t1;
XA END 'x';
XA PREPARE 'x';
Warnings:
Warning 1030 Got error 131 "Command not supported by the engine" from storage engine Aria
XA COMMIT 'x';
SELECT * from t1;
a
XA BEGIN 'x';
INSERT INTO t1 VALUES (3),(4);
XA END 'x';
XA PREPARE 'x';
Warnings:
Warning 1030 Got error 131 "Command not supported by the engine" from storage engine Aria
XA ROLLBACK 'x';
Warnings:
Warning 1196 Some non-transactional changed tables couldn't be rolled back
SELECT * from t1;
a
3
4
DROP TABLE t1;
SHOW BINLOG EVENTS LIMIT 3,100;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid 1 # XA START X'786174657374',X'',1 GTID #-#-#
master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES (1)
@ -32,4 +58,28 @@ master-bin.000001 # Xid 1 # COMMIT /* xid=XX */
master-bin.000001 # Gtid 1 # BEGIN GTID #-#-#
master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES (3)
master-bin.000001 # Xid 1 # COMMIT /* xid=XX */
DROP TABLE t1;
master-bin.000001 # Gtid 1 # GTID #-#-#
master-bin.000001 # Query 1 # use `test`; DROP TABLE `t1` /* generated by server */
master-bin.000001 # Gtid 1 # GTID #-#-#
master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1 (a INT) ENGINE=Aria
master-bin.000001 # Gtid 1 # BEGIN GTID #-#-#
master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES (1),(2)
master-bin.000001 # Query 1 # COMMIT
master-bin.000001 # Gtid 1 # BEGIN GTID #-#-#
master-bin.000001 # Query 1 # use `test`; DELETE FROM t1
master-bin.000001 # Query 1 # COMMIT
master-bin.000001 # Gtid 1 # XA START X'78',X'',1 GTID #-#-#
master-bin.000001 # Query 1 # XA END X'78',X'',1
master-bin.000001 # XA_prepare 1 # XA PREPARE X'78',X'',1
master-bin.000001 # Gtid 1 # GTID #-#-#
master-bin.000001 # Query 1 # XA COMMIT X'78',X'',1
master-bin.000001 # Gtid 1 # BEGIN GTID #-#-#
master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES (3),(4)
master-bin.000001 # Query 1 # COMMIT
master-bin.000001 # Gtid 1 # XA START X'78',X'',1 GTID #-#-#
master-bin.000001 # Query 1 # XA END X'78',X'',1
master-bin.000001 # XA_prepare 1 # XA PREPARE X'78',X'',1
master-bin.000001 # Gtid 1 # GTID #-#-#
master-bin.000001 # Query 1 # XA ROLLBACK X'78',X'',1
master-bin.000001 # Gtid 1 # GTID #-#-#
master-bin.000001 # Query 1 # use `test`; DROP TABLE `t1` /* generated by server */

35
mysql-test/main/xa_binlog.test

@ -24,9 +24,38 @@ INSERT INTO t1 VALUES (3);
COMMIT;
SELECT * FROM t1 ORDER BY a;
DROP TABLE t1;
--replace_column 2 # 5 #
--replace_regex /xid=[0-9]+/xid=XX/ /GTID [0-9]+-[0-9]+-[0-9]+/GTID #-#-#/
SHOW BINLOG EVENTS LIMIT 3,12;
#
# MDEV-22607 Assertion `ha_info->ht() != binlog_hton' failed in
# MYSQL_BIN_LOG::unlog_xa_prepare
#
CREATE TABLE t1 (a INT) ENGINE=Aria;
INSERT INTO t1 VALUES (1),(2);
XA BEGIN 'x';
DELETE FROM t1;
XA END 'x';
XA PREPARE 'x';
# Cleanup
XA COMMIT 'x';
SELECT * from t1;
XA BEGIN 'x';
INSERT INTO t1 VALUES (3),(4);
XA END 'x';
XA PREPARE 'x';
XA ROLLBACK 'x';
SELECT * from t1;
DROP TABLE t1;
#
# Time to check the log
#
--replace_column 2 # 5 #
--replace_regex /xid=[0-9]+/xid=XX/ /GTID [0-9]+-[0-9]+-[0-9]+/GTID #-#-#/
SHOW BINLOG EVENTS LIMIT 3,100;

159
mysql-test/suite/handler/aria.result

@ -1132,166 +1132,7 @@ connection default;
# Reaping 'select * from t2'
ERROR 42S02: Table 'test.t2' doesn't exist
handler t1 close;
#
# ROLLBACK TO SAVEPOINT releases transactional locks,
# but has no effect on open HANDLERs
#
create table t2 like t1;
create table t3 like t1;
begin;
# Have something before the savepoint
select * from t3;
a
savepoint sv;
handler t1 open;
handler t1 read a first;
a
1
handler t1 read a next;
a
2
select * from t2;
a
connection con1;
# Sending:
drop table t1;
connection con2;
# Sending:
drop table t2;
connection default;
# Let DROP TABLE statements sync in. We must use
# a separate connection for that, because otherwise SELECT
# will auto-close the HANDLERs, becaues there are pending
# exclusive locks against them.
connection con3;
# Waiting for 'drop table t1' to get blocked...
# Waiting for 'drop table t2' to get blocked...
# Demonstrate that t2 lock was released and t2 was dropped
# after ROLLBACK TO SAVEPOINT
connection default;
rollback to savepoint sv;
connection con2;
# Reaping 'drop table t2'...
# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
# lock.
connection default;
handler t1 read a next;
a
3
handler t1 read a next;
a
4
# Demonstrate that the drop will go through as soon as we close the
# HANDLER
handler t1 close;
connection con1;
# Reaping 'drop table t1'...
connection default;
commit;
drop table t3;
#
# A few special cases when using SAVEPOINT/ROLLBACK TO
# SAVEPOINT and HANDLER.
#
# Show that rollback to the savepoint taken in the beginning
# of the transaction doesn't release mdl lock on
# the HANDLER that was opened later.
#
create table t1 (a int, key using btree (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
begin;
savepoint sv;
handler t1 open;
handler t1 read a first;
a
1
handler t1 read a next;
a
2
select * from t2;
a
connection con1;
# Sending:
drop table t1;
connection con2;
# Sending:
drop table t2;
connection default;
# Let DROP TABLE statements sync in. We must use
# a separate connection for that, because otherwise SELECT
# will auto-close the HANDLERs, becaues there are pending
# exclusive locks against them.
connection con3;
# Waiting for 'drop table t1' to get blocked...
# Waiting for 'drop table t2' to get blocked...
# Demonstrate that t2 lock was released and t2 was dropped
# after ROLLBACK TO SAVEPOINT
connection default;
rollback to savepoint sv;
connection con2;
# Reaping 'drop table t2'...
# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
# lock.
connection default;
handler t1 read a next;
a
3
handler t1 read a next;
a
4
# Demonstrate that the drop will go through as soon as we close the
# HANDLER
handler t1 close;
connection con1;
# Reaping 'drop table t1'...
connection default;
commit;
#
# Show that rollback to the savepoint taken in the beginning
# of the transaction works properly (no valgrind warnins, etc),
# even though it's done after the HANDLER mdl lock that was there
# at the beginning is released and added again.
#
create table t1 (a int, key using btree (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
create table t3 like t1;
insert into t3 (a) select a from t1;
begin;
handler t1 open;
savepoint sv;
handler t1 read a first;
a
1
select * from t2;
a
handler t1 close;
handler t3 open;
handler t3 read a first;
a
1
rollback to savepoint sv;
connection con1;
drop table t1, t2;
# Sending:
drop table t3;
# Let DROP TABLE statement sync in.
connection con2;
# Waiting for 'drop table t3' to get blocked...
# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
# lock.
connection default;
handler t3 read a next;
a
2
# Demonstrate that the drop will go through as soon as we close the
# HANDLER
handler t3 close;
connection con1;
# Reaping 'drop table t3'...
connection default;
commit;
#
# If we have to wait on an exclusive locks while having
# an open HANDLER, ER_LOCK_DEADLOCK is reported.

161
mysql-test/suite/handler/handler.inc

@ -890,166 +890,7 @@ connection default;
--error ER_NO_SUCH_TABLE
reap;
handler t1 close;
--echo #
--echo # ROLLBACK TO SAVEPOINT releases transactional locks,
--echo # but has no effect on open HANDLERs
--echo #
create table t2 like t1;
create table t3 like t1;
begin;
--echo # Have something before the savepoint
select * from t3;
savepoint sv;
handler t1 open;
handler t1 read a first;
handler t1 read a next;
select * from t2;
connection con1;
--echo # Sending:
--send drop table t1
connection con2;
--echo # Sending:
--send drop table t2
connection default;
--echo # Let DROP TABLE statements sync in. We must use
--echo # a separate connection for that, because otherwise SELECT
--echo # will auto-close the HANDLERs, becaues there are pending
--echo # exclusive locks against them.
connection con3;
--echo # Waiting for 'drop table t1' to get blocked...
let $wait_condition=select count(*)=1 from information_schema.processlist
where state='Waiting for table metadata lock' and
info='drop table t1';
--source include/wait_condition.inc
--echo # Waiting for 'drop table t2' to get blocked...
let $wait_condition=select count(*)=1 from information_schema.processlist
where state='Waiting for table metadata lock' and
info='drop table t2';
--source include/wait_condition.inc
--echo # Demonstrate that t2 lock was released and t2 was dropped
--echo # after ROLLBACK TO SAVEPOINT
connection default;
rollback to savepoint sv;
connection con2;
--echo # Reaping 'drop table t2'...
--reap
--echo # Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
--echo # lock.
connection default;
handler t1 read a next;
handler t1 read a next;
--echo # Demonstrate that the drop will go through as soon as we close the
--echo # HANDLER
handler t1 close;
connection con1;
--echo # Reaping 'drop table t1'...
--reap
connection default;
commit;
drop table t3;
--echo #
--echo # A few special cases when using SAVEPOINT/ROLLBACK TO
--echo # SAVEPOINT and HANDLER.
--echo #
--echo # Show that rollback to the savepoint taken in the beginning
--echo # of the transaction doesn't release mdl lock on
--echo # the HANDLER that was opened later.
--echo #
create table t1 (a int, key using btree (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
begin;
savepoint sv;
handler t1 open;
handler t1 read a first;
handler t1 read a next;
select * from t2;
connection con1;
--echo # Sending:
--send drop table t1
connection con2;
--echo # Sending:
--send drop table t2
connection default;
--echo # Let DROP TABLE statements sync in. We must use
--echo # a separate connection for that, because otherwise SELECT
--echo # will auto-close the HANDLERs, becaues there are pending
--echo # exclusive locks against them.
connection con3;
--echo # Waiting for 'drop table t1' to get blocked...
let $wait_condition=select count(*)=1 from information_schema.processlist
where state='Waiting for table metadata lock' and
info='drop table t1';
--source include/wait_condition.inc
--echo # Waiting for 'drop table t2' to get blocked...
let $wait_condition=select count(*)=1 from information_schema.processlist
where state='Waiting for table metadata lock' and
info='drop table t2';
--source include/wait_condition.inc
--echo # Demonstrate that t2 lock was released and t2 was dropped
--echo # after ROLLBACK TO SAVEPOINT
connection default;
rollback to savepoint sv;
connection con2;
--echo # Reaping 'drop table t2'...
--reap
--echo # Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
--echo # lock.
connection default;
handler t1 read a next;
handler t1 read a next;
--echo # Demonstrate that the drop will go through as soon as we close the
--echo # HANDLER
handler t1 close;
connection con1;
--echo # Reaping 'drop table t1'...
--reap
connection default;
commit;
--echo #
--echo # Show that rollback to the savepoint taken in the beginning
--echo # of the transaction works properly (no valgrind warnins, etc),
--echo # even though it's done after the HANDLER mdl lock that was there
--echo # at the beginning is released and added again.
--echo #
create table t1 (a int, key using btree (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
create table t3 like t1;
insert into t3 (a) select a from t1;
begin;
handler t1 open;
savepoint sv;
handler t1 read a first;
select * from t2;
handler t1 close;
handler t3 open;
handler t3 read a first;
rollback to savepoint sv;
connection con1;
drop table t1, t2;
--echo # Sending:
--send drop table t3
--echo # Let DROP TABLE statement sync in.
connection con2;
--echo # Waiting for 'drop table t3' to get blocked...
let $wait_condition=select count(*)=1 from information_schema.processlist
where state='Waiting for table metadata lock' and
info='drop table t3';
--source include/wait_condition.inc
--echo # Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
--echo # lock.
connection default;
handler t3 read a next;
--echo # Demonstrate that the drop will go through as soon as we close the
--echo # HANDLER
handler t3 close;
connection con1;
--echo # Reaping 'drop table t3'...
--reap
connection default;
commit;
drop table t1;
--echo #
--echo # If we have to wait on an exclusive locks while having

159
mysql-test/suite/handler/heap.result

@ -1131,166 +1131,7 @@ connection default;
# Reaping 'select * from t2'
ERROR 42S02: Table 'test.t2' doesn't exist
handler t1 close;
#
# ROLLBACK TO SAVEPOINT releases transactional locks,
# but has no effect on open HANDLERs
#
create table t2 like t1;
create table t3 like t1;
begin;
# Have something before the savepoint
select * from t3;
a
savepoint sv;
handler t1 open;
handler t1 read a first;
a
1
handler t1 read a next;
a
2
select * from t2;
a
connection con1;
# Sending:
drop table t1;
connection con2;
# Sending:
drop table t2;
connection default;
# Let DROP TABLE statements sync in. We must use
# a separate connection for that, because otherwise SELECT
# will auto-close the HANDLERs, becaues there are pending
# exclusive locks against them.
connection con3;
# Waiting for 'drop table t1' to get blocked...
# Waiting for 'drop table t2' to get blocked...
# Demonstrate that t2 lock was released and t2 was dropped
# after ROLLBACK TO SAVEPOINT
connection default;
rollback to savepoint sv;
connection con2;
# Reaping 'drop table t2'...
# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
# lock.
connection default;
handler t1 read a next;
a
3
handler t1 read a next;
a
4
# Demonstrate that the drop will go through as soon as we close the
# HANDLER
handler t1 close;
connection con1;
# Reaping 'drop table t1'...
connection default;
commit;
drop table t3;
#
# A few special cases when using SAVEPOINT/ROLLBACK TO
# SAVEPOINT and HANDLER.
#
# Show that rollback to the savepoint taken in the beginning
# of the transaction doesn't release mdl lock on
# the HANDLER that was opened later.
#
create table t1 (a int, key using btree (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
begin;
savepoint sv;
handler t1 open;
handler t1 read a first;
a
1
handler t1 read a next;
a
2
select * from t2;
a
connection con1;
# Sending:
drop table t1;
connection con2;
# Sending:
drop table t2;
connection default;
# Let DROP TABLE statements sync in. We must use
# a separate connection for that, because otherwise SELECT
# will auto-close the HANDLERs, becaues there are pending
# exclusive locks against them.
connection con3;
# Waiting for 'drop table t1' to get blocked...
# Waiting for 'drop table t2' to get blocked...
# Demonstrate that t2 lock was released and t2 was dropped
# after ROLLBACK TO SAVEPOINT
connection default;
rollback to savepoint sv;
connection con2;
# Reaping 'drop table t2'...
# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
# lock.
connection default;
handler t1 read a next;
a
3
handler t1 read a next;
a
4
# Demonstrate that the drop will go through as soon as we close the
# HANDLER
handler t1 close;
connection con1;
# Reaping 'drop table t1'...
connection default;
commit;
#
# Show that rollback to the savepoint taken in the beginning
# of the transaction works properly (no valgrind warnins, etc),
# even though it's done after the HANDLER mdl lock that was there
# at the beginning is released and added again.
#
create table t1 (a int, key using btree (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
create table t3 like t1;
insert into t3 (a) select a from t1;
begin;
handler t1 open;
savepoint sv;
handler t1 read a first;
a
1
select * from t2;
a
handler t1 close;
handler t3 open;
handler t3 read a first;
a
1
rollback to savepoint sv;
connection con1;
drop table t1, t2;
# Sending:
drop table t3;
# Let DROP TABLE statement sync in.
connection con2;
# Waiting for 'drop table t3' to get blocked...
# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
# lock.
connection default;
handler t3 read a next;
a
2
# Demonstrate that the drop will go through as soon as we close the
# HANDLER
handler t3 close;
connection con1;
# Reaping 'drop table t3'...
connection default;
commit;
#
# If we have to wait on an exclusive locks while having
# an open HANDLER, ER_LOCK_DEADLOCK is reported.

338
mysql-test/suite/handler/innodb.result

@ -1136,166 +1136,7 @@ connection default;
# Reaping 'select * from t2'
ERROR 42S02: Table 'test.t2' doesn't exist
handler t1 close;
#
# ROLLBACK TO SAVEPOINT releases transactional locks,
# but has no effect on open HANDLERs
#
create table t2 like t1;
create table t3 like t1;
begin;
# Have something before the savepoint
select * from t3;
a
savepoint sv;
handler t1 open;
handler t1 read a first;
a
1
handler t1 read a next;
a
2
select * from t2;
a
connection con1;
# Sending:
drop table t1;
connection con2;
# Sending:
drop table t2;
connection default;
# Let DROP TABLE statements sync in. We must use
# a separate connection for that, because otherwise SELECT
# will auto-close the HANDLERs, becaues there are pending
# exclusive locks against them.
connection con3;
# Waiting for 'drop table t1' to get blocked...
# Waiting for 'drop table t2' to get blocked...
# Demonstrate that t2 lock was released and t2 was dropped
# after ROLLBACK TO SAVEPOINT
connection default;
rollback to savepoint sv;
connection con2;
# Reaping 'drop table t2'...
# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
# lock.
connection default;
handler t1 read a next;
a
3
handler t1 read a next;
a
4
# Demonstrate that the drop will go through as soon as we close the
# HANDLER
handler t1 close;
connection con1;
# Reaping 'drop table t1'...
connection default;
commit;
drop table t3;
#
# A few special cases when using SAVEPOINT/ROLLBACK TO
# SAVEPOINT and HANDLER.
#
# Show that rollback to the savepoint taken in the beginning
# of the transaction doesn't release mdl lock on
# the HANDLER that was opened later.
#
create table t1 (a int, key using btree (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
begin;
savepoint sv;
handler t1 open;
handler t1 read a first;
a
1
handler t1 read a next;
a
2
select * from t2;
a
connection con1;
# Sending:
drop table t1;
connection con2;
# Sending:
drop table t2;
connection default;
# Let DROP TABLE statements sync in. We must use
# a separate connection for that, because otherwise SELECT
# will auto-close the HANDLERs, becaues there are pending
# exclusive locks against them.
connection con3;
# Waiting for 'drop table t1' to get blocked...
# Waiting for 'drop table t2' to get blocked...
# Demonstrate that t2 lock was released and t2 was dropped
# after ROLLBACK TO SAVEPOINT
connection default;
rollback to savepoint sv;
connection con2;
# Reaping 'drop table t2'...
# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
# lock.
connection default;
handler t1 read a next;
a
3
handler t1 read a next;
a
4
# Demonstrate that the drop will go through as soon as we close the
# HANDLER
handler t1 close;
connection con1;
# Reaping 'drop table t1'...
connection default;
commit;
#
# Show that rollback to the savepoint taken in the beginning
# of the transaction works properly (no valgrind warnins, etc),
# even though it's done after the HANDLER mdl lock that was there
# at the beginning is released and added again.
#
create table t1 (a int, key using btree (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
create table t3 like t1;
insert into t3 (a) select a from t1;
begin;
handler t1 open;
savepoint sv;
handler t1 read a first;
a
1
select * from t2;
a
handler t1 close;
handler t3 open;
handler t3 read a first;
a
1
rollback to savepoint sv;
connection con1;
drop table t1, t2;
# Sending:
drop table t3;
# Let DROP TABLE statement sync in.
connection con2;
# Waiting for 'drop table t3' to get blocked...
# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
# lock.
connection default;
handler t3 read a next;
a
2
# Demonstrate that the drop will go through as soon as we close the
# HANDLER
handler t3 close;
connection con1;
# Reaping 'drop table t3'...
connection default;
commit;
#
# If we have to wait on an exclusive locks while having
# an open HANDLER, ER_LOCK_DEADLOCK is reported.
@ -1742,6 +1583,185 @@ HANDLER t1 READ a NEXT;
a
HANDLER t1 CLOSE;
DROP TABLE t1;
#
# Testing savepoints with handlers that supports it
#
connect con1, localhost, root,,;
connect con2, localhost, root,,;
connect con3, localhost, root,,;
connection default;
#
# ROLLBACK TO SAVEPOINT releases transactional locks,
# but has no effect on open HANDLERs
#
create table t1 (a int, key a (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
create table t3 like t1;
begin;
# Have something before the savepoint
select * from t3;
a
savepoint sv;
handler t1 open;
handler t1 read a first;
a
1
handler t1 read a next;
a
2
select * from t2;
a
connection con1;
# Sending:
drop table t1;
connection con2;
# Sending:
drop table t2;
connection default;
# Let DROP TABLE statements sync in. We must use
# a separate connection for that, because otherwise SELECT
# will auto-close the HANDLERs, becaues there are pending
# exclusive locks against them.
connection con3;
# Waiting for 'drop table t1' to get blocked...
# Waiting for 'drop table t2' to get blocked...
# Demonstrate that t2 lock was released and t2 was dropped
# after ROLLBACK TO SAVEPOINT
connection default;
rollback to savepoint sv;
connection con2;
# Reaping 'drop table t2'...
# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
# lock.
connection default;
handler t1 read a next;
a
3
handler t1 read a next;
a
4
# Demonstrate that the drop will go through as soon as we close the
# HANDLER
handler t1 close;
connection con1;
# Reaping 'drop table t1'...
connection default;
commit;
drop table t3;
#
# A few special cases when using SAVEPOINT/ROLLBACK TO
# SAVEPOINT and HANDLER.
#
# Show that rollback to the savepoint taken in the beginning
# of the transaction doesn't release mdl lock on
# the HANDLER that was opened later.
#
create table t1 (a int, key using btree (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
begin;
savepoint sv;
handler t1 open;
handler t1 read a first;
a
1
handler t1 read a next;
a
2
select * from t2;
a
connection con1;
# Sending:
drop table t1;
connection con2;
# Sending:
drop table t2;
connection default;
# Let DROP TABLE statements sync in. We must use
# a separate connection for that, because otherwise SELECT
# will auto-close the HANDLERs, becaues there are pending
# exclusive locks against them.
connection con3;
# Waiting for 'drop table t1' to get blocked...
# Waiting for 'drop table t2' to get blocked...
# Demonstrate that t2 lock was released and t2 was dropped
# after ROLLBACK TO SAVEPOINT
connection default;
rollback to savepoint sv;
connection con2;
# Reaping 'drop table t2'...
# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
# lock.
connection default;
handler t1 read a next;
a
3
handler t1 read a next;
a
4
# Demonstrate that the drop will go through as soon as we close the
# HANDLER
handler t1 close;
connection con1;
# Reaping 'drop table t1'...
connection default;
commit;
#
# Show that rollback to the savepoint taken in the beginning
# of the transaction works properly (no valgrind warnins, etc),
# even though it's done after the HANDLER mdl lock that was there
# at the beginning is released and added again.
#
create table t1 (a int, key using btree (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
create table t3 like t1;
insert into t3 (a) select a from t1;
begin;
handler t1 open;
savepoint sv;
handler t1 read a first;
a
1
select * from t2;
a
handler t1 close;
handler t3 open;
handler t3 read a first;
a
1
rollback to savepoint sv;
connection con1;
drop table t1, t2;
# Sending:
drop table t3;
# Let DROP TABLE statement sync in.
connection con2;
# Waiting for 'drop table t3' to get blocked...
# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
# lock.
connection default;
handler t3 read a next;
a
2
# Demonstrate that the drop will go through as soon as we close the
# HANDLER
handler t3 close;
connection con1;
# Reaping 'drop table t3'...
connection default;
commit;
#
# Cleanup for savepoint.inc
#
connection con1;
disconnect con1;
connection con2;
disconnect con2;
connection con3;
disconnect con3;
connection default;
CREATE TABLE t1 (f1 integer, f2 integer, primary key (f1), key (f2)) engine=innodb;
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
HANDLER t1 OPEN;

1
mysql-test/suite/handler/innodb.test

@ -15,6 +15,7 @@ let $engine_type= InnoDB;
--source init.inc
--source handler.inc
--source savepoint.inc
#
# LP#697610 ha_index_prev(uchar*): Assertion `inited==INDEX'

159
mysql-test/suite/handler/myisam.result

@ -1132,166 +1132,7 @@ connection default;
# Reaping 'select * from t2'
ERROR 42S02: Table 'test.t2' doesn't exist
handler t1 close;
#
# ROLLBACK TO SAVEPOINT releases transactional locks,
# but has no effect on open HANDLERs
#
create table t2 like t1;
create table t3 like t1;
begin;
# Have something before the savepoint
select * from t3;
a
savepoint sv;
handler t1 open;
handler t1 read a first;
a
1
handler t1 read a next;
a
2
select * from t2;
a
connection con1;
# Sending:
drop table t1;
connection con2;
# Sending:
drop table t2;
connection default;
# Let DROP TABLE statements sync in. We must use
# a separate connection for that, because otherwise SELECT
# will auto-close the HANDLERs, becaues there are pending
# exclusive locks against them.
connection con3;
# Waiting for 'drop table t1' to get blocked...
# Waiting for 'drop table t2' to get blocked...
# Demonstrate that t2 lock was released and t2 was dropped
# after ROLLBACK TO SAVEPOINT
connection default;
rollback to savepoint sv;
connection con2;
# Reaping 'drop table t2'...
# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
# lock.
connection default;
handler t1 read a next;
a
3
handler t1 read a next;
a
4
# Demonstrate that the drop will go through as soon as we close the
# HANDLER
handler t1 close;
connection con1;
# Reaping 'drop table t1'...
connection default;
commit;
drop table t3;
#
# A few special cases when using SAVEPOINT/ROLLBACK TO
# SAVEPOINT and HANDLER.
#
# Show that rollback to the savepoint taken in the beginning
# of the transaction doesn't release mdl lock on
# the HANDLER that was opened later.
#
create table t1 (a int, key using btree (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
begin;
savepoint sv;
handler t1 open;
handler t1 read a first;
a
1
handler t1 read a next;
a
2
select * from t2;
a
connection con1;
# Sending:
drop table t1;
connection con2;
# Sending:
drop table t2;
connection default;
# Let DROP TABLE statements sync in. We must use
# a separate connection for that, because otherwise SELECT
# will auto-close the HANDLERs, becaues there are pending
# exclusive locks against them.
connection con3;
# Waiting for 'drop table t1' to get blocked...
# Waiting for 'drop table t2' to get blocked...
# Demonstrate that t2 lock was released and t2 was dropped
# after ROLLBACK TO SAVEPOINT
connection default;
rollback to savepoint sv;
connection con2;
# Reaping 'drop table t2'...
# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
# lock.
connection default;
handler t1 read a next;
a
3
handler t1 read a next;
a
4
# Demonstrate that the drop will go through as soon as we close the
# HANDLER
handler t1 close;
connection con1;
# Reaping 'drop table t1'...
connection default;
commit;
#
# Show that rollback to the savepoint taken in the beginning
# of the transaction works properly (no valgrind warnins, etc),
# even though it's done after the HANDLER mdl lock that was there
# at the beginning is released and added again.
#
create table t1 (a int, key using btree (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
create table t3 like t1;
insert into t3 (a) select a from t1;
begin;
handler t1 open;
savepoint sv;
handler t1 read a first;
a
1
select * from t2;
a
handler t1 close;
handler t3 open;
handler t3 read a first;
a
1
rollback to savepoint sv;
connection con1;
drop table t1, t2;
# Sending:
drop table t3;
# Let DROP TABLE statement sync in.
connection con2;
# Waiting for 'drop table t3' to get blocked...
# Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
# lock.
connection default;
handler t3 read a next;
a
2
# Demonstrate that the drop will go through as soon as we close the
# HANDLER
handler t3 close;
connection con1;
# Reaping 'drop table t3'...
connection default;
commit;
#
# If we have to wait on an exclusive locks while having
# an open HANDLER, ER_LOCK_DEADLOCK is reported.

182
mysql-test/suite/handler/savepoint.inc

@ -0,0 +1,182 @@
--echo #
--echo # Testing savepoints with handlers that supports it
--echo #
connect(con1, localhost, root,,);
connect(con2, localhost, root,,);
connect(con3, localhost, root,,);
connection default;
--echo #
--echo # ROLLBACK TO SAVEPOINT releases transactional locks,
--echo # but has no effect on open HANDLERs
--echo #
create table t1 (a int, key a (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
create table t3 like t1;
begin;
--echo # Have something before the savepoint
select * from t3;
savepoint sv;
handler t1 open;
handler t1 read a first;
handler t1 read a next;
select * from t2;
connection con1;
--echo # Sending:
--send drop table t1
connection con2;
--echo # Sending:
--send drop table t2
connection default;
--echo # Let DROP TABLE statements sync in. We must use
--echo # a separate connection for that, because otherwise SELECT
--echo # will auto-close the HANDLERs, becaues there are pending
--echo # exclusive locks against them.
connection con3;
--echo # Waiting for 'drop table t1' to get blocked...
let $wait_condition=select count(*)=1 from information_schema.processlist
where state='Waiting for table metadata lock' and
info='drop table t1';
--source include/wait_condition.inc
--echo # Waiting for 'drop table t2' to get blocked...
let $wait_condition=select count(*)=1 from information_schema.processlist
where state='Waiting for table metadata lock' and
info='drop table t2';
--source include/wait_condition.inc
--echo # Demonstrate that t2 lock was released and t2 was dropped
--echo # after ROLLBACK TO SAVEPOINT
connection default;
rollback to savepoint sv;
connection con2;
--echo # Reaping 'drop table t2'...
--reap
--echo # Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
--echo # lock.
connection default;
handler t1 read a next;
handler t1 read a next;
--echo # Demonstrate that the drop will go through as soon as we close the
--echo # HANDLER
handler t1 close;
connection con1;
--echo # Reaping 'drop table t1'...
--reap
connection default;
commit;
drop table t3;
--echo #
--echo # A few special cases when using SAVEPOINT/ROLLBACK TO
--echo # SAVEPOINT and HANDLER.
--echo #
--echo # Show that rollback to the savepoint taken in the beginning
--echo # of the transaction doesn't release mdl lock on
--echo # the HANDLER that was opened later.
--echo #
create table t1 (a int, key using btree (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
begin;
savepoint sv;
handler t1 open;
handler t1 read a first;
handler t1 read a next;
select * from t2;
connection con1;
--echo # Sending:
--send drop table t1
connection con2;
--echo # Sending:
--send drop table t2
connection default;
--echo # Let DROP TABLE statements sync in. We must use
--echo # a separate connection for that, because otherwise SELECT
--echo # will auto-close the HANDLERs, becaues there are pending
--echo # exclusive locks against them.
connection con3;
--echo # Waiting for 'drop table t1' to get blocked...
let $wait_condition=select count(*)=1 from information_schema.processlist
where state='Waiting for table metadata lock' and
info='drop table t1';
--source include/wait_condition.inc
--echo # Waiting for 'drop table t2' to get blocked...
let $wait_condition=select count(*)=1 from information_schema.processlist
where state='Waiting for table metadata lock' and
info='drop table t2';
--source include/wait_condition.inc
--echo # Demonstrate that t2 lock was released and t2 was dropped
--echo # after ROLLBACK TO SAVEPOINT
connection default;
rollback to savepoint sv;
connection con2;
--echo # Reaping 'drop table t2'...
--reap
--echo # Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
--echo # lock.
connection default;
handler t1 read a next;
handler t1 read a next;
--echo # Demonstrate that the drop will go through as soon as we close the
--echo # HANDLER
handler t1 close;
connection con1;
--echo # Reaping 'drop table t1'...
--reap
connection default;
commit;
--echo #
--echo # Show that rollback to the savepoint taken in the beginning
--echo # of the transaction works properly (no valgrind warnins, etc),
--echo # even though it's done after the HANDLER mdl lock that was there
--echo # at the beginning is released and added again.
--echo #
create table t1 (a int, key using btree (a));
insert into t1 (a) values (1), (2), (3), (4), (5);
create table t2 like t1;
create table t3 like t1;
insert into t3 (a) select a from t1;
begin;
handler t1 open;
savepoint sv;
handler t1 read a first;
select * from t2;
handler t1 close;
handler t3 open;
handler t3 read a first;
rollback to savepoint sv;
connection con1;
drop table t1, t2;
--echo # Sending:
--send drop table t3
--echo # Let DROP TABLE statement sync in.
connection con2;
--echo # Waiting for 'drop table t3' to get blocked...
let $wait_condition=select count(*)=1 from information_schema.processlist
where state='Waiting for table metadata lock' and
info='drop table t3';
--source include/wait_condition.inc
--echo # Demonstrate that ROLLBACK TO SAVEPOINT didn't release the handler
--echo # lock.
connection default;
handler t3 read a next;
--echo # Demonstrate that the drop will go through as soon as we close the
--echo # HANDLER
handler t3 close;
connection con1;
--echo # Reaping 'drop table t3'...
--reap
connection default;
commit;
--echo #
--echo # Cleanup for savepoint.inc
--echo #
connection con1;
disconnect con1;
--source include/wait_until_disconnected.inc
connection con2;
disconnect con2;
--source include/wait_until_disconnected.inc
connection con3;
disconnect con3;
--source include/wait_until_disconnected.inc
connection default;

5
mysql-test/suite/maria/maria-connect.result

@ -8,6 +8,11 @@ CREATE TABLE t1 (a int primary key);
insert t1 values (1),(2),(3);
insert t1 values (4),(2),(5);
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
show warnings;
Level Code Message
Error 1062 Duplicate entry '2' for key 'PRIMARY'
Note 4173 Engine Aria does not support rollback. Changes where commited during rollback call
Warning 1196 Some non-transactional changed tables couldn't be rolled back
select * from t1;
a
1

1
mysql-test/suite/maria/maria-connect.test

@ -29,6 +29,7 @@ CREATE TABLE t1 (a int primary key);
insert t1 values (1),(2),(3);
--error ER_DUP_ENTRY
insert t1 values (4),(2),(5);
show warnings;
select * from t1;
--replace_result $start_pos <start_pos>
--replace_column 2 # 5 #

186
mysql-test/suite/maria/rollback.result

@ -0,0 +1,186 @@
call mtr.add_suppression("Table '.*' is marked as crashed and should be repaired");
call mtr.add_suppression("Checking table: .*");
create table t1 (a int primary key auto_increment, b int) engine=aria transactional= 1;
create table t2 (a int primary key auto_increment, b int) engine=aria transactional= 0;
create sequence s1 cache=2 engine=aria;
insert into t1 (b) values (1),(2),(3),(4);
insert into t2 (b) values (1),(2),(3),(4);
select NEXT VALUE for s1,seq from seq_1_to_4;
NEXT VALUE for s1 seq
1 1
2 2
3 3
4 4
begin;
insert into t1 (b) values (5),(6);
insert into t1 (b) values (7),(8);
insert into t2 (b) values (5),(6);
insert into t2 (b) values (7),(8);
commit;
begin;
insert into t1 (b) values (10),(11),(12);
update t1 set b=100 where a=2;
delete from t1 where a between 3 and 4;
insert into t2 (b) values (10),(11),(12);
update t2 set b=100 where a=2;
delete from t2 where a between 3 and 4;
select NEXT VALUE for s1,seq from seq_1_to_4;
NEXT VALUE for s1 seq
5 1
6 2
7 3
8 4
# Kill and restart
select * from t1 order by a;
a b
1 1
2 100
5 5
6 6
7 7
8 8
9 10
10 11
11 12
select * from t2 order by a;
a b
1 1
2 100
5 5
6 6
7 7
8 8
9 10
10 11
11 12
Warnings:
Error 145 Table './test/t2' is marked as crashed and should be repaired
Warning 1034 1 client is using or hasn't closed the table properly
Note 1034 Table is fixed
insert into t1 (b) values (100),(200);
insert into t2 (b) values (100),(200);
select * from t1 order by a;
a b
1 1
2 100
5 5
6 6
7 7
8 8
9 10
10 11
11 12
12 100
13 200
select * from t2 order by a;
a b
1 1
2 100
5 5
6 6
7 7
8 8
9 10
10 11
11 12
12 100
13 200
select NEXT VALUE for s1,seq from seq_1_to_4;
NEXT VALUE for s1 seq
9 1
10 2
11 3
12 4
Warnings:
Error 145 Table './test/s1' is marked as crashed and should be repaired
Warning 1034 1 client is using or hasn't closed the table properly
Note 1034 Table is fixed
drop table t1,t2;
drop sequence s1;
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Table \'.*\' is marked as crashed and should be repaired' COLLATE 'latin1_swedish_ci'))
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Checking table: .*' COLLATE 'latin1_swedish_ci'))
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t1 (a int primary key auto_increment, b int) engine=aria transactional= 1
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t2 (a int primary key auto_increment, b int) engine=aria transactional= 0
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create sequence s1 cache=2 engine=aria
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Intvar # # INSERT_ID=1
master-bin.000001 # Query # # use `test`; insert into t1 (b) values (1),(2),(3),(4)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Intvar # # INSERT_ID=1
master-bin.000001 # Query # # use `test`; insert into t2 (b) values (1),(2),(3),(4)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Annotate_rows # # select NEXT VALUE for s1,seq from seq_1_to_4
master-bin.000001 # Table_map # # table_id: # (test.s1)
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Intvar # # INSERT_ID=5
master-bin.000001 # Query # # use `test`; insert into t1 (b) values (5),(6)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Intvar # # INSERT_ID=7
master-bin.000001 # Query # # use `test`; insert into t1 (b) values (7),(8)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Intvar # # INSERT_ID=5
master-bin.000001 # Query # # use `test`; insert into t2 (b) values (5),(6)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Intvar # # INSERT_ID=7
master-bin.000001 # Query # # use `test`; insert into t2 (b) values (7),(8)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Intvar # # INSERT_ID=9
master-bin.000001 # Query # # use `test`; insert into t1 (b) values (10),(11),(12)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; update t1 set b=100 where a=2
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; delete from t1 where a between 3 and 4
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Intvar # # INSERT_ID=9
master-bin.000001 # Query # # use `test`; insert into t2 (b) values (10),(11),(12)
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; update t2 set b=100 where a=2
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test`; delete from t2 where a between 3 and 4
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Annotate_rows # # select NEXT VALUE for s1,seq from seq_1_to_4
master-bin.000001 # Table_map # # table_id: # (test.s1)
master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000002 # Gtid # # BEGIN GTID #-#-#
master-bin.000002 # Intvar # # INSERT_ID=12
master-bin.000002 # Query # # use `test`; insert into t1 (b) values (100),(200)
master-bin.000002 # Query # # COMMIT
master-bin.000002 # Gtid # # BEGIN GTID #-#-#
master-bin.000002 # Intvar # # INSERT_ID=12
master-bin.000002 # Query # # use `test`; insert into t2 (b) values (100),(200)
master-bin.000002 # Query # # COMMIT
master-bin.000002 # Gtid # # BEGIN GTID #-#-#
master-bin.000002 # Annotate_rows # # select NEXT VALUE for s1,seq from seq_1_to_4
master-bin.000002 # Table_map # # table_id: # (test.s1)
master-bin.000002 # Write_rows_v1 # # table_id: # flags: STMT_END_F
master-bin.000002 # Query # # COMMIT
master-bin.000002 # Gtid # # GTID #-#-#
master-bin.000002 # Query # # use `test`; DROP TABLE `t1`,`t2` /* generated by server */
master-bin.000002 # Gtid # # GTID #-#-#
master-bin.000002 # Query # # use `test`; DROP SEQUENCE `s1` /* generated by server */

51
mysql-test/suite/maria/rollback.test

@ -0,0 +1,51 @@
--source include/have_binlog_format_mixed_or_statement.inc
--source include/have_sequence.inc
# no-protocol doesn't print warnings about repaired tables
--source include/no_protocol.inc
call mtr.add_suppression("Table '.*' is marked as crashed and should be repaired");
call mtr.add_suppression("Checking table: .*");
#
# Testing rollback after crash
#
create table t1 (a int primary key auto_increment, b int) engine=aria transactional= 1;
create table t2 (a int primary key auto_increment, b int) engine=aria transactional= 0;
create sequence s1 cache=2 engine=aria;
insert into t1 (b) values (1),(2),(3),(4);
insert into t2 (b) values (1),(2),(3),(4);
select NEXT VALUE for s1,seq from seq_1_to_4;
begin;
insert into t1 (b) values (5),(6);
insert into t1 (b) values (7),(8);
insert into t2 (b) values (5),(6);
insert into t2 (b) values (7),(8);
commit;
begin;
insert into t1 (b) values (10),(11),(12);
update t1 set b=100 where a=2;
delete from t1 where a between 3 and 4;
insert into t2 (b) values (10),(11),(12);
update t2 set b=100 where a=2;
delete from t2 where a between 3 and 4;
select NEXT VALUE for s1,seq from seq_1_to_4;
--source include/kill_and_restart_mysqld.inc
select * from t1 order by a;
select * from t2 order by a;
insert into t1 (b) values (100),(200);
insert into t2 (b) values (100),(200);
select * from t1 order by a;
select * from t2 order by a;
select NEXT VALUE for s1,seq from seq_1_to_4;
drop table t1,t2;
drop sequence s1;
source include/show_binlog_events.inc;
--let $binlog_file=master-bin.000002
source include/show_binlog_events.inc;

19
mysql-test/suite/maria/transaction.result

@ -0,0 +1,19 @@
connect con1, localhost, root,,;
connection default;
CREATE TABLE t1 (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c1))
ENGINE = aria;
START TRANSACTION;
INSERT INTO t1 (c1) VALUES (2);
INSERT INTO t1 (c1) VALUES (4);
connection con1;
START TRANSACTION;
select * from t1;
c1
2
4
select * from t1 where c1=2;
c1
2
disconnect con1;
connection default;
drop table t1;

26
mysql-test/suite/maria/transaction.test

@ -0,0 +1,26 @@
#
# Test that checks transactions and MVCC
#
#
# This is a taken from parts.partition_auto_increment_maria. It originally
# crashde because con1 could read the first record from t1, which confused
# the optimizer.
#
connect(con1, localhost, root,,);
connection default;
CREATE TABLE t1 (c1 INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (c1))
ENGINE = aria;
START TRANSACTION;
INSERT INTO t1 (c1) VALUES (2);
INSERT INTO t1 (c1) VALUES (4);
connection con1;
START TRANSACTION;
# When Aria proparly supports MVCC, the following two queries will not see
# any rows
select * from t1;
select * from t1 where c1=2;
disconnect con1;
connection default;
drop table t1;

956
mysql-test/suite/perfschema/r/event_aggregate.result
File diff suppressed because it is too large
View File

652
mysql-test/suite/perfschema/r/event_aggregate_no_a.result
File diff suppressed because it is too large
View File

556
mysql-test/suite/perfschema/r/event_aggregate_no_a_no_h.result
File diff suppressed because it is too large
View File

332
mysql-test/suite/perfschema/r/event_aggregate_no_a_no_u.result
File diff suppressed because it is too large
View File

236
mysql-test/suite/perfschema/r/event_aggregate_no_a_no_u_no_h.result

@ -188,14 +188,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 4
stage/sql/closing tables 13
stage/sql/closing tables 11
stage/sql/init 3
stage/sql/Opening tables 7
stage/sql/starting 6
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 4
stage/sql/closing tables 13
stage/sql/closing tables 11
stage/sql/init 3
stage/sql/Opening tables 7
stage/sql/starting 6
@ -225,10 +225,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 1
transaction 2
execute dump_transactions_history;
event_name count(event_name)
transaction 1
transaction 2
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -272,14 +272,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 4
stage/sql/closing tables 13
stage/sql/closing tables 11
stage/sql/init 3
stage/sql/Opening tables 7
stage/sql/starting 6
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 4
stage/sql/closing tables 13
stage/sql/closing tables 11
stage/sql/init 3
stage/sql/Opening tables 7
stage/sql/starting 6
@ -309,10 +309,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 1
transaction 2
execute dump_transactions_history;
event_name count(event_name)
transaction 1
transaction 2
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -368,14 +368,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 8
stage/sql/closing tables 24
stage/sql/closing tables 21
stage/sql/init 6
stage/sql/Opening tables 13
stage/sql/starting 12
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 8
stage/sql/closing tables 24
stage/sql/closing tables 21
stage/sql/init 6
stage/sql/Opening tables 13
stage/sql/starting 12
@ -405,10 +405,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 2
transaction 4
execute dump_transactions_history;
event_name count(event_name)
transaction 2
transaction 4
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -453,14 +453,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 8
stage/sql/closing tables 24
stage/sql/closing tables 21
stage/sql/init 6
stage/sql/Opening tables 13
stage/sql/starting 12
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 8
stage/sql/closing tables 24
stage/sql/closing tables 21
stage/sql/init 6
stage/sql/Opening tables 13
stage/sql/starting 12
@ -490,10 +490,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 2
transaction 4
execute dump_transactions_history;
event_name count(event_name)
transaction 2
transaction 4
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -550,14 +550,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 12
stage/sql/closing tables 35
stage/sql/closing tables 31
stage/sql/init 9
stage/sql/Opening tables 19
stage/sql/starting 18
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 12
stage/sql/closing tables 35
stage/sql/closing tables 31
stage/sql/init 9
stage/sql/Opening tables 19
stage/sql/starting 18
@ -587,10 +587,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 3
transaction 6
execute dump_transactions_history;
event_name count(event_name)
transaction 3
transaction 6
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -636,14 +636,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 12
stage/sql/closing tables 35
stage/sql/closing tables 31
stage/sql/init 9
stage/sql/Opening tables 19
stage/sql/starting 18
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 12
stage/sql/closing tables 35
stage/sql/closing tables 31
stage/sql/init 9
stage/sql/Opening tables 19
stage/sql/starting 18
@ -673,10 +673,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 3
transaction 6
execute dump_transactions_history;
event_name count(event_name)
transaction 3
transaction 6
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -734,14 +734,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 24
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 24
@ -771,10 +771,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -819,14 +819,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 25
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 25
@ -857,10 +857,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -904,14 +904,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 26
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 26
@ -942,10 +942,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -988,14 +988,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 27
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 27
@ -1026,10 +1026,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -1071,14 +1071,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -1109,10 +1109,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -1155,14 +1155,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -1193,10 +1193,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -1238,14 +1238,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -1276,10 +1276,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -1321,14 +1321,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -1359,10 +1359,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -1404,14 +1404,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -1442,10 +1442,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -1487,14 +1487,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -1525,10 +1525,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -1570,14 +1570,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -1608,10 +1608,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -1653,14 +1653,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -1691,10 +1691,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -1736,14 +1736,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -1774,10 +1774,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -1819,14 +1819,14 @@ host event_name count_star
execute dump_stages_global;
event_name count_star
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -1857,10 +1857,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -1909,7 +1909,7 @@ stage/sql/starting 0
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -1940,10 +1940,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -1992,7 +1992,7 @@ stage/sql/starting 0
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -2023,10 +2023,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -2075,7 +2075,7 @@ stage/sql/starting 0
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -2106,10 +2106,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -2158,7 +2158,7 @@ stage/sql/starting 0
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -2189,10 +2189,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -2241,7 +2241,7 @@ stage/sql/starting 0
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -2272,10 +2272,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -2324,7 +2324,7 @@ stage/sql/starting 0
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -2355,10 +2355,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -2407,7 +2407,7 @@ stage/sql/starting 0
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -2438,10 +2438,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -2490,7 +2490,7 @@ stage/sql/starting 0
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -2521,10 +2521,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -2573,7 +2573,7 @@ stage/sql/starting 0
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -2604,10 +2604,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -2656,7 +2656,7 @@ stage/sql/starting 0
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -2687,10 +2687,10 @@ execute dump_transactions_host;
host event_name count_star
execute dump_transactions_global;
event_name count_star
transaction 4
transaction 8
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -2739,7 +2739,7 @@ stage/sql/starting 0
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -2773,7 +2773,7 @@ event_name count_star
transaction 0
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -2822,7 +2822,7 @@ stage/sql/starting 0
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -2856,7 +2856,7 @@ event_name count_star
transaction 0
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -2905,7 +2905,7 @@ stage/sql/starting 0
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -2939,7 +2939,7 @@ event_name count_star
transaction 0
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;
@ -2988,7 +2988,7 @@ stage/sql/starting 0
execute dump_stages_history;
event_name count(event_name)
stage/sql/checking permissions 16
stage/sql/closing tables 46
stage/sql/closing tables 41
stage/sql/init 12
stage/sql/Opening tables 25
stage/sql/starting 28
@ -3022,7 +3022,7 @@ event_name count_star
transaction 0
execute dump_transactions_history;
event_name count(event_name)
transaction 4
transaction 8
execute dump_accounts;
USER HOST CURRENT_CONNECTIONS TOTAL_CONNECTIONS
execute dump_users;

860
mysql-test/suite/perfschema/r/event_aggregate_no_h.result
File diff suppressed because it is too large
View File

636
mysql-test/suite/perfschema/r/event_aggregate_no_u.result
File diff suppressed because it is too large
View File

540
mysql-test/suite/perfschema/r/event_aggregate_no_u_no_h.result
File diff suppressed because it is too large
View File

208
mysql-test/suite/perfschema/r/transaction_nested_events.result

@ -327,7 +327,7 @@ FROM performance_schema.events_transactions_current
WHERE ((THREAD_ID = @con1_thread_id) OR (@all_threads = 1))
ORDER BY thread_id, event_id;
THREAD_ID R_EVENT_ID R_END_EVENT_ID EVENT_NAME STATE ACCESS_MODE ISOLATION_LEVEL AUTO R_NESTING_EVENT_ID NESTING_EVENT_TYPE
thread_id 3 10 transaction COMMITTED READ WRITE REPEATABLE READ NO 2 STATEMENT
thread_id 10 12 transaction COMMITTED READ WRITE REPEATABLE READ NO 9 STATEMENT
#
# EVENTS_TRANSACTIONS_HISTORY_LONG
#
@ -345,7 +345,9 @@ FROM performance_schema.events_transactions_history_long
WHERE ((THREAD_ID = @con1_thread_id) OR (@all_threads = 1))
ORDER BY thread_id, event_id;
THREAD_ID R_EVENT_ID R_END_EVENT_ID EVENT_NAME STATE ACCESS_MODE ISOLATION_LEVEL AUTO R_NESTING_EVENT_ID NESTING_EVENT_TYPE
thread_id 3 10 transaction COMMITTED READ WRITE REPEATABLE READ NO 2 STATEMENT
thread_id 2 2 transaction COMMITTED READ WRITE REPEATABLE READ YES 1 STATEMENT
thread_id 10 10 transaction COMMITTED READ WRITE REPEATABLE READ NO 9 STATEMENT
thread_id 10 12 transaction COMMITTED READ WRITE REPEATABLE READ NO 9 STATEMENT
#
# EVENTS_STATEMENTS_HISTORY_LONG
#
@ -362,15 +364,15 @@ FROM performance_schema.events_statements_history_long
WHERE ((THREAD_ID = @con1_thread_id) OR (@all_threads = 1))
ORDER BY thread_id, event_id;
THREAD_ID R_EVENT_ID R_END_EVENT_ID EVENT_NAME OBJECT_NAME R_NESTING_EVENT_ID NESTING_EVENT_TYPE LEVEL SQL_TEXT
thread_id 1 1 statement/sql/create_procedure NULL NULL NULL 0 CREATE PROCEDURE tp_update() UPDATE t1 SET s1 = s1 + 1
thread_id 2 3 statement/sql/begin NULL NULL NULL 0 START TRANSACTION
thread_id 4 4 statement/sql/insert NULL 3 TRANSACTION 0 INSERT INTO t1 VALUES (310, "INSERT 310")
thread_id 5 5 statement/sql/insert NULL 3 TRANSACTION 0 INSERT INTO t1 VALUES (311, "INSERT 311")
thread_id 6 6 statement/sql/insert NULL 3 TRANSACTION 0 INSERT INTO t1 VALUES (312, "INSERT 312")
thread_id 7 7 statement/sql/insert NULL 3 TRANSACTION 0 INSERT INTO t1 VALUES (313, "INSERT 313")
thread_id 8 9 statement/sql/call_procedure NULL 3 TRANSACTION 0 CALL tp_update()
thread_id 9 9 statement/sp/stmt tp_update 8 STATEMENT 1 UPDATE t1 SET s1 = s1 + 1
thread_id 10 10 statement/sql/commit NULL 3 TRANSACTION 0 COMMIT
thread_id 1 2 statement/sql/create_procedure NULL NULL NULL 0 CREATE PROCEDURE tp_update() UPDATE t1 SET s1 = s1 + 1
thread_id 3 4 statement/sql/begin NULL NULL NULL 0 START TRANSACTION
thread_id 5 5 statement/sql/insert NULL 4 TRANSACTION 0 INSERT INTO t1 VALUES (310, "INSERT 310")
thread_id 6 6 statement/sql/insert NULL 4 TRANSACTION 0 INSERT INTO t1 VALUES (311, "INSERT 311")
thread_id 7 7 statement/sql/insert NULL 4 TRANSACTION 0 INSERT INTO t1 VALUES (312, "INSERT 312")
thread_id 8 8 statement/sql/insert NULL 4 TRANSACTION 0 INSERT INTO t1 VALUES (313, "INSERT 313")
thread_id 9 11 statement/sql/call_procedure NULL 4 TRANSACTION 0 CALL tp_update()
thread_id 11 11 statement/sp/stmt tp_update 9 STATEMENT 1 UPDATE t1 SET s1 = s1 + 1
thread_id 12 12 statement/sql/commit NULL NULL NULL 0 COMMIT
#
### Combined statement and transaction event history ordered by event id
#
@ -397,16 +399,18 @@ FROM performance_schema.events_statements_history_long s
WHERE ((s.thread_id = @con1_thread_id) OR (@all_threads = 1))
ORDER BY thread_id, r_event_id;
THREAD_ID R_EVENT_ID R_END_EVENT_ID EVENT_NAME R_NESTING_EVENT_ID NESTING_EVENT_TYPE SQL_TXT
thread_id 1 1 statement/sql/create_proc NULL NULL CREATE PROCEDURE tp_update() UPDATE t1 SET s1 = s1 + 1
thread_id 2 3 statement/sql/begin NULL NULL START TRANSACTION
thread_id 3 10 transaction 2 STATEMENT <transaction started>
thread_id 4 4 statement/sql/insert 3 TRANSACTION INSERT INTO t1 VALUES (310, "INSERT 310")
thread_id 5 5 statement/sql/insert 3 TRANSACTION INSERT INTO t1 VALUES (311, "INSERT 311")
thread_id 6 6 statement/sql/insert 3 TRANSACTION INSERT INTO t1 VALUES (312, "INSERT 312")
thread_id 7 7 statement/sql/insert 3 TRANSACTION INSERT INTO t1 VALUES (313, "INSERT 313")
thread_id 8 9 statement/sql/call_proced 3 TRANSACTION CALL tp_update()
thread_id 9 9 statement/sp/stmt 8 STATEMENT UPDATE t1 SET s1 = s1 + 1
thread_id 10 10 statement/sql/commit 3 TRANSACTION COMMIT
thread_id 1 2 statement/sql/create_proc NULL NULL CREATE PROCEDURE tp_update() UPDATE t1 SET s1 = s1 + 1
thread_id 2 2 transaction 1 STATEMENT <transaction started>
thread_id 3 4 statement/sql/begin NULL NULL START TRANSACTION
thread_id 5 5 statement/sql/insert 4 TRANSACTION INSERT INTO t1 VALUES (310, "INSERT 310")
thread_id 6 6 statement/sql/insert 4 TRANSACTION INSERT INTO t1 VALUES (311, "INSERT 311")
thread_id 7 7 statement/sql/insert 4 TRANSACTION INSERT INTO t1 VALUES (312, "INSERT 312")
thread_id 8 8 statement/sql/insert 4 TRANSACTION INSERT INTO t1 VALUES (313, "INSERT 313")
thread_id 9 11 statement/sql/call_proced 4 TRANSACTION CALL tp_update()
thread_id 10 10 transaction 9 STATEMENT <transaction started>
thread_id 10 12 transaction 9 STATEMENT <transaction started>
thread_id 11 11 statement/sp/stmt 9 STATEMENT UPDATE t1 SET s1 = s1 + 1
thread_id 12 12 statement/sql/commit NULL NULL COMMIT
#
### Clear statement and transaction history
# CALL test.clear_history();
@ -464,7 +468,7 @@ FROM performance_schema.events_transactions_current
WHERE ((THREAD_ID = @con1_thread_id) OR (@all_threads = 1))
ORDER BY thread_id, event_id;
THREAD_ID R_EVENT_ID R_END_EVENT_ID EVENT_NAME STATE ACCESS_MODE ISOLATION_LEVEL AUTO R_NESTING_EVENT_ID NESTING_EVENT_TYPE
thread_id 4 9 transaction COMMITTED READ WRITE REPEATABLE READ NO 3 STATEMENT
thread_id 6 11 transaction COMMITTED READ WRITE REPEATABLE READ NO 5 STATEMENT
#
# EVENTS_TRANSACTIONS_HISTORY_LONG
#
@ -482,7 +486,9 @@ FROM performance_schema.events_transactions_history_long
WHERE ((THREAD_ID = @con1_thread_id) OR (@all_threads = 1))
ORDER BY thread_id, event_id;
THREAD_ID R_EVENT_ID R_END_EVENT_ID EVENT_NAME STATE ACCESS_MODE ISOLATION_LEVEL AUTO R_NESTING_EVENT_ID NESTING_EVENT_TYPE
thread_id 4 9 transaction COMMITTED READ WRITE REPEATABLE READ NO 3 STATEMENT
thread_id 2 2 transaction COMMITTED READ WRITE REPEATABLE READ YES 1 STATEMENT
thread_id 4 4 transaction COMMITTED READ WRITE REPEATABLE READ YES 3 STATEMENT
thread_id 6 11 transaction COMMITTED READ WRITE REPEATABLE READ NO 5 STATEMENT
#
# EVENTS_STATEMENTS_HISTORY_LONG
#
@ -499,14 +505,14 @@ FROM performance_schema.events_statements_history_long
WHERE ((THREAD_ID = @con1_thread_id) OR (@all_threads = 1))
ORDER BY thread_id, event_id;
THREAD_ID R_EVENT_ID R_END_EVENT_ID EVENT_NAME OBJECT_NAME R_NESTING_EVENT_ID NESTING_EVENT_TYPE LEVEL SQL_TEXT
thread_id 1 1 statement/sql/create_procedure NULL NULL NULL 0 CREATE PROCEDURE tp_start() START TRANSACTION
thread_id 2 4 statement/sql/call_procedure NULL NULL NULL 0 CALL tp_start()
thread_id 3 4 statement/sp/stmt tp_start 2 STATEMENT 1 START TRANSACTION
thread_id 5 5 statement/sql/insert NULL 4 TRANSACTION 0 INSERT INTO t1 VALUES (320, "INSERT 320"),(321, "INSERT 321")
thread_id 6 6 statement/sql/insert NULL 4 TRANSACTION 0 INSERT INTO t1 VALUES (322, "INSERT 322"),(323, "INSERT 323")
thread_id 7 7 statement/sql/update NULL 4 TRANSACTION 0 UPDATE t1 SET s1 = s1 + 1 WHERE s1 > 320
thread_id 8 8 statement/sql/select NULL 4 TRANSACTION 0 SELECT * FROM t1 ORDER BY s1
thread_id 9 9 statement/sql/commit NULL 4 TRANSACTION 0 COMMIT
thread_id 1 2 statement/sql/create_procedure NULL NULL NULL 0 CREATE PROCEDURE tp_start() START TRANSACTION
thread_id 3 6 statement/sql/call_procedure NULL NULL NULL 0 CALL tp_start()
thread_id 5 6 statement/sp/stmt tp_start 3 STATEMENT 1 START TRANSACTION
thread_id 7 7 statement/sql/insert NULL 6 TRANSACTION 0 INSERT INTO t1 VALUES (320, "INSERT 320"),(321, "INSERT 321")
thread_id 8 8 statement/sql/insert NULL 6 TRANSACTION 0 INSERT INTO t1 VALUES (322, "INSERT 322"),(323, "INSERT 323")
thread_id 9 9 statement/sql/update NULL 6 TRANSACTION 0 UPDATE t1 SET s1 = s1 + 1 WHERE s1 > 320
thread_id 10 10 statement/sql/select NULL 6 TRANSACTION 0 SELECT * FROM t1 ORDER BY s1
thread_id 11 11 statement/sql/commit NULL 6 TRANSACTION 0 COMMIT
#
### Combined statement and transaction event history ordered by event id
#
@ -533,15 +539,17 @@ FROM performance_schema.events_statements_history_long s
WHERE ((s.thread_id = @con1_thread_id) OR (@all_threads = 1))
ORDER BY thread_id, r_event_id;
THREAD_ID R_EVENT_ID R_END_EVENT_ID EVENT_NAME R_NESTING_EVENT_ID NESTING_EVENT_TYPE SQL_TXT
thread_id 1 1 statement/sql/create_proc NULL NULL CREATE PROCEDURE tp_start() START TRANSACTION
thread_id 2 4 statement/sql/call_proced NULL NULL CALL tp_start()
thread_id 3 4 statement/sp/stmt 2 STATEMENT START TRANSACTION
thread_id 4 9 transaction 3 STATEMENT <transaction started>
thread_id 5 5 statement/sql/insert 4 TRANSACTION INSERT INTO t1 VALUES (320, "INSERT 320"),(321, "INSERT 321")
thread_id 6 6 statement/sql/insert 4 TRANSACTION INSERT INTO t1 VALUES (322, "INSERT 322"),(323, "INSERT 323")
thread_id 7 7 statement/sql/update 4 TRANSACTION UPDATE t1 SET s1 = s1 + 1 WHERE s1 > 320
thread_id 8 8 statement/sql/select 4 TRANSACTION SELECT * FROM t1 ORDER BY s1
thread_id 9 9 statement/sql/commit 4 TRANSACTION COMMIT
thread_id 1 2 statement/sql/create_proc NULL NULL CREATE PROCEDURE tp_start() START TRANSACTION
thread_id 2 2 transaction 1 STATEMENT <transaction started>
thread_id 3 6 statement/sql/call_proced NULL NULL CALL tp_start()
thread_id 4 4 transaction 3 STATEMENT <transaction started>
thread_id 5 6 statement/sp/stmt 3 STATEMENT START TRANSACTION
thread_id 6 11 transaction 5 STATEMENT <transaction started>
thread_id 7 7 statement/sql/insert 6 TRANSACTION INSERT INTO t1 VALUES (320, "INSERT 320"),(321, "INSERT 321")
thread_id 8 8 statement/sql/insert 6 TRANSACTION INSERT INTO t1 VALUES (322, "INSERT 322"),(323, "INSERT 323")
thread_id 9 9 statement/sql/update 6 TRANSACTION UPDATE t1 SET s1 = s1 + 1 WHERE s1 > 320
thread_id 10 10 statement/sql/select 6 TRANSACTION SELECT * FROM t1 ORDER BY s1
thread_id 11 11 statement/sql/commit 6 TRANSACTION COMMIT
#
### Clear statement and transaction history
# CALL test.clear_history();
@ -609,7 +617,7 @@ FROM performance_schema.events_transactions_current
WHERE ((THREAD_ID = @con1_thread_id) OR (@all_threads = 1))
ORDER BY thread_id, event_id;
THREAD_ID R_EVENT_ID R_END_EVENT_ID EVENT_NAME STATE ACCESS_MODE ISOLATION_LEVEL AUTO R_NESTING_EVENT_ID NESTING_EVENT_TYPE
thread_id 18 18 transaction COMMITTED READ WRITE REPEATABLE READ YES 17 STATEMENT
thread_id 22 22 transaction COMMITTED READ WRITE REPEATABLE READ YES 21 STATEMENT
#
# EVENTS_TRANSACTIONS_HISTORY_LONG
#
@ -627,10 +635,14 @@ FROM performance_schema.events_transactions_history_long
WHERE ((THREAD_ID = @con1_thread_id) OR (@all_threads = 1))
ORDER BY thread_id, event_id;
THREAD_ID R_EVENT_ID R_END_EVENT_ID EVENT_NAME STATE ACCESS_MODE ISOLATION_LEVEL AUTO R_NESTING_EVENT_ID NESTING_EVENT_TYPE
thread_id 4 9 transaction COMMITTED READ WRITE REPEATABLE READ NO 3 STATEMENT
thread_id 11 11 transaction COMMITTED READ WRITE REPEATABLE READ YES 10 STATEMENT
thread_id 13 16 transaction ROLLED BACK READ WRITE REPEATABLE READ NO 12 STATEMENT
thread_id 18 18 transaction COMMITTED READ WRITE REPEATABLE READ YES 17 STATEMENT
thread_id 2 2 transaction COMMITTED READ WRITE REPEATABLE READ YES 1 STATEMENT
thread_id 4 4 transaction COMMITTED READ WRITE REPEATABLE READ YES 3 STATEMENT
thread_id 11 11 transaction COMMITTED READ WRITE REPEATABLE READ NO 10 STATEMENT
thread_id 11 12 transaction COMMITTED READ WRITE REPEATABLE READ NO 10 STATEMENT
thread_id 14 14 transaction COMMITTED READ WRITE REPEATABLE READ YES 13 STATEMENT
thread_id 19 19 transaction COMMITTED READ WRITE REPEATABLE READ NO 18 STATEMENT
thread_id 19 20 transaction ROLLED BACK READ WRITE REPEATABLE READ NO 18 STATEMENT
thread_id 22 22 transaction COMMITTED READ WRITE REPEATABLE READ YES 21 STATEMENT
#
# EVENTS_STATEMENTS_HISTORY_LONG
#
@ -647,20 +659,20 @@ FROM performance_schema.events_statements_history_long
WHERE ((THREAD_ID = @con1_thread_id) OR (@all_threads = 1))
ORDER BY thread_id, event_id;
THREAD_ID R_EVENT_ID R_END_EVENT_ID EVENT_NAME OBJECT_NAME R_NESTING_EVENT_ID NESTING_EVENT_TYPE LEVEL SQL_TEXT
thread_id 1 1 statement/sql/create_procedure NULL NULL NULL 0 CREATE PROCEDURE tp_rollback() ROLLBACK
thread_id 2 2 statement/sql/create_procedure NULL NULL NULL 0 CREATE PROCEDURE tp_commit() COMMIT
thread_id 3 4 statement/sql/begin NULL NULL NULL 0 START TRANSACTION
thread_id 5 5 statement/sql/insert NULL 4 TRANSACTION 0 INSERT INTO t1 VALUES (330, "INSERT 330"),(331, "INSERT 331")
thread_id 6 6 statement/sql/insert NULL 4 TRANSACTION 0 INSERT INTO t1 VALUES (332, "INSERT 332"),(333, "INSERT 333")
thread_id 7 7 statement/sql/delete NULL 4 TRANSACTION 0 DELETE FROM t1 WHERE s1 > 331
thread_id 8 9 statement/sql/call_procedure NULL 4 TRANSACTION 0 CALL tp_commit()
thread_id 9 9 statement/sp/stmt tp_commit 8 STATEMENT 1 COMMIT
thread_id 10 11 statement/sql/select NULL NULL NULL 0 SELECT * FROM t1 ORDER BY s1
thread_id 12 13 statement/sql/begin NULL NULL NULL 0 START TRANSACTION
thread_id 14 14 statement/sql/update NULL 13 TRANSACTION 0 UPDATE t1 SET s1 = s1*2 WHERE s1 > 331
thread_id 15 16 statement/sql/call_procedure NULL 13 TRANSACTION 0 CALL tp_rollback()
thread_id 16 16 statement/sp/stmt tp_rollback 15 STATEMENT 1 ROLLBACK
thread_id 17 18 statement/sql/select NULL NULL NULL 0 SELECT * FROM t1 ORDER BY s1
thread_id 1 2 statement/sql/create_procedure NULL NULL NULL 0 CREATE PROCEDURE tp_rollback() ROLLBACK
thread_id 3 4 statement/sql/create_procedure NULL NULL NULL 0 CREATE PROCEDURE tp_commit() COMMIT
thread_id 5 6 statement/sql/begin NULL NULL NULL 0 START TRANSACTION
thread_id 7 7 statement/sql/insert NULL 6 TRANSACTION 0 INSERT INTO t1 VALUES (330, "INSERT 330"),(331, "INSERT 331")
thread_id 8 8 statement/sql/insert NULL 6 TRANSACTION 0 INSERT INTO t1 VALUES (332, "INSERT 332"),(333, "INSERT 333")
thread_id 9 9 statement/sql/delete NULL 6 TRANSACTION 0 DELETE FROM t1 WHERE s1 > 331
thread_id 10 12 statement/sql/call_procedure NULL 6 TRANSACTION 0 CALL tp_commit()
thread_id 12 12 statement/sp/stmt tp_commit 10 STATEMENT 1 COMMIT
thread_id 13 14 statement/sql/select NULL NULL NULL 0 SELECT * FROM t1 ORDER BY s1
thread_id 15 16 statement/sql/begin NULL NULL NULL 0 START TRANSACTION
thread_id 17 17 statement/sql/update NULL 16 TRANSACTION 0 UPDATE t1 SET s1 = s1*2 WHERE s1 > 331
thread_id 18 20 statement/sql/call_procedure NULL 16 TRANSACTION 0 CALL tp_rollback()
thread_id 20 20 statement/sp/stmt tp_rollback 18 STATEMENT 1 ROLLBACK
thread_id 21 22 statement/sql/select NULL NULL NULL 0 SELECT * FROM t1 ORDER BY s1
#
### Combined statement and transaction event history ordered by event id
#
@ -687,24 +699,28 @@ FROM performance_schema.events_statements_history_long s
WHERE ((s.thread_id = @con1_thread_id) OR (@all_threads = 1))
ORDER BY thread_id, r_event_id;
THREAD_ID R_EVENT_ID R_END_EVENT_ID EVENT_NAME R_NESTING_EVENT_ID NESTING_EVENT_TYPE SQL_TXT
thread_id 1 1 statement/sql/create_proc NULL NULL CREATE PROCEDURE tp_rollback() ROLLBACK
thread_id 2 2 statement/sql/create_proc NULL NULL CREATE PROCEDURE tp_commit() COMMIT
thread_id 3 4 statement/sql/begin NULL NULL START TRANSACTION
thread_id 4 9 transaction 3 STATEMENT <transaction started>
thread_id 5 5 statement/sql/insert 4 TRANSACTION INSERT INTO t1 VALUES (330, "INSERT 330"),(331, "INSERT 331")
thread_id 6 6 statement/sql/insert 4 TRANSACTION INSERT INTO t1 VALUES (332, "INSERT 332"),(333, "INSERT 333")
thread_id 7 7 statement/sql/delete 4 TRANSACTION DELETE FROM t1 WHERE s1 > 331
thread_id 8 9 statement/sql/call_proced 4 TRANSACTION CALL tp_commit()
thread_id 9 9 statement/sp/stmt 8 STATEMENT COMMIT
thread_id 10 11 statement/sql/select NULL NULL SELECT * FROM t1 ORDER BY s1
thread_id 1 2 statement/sql/create_proc NULL NULL CREATE PROCEDURE tp_rollback() ROLLBACK
thread_id 2 2 transaction 1 STATEMENT <transaction started>
thread_id 3 4 statement/sql/create_proc NULL NULL CREATE PROCEDURE tp_commit() COMMIT
thread_id 4 4 transaction 3 STATEMENT <transaction started>
thread_id 5 6 statement/sql/begin NULL NULL START TRANSACTION
thread_id 7 7 statement/sql/insert 6 TRANSACTION INSERT INTO t1 VALUES (330, "INSERT 330"),(331, "INSERT 331")
thread_id 8 8 statement/sql/insert 6 TRANSACTION INSERT INTO t1 VALUES (332, "INSERT 332"),(333, "INSERT 333")
thread_id 9 9 statement/sql/delete 6 TRANSACTION DELETE FROM t1 WHERE s1 > 331
thread_id 10 12 statement/sql/call_proced 6 TRANSACTION CALL tp_commit()
thread_id 11 11 transaction 10 STATEMENT <transaction started>
thread_id 12 13 statement/sql/begin NULL NULL START TRANSACTION
thread_id 13 16 transaction 12 STATEMENT <transaction started>
thread_id 14 14 statement/sql/update 13 TRANSACTION UPDATE t1 SET s1 = s1*2 WHERE s1 > 331
thread_id 15 16 statement/sql/call_proced 13 TRANSACTION CALL tp_rollback()
thread_id 16 16 statement/sp/stmt 15 STATEMENT ROLLBACK
thread_id 17 18 statement/sql/select NULL NULL SELECT * FROM t1 ORDER BY s1
thread_id 18 18 transaction 17 STATEMENT <transaction started>
thread_id 11 12 transaction 10 STATEMENT <transaction started>
thread_id 12 12 statement/sp/stmt 10 STATEMENT COMMIT
thread_id 13 14 statement/sql/select NULL NULL SELECT * FROM t1 ORDER BY s1
thread_id 14 14 transaction 13 STATEMENT <transaction started>
thread_id 15 16 statement/sql/begin NULL NULL START TRANSACTION
thread_id 17 17 statement/sql/update 16 TRANSACTION UPDATE t1 SET s1 = s1*2 WHERE s1 > 331
thread_id 18 20 statement/sql/call_proced 16 TRANSACTION CALL tp_rollback()
thread_id 19 19 transaction 18 STATEMENT <transaction started>
thread_id 19 20 transaction 18 STATEMENT <transaction started>
thread_id 20 20 statement/sp/stmt 18 STATEMENT ROLLBACK
thread_id 21 22 statement/sql/select NULL NULL SELECT * FROM t1 ORDER BY s1
thread_id 22 22 transaction 21 STATEMENT <transaction started>
#
### Clear statement and transaction history
# CALL test.clear_history();
@ -783,7 +799,7 @@ FROM performance_schema.events_transactions_current
WHERE ((THREAD_ID = @con1_thread_id) OR (@all_threads = 1))
ORDER BY thread_id, event_id;
THREAD_ID R_EVENT_ID R_END_EVENT_ID EVENT_NAME STATE ACCESS_MODE ISOLATION_LEVEL AUTO R_NESTING_EVENT_ID NESTING_EVENT_TYPE
thread_id 13 13 transaction COMMITTED READ WRITE REPEATABLE READ YES 12 STATEMENT
thread_id 14 14 transaction COMMITTED READ WRITE REPEATABLE READ YES 13 STATEMENT
#
# EVENTS_TRANSACTIONS_HISTORY_LONG
#
@ -801,8 +817,9 @@ FROM performance_schema.events_transactions_history_long
WHERE ((THREAD_ID = @con1_thread_id) OR (@all_threads = 1))
ORDER BY thread_id, event_id;
THREAD_ID R_EVENT_ID R_END_EVENT_ID EVENT_NAME STATE ACCESS_MODE ISOLATION_LEVEL AUTO R_NESTING_EVENT_ID NESTING_EVENT_TYPE
thread_id 2 11 transaction COMMITTED READ WRITE REPEATABLE READ NO 1 STATEMENT
thread_id 13 13 transaction COMMITTED READ WRITE REPEATABLE READ YES 12 STATEMENT
thread_id 9 9 transaction COMMITTED READ WRITE REPEATABLE READ NO 8 STATEMENT
thread_id 9 12 transaction COMMITTED READ WRITE REPEATABLE READ NO 8 STATEMENT
thread_id 14 14 transaction COMMITTED READ WRITE REPEATABLE READ YES 13 STATEMENT
#
# EVENTS_STATEMENTS_HISTORY_LONG
#
@ -825,11 +842,11 @@ thread_id 4 4 statement/sql/insert NULL
thread_id 5 5 statement/sql/insert NULL 2 TRANSACTION 0 INSERT INTO t1 VALUES (412, "INSERT 412")
thread_id 6 6 statement/sql/delete NULL 2 TRANSACTION 0 DELETE FROM t1 WHERE s1 > 410
thread_id 7 7 statement/sql/select NULL 2 TRANSACTION 0 SELECT * FROM t1 ORDER BY s1
thread_id 8 10 statement/sql/select NULL 2 TRANSACTION 0 SELECT fn_add(413, 414)
thread_id 9 9 statement/sp/stmt fn_add 8 STATEMENT 1 INSERT INTO t1 VALUES (x, "INSERT x"),(y, "INSERT y")
thread_id 10 10 statement/sp/freturn fn_add 8 STATEMENT 1 NULL
thread_id 11 11 statement/sql/commit NULL 2 TRANSACTION 0 COMMIT
thread_id 12 13 statement/sql/select NULL NULL NULL 0 SELECT * FROM t1 ORDER BY s1
thread_id 8 11 statement/sql/select NULL 2 TRANSACTION 0 SELECT fn_add(413, 414)
thread_id 10 10 statement/sp/stmt fn_add 8 STATEMENT 1 INSERT INTO t1 VALUES (x, "INSERT x"),(y, "INSERT y")
thread_id 11 11 statement/sp/freturn fn_add 8 STATEMENT 1 NULL
thread_id 12 12 statement/sql/commit NULL NULL NULL 0 COMMIT
thread_id 13 14 statement/sql/select NULL NULL NULL 0 SELECT * FROM t1 ORDER BY s1
#
### Combined statement and transaction event history ordered by event id
#
@ -857,18 +874,19 @@ WHERE ((s.thread_id = @con1_thread_id) OR (@all_threads = 1))
ORDER BY thread_id, r_event_id;
THREAD_ID R_EVENT_ID R_END_EVENT_ID EVENT_NAME R_NESTING_EVENT_ID NESTING_EVENT_TYPE SQL_TXT
thread_id 1 2 statement/sql/begin NULL NULL START TRANSACTION
thread_id 2 11 transaction 1 STATEMENT <transaction started>
thread_id 3 3 statement/sql/insert 2 TRANSACTION INSERT INTO t1 VALUES (410, "INSERT 410")
thread_id 4 4 statement/sql/insert 2 TRANSACTION INSERT INTO t1 VALUES (411, "INSERT 411")
thread_id 5 5 statement/sql/insert 2 TRANSACTION INSERT INTO t1 VALUES (412, "INSERT 412")
thread_id 6 6 statement/sql/delete 2 TRANSACTION DELETE FROM t1 WHERE s1 > 410
thread_id 7 7 statement/sql/select 2 TRANSACTION SELECT * FROM t1 ORDER BY s1
thread_id 8 10 statement/sql/select 2 TRANSACTION SELECT fn_add(413, 414)
thread_id 9 9 statement/sp/stmt 8 STATEMENT INSERT INTO t1 VALUES (x, "INSERT x"),(y, "INSERT y")
thread_id 10 10 statement/sp/freturn 8 STATEMENT NULL
thread_id 11 11 statement/sql/commit 2 TRANSACTION COMMIT
thread_id 12 13 statement/sql/select NULL NULL SELECT * FROM t1 ORDER BY s1
thread_id 13 13 transaction 12 STATEMENT <transaction started>
thread_id 8 11 statement/sql/select 2 TRANSACTION SELECT fn_add(413, 414)
thread_id 9 9 transaction 8 STATEMENT <transaction started>
thread_id 9 12 transaction 8 STATEMENT <transaction started>
thread_id 10 10 statement/sp/stmt 8 STATEMENT INSERT INTO t1 VALUES (x, "INSERT x"),(y, "INSERT y")
thread_id 11 11 statement/sp/freturn 8 STATEMENT NULL
thread_id 12 12 statement/sql/commit NULL NULL COMMIT
thread_id 13 14 statement/sql/select NULL NULL SELECT * FROM t1 ORDER BY s1
thread_id 14 14 transaction 13 STATEMENT <transaction started>
#
### Clear statement and transaction history
# CALL test.clear_history();
@ -1023,11 +1041,11 @@ connection con1;
SELECT fn_err1();
ERROR 42000: FUNCTION db.fn_err1 does not exist
#
## Expect 0 transactions
## Expect 1 transactions
connection default;
SELECT COUNT(*) FROM performance_schema.events_transactions_history;
COUNT(*)
0
1
connection con1;
#
CREATE FUNCTION fn_err2() RETURNS VARCHAR(10) BEGIN COMMIT; RETURN 'invalid' ; END|
@ -1040,11 +1058,11 @@ DELETE FROM t1 WHERE s1 > 320;
SELECT fn_err2();
ERROR 42000: FUNCTION db.fn_err2 does not exist
#
## Expect 0 transactions
## Expect 2 transactions
connection default;
SELECT COUNT(*) FROM performance_schema.events_transactions_history;
COUNT(*)
0
2
#
## Clear transaction and statement tables
CALL test.clear_history();

4
mysql-test/suite/perfschema/t/transaction_nested_events.test

@ -235,7 +235,7 @@ SELECT COUNT(*) FROM performance_schema.events_transactions_history;
SELECT fn_err1();
--echo #
--echo ## Expect 0 transactions
--echo ## Expect 1 transactions
--connection default
SELECT COUNT(*) FROM performance_schema.events_transactions_history;
--connection con1
@ -255,7 +255,7 @@ DELETE FROM t1 WHERE s1 > 320;
SELECT fn_err2();
--echo #
--echo ## Expect 0 transactions
--echo ## Expect 2 transactions
--connection default
SELECT COUNT(*) FROM performance_schema.events_transactions_history;

83
sql/event_db_repository.cc

@ -30,6 +30,7 @@
#include "events.h"
#include "sql_show.h"
#include "lock.h" // MYSQL_LOCK_IGNORE_TIMEOUT
#include "transaction.h"
/**
@addtogroup Event_Scheduler
@ -533,23 +534,26 @@ Event_db_repository::fill_schema_events(THD *thd, TABLE_LIST *i_s_table,
const char *db)
{
TABLE *schema_table= i_s_table->table;
Open_tables_backup open_tables_backup;
TABLE_LIST event_table;
int ret= 0;
DBUG_ENTER("Event_db_repository::fill_schema_events");
DBUG_PRINT("info",("db=%s", db? db:"(null)"));
start_new_trans new_trans(thd);
event_table.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_EVENT_NAME, 0, TL_READ);
if (open_system_tables_for_read(thd, &event_table, &open_tables_backup))
if (open_system_tables_for_read(thd, &event_table))
{
new_trans.restore_old_transaction();
DBUG_RETURN(TRUE);
}
if (table_intact.check(event_table.table, &event_table_def))
{
close_system_tables(thd, &open_tables_backup);
my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0));
DBUG_RETURN(TRUE);
ret= 1;
goto err;
}
/*
@ -566,7 +570,9 @@ Event_db_repository::fill_schema_events(THD *thd, TABLE_LIST *i_s_table,
else
ret= table_scan_all_for_i_s(thd, schema_table, event_table.table);
close_system_tables(thd, &open_tables_backup);
err:
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
DBUG_PRINT("info", ("Return code=%d", ret));
DBUG_RETURN(ret);
@ -612,7 +618,8 @@ Event_db_repository::open_event_table(THD *thd, enum thr_lock_type lock_type,
if (table_intact.check(*table, &event_table_def))
{
close_thread_tables(thd);
thd->commit_whole_transaction_and_close_tables();
*table= 0; // Table is now closed
my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0));
DBUG_RETURN(TRUE);
}
@ -742,7 +749,8 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
ret= 0;
end:
close_thread_tables(thd);
if (table)
thd->commit_whole_transaction_and_close_tables();
thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
thd->variables.sql_mode= saved_mode;
@ -784,7 +792,6 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data,
*/
MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
int ret= 1;
DBUG_ENTER("Event_db_repository::update_event");
/* None or both must be set */
@ -857,7 +864,8 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data,
ret= 0;
end:
close_thread_tables(thd);
if (table)
thd->commit_whole_transaction_and_close_tables();
thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
thd->variables.sql_mode= saved_mode;
@ -919,7 +927,8 @@ Event_db_repository::drop_event(THD *thd, const LEX_CSTRING *db,
ret= 0;
end:
close_thread_tables(thd);
if (table)
thd->commit_whole_transaction_and_close_tables();
thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
DBUG_RETURN(MY_TEST(ret));
@ -999,12 +1008,16 @@ Event_db_repository::drop_schema_events(THD *thd, const LEX_CSTRING *schema)
TABLE *table= NULL;
READ_RECORD read_record_info;
enum enum_events_table_field field= ET_FIELD_DB;
MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
DBUG_ENTER("Event_db_repository::drop_schema_events");
DBUG_PRINT("enter", ("field: %d schema: %s", field, schema->str));
start_new_trans new_trans(thd);
if (open_event_table(thd, TL_WRITE, &table))
{
new_trans.restore_old_transaction();
DBUG_VOID_RETURN;
}
/* only enabled events are in memory, so we go now and delete the rest */
if (init_read_record(&read_record_info, thd, table, NULL, NULL, 1, 0, FALSE))
@ -1033,13 +1046,8 @@ Event_db_repository::drop_schema_events(THD *thd, const LEX_CSTRING *schema)
end_read_record(&read_record_info);
end:
close_thread_tables(thd);
/*
Make sure to only release the MDL lock on mysql.event, not other
metadata locks DROP DATABASE might have acquired.
*/
thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
DBUG_VOID_RETURN;
}
@ -1060,29 +1068,29 @@ Event_db_repository::load_named_event(THD *thd, const LEX_CSTRING *dbname,
Event_basic *etn)
{
bool ret;
Open_tables_backup open_tables_backup;
TABLE_LIST event_table;
DBUG_ENTER("Event_db_repository::load_named_event");
DBUG_PRINT("enter",("thd: %p name: %*s", thd,
(int) name->length, name->str));
event_table.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_EVENT_NAME, 0, TL_READ);
start_new_trans new_trans(thd);
/* Reset sql_mode during data dictionary operations. */
Sql_mode_instant_set sms(thd, 0);
event_table.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_EVENT_NAME, 0, TL_READ);
/*
We don't use open_event_table() here to make sure that SHOW
CREATE EVENT works properly in transactional context, and
does not release transactional metadata locks when the
event table is closed.
*/
if (!(ret= open_system_tables_for_read(thd, &event_table, &open_tables_backup)))
if (!(ret= open_system_tables_for_read(thd, &event_table)))
{
if (table_intact.check(event_table.table, &event_table_def))
{
close_system_tables(thd, &open_tables_backup);
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0));
DBUG_RETURN(TRUE);
}
@ -1091,9 +1099,9 @@ Event_db_repository::load_named_event(THD *thd, const LEX_CSTRING *dbname,
my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), name->str);
else if ((ret= etn->load_from_row(thd, event_table.table)))
my_error(ER_CANNOT_LOAD_FROM_TABLE_V2, MYF(0), "mysql", "event");
close_system_tables(thd, &open_tables_backup);
thd->commit_whole_transaction_and_close_tables();
}
new_trans.restore_old_transaction();
DBUG_RETURN(ret);
}
@ -1117,22 +1125,20 @@ update_timing_fields_for_event(THD *thd,
TABLE *table= NULL;
Field **fields;
int ret= 1;
enum_binlog_format save_binlog_format;
MYSQL_TIME time;
DBUG_ENTER("Event_db_repository::update_timing_fields_for_event");
/*
Turn off row binlogging of event timing updates. These are not used
for RBR of events replicated to the slave.
*/
save_binlog_format= thd->set_current_stmt_binlog_format_stmt();
DBUG_ASSERT(thd->security_ctx->master_access & PRIV_IGNORE_READ_ONLY);
if (open_event_table(thd, TL_WRITE, &table))
goto end;
DBUG_RETURN(1);
fields= table->field;
/*
Turn off row binlogging of event timing updates. These are not used
for RBR of events replicated to the slave.
*/
table->file->row_logging= 0;
if (find_named_event(event_db_name, event_name, table))
goto end;
@ -1153,12 +1159,9 @@ update_timing_fields_for_event(THD *thd,
}
ret= 0;
end:
if (table)
close_mysql_tables(thd);
thd->restore_stmt_binlog_format(save_binlog_format);
if (thd->commit_whole_transaction_and_close_tables())
ret= 1;
DBUG_RETURN(MY_TEST(ret));
}

2
sql/event_scheduler.cc

@ -511,6 +511,8 @@ Event_scheduler::run(THD *thd)
}
DBUG_PRINT("info", ("state=%s", scheduler_states_names[state].str));
free_root(thd->mem_root, MYF(0));
/* Ensure we don't have any open tables or table locks */
DBUG_ASSERT(thd->lock == 0);
}
LOCK_DATA();

6
sql/ha_partition.cc

@ -11014,9 +11014,9 @@ int ha_partition::check_misplaced_rows(uint read_part_id, bool do_repair)
/*
If the engine supports transactions, the failure will be
rollbacked.
rolled back
*/
if (!m_file[correct_part_id]->has_transactions())
if (!m_file[correct_part_id]->has_transactions_and_rollback())
{
/* Log this error, so the DBA can notice it and fix it! */
sql_print_error("Table '%-192s' failed to move/insert a row"
@ -11040,7 +11040,7 @@ int ha_partition::check_misplaced_rows(uint read_part_id, bool do_repair)
/* Delete row from wrong partition. */
if ((result= m_file[read_part_id]->ha_delete_row(m_rec0)))
{
if (m_file[correct_part_id]->has_transactions())
if (m_file[correct_part_id]->has_transactions_and_rollback())
break;
/*
We have introduced a duplicate, since we failed to remove it

27
sql/handler.cc

@ -1547,15 +1547,6 @@ int ha_commit_trans(THD *thd, bool all)
wsrep_commit_empty(thd, all);
#endif /* WITH_WSREP */
#if defined(WITH_ARIA_STORAGE_ENGINE)
/* This is needed to ensure that repair commits properly */
if ((error= ha_maria::implicit_commit(thd, TRUE)))
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
ha_rollback_trans(thd, all);
DBUG_RETURN(1);
}
#endif
DBUG_RETURN(0);
}
@ -1579,7 +1570,7 @@ int ha_commit_trans(THD *thd, bool all)
the plugin table to innodb and thus plugin_load will call
mysql_close_tables() which calls trans_commit_trans() with maria_hton = 0
*/
if (rw_trans || (likely(maria_hton) && thd_get_ha_data(thd, maria_hton)))
if (rw_trans)
{
/*
Acquire a metadata lock which will ensure that COMMIT is blocked
@ -1602,14 +1593,6 @@ int ha_commit_trans(THD *thd, bool all)
DEBUG_SYNC(thd, "ha_commit_trans_after_acquire_commit_lock");
}
#if defined(WITH_ARIA_STORAGE_ENGINE)
if ((error= ha_maria::implicit_commit(thd, TRUE)))
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
goto err;
}
#endif
if (rw_trans &&
opt_readonly &&
!(thd->security_ctx->master_access & PRIV_IGNORE_READ_ONLY) &&
@ -2001,7 +1984,8 @@ int ha_rollback_trans(THD *thd, bool all)
int err;
handlerton *ht= ha_info->ht();
if ((err= ht->rollback(ht, thd, all)))
{ // cannot happen
{
// cannot happen
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
error=1;
#ifdef WITH_WSREP
@ -4514,7 +4498,6 @@ void handler::mark_trx_read_write_internal()
*/
if (ha_info->is_started())
{
DBUG_ASSERT(has_transaction_manager());
/*
table_share can be NULL in ha_delete_table(). See implementation
of standalone function ha_delete_table() in sql_base.cc.
@ -6180,7 +6163,7 @@ extern "C" check_result_t handler_index_cond_check(void* h_arg)
THD *thd= h->table->in_use;
check_result_t res;
enum thd_kill_levels abort_at= h->has_transactions() ?
enum thd_kill_levels abort_at= h->has_rollback() ?
THD_ABORT_SOFTLY : THD_ABORT_ASAP;
if (thd_kill_level(thd) > abort_at)
return CHECK_ABORTED_BY_USER;
@ -6947,7 +6930,7 @@ bool handler::prepare_for_row_logging()
row_logging_has_trans=
((sql_command_flags[table->in_use->lex->sql_command] &
(CF_SCHEMA_CHANGE | CF_ADMIN_COMMAND)) ||
table->file->has_transactions());
table->file->has_transactions_and_rollback());
}
else
{

42
sql/handler.h

@ -1765,6 +1765,14 @@ handlerton *ha_default_tmp_handlerton(THD *thd);
*/
#define HTON_TABLE_MAY_NOT_EXIST_ON_SLAVE (1 << 15)
/*
True if handler cannot rollback transactions. If not true, the transaction
will be put in the transactional binlog cache.
For some engines, like Aria, the rollback can happen in case of crash, but
not trough a handler rollback call.
*/
#define HTON_NO_ROLLBACK (1 << 16)
class Ha_trx_info;
struct THD_TRANS
@ -3541,9 +3549,12 @@ public:
virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; }
/*
True if changes to the table is persistent (no rollback)
This is mainly used to decide how to log changes to the table in
the binary log.
True if changes to the table is persistent (if there are no rollback)
This is used to decide:
- If the table is stored in the transaction or non transactional binary
log
- How things are tracked in trx and in add_changed_table().
- If we can combine several statements under one commit in the binary log.
*/
bool has_transactions()
{
@ -3551,11 +3562,31 @@ public:
== 0);
}
/*
True if the underlaying table doesn't support transactions
True if table has both transactions and rollback. This is used to decide
if we should write the changes to the binary log. If this is true,
we don't have to write failed statements to the log as they can be
rolled back.
*/
bool has_transactions_and_rollback()
{
return has_transactions() && has_rollback();
}
/*
True if the underlaying table support transactions and rollback
*/
bool has_transaction_manager()
{
return ((ha_table_flags() & HA_NO_TRANSACTIONS) == 0);
return ((ha_table_flags() & HA_NO_TRANSACTIONS) == 0 && has_rollback());
}
/*
True if table has rollback. Used to check if an update on the table
can be killed fast.
*/
bool has_rollback()
{
return ((ht->flags & HTON_NO_ROLLBACK) == 0);
}
/**
@ -4975,7 +5006,6 @@ public:
inline int ha_update_tmp_row(const uchar * old_data, uchar * new_data);
virtual void set_lock_type(enum thr_lock_type lock);
friend check_result_t handler_index_cond_check(void* h_arg);
friend check_result_t handler_rowid_filter_check(void *h_arg);

35
sql/log.cc

@ -1701,7 +1701,7 @@ int binlog_init(void *p)
// recover needs to be set to make xa{commit,rollback}_handlerton effective
binlog_hton->recover= binlog_xa_recover_dummy;
}
binlog_hton->flags= HTON_NOT_USER_SELECTABLE | HTON_HIDDEN;
binlog_hton->flags= HTON_NOT_USER_SELECTABLE | HTON_HIDDEN | HTON_NO_ROLLBACK;
return 0;
}
@ -5611,7 +5611,8 @@ trans_has_updated_trans_table(const THD* thd)
@param thd The client thread that executed the current statement.
@return
@c true if a transactional table was updated, @c false otherwise.
@c true if a transactional table with rollback was updated,
@c false otherwise.
*/
bool
stmt_has_updated_trans_table(const THD *thd)
@ -5621,7 +5622,8 @@ stmt_has_updated_trans_table(const THD *thd)
for (ha_info= thd->transaction->stmt.ha_list; ha_info;
ha_info= ha_info->next())
{
if (ha_info->is_trx_read_write() && ha_info->ht() != binlog_hton)
if (ha_info->is_trx_read_write() &&
!(ha_info->ht()->flags & HTON_NO_ROLLBACK))
return (TRUE);
}
return (FALSE);
@ -10125,14 +10127,31 @@ int TC_LOG_BINLOG::unlog_xa_prepare(THD *thd, bool all)
uint rw_count= ha_count_rw_all(thd, &ha_info);
bool rc= false;
if (rw_count > 0)
{
/* an empty XA-prepare event group is logged */
#ifndef DBUG_OFF
for (ha_info= thd->transaction->all.ha_list; rw_count > 1 && ha_info;
if (rw_count > 1)
{
/*
There must be no binlog_hton used in a transaction consisting of more
than 1 engine, *when* (at this point) this transaction has not been
binlogged. The one exception is if there is an engine without a
prepare method, as in this case the engine doesn't support XA and
we have to ignore this check.
*/
bool binlog= false, exist_hton_without_prepare= false;
for (ha_info= thd->transaction->all.ha_list; ha_info;
ha_info= ha_info->next())
DBUG_ASSERT(ha_info->ht() != binlog_hton);
{
if (ha_info->ht() == binlog_hton)
binlog= true;
if (!ha_info->ht()->prepare)
exist_hton_without_prepare= true;
}
DBUG_ASSERT(!binlog || exist_hton_without_prepare);
}
#endif
if (rw_count > 0)
{
/* an empty XA-prepare event group is logged */
rc= write_empty_xa_prepare(thd, cache_mngr); // normally gains need_unlog
trans_register_ha(thd, true, binlog_hton, 0); // do it for future commmit
}

2
sql/log_event_server.cc

@ -5569,7 +5569,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
if (table)
{
master_had_triggers= table->master_had_triggers;
bool transactional_table= table->file->has_transactions();
bool transactional_table= table->file->has_transactions_and_rollback();
/*
table == NULL means that this table should not be replicated
(this was set up by Table_map_log_event::do_apply_event()

2
sql/share/errmsg-utf8.txt

@ -7963,3 +7963,5 @@ ER_KEY_CANT_HAVE_WITHOUT_OVERLAPS
eng "Key %`s cannot have WITHOUT OVERLAPS"
ER_NOT_ALLOWED_IN_THIS_CONTEXT
eng "'%-.128s' is not allowed in this context"
ER_DATA_WAS_COMMITED_UNDER_ROLLBACK
eng "Engine %s does not support rollback. Changes where commited during rollback call"

72
sql/sp.cc

@ -30,6 +30,7 @@
#include "sql_table.h" // write_bin_log
#include "sp_head.h"
#include "sp_cache.h"
#include "transaction.h"
#include "lock.h" // lock_object_name
#include <my_user.h>
@ -470,27 +471,31 @@ static Proc_table_intact proc_table_intact;
currently open tables will be saved, and from which will be
restored when we will end work with mysql.proc.
NOTES
On must have a start_new_trans object active when calling this function
@retval
0 Error
@retval
\# Pointer to TABLE object of mysql.proc
*/
TABLE *open_proc_table_for_read(THD *thd, Open_tables_backup *backup)
TABLE *open_proc_table_for_read(THD *thd)
{
TABLE_LIST table;
DBUG_ENTER("open_proc_table_for_read");
DBUG_ASSERT(thd->internal_transaction());
table.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_PROC_NAME, NULL, TL_READ);
if (open_system_tables_for_read(thd, &table, backup))
if (open_system_tables_for_read(thd, &table))
DBUG_RETURN(NULL);
if (!proc_table_intact.check(table.table, &proc_table_def))
DBUG_RETURN(table.table);
close_system_tables(thd, backup);
thd->commit_whole_transaction_and_close_tables();
DBUG_RETURN(NULL);
}
@ -504,6 +509,10 @@ TABLE *open_proc_table_for_read(THD *thd, Open_tables_backup *backup)
@note
Table opened with this call should closed using close_thread_tables().
We don't need to use the start_new_transaction object when calling this
as there can't be any active transactions when we create or alter
stored procedures
@retval
0 Error
@retval
@ -517,7 +526,10 @@ static TABLE *open_proc_table_for_update(THD *thd)
MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
DBUG_ENTER("open_proc_table_for_update");
table_list.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_PROC_NAME, NULL, TL_WRITE);
DBUG_ASSERT(!thd->internal_transaction());
table_list.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_PROC_NAME, NULL,
TL_WRITE);
if (!(table= open_system_table_for_update(thd, &table_list)))
DBUG_RETURN(NULL);
@ -525,7 +537,7 @@ static TABLE *open_proc_table_for_update(THD *thd)
if (!proc_table_intact.check(table, &proc_table_def))
DBUG_RETURN(table);
close_thread_tables(thd);
thd->commit_whole_transaction_and_close_tables();
thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
DBUG_RETURN(NULL);
@ -683,23 +695,26 @@ Sp_handler::db_find_routine(THD *thd,
longlong modified;
Sp_chistics chistics;
bool saved_time_zone_used= thd->time_zone_used;
bool trans_commited= 0;
sql_mode_t sql_mode;
Open_tables_backup open_tables_state_backup;
Stored_program_creation_ctx *creation_ctx;
AUTHID definer;
DBUG_ENTER("db_find_routine");
DBUG_PRINT("enter", ("type: %s name: %.*s",
type_str(),
(int) name->m_name.length, name->m_name.str));
*sphp= 0; // In case of errors
if (!(table= open_proc_table_for_read(thd, &open_tables_state_backup)))
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
/* Reset sql_mode during data dictionary operations. */
start_new_trans new_trans(thd);
Sql_mode_instant_set sms(thd, 0);
if (!(table= open_proc_table_for_read(thd)))
{
ret= SP_OPEN_TABLE_FAILED;
goto done;
}
if ((ret= db_find_routine_aux(thd, name, table)) != SP_OK)
goto done;
@ -741,8 +756,9 @@ Sp_handler::db_find_routine(THD *thd,
creation_ctx= Stored_routine_creation_ctx::load_from_db(thd, name, table);
close_system_tables(thd, &open_tables_state_backup);
table= 0;
trans_commited= 1;
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
ret= db_load_routine(thd, name, sphp,
sql_mode, params, returns, body, chistics, definer,
@ -753,8 +769,12 @@ Sp_handler::db_find_routine(THD *thd,
does not affect replication.
*/
thd->time_zone_used= saved_time_zone_used;
if (table)
close_system_tables(thd, &open_tables_state_backup);
if (!trans_commited)
{
if (table)
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
}
DBUG_RETURN(ret);
}
@ -1727,7 +1747,6 @@ bool lock_db_routines(THD *thd, const char *db)
{
TABLE *table;
uint key_len;
Open_tables_backup open_tables_state_backup;
MDL_request_list mdl_requests;
Lock_db_routines_error_handler err_handler;
uchar keybuf[MAX_KEY_LENGTH];
@ -1735,13 +1754,15 @@ bool lock_db_routines(THD *thd, const char *db)
DBUG_SLOW_ASSERT(ok_for_lower_case_names(db));
start_new_trans new_trans(thd);
/*
mysql.proc will be re-opened during deletion, so we can ignore
errors when opening the table here. The error handler is
used to avoid getting the same warning twice.
*/
thd->push_internal_handler(&err_handler);
table= open_proc_table_for_read(thd, &open_tables_state_backup);
table= open_proc_table_for_read(thd);
thd->pop_internal_handler();
if (!table)
{
@ -1750,6 +1771,7 @@ bool lock_db_routines(THD *thd, const char *db)
or is outdated. We therefore only abort mysql_rm_db() if we
have errors not handled by the error handler.
*/
new_trans.restore_old_transaction();
DBUG_RETURN(thd->is_error() || thd->killed);
}
@ -1760,11 +1782,10 @@ bool lock_db_routines(THD *thd, const char *db)
if (nxtres)
{
table->file->print_error(nxtres, MYF(0));
close_system_tables(thd, &open_tables_state_backup);
DBUG_RETURN(true);
goto error;
}
if (! table->file->ha_index_read_map(table->record[0], keybuf, (key_part_map)1,
if (!table->file->ha_index_read_map(table->record[0], keybuf, (key_part_map)1,
HA_READ_KEY_EXACT))
{
do
@ -1789,10 +1810,10 @@ bool lock_db_routines(THD *thd, const char *db)
if (nxtres != 0 && nxtres != HA_ERR_END_OF_FILE)
{
table->file->print_error(nxtres, MYF(0));
close_system_tables(thd, &open_tables_state_backup);
DBUG_RETURN(true);
goto error;
}
close_system_tables(thd, &open_tables_state_backup);
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
/* We should already hold a global IX lock and a schema X lock. */
DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::BACKUP, "", "",
@ -1801,6 +1822,10 @@ bool lock_db_routines(THD *thd, const char *db)
MDL_EXCLUSIVE));
DBUG_RETURN(thd->mdl_context.acquire_locks(&mdl_requests,
thd->variables.lock_wait_timeout));
error:
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
DBUG_RETURN(true);
}
@ -1879,6 +1904,7 @@ sp_drop_db_routines(THD *thd, const char *db)
table->file->ha_index_end();
err_idx_init:
trans_commit_stmt(thd);
close_thread_tables(thd);
/*
Make sure to only release the MDL lock on mysql.proc, not other

2
sql/sp.h

@ -655,7 +655,7 @@ extern "C" uchar* sp_sroutine_key(const uchar *ptr, size_t *plen,
Routines which allow open/lock and close mysql.proc table even when
we already have some tables open and locked.
*/
TABLE *open_proc_table_for_read(THD *thd, Open_tables_backup *backup);
TABLE *open_proc_table_for_read(THD *thd);
bool load_charset(MEM_ROOT *mem_root,
Field *field,

59
sql/sql_base.cc

@ -4259,7 +4259,7 @@ restart:
list, we still need to call open_and_process_routine() to take
MDL locks on the routines.
*/
if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
if (thd->locked_tables_mode <= LTM_LOCK_TABLES && *sroutine_to_open)
{
/*
Process elements of the prelocking set which are present there
@ -8881,17 +8881,16 @@ bool is_equal(const LEX_CSTRING *a, const LEX_CSTRING *b)
open_system_tables_for_read()
thd Thread context.
table_list List of tables to open.
backup Pointer to Open_tables_state instance where
information about currently open tables will be
saved, and from which will be restored when we will
end work with system tables.
NOTES
Caller should have used start_new_trans object to start a new
transcation when reading system tables.
Thanks to restrictions which we put on opening and locking of
system tables for writing, we can open and lock them for reading
even when we already have some other tables open and locked. One
must call close_system_tables() to close systems tables opened
with this call.
even when we already have some other tables open and locked.
One should call thd->commit_whole_transaction_and_close_tables()
to close systems tables opened with this call.
NOTES
In some situations we use this function to open system tables for
@ -8905,22 +8904,20 @@ bool is_equal(const LEX_CSTRING *a, const LEX_CSTRING *b)
*/
bool
open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
Open_tables_backup *backup)
open_system_tables_for_read(THD *thd, TABLE_LIST *table_list)
{
Query_tables_list query_tables_list_backup;
LEX *lex= thd->lex;
DBUG_ENTER("open_system_tables_for_read");
DBUG_ASSERT(thd->internal_transaction());
/*
Besides using new Open_tables_state for opening system tables,
we also have to backup and reset/and then restore part of LEX
which is accessed by open_tables() in order to determine if
prelocking is needed and what tables should be added for it.
close_system_tables() doesn't require such treatment.
*/
lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
thd->reset_n_backup_open_tables_state(backup);
thd->lex->sql_command= SQLCOM_SELECT;
/*
@ -8935,7 +8932,6 @@ open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
MYSQL_LOCK_IGNORE_TIMEOUT : 0))))
{
lex->restore_backup_query_tables_list(&query_tables_list_backup);
thd->restore_backup_open_tables_state(backup);
DBUG_RETURN(TRUE);
}
@ -8950,33 +8946,6 @@ open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(FALSE);
}
/*
Close system tables, opened with open_system_tables_for_read().
SYNOPSIS
close_system_tables()
thd Thread context
backup Pointer to Open_tables_backup instance which holds
information about tables which were open before we
decided to access system tables.
*/
void
close_system_tables(THD *thd, Open_tables_backup *backup)
{
/*
Inform the transaction handler that we are closing the
system tables and we don't need the read view anymore.
*/
for (TABLE *table= thd->open_tables ; table ; table= table->next)
table->file->extra(HA_EXTRA_PREPARE_FOR_FORCED_CLOSE);
close_thread_tables(thd);
thd->restore_backup_open_tables_state(backup);
}
/**
A helper function to close a mysql.* table opened
in an auxiliary THD during bootstrap or in the main
@ -9085,9 +9054,17 @@ open_log_table(THD *thd, TABLE_LIST *one_table, Open_tables_backup *backup)
@param thd The current thread
@param backup [in] the context to restore.
*/
void close_log_table(THD *thd, Open_tables_backup *backup)
{
close_system_tables(thd, backup);
/*
Inform the transaction handler that we are closing the
system tables and we don't need the read view anymore.
*/
for (TABLE *table= thd->open_tables ; table ; table= table->next)
table->file->extra(HA_EXTRA_PREPARE_FOR_FORCED_CLOSE);
close_thread_tables(thd);
thd->restore_backup_open_tables_state(backup);
}

5
sql/sql_base.h

@ -294,9 +294,8 @@ bool is_equal(const LEX_CSTRING *a, const LEX_CSTRING *b);
class Open_tables_backup;
/* Functions to work with system tables. */
bool open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
Open_tables_backup *backup);
void close_system_tables(THD *thd, Open_tables_backup *backup);
bool open_system_tables_for_read(THD *thd, TABLE_LIST *table_list);
void close_system_tables(THD *thd);
void close_mysql_tables(THD *thd);
TABLE *open_system_table_for_update(THD *thd, TABLE_LIST *one_table);
TABLE *open_log_table(THD *thd, TABLE_LIST *one_table, Open_tables_backup *backup);

90
sql/sql_class.cc

@ -72,6 +72,7 @@
#include "wsrep_trans_observer.h"
#endif /* WITH_WSREP */
#include "opt_trace.h"
#include <mysql/psi/mysql_transaction.h>
#ifdef HAVE_SYS_SYSCALL_H
#include <sys/syscall.h>
@ -2589,7 +2590,8 @@ void THD::add_changed_table(TABLE *table)
{
DBUG_ENTER("THD::add_changed_table(table)");
DBUG_ASSERT(in_multi_stmt_transaction_mode() && table->file->has_transactions());
DBUG_ASSERT(in_multi_stmt_transaction_mode() &&
table->file->has_transactions());
add_changed_table(table->s->table_cache_key.str,
(long) table->s->table_cache_key.length);
DBUG_VOID_RETURN;
@ -5742,6 +5744,92 @@ void THD::mark_transaction_to_rollback(bool all)
}
/**
Commit the whole transaction (both statment and all)
This is used mainly to commit an independent transaction,
like reading system tables.
@return 0 0k
@return <>0 error code. my_error() has been called()
*/
int THD::commit_whole_transaction_and_close_tables()
{
int error, error2;
DBUG_ENTER("THD::commit_whole_transaction_and_close_tables");
/*
This can only happened if we failed to open any table in the
new transaction
*/
DBUG_ASSERT(open_tables);
if (!open_tables) // Safety for production usage
DBUG_RETURN(0);
/*
Ensure table was locked (opened with open_and_lock_tables()). If not
the THD can't be part of any transactions and doesn't have to call
this function.
*/
DBUG_ASSERT(lock);
error= ha_commit_trans(this, FALSE);
/* This will call external_lock to unlock all tables */
if ((error2= mysql_unlock_tables(this, lock)))
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error2);
error= error2;
}
lock= 0;
if ((error2= ha_commit_trans(this, TRUE)))
error= error2;
close_thread_tables(this);
DBUG_RETURN(error);
}
/**
Start a new independent transaction
*/
start_new_trans::start_new_trans(THD *thd)
{
org_thd= thd;
mdl_savepoint= thd->mdl_context.mdl_savepoint();
memcpy(old_ha_data, thd->ha_data, sizeof(old_ha_data));
thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
bzero(thd->ha_data, sizeof(thd->ha_data));
old_transaction= thd->transaction;
thd->transaction= &new_transaction;
new_transaction.on= 1;
in_sub_stmt= thd->in_sub_stmt;
thd->in_sub_stmt= 0;
server_status= thd->server_status;
m_transaction_psi= thd->m_transaction_psi;
thd->m_transaction_psi= 0;
thd->server_status&= ~(SERVER_STATUS_IN_TRANS |
SERVER_STATUS_IN_TRANS_READONLY);
thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
}
void start_new_trans::restore_old_transaction()
{
org_thd->transaction= old_transaction;
org_thd->restore_backup_open_tables_state(&open_tables_state_backup);
ha_close_connection(org_thd);
memcpy(org_thd->ha_data, old_ha_data, sizeof(old_ha_data));
org_thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
org_thd->in_sub_stmt= in_sub_stmt;
org_thd->server_status= server_status;
if (org_thd->m_transaction_psi)
MYSQL_COMMIT_TRANSACTION(org_thd->m_transaction_psi);
org_thd->m_transaction_psi= m_transaction_psi;
org_thd= 0;
}
/**
Decide on logging format to use for the statement and issue errors
or warnings as needed. The decision depends on the following

37
sql/sql_class.h

@ -3741,6 +3741,8 @@ public:
{
return server_status & SERVER_STATUS_IN_TRANS;
}
/* Commit both statement and full transaction */
int commit_whole_transaction_and_close_tables();
void give_protection_error();
inline bool has_read_only_protection()
{
@ -4765,6 +4767,7 @@ public:
}
void mark_transaction_to_rollback(bool all);
bool internal_transaction() { return transaction != &default_transaction; }
private:
/** The current internal error handler for this thread, or NULL. */
@ -5149,6 +5152,40 @@ public:
};
/*
Start a new independent transaction for the THD.
The old one is stored in this object and restored when calling
restore_old_transaction() or when the object is freed
*/
class start_new_trans
{
/* container for handler's private per-connection data */
Ha_data old_ha_data[MAX_HA];
struct THD::st_transactions *old_transaction, new_transaction;
Open_tables_backup open_tables_state_backup;
MDL_savepoint mdl_savepoint;
PSI_transaction_locker *m_transaction_psi;
THD *org_thd;
uint in_sub_stmt;
uint server_status;
public:
start_new_trans(THD *thd);
~start_new_trans()
{
destroy();
}
void destroy()
{
if (org_thd) // Safety
restore_old_transaction();
new_transaction.free();
}
void restore_old_transaction();
};
/** A short cut for thd->get_stmt_da()->set_ok_status(). */
inline void

6
sql/sql_delete.cc

@ -875,7 +875,7 @@ cleanup:
deltempfile=NULL;
delete select;
select= NULL;
transactional_table= table->file->has_transactions();
transactional_table= table->file->has_transactions_and_rollback();
if (!transactional_table && deleted > 0)
thd->transaction->stmt.modified_non_trans_table=
@ -1388,7 +1388,7 @@ void multi_delete::abort_result_set()
*/
if (do_delete && normal_tables &&
(table_being_deleted != delete_tables ||
!table_being_deleted->table->file->has_transactions()))
!table_being_deleted->table->file->has_transactions_and_rollback()))
{
/*
We have to execute the recorded do_deletes() and write info into the
@ -1537,7 +1537,7 @@ int multi_delete::do_table_deletes(TABLE *table, SORT_INFO *sort_info,
table->file->print_error(local_error, MYF(0));
}
}
if (last_deleted != deleted && !table->file->has_transactions())
if (last_deleted != deleted && !table->file->has_transactions_and_rollback())
thd->transaction->stmt.modified_non_trans_table= TRUE;
end_read_record(&info);

11
sql/sql_help.cc

@ -709,8 +709,9 @@ static bool mysqld_help_internal(THD *thd, const char *mask)
Reset and backup the current open tables state to
make it possible.
*/
Open_tables_backup open_tables_state_backup;
if (open_system_tables_for_read(thd, tables, &open_tables_state_backup))
start_new_trans new_trans(thd);
if (open_system_tables_for_read(thd, tables))
goto error2;
/*
@ -843,11 +844,13 @@ static bool mysqld_help_internal(THD *thd, const char *mask)
}
my_eof(thd);
close_system_tables(thd, &open_tables_state_backup);
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
DBUG_RETURN(FALSE);
error:
close_system_tables(thd, &open_tables_state_backup);
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
error2:
DBUG_RETURN(TRUE);

12
sql/sql_insert.cc

@ -1144,7 +1144,7 @@ values_loop_end:
table->file->ha_rnd_end();
}
transactional_table= table->file->has_transactions();
transactional_table= table->file->has_transactions_and_rollback();
if (likely(changed= (info.copied || info.deleted || info.updated)))
{
@ -2055,7 +2055,7 @@ int write_record(THD *thd, TABLE *table, COPY_INFO *info, select_result *sink)
info->deleted++;
else
info->updated++;
if (!table->file->has_transactions())
if (!table->file->has_transactions_and_rollback())
thd->transaction->stmt.modified_non_trans_table= TRUE;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
@ -2121,7 +2121,7 @@ ok:
after_trg_or_ignored_err:
if (key)
my_safe_afree(key,table->s->max_unique_length);
if (!table->file->has_transactions())
if (!table->file->has_transactions_and_rollback())
thd->transaction->stmt.modified_non_trans_table= TRUE;
DBUG_RETURN(trg_error);
@ -4104,13 +4104,13 @@ void select_insert::store_values(List<Item> &values)
bool select_insert::prepare_eof()
{
int error;
bool const trans_table= table->file->has_transactions();
bool const trans_table= table->file->has_transactions_and_rollback();
bool changed;
bool binary_logged= 0;
killed_state killed_status= thd->killed;
DBUG_ENTER("select_insert::prepare_eof");
DBUG_PRINT("enter", ("trans_table=%d, table_type='%s'",
DBUG_PRINT("enter", ("trans_table: %d, table_type: '%s'",
trans_table, table->file->table_type()));
#ifdef WITH_WSREP
@ -4273,7 +4273,7 @@ void select_insert::abort_result_set()
zero, so no check for that is made.
*/
changed= (info.copied || info.deleted || info.updated);
transactional_table= table->file->has_transactions();
transactional_table= table->file->has_transactions_and_rollback();
if (thd->transaction->stmt.modified_non_trans_table ||
thd->log_current_statement)
{

4
sql/sql_load.cc

@ -436,7 +436,7 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list,
}
table= table_list->table;
transactional_table= table->file->has_transactions();
transactional_table= table->file->has_transactions_and_rollback();
#ifndef EMBEDDED_LIBRARY
is_concurrent= (table_list->lock_type == TL_WRITE_CONCURRENT_INSERT);
#endif
@ -1212,7 +1212,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
bool no_trans_update_stmt;
DBUG_ENTER("read_xml_field");
no_trans_update_stmt= !table->file->has_transactions();
no_trans_update_stmt= !table->file->has_transactions_and_rollback();
for ( ; ; it.rewind())
{

60
sql/sql_parse.cc

@ -437,16 +437,13 @@ bool stmt_causes_implicit_commit(THD *thd, uint mask)
DBUG_RETURN(FALSE);
switch (lex->sql_command) {
case SQLCOM_DROP_TABLE:
case SQLCOM_DROP_SEQUENCE:
skip= (lex->tmp_table() ||
(thd->variables.option_bits & OPTION_GTID_BEGIN));
break;
case SQLCOM_ALTER_TABLE:
case SQLCOM_ALTER_SEQUENCE:
/* If ALTER TABLE of non-temporary table, do implicit commit */
skip= (lex->tmp_table());
break;
case SQLCOM_DROP_TABLE:
case SQLCOM_DROP_SEQUENCE:
case SQLCOM_CREATE_TABLE:
case SQLCOM_CREATE_SEQUENCE:
/*
@ -1532,42 +1529,6 @@ public:
};
#endif
/*
Do an implict commit into the Aria storage engine
*/
static inline my_bool aria_implicit_commit(THD *thd)
{
#if defined(WITH_ARIA_STORAGE_ENGINE)
if (thd_get_ha_data(thd, maria_hton))
{
MDL_request mdl_request;
bool locked;
int res;
Silence_all_errors error_handler;
DBUG_ASSERT(maria_hton);
MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
MDL_EXPLICIT);
/*
We have to ignore any errors from acquire_lock and continue even if we
don't get the lock as Aria can't roll back!
This function is also called in some cases when the message is already
sent to the user, so we can't even send a warning.
*/
thd->push_internal_handler(& error_handler);
locked= !thd->mdl_context.acquire_lock(&mdl_request,
thd->variables.lock_wait_timeout);
thd->pop_internal_handler();
res= ha_maria::implicit_commit(thd, FALSE);
if (locked)
thd->mdl_context.release_lock(mdl_request.ticket);
return res;
}
#endif
return 0;
}
/**
Perform one connection-level (COM_XXXX) command.
@ -1921,8 +1882,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
*/
char *beginning_of_next_stmt= (char*) parser_state.m_lip.found_semicolon;
aria_implicit_commit(thd);
/* Finalize server status flags after executing a statement. */
thd->update_server_status();
thd->protocol->end_statement();
@ -3170,14 +3129,13 @@ mysql_create_routine(THD *thd, LEX *lex)
statement takes metadata locks should be detected by a deadlock
detector in MDL subsystem and reported as errors.
No need to commit/rollback statement transaction, it's not started.
TODO: Long-term we should either ensure that implicit GRANT statement
is written into binary log as a separate statement or make both
creation of routine and implicit GRANT parts of one fully atomic
statement.
*/
DBUG_ASSERT(thd->transaction->stmt.is_empty());
if (trans_commit_stmt(thd))
goto wsrep_error_label;
close_thread_tables(thd);
/*
Check if the definer exists on slave,
@ -3221,7 +3179,9 @@ mysql_create_routine(THD *thd, LEX *lex)
#endif
return false;
}
#ifdef WITH_WSREP
(void) trans_commit_stmt(thd);
#if !defined(NO_EMBEDDED_ACCESS_CHECKS) || defined(WITH_WSREP)
wsrep_error_label:
#endif
return true;
@ -6049,7 +6009,6 @@ finish:
trans_commit_stmt(thd);
thd->get_stmt_da()->set_overwrite_status(false);
}
aria_implicit_commit(thd);
}
/* Free tables. Set stage 'closing tables' */
@ -6571,14 +6530,13 @@ drop_routine(THD *thd, LEX *lex)
statement takes metadata locks should be detected by a deadlock
detector in MDL subsystem and reported as errors.
No need to commit/rollback statement transaction, it's not started.
TODO: Long-term we should either ensure that implicit REVOKE statement
is written into binary log as a separate statement or make both
dropping of routine and implicit REVOKE parts of one fully atomic
statement.
*/
DBUG_ASSERT(thd->transaction->stmt.is_empty());
if (trans_commit_stmt(thd))
sp_result= SP_INTERNAL_ERROR;
close_thread_tables(thd);
if (sp_result != SP_KEY_NOT_FOUND &&

3
sql/sql_sequence.cc

@ -301,8 +301,7 @@ bool sequence_insert(THD *thd, LEX *lex, TABLE_LIST *org_table_list)
if (!temporary_table)
{
/*
The following code works like open_system_tables_for_read() and
close_system_tables()
The following code works like open_system_tables_for_read()
The idea is:
- Copy the table_list object for the sequence that was created
- Backup the current state of open tables and create a new

13
sql/sql_show.cc

@ -6105,7 +6105,7 @@ static my_bool iter_schema_engines(THD *thd, plugin_ref plugin,
table->field[1]->store(option_name, strlen(option_name), scs);
table->field[2]->store(plugin_decl(plugin)->descr,
strlen(plugin_decl(plugin)->descr), scs);
tmp= &yesno[MY_TEST(hton->commit)];
tmp= &yesno[MY_TEST(hton->commit && !(hton->flags & HTON_NO_ROLLBACK))];
table->field[3]->store(tmp->str, tmp->length, scs);
table->field[3]->set_notnull();
tmp= &yesno[MY_TEST(hton->prepare)];
@ -6492,7 +6492,6 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond)
TABLE *table= tables->table;
bool full_access;
char definer[USER_HOST_BUFF_SIZE];
Open_tables_backup open_tables_state_backup;
enum enum_schema_tables schema_table_idx=
get_schema_table_idx(tables->schema_table);
DBUG_ENTER("fill_schema_proc");
@ -6507,8 +6506,12 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond)
proc_tables.lock_type= TL_READ;
full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, FALSE,
1, TRUE);
if (!(proc_table= open_proc_table_for_read(thd, &open_tables_state_backup)))
start_new_trans new_trans(thd);
if (!(proc_table= open_proc_table_for_read(thd)))
{
new_trans.restore_old_transaction();
DBUG_RETURN(1);
}
@ -6550,7 +6553,9 @@ err:
if (proc_table->file->inited)
(void) proc_table->file->ha_index_end();
close_system_tables(thd, &open_tables_state_backup);
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
thd->variables.sql_mode = sql_mode_was;
DBUG_RETURN(res);
}

87
sql/sql_statistics.cc

@ -230,17 +230,17 @@ index_stat_def= {INDEX_STAT_N_FIELDS, index_stat_fields, 4, index_stat_pk_col};
Open all statistical tables and lock them
*/
static int open_stat_tables(THD *thd, TABLE_LIST *tables,
Open_tables_backup *backup, bool for_write)
static int open_stat_tables(THD *thd, TABLE_LIST *tables, bool for_write)
{
int rc;
Dummy_error_handler deh; // suppress errors
DBUG_ASSERT(thd->internal_transaction());
thd->push_internal_handler(&deh);
init_table_list_for_stat_tables(tables, for_write);
init_mdl_requests(tables);
thd->in_sub_stmt|= SUB_STMT_STAT_TABLES;
rc= open_system_tables_for_read(thd, tables, backup);
rc= open_system_tables_for_read(thd, tables);
thd->in_sub_stmt&= ~SUB_STMT_STAT_TABLES;
thd->pop_internal_handler();
@ -253,7 +253,7 @@ static int open_stat_tables(THD *thd, TABLE_LIST *tables,
stat_table_intact.check(tables[COLUMN_STAT].table, &column_stat_def) ||
stat_table_intact.check(tables[INDEX_STAT].table, &index_stat_def)))
{
close_system_tables(thd, backup);
close_thread_tables(thd);
rc= 1;
}
@ -270,13 +270,12 @@ static int open_stat_tables(THD *thd, TABLE_LIST *tables,
stat tables need to be adjusted accordingly.
*/
static inline int open_stat_table_for_ddl(THD *thd, TABLE_LIST *table,
const LEX_CSTRING *stat_tab_name,
Open_tables_backup *backup)
const LEX_CSTRING *stat_tab_name)
{
table->init_one_table(&MYSQL_SCHEMA_NAME, stat_tab_name, NULL, TL_WRITE);
No_such_table_error_handler nst_handler;
thd->push_internal_handler(&nst_handler);
int res= open_system_tables_for_read(thd, table, backup);
int res= open_system_tables_for_read(thd, table);
thd->pop_internal_handler();
return res;
}
@ -2875,18 +2874,18 @@ int collect_statistics_for_table(THD *thd, TABLE *table)
int update_statistics_for_table(THD *thd, TABLE *table)
{
TABLE_LIST tables[STATISTICS_TABLES];
Open_tables_backup open_tables_backup;
uint i;
int err;
enum_binlog_format save_binlog_format;
int rc= 0;
TABLE *stat_table;
DBUG_ENTER("update_statistics_for_table");
DEBUG_SYNC(thd, "statistics_update_start");
if (open_stat_tables(thd, tables, &open_tables_backup, TRUE))
start_new_trans new_trans(thd);
if (open_stat_tables(thd, tables, TRUE))
DBUG_RETURN(rc);
save_binlog_format= thd->set_current_stmt_binlog_format_stmt();
@ -2936,8 +2935,9 @@ int update_statistics_for_table(THD *thd, TABLE *table)
}
thd->restore_stmt_binlog_format(save_binlog_format);
close_system_tables(thd, &open_tables_backup);
if (thd->commit_whole_transaction_and_close_tables())
rc= 1;
new_trans.restore_old_transaction();
DBUG_RETURN(rc);
}
@ -3291,7 +3291,6 @@ int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables)
int read_statistics_for_tables(THD *thd, TABLE_LIST *tables)
{
TABLE_LIST stat_tables[STATISTICS_TABLES];
Open_tables_backup open_tables_backup;
DBUG_ENTER("read_statistics_for_tables");
@ -3332,7 +3331,9 @@ int read_statistics_for_tables(THD *thd, TABLE_LIST *tables)
if (!statistics_for_tables_is_needed(thd, tables))
DBUG_RETURN(0);
if (open_stat_tables(thd, stat_tables, &open_tables_backup, FALSE))
start_new_trans new_trans(thd);
if (open_stat_tables(thd, stat_tables, FALSE))
DBUG_RETURN(1);
for (TABLE_LIST *tl= tables; tl; tl= tl->next_global)
@ -3364,7 +3365,8 @@ int read_statistics_for_tables(THD *thd, TABLE_LIST *tables)
}
}
close_system_tables(thd, &open_tables_backup);
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
DBUG_RETURN(0);
}
@ -3404,8 +3406,10 @@ int delete_statistics_for_table(THD *thd, const LEX_CSTRING *db,
Open_tables_backup open_tables_backup;
int rc= 0;
DBUG_ENTER("delete_statistics_for_table");
start_new_trans new_trans(thd);
if (open_stat_tables(thd, tables, &open_tables_backup, TRUE))
if (open_stat_tables(thd, tables, TRUE))
DBUG_RETURN(0);
save_binlog_format= thd->set_current_stmt_binlog_format_stmt();
@ -3448,8 +3452,8 @@ int delete_statistics_for_table(THD *thd, const LEX_CSTRING *db,
rc= 1;
thd->restore_stmt_binlog_format(save_binlog_format);
close_system_tables(thd, &open_tables_backup);
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
DBUG_RETURN(rc);
}
@ -3481,12 +3485,12 @@ int delete_statistics_for_column(THD *thd, TABLE *tab, Field *col)
enum_binlog_format save_binlog_format;
TABLE *stat_table;
TABLE_LIST tables;
Open_tables_backup open_tables_backup;
int rc= 0;
DBUG_ENTER("delete_statistics_for_column");
if (open_stat_table_for_ddl(thd, &tables, &stat_table_name[1],
&open_tables_backup))
start_new_trans new_trans(thd);
if (open_stat_table_for_ddl(thd, &tables, &stat_table_name[1]))
DBUG_RETURN(0);
save_binlog_format= thd->set_current_stmt_binlog_format_stmt();
@ -3502,8 +3506,9 @@ int delete_statistics_for_column(THD *thd, TABLE *tab, Field *col)
}
thd->restore_stmt_binlog_format(save_binlog_format);
close_system_tables(thd, &open_tables_backup);
if (thd->commit_whole_transaction_and_close_tables())
rc= 1;
new_trans.restore_old_transaction();
DBUG_RETURN(rc);
}
@ -3538,12 +3543,12 @@ int delete_statistics_for_index(THD *thd, TABLE *tab, KEY *key_info,
enum_binlog_format save_binlog_format;
TABLE *stat_table;
TABLE_LIST tables;
Open_tables_backup open_tables_backup;
int rc= 0;
DBUG_ENTER("delete_statistics_for_index");
if (open_stat_table_for_ddl(thd, &tables, &stat_table_name[2],
&open_tables_backup))
start_new_trans new_trans(thd);
if (open_stat_table_for_ddl(thd, &tables, &stat_table_name[2]))
DBUG_RETURN(0);
save_binlog_format= thd->set_current_stmt_binlog_format_stmt();
@ -3579,8 +3584,9 @@ int delete_statistics_for_index(THD *thd, TABLE *tab, KEY *key_info,
rc= 1;
thd->restore_stmt_binlog_format(save_binlog_format);
close_system_tables(thd, &open_tables_backup);
if (thd->commit_whole_transaction_and_close_tables())
rc= 1;
new_trans.restore_old_transaction();
DBUG_RETURN(rc);
}
@ -3622,14 +3628,13 @@ int rename_table_in_stat_tables(THD *thd, const LEX_CSTRING *db,
enum_binlog_format save_binlog_format;
TABLE *stat_table;
TABLE_LIST tables[STATISTICS_TABLES];
Open_tables_backup open_tables_backup;
int rc= 0;
DBUG_ENTER("rename_table_in_stat_tables");
if (open_stat_tables(thd, tables, &open_tables_backup, TRUE))
{
start_new_trans new_trans(thd);
if (open_stat_tables(thd, tables, TRUE))
DBUG_RETURN(0); // not an error
}
save_binlog_format= thd->set_current_stmt_binlog_format_stmt();
@ -3678,8 +3683,9 @@ int rename_table_in_stat_tables(THD *thd, const LEX_CSTRING *db,
}
thd->restore_stmt_binlog_format(save_binlog_format);
close_system_tables(thd, &open_tables_backup);
if (thd->commit_whole_transaction_and_close_tables())
rc= 1;
new_trans.restore_old_transaction();
DBUG_RETURN(rc);
}
@ -3712,15 +3718,15 @@ int rename_column_in_stat_tables(THD *thd, TABLE *tab, Field *col,
enum_binlog_format save_binlog_format;
TABLE *stat_table;
TABLE_LIST tables;
Open_tables_backup open_tables_backup;
int rc= 0;
DBUG_ENTER("rename_column_in_stat_tables");
if (tab->s->tmp_table != NO_TMP_TABLE)
DBUG_RETURN(0);
if (open_stat_table_for_ddl(thd, &tables, &stat_table_name[1],
&open_tables_backup))
start_new_trans new_trans(thd);
if (open_stat_table_for_ddl(thd, &tables, &stat_table_name[1]))
DBUG_RETURN(rc);
save_binlog_format= thd->set_current_stmt_binlog_format_stmt();
@ -3737,8 +3743,9 @@ int rename_column_in_stat_tables(THD *thd, TABLE *tab, Field *col,
}
thd->restore_stmt_binlog_format(save_binlog_format);
close_system_tables(thd, &open_tables_backup);
if (thd->commit_whole_transaction_and_close_tables())
rc= 1;
new_trans.restore_old_transaction();
DBUG_RETURN(rc);
}

4
sql/sql_trigger.cc

@ -590,10 +590,8 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
table->triggers->create_trigger(thd, tables, &stmt_query):
table->triggers->drop_trigger(thd, tables, &stmt_query));
if (result)
goto end;
close_all_tables_for_name(thd, table->s, HA_EXTRA_NOT_USED, NULL);
/*
Reopen the table if we were under LOCK TABLES.
Ignore the return value for now. It's better to

2
sql/sql_truncate.cc

@ -246,7 +246,7 @@ Sql_cmd_truncate_table::handler_truncate(THD *thd, TABLE_LIST *table_ref,
inspite of errors.
*/
if (error == HA_ERR_WRONG_COMMAND ||
table_ref->table->file->has_transactions())
table_ref->table->file->has_transactions_and_rollback())
DBUG_RETURN(TRUNCATE_FAILED_SKIP_BINLOG);
else
DBUG_RETURN(TRUNCATE_FAILED_BUT_BINLOG);

8
sql/sql_update.cc

@ -931,7 +931,7 @@ update_begin:
thd->count_cuted_fields= CHECK_FIELD_WARN;
thd->cuted_fields=0L;
transactional_table= table->file->has_transactions();
transactional_table= table->file->has_transactions_and_rollback();
thd->abort_on_warning= !ignore && thd->is_strict_mode();
if (do_direct_update)
@ -2572,7 +2572,7 @@ int multi_update::send_data(List<Item> &not_used_values)
}
/* non-transactional or transactional table got modified */
/* either multi_update class' flag is raised in its branch */
if (table->file->has_transactions())
if (table->file->has_transactions_and_rollback())
transactional_tables= TRUE;
else
{
@ -2891,7 +2891,7 @@ int multi_update::do_updates()
if (updated != org_updated)
{
if (table->file->has_transactions())
if (table->file->has_transactions_and_rollback())
transactional_tables= TRUE;
else
{
@ -2928,7 +2928,7 @@ err2:
if (updated != org_updated)
{
if (table->file->has_transactions())
if (table->file->has_transactions_and_rollback())
transactional_tables= TRUE;
else
{

13
sql/transaction.cc

@ -73,11 +73,10 @@ static bool trans_check(THD *thd)
if (unlikely(thd->in_sub_stmt))
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
if (thd->transaction->xid_state.is_explicit_XA())
thd->transaction->xid_state.er_xaer_rmfail();
else
if (!thd->transaction->xid_state.is_explicit_XA())
DBUG_RETURN(FALSE);
thd->transaction->xid_state.er_xaer_rmfail();
DBUG_RETURN(TRUE);
}
@ -261,10 +260,10 @@ bool trans_commit(THD *thd)
mysql_mutex_assert_not_owner(&LOCK_after_binlog_sync);
mysql_mutex_assert_not_owner(&LOCK_commit_ordered);
/*
if res is non-zero, then ha_commit_trans has rolled back the
transaction, so the hooks for rollback will be called.
*/
/*
if res is non-zero, then ha_commit_trans has rolled back the
transaction, so the hooks for rollback will be called.
*/
#ifdef HAVE_REPLICATION
if (res)
repl_semisync_master.wait_after_rollback(thd, FALSE);

13
sql/tztime.cc

@ -2330,16 +2330,21 @@ my_tz_find(THD *thd, const String *name)
else if (time_zone_tables_exist)
{
TABLE_LIST tz_tables[MY_TZ_TABLES_COUNT];
Open_tables_backup open_tables_state_backup;
/*
Allocate start_new_trans with malloc as it's > 4000 bytes and this
function can be called deep inside a stored procedure
*/
start_new_trans *new_trans= new start_new_trans(thd);
tz_init_table_list(tz_tables);
init_mdl_requests(tz_tables);
if (!open_system_tables_for_read(thd, tz_tables,
&open_tables_state_backup))
if (!open_system_tables_for_read(thd, tz_tables))
{
result_tz= tz_load_from_open_tables(name, tz_tables);
close_system_tables(thd, &open_tables_state_backup);
thd->commit_whole_transaction_and_close_tables();
}
new_trans->restore_old_transaction();
delete new_trans;
}
}

95
storage/maria/ha_maria.cc

@ -50,12 +50,12 @@ C_MODE_END
Note that in future versions, only *transactional* Maria tables can
rollback, so this flag should be up or down conditionally.
*/
#ifdef MARIA_CANNOT_ROLLBACK
#define CANNOT_ROLLBACK_FLAG HA_NO_TRANSACTIONS
#define trans_register_ha(A, B, C) do { /* nothing */ } while(0)
#ifdef ARIA_HAS_TRANSACTIONS
#define TRANSACTION_STATE
#else
#define CANNOT_ROLLBACK_FLAG 0
#define TRANSACTION_STATE HA_NO_TRANSACTIONS
#endif
#define THD_TRN (TRN*) thd_get_ha_data(thd, maria_hton)
ulong pagecache_division_limit, pagecache_age_threshold, pagecache_file_hash_size;
@ -964,12 +964,12 @@ static int maria_create_trn_for_mysql(MARIA_HA *info)
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
thd_set_ha_data(thd, maria_hton, trn);
if (thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
trans_register_ha(thd, TRUE, maria_hton);
trans_register_ha(thd, TRUE, maria_hton, trn->trid);
}
_ma_set_trn_for_table(info, trn);
if (!trnman_increment_locked_tables(trn))
{
trans_register_ha(thd, FALSE, maria_hton);
trans_register_ha(thd, FALSE, maria_hton, trn->trid);
trnman_new_statement(trn);
}
#ifdef EXTRA_DEBUG
@ -1020,7 +1020,7 @@ handler(hton, table_arg), file(0),
int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
HA_FILE_BASED | HA_CAN_GEOMETRY | CANNOT_ROLLBACK_FLAG |
HA_FILE_BASED | HA_CAN_GEOMETRY | TRANSACTION_STATE |
HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS | HA_CAN_REPAIR |
HA_CAN_VIRTUAL_COLUMNS | HA_CAN_EXPORT |
HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT |
@ -1185,7 +1185,7 @@ int ha_maria::open(const char *name, int mode, uint test_if_locked)
client doing INSERT DELAYED knows the specificities; but we then should
make sure to regularly commit in the delayed_insert thread).
*/
int_table_flags|= HA_CAN_INSERT_DELAYED;
int_table_flags|= HA_CAN_INSERT_DELAYED | HA_NO_TRANSACTIONS;
}
if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
int_table_flags |= HA_HAS_NEW_CHECKSUM;
@ -2745,6 +2745,7 @@ void ha_maria::change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
int ha_maria::external_lock(THD *thd, int lock_type)
{
int result= 0, result2;
DBUG_ENTER("ha_maria::external_lock");
file->external_ref= (void*) table; // For ma_killed()
/*
@ -2785,7 +2786,19 @@ int ha_maria::external_lock(THD *thd, int lock_type)
*/
DBUG_PRINT("info", ("Disabling logging for table"));
_ma_tmp_disable_logging_for_table(file, TRUE);
file->autocommit= 0;
}
else
file->autocommit= !(thd->variables.option_bits &
(OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
#ifndef ARIA_HAS_TRANSACTIONS
/*
Until Aria has full transactions support, including MVCC support for
delete and update and purging of old states, we have to commit for
every statement.
*/
file->autocommit=1;
#endif
}
else
{
@ -2827,27 +2840,27 @@ int ha_maria::external_lock(THD *thd, int lock_type)
*/
DBUG_ASSERT(!thd->get_stmt_da()->is_sent() ||
thd->killed);
/* autocommit ? rollback a transaction */
#ifdef MARIA_CANNOT_ROLLBACK
if (ma_commit(trn))
DBUG_RETURN(1);
thd_set_ha_data(thd, maria_hton, 0);
#else
if (!(thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
/*
If autocommit, commit transaction. This can happen when open and
lock tables as part of creating triggers, in which case commit
is not called.
Until ARIA_HAS_TRANSACTIONS is not defined, always commit.
*/
if (file->autocommit)
{
trnman_rollback_trn(trn);
DBUG_PRINT("info", ("THD_TRN set to 0x0"));
if (ma_commit(trn))
result= HA_ERR_INTERNAL_ERROR;
thd_set_ha_data(thd, maria_hton, 0);
}
#endif
}
trnman_set_flags(trn, trnman_get_flags(trn) & ~ TRN_STATE_INFO_LOGGED);
}
}
} /* if transactional table */
int result = maria_lock_database(file, !table->s->tmp_table ?
lock_type : ((lock_type == F_UNLCK) ?
F_UNLCK : F_EXTRA_LCK));
if ((result2= maria_lock_database(file, !table->s->tmp_table ?
lock_type : ((lock_type == F_UNLCK) ?
F_UNLCK : F_EXTRA_LCK))))
result= result2;
if (!file->s->base.born_transactional)
file->state= &file->s->state.state; // Restore state if clone
@ -3401,22 +3414,46 @@ static int maria_commit(handlerton *hton __attribute__ ((unused)),
{
TRN *trn= THD_TRN;
int res;
MARIA_HA *used_instances= (MARIA_HA*) trn->used_instances;
MARIA_HA *used_instances;
DBUG_ENTER("maria_commit");
DBUG_ASSERT(trnman_has_locked_tables(trn) == 0);
trnman_reset_locked_tables(trn, 0);
trnman_set_flags(trn, trnman_get_flags(trn) & ~TRN_STATE_INFO_LOGGED);
/* No commit inside lock_tables() */
if ((!trn ||
thd->locked_tables_mode == LTM_LOCK_TABLES ||
thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES))
DBUG_RETURN(0);
/* statement or transaction ? */
if ((thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
!all)
DBUG_RETURN(0); // end of statement
used_instances= (MARIA_HA*) trn->used_instances;
trnman_reset_locked_tables(trn, 0);
trnman_set_flags(trn, trnman_get_flags(trn) & ~TRN_STATE_INFO_LOGGED);
trn->used_instances= 0;
res= ma_commit(trn);
reset_thd_trn(thd, used_instances);
thd_set_ha_data(thd, maria_hton, 0);
DBUG_RETURN(res);
}
#ifdef MARIA_CANNOT_ROLLBACK
static int maria_rollback(handlerton *hton, THD *thd, bool all)
{
TRN *trn= THD_TRN;
DBUG_ENTER("maria_rollback");
if (!trn)
DBUG_RETURN(0);
if (trn->undo_lsn)
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_DATA_WAS_COMMITED_UNDER_ROLLBACK,
ER_THD(thd, ER_DATA_WAS_COMMITED_UNDER_ROLLBACK),
"Aria");
DBUG_RETURN(maria_commit(hton, thd, all));
}
#else
static int maria_rollback(handlerton *hton __attribute__ ((unused)),
THD *thd, bool all)
@ -3437,7 +3474,7 @@ static int maria_rollback(handlerton *hton __attribute__ ((unused)),
DBUG_RETURN(trnman_rollback_trn(trn) ?
HA_ERR_OUT_OF_MEM : 0); // end of transaction
}
#endif /* MARIA_CANNOT_ROLLBACK */
/**
@ -3681,16 +3718,14 @@ static int ha_maria_init(void *p)
maria_hton->commit= maria_commit;
maria_hton->rollback= maria_rollback;
maria_hton->checkpoint_state= maria_checkpoint_state;
#ifdef MARIA_CANNOT_ROLLBACK
maria_hton->commit= 0;
#endif
maria_hton->flush_logs= maria_flush_logs;
maria_hton->show_status= maria_show_status;
maria_hton->prepare_for_backup= maria_prepare_for_backup;
maria_hton->end_backup= maria_end_backup;
/* TODO: decide if we support Maria being used for log tables */
maria_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
maria_hton->flags= (HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES |
HTON_NO_ROLLBACK);
bzero(maria_log_pagecache, sizeof(*maria_log_pagecache));
maria_tmpdir= &mysql_tmpdir_list; /* For REDO */

5
storage/maria/ma_checkpoint.c

@ -1218,10 +1218,9 @@ err:
MARIA_SHARE *share= distinct_shares[i];
if (share->in_checkpoint & MARIA_CHECKPOINT_SHOULD_FREE_ME)
{
share->in_checkpoint&= ~MARIA_CHECKPOINT_SHOULD_FREE_ME;
/* maria_close() left us to free the share */
mysql_mutex_destroy(&share->intern_lock);
ma_crypt_free(share);
my_free(share);
free_maria_share(share);
}
else
{

64
storage/maria/ma_close.c

@ -29,7 +29,6 @@
int maria_close(register MARIA_HA *info)
{
int error=0,flag;
my_bool share_can_be_freed= FALSE;
MARIA_SHARE *share= info->s;
my_bool internal_table= share->internal_table;
DBUG_ENTER("maria_close");
@ -95,12 +94,16 @@ int maria_close(register MARIA_HA *info)
if (flag)
{
/* Last close of file; Flush everything */
/* Last close of file */
/* Check that we don't have any dangling pointers from the transaction */
DBUG_ASSERT(share->in_trans == 0);
/*
Check that we don't have any dangling open files
We may still have some open transactions. In this case the share
will be kept around until the transaction has closed
*/
DBUG_ASSERT(share->open_list == 0);
/* Flush everything */
if (share->kfile.file >= 0)
{
my_bool save_global_changed= share->global_changed;
@ -199,8 +202,6 @@ int maria_close(register MARIA_HA *info)
/* we cannot my_free() the share, Checkpoint would see a bad pointer */
share->in_checkpoint|= MARIA_CHECKPOINT_SHOULD_FREE_ME;
}
else
share_can_be_freed= TRUE;
if (share->state_history)
{
@ -232,23 +233,12 @@ int maria_close(register MARIA_HA *info)
if (!internal_table)
{
mysql_mutex_unlock(&THR_LOCK_maria);
mysql_mutex_unlock(&share->intern_lock);
mysql_mutex_unlock(&share->close_lock);
}
if (share_can_be_freed)
{
ma_crypt_free(share);
my_free(share->s3_path);
(void) mysql_mutex_destroy(&share->intern_lock);
(void) mysql_mutex_destroy(&share->close_lock);
(void) mysql_cond_destroy(&share->key_del_cond);
my_free(share);
/*
If share cannot be freed, it's because checkpoint has previously
recorded to include this share in the checkpoint and so is soon going to
look at some of its content (share->in_checkpoint/id/last_version).
*/
}
/* free_maria_share will free share->internal_lock */
free_maria_share(share);
my_free(info->ftparser_param);
if (info->dfile.file >= 0 && ! info->s3)
{
@ -274,3 +264,35 @@ int maria_close(register MARIA_HA *info)
}
DBUG_RETURN(0);
} /* maria_close */
/**
Free Aria table share
Note that share will not be freed a long as there are active checkpoints
or transactions pointing at the shared object
*/
void free_maria_share(MARIA_SHARE *share)
{
if (!share->internal_table)
mysql_mutex_assert_owner(&share->intern_lock);
if (!share->reopen && !share->in_trans &&
!(share->in_checkpoint & MARIA_CHECKPOINT_SHOULD_FREE_ME))
{
/* No one can access this share anymore, time to delete it ! */
if (!share->internal_table)
mysql_mutex_unlock(&share->intern_lock);
ma_crypt_free(share);
my_free(share->s3_path);
(void) mysql_mutex_destroy(&share->intern_lock);
(void) mysql_mutex_destroy(&share->close_lock);
(void) mysql_cond_destroy(&share->key_del_cond);
my_free(share);
return;
}
if (!share->internal_table)
mysql_mutex_unlock(&share->intern_lock);
return;
}

4
storage/maria/ma_open.c

@ -90,7 +90,6 @@ MARIA_HA *_ma_test_if_reopen(const char *filename)
0 Error
*/
static MARIA_HA *maria_clone_internal(MARIA_SHARE *share,
int mode, File data_file,
uint internal_table,
@ -152,7 +151,8 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share,
info.last_loop= share->state.update_count;
#endif
info.errkey= -1;
info.page_changed=1;
info.page_changed= 1;
info.autocommit= 1;
info.keyread_buff= info.buff + share->base.max_key_block_length;
info.lock_type= F_UNLCK;

22
storage/maria/ma_state.c

@ -535,20 +535,17 @@ my_bool _ma_trnman_end_trans_hook(TRN *trn, my_bool commit,
share, share->in_trans));
}
}
share->in_trans--;
mysql_mutex_unlock(&share->intern_lock);
/* The following calls frees &share->intern_lock */
decrement_share_in_trans(share);
}
else
{
#ifdef DBUG_ASSERT_EXISTS
/*
We need to keep share->in_trans correct in the debug library
because of the assert in maria_close()
We need to keep share->in_trans correct because of the check
in free_maria_share()
*/
mysql_mutex_lock(&share->intern_lock);
share->in_trans--;
mysql_mutex_unlock(&share->intern_lock);
#endif
decrement_share_in_trans(share);
}
my_free(tables);
}
@ -590,6 +587,10 @@ void _ma_remove_table_from_trnman(MARIA_HA *info)
if (tables->share == share)
{
*prev= tables->next;
/*
We don't have to and can't call decrement_share_in_trans(share) here
as we know there is an active MARIA_HA handler around.
*/
share->in_trans--;
my_free(tables);
break;
@ -635,9 +636,10 @@ void _ma_block_get_status(void* param, my_bool concurrent_insert)
info->row_base_length= info->s->base_length;
info->row_flag= info->s->base.default_row_flag;
if (concurrent_insert)
DBUG_ASSERT(!concurrent_insert ||
info->lock.type == TL_WRITE_CONCURRENT_INSERT);
if (concurrent_insert || !info->autocommit)
{
DBUG_ASSERT(info->lock.type == TL_WRITE_CONCURRENT_INSERT);
info->row_flag|= ROW_FLAG_TRANSID;
info->row_base_length+= TRANSID_SIZE;
}

13
storage/maria/maria_def.h

@ -724,6 +724,8 @@ struct st_maria_handler
my_bool once_flags; /* For MARIA_MRG */
/* For bulk insert enable/disable transactions control */
my_bool switched_transactional;
/* If transaction will autocommit */
my_bool autocommit;
#ifdef _WIN32
my_bool owned_by_merge; /* This Maria table is part of a merge union */
#endif
@ -1466,6 +1468,7 @@ extern my_bool ma_yield_and_check_if_killed(MARIA_HA *info, int inx);
extern my_bool ma_killed_standalone(MARIA_HA *);
extern uint _ma_file_callback_to_id(void *callback_data);
extern void free_maria_share(MARIA_SHARE *share);
static inline void unmap_file(MARIA_HA *info __attribute__((unused)))
{
@ -1474,4 +1477,14 @@ static inline void unmap_file(MARIA_HA *info __attribute__((unused)))
_ma_unmap_file(info);
#endif
}
static inline void decrement_share_in_trans(MARIA_SHARE *share)
{
/* Internal tables doesn't have transactions */
DBUG_ASSERT(!share->internal_table);
if (!--share->in_trans)
free_maria_share(share);
else
mysql_mutex_unlock(&share->intern_lock);
}
C_MODE_END

2
storage/spider/spd_db_conn.cc

@ -10189,7 +10189,7 @@ int spider_db_udf_direct_sql(
if (direct_sql->real_table_used)
{
if (spider_sys_open_tables(c_thd, &direct_sql->table_list_first,
&direct_sql->open_tables_backup))
&direct_sql->open_tables_backup))
{
direct_sql->real_table_used = FALSE;
DBUG_RETURN(my_errno);

17
storage/spider/spd_sys_table.cc

@ -584,7 +584,8 @@ void spider_sys_close_table(
) {
DBUG_ENTER("spider_sys_close_table");
close_thread_tables(thd);
thd->restore_backup_open_tables_state(open_tables_backup);
if (open_tables_backup)
thd->restore_backup_open_tables_state(open_tables_backup);
DBUG_VOID_RETURN;
}
#endif
@ -3294,15 +3295,15 @@ int spider_sys_get_table_crd(
TABLE *table_crd = NULL;
#if MYSQL_VERSION_ID < 50500
Open_tables_state open_tables_backup;
#else
Open_tables_backup open_tables_backup;
#endif
DBUG_ENTER("spider_sys_get_table_crd");
start_new_trans new_trans(thd);
if (
!(table_crd = spider_open_sys_table(
thd, SPIDER_SYS_TABLE_CRD_TABLE_NAME_STR,
SPIDER_SYS_TABLE_CRD_TABLE_NAME_LEN, TRUE,
&open_tables_backup, need_lock, &error_num))
0, need_lock, &error_num))
) {
goto error;
}
@ -3335,15 +3336,17 @@ int spider_sys_get_table_crd(
goto error;
}
spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock);
table_crd = NULL;
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
DBUG_RETURN(0);
error:
if (index_inited)
spider_sys_index_end(table_crd);
if (table_crd)
spider_close_sys_table(thd, table_crd, &open_tables_backup, need_lock);
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
DBUG_RETURN(error_num);
}

41
storage/spider/spd_table.cc

@ -4731,10 +4731,12 @@ SPIDER_SHARE *spider_get_share(
{
SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
init_mem_root = TRUE;
start_new_trans new_trans(thd);
if (
!(table_tables = spider_open_sys_table(
thd, SPIDER_SYS_TABLES_TABLE_NAME_STR,
SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE, &open_tables_backup,
SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE, 0,
FALSE, error_num))
) {
for (roop_count = 0;
@ -4771,21 +4773,19 @@ SPIDER_SHARE *spider_get_share(
share->init_error_time = (time_t) time((time_t*) 0);
share->init = TRUE;
spider_free_share(share);
goto error_get_link_statuses;
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
goto error_open_sys_table;
}
} else {
memcpy(share->alter_table.tmp_link_statuses, share->link_statuses,
sizeof(long) * share->all_link_count);
share->link_status_init = TRUE;
}
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
}
share->have_recovery_link = spider_conn_check_recovery_link(share);
if (table_tables)
{
spider_close_sys_table(thd, table_tables,
&open_tables_backup, FALSE);
table_tables = NULL;
}
if (init_mem_root)
{
free_root(&mem_root, MYF(0));
@ -5269,6 +5269,7 @@ SPIDER_SHARE *spider_get_share(
}
if (!share->link_status_init)
{
DBUG_ASSERT(!table_tables);
/*
The link statuses need to be refreshed from the spider_tables table
if the operation:
@ -5285,10 +5286,12 @@ SPIDER_SHARE *spider_get_share(
{
SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME));
init_mem_root = TRUE;
start_new_trans new_trans(thd);
if (
!(table_tables = spider_open_sys_table(
thd, SPIDER_SYS_TABLES_TABLE_NAME_STR,
SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE, &open_tables_backup,
SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE, 0,
FALSE, error_num))
) {
for (roop_count = 0;
@ -5319,21 +5322,20 @@ SPIDER_SHARE *spider_get_share(
}
pthread_mutex_unlock(&share->mutex);
spider_free_share(share);
goto error_get_link_statuses;
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
goto error_open_sys_table;
}
} else {
memcpy(share->alter_table.tmp_link_statuses, share->link_statuses,
sizeof(long) * share->all_link_count);
share->link_status_init = TRUE;
}
thd->commit_whole_transaction_and_close_tables();
new_trans.restore_old_transaction();
table_tables= 0;
}
share->have_recovery_link = spider_conn_check_recovery_link(share);
if (table_tables)
{
spider_close_sys_table(thd, table_tables,
&open_tables_backup, FALSE);
table_tables = NULL;
}
if (init_mem_root)
{
free_root(&mem_root, MYF(0));
@ -5776,13 +5778,6 @@ error_hash_insert:
spider_free_share_resource_only(share);
error_alloc_share:
pthread_mutex_unlock(&spider_tbl_mutex);
error_get_link_statuses:
if (table_tables)
{
spider_close_sys_table(thd, table_tables,
&open_tables_backup, FALSE);
table_tables = NULL;
}
error_open_sys_table:
#ifndef WITHOUT_SPIDER_BG_SEARCH
error_crd_spider_init:

Loading…
Cancel
Save