diff --git a/client/mysql.cc b/client/mysql.cc index d39dd939730..68766b5898c 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2884,7 +2884,9 @@ static void fix_history(String *final_command) ptr++; } if (total_lines > 1) - add_history(fixed_buffer.ptr()); + { + add_history(fixed_buffer.c_ptr()); + } } /* diff --git a/mysql-test/lib/My/Debugger.pm b/mysql-test/lib/My/Debugger.pm index 2ab8a3520c8..a3985e65bab 100644 --- a/mysql-test/lib/My/Debugger.pm +++ b/mysql-test/lib/My/Debugger.pm @@ -81,6 +81,7 @@ my %debuggers = ( options => '_RR_TRACE_DIR={log} rr record {exe} {args}', run => 'env', pre => sub { + push @::global_suppressions, qr/InnoDB: native AIO failed/; ::mtr_error('rr requires kernel.perf_event_paranoid <= 1') if ::mtr_grab_file('/proc/sys/kernel/perf_event_paranoid') > 1; } diff --git a/mysql-test/main/analyze_engine_stats.result b/mysql-test/main/analyze_engine_stats.result index 02eb936c4c6..df9b2be41d0 100644 --- a/mysql-test/main/analyze_engine_stats.result +++ b/mysql-test/main/analyze_engine_stats.result @@ -71,7 +71,8 @@ X "rows": 10000, "r_rows": 10000, "r_filtered": 100, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": { "pages_accessed": "REPLACED", "pages_updated": "REPLACED" @@ -104,7 +105,8 @@ X "rows": 10000, "r_rows": 10000, "r_filtered": 50, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": { "pages_accessed": "REPLACED", "pages_updated": "REPLACED" diff --git a/mysql-test/main/analyze_format_json.result b/mysql-test/main/analyze_format_json.result index 8a967186180..7d3b6b8d271 100644 --- a/mysql-test/main/analyze_format_json.result +++ b/mysql-test/main/analyze_format_json.result @@ -419,7 +419,8 @@ ANALYZE "rows": 1000, "r_rows": 1000, "r_filtered": 100, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED } } @@ -483,7 +484,8 @@ ANALYZE "rows": 10, "r_rows": 10, "r_filtered": 50, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED, "attached_condition": "t1.pk < 10 and t1.b > 4" } @@ -1295,3 +1297,121 @@ ANALYZE } set join_cache_level=@tmp; drop table t10, t11; +# +# MDEV-33309: ANALYZE FORMAT=JSON: UPDATE|DELETE don't show r_other_time_ms +# +create table t1 (pk int primary key, a int); +insert into t1 select seq, seq from seq_1_to_1000; +create table t2 like t1; +insert into t2 select * from t1; +# Top-level query block must have r_table_time_ms and r_other_time_ms +analyze format=json +update t1 set a=a+1 +where t1.pk > (select max(a) from t2 where t2.pk+1 = t1.pk+1 ) - 10; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "r_total_time_ms": "REPLACED", + "table": { + "update": 1, + "table_name": "t1", + "access_type": "ALL", + "rows": 1000, + "r_rows": 1000, + "r_filtered": 100, + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, + "attached_condition": "t1.pk > (subquery#2) - 10" + }, + "subqueries": [ + { + "query_block": { + "select_id": 2, + "cost": "REPLACED", + "r_loops": 1000, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t2", + "access_type": "ALL", + "loops": 1, + "r_loops": 1000, + "rows": 1000, + "r_rows": 1000, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, + "filtered": 100, + "r_filtered": 0.1, + "attached_condition": "t2.pk + 1 = t1.pk + 1" + } + } + ] + } + } + ] + } +} +# Top-level query block must have r_table_time_ms and r_other_time_ms +analyze format=json +delete from t1 +where t1.pk > (select max(a) from t2 where t2.pk+1 = t1.pk+1 ) - 10; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "r_total_time_ms": "REPLACED", + "table": { + "delete": 1, + "table_name": "t1", + "access_type": "ALL", + "rows": 1000, + "r_rows": 1000, + "r_filtered": 100, + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, + "attached_condition": "t1.pk > (subquery#2) - 10" + }, + "subqueries": [ + { + "query_block": { + "select_id": 2, + "cost": "REPLACED", + "r_loops": 1000, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t2", + "access_type": "ALL", + "loops": 1, + "r_loops": 1000, + "rows": 1000, + "r_rows": 1000, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, + "filtered": 100, + "r_filtered": 0.1, + "attached_condition": "t2.pk + 1 = t1.pk + 1" + } + } + ] + } + } + ] + } +} +drop table t1, t2; diff --git a/mysql-test/main/analyze_format_json.test b/mysql-test/main/analyze_format_json.test index 001616304cf..43af2b27b79 100644 --- a/mysql-test/main/analyze_format_json.test +++ b/mysql-test/main/analyze_format_json.test @@ -269,4 +269,25 @@ where set join_cache_level=@tmp; drop table t10, t11; +--echo # +--echo # MDEV-33309: ANALYZE FORMAT=JSON: UPDATE|DELETE don't show r_other_time_ms +--echo # +--source include/have_sequence.inc +create table t1 (pk int primary key, a int); +insert into t1 select seq, seq from seq_1_to_1000; +create table t2 like t1; +insert into t2 select * from t1; +--echo # Top-level query block must have r_table_time_ms and r_other_time_ms +--source include/analyze-format.inc +analyze format=json +update t1 set a=a+1 +where t1.pk > (select max(a) from t2 where t2.pk+1 = t1.pk+1 ) - 10; + +--echo # Top-level query block must have r_table_time_ms and r_other_time_ms +--source include/analyze-format.inc +analyze format=json +delete from t1 +where t1.pk > (select max(a) from t2 where t2.pk+1 = t1.pk+1 ) - 10; + +drop table t1, t2; diff --git a/mysql-test/main/analyze_stmt_orderby.result b/mysql-test/main/analyze_stmt_orderby.result index 020e68f34de..46ed05f560b 100644 --- a/mysql-test/main/analyze_stmt_orderby.result +++ b/mysql-test/main/analyze_stmt_orderby.result @@ -55,7 +55,8 @@ ANALYZE "rows": 10000, "r_rows": 10000, "r_filtered": 100, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED } } @@ -111,7 +112,8 @@ ANALYZE "rows": 9, "r_rows": 10, "r_filtered": 100, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED, "attached_condition": "t2.a < 10" } @@ -165,7 +167,8 @@ ANALYZE "rows": 10000, "r_rows": 10000, "r_filtered": 100, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED } } diff --git a/mysql-test/main/backup_locks.test b/mysql-test/main/backup_locks.test index 6a1fe9f6094..c2618cbbadb 100644 --- a/mysql-test/main/backup_locks.test +++ b/mysql-test/main/backup_locks.test @@ -5,6 +5,7 @@ --source include/long_test.inc --source include/have_innodb.inc --source include/have_metadata_lock_info.inc +--source include/have_profiling.inc --source include/not_embedded.inc --source include/no_view_protocol.inc diff --git a/mysql-test/main/explain_json_format_partitions.result b/mysql-test/main/explain_json_format_partitions.result index 6cdac94f20c..bac122acddf 100644 --- a/mysql-test/main/explain_json_format_partitions.result +++ b/mysql-test/main/explain_json_format_partitions.result @@ -80,7 +80,8 @@ ANALYZE "rows": 10, "r_rows": 10, "r_filtered": 30, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED, "attached_condition": "t1.a in (2,3,4)" } @@ -104,7 +105,8 @@ ANALYZE "rows": 10, "r_rows": 10, "r_filtered": 0, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED, "attached_condition": "t1.a in (20,30,40)" } diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index f9e505796ac..b3b438b4d02 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -2686,6 +2686,12 @@ json_detailed('[[123],456]') [123], 456 ] +# +# MDEV-37428 JSON_VALUE returns NULL for a key with an empty string value rather than an empty string +# +SELECT JSON_VALUE(JSON_OBJECT("a", ""), '$.a') = "" AS not_null; +not_null +1 # End of 10.11 Test # # MDEV-32007: JSON_VALUE and JSON_EXTRACT doesn't handle dash (-) diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index 821769d1de4..ffebbceb53e 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -1949,6 +1949,12 @@ select json_detailed('[[123],456]'); set @@collation_connection=@save_collation_connection; select json_detailed('[[123],456]'); +--echo # +--echo # MDEV-37428 JSON_VALUE returns NULL for a key with an empty string value rather than an empty string +--echo # + +SELECT JSON_VALUE(JSON_OBJECT("a", ""), '$.a') = "" AS not_null; + --echo # End of 10.11 Test --echo # diff --git a/mysql-test/main/information_schema.test b/mysql-test/main/information_schema.test index 99e88c4f413..1ce70a52b34 100644 --- a/mysql-test/main/information_schema.test +++ b/mysql-test/main/information_schema.test @@ -1,6 +1,7 @@ # This test uses grants, which can't get tested for embedded server -- source include/not_embedded.inc -- source include/have_perfschema.inc +-- source include/have_profiling.inc # check that CSV engine was compiled in, as the result of the test depends # on the presence of the log tables (which are CSV-based). diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result index 55cc07ce067..b195e1f7995 100644 --- a/mysql-test/main/long_unique_bugs.result +++ b/mysql-test/main/long_unique_bugs.result @@ -843,3 +843,11 @@ insert into t (a) values (1); update t set a=2; drop table t; # End of 10.6 tests +# +# MDEV-37404 InnoDB: Failing assertion: node->pcur->rel_pos == BTR_PCUR_ON +# +create table t(c int primary key, c2 blob unique) engine=innodb; +insert into t values (0, ''); +replace into t values (0, '123'); +drop table t; +# End of 10.11 tests diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test index 256cfcf286f..fc171e67411 100644 --- a/mysql-test/main/long_unique_bugs.test +++ b/mysql-test/main/long_unique_bugs.test @@ -767,3 +767,13 @@ update t set a=2; drop table t; --echo # End of 10.6 tests + +--echo # +--echo # MDEV-37404 InnoDB: Failing assertion: node->pcur->rel_pos == BTR_PCUR_ON +--echo # +create table t(c int primary key, c2 blob unique) engine=innodb; +insert into t values (0, ''); +replace into t values (0, '123'); +drop table t; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/subselect_mat.result b/mysql-test/main/subselect_mat.result index 4ba2b0d7a42..6ac666958e4 100644 --- a/mysql-test/main/subselect_mat.result +++ b/mysql-test/main/subselect_mat.result @@ -3335,7 +3335,8 @@ ANALYZE "rows": 4, "r_rows": 4, "r_filtered": 25, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED, "attached_condition": "!((t1.a,t1.a in (subquery#2)))" }, @@ -3413,7 +3414,8 @@ ANALYZE "rows": 2, "r_rows": 2, "r_filtered": 0, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED, "attached_condition": "!((t1.a,t1.a in (subquery#2)))" }, diff --git a/mysql-test/main/type_num_innodb.result b/mysql-test/main/type_num_innodb.result index 72e7752b3d1..76ab147ea7e 100644 --- a/mysql-test/main/type_num_innodb.result +++ b/mysql-test/main/type_num_innodb.result @@ -46,70 +46,23 @@ ALTER TABLE t1 MODIFY a DECIMAL(10,0); SELECT * FROM t1,t2 WHERE a=d; a b c pk d e Warnings: -Warning 1292 Truncated incorrect DOUBLE value: 'd' -Warning 1292 Truncated incorrect DOUBLE value: 'd' -Warning 1292 Truncated incorrect DOUBLE value: 'f' -Warning 1292 Truncated incorrect DOUBLE value: 'f' -Warning 1292 Truncated incorrect DOUBLE value: 'g' -Warning 1292 Truncated incorrect DOUBLE value: 'k' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'o' -Warning 1292 Truncated incorrect DOUBLE value: 'q' -Warning 1292 Truncated incorrect DOUBLE value: 'r' -Warning 1292 Truncated incorrect DOUBLE value: 'u' -Warning 1292 Truncated incorrect DOUBLE value: 'w' -Warning 1292 Truncated incorrect DOUBLE value: 'x' -Warning 1292 Truncated incorrect DOUBLE value: 'x' -Warning 1292 Truncated incorrect DOUBLE value: 'y' -Warning 1292 Truncated incorrect DOUBLE value: 'd' -Warning 1292 Truncated incorrect DOUBLE value: 'd' -Warning 1292 Truncated incorrect DOUBLE value: 'f' -Warning 1292 Truncated incorrect DOUBLE value: 'f' -Warning 1292 Truncated incorrect DOUBLE value: 'g' -Warning 1292 Truncated incorrect DOUBLE value: 'k' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'o' -Warning 1292 Truncated incorrect DOUBLE value: 'q' -Warning 1292 Truncated incorrect DOUBLE value: 'r' -Warning 1292 Truncated incorrect DOUBLE value: 'u' -Warning 1292 Truncated incorrect DOUBLE value: 'w' -Warning 1292 Truncated incorrect DOUBLE value: 'x' -Warning 1292 Truncated incorrect DOUBLE value: 'x' -Warning 1292 Truncated incorrect DOUBLE value: 'y' -Warning 1292 Truncated incorrect DOUBLE value: 'd' -Warning 1292 Truncated incorrect DOUBLE value: 'd' -Warning 1292 Truncated incorrect DOUBLE value: 'f' -Warning 1292 Truncated incorrect DOUBLE value: 'f' -Warning 1292 Truncated incorrect DOUBLE value: 'g' -Warning 1292 Truncated incorrect DOUBLE value: 'k' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'o' -Warning 1292 Truncated incorrect DOUBLE value: 'q' -Warning 1292 Truncated incorrect DOUBLE value: 'r' -Warning 1292 Truncated incorrect DOUBLE value: 'u' -Warning 1292 Truncated incorrect DOUBLE value: 'w' -Warning 1292 Truncated incorrect DOUBLE value: 'x' -Warning 1292 Truncated incorrect DOUBLE value: 'x' -Warning 1292 Truncated incorrect DOUBLE value: 'y' -Warning 1292 Truncated incorrect DOUBLE value: 'd' -Warning 1292 Truncated incorrect DOUBLE value: 'd' -Warning 1292 Truncated incorrect DOUBLE value: 'f' -Warning 1292 Truncated incorrect DOUBLE value: 'f' -Warning 1292 Truncated incorrect DOUBLE value: 'g' -Warning 1292 Truncated incorrect DOUBLE value: 'k' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'o' -Warning 1292 Truncated incorrect DOUBLE value: 'q' -Warning 1292 Truncated incorrect DOUBLE value: 'r' -Warning 1292 Truncated incorrect DOUBLE value: 'u' +Warning 1292 Truncated incorrect DECIMAL value: 'd' +Warning 1292 Truncated incorrect DECIMAL value: 'd' +Warning 1292 Truncated incorrect DECIMAL value: 'f' +Warning 1292 Truncated incorrect DECIMAL value: 'f' +Warning 1292 Truncated incorrect DECIMAL value: 'g' +Warning 1292 Truncated incorrect DECIMAL value: 'k' +Warning 1292 Truncated incorrect DECIMAL value: 'm' +Warning 1292 Truncated incorrect DECIMAL value: 'm' +Warning 1292 Truncated incorrect DECIMAL value: 'm' +Warning 1292 Truncated incorrect DECIMAL value: 'o' +Warning 1292 Truncated incorrect DECIMAL value: 'q' +Warning 1292 Truncated incorrect DECIMAL value: 'r' +Warning 1292 Truncated incorrect DECIMAL value: 'u' +Warning 1292 Truncated incorrect DECIMAL value: 'w' +Warning 1292 Truncated incorrect DECIMAL value: 'x' +Warning 1292 Truncated incorrect DECIMAL value: 'x' +Warning 1292 Truncated incorrect DECIMAL value: 'y' ALTER TABLE t1 MODIFY a DOUBLE; SELECT * FROM t1,t2 WHERE a=d; a b c pk d e @@ -131,53 +84,6 @@ Warning 1292 Truncated incorrect DOUBLE value: 'w' Warning 1292 Truncated incorrect DOUBLE value: 'x' Warning 1292 Truncated incorrect DOUBLE value: 'x' Warning 1292 Truncated incorrect DOUBLE value: 'y' -Warning 1292 Truncated incorrect DOUBLE value: 'd' -Warning 1292 Truncated incorrect DOUBLE value: 'd' -Warning 1292 Truncated incorrect DOUBLE value: 'f' -Warning 1292 Truncated incorrect DOUBLE value: 'f' -Warning 1292 Truncated incorrect DOUBLE value: 'g' -Warning 1292 Truncated incorrect DOUBLE value: 'k' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'o' -Warning 1292 Truncated incorrect DOUBLE value: 'q' -Warning 1292 Truncated incorrect DOUBLE value: 'r' -Warning 1292 Truncated incorrect DOUBLE value: 'u' -Warning 1292 Truncated incorrect DOUBLE value: 'w' -Warning 1292 Truncated incorrect DOUBLE value: 'x' -Warning 1292 Truncated incorrect DOUBLE value: 'x' -Warning 1292 Truncated incorrect DOUBLE value: 'y' -Warning 1292 Truncated incorrect DOUBLE value: 'd' -Warning 1292 Truncated incorrect DOUBLE value: 'd' -Warning 1292 Truncated incorrect DOUBLE value: 'f' -Warning 1292 Truncated incorrect DOUBLE value: 'f' -Warning 1292 Truncated incorrect DOUBLE value: 'g' -Warning 1292 Truncated incorrect DOUBLE value: 'k' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'o' -Warning 1292 Truncated incorrect DOUBLE value: 'q' -Warning 1292 Truncated incorrect DOUBLE value: 'r' -Warning 1292 Truncated incorrect DOUBLE value: 'u' -Warning 1292 Truncated incorrect DOUBLE value: 'w' -Warning 1292 Truncated incorrect DOUBLE value: 'x' -Warning 1292 Truncated incorrect DOUBLE value: 'x' -Warning 1292 Truncated incorrect DOUBLE value: 'y' -Warning 1292 Truncated incorrect DOUBLE value: 'd' -Warning 1292 Truncated incorrect DOUBLE value: 'd' -Warning 1292 Truncated incorrect DOUBLE value: 'f' -Warning 1292 Truncated incorrect DOUBLE value: 'f' -Warning 1292 Truncated incorrect DOUBLE value: 'g' -Warning 1292 Truncated incorrect DOUBLE value: 'k' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'm' -Warning 1292 Truncated incorrect DOUBLE value: 'o' -Warning 1292 Truncated incorrect DOUBLE value: 'q' -Warning 1292 Truncated incorrect DOUBLE value: 'r' -Warning 1292 Truncated incorrect DOUBLE value: 'u' DROP TABLE t1,t2; # # End of 10.2 tests diff --git a/mysql-test/suite/encryption/r/innodb-read-only.result b/mysql-test/suite/encryption/r/innodb-read-only.result index 35ba28dbe1e..3d23d3142f4 100644 --- a/mysql-test/suite/encryption/r/innodb-read-only.result +++ b/mysql-test/suite/encryption/r/innodb-read-only.result @@ -1,4 +1,16 @@ # Wait max 10 min for key encryption threads to encrypt all spaces # Success! +SET GLOBAL innodb_encryption_threads=4; +SELECT COUNT(*) AS encrypt_threads_running +FROM performance_schema.threads +WHERE NAME LIKE '%encrypt%'; +encrypt_threads_running +4 # restart: --innodb-read-only=1 --innodb-encrypt-tables=1 +SET GLOBAL innodb_encryption_threads=4; +SELECT COUNT(*) AS encrypt_threads_running +FROM performance_schema.threads +WHERE NAME LIKE '%encrypt%'; +encrypt_threads_running +0 # All done diff --git a/mysql-test/suite/encryption/t/innodb-read-only.test b/mysql-test/suite/encryption/t/innodb-read-only.test index 10ec87467b6..d51825e1da5 100644 --- a/mysql-test/suite/encryption/t/innodb-read-only.test +++ b/mysql-test/suite/encryption/t/innodb-read-only.test @@ -25,10 +25,22 @@ if (!$success) } --echo # Success! +# Server in normal mode +SET GLOBAL innodb_encryption_threads=4; +SELECT COUNT(*) AS encrypt_threads_running +FROM performance_schema.threads +WHERE NAME LIKE '%encrypt%'; + # # MDEV-11835: InnoDB: Failing assertion: free_slot != NULL on # restarting server with encryption and read-only # --let $restart_parameters= --innodb-read-only=1 --innodb-encrypt-tables=1 --source include/restart_mysqld.inc + +# Server read-only mode +SET GLOBAL innodb_encryption_threads=4; +SELECT COUNT(*) AS encrypt_threads_running +FROM performance_schema.threads +WHERE NAME LIKE '%encrypt%'; --echo # All done diff --git a/mysql-test/suite/galera/r/galera_partitioned_tables.result b/mysql-test/suite/galera/r/galera_partitioned_tables.result index b68c1786ff7..dab39fe0493 100644 --- a/mysql-test/suite/galera/r/galera_partitioned_tables.result +++ b/mysql-test/suite/galera/r/galera_partitioned_tables.result @@ -94,8 +94,6 @@ ALTER TABLE t1 ADD COLUMN v2 int; ALTER TABLE t2 ADD COLUMN v2 int; ERROR HY000: Galera replication not supported INSERT INTO t1 VALUES (1,1),(2,2); -Warnings: -Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine partition for table 'test'.'t1' is not supported in Galera INSERT INTO t2 VALUES (1),(2); Warnings: Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine partition for table 'test'.'t2' is not supported in Galera @@ -104,8 +102,6 @@ ERROR HY000: Galera replication not supported ALTER TABLE t2 ADD COLUMN v3 int, ENGINE=Aria; ERROR HY000: Galera replication not supported UPDATE t1 SET v2 = v2 + 3; -Warnings: -Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine partition for table 'test'.'t1' is not supported in Galera UPDATE t2 SET v1 = v1 + 3; Warnings: Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine partition for table 'test'.'t2' is not supported in Galera @@ -173,4 +169,61 @@ SELECT @@wsrep_mode; STRICT_REPLICATION ALTER TABLE t2 ENGINE=InnoDB; DROP TABLE t2; -SET GLOBAL wsrep_mode = DEFAULT; +connection node_1; +# +# MDEV-37373 InnoDB partition table disallow local GTIDs in galera +# wsrep-mode= DISALLOW_LOCAL_GTID +# +SET GLOBAL wsrep_mode = "DISALLOW_LOCAL_GTID"; +SELECT @@wsrep_mode; +@@wsrep_mode +DISALLOW_LOCAL_GTID +CREATE TABLE `sales` ( +`customer_id` int(11) NOT NULL, +`customer_name` varchar(40) DEFAULT NULL, +`store_id` varchar(20) NOT NULL, +`bill_number` int(11) NOT NULL, +`bill_date` date NOT NULL, +`amount` decimal(8,2) NOT NULL, +PRIMARY KEY (`bill_date`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +PARTITION BY RANGE (year(`bill_date`)) +(PARTITION `p0` VALUES LESS THAN (2016) ENGINE = InnoDB, +PARTITION `p1` VALUES LESS THAN (2017) ENGINE = InnoDB, +PARTITION `p2` VALUES LESS THAN (2018) ENGINE = InnoDB, +PARTITION `p3` VALUES LESS THAN (2020) ENGINE = InnoDB); +INSERT INTO sales +VALUES (1, 'Michael', 'S001', 101, '2015-01-02', 125.56), +(2, 'Jim', 'S003', 103, '2015-01-25', 476.50), +(3, 'Dwight', 'S012', 122, '2016-02-15', 335.00), +(4, 'Andy', 'S345', 121, '2016-03-26', 787.00), +(5, 'Pam', 'S234', 132, '2017-04-19', 678.00), +(6, 'Karen', 'S743', 111, '2017-05-31', 864.00), +(7, 'Toby', 'S234', 115, '2018-06-11', 762.00), +(8, 'Oscar', 'S012', 125, '2019-07-24', 300.00), +(9, 'Darryl', 'S456', 119, '2019-08-02', 492.20); +SELECT * FROM sales; +customer_id customer_name store_id bill_number bill_date amount +1 Michael S001 101 2015-01-02 125.56 +2 Jim S003 103 2015-01-25 476.50 +3 Dwight S012 122 2016-02-15 335.00 +4 Andy S345 121 2016-03-26 787.00 +5 Pam S234 132 2017-04-19 678.00 +6 Karen S743 111 2017-05-31 864.00 +7 Toby S234 115 2018-06-11 762.00 +8 Oscar S012 125 2019-07-24 300.00 +9 Darryl S456 119 2019-08-02 492.20 +SET GLOBAL wsrep_mode=DEFAULT; +connection node_2; +SELECT * FROM sales; +customer_id customer_name store_id bill_number bill_date amount +1 Michael S001 101 2015-01-02 125.56 +2 Jim S003 103 2015-01-25 476.50 +3 Dwight S012 122 2016-02-15 335.00 +4 Andy S345 121 2016-03-26 787.00 +5 Pam S234 132 2017-04-19 678.00 +6 Karen S743 111 2017-05-31 864.00 +7 Toby S234 115 2018-06-11 762.00 +8 Oscar S012 125 2019-07-24 300.00 +9 Darryl S456 119 2019-08-02 492.20 +DROP TABLE sales; diff --git a/mysql-test/suite/galera/t/galera_partitioned_tables.combinations b/mysql-test/suite/galera/t/galera_partitioned_tables.combinations new file mode 100644 index 00000000000..cef98e75213 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_partitioned_tables.combinations @@ -0,0 +1,5 @@ +[binlogon] +log-bin +log-slave-updates + +[binlogoff] diff --git a/mysql-test/suite/galera/t/galera_partitioned_tables.test b/mysql-test/suite/galera/t/galera_partitioned_tables.test index 8e52b59d97d..41d2689f171 100644 --- a/mysql-test/suite/galera/t/galera_partitioned_tables.test +++ b/mysql-test/suite/galera/t/galera_partitioned_tables.test @@ -130,4 +130,41 @@ SELECT @@wsrep_mode; ALTER TABLE t2 ENGINE=InnoDB; DROP TABLE t2; -SET GLOBAL wsrep_mode = DEFAULT; +--connection node_1 +--echo # +--echo # MDEV-37373 InnoDB partition table disallow local GTIDs in galera +--echo # wsrep-mode= DISALLOW_LOCAL_GTID +--echo # +SET GLOBAL wsrep_mode = "DISALLOW_LOCAL_GTID"; +SELECT @@wsrep_mode; +CREATE TABLE `sales` ( + `customer_id` int(11) NOT NULL, + `customer_name` varchar(40) DEFAULT NULL, + `store_id` varchar(20) NOT NULL, + `bill_number` int(11) NOT NULL, + `bill_date` date NOT NULL, + `amount` decimal(8,2) NOT NULL, + PRIMARY KEY (`bill_date`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY RANGE (year(`bill_date`)) +(PARTITION `p0` VALUES LESS THAN (2016) ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN (2017) ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN (2018) ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN (2020) ENGINE = InnoDB); + +INSERT INTO sales +VALUES (1, 'Michael', 'S001', 101, '2015-01-02', 125.56), +(2, 'Jim', 'S003', 103, '2015-01-25', 476.50), +(3, 'Dwight', 'S012', 122, '2016-02-15', 335.00), +(4, 'Andy', 'S345', 121, '2016-03-26', 787.00), +(5, 'Pam', 'S234', 132, '2017-04-19', 678.00), +(6, 'Karen', 'S743', 111, '2017-05-31', 864.00), +(7, 'Toby', 'S234', 115, '2018-06-11', 762.00), +(8, 'Oscar', 'S012', 125, '2019-07-24', 300.00), +(9, 'Darryl', 'S456', 119, '2019-08-02', 492.20); + +SELECT * FROM sales; +SET GLOBAL wsrep_mode=DEFAULT; +--connection node_2 +SELECT * FROM sales; +DROP TABLE sales; \ No newline at end of file diff --git a/mysql-test/suite/galera_3nodes/r/galera_vote_majority_dml.result b/mysql-test/suite/galera_3nodes/r/galera_vote_majority_dml.result new file mode 100644 index 00000000000..cef1583eebc --- /dev/null +++ b/mysql-test/suite/galera_3nodes/r/galera_vote_majority_dml.result @@ -0,0 +1,70 @@ +connection node_2; +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 BLOB) ENGINE=InnoDB; +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connection node_3; +SET GLOBAL wsrep_on=OFF; +ALTER TABLE t1 MODIFY f2 LONGTEXT; +SET GLOBAL wsrep_on=ON; +INSERT INTO t1 VALUES (3, 'a'); +connection node_1; +SHOW STATUS LIKE 'wsrep_cluster_status'; +Variable_name Value +wsrep_cluster_status Primary +connection node_2; +SHOW STATUS LIKE 'wsrep_cluster_status'; +Variable_name Value +wsrep_cluster_status Primary +INSERT INTO t1 VALUES (2, 'a'); +connection node_3; +SET SESSION wsrep_sync_wait=0; +SET SESSION wsrep_on=OFF; +# restart +SET SESSION wsrep_on=ON; +INSERT INTO t1 VALUES (3, 'a'); +connection node_1; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + `f2` blob DEFAULT NULL, + PRIMARY KEY (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * FROM t1; +f1 f2 +2 a +3 a +connection node_2; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + `f2` blob DEFAULT NULL, + PRIMARY KEY (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * FROM t1; +f1 f2 +2 a +3 a +connection node_3; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + `f2` blob DEFAULT NULL, + PRIMARY KEY (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * FROM t1; +f1 f2 +2 a +3 a +DROP TABLE t1; +connection node_1; +CALL mtr.add_suppression("Replica SQL: Column 1 of table 'test.t1' cannot be converted from type 'longblob' to type 'blob', Error_code: MY-013146"); +CALL mtr.add_suppression("Event 3 Write_rows_v1 apply failed: 3, seqno"); +connection node_2; +CALL mtr.add_suppression("Replica SQL: Column 1 of table 'test.t1' cannot be converted from type 'longblob' to type 'blob', Error_code: MY-013146"); +CALL mtr.add_suppression("Event 3 Write_rows_v1 apply failed: 3, seqno"); +connection node_3; +CALL mtr.add_suppression("Vote 0 \\(success\\) on (.*) is inconsistent with group. Leaving cluster."); +CALL mtr.add_suppression("Plugin 'InnoDB' will be forced to shutdown"); diff --git a/mysql-test/suite/galera_3nodes/t/galera_vote_majority_dml.cnf b/mysql-test/suite/galera_3nodes/t/galera_vote_majority_dml.cnf new file mode 100644 index 00000000000..fcda8c89526 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_vote_majority_dml.cnf @@ -0,0 +1,5 @@ +!include ../galera_3nodes.cnf + +[mysqld] +wsrep-ignore-apply-errors=0 + diff --git a/mysql-test/suite/galera_3nodes/t/galera_vote_majority_dml.test b/mysql-test/suite/galera_3nodes/t/galera_vote_majority_dml.test new file mode 100644 index 00000000000..606fe06ce65 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_vote_majority_dml.test @@ -0,0 +1,67 @@ +# +# MDEV-37494: Inconsistency voting: create conditions where applying would +# fail on replicas in table_def::compatible_with() and check that +# that replicas survive and the primary (trx source) bails out. +# +--source include/galera_cluster.inc + +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 BLOB) ENGINE=InnoDB; + +--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 +--connection node_3 +SET GLOBAL wsrep_on=OFF; +ALTER TABLE t1 MODIFY f2 LONGTEXT; # Introducing schema inconsistency +SET GLOBAL wsrep_on=ON; +INSERT INTO t1 VALUES (3, 'a'); # Nodes 1 and 2 should fail to apply this + +--connection node_1 +# Wait until node #3 leaves the cluster +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +SHOW STATUS LIKE 'wsrep_cluster_status'; + +--connection node_2 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_size' +# Wait until node #3 leaves the cluster +--source include/wait_condition.inc +SHOW STATUS LIKE 'wsrep_cluster_status'; + +INSERT INTO t1 VALUES (2, 'a'); # Nodes 1 and 2 should successfully apply this + +--connection node_3 +SET SESSION wsrep_sync_wait=0; +--let $wait_condition = SELECT VARIABLE_VALUE = 'Disconnected' FROM performance_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +--source include/wait_condition.inc +SET SESSION wsrep_on=OFF; +--source include/restart_mysqld.inc +--source include/wait_wsrep_ready.inc +SET SESSION wsrep_on=ON; + +INSERT INTO t1 VALUES (3, 'a'); # All nodes should successfully apply this + +# Check that consistency is restored +--connection node_1 +SHOW CREATE TABLE t1; +SELECT * FROM t1; + +--connection node_2 +SHOW CREATE TABLE t1; +SELECT * FROM t1; + +--connection node_3 +SHOW CREATE TABLE t1; +SELECT * FROM t1; + +DROP TABLE t1; + +--connection node_1 +CALL mtr.add_suppression("Replica SQL: Column 1 of table 'test.t1' cannot be converted from type 'longblob' to type 'blob', Error_code: MY-013146"); +CALL mtr.add_suppression("Event 3 Write_rows_v1 apply failed: 3, seqno"); + +--connection node_2 +CALL mtr.add_suppression("Replica SQL: Column 1 of table 'test.t1' cannot be converted from type 'longblob' to type 'blob', Error_code: MY-013146"); +CALL mtr.add_suppression("Event 3 Write_rows_v1 apply failed: 3, seqno"); + +--connection node_3 +CALL mtr.add_suppression("Vote 0 \\(success\\) on (.*) is inconsistent with group. Leaving cluster."); +CALL mtr.add_suppression("Plugin 'InnoDB' will be forced to shutdown"); diff --git a/mysql-test/suite/innodb/r/alter_copy_stats.result b/mysql-test/suite/innodb/r/alter_copy_stats.result new file mode 100644 index 00000000000..15913a44f55 --- /dev/null +++ b/mysql-test/suite/innodb/r/alter_copy_stats.result @@ -0,0 +1,105 @@ +CREATE TABLE t1 ( +c1 INT PRIMARY KEY, +c2 VARCHAR(50), +c3 VARCHAR(50), +c4 VARCHAR(50))ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, 'AAA_2', 'AAA_3', 'AAA_4'), +(2, 'BBB_2', 'BBB_3', 'BBB_4'), +(3, 'CCC_2', 'CCC_3', 'CCC_4'), +(4, 'DDD_2', 'DDD_3', 'DDD_4'), +(5, 'EEE_2', 'EEE_3', 'EEE_4'); +ALTER TABLE t1 CONVERT TO CHARACTER SET 'utf8mb4',ALGORITHM=COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); +n_rows database_name lower(table_name) +5 test t1 +ALTER TABLE t1 ADD COLUMN c5 VARCHAR(15), ALGORITHM = COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); +n_rows database_name lower(table_name) +5 test t1 +ALTER TABLE t1 DROP COLUMN c5, ALGORITHM = COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); +n_rows database_name lower(table_name) +5 test t1 +ALTER TABLE t1 ADD COLUMN c5 VARCHAR(15), ALGORITHM = COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); +n_rows database_name lower(table_name) +5 test t1 +ALTER TABLE t1 DROP COLUMN c5, ALGORITHM = COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); +n_rows database_name lower(table_name) +5 test t1 +ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY (c4), ALGORITHM=COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); +n_rows database_name lower(table_name) +5 test t1 +ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY (c1), ALGORITHM = COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); +n_rows database_name lower(table_name) +5 test t1 +ALTER TABLE t1 ADD COLUMN c5 VARCHAR(15), ALGORITHM = INPLACE; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); +n_rows database_name lower(table_name) +5 test t1 +ALTER TABLE t1 DROP COLUMN c5, ALGORITHM = INPLACE; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); +n_rows database_name lower(table_name) +5 test t1 +CREATE TABLE t2 ( +c1 INT PRIMARY KEY, +c2 VARCHAR(50), +c3 VARCHAR(50), +c4 VARCHAR(50) +) ENGINE=InnoDB PARTITION BY RANGE (c1) ( +PARTITION p1 VALUES LESS THAN (6), +PARTITION p2 VALUES LESS THAN (11), +PARTITION p3 VALUES LESS THAN (16), +PARTITION p4 VALUES LESS THAN (21) +); +INSERT INTO t2 VALUES(1, 'AAA_2', 'AAA_3', 'AAA_4'), +(2, 'BBB_2', 'BBB_3', 'BBB_4'), +(3, 'CCC_2', 'CCC_3', 'CCC_4'), +(4, 'DDD_2', 'DDD_3', 'DDD_4'), +(5, 'EEE_2', 'EEE_3', 'EEE_4'), +(6, 'FFF_2', 'DDD_3', 'DDD_4'), +(7, 'GGG_2', 'DDD_3', 'DDD_4'), +(8, 'HHH_2', 'DDD_3', 'DDD_4'), +(9, 'III_2', 'DDD_3', 'DDD_4'), +(10, 'JJJ_2', 'DDD_3', 'DDD_4'), +(13, 'KKK_2', 'DDD_3', 'DDD_4'), +(20, 'LLL_2', 'DDD_3', 'DDD_4'); +ALTER TABLE t2 CONVERT TO CHARACTER SET 'utf8mb4',ALGORITHM=COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name LIKE '%t2%'; +n_rows database_name lower(table_name) +5 test t2#p#p1 +5 test t2#p#p2 +1 test t2#p#p3 +1 test t2#p#p4 +ALTER TABLE t2 ADD COLUMN c5 VARCHAR(15), ALGORITHM = COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name LIKE '%t2%'; +n_rows database_name lower(table_name) +5 test t2#p#p1 +5 test t2#p#p2 +1 test t2#p#p3 +1 test t2#p#p4 +ALTER TABLE t2 DROP COLUMN c5, ALGORITHM = COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name LIKE '%t2%'; +n_rows database_name lower(table_name) +5 test t2#p#p1 +5 test t2#p#p2 +1 test t2#p#p3 +1 test t2#p#p4 +# Test Cleanup. +DROP TABLE t1; +DROP TABLE t2; diff --git a/mysql-test/suite/innodb/r/innodb-alter-debug.result b/mysql-test/suite/innodb/r/innodb-alter-debug.result index fd33581ffab..d1d72a375fd 100644 --- a/mysql-test/suite/innodb/r/innodb-alter-debug.result +++ b/mysql-test/suite/innodb/r/innodb-alter-debug.result @@ -117,8 +117,9 @@ ALTER TABLE t1 FORCE, ALGORITHM=COPY; connection default; SET DEBUG_SYNC='now WAIT_FOR blocked'; BEGIN; -SELECT * FROM mysql.innodb_table_stats FOR UPDATE; -database_name table_name last_update n_rows clustered_index_size sum_of_other_index_sizes +SELECT database_name, table_name FROM mysql.innodb_table_stats FOR UPDATE; +database_name table_name +test t1 SET DEBUG_SYNC='now SIGNAL go'; connection con1; connection default; diff --git a/mysql-test/suite/innodb/r/xap_release_locks_on_dict_stats_table.result b/mysql-test/suite/innodb/r/xap_release_locks_on_dict_stats_table.result index 1a849f1c477..a2f25c528f4 100644 --- a/mysql-test/suite/innodb/r/xap_release_locks_on_dict_stats_table.result +++ b/mysql-test/suite/innodb/r/xap_release_locks_on_dict_stats_table.result @@ -6,7 +6,7 @@ SET @old_debug_dbug = @@global.debug_dbug; XA START 'a'; INSERT INTO mysql.innodb_index_stats SELECT '','' AS table_name,index_name,LAST_UPDATE,stat_name,0 AS stat_value,sample_size,stat_description FROM mysql.innodb_index_stats WHERE table_name='dummy' FOR UPDATE; SET GLOBAL debug_dbug = "+d,dict_stats_save_exit_notify"; -INSERT INTO t VALUES (1); +INSERT INTO t VALUES (1), (2); XA END 'a'; XA PREPARE 'a'; SET DEBUG_SYNC="now WAIT_FOR dict_stats_save_finished"; diff --git a/mysql-test/suite/innodb/t/alter_copy_stats.test b/mysql-test/suite/innodb/t/alter_copy_stats.test new file mode 100644 index 00000000000..3b0c59d5726 --- /dev/null +++ b/mysql-test/suite/innodb/t/alter_copy_stats.test @@ -0,0 +1,90 @@ +--source include/have_innodb.inc +--source include/have_partition.inc + +CREATE TABLE t1 ( + c1 INT PRIMARY KEY, + c2 VARCHAR(50), + c3 VARCHAR(50), + c4 VARCHAR(50))ENGINE=InnoDB; + +INSERT INTO t1 VALUES(1, 'AAA_2', 'AAA_3', 'AAA_4'), + (2, 'BBB_2', 'BBB_3', 'BBB_4'), + (3, 'CCC_2', 'CCC_3', 'CCC_4'), + (4, 'DDD_2', 'DDD_3', 'DDD_4'), + (5, 'EEE_2', 'EEE_3', 'EEE_4'); + +ALTER TABLE t1 CONVERT TO CHARACTER SET 'utf8mb4',ALGORITHM=COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); + +ALTER TABLE t1 ADD COLUMN c5 VARCHAR(15), ALGORITHM = COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); + +ALTER TABLE t1 DROP COLUMN c5, ALGORITHM = COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); + +ALTER TABLE t1 ADD COLUMN c5 VARCHAR(15), ALGORITHM = COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); + +ALTER TABLE t1 DROP COLUMN c5, ALGORITHM = COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); + +ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY (c4), ALGORITHM=COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); + +ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY (c1), ALGORITHM = COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); + +ALTER TABLE t1 ADD COLUMN c5 VARCHAR(15), ALGORITHM = INPLACE; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); + +ALTER TABLE t1 DROP COLUMN c5, ALGORITHM = INPLACE; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name IN ('t1'); + +CREATE TABLE t2 ( + c1 INT PRIMARY KEY, + c2 VARCHAR(50), + c3 VARCHAR(50), + c4 VARCHAR(50) + ) ENGINE=InnoDB PARTITION BY RANGE (c1) ( + PARTITION p1 VALUES LESS THAN (6), + PARTITION p2 VALUES LESS THAN (11), + PARTITION p3 VALUES LESS THAN (16), + PARTITION p4 VALUES LESS THAN (21) +); +INSERT INTO t2 VALUES(1, 'AAA_2', 'AAA_3', 'AAA_4'), + (2, 'BBB_2', 'BBB_3', 'BBB_4'), + (3, 'CCC_2', 'CCC_3', 'CCC_4'), + (4, 'DDD_2', 'DDD_3', 'DDD_4'), + (5, 'EEE_2', 'EEE_3', 'EEE_4'), + (6, 'FFF_2', 'DDD_3', 'DDD_4'), + (7, 'GGG_2', 'DDD_3', 'DDD_4'), + (8, 'HHH_2', 'DDD_3', 'DDD_4'), + (9, 'III_2', 'DDD_3', 'DDD_4'), + (10, 'JJJ_2', 'DDD_3', 'DDD_4'), + (13, 'KKK_2', 'DDD_3', 'DDD_4'), + (20, 'LLL_2', 'DDD_3', 'DDD_4'); + +ALTER TABLE t2 CONVERT TO CHARACTER SET 'utf8mb4',ALGORITHM=COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name LIKE '%t2%'; + +ALTER TABLE t2 ADD COLUMN c5 VARCHAR(15), ALGORITHM = COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name LIKE '%t2%'; + +ALTER TABLE t2 DROP COLUMN c5, ALGORITHM = COPY; +SELECT n_rows, database_name, lower(table_name) +FROM mysql.innodb_table_stats WHERE table_name LIKE '%t2%'; + +--echo # Test Cleanup. +DROP TABLE t1; +DROP TABLE t2; diff --git a/mysql-test/suite/innodb/t/innodb-alter-debug.test b/mysql-test/suite/innodb/t/innodb-alter-debug.test index 6b94bfd214f..ee899f813c2 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-debug.test +++ b/mysql-test/suite/innodb/t/innodb-alter-debug.test @@ -156,7 +156,7 @@ ALTER TABLE t1 FORCE, ALGORITHM=COPY; connection default; SET DEBUG_SYNC='now WAIT_FOR blocked'; BEGIN; -SELECT * FROM mysql.innodb_table_stats FOR UPDATE; +SELECT database_name, table_name FROM mysql.innodb_table_stats FOR UPDATE; SET DEBUG_SYNC='now SIGNAL go'; connection con1; diff --git a/mysql-test/suite/innodb/t/xap_release_locks_on_dict_stats_table.test b/mysql-test/suite/innodb/t/xap_release_locks_on_dict_stats_table.test index a02a032ef61..0de3e6f24ef 100644 --- a/mysql-test/suite/innodb/t/xap_release_locks_on_dict_stats_table.test +++ b/mysql-test/suite/innodb/t/xap_release_locks_on_dict_stats_table.test @@ -20,7 +20,7 @@ SET @old_debug_dbug = @@global.debug_dbug; XA START 'a'; INSERT INTO mysql.innodb_index_stats SELECT '','' AS table_name,index_name,LAST_UPDATE,stat_name,0 AS stat_value,sample_size,stat_description FROM mysql.innodb_index_stats WHERE table_name='dummy' FOR UPDATE; # Note the SELECT is empty SET GLOBAL debug_dbug = "+d,dict_stats_save_exit_notify"; -INSERT INTO t VALUES (1); +INSERT INTO t VALUES (1), (2); XA END 'a'; XA PREPARE 'a'; diff --git a/mysql-test/suite/perfschema/t/max_program_zero.test b/mysql-test/suite/perfschema/t/max_program_zero.test index 064ba2ae2d9..7cbe95c1c0c 100644 --- a/mysql-test/suite/perfschema/t/max_program_zero.test +++ b/mysql-test/suite/perfschema/t/max_program_zero.test @@ -11,6 +11,7 @@ --source include/not_embedded.inc --source include/have_perfschema.inc +--source include/not_msan_with_debug.inc --source ../include/start_server_common.inc diff --git a/mysql-test/suite/perfschema/t/statement_program_lost_inst.test b/mysql-test/suite/perfschema/t/statement_program_lost_inst.test index 0742043bba3..321bb649daf 100644 --- a/mysql-test/suite/perfschema/t/statement_program_lost_inst.test +++ b/mysql-test/suite/perfschema/t/statement_program_lost_inst.test @@ -22,7 +22,7 @@ let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; --write_line wait $restart_file --shutdown_server --source include/wait_until_disconnected.inc ---write_line "restart:--performance_schema_max_program_instances=7 --performance_schema_max_statement_stack=2 --thread_stack=655360" $restart_file +--write_line "restart:--performance_schema_max_program_instances=7 --performance_schema_max_statement_stack=2 --thread_stack=1048576" $restart_file --enable_reconnect --source include/wait_until_connected_again.inc diff --git a/mysql-test/suite/perfschema/t/statement_program_nested.test b/mysql-test/suite/perfschema/t/statement_program_nested.test index 183e9858226..75218359314 100644 --- a/mysql-test/suite/perfschema/t/statement_program_nested.test +++ b/mysql-test/suite/perfschema/t/statement_program_nested.test @@ -5,6 +5,7 @@ --source include/not_embedded.inc --source include/have_perfschema.inc --source include/have_innodb.inc +--source include/not_msan_with_debug.inc TRUNCATE TABLE performance_schema.events_statements_summary_by_program; TRUNCATE TABLE performance_schema.events_statements_history_long; diff --git a/mysql-test/suite/perfschema/t/statement_program_nesting_event_check.test b/mysql-test/suite/perfschema/t/statement_program_nesting_event_check.test index 73829be8b42..31368b9f7d6 100644 --- a/mysql-test/suite/perfschema/t/statement_program_nesting_event_check.test +++ b/mysql-test/suite/perfschema/t/statement_program_nesting_event_check.test @@ -8,6 +8,7 @@ --source include/not_embedded.inc --source include/have_perfschema.inc --source include/have_innodb.inc +--source include/not_msan_with_debug.inc TRUNCATE TABLE performance_schema.events_statements_history_long; diff --git a/mysql-test/suite/plugins/r/server_audit_query_id.result b/mysql-test/suite/plugins/r/server_audit_query_id.result new file mode 100644 index 00000000000..3d2d9f18cc2 --- /dev/null +++ b/mysql-test/suite/plugins/r/server_audit_query_id.result @@ -0,0 +1,69 @@ +set global server_audit_logging=on; +USE test; +CREATE TABLE source ( +id bigint(20) NOT NULL AUTO_INCREMENT, +PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +CREATE TABLE dest ( +id bigint(20) NOT NULL, +PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +CREATE TABLE dest_2 ( +id bigint(20) NOT NULL, +PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +CREATE TRIGGER test_trigger +AFTER INSERT ON source +FOR EACH ROW +INSERT INTO dest (id) VALUES(NEW.id)// +CREATE TRIGGER test_trigger_2 +AFTER INSERT ON dest +FOR EACH ROW +INSERT INTO dest_2 (id) VALUES(NEW.id)// +CREATE PROCEDURE test_procedure (IN id bigint(20)) +NOT DETERMINISTIC MODIFIES SQL DATA +BEGIN +INSERT INTO source VALUES (id), (NULL); +END;// +# Insert a row to trigger the AFTER trigger +INSERT INTO source VALUES (NULL); +# Insert another row to see the pattern +INSERT INTO source VALUES (NULL); +# Test with multi-row insert +INSERT INTO source VALUES (NULL), (NULL); +# Test with stored procedure +CALL test_procedure(NULL); +# Clean up +DROP PROCEDURE test_procedure; +DROP TABLE source, dest, dest_2; +set global server_audit_logging=off; +# Wait for audit events to be written +FOUND 1 /set global server_audit_logging=off/ in server_audit_query_id.log +TIMESTAMP,HOSTNAME,root,localhost,4,0,QUERY,test,'set global server_audit_logging=on',0 +TIMESTAMP,HOSTNAME,root,localhost,4,1,QUERY,test,'USE test',0 +TIMESTAMP,HOSTNAME,root,localhost,4,2,QUERY,test,'CREATE TABLE source (\nid bigint(20) NOT NULL AUTO_INCREMENT,\nPRIMARY KEY (id)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4',0 +TIMESTAMP,HOSTNAME,root,localhost,4,3,QUERY,test,'CREATE TABLE dest (\nid bigint(20) NOT NULL,\nPRIMARY KEY (id)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4',0 +TIMESTAMP,HOSTNAME,root,localhost,4,4,QUERY,test,'CREATE TABLE dest_2 (\nid bigint(20) NOT NULL,\nPRIMARY KEY (id)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4',0 +TIMESTAMP,HOSTNAME,root,localhost,4,5,QUERY,test,'CREATE TRIGGER test_trigger\nAFTER INSERT ON source\nFOR EACH ROW\nINSERT INTO dest (id) VALUES(NEW.id)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,6,QUERY,test,'CREATE TRIGGER test_trigger_2\nAFTER INSERT ON dest\nFOR EACH ROW\nINSERT INTO dest_2 (id) VALUES(NEW.id)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,7,QUERY,test,'CREATE PROCEDURE test_procedure (IN id bigint(20))\nNOT DETERMINISTIC MODIFIES SQL DATA\nBEGIN\nINSERT INTO source VALUES (id), (NULL);\nEND',0 +TIMESTAMP,HOSTNAME,root,localhost,4,10,QUERY,test,'INSERT INTO dest_2 (id) VALUES(NEW.id)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,9,QUERY,test,'INSERT INTO dest (id) VALUES(NEW.id)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,8,QUERY,test,'INSERT INTO source VALUES (NULL)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,13,QUERY,test,'INSERT INTO dest_2 (id) VALUES(NEW.id)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,12,QUERY,test,'INSERT INTO dest (id) VALUES(NEW.id)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,11,QUERY,test,'INSERT INTO source VALUES (NULL)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,16,QUERY,test,'INSERT INTO dest_2 (id) VALUES(NEW.id)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,15,QUERY,test,'INSERT INTO dest (id) VALUES(NEW.id)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,18,QUERY,test,'INSERT INTO dest_2 (id) VALUES(NEW.id)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,17,QUERY,test,'INSERT INTO dest (id) VALUES(NEW.id)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,14,QUERY,test,'INSERT INTO source VALUES (NULL), (NULL)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,22,QUERY,test,'INSERT INTO dest_2 (id) VALUES(NEW.id)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,21,QUERY,test,'INSERT INTO dest (id) VALUES(NEW.id)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,24,QUERY,test,'INSERT INTO dest_2 (id) VALUES(NEW.id)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,23,QUERY,test,'INSERT INTO dest (id) VALUES(NEW.id)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,20,QUERY,test,'INSERT INTO source VALUES ( NAME_CONST(\'id\',NULL)), (NULL)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,19,QUERY,test,'CALL test_procedure(NULL)',0 +TIMESTAMP,HOSTNAME,root,localhost,4,25,QUERY,test,'DROP PROCEDURE test_procedure',0 +TIMESTAMP,HOSTNAME,root,localhost,4,26,QUERY,test,'DROP TABLE source, dest, dest_2',0 +TIMESTAMP,HOSTNAME,root,localhost,4,27,QUERY,test,'set global server_audit_logging=off',0 diff --git a/mysql-test/suite/plugins/t/normalize_query_id.pl b/mysql-test/suite/plugins/t/normalize_query_id.pl new file mode 100644 index 00000000000..601809a429d --- /dev/null +++ b/mysql-test/suite/plugins/t/normalize_query_id.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl +use strict; +use warnings; + +my $filename = $ARGV[0] or die "Usage: $0 \n"; + +# Read all lines into memory +open(my $fh, '<', $filename) or die "Cannot open file '$filename': $!"; +my @lines = <$fh>; +close($fh); + +# Process lines and normalize query IDs +my $first_id; +foreach my $line (@lines) { + if ($line =~ /,(\d+),QUERY/) { + $first_id = $1 unless defined $first_id; + my $normalized = $1 - $first_id; + $line =~ s/,$1,QUERY/,$normalized,QUERY/; + } +} + +# Write back to the same file +open($fh, '>', $filename) or die "Cannot write to file '$filename': $!"; +print $fh @lines; +close($fh); diff --git a/mysql-test/suite/plugins/t/server_audit_query_id.opt b/mysql-test/suite/plugins/t/server_audit_query_id.opt new file mode 100644 index 00000000000..869b5f81739 --- /dev/null +++ b/mysql-test/suite/plugins/t/server_audit_query_id.opt @@ -0,0 +1,5 @@ +--plugin-load-add=server_audit +--server_audit_mode=0 +--server_audit_file_path='server_audit_query_id.log' +--server_audit_output_type=file +--server_audit_events='QUERY' diff --git a/mysql-test/suite/plugins/t/server_audit_query_id.test b/mysql-test/suite/plugins/t/server_audit_query_id.test new file mode 100644 index 00000000000..0b88a6deef5 --- /dev/null +++ b/mysql-test/suite/plugins/t/server_audit_query_id.test @@ -0,0 +1,89 @@ +--source include/have_innodb.inc +--source include/have_plugin_auth.inc +--source include/not_embedded.inc + +if (!$SERVER_AUDIT_SO) { + skip No SERVER_AUDIT plugin; +} + +# An unfortunate wait for check-testcase.inc to complete disconnect. +let count_sessions= 1; +source include/wait_until_count_sessions.inc; + +let $MYSQLD_DATADIR= `SELECT @@datadir`; +let SEARCH_FILE= $MYSQLD_DATADIR/server_audit_query_id.log; + +--disable_ps_protocol + +set global server_audit_logging=on; + +USE test; + +CREATE TABLE source ( + id bigint(20) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE dest ( + id bigint(20) NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE dest_2 ( + id bigint(20) NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +DELIMITER //; +CREATE TRIGGER test_trigger +AFTER INSERT ON source +FOR EACH ROW +INSERT INTO dest (id) VALUES(NEW.id)// +DELIMITER ;// + +DELIMITER //; +CREATE TRIGGER test_trigger_2 +AFTER INSERT ON dest +FOR EACH ROW +INSERT INTO dest_2 (id) VALUES(NEW.id)// +DELIMITER ;// + +DELIMITER //; +CREATE PROCEDURE test_procedure (IN id bigint(20)) +NOT DETERMINISTIC MODIFIES SQL DATA +BEGIN + INSERT INTO source VALUES (id), (NULL); +END;// +DELIMITER ;// + +--echo # Insert a row to trigger the AFTER trigger +INSERT INTO source VALUES (NULL); + +--echo # Insert another row to see the pattern +INSERT INTO source VALUES (NULL); + +--echo # Test with multi-row insert +INSERT INTO source VALUES (NULL), (NULL); + +--echo # Test with stored procedure +CALL test_procedure(NULL); + +--echo # Clean up +DROP PROCEDURE test_procedure; +DROP TABLE source, dest, dest_2; + +set global server_audit_logging=off; + +--echo # Wait for audit events to be written +--let SEARCH_FILE = $MYSQLD_DATADIR/server_audit_query_id.log +--let SEARCH_PATTERN = set global server_audit_logging=off +--source include/search_pattern_in_file.inc + +# Read and normalize the log +--exec perl $MYSQL_TEST_DIR/suite/plugins/t/normalize_query_id.pl $SEARCH_FILE + +# Output the log without heavy replacements so we can see the actual order +--replace_regex /\d\d\d\d\d\d\d\d \d\d:\d\d:\d\d/TIMESTAMP/ /,[^,]+,root,localhost,/,HOSTNAME,root,localhost,/ + +cat_file $SEARCH_FILE; +remove_file $SEARCH_FILE; diff --git a/mysql-test/suite/sql_sequence/default.result b/mysql-test/suite/sql_sequence/default.result index fe9c6af1795..a6f6d1270f8 100644 --- a/mysql-test/suite/sql_sequence/default.result +++ b/mysql-test/suite/sql_sequence/default.result @@ -313,4 +313,37 @@ insert v1 values (default); ERROR HY000: The target table v1 of the INSERT is not insertable-into drop view v1; drop table t1; +# +# MDEV-37172 Server crashes in Item_func_nextval::update_table after +# INSERT to the table, that uses expression with nextval() as default +# +create sequence s1; +create sequence s2; +create table t1 (id int default(nextval(s1))); +create table t2 (id int default(nextval(s1)+nextval(s1))); +create table t3 (id1 int default(nextval(s1)+nextval(s1)), +id2 int default(nextval(s2))); +insert t1 values (); +select lastval(s1); +lastval(s1) +1 +select * from t1; +id +1 +insert t2 values (); +select lastval(s1); +lastval(s1) +3 +select * from t2; +id +5 +insert t3 values (); +select lastval(s1), lastval(s2); +lastval(s1) lastval(s2) +5 1 +select * from t3; +id1 id2 +9 1 +drop table t1,t2,t3; +drop sequence s1,s2; # End of 10.6 tests diff --git a/mysql-test/suite/sql_sequence/default.test b/mysql-test/suite/sql_sequence/default.test index 5cbfe237cd3..45ef4b31b5a 100644 --- a/mysql-test/suite/sql_sequence/default.test +++ b/mysql-test/suite/sql_sequence/default.test @@ -240,4 +240,27 @@ insert v1 values (default); drop view v1; drop table t1; +--echo # +--echo # MDEV-37172 Server crashes in Item_func_nextval::update_table after +--echo # INSERT to the table, that uses expression with nextval() as default +--echo # + +create sequence s1; +create sequence s2; +create table t1 (id int default(nextval(s1))); +create table t2 (id int default(nextval(s1)+nextval(s1))); +create table t3 (id1 int default(nextval(s1)+nextval(s1)), + id2 int default(nextval(s2))); +insert t1 values (); +select lastval(s1); +select * from t1; +insert t2 values (); +select lastval(s1); +select * from t2; +insert t3 values (); +select lastval(s1), lastval(s2); +select * from t3; +drop table t1,t2,t3; +drop sequence s1,s2; + --echo # End of 10.6 tests diff --git a/mysys/my_once.c b/mysys/my_once.c index b4a30da95ea..091210ebd38 100644 --- a/mysys/my_once.c +++ b/mysys/my_once.c @@ -69,6 +69,8 @@ void* my_once_alloc(size_t Size, myf MyFlags) (int64) get_size, MY_MEMORY_ORDER_RELAXED); DBUG_PRINT("test",("my_once_malloc %lu byte malloced", (ulong) get_size)); + my_once_allocated+= get_size; + update_malloc_size(get_size, 0); next->next= 0; next->size= get_size; next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM)); @@ -119,7 +121,9 @@ void my_once_free(void) old=next; next= next->next ; free((uchar*) old); } + update_malloc_size(- (longlong) my_once_allocated, 0); my_once_root_block=0; + my_once_allocated= 0; my_malloc_init_memory_allocated= 0; DBUG_VOID_RETURN; diff --git a/mysys/my_static.c b/mysys/my_static.c index 782f7ddeda6..efeb6a4568b 100644 --- a/mysys/my_static.c +++ b/mysys/my_static.c @@ -92,6 +92,7 @@ const char *soundex_map= "01230120022455012623010202"; /* from my_malloc */ USED_MEM* my_once_root_block=0; /* pointer to first block */ uint my_once_extra=ONCE_ALLOC_INIT; /* Memory to alloc / block */ +size_t my_once_allocated= 0; /* from errors.c */ diff --git a/mysys/my_static.h b/mysys/my_static.h index b30540b1ce4..80fc3e90e51 100644 --- a/mysys/my_static.h +++ b/mysys/my_static.h @@ -40,6 +40,7 @@ extern const char *soundex_map; extern USED_MEM* my_once_root_block; extern uint my_once_extra; +extern size_t my_once_allocated; extern struct st_my_file_info my_file_info_default[MY_NFILE]; diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index e17f001ee47..2d5b89aca69 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -2013,6 +2013,16 @@ static int log_statement(const struct connection_info *cn, const struct mysql_event_general *event, const char *type) { + DBUG_PRINT("info", ("log_statement: event_subclass=%d, general_command=%.*s, " + "cn->query_id=%lld, cn->query=%.*s, event->query_id=%lld, " + "event->general_query=%.*s, type=%s", + event->event_subclass, event->general_command_length, + event->general_command, + cn->query_id, + cn->query_length == 0x4f4f4f4f ? 0 : cn->query_length, + cn->query == (const char *)0x4f4f4f4f4f4f4f4fL ? NULL : cn->query, + event->query_id, event->general_query_length, + event->general_query, type)); return log_statement_ex(cn, event->general_time, event->general_thread_id, event->general_query, event->general_query_length, event->general_error_code, type, 1); @@ -2113,6 +2123,16 @@ static void update_connection_info(MYSQL_THD thd, struct connection_info *cn, { const struct mysql_event_general *event = (const struct mysql_event_general *) ev; + DBUG_PRINT("info", ("update_connection_info: before: event_subclass=%d, " + "general_command=%.*s, cn->query_id=%lld, cn->query=%.*s, " + "event->query_id=%lld, event->general_query=%.*s", + event->event_subclass, event->general_command_length, + event->general_command, + cn->query_id, + cn->query_length == 0x4f4f4f4f ? 0 : cn->query_length, + cn->query == (const char *)0x4f4f4f4f4f4f4f4fL ? NULL : cn->query, + event->query_id, event->general_query_length, + event->general_query)); switch (event->event_subclass) { case MYSQL_AUDIT_GENERAL_LOG: { @@ -2142,8 +2162,8 @@ static void update_connection_info(MYSQL_THD thd, struct connection_info *cn, setup_connection_query(cn, event); else setup_connection_simple(cn); - break; } + break; case MYSQL_AUDIT_GENERAL_STATUS: if (event_query_command(event)) @@ -2151,10 +2171,14 @@ static void update_connection_info(MYSQL_THD thd, struct connection_info *cn, if (ci_needs_setup(cn)) setup_connection_query(cn, event); - if (mode == 0 && cn->db_length == 0 && event->database.length > 0) - get_str_n(cn->db, &cn->db_length, sizeof(cn->db), - event->database.str, event->database.length); + if (mode == 0) + { + if (cn->db_length == 0 && event->database.length > 0) + get_str_n(cn->db, &cn->db_length, sizeof(cn->db), + event->database.str, event->database.length); + cn->query_id= event->query_id; + } if (event->general_error_code == 0) { /* We need to check if it's the USE command to change the DB */ @@ -2174,6 +2198,7 @@ static void update_connection_info(MYSQL_THD thd, struct connection_info *cn, update_general_user(cn, event); } break; + case MYSQL_AUDIT_GENERAL_ERROR: /* We need this because the MariaDB returns NULL query field for the @@ -2190,6 +2215,16 @@ static void update_connection_info(MYSQL_THD thd, struct connection_info *cn, break; default:; } + DBUG_PRINT("info", ("update_connection_info: after: event_subclass=%d, " + "general_command=%.*s, cn->query_id=%lld, cn->query=%.*s, " + "event->query_id=%lld, event->general_query=%.*s", + event->event_subclass, event->general_command_length, + event->general_command, + cn->query_id, + cn->query_length == 0x4f4f4f4f ? 0 : cn->query_length, + cn->query == (const char *)0x4f4f4f4f4f4f4f4fL ? NULL : cn->query, + event->query_id, event->general_query_length, + event->general_query)); break; } case MYSQL_AUDIT_TABLE_CLASS: @@ -2307,6 +2342,7 @@ void auditing(MYSQL_THD thd, unsigned int event_class, const void *ev) { log_statement(cn, event, "QUERY"); cn->query_length= 0; /* So the log_current_query() won't log this again. */ + cn->query_id= 0; cn->log_always= 0; } } diff --git a/sql/handler.h b/sql/handler.h index 084c590e71c..288172ab085 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1094,7 +1094,8 @@ enum enum_schema_tables SCH_TRIGGERS, SCH_USER_PRIVILEGES, SCH_VIEWS, - SCH_ENUM_SIZE + SCH_N_SERVER_TABLES, /* How many SCHEMA tables in the server. */ + SCH_PLUGIN_TABLE /* Schema table defined in plugin. */ }; struct TABLE_SHARE; diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 5a66027e375..a08acaf8efc 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -114,12 +114,14 @@ bool st_append_json(String *s, return false; } - if ((str_len= json_unescape(json_cs, js, js + js_len, - s->charset(), (uchar *) s->end(), (uchar *) s->end() + str_len)) > 0) - { + str_len= json_unescape(json_cs, js, js + js_len, s->charset(), + (uchar *) s->end(), (uchar *) s->end() + str_len); + if (str_len > 0) s->length(s->length() + str_len); + + if (str_len >= 0) return false; - } + if (current_thd) { if (str_len == JSON_ERROR_OUT_OF_SPACE) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index b0a9966b607..5f4fb6f997e 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1434,6 +1434,9 @@ sp_head::execute(THD *thd, bool merge_da_on_success) DBUG_ASSERT(thd->Item_change_list::is_empty()); old_change_list.move_elements_to(thd); thd->lex= old_lex; + DBUG_PRINT("info", ("sp_head::execute: query_id restore: old_query_id=%lld, query_id=%lld, query=%.*s", + old_query_id, + thd->query_id, thd->query_length(), thd->query())); thd->set_query_id(old_query_id); thd->set_query_inner(old_query); DBUG_ASSERT(!thd->derived_tables); diff --git a/sql/sql_audit.h b/sql/sql_audit.h index 64500067699..49b877ada94 100644 --- a/sql/sql_audit.h +++ b/sql/sql_audit.h @@ -175,6 +175,8 @@ void mysql_audit_general(THD *thd, uint event_subtype, event.general_rows= thd->get_stmt_da()->current_row_for_warning(); event.database= thd->db; event.query_id= thd->query_id; + DBUG_PRINT("info", ("mysql_audit_general: query_id=%lld, query=%.*s, subtype=%d, error_code=%d, msg=%s", + thd->query_id, thd->query_length(), thd->query(), event_subtype, error_code, msg)); } else { diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 60fc3c514fc..2839c4bc617 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5031,11 +5031,12 @@ bool table_already_fk_prelocked(TABLE_LIST *tl, LEX_CSTRING *db, static TABLE_LIST *internal_table_exists(TABLE_LIST *global_list, - const char *table_name) + TABLE_LIST *table) { do { - if (global_list->table_name.str == table_name) + if (global_list->table_name.str == table->table_name.str && + global_list->db.str == table->db.str) return global_list; } while ((global_list= global_list->next_global)); return 0; @@ -5056,8 +5057,7 @@ add_internal_tables(THD *thd, Query_tables_list *prelocking_ctx, /* Skip table if already in the list. Can happen with prepared statements */ - if ((tmp= internal_table_exists(global_table_list, - tables->table_name.str))) + if ((tmp= internal_table_exists(global_table_list, tables))) { /* Use the original value for the next local, used by the diff --git a/sql/sql_const.h b/sql/sql_const.h index 58e4a27dff8..a142eb0f041 100644 --- a/sql/sql_const.h +++ b/sql/sql_const.h @@ -172,7 +172,14 @@ Feel free to raise this by the smallest amount you can to get the "execution_constants" test to pass. */ +#ifndef __has_feature +#define __has_feature(x) 0 +#endif +#if defined(__clang__) && __has_feature(memory_sanitizer) && !defined(DBUG_OFF) +#define STACK_MIN_SIZE 44000 +#else #define STACK_MIN_SIZE 16000 // Abort if less stack during eval. +#endif #define STACK_MIN_SIZE_FOR_OPEN (1024*80) #define STACK_BUFF_ALLOC 352 ///< For stack overrun checks diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 849a4c3050c..e7c163d335e 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -128,6 +128,7 @@ bool Update_plan::save_explain_data_intern(THD *thd, (thd->variables.log_slow_verbosity & LOG_SLOW_VERBOSITY_ENGINE)) { + explain->table_tracker.set_gap_tracker(&explain->extra_time_tracker); table->file->set_time_tracker(&explain->table_tracker); if (table->file->handler_stats && table->s->tmp_table != INTERNAL_TMP_TABLE) diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index aafccdac447..908c9d4aca3 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -2838,8 +2838,8 @@ void Explain_update::print_explain_json(Explain_query *query, if (table_tracker.has_timed_statistics()) { - writer->add_member("r_total_time_ms"). - add_double(table_tracker.get_time_ms()); + writer->add_member("r_table_time_ms").add_double(table_tracker.get_time_ms()); + writer->add_member("r_other_time_ms").add_double(extra_time_tracker.get_time_ms()); } } diff --git a/sql/sql_explain.h b/sql/sql_explain.h index a8b56bb3d42..1aff4c05e60 100644 --- a/sql/sql_explain.h +++ b/sql/sql_explain.h @@ -1025,6 +1025,7 @@ public: /* TODO: This tracks time to read rows from the table */ Exec_time_tracker table_tracker; + Gap_time_tracker extra_time_tracker; /* The same as Explain_table_access::handler_for_stats */ handler *handler_for_stats; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 4ce62dc5827..0a92612707a 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -702,8 +702,7 @@ int prepare_for_replace(TABLE *table, enum_duplicates handle_duplicates, { create_lookup_handler= true; table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); - if (table->file->ha_table_flags() & HA_DUPLICATE_POS || - table->s->long_unique_table) + if (table->file->ha_table_flags() & HA_DUPLICATE_POS) { if (table->file->ha_rnd_init_with_error(false)) return 1; @@ -2015,17 +2014,26 @@ int vers_insert_history_row(TABLE *table) */ int Write_record::locate_dup_record() { - handler *h= table->file; int error= 0; - if (h->ha_table_flags() & HA_DUPLICATE_POS || h->lookup_errkey != (uint)-1) + if (table->file->ha_table_flags() & HA_DUPLICATE_POS || + table->file->lookup_errkey != (uint)-1) { DBUG_PRINT("info", ("Locating offending record using rnd_pos()")); - error= h->ha_rnd_pos(table->record[1], h->dup_ref); + const bool init_lookup_handler= (table->file->inited == handler::NONE); + if (init_lookup_handler) + { + error= table->file->ha_rnd_init_with_error(false); + if (error) + return error; + } + error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref); + if (init_lookup_handler) + table->file->ha_rnd_end(); if (unlikely(error)) { DBUG_PRINT("info", ("rnd_pos() returns error %d",error)); - h->print_error(error, MYF(0)); + table->file->print_error(error, MYF(0)); } } else @@ -2033,10 +2041,7 @@ int Write_record::locate_dup_record() DBUG_PRINT("info", ("Locating offending record using ha_index_read_idx_map")); - if (h->lookup_handler) - h= h->lookup_handler; - - error= h->extra(HA_EXTRA_FLUSH_CACHE); + error= table->file->extra(HA_EXTRA_FLUSH_CACHE); if (unlikely(error)) { DBUG_PRINT("info",("Error when setting HA_EXTRA_FLUSH_CACHE")); @@ -2055,12 +2060,12 @@ int Write_record::locate_dup_record() key_copy(key, table->record[0], table->key_info + key_nr, 0); - error= h->ha_index_read_idx_map(table->record[1], key_nr, key, + error= table->file->ha_index_read_idx_map(table->record[1], key_nr, key, HA_WHOLE_KEY, HA_READ_KEY_EXACT); if (unlikely(error)) { DBUG_PRINT("info", ("index_read_idx() returns %d", error)); - h->print_error(error, MYF(0)); + table->file->print_error(error, MYF(0)); } } diff --git a/sql/sql_insert.h b/sql/sql_insert.h index 414dfb4ff73..85058f7e9e8 100644 --- a/sql/sql_insert.h +++ b/sql/sql_insert.h @@ -34,16 +34,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table,List &fields, List &values, List &update_fields, List &update_values, enum_duplicates flag, bool ignore, select_result* result); -void upgrade_lock_type_for_insert(THD *thd, thr_lock_type *lock_type, - enum_duplicates duplic, - bool is_multi_insert); int check_that_all_fields_are_given_values(THD *thd, TABLE *entry, TABLE_LIST *table_list); int vers_insert_history_row(TABLE *table); int check_duplic_insert_without_overlaps(THD *thd, TABLE *table, enum_duplicates duplic); -int write_record(THD *thd, TABLE *table, COPY_INFO *info, - select_result *returning= NULL); void kill_delayed_threads(void); bool binlog_create_table(THD *thd, TABLE *table, bool replace); bool binlog_drop_table(THD *thd, TABLE *table); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f2dba46209c..d54ea643379 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1875,7 +1875,7 @@ dispatch_command_return dispatch_command(enum enum_server_command command, THD * (char *) thd->security_ctx->host_or_ip); char *packet_end= thd->query() + thd->query_length(); general_log_write(thd, command, thd->query(), thd->query_length()); - DBUG_PRINT("query",("%-.4096s",thd->query())); + DBUG_PRINT("query",("query_id=%lld, %.*s", thd->query_id, thd->query_length(), thd->query())); #if defined(ENABLED_PROFILING) thd->profiling.set_query_source(thd->query(), thd->query_length()); #endif @@ -8153,8 +8153,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, } } } - /* Store the table reference preceding the current one. */ - TABLE_LIST *UNINIT_VAR(previous_table_ref); /* The table preceding the current one. */ + /* Store the table reference preceding the current in previous_table_ref */ + TABLE_LIST *UNINIT_VAR(previous_table_ref); if (table_list.elements > 0 && likely(!ptr->sequence)) { /* diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index b0769ff06eb..fbbe80cd976 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -96,7 +96,7 @@ When one supplies long data for a placeholder: #include "sql_cache.h" // query_cache_* #include "sql_view.h" // create_view_precheck #include "sql_select.h" // for JOIN -#include "sql_insert.h" // upgrade_lock_type_for_insert, mysql_prepare_insert +#include "sql_insert.h" // mysql_prepare_insert #include "sql_db.h" // mysql_opt_change_db, mysql_change_db #include "sql_derived.h" // mysql_derived_prepare, // mysql_handle_derived @@ -1322,8 +1322,6 @@ static bool mysql_test_insert_common(Prepared_statement *stmt, if (insert_precheck(thd, table_list)) goto error; - //upgrade_lock_type_for_insert(thd, &table_list->lock_type, duplic, - // values_list.elements > 1); /* open temporary memory pool for temporary data allocated by derived tables & preparation procedure diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a1c83442c8e..fa7ee195785 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4397,6 +4397,12 @@ bool get_lookup_field_values(THD *thd, COND *cond, bool fix_table_name_case, enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table) { + if (schema_table < schema_tables || + schema_table > &schema_tables[SCH_N_SERVER_TABLES]) + { + return SCH_PLUGIN_TABLE; + } + return (enum enum_schema_tables) (schema_table - &schema_tables[0]); } @@ -10524,7 +10530,7 @@ ST_SCHEMA_TABLE schema_tables[]= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; -static_assert(array_elements(schema_tables) == SCH_ENUM_SIZE + 1, +static_assert(array_elements(schema_tables) == SCH_N_SERVER_TABLES + 1, "Update enum_schema_tables as well."); int initialize_schema_table(void *plugin_) diff --git a/sql/table.cc b/sql/table.cc index 55c9a3c551d..8596a19d016 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4026,6 +4026,7 @@ unpack_vcol_info_from_frm(THD *thd, TABLE *table, LEX *old_lex= thd->lex; LEX lex; bool error; + TABLE_LIST *sequence, *last; DBUG_ENTER("unpack_vcol_info_from_frm"); DBUG_ASSERT(vcol->expr == NULL); @@ -4043,11 +4044,12 @@ unpack_vcol_info_from_frm(THD *thd, TABLE *table, if (unlikely(error)) goto end; - if (lex.current_select->table_list.first[0].next_global) + if ((sequence= lex.current_select->table_list.first[0].next_global)) { - /* We are using NEXT VALUE FOR sequence. Remember table name for open */ - TABLE_LIST *sequence= lex.current_select->table_list.first[0].next_global; - sequence->next_global= table->internal_tables; + /* We are using NEXT VALUE FOR sequence. Remember table for open */ + for (last= sequence ; last->next_global ; last= last->next_global) + ; + last->next_global= table->internal_tables; table->internal_tables= sequence; } diff --git a/sql/wsrep_applier.cc b/sql/wsrep_applier.cc index ee3da59d4f2..4ce644c52f7 100644 --- a/sql/wsrep_applier.cc +++ b/sql/wsrep_applier.cc @@ -83,9 +83,35 @@ wsrep_get_apply_format(THD* thd) return thd->wsrep_rgi->rli->relay_log.description_event_for_exec; } -void wsrep_store_error(const THD* const thd, - wsrep::mutable_buffer& dst, - bool const include_msg) +/* store error from rli */ +static void wsrep_store_error_rli(const THD* const thd, + wsrep::mutable_buffer& dst, + bool const include_msg) +{ + Slave_reporting_capability* const rli= thd->wsrep_rgi->rli; + if (rli && rli->last_error().number != 0) + { + auto error= rli->last_error(); + std::ostringstream os; + if (include_msg) + { + os << error.message << ","; + } + os << " Error_code: " << error.number << ';'; + std::string const err_str= os.str(); + dst.resize(err_str.length() + 1); + sprintf(dst.data(), "%s", err_str.c_str()); + + WSREP_DEBUG("Error buffer (RLI) for thd %u seqno %lld, %zu bytes: '%s'", + thd->thread_id, (long long)wsrep_thd_trx_seqno(thd), + dst.size(), dst.size() ? dst.data() : "(null)"); + } +} + +/* store error from diagnostic area */ +static void wsrep_store_error_da(const THD* const thd, + wsrep::mutable_buffer& dst, + bool const include_msg) { Diagnostics_area::Sql_condition_iterator it= thd->get_stmt_da()->sql_conditions(); @@ -123,11 +149,35 @@ void wsrep_store_error(const THD* const thd, dst.resize(slider - dst.data()); - WSREP_DEBUG("Error buffer for thd %llu seqno %lld, %zu bytes: '%s'", + WSREP_DEBUG("Error buffer (DA) for thd %llu seqno %lld, %zu bytes: '%s'", thd->thread_id, (long long)wsrep_thd_trx_seqno(thd), dst.size(), dst.size() ? dst.data() : "(null)"); } +/* store error info after applying error */ +void wsrep_store_error(const THD* const thd, + wsrep::mutable_buffer& dst, + bool const include_msg) +{ + dst.clear(); + wsrep_store_error_da(thd, dst, include_msg); + if (dst.size() == 0) + { + wsrep_store_error_rli(thd, dst, include_msg); + } + if (dst.size() == 0) + { + WSREP_WARN("Failed to get apply error description from either " + "Relay_log_info or Diagnostics_area, will use random data."); + DBUG_ASSERT(0); + uintptr_t const n1= reinterpret_cast(&dst); + uintptr_t const n2= reinterpret_cast(thd); + uintptr_t const data= n1 ^ (n2 < 1); + const char* const data_ptr= reinterpret_cast(&data); + dst.push_back(data_ptr, data_ptr + sizeof(data)); + } +} + int wsrep_apply_events(THD* thd, Relay_log_info* rli, const void* events_buf, diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index c63c51eca2e..091230ce5fa 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1448,10 +1448,16 @@ bool wsrep_check_mode_after_open_table (THD *thd, if (!is_dml_stmt) return true; - const legacy_db_type db_type= hton->db_type; + TABLE *tbl= tables->table; + /* If this is partitioned table we need to find out + implementing storage engine handlerton. + */ + const handlerton *ht= tbl->file->partition_ht(); + if (!ht) ht= hton; + + const legacy_db_type db_type= ht->db_type; bool replicate= ((db_type == DB_TYPE_MYISAM && wsrep_check_mode(WSREP_MODE_REPLICATE_MYISAM)) || (db_type == DB_TYPE_ARIA && wsrep_check_mode(WSREP_MODE_REPLICATE_ARIA))); - TABLE *tbl= tables->table; if (replicate) { diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 45482f5de50..a61f33fcf82 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -379,7 +379,15 @@ dict_table_schema_check( return DB_STATS_DO_NOT_EXIST; } - if (!table->is_readable() || !table->space) { + if (!table->is_readable()) { + /* table is not readable */ + snprintf(errstr, errstr_sz, + "Table %s is not readable.", + req_schema->table_name_sql); + return DB_ERROR; + } + + if (!table->space) { /* missing tablespace */ snprintf(errstr, errstr_sz, "Tablespace for table %s is missing.", @@ -3662,8 +3670,9 @@ dberr_t dict_stats_rename_table(const char *old_name, const char *new_name, dict_fs2utf8(old_name, old_db, sizeof old_db, old_table, sizeof old_table); dict_fs2utf8(new_name, new_db, sizeof new_db, new_table, sizeof new_table); - if (dict_table_t::is_temporary_name(old_name) || - dict_table_t::is_temporary_name(new_name)) + /* Delete the stats only if renaming the table from old table to + intermediate table during COPY algorithm */ + if (dict_table_t::is_temporary_name(new_name)) { if (dberr_t e= dict_stats_delete_from_table_stats(old_db, old_table, trx)) return e; diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 269ed9a2c31..eeba660c63b 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -2108,6 +2108,9 @@ Adjust thread count for key rotation @param[in] enw_cnt Number of threads to be used */ void fil_crypt_set_thread_cnt(const uint new_cnt) { + if (srv_read_only_mode) + return; + if (!fil_crypt_threads_inited) { if (srv_shutdown_state != SRV_SHUTDOWN_NONE) return; @@ -2261,6 +2264,8 @@ void fil_crypt_set_encrypt_tables(ulong val) Init threads for key rotation */ void fil_crypt_threads_init() { + ut_ad(!srv_read_only_mode); + if (!fil_crypt_threads_inited) { pthread_cond_init(&fil_crypt_cond, nullptr); pthread_cond_init(&fil_crypt_threads_cond, nullptr); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index bb35ae29d8f..4a2649156b3 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -15827,16 +15827,17 @@ ha_innobase::extra( /* Warning: since it is not sure that MariaDB calls external_lock() before calling this function, m_prebuilt->trx can be obsolete! */ trx_t* trx; + THD* thd = ha_thd(); switch (operation) { case HA_EXTRA_FLUSH: - (void)check_trx_exists(ha_thd()); + (void)check_trx_exists(thd); if (m_prebuilt->blob_heap) { row_mysql_prebuilt_free_blob_heap(m_prebuilt); } break; case HA_EXTRA_RESET_STATE: - trx = check_trx_exists(ha_thd()); + trx = check_trx_exists(thd); reset_template(); trx->duplicates = 0; stmt_boundary: @@ -15845,23 +15846,23 @@ ha_innobase::extra( trx->bulk_insert &= TRX_DDL_BULK; break; case HA_EXTRA_NO_KEYREAD: - (void)check_trx_exists(ha_thd()); + (void)check_trx_exists(thd); m_prebuilt->read_just_key = 0; break; case HA_EXTRA_KEYREAD: - (void)check_trx_exists(ha_thd()); + (void)check_trx_exists(thd); m_prebuilt->read_just_key = 1; break; case HA_EXTRA_KEYREAD_PRESERVE_FIELDS: - (void)check_trx_exists(ha_thd()); + (void)check_trx_exists(thd); m_prebuilt->keep_other_fields_on_keyread = 1; break; case HA_EXTRA_INSERT_WITH_UPDATE: - trx = check_trx_exists(ha_thd()); + trx = check_trx_exists(thd); trx->duplicates |= TRX_DUP_IGNORE; goto stmt_boundary; case HA_EXTRA_NO_IGNORE_DUP_KEY: - trx = check_trx_exists(ha_thd()); + trx = check_trx_exists(thd); trx->duplicates &= ~TRX_DUP_IGNORE; if (trx->is_bulk_insert()) { /* Allow a subsequent INSERT into an empty table @@ -15874,11 +15875,11 @@ ha_innobase::extra( } goto stmt_boundary; case HA_EXTRA_WRITE_CAN_REPLACE: - trx = check_trx_exists(ha_thd()); + trx = check_trx_exists(thd); trx->duplicates |= TRX_DUP_REPLACE; goto stmt_boundary; case HA_EXTRA_WRITE_CANNOT_REPLACE: - trx = check_trx_exists(ha_thd()); + trx = check_trx_exists(thd); trx->duplicates &= ~TRX_DUP_REPLACE; if (trx->is_bulk_insert()) { /* Allow a subsequent INSERT into an empty table @@ -15887,7 +15888,7 @@ ha_innobase::extra( } goto stmt_boundary; case HA_EXTRA_BEGIN_ALTER_COPY: - trx = check_trx_exists(ha_thd()); + trx = check_trx_exists(thd); m_prebuilt->table->skip_alter_undo = 1; if (m_prebuilt->table->is_temporary() || !m_prebuilt->table->versioned_by_id()) { @@ -15900,7 +15901,7 @@ ha_innobase::extra( .first->second.set_versioned(0); break; case HA_EXTRA_END_ALTER_COPY: - trx = check_trx_exists(ha_thd()); + trx = check_trx_exists(thd); if (!m_prebuilt->table->skip_alter_undo) { /* This could be invoked inside INSERT...SELECT. We do not want any extra log writes, because @@ -15934,6 +15935,7 @@ ha_innobase::extra( handler::extra(HA_EXTRA_BEGIN_ALTER_COPY). */ log_buffer_flush_to_disk(); } + alter_stats_rebuild(m_prebuilt->table, thd); break; case HA_EXTRA_ABORT_ALTER_COPY: if (m_prebuilt->table->skip_alter_undo) { @@ -21280,3 +21282,25 @@ void ins_node_t::vers_update_end(row_prebuilt_t *prebuilt, bool history_row) if (UNIV_LIKELY_NULL(local_heap)) mem_heap_free(local_heap); } + +/** Adjust the persistent statistics after rebuilding ALTER TABLE. +Remove statistics for dropped indexes, add statistics for created indexes +and rename statistics for renamed indexes. +@param table InnoDB table that was rebuilt by ALTER TABLE +@param thd alter table thread */ +void alter_stats_rebuild(dict_table_t *table, THD *thd) +{ + DBUG_ENTER("alter_stats_rebuild"); + if (!table->space || !table->stats_is_persistent() + || dict_stats_persistent_storage_check(false) != SCHEMA_OK) + DBUG_VOID_RETURN; + + dberr_t ret= dict_stats_update_persistent(table); + if (ret == DB_SUCCESS) + ret= dict_stats_save(table); + if (ret != DB_SUCCESS) + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_ALTER_INFO, "Error updating stats for table after" + " table rebuild: %s", ut_strerr(ret)); + DBUG_VOID_RETURN; +} diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index a77e6aae0f3..58a28fd8ecf 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -923,3 +923,10 @@ ib_push_frm_error( @return true if index column length exceeds limit */ MY_ATTRIBUTE((warn_unused_result)) bool too_big_key_part_length(size_t max_field_len, const KEY& key); + +/** Adjust the persistent statistics after rebuilding ALTER TABLE. +Remove statistics for dropped indexes, add statistics for created indexes +and rename statistics for renamed indexes. +@param table_name Table name in MySQL +@param thd alter table thread */ +void alter_stats_rebuild(dict_table_t *table, THD *thd); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 8281a3859f8..4e9f676f9ea 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -11209,7 +11209,7 @@ Remove statistics for dropped indexes, add statistics for created indexes and rename statistics for renamed indexes. @param ha_alter_info Data used during in-place alter @param ctx In-place ALTER TABLE context -@param thd MySQL connection +@param thd alter table thread */ static void @@ -11241,46 +11241,6 @@ alter_stats_norebuild( DBUG_VOID_RETURN; } -/** Adjust the persistent statistics after rebuilding ALTER TABLE. -Remove statistics for dropped indexes, add statistics for created indexes -and rename statistics for renamed indexes. -@param table InnoDB table that was rebuilt by ALTER TABLE -@param table_name Table name in MySQL -@param thd MySQL connection -*/ -static -void -alter_stats_rebuild( -/*================*/ - dict_table_t* table, - const char* table_name, - THD* thd) -{ - DBUG_ENTER("alter_stats_rebuild"); - - if (!table->space || !table->stats_is_persistent() - || dict_stats_persistent_storage_check(false) != SCHEMA_OK) { - DBUG_VOID_RETURN; - } - - dberr_t ret = dict_stats_update_persistent(table); - if (ret == DB_SUCCESS) { - ret = dict_stats_save(table); - } - - if (ret != DB_SUCCESS) { - push_warning_printf( - thd, - Sql_condition::WARN_LEVEL_WARN, - ER_ALTER_INFO, - "Error updating stats for table '%s'" - " after table rebuild: %s", - table_name, ut_strerr(ret)); - } - - DBUG_VOID_RETURN; -} - /** Apply the log for the table rebuild operation. @param[in] ctx Inplace Alter table context @param[in] altered_table MySQL table that is being altered @@ -11951,9 +11911,7 @@ foreign_fail: (*pctx); DBUG_ASSERT(ctx->need_rebuild()); - alter_stats_rebuild( - ctx->new_table, table->s->table_name.str, - m_user_thd); + alter_stats_rebuild(ctx->new_table, m_user_thd); } } else { for (inplace_alter_handler_ctx** pctx = ctx_array; diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 7a4f9b034cd..ef20ff4135b 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -2655,9 +2655,8 @@ all_done: ut_ad((mrec == NULL) == (index->online_log->head.bytes == 0)); #ifdef UNIV_DEBUG - if (index->online_log->head.block && - next_mrec_end == index->online_log->head.block - + srv_sort_buf_size) { + if (next_mrec_end - srv_sort_buf_size + == index->online_log->head.block) { /* If tail.bytes == 0, next_mrec_end can also be at the end of tail.block. */ if (index->online_log->tail.bytes == 0) { @@ -2671,9 +2670,8 @@ all_done: ut_ad(index->online_log->tail.blocks > index->online_log->head.blocks); } - } else if (index->online_log->tail.block && - next_mrec_end == index->online_log->tail.block - + index->online_log->tail.bytes) { + } else if (next_mrec_end - index->online_log->tail.bytes + == index->online_log->tail.block) { ut_ad(next_mrec == index->online_log->tail.block + index->online_log->head.bytes); ut_ad(index->online_log->tail.blocks == 0); @@ -2774,7 +2772,7 @@ process_next_block: } else { memcpy(index->online_log->head.buf, mrec, ulint(mrec_end - mrec)); - mrec_end += ulint(index->online_log->head.buf - mrec); + mrec_end -= ulint(mrec - index->online_log->head.buf); mrec = index->online_log->head.buf; goto process_next_block; } @@ -3567,8 +3565,8 @@ all_done: ut_ad((mrec == NULL) == (index->online_log->head.bytes == 0)); #ifdef UNIV_DEBUG - if (next_mrec_end == index->online_log->head.block - + srv_sort_buf_size) { + if (next_mrec_end - srv_sort_buf_size + == index->online_log->head.block) { /* If tail.bytes == 0, next_mrec_end can also be at the end of tail.block. */ if (index->online_log->tail.bytes == 0) { @@ -3582,8 +3580,8 @@ all_done: ut_ad(index->online_log->tail.blocks > index->online_log->head.blocks); } - } else if (next_mrec_end == index->online_log->tail.block - + index->online_log->tail.bytes) { + } else if (next_mrec_end - index->online_log->tail.bytes + == index->online_log->tail.block) { ut_ad(next_mrec == index->online_log->tail.block + index->online_log->head.bytes); ut_ad(index->online_log->tail.blocks == 0); @@ -3666,7 +3664,7 @@ process_next_block: } else { memcpy(index->online_log->head.buf, mrec, ulint(mrec_end - mrec)); - mrec_end += ulint(index->online_log->head.buf - mrec); + mrec_end -= ulint(mrec - index->online_log->head.buf); mrec = index->online_log->head.buf; goto process_next_block; }