diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-11-25 08:10:02 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-11-25 08:10:02 +0200 |
commit | 5f160b4d864866e30f49bac2ee4f51b4cf530a86 (patch) | |
tree | 13ed4a2912991add08ee2035570595235c146493 | |
parent | 80834a8f5d0bbaefd98baac6399321bb2e06e97c (diff) | |
parent | 3cfbfa58de20057c07ddcc066b6eb4956f77c9e1 (diff) | |
download | mariadb-git-5f160b4d864866e30f49bac2ee4f51b4cf530a86.tar.gz |
Merge 10.6 into 10.7
27 files changed, 1066 insertions, 176 deletions
diff --git a/debian/additions/mariadb.conf.d/50-server.cnf b/debian/additions/mariadb.conf.d/50-server.cnf index 6bbb995c4b9..728ca23178b 100644 --- a/debian/additions/mariadb.conf.d/50-server.cnf +++ b/debian/additions/mariadb.conf.d/50-server.cnf @@ -12,14 +12,11 @@ # * Basic Settings # -user = mysql +#user = mysql pid-file = /run/mysqld/mysqld.pid basedir = /usr -datadir = /var/lib/mysql -tmpdir = /tmp -lc-messages-dir = /usr/share/mysql -lc-messages = en_US -skip-external-locking +#datadir = /var/lib/mysql +#tmpdir = /tmp # Broken reverse DNS slows down connections considerably and name resolve is # safe to skip if there are no "host by domain name" access grants diff --git a/mysql-test/suite/galera/r/galera_log_bin_ext.result b/mysql-test/suite/galera/r/galera_log_bin_ext.result new file mode 100644 index 00000000000..58e13fb71a0 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_log_bin_ext.result @@ -0,0 +1,80 @@ +connection node_2; +connection node_1; +connection node_1; +set global wsrep_on=OFF; +reset master; +set global wsrep_on=ON; +connection node_2; +set global wsrep_on=OFF; +reset master; +set global wsrep_on=ON; +CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +CREATE TABLE t2 (id INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1); +INSERT INTO t2 VALUES (1); +connection node_2; +SELECT COUNT(*) = 1 FROM t1; +COUNT(*) = 1 +1 +SELECT COUNT(*) = 2 FROM t2; +COUNT(*) = 2 +1 +connection node_1; +ALTER TABLE t1 ADD COLUMN f2 INTEGER; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +hostname1-bin.000001 # Gtid # # GTID #-#-# +hostname1-bin.000001 # Query # # use `test`; CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB +hostname1-bin.000001 # Gtid # # BEGIN GTID #-#-# +hostname1-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES (1) +hostname1-bin.000001 # Table_map # # table_id: # (test.t1) +hostname1-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +hostname1-bin.000001 # Xid # # COMMIT /* XID */ +hostname1-bin.000001 # Gtid # # GTID #-#-# +hostname1-bin.000001 # Query # # use `test`; CREATE TABLE t2 (id INT) ENGINE=InnoDB +hostname1-bin.000001 # Gtid # # BEGIN GTID #-#-# +hostname1-bin.000001 # Annotate_rows # # INSERT INTO t2 VALUES (1) +hostname1-bin.000001 # Table_map # # table_id: # (test.t2) +hostname1-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +hostname1-bin.000001 # Xid # # COMMIT /* XID */ +hostname1-bin.000001 # Gtid # # BEGIN GTID #-#-# +hostname1-bin.000001 # Annotate_rows # # INSERT INTO t2 VALUES (1) +hostname1-bin.000001 # Table_map # # table_id: # (test.t2) +hostname1-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +hostname1-bin.000001 # Xid # # COMMIT /* XID */ +hostname1-bin.000001 # Gtid # # GTID #-#-# +hostname1-bin.000001 # Query # # use `test`; ALTER TABLE t1 ADD COLUMN f2 INTEGER +connection node_2; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +hostname1-bin.000001 # Gtid # # GTID #-#-# +hostname1-bin.000001 # Query # # use `test`; CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB +hostname1-bin.000001 # Gtid # # BEGIN GTID #-#-# +hostname1-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES (1) +hostname1-bin.000001 # Table_map # # table_id: # (test.t1) +hostname1-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +hostname1-bin.000001 # Xid # # COMMIT /* XID */ +hostname1-bin.000001 # Gtid # # GTID #-#-# +hostname1-bin.000001 # Query # # use `test`; CREATE TABLE t2 (id INT) ENGINE=InnoDB +hostname1-bin.000001 # Gtid # # BEGIN GTID #-#-# +hostname1-bin.000001 # Annotate_rows # # INSERT INTO t2 VALUES (1) +hostname1-bin.000001 # Table_map # # table_id: # (test.t2) +hostname1-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +hostname1-bin.000001 # Xid # # COMMIT /* XID */ +hostname1-bin.000001 # Gtid # # BEGIN GTID #-#-# +hostname1-bin.000001 # Annotate_rows # # INSERT INTO t2 VALUES (1) +hostname1-bin.000001 # Table_map # # table_id: # (test.t2) +hostname1-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +hostname1-bin.000001 # Xid # # COMMIT /* XID */ +hostname1-bin.000001 # Gtid # # GTID #-#-# +hostname1-bin.000001 # Query # # use `test`; ALTER TABLE t1 ADD COLUMN f2 INTEGER +DROP TABLE t1; +DROP TABLE t2; +#cleanup +connection node_1; +SET GLOBAL wsrep_on=OFF; +RESET MASTER; diff --git a/mysql-test/suite/galera/r/galera_sst_mariabackup_force_recovery,debug.rdiff b/mysql-test/suite/galera/r/galera_sst_mariabackup_force_recovery,debug.rdiff new file mode 100644 index 00000000000..bad8355b514 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_sst_mariabackup_force_recovery,debug.rdiff @@ -0,0 +1,192 @@ +--- r/galera_sst_mariabackup.result 2021-04-10 14:25:04.142716409 +0300 ++++ r/galera_sst_mariabackup,debug.reject 2021-04-10 14:53:30.033162191 +0300 +@@ -516,5 +516,189 @@ + 1 + DROP TABLE t1; + COMMIT; ++Performing State Transfer on a server that has been killed and restarted ++while a DDL was in progress on it ++connection node_1; ++CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB; ++SET AUTOCOMMIT=OFF; ++START TRANSACTION; ++INSERT INTO t1 VALUES (1,'node1_committed_before'); ++INSERT INTO t1 VALUES (2,'node1_committed_before'); ++INSERT INTO t1 VALUES (3,'node1_committed_before'); ++INSERT INTO t1 VALUES (4,'node1_committed_before'); ++INSERT INTO t1 VALUES (5,'node1_committed_before'); ++connection node_2; ++START TRANSACTION; ++INSERT INTO t1 VALUES (6,'node2_committed_before'); ++INSERT INTO t1 VALUES (7,'node2_committed_before'); ++INSERT INTO t1 VALUES (8,'node2_committed_before'); ++INSERT INTO t1 VALUES (9,'node2_committed_before'); ++INSERT INTO t1 VALUES (10,'node2_committed_before'); ++COMMIT; ++SET GLOBAL debug_dbug = 'd,sync.alter_opened_table'; ++connection node_1; ++ALTER TABLE t1 ADD COLUMN f2 INTEGER; ++connection node_2; ++SET wsrep_sync_wait = 0; ++Killing server ... ++connection node_1; ++SET AUTOCOMMIT=OFF; ++START TRANSACTION; ++INSERT INTO t1 (id,f1) VALUES (11,'node1_committed_during'); ++INSERT INTO t1 (id,f1) VALUES (12,'node1_committed_during'); ++INSERT INTO t1 (id,f1) VALUES (13,'node1_committed_during'); ++INSERT INTO t1 (id,f1) VALUES (14,'node1_committed_during'); ++INSERT INTO t1 (id,f1) VALUES (15,'node1_committed_during'); ++COMMIT; ++START TRANSACTION; ++INSERT INTO t1 (id,f1) VALUES (16,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (17,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (18,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (19,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (20,'node1_to_be_committed_after'); ++connect node_1a_galera_st_kill_slave_ddl, 127.0.0.1, root, , test, $NODE_MYPORT_1; ++SET AUTOCOMMIT=OFF; ++START TRANSACTION; ++INSERT INTO t1 (id,f1) VALUES (21,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (22,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (23,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (24,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (25,'node1_to_be_rollbacked_after'); ++connection node_2; ++Performing --wsrep-recover ... ++connection node_2; ++Starting server ... ++Using --wsrep-start-position when starting mysqld ... ++SET AUTOCOMMIT=OFF; ++START TRANSACTION; ++INSERT INTO t1 (id,f1) VALUES (26,'node2_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (27,'node2_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (28,'node2_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (29,'node2_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (30,'node2_committed_after'); ++COMMIT; ++connection node_1; ++INSERT INTO t1 (id,f1) VALUES (31,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (32,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (33,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (34,'node1_to_be_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (35,'node1_to_be_committed_after'); ++COMMIT; ++SET AUTOCOMMIT=OFF; ++START TRANSACTION; ++INSERT INTO t1 (id,f1) VALUES (36,'node1_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (37,'node1_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (38,'node1_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (39,'node1_committed_after'); ++INSERT INTO t1 (id,f1) VALUES (40,'node1_committed_after'); ++COMMIT; ++connection node_1a_galera_st_kill_slave_ddl; ++INSERT INTO t1 (id,f1) VALUES (41,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (42,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (43,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (44,'node1_to_be_rollbacked_after'); ++INSERT INTO t1 (id,f1) VALUES (45,'node1_to_be_rollbacked_after'); ++ROLLBACK; ++SET AUTOCOMMIT=ON; ++SET SESSION wsrep_sync_wait=15; ++SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; ++EXPECT_3 ++3 ++SELECT COUNT(*) AS EXPECT_35 FROM t1; ++EXPECT_35 ++35 ++SELECT * FROM t1; ++id f1 f2 ++1 node1_committed_before NULL ++2 node1_committed_before NULL ++3 node1_committed_before NULL ++4 node1_committed_before NULL ++5 node1_committed_before NULL ++6 node2_committed_before NULL ++7 node2_committed_before NULL ++8 node2_committed_before NULL ++9 node2_committed_before NULL ++10 node2_committed_before NULL ++11 node1_committed_during NULL ++12 node1_committed_during NULL ++13 node1_committed_during NULL ++14 node1_committed_during NULL ++15 node1_committed_during NULL ++16 node1_to_be_committed_after NULL ++17 node1_to_be_committed_after NULL ++18 node1_to_be_committed_after NULL ++19 node1_to_be_committed_after NULL ++20 node1_to_be_committed_after NULL ++26 node2_committed_after NULL ++27 node2_committed_after NULL ++28 node2_committed_after NULL ++29 node2_committed_after NULL ++30 node2_committed_after NULL ++31 node1_to_be_committed_after NULL ++32 node1_to_be_committed_after NULL ++33 node1_to_be_committed_after NULL ++34 node1_to_be_committed_after NULL ++35 node1_to_be_committed_after NULL ++36 node1_committed_after NULL ++37 node1_committed_after NULL ++38 node1_committed_after NULL ++39 node1_committed_after NULL ++40 node1_committed_after NULL ++SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; ++COUNT(*) = 0 ++1 ++COMMIT; ++connection node_1; ++SET AUTOCOMMIT=ON; ++SET SESSION wsrep_sync_wait=15; ++SELECT COUNT(*) AS EXPECT_3 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; ++EXPECT_3 ++3 ++SELECT COUNT(*) AS EXPECT_35 FROM t1; ++EXPECT_35 ++35 ++SELECT * FROM t1; ++id f1 f2 ++1 node1_committed_before NULL ++2 node1_committed_before NULL ++3 node1_committed_before NULL ++4 node1_committed_before NULL ++5 node1_committed_before NULL ++6 node2_committed_before NULL ++7 node2_committed_before NULL ++8 node2_committed_before NULL ++9 node2_committed_before NULL ++10 node2_committed_before NULL ++11 node1_committed_during NULL ++12 node1_committed_during NULL ++13 node1_committed_during NULL ++14 node1_committed_during NULL ++15 node1_committed_during NULL ++16 node1_to_be_committed_after NULL ++17 node1_to_be_committed_after NULL ++18 node1_to_be_committed_after NULL ++19 node1_to_be_committed_after NULL ++20 node1_to_be_committed_after NULL ++26 node2_committed_after NULL ++27 node2_committed_after NULL ++28 node2_committed_after NULL ++29 node2_committed_after NULL ++30 node2_committed_after NULL ++31 node1_to_be_committed_after NULL ++32 node1_to_be_committed_after NULL ++33 node1_to_be_committed_after NULL ++34 node1_to_be_committed_after NULL ++35 node1_to_be_committed_after NULL ++36 node1_committed_after NULL ++37 node1_committed_after NULL ++38 node1_committed_after NULL ++39 node1_committed_after NULL ++40 node1_committed_after NULL ++SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; ++COUNT(*) = 0 ++1 ++DROP TABLE t1; ++COMMIT; ++SET GLOBAL debug_dbug = $debug_orig; + disconnect node_2; + disconnect node_1; diff --git a/mysql-test/suite/galera/r/galera_sst_mariabackup_force_recovery.result b/mysql-test/suite/galera/r/galera_sst_mariabackup_force_recovery.result new file mode 100644 index 00000000000..caf602c017c --- /dev/null +++ b/mysql-test/suite/galera/r/galera_sst_mariabackup_force_recovery.result @@ -0,0 +1,520 @@ +connection node_2; +connection node_1; +connection node_1; +connection node_2; +Performing State Transfer on a server that has been shut down cleanly and restarted +connection node_1; +CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'node1_committed_before'); +INSERT INTO t1 VALUES (2,'node1_committed_before'); +INSERT INTO t1 VALUES (3,'node1_committed_before'); +INSERT INTO t1 VALUES (4,'node1_committed_before'); +INSERT INTO t1 VALUES (5,'node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (6,'node2_committed_before'); +INSERT INTO t1 VALUES (7,'node2_committed_before'); +INSERT INTO t1 VALUES (8,'node2_committed_before'); +INSERT INTO t1 VALUES (9,'node2_committed_before'); +INSERT INTO t1 VALUES (10,'node2_committed_before'); +COMMIT; +Shutting down server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (11,'node1_committed_during'); +INSERT INTO t1 VALUES (12,'node1_committed_during'); +INSERT INTO t1 VALUES (13,'node1_committed_during'); +INSERT INTO t1 VALUES (14,'node1_committed_during'); +INSERT INTO t1 VALUES (15,'node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES (16,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (17,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (18,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (19,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (20,'node1_to_be_committed_after'); +connect node_1a_galera_st_shutdown_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (21,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (22,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (23,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (24,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (25,'node1_to_be_rollbacked_after'); +connection node_2; +Starting server ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (26,'node2_committed_after'); +INSERT INTO t1 VALUES (27,'node2_committed_after'); +INSERT INTO t1 VALUES (28,'node2_committed_after'); +INSERT INTO t1 VALUES (29,'node2_committed_after'); +INSERT INTO t1 VALUES (30,'node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES (31,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (32,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (33,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (34,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (35,'node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (36,'node1_committed_after'); +INSERT INTO t1 VALUES (37,'node1_committed_after'); +INSERT INTO t1 VALUES (38,'node1_committed_after'); +INSERT INTO t1 VALUES (39,'node1_committed_after'); +INSERT INTO t1 VALUES (40,'node1_committed_after'); +COMMIT; +connection node_1a_galera_st_shutdown_slave; +INSERT INTO t1 VALUES (41,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (42,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (43,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (44,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (45,'node1_to_be_rollbacked_after'); +ROLLBACK; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_15 FROM t1; +EXPECT_15 +35 +SELECT * from t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +connection node_1; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_15 FROM t1; +EXPECT_15 +35 +SELECT * from t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +Performing State Transfer on a server that starts from a clean var directory +This is accomplished by shutting down node #2 and removing its var directory before restarting it +connection node_1; +CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'node1_committed_before'); +INSERT INTO t1 VALUES (2,'node1_committed_before'); +INSERT INTO t1 VALUES (3,'node1_committed_before'); +INSERT INTO t1 VALUES (4,'node1_committed_before'); +INSERT INTO t1 VALUES (5,'node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (6,'node2_committed_before'); +INSERT INTO t1 VALUES (7,'node2_committed_before'); +INSERT INTO t1 VALUES (8,'node2_committed_before'); +INSERT INTO t1 VALUES (9,'node2_committed_before'); +INSERT INTO t1 VALUES (10,'node2_committed_before'); +COMMIT; +Shutting down server ... +connection node_1; +Cleaning var directory ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (11,'node1_committed_during'); +INSERT INTO t1 VALUES (12,'node1_committed_during'); +INSERT INTO t1 VALUES (13,'node1_committed_during'); +INSERT INTO t1 VALUES (14,'node1_committed_during'); +INSERT INTO t1 VALUES (15,'node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES (16,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (17,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (18,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (19,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (20,'node1_to_be_committed_after'); +connect node_1a_galera_st_clean_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (21,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (22,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (23,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (24,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (25,'node1_to_be_rollbacked_after'); +connection node_2; +Starting server ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (26,'node2_committed_after'); +INSERT INTO t1 VALUES (27,'node2_committed_after'); +INSERT INTO t1 VALUES (28,'node2_committed_after'); +INSERT INTO t1 VALUES (29,'node2_committed_after'); +INSERT INTO t1 VALUES (30,'node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES (31,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (32,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (33,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (34,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (35,'node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (36,'node1_committed_after'); +INSERT INTO t1 VALUES (37,'node1_committed_after'); +INSERT INTO t1 VALUES (38,'node1_committed_after'); +INSERT INTO t1 VALUES (39,'node1_committed_after'); +INSERT INTO t1 VALUES (40,'node1_committed_after'); +COMMIT; +connection node_1a_galera_st_clean_slave; +INSERT INTO t1 VALUES (41,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (42,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (43,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (44,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (45,'node1_to_be_rollbacked_after'); +ROLLBACK; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_35 FROM t1; +EXPECT_35 +35 +SELECT * from t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +connection node_1; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_35 FROM t1; +EXPECT_35 +35 +SELECT * from t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +Performing State Transfer on a server that has been killed and restarted +connection node_1; +CREATE TABLE t1 (id int not null primary key,f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (1,'node1_committed_before'); +INSERT INTO t1 VALUES (2,'node1_committed_before'); +INSERT INTO t1 VALUES (3,'node1_committed_before'); +INSERT INTO t1 VALUES (4,'node1_committed_before'); +INSERT INTO t1 VALUES (5,'node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (6,'node2_committed_before'); +INSERT INTO t1 VALUES (7,'node2_committed_before'); +INSERT INTO t1 VALUES (8,'node2_committed_before'); +INSERT INTO t1 VALUES (9,'node2_committed_before'); +INSERT INTO t1 VALUES (10,'node2_committed_before'); +COMMIT; +Killing server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (11,'node1_committed_during'); +INSERT INTO t1 VALUES (12,'node1_committed_during'); +INSERT INTO t1 VALUES (13,'node1_committed_during'); +INSERT INTO t1 VALUES (14,'node1_committed_during'); +INSERT INTO t1 VALUES (15,'node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES (16,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (17,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (18,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (19,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (20,'node1_to_be_committed_after'); +connect node_1a_galera_st_kill_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (21,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (22,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (23,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (24,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (25,'node1_to_be_rollbacked_after'); +connection node_2; +Performing --wsrep-recover ... +Starting server ... +Using --wsrep-start-position when starting mysqld ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (26,'node2_committed_after'); +INSERT INTO t1 VALUES (27,'node2_committed_after'); +INSERT INTO t1 VALUES (28,'node2_committed_after'); +INSERT INTO t1 VALUES (29,'node2_committed_after'); +INSERT INTO t1 VALUES (30,'node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES (31,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (32,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (33,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (34,'node1_to_be_committed_after'); +INSERT INTO t1 VALUES (35,'node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES (36,'node1_committed_after'); +INSERT INTO t1 VALUES (37,'node1_committed_after'); +INSERT INTO t1 VALUES (38,'node1_committed_after'); +INSERT INTO t1 VALUES (39,'node1_committed_after'); +INSERT INTO t1 VALUES (40,'node1_committed_after'); +COMMIT; +connection node_1a_galera_st_kill_slave; +INSERT INTO t1 VALUES (41,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (42,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (43,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (45,'node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES (46,'node1_to_be_rollbacked_after'); +ROLLBACK; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_35 FROM t1; +EXPECT_35 +35 +SELECT * FROM t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +connection node_1; +SET AUTOCOMMIT=ON; +SET SESSION wsrep_sync_wait=15; +SELECT COUNT(*) AS EXPECT_35 FROM t1; +EXPECT_35 +35 +SELECT * FROM t1; +id f1 +1 node1_committed_before +2 node1_committed_before +3 node1_committed_before +4 node1_committed_before +5 node1_committed_before +6 node2_committed_before +7 node2_committed_before +8 node2_committed_before +9 node2_committed_before +10 node2_committed_before +11 node1_committed_during +12 node1_committed_during +13 node1_committed_during +14 node1_committed_during +15 node1_committed_during +16 node1_to_be_committed_after +17 node1_to_be_committed_after +18 node1_to_be_committed_after +19 node1_to_be_committed_after +20 node1_to_be_committed_after +26 node2_committed_after +27 node2_committed_after +28 node2_committed_after +29 node2_committed_after +30 node2_committed_after +31 node1_to_be_committed_after +32 node1_to_be_committed_after +33 node1_to_be_committed_after +34 node1_to_be_committed_after +35 node1_to_be_committed_after +36 node1_committed_after +37 node1_committed_after +38 node1_committed_after +39 node1_committed_after +40 node1_committed_after +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +disconnect node_2; +disconnect node_1; diff --git a/mysql-test/suite/galera/t/galera_log_bin_ext.cnf b/mysql-test/suite/galera/t/galera_log_bin_ext.cnf new file mode 100644 index 00000000000..012209610ea --- /dev/null +++ b/mysql-test/suite/galera/t/galera_log_bin_ext.cnf @@ -0,0 +1,11 @@ +!include ../galera_2nodes.cnf + +[mysqld.1] +log-bin = hostname1-bin +log-bin-index = hostname1.bdx +log-slave-updates + +[mysqld.2] +log-bin = hostname2-bin +log-bin-index = hostname2.bdx +log-slave-updates diff --git a/mysql-test/suite/galera/t/galera_log_bin_ext.test b/mysql-test/suite/galera/t/galera_log_bin_ext.test new file mode 100644 index 00000000000..923bd623a8a --- /dev/null +++ b/mysql-test/suite/galera/t/galera_log_bin_ext.test @@ -0,0 +1 @@ +--source galera_log_bin.inc diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup_force_recovery-master.opt b/mysql-test/suite/galera/t/galera_sst_mariabackup_force_recovery-master.opt new file mode 100644 index 00000000000..b54b4fad444 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_mariabackup_force_recovery-master.opt @@ -0,0 +1 @@ +--innodb-force-recovery=1 diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup_force_recovery.cnf b/mysql-test/suite/galera/t/galera_sst_mariabackup_force_recovery.cnf new file mode 100644 index 00000000000..857a4101406 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_mariabackup_force_recovery.cnf @@ -0,0 +1,16 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep_sst_method=mariabackup +wsrep_sst_auth="root:" +wsrep_debug=1 + +[mysqld.1] +wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' + +[mysqld.2] +wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true' + +[sst] +transferfmt=@ENV.MTR_GALERA_TFMT +streamfmt=mbstream diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup_force_recovery.test b/mysql-test/suite/galera/t/galera_sst_mariabackup_force_recovery.test new file mode 100644 index 00000000000..bcb9ade3a25 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_mariabackup_force_recovery.test @@ -0,0 +1,20 @@ +--source include/big_test.inc +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_mariabackup.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc + +--source suite/galera/include/galera_st_shutdown_slave.inc +--source suite/galera/include/galera_st_clean_slave.inc + +--source suite/galera/include/galera_st_kill_slave.inc +--source suite/galera/include/galera_st_kill_slave_ddl.inc + +# Restore original auto_increment_offset values. +--source include/auto_increment_offset_restore.inc + +--source include/galera_end.inc diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index 3d61765f6d3..f043b56da90 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -44,6 +44,7 @@ WSREP_SST_OPT_HOST_ESCAPED="" INNODB_DATA_HOME_DIR="${INNODB_DATA_HOME_DIR:-}" INNODB_LOG_GROUP_HOME="${INNODB_LOG_GROUP_HOME:-}" INNODB_UNDO_DIR="${INNODB_UNDO_DIR:-}" +INNODB_FORCE_RECOVERY="" INNOEXTRA="" while [ $# -gt 0 ]; do @@ -229,7 +230,7 @@ case "$1" in shift ;; '--binlog-index'|'--log-bin-index') - readonly WSREP_SST_OPT_BINLOG_INDEX="$2" + WSREP_SST_OPT_BINLOG_INDEX="$2" shift ;; '--log-basename') @@ -382,6 +383,14 @@ case "$1" in fi skip_mysqld_arg=1 ;; + '--innodb-force-recovery') + if [ -n "$value" ]; then + if [ "$value" -ne 0 ]; then + INNODB_FORCE_RECOVERY="$value" + fi + fi + skip_mysqld_arg=1 + ;; '--log-bin') if [ -z "$WSREP_SST_OPT_BINLOG" ]; then MYSQLD_OPT_LOG_BIN="$value" @@ -444,7 +453,7 @@ if [ -n "${MYSQLD_OPT_LOG_BIN:-}" -a \ fi if [ -n "${MYSQLD_OPT_LOG_BIN_INDEX:-}" -a \ -z "$WSREP_SST_OPT_BINLOG_INDEX" ]; then - readonly WSREP_SST_OPT_BINLOG_INDEX="$MYSQLD_OPT_LOG_BIN_INDEX" + WSREP_SST_OPT_BINLOG_INDEX="$MYSQLD_OPT_LOG_BIN_INDEX" fi if [ -n "${MYSQLD_OPT_DATADIR:-}" -a \ -z "$WSREP_SST_OPT_DATA" ]; then @@ -499,6 +508,7 @@ if [ -n "$WSREP_SST_OPT_BINLOG" ]; then fi fi +readonly INNODB_FORCE_RECOVERY readonly WSREP_SST_OPT_MYSQLD get_binlog() @@ -553,6 +563,16 @@ get_binlog() # is already defined above): readonly WSREP_SST_OPT_BINLOG_INDEX="$WSREP_SST_OPT_BINLOG.index" fi + else + # Remove all directories from the index file path: + local filename="${WSREP_SST_OPT_BINLOG_INDEX##*/}" + # Check if the index file name contains the extension: + if [ "${filename%.*}" = "$filename" ]; then + # Let's add the default extension (".index"): + readonly WSREP_SST_OPT_BINLOG_INDEX="$WSREP_SST_OPT_BINLOG_INDEX.index" + else + readonly WSREP_SST_OPT_BINLOG_INDEX + fi fi fi } diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index 3fe3bf5c206..b429a9effd5 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -951,7 +951,11 @@ setup_commands() if [ -n "$WSREP_SST_OPT_MYSQLD" ]; then mysqld_args="--mysqld-args $WSREP_SST_OPT_MYSQLD" fi - INNOAPPLY="$BACKUP_BIN --prepare $disver $iapts $INNOEXTRA --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY" + if [ -z "$INNODB_FORCE_RECOVERY" ]; then + INNOAPPLY="$BACKUP_BIN --prepare $disver $iapts $INNOEXTRA --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY" + else + INNOAPPLY="$BACKUP_BIN --prepare $disver $iapts $INNOEXTRA --innodb-force-recovery=$INNODB_FORCE_RECOVERY --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY" + fi INNOMOVE="$BACKUP_BIN $WSREP_SST_OPT_CONF --move-back $disver $impts --force-non-empty-directories --target-dir='$DATA' --datadir='${TDATA:-$DATA}' $INNOMOVE" INNOBACKUP="$BACKUP_BIN $WSREP_SST_OPT_CONF --backup $disver $iopts $tmpopts $INNOEXTRA --galera-info --stream=$sfmt --target-dir='$itmpdir' --datadir='$DATA' $mysqld_args $INNOBACKUP" } @@ -1245,8 +1249,8 @@ then cd "$binlog_dir" wsrep_log_info "Cleaning the binlog directory $binlog_dir as well" rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || true - binlog_index="${WSREP_SST_OPT_BINLOG_INDEX%.index}.index" - [ -f "$binlog_index" ] && rm -fv "$binlog_index" 1>&2 \+ || true + [ -f "$WSREP_SST_OPT_BINLOG_INDEX" ] && \ + rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ || true cd "$OLD_PWD" fi @@ -1321,7 +1325,7 @@ then cd "$BINLOG_DIRNAME" for bfile in $(ls -1 "$BINLOG_FILENAME".[0-9]*); do - echo "$BINLOG_DIRNAME/$bfile" >> "${WSREP_SST_OPT_BINLOG_INDEX%.index}.index" + echo "$BINLOG_DIRNAME/$bfile" >> "$WSREP_SST_OPT_BINLOG_INDEX" done cd "$OLD_PWD" diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index ad9688011e1..29c9cd43470 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -392,7 +392,7 @@ EOF # Prepare binlog files cd "$BINLOG_DIRNAME" - binlog_files_full=$(tail -n $BINLOG_N_FILES "${WSREP_SST_OPT_BINLOG_INDEX%.index}.index") + binlog_files_full=$(tail -n $BINLOG_N_FILES "$WSREP_SST_OPT_BINLOG_INDEX") binlog_files="" for ii in $binlog_files_full @@ -732,7 +732,7 @@ EOF if [ -f "$BINLOG_TAR_FILE" ]; then cd "$BINLOG_DIRNAME" - binlog_index="${WSREP_SST_OPT_BINLOG_INDEX%.index}.index" + binlog_index="$WSREP_SST_OPT_BINLOG_INDEX" # Clean up old binlog files first rm -f "$BINLOG_FILENAME".[0-9]* diff --git a/sql/mdl.cc b/sql/mdl.cc index 7f170a56d7a..c2475bb3b91 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -784,7 +784,7 @@ int mdl_iterate(mdl_iterator_callback callback, void *arg) my_hash_value_type mdl_hash_function(CHARSET_INFO *cs, const uchar *key, size_t length) { - MDL_key *mdl_key= (MDL_key*) (key - my_offsetof(MDL_key, m_ptr)); + MDL_key *mdl_key= (MDL_key*) (key - offsetof(MDL_key, m_ptr)); return mdl_key->hash_value(); } diff --git a/sql/my_json_writer.h b/sql/my_json_writer.h index e2d60df4bf5..089abd0ad48 100644 --- a/sql/my_json_writer.h +++ b/sql/my_json_writer.h @@ -19,6 +19,9 @@ #include "my_base.h" #if !defined(NDEBUG) || defined(JSON_WRITER_UNIT_TEST) || defined ENABLED_JSON_WRITER_CONSISTENCY_CHECKS +#include <set> +#include <stack> +#include <string> #include <vector> #endif @@ -32,6 +35,8 @@ constexpr uint FAKE_SELECT_LEX_ID= UINT_MAX; #define VALIDITY_ASSERT(x) DBUG_ASSERT(x) #endif +#include <type_traits> + class Opt_trace_stmt; class Opt_trace_context; class Json_writer; @@ -372,16 +377,21 @@ protected: */ bool closed; -public: - explicit Json_writer_struct(THD *thd, bool expect_named_children) + explicit Json_writer_struct(Json_writer *writer) + : my_writer(writer) { - my_writer= thd->opt_trace.get_current_json(); context.init(my_writer); closed= false; #ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS named_items_expectation.push_back(expect_named_children); #endif } + explicit Json_writer_struct(THD *thd) + : Json_writer_struct(thd->opt_trace.get_current_json()) + { + } + +public: virtual ~Json_writer_struct() { @@ -421,8 +431,8 @@ private: my_writer->add_member(name); } public: - explicit Json_writer_object(THD* thd, const char *str= nullptr) - : Json_writer_struct(thd, true) + explicit Json_writer_object(Json_writer* writer, const char *str= nullptr) + : Json_writer_struct(writer) { #ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS DBUG_ASSERT(named_item_expected()); @@ -435,6 +445,11 @@ public: } } + explicit Json_writer_object(THD* thd, const char *str= nullptr) + : Json_writer_object(thd->opt_trace.get_current_json(), str) + { + } + ~Json_writer_object() { if (my_writer && !closed) @@ -452,17 +467,22 @@ public: } return *this; } + Json_writer_object& add(const char *name, ulonglong value) { DBUG_ASSERT(!closed); if (my_writer) { add_member(name); - context.add_ll(static_cast<longlong>(value)); + my_writer->add_ull(value); } return *this; } - Json_writer_object& add(const char *name, longlong value) + + template<class IntT, + typename= typename ::std::enable_if<std::is_integral<IntT>::value>::type + > + Json_writer_object& add(const char *name, IntT value) { DBUG_ASSERT(!closed); if (my_writer) @@ -472,6 +492,7 @@ public: } return *this; } + Json_writer_object& add(const char *name, double value) { DBUG_ASSERT(!closed); @@ -482,18 +503,7 @@ public: } return *this; } - #ifndef _WIN64 - Json_writer_object& add(const char *name, size_t value) - { - DBUG_ASSERT(!closed); - if (my_writer) - { - add_member(name); - context.add_ll(static_cast<longlong>(value)); - } - return *this; - } - #endif + Json_writer_object& add(const char *name, const char *value) { DBUG_ASSERT(!closed); @@ -594,25 +604,25 @@ public: class Json_writer_array : public Json_writer_struct { public: - Json_writer_array(THD *thd) - : Json_writer_struct(thd, false) + explicit Json_writer_array(Json_writer *writer, const char *str= nullptr) + : Json_writer_struct(writer) { #ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS DBUG_ASSERT(!named_item_expected()); #endif if (unlikely(my_writer)) + { + if (str) + my_writer->add_member(str); my_writer->start_array(); + } } - Json_writer_array(THD *thd, const char *str) - : Json_writer_struct(thd, false) + explicit Json_writer_array(THD *thd, const char *str= nullptr) + : Json_writer_array(thd->opt_trace.get_current_json(), str) { -#ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS - DBUG_ASSERT(named_item_expected()); -#endif - if (unlikely(my_writer)) - my_writer->add_member(str).start_array(); } + ~Json_writer_array() { if (unlikely(my_writer && !closed)) @@ -621,6 +631,7 @@ public: closed= TRUE; } } + void end() { DBUG_ASSERT(!closed); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 9dc1bcf733f..06063cb9ae1 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -6937,7 +6937,7 @@ static bool ror_intersect_add(ROR_INTERSECT_INFO *info, DBUG_PRINT("info", ("info->total_cost= %g", info->total_cost)); } else - trace_costs->add("disk_sweep_cost", static_cast<longlong>(0)); + trace_costs->add("disk_sweep_cost", 0); DBUG_PRINT("info", ("New out_rows: %g", info->out_rows)); DBUG_PRINT("info", ("New cost: %g, %scovering", info->total_cost, diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a357d4f8c8a..0dfe95e81b0 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -505,7 +505,7 @@ static void trace_table_dependencies(THD *thd, { if (map & (1ULL << j)) { - trace_one_table.add("map_bit", static_cast<longlong>(j)); + trace_one_table.add("map_bit", j); break; } } diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index e18ca6392d8..7127cbc00f6 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -5718,14 +5718,14 @@ static bool update_locale(sys_var *self, THD* thd, enum_var_type type) static Sys_var_struct Sys_lc_messages( "lc_messages", "Set the language used for the error messages", SESSION_VAR(lc_messages), NO_CMD_LINE, - my_offsetof(MY_LOCALE, name), DEFAULT(&my_default_lc_messages), + offsetof(MY_LOCALE, name), DEFAULT(&my_default_lc_messages), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_locale), ON_UPDATE(update_locale)); static Sys_var_struct Sys_lc_time_names( "lc_time_names", "Set the language used for the month " "names and the days of the week", SESSION_VAR(lc_time_names), NO_CMD_LINE, - my_offsetof(MY_LOCALE, name), DEFAULT(&my_default_lc_time_names), + offsetof(MY_LOCALE, name), DEFAULT(&my_default_lc_time_names), NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_locale)); static Sys_var_tz Sys_time_zone( diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 720a9f39ebb..c31d9aef8eb 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -971,6 +971,7 @@ buf_block_init(buf_block_t* block, byte* frame) MEM_MAKE_DEFINED(&block->modify_clock, sizeof block->modify_clock); ut_ad(!block->modify_clock); + MEM_MAKE_DEFINED(&block->page.lock, sizeof block->page.lock); block->page.init(buf_page_t::NOT_USED, page_id_t(~0ULL)); #ifdef BTR_CUR_HASH_ADAPT MEM_MAKE_DEFINED(&block->index, sizeof block->index); @@ -983,8 +984,6 @@ buf_block_init(buf_block_t* block, byte* frame) MEM_MAKE_DEFINED(&block->page.hash, sizeof block->page.hash); ut_ad(!block->page.hash); - MEM_MAKE_DEFINED(&block->page.lock, sizeof block->page.lock); - block->page.lock.init(); } /** Allocate a chunk of buffer frames. @@ -2514,20 +2513,21 @@ buf_page_get_low( page_hash_latch& hash_lock = buf_pool.page_hash.lock_get(chain); loop: buf_block_t* block = guess; + uint32_t state; if (block) { transactional_shared_lock_guard<page_hash_latch> g{hash_lock}; if (buf_pool.is_uncompressed(block) && page_id == block->page.id()) { ut_ad(!block->page.in_zip_hash); - const auto state = block->page.state(); + state = block->page.state(); /* Ignore guesses that point to read-fixed blocks. We can only avoid a race condition by looking up the block via buf_pool.page_hash. */ if ((state >= buf_page_t::FREED - && state < buf_page_t::READ_FIX) || - state >= buf_page_t::WRITE_FIX) { - block->fix(); + && state < buf_page_t::READ_FIX) + || state >= buf_page_t::WRITE_FIX) { + state = block->page.fix(); goto got_block; } } @@ -2541,7 +2541,7 @@ loop: buf_pool.page_hash.get(page_id, chain)); if (UNIV_LIKELY(block && !buf_pool.watch_is_sentinel(block->page))) { - block->fix(); + state = block->page.fix(); hash_lock.unlock_shared(); goto got_block; } @@ -2558,11 +2558,8 @@ loop: hash_lock.lock(); block = reinterpret_cast<buf_block_t*> (buf_pool.watch_set(page_id, chain)); - if (block) { - /* buffer-fixing prevents block->page.in_file() - from changing */ - block->fix(); - } + /* buffer-fixing will prevent eviction */ + state = block ? block->page.fix() : 0; hash_lock.unlock(); if (block) { @@ -2651,19 +2648,34 @@ loop: got_block: ut_ad(!block->page.in_zip_hash); - ut_ad(block->page.in_file()); + state++; + ut_ad(state > buf_page_t::FREED); - if (mode == BUF_PEEK_IF_IN_POOL) { - if (UNIV_UNLIKELY(!block->page.frame - || block->page.is_read_fixed())) { - /* This mode is only used for dropping an - adaptive hash index. There cannot be an - adaptive hash index for a compressed-only page - or a page that is only being read into the - buffer pool. */ + if (state > buf_page_t::READ_FIX && state < buf_page_t::WRITE_FIX) { + if (mode == BUF_PEEK_IF_IN_POOL + || mode == BUF_EVICT_IF_IN_POOL) { +ignore_block: block->unfix(); return nullptr; } + + if (UNIV_LIKELY(block->page.frame != nullptr)) { + /* A read-fix is released after block->page.lock + in buf_page_t::read_complete() or + buf_pool_t::corrupted_evict(), or + after buf_zip_decompress() in this function. */ + block->page.lock.s_lock(); + state = block->page.state(); + block->page.lock.s_unlock(); + ut_ad(state < buf_page_t::READ_FIX); + } + } else if (mode == BUF_PEEK_IF_IN_POOL) { + if (UNIV_UNLIKELY(!block->page.frame)) { + /* This mode is only used for dropping an + adaptive hash index. There cannot be an + adaptive hash index for a compressed-only page. */ + goto ignore_block; + } } else if (mode == BUF_EVICT_IF_IN_POOL) { ut_ad(!block->page.oldest_modification()); mysql_mutex_lock(&buf_pool.mutex); @@ -2693,6 +2705,7 @@ got_block: buf_block_t *new_block = buf_LRU_get_free_block(false); buf_block_init_low(new_block); +wait_for_unfix: mysql_mutex_lock(&buf_pool.mutex); page_hash_latch& hash_lock=buf_pool.page_hash.lock_get(chain); @@ -2709,37 +2722,36 @@ got_block: FIXME: Never fix() before acquiring the lock. Only in buf_page_get_gen(), buf_page_get_low(), buf_page_free() we are violating that principle. */ - auto state = block->page.state(); + state = block->page.state(); - for (;; state = block->page.state()) { - switch (state) { - case buf_page_t::UNFIXED + 1: - case buf_page_t::IBUF_EXIST + 1: - case buf_page_t::REINIT + 1: - break; - default: - ut_ad(state < buf_page_t::READ_FIX); - - if (state < buf_page_t::UNFIXED + 1) { - ut_ad(state > buf_page_t::FREED); - ut_ad(mode == BUF_GET_POSSIBLY_FREED - || mode == BUF_PEEK_IF_IN_POOL); - block->page.unfix(); - block->page.lock.x_unlock(); - hash_lock.unlock(); - buf_LRU_block_free_non_file_page(new_block); - mysql_mutex_unlock(&buf_pool.mutex); - return nullptr; - } - - LF_BACKOFF(); - continue; - } + switch (state) { + case buf_page_t::UNFIXED + 1: + case buf_page_t::IBUF_EXIST + 1: + case buf_page_t::REINIT + 1: break; + default: + ut_ad(state < buf_page_t::READ_FIX); + + if (state < buf_page_t::UNFIXED + 1) { + ut_ad(state > buf_page_t::FREED); + ut_ad(mode == BUF_GET_POSSIBLY_FREED + || mode == BUF_PEEK_IF_IN_POOL); + block->page.unfix(); + block->page.lock.x_unlock(); + hash_lock.unlock(); + buf_LRU_block_free_non_file_page(new_block); + mysql_mutex_unlock(&buf_pool.mutex); + return nullptr; + } + + mysql_mutex_unlock(&buf_pool.mutex); + hash_lock.unlock(); + std::this_thread::sleep_for( + std::chrono::microseconds(100)); + goto wait_for_unfix; } - /* Ensure that mtr_t::page_lock(new_block, RW_NO_LATCH) - in another thread will wait for + /* Ensure that another buf_page_get_low() will wait for new_block->page.lock.x_unlock(). */ block->page.set_state(buf_page_t::READ_FIX); @@ -2782,6 +2794,7 @@ got_block: buf_pool.mutex. */ auto ok = buf_zip_decompress(block, false); block->page.read_unfix(state); + state = block->page.state(); block->page.lock.x_unlock(); --buf_pool.n_pend_unzip; @@ -2792,12 +2805,10 @@ got_block: if (err) { *err = DB_PAGE_CORRUPTED; } - return NULL; + return nullptr; } } - ut_ad(block->page.frame); - #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG re_evict: if (mode != BUF_GET_IF_IN_POOL @@ -2837,9 +2848,13 @@ re_evict: buf_flush_list(); buf_flush_wait_batch_end_acquiring_mutex(false); while (buf_flush_list_space(space)); - os_aio_wait_until_no_pending_writes(); + /* Wait for page write completion. */ + block->page.lock.u_lock(); + block->page.lock.u_unlock(); + + state = block->page.state(); - if (block->page.buf_fix_count() == 1 + if (state == buf_page_t::UNFIXED + 1 && !block->page.oldest_modification()) { goto re_evict; } @@ -2848,8 +2863,9 @@ re_evict: } #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ - ut_ad(block->page.buf_fix_count()); - ut_ad(block->page.in_file()); + ut_ad(state > buf_page_t::FREED); + ut_ad(state < buf_page_t::UNFIXED || (~buf_page_t::LRU_MASK) & state); + ut_ad(state > buf_page_t::WRITE_FIX || state < buf_page_t::READ_FIX); /* While tablespace is reinited the indexes are already freed but the blocks related to it still resides in buffer pool. Trying to remove @@ -2859,7 +2875,7 @@ re_evict: with mode = BUF_PEEK_IF_IN_POOL that is invoked from "btr_search_drop_page_hash_when_freed". */ ut_ad(mode == BUF_GET_POSSIBLY_FREED || mode == BUF_PEEK_IF_IN_POOL - || !block->page.is_freed()); + || state > buf_page_t::UNFIXED); const bool not_first_access = block->page.set_accessed(); @@ -2874,19 +2890,18 @@ re_evict: #ifdef UNIV_DEBUG if (!(++buf_dbg_counter % 5771)) buf_pool.validate(); #endif /* UNIV_DEBUG */ - ut_ad(block->page.in_file()); ut_ad(block->page.frame); ut_ad(block->page.id() == page_id); - if (!block->page.is_freed() + if (state >= buf_page_t::UNFIXED && allow_ibuf_merge && fil_page_get_type(block->page.frame) == FIL_PAGE_INDEX && page_is_leaf(block->page.frame)) { block->page.lock.x_lock(); - ut_ad(!block->page.is_io_fixed()); + state = block->page.state(); + ut_ad(state < buf_page_t::READ_FIX); - const auto state = block->page.state(); if (state >= buf_page_t::IBUF_EXIST && state < buf_page_t::REINIT) { block->page.clear_ibuf_exist(); diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index 0658ca57c60..9846b4a6af5 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -1318,7 +1318,7 @@ func_exit: /* Avoid GCC 4.8.5 internal compiler error "could not split insn". We would only need this for buf_LRU_scan_and_free_block(), but GCC 4.8.5 does not support pop_options. */ -# pragma GCC optimize ("no-expensive-optimizations") +# pragma GCC optimize ("O0") #endif /** Try to free a replaceable block. @param limit maximum number of blocks to scan diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index d4220d0ac5f..ba1b2a7883c 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -19397,8 +19397,15 @@ bool innodb_use_native_aio_default() #ifdef HAVE_URING utsname &u= uname_for_io_uring; if (!uname(&u) && u.release[0] == '5' && u.release[1] == '.' && - u.release[2] == '1' && u.release[3] > '0' && u.release[3] < '6') + u.release[2] == '1' && u.release[3] >= '1' && u.release[3] <= '5' && + u.release[4] == '.') { + if (u.release[3] == '5') { + const char *s= strstr(u.version, "5.15."); + if (s || (s= strstr(u.release, "5.15."))) + if ((s[5] >= '3' || s[6] >= '0')) + return true; /* 5.15.3 and later should be fine */ + } io_uring_may_be_unsafe= u.release; return false; /* working around io_uring hangs (MDEV-26674) */ } diff --git a/storage/innobase/include/srw_lock.h b/storage/innobase/include/srw_lock.h index 23d8e35aa7b..e8ed346d3ac 100644 --- a/storage/innobase/include/srw_lock.h +++ b/storage/innobase/include/srw_lock.h @@ -138,6 +138,7 @@ public: /** @return whether any writer is waiting */ bool is_waiting() const { return (value() & WRITER_WAITING) != 0; } bool is_write_locked() const { return rw_lock::is_write_locked(); } + bool is_locked_or_waiting() const { return rw_lock::is_locked_or_waiting(); } bool rd_lock_try() { uint32_t l; return read_trylock(l); } bool wr_lock_try() { return write_trylock(); } diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index 62c2dae91a0..615688aed0e 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -1167,26 +1167,17 @@ void mtr_t::lock_upgrade(const index_lock &lock) void mtr_t::page_lock(buf_block_t *block, ulint rw_latch) { mtr_memo_type_t fix_type; - const auto state= block->page.state(); - ut_ad(state >= buf_page_t::FREED); + ut_d(const auto state= block->page.state()); + ut_ad(state > buf_page_t::FREED); + ut_ad(state > buf_page_t::WRITE_FIX || state < buf_page_t::READ_FIX); switch (rw_latch) { case RW_NO_LATCH: fix_type= MTR_MEMO_BUF_FIX; - if (state >= buf_page_t::READ_FIX && state < buf_page_t::WRITE_FIX) - { - /* The io-fix will be released after block->page.lock in - buf_page_t::read_complete(), buf_pool_t::corrupted_evict(), and - buf_page_t::write_complete(). */ - block->page.lock.s_lock(); - ut_ad(!block->page.is_read_fixed()); - block->page.lock.s_unlock(); - } goto done; case RW_S_LATCH: fix_type= MTR_MEMO_PAGE_S_FIX; block->page.lock.s_lock(); - ut_ad(!block->page.is_read_fixed()); break; case RW_SX_LATCH: fix_type= MTR_MEMO_PAGE_SX_FIX; diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc index d7cac927d30..48641ab1c68 100644 --- a/storage/perfschema/pfs.cc +++ b/storage/perfschema/pfs.cc @@ -4841,8 +4841,8 @@ pfs_start_stage_v1(PSI_stage_key key, const char *src_file, int src_line) pfs->m_class= NULL; /* New waits will now be attached directly to the parent statement. */ - child_wait->m_event_id= parent_statement->m_event_id; - child_wait->m_event_type= parent_statement->m_event_type; + child_wait->m_event_id= parent_statement->m_event.m_event_id; + child_wait->m_event_type= parent_statement->m_event.m_event_type; /* See below for new stages, that may overwrite this. */ } @@ -4957,8 +4957,8 @@ void pfs_end_stage_v1() /* New waits will now be attached directly to the parent statement. */ PFS_events_waits *child_wait= & pfs_thread->m_events_waits_stack[0]; PFS_events_statements *parent_statement= & pfs_thread->m_statement_stack[0]; - child_wait->m_event_id= parent_statement->m_event_id; - child_wait->m_event_type= parent_statement->m_event_type; + child_wait->m_event_id= parent_statement->m_event.m_event_id; + child_wait->m_event_type= parent_statement->m_event.m_event_type; /* This stage is completed */ pfs->m_class= NULL; @@ -5009,13 +5009,13 @@ pfs_get_thread_statement_locker_v1(PSI_statement_locker_state *state, pfs_dirty_state dirty_state; pfs_thread->m_stmt_lock.allocated_to_dirty(& dirty_state); PFS_events_statements *pfs= & pfs_thread->m_statement_stack[pfs_thread->m_events_statements_count]; - pfs->m_thread_internal_id= pfs_thread->m_thread_internal_id; - pfs->m_event_id= event_id; - pfs->m_event_type= EVENT_TYPE_STATEMENT; - pfs->m_end_event_id= 0; - pfs->m_class= klass; - pfs->m_timer_start= 0; - pfs->m_timer_end= 0; + pfs->m_event.m_thread_internal_id= pfs_thread->m_thread_internal_id; + pfs->m_event.m_event_id= event_id; + pfs->m_event.m_event_type= EVENT_TYPE_STATEMENT; + pfs->m_event.m_end_event_id= 0; + pfs->m_event.m_class= klass; + pfs->m_event.m_timer_start= 0; + pfs->m_event.m_timer_end= 0; pfs->m_lock_time= 0; pfs->m_current_schema_name_length= 0; pfs->m_sqltext_length= 0; @@ -5065,9 +5065,9 @@ pfs_get_thread_statement_locker_v1(PSI_statement_locker_state *state, if (pfs_thread->m_events_statements_count > 0) { parent_statement= pfs - 1; - parent_event= parent_statement->m_event_id; - parent_type= parent_statement->m_event_type; - parent_level= parent_statement->m_nesting_event_level + 1; + parent_event= parent_statement->m_event.m_event_id; + parent_type= parent_statement->m_event.m_event_type; + parent_level= parent_statement->m_event.m_nesting_event_level + 1; } if (parent_transaction->m_state == TRANS_STATE_ACTIVE && @@ -5077,9 +5077,9 @@ pfs_get_thread_statement_locker_v1(PSI_statement_locker_state *state, parent_type= parent_transaction->m_event_type; } - pfs->m_nesting_event_id= parent_event; - pfs->m_nesting_event_type= parent_type; - pfs->m_nesting_event_level= parent_level; + pfs->m_event.m_nesting_event_id= parent_event; + pfs->m_event.m_nesting_event_type= parent_type; + pfs->m_event.m_nesting_event_level= parent_level; /* Set parent Stored Procedure information for this statement. */ if(sp_share) @@ -5197,7 +5197,7 @@ pfs_refine_statement_v1(PSI_statement_locker *locker, DBUG_ASSERT(pfs != NULL); /* mutate EVENTS_STATEMENTS_CURRENT.EVENT_NAME */ - pfs->m_class= klass; + pfs->m_event.m_class= klass; } state->m_class= klass; @@ -5233,9 +5233,9 @@ void pfs_start_statement_v1(PSI_statement_locker *locker, PFS_events_statements *pfs= reinterpret_cast<PFS_events_statements*> (state->m_statement); DBUG_ASSERT(pfs != NULL); - pfs->m_timer_start= timer_start; - pfs->m_source_file= src_file; - pfs->m_source_line= src_line; + pfs->m_event.m_timer_start= timer_start; + pfs->m_event.m_source_file= src_file; + pfs->m_event.m_source_line= src_line; DBUG_ASSERT(db_len <= sizeof(pfs->m_current_schema_name)); if (db_len > 0) @@ -5492,8 +5492,8 @@ void pfs_end_statement_v1(PSI_statement_locker *locker, void *stmt_da) break; } - pfs->m_timer_end= timer_end; - pfs->m_end_event_id= thread->m_event_id; + pfs->m_event.m_timer_end= timer_end; + pfs->m_event.m_end_event_id= thread->m_event_id; if (digest_storage != NULL) { @@ -5970,8 +5970,8 @@ pfs_get_thread_transaction_locker_v1(PSI_transaction_locker_state *state, { PFS_events_statements *pfs_statement= &pfs_thread->m_statement_stack[statements_count - 1]; - pfs->m_nesting_event_id= pfs_statement->m_event_id; - pfs->m_nesting_event_type= pfs_statement->m_event_type; + pfs->m_nesting_event_id= pfs_statement->m_event.m_event_id; + pfs->m_nesting_event_type= pfs_statement->m_event.m_event_type; } else { diff --git a/storage/perfschema/pfs_events_statements.cc b/storage/perfschema/pfs_events_statements.cc index e0f1b2bfb77..7c1ac8b1d5b 100644 --- a/storage/perfschema/pfs_events_statements.cc +++ b/storage/perfschema/pfs_events_statements.cc @@ -147,27 +147,26 @@ void cleanup_events_statements_history_long(void) h_long_stmts_text_array= NULL; } -static inline void copy_events_statements(PFS_events_statements *dest, - const PFS_events_statements *source) +inline void PFS_events_statements::copy(const PFS_events_statements &source) { /* Copy all attributes except SQL TEXT and DIGEST */ - memcpy(dest, source, my_offsetof(PFS_events_statements, m_sqltext)); + memcpy((void*) this, &source, offsetof(PFS_events_statements, m_sqltext)); /* Copy SQL TEXT */ - int sqltext_length= source->m_sqltext_length; + int sqltext_length= source.m_sqltext_length; if (sqltext_length > 0) { - memcpy(dest->m_sqltext, source->m_sqltext, sqltext_length); - dest->m_sqltext_length= sqltext_length; + memcpy(m_sqltext, source.m_sqltext, sqltext_length); + m_sqltext_length= sqltext_length; } else { - dest->m_sqltext_length= 0; + m_sqltext_length= 0; } /* Copy DIGEST */ - dest->m_digest_storage.copy(& source->m_digest_storage); + m_digest_storage.copy(&source.m_digest_storage); } /** @@ -192,7 +191,7 @@ void insert_events_statements_history(PFS_thread *thread, PFS_events_statements to make this thread (the writer) faster. This is ok, the readers of m_statements_history will filter this out. */ - copy_events_statements(&thread->m_statements_history[index], statement); + thread->m_statements_history[index].copy(*statement); index++; if (index >= events_statements_history_per_thread) @@ -221,7 +220,7 @@ void insert_events_statements_history_long(PFS_events_statements *statement) events_statements_history_long_full= true; /* See related comment in insert_events_statements_history. */ - copy_events_statements(&events_statements_history_long_array[index], statement); + events_statements_history_long_array[index].copy(*statement); } static void fct_reset_events_statements_current(PFS_thread *pfs_thread) @@ -230,7 +229,7 @@ static void fct_reset_events_statements_current(PFS_thread *pfs_thread) PFS_events_statements *pfs_stmt_last= pfs_stmt + statement_stack_max; for ( ; pfs_stmt < pfs_stmt_last; pfs_stmt++) - pfs_stmt->m_class= NULL; + pfs_stmt->m_event.m_class= nullptr; } /** Reset table EVENTS_STATEMENTS_CURRENT data. */ @@ -247,7 +246,7 @@ static void fct_reset_events_statements_history(PFS_thread *pfs_thread) pfs_thread->m_statements_history_index= 0; pfs_thread->m_statements_history_full= false; for ( ; pfs < pfs_last; pfs++) - pfs->m_class= NULL; + pfs->m_event.m_class= nullptr; } /** Reset table EVENTS_STATEMENTS_HISTORY data. */ @@ -265,7 +264,7 @@ void reset_events_statements_history_long(void) PFS_events_statements *pfs= events_statements_history_long_array; PFS_events_statements *pfs_last= pfs + events_statements_history_long_size; for ( ; pfs < pfs_last; pfs++) - pfs->m_class= NULL; + pfs->m_event.m_class= nullptr; } static void fct_reset_events_statements_by_thread(PFS_thread *thread) diff --git a/storage/perfschema/pfs_events_statements.h b/storage/perfschema/pfs_events_statements.h index 8b24a9e75c8..a21e1c4980c 100644 --- a/storage/perfschema/pfs_events_statements.h +++ b/storage/perfschema/pfs_events_statements.h @@ -38,8 +38,9 @@ struct PFS_user; struct PFS_host; /** A statement record. */ -struct PFS_events_statements : public PFS_events +struct PFS_events_statements { + PFS_events m_event; enum_object_type m_sp_type; char m_schema_name[NAME_LEN]; uint m_schema_name_length; @@ -117,6 +118,8 @@ struct PFS_events_statements : public PFS_events and always point to pre allocated memory. */ sql_digest_storage m_digest_storage; + + inline void copy(const PFS_events_statements &source); }; void insert_events_statements_history(PFS_thread *thread, PFS_events_statements *statement); diff --git a/storage/perfschema/pfs_prepared_stmt.cc b/storage/perfschema/pfs_prepared_stmt.cc index dcb7991633a..5885f31857a 100644 --- a/storage/perfschema/pfs_prepared_stmt.cc +++ b/storage/perfschema/pfs_prepared_stmt.cc @@ -126,9 +126,9 @@ create_prepared_stmt(void *identity, if (pfs_stmt) { if (pfs_program) - pfs->m_owner_event_id= pfs_stmt->m_nesting_event_id; + pfs->m_owner_event_id= pfs_stmt->m_event.m_nesting_event_id; else - pfs->m_owner_event_id= pfs_stmt->m_event_id; + pfs->m_owner_event_id= pfs_stmt->m_event.m_event_id; } /* Insert this record. */ diff --git a/storage/perfschema/table_events_statements.cc b/storage/perfschema/table_events_statements.cc index 9404bd87fcb..1fb02eddc48 100644 --- a/storage/perfschema/table_events_statements.cc +++ b/storage/perfschema/table_events_statements.cc @@ -228,17 +228,18 @@ void table_events_statements_common::make_row_part_1(PFS_events_statements *stat m_row_exists= false; - PFS_statement_class *unsafe= (PFS_statement_class*) statement->m_class; + PFS_statement_class *unsafe= (PFS_statement_class*) + statement->m_event.m_class; PFS_statement_class *klass= sanitize_statement_class(unsafe); if (unlikely(klass == NULL)) return; - m_row.m_thread_internal_id= statement->m_thread_internal_id; - m_row.m_event_id= statement->m_event_id; - m_row.m_end_event_id= statement->m_end_event_id; - m_row.m_nesting_event_id= statement->m_nesting_event_id; - m_row.m_nesting_event_type= statement->m_nesting_event_type; - m_row.m_nesting_event_level= statement->m_nesting_event_level; + m_row.m_thread_internal_id= statement->m_event.m_thread_internal_id; + m_row.m_event_id= statement->m_event.m_event_id; + m_row.m_end_event_id= statement->m_event.m_end_event_id; + m_row.m_nesting_event_id= statement->m_event.m_nesting_event_id; + m_row.m_nesting_event_type= statement->m_event.m_nesting_event_type; + m_row.m_nesting_event_level= statement->m_event.m_nesting_event_level; if (m_row.m_end_event_id == 0) { @@ -246,10 +247,10 @@ void table_events_statements_common::make_row_part_1(PFS_events_statements *stat } else { - timer_end= statement->m_timer_end; + timer_end= statement->m_event.m_timer_end; } - m_normalizer->to_pico(statement->m_timer_start, timer_end, + m_normalizer->to_pico(statement->m_event.m_timer_start, timer_end, & m_row.m_timer_start, & m_row.m_timer_end, & m_row.m_timer_wait); m_row.m_lock_time= statement->m_lock_time * MICROSEC_TO_PICOSEC; @@ -662,7 +663,7 @@ int table_events_statements_current::rnd_pos(const void *pos) statement= &pfs_thread->m_statement_stack[m_pos.m_index_2]; - if (statement->m_class != NULL) + if (statement->m_event.m_class) { make_row(pfs_thread, statement); return 0; @@ -762,7 +763,7 @@ int table_events_statements_history::rnd_next(void) statement= &pfs_thread->m_statements_history[m_pos.m_index_2]; - if (statement->m_class != NULL) + if (statement->m_event.m_class) { make_row(pfs_thread, statement); /* Next iteration, look for the next history in this thread */ @@ -793,7 +794,7 @@ int table_events_statements_history::rnd_pos(const void *pos) return HA_ERR_RECORD_DELETED; statement= &pfs_thread->m_statements_history[m_pos.m_index_2]; - if (statement->m_class != NULL) + if (statement->m_event.m_class) { make_row(pfs_thread, statement); return 0; @@ -876,7 +877,7 @@ int table_events_statements_history_long::rnd_next(void) { statement= &events_statements_history_long_array[m_pos.m_index]; - if (statement->m_class != NULL) + if (statement->m_event.m_class) { make_row(statement); /* Next iteration, look for the next entry */ @@ -908,7 +909,7 @@ int table_events_statements_history_long::rnd_pos(const void *pos) statement= &events_statements_history_long_array[m_pos.m_index]; - if (statement->m_class == NULL) + if (!statement->m_event.m_class) return HA_ERR_RECORD_DELETED; make_row(statement); |