1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Merge 10.6 into 10.7

This commit is contained in:
Marko Mäkelä
2021-10-22 14:41:47 +03:00
160 changed files with 4784 additions and 1682 deletions

3
.gitignore vendored
View File

@@ -10,8 +10,11 @@
.ninja_*
*.mri
*.mri.tpl
/.cproject
/.project
.gdb_history
.vs/
/.settings/
errmsg.sys
typescript
_CPack_Packages

View File

@@ -174,6 +174,10 @@ IF(DISABLE_SHARED)
SET(WITHOUT_DYNAMIC_PLUGINS 1)
ENDIF()
OPTION(ENABLED_PROFILING "Enable profiling" ON)
OPTION(ENABLED_JSON_WRITER_CONSISTENCY_CHECKS "Enable Json_writer_object / Json_writer_array checking to produce consistent JSON output" OFF)
IF(ENABLED_JSON_WRITER_CONSISTENCY_CHECKS)
ADD_DEFINITIONS(-DENABLED_JSON_WRITER_CONSISTENCY_CHECKS)
ENDIF()
OPTION(WITHOUT_SERVER "Build only the client library and clients" OFF)
IF(UNIX)
OPTION(WITH_VALGRIND "Valgrind instrumentation" OFF)

View File

@@ -11,21 +11,22 @@ MACRO(BUNDLE_PCRE2)
FOREACH(lib pcre2-posix pcre2-8)
ADD_LIBRARY(${lib} STATIC IMPORTED GLOBAL)
ADD_DEPENDENCIES(${lib} pcre2)
GET_PROPERTY(MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
IF(MULTICONFIG)
SET(intdir "${CMAKE_CFG_INTDIR}/")
ELSE()
SET(intdir)
ENDIF()
SET(file ${dir}/src/pcre2-build/${intdir}${CMAKE_STATIC_LIBRARY_PREFIX}${lib}${CMAKE_STATIC_LIBRARY_SUFFIX})
IF(WIN32)
# Debug libary name.
# Same condition as in pcre2 CMakeLists.txt that adds "d"
GET_PROPERTY(MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
IF(MULTICONFIG)
SET(intdir "${CMAKE_CFG_INTDIR}/")
ELSE()
SET(intdir)
ENDIF()
SET(file ${dir}/src/pcre2-build/${intdir}${CMAKE_STATIC_LIBRARY_PREFIX}${lib}${CMAKE_STATIC_LIBRARY_SUFFIX})
SET(file_d ${dir}/src/pcre2-build/${intdir}${CMAKE_STATIC_LIBRARY_PREFIX}${lib}d${CMAKE_STATIC_LIBRARY_SUFFIX})
SET_TARGET_PROPERTIES(${lib} PROPERTIES IMPORTED_LOCATION_DEBUG ${file_d})
ELSE()
SET(file ${dir}/src/pcre2-build/${CMAKE_STATIC_LIBRARY_PREFIX}${lib}${CMAKE_STATIC_LIBRARY_SUFFIX})
SET(file_d)
ENDIF()
SET(byproducts ${byproducts} BUILD_BYPRODUCTS ${file} ${file_d})

View File

@@ -867,7 +867,25 @@ int main()
long long int *ptr= &var;
return (int)__atomic_load_n(ptr, __ATOMIC_SEQ_CST);
}"
HAVE_GCC_C11_ATOMICS)
HAVE_GCC_C11_ATOMICS_WITHOUT_LIBATOMIC)
IF (HAVE_GCC_C11_ATOMICS_WITHOUT_LIBATOMIC)
SET(HAVE_GCC_C11_ATOMICS True)
ELSE()
SET(OLD_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
LIST(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
CHECK_CXX_SOURCE_COMPILES("
int main()
{
long long int var= 1;
long long int *ptr= &var;
return (int)__atomic_load_n(ptr, __ATOMIC_SEQ_CST);
}"
HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
IF(HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
SET(HAVE_GCC_C11_ATOMICS True)
ENDIF()
SET(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQUIRED_LIBRARIES})
ENDIF()
IF(WITH_VALGRIND)
SET(HAVE_valgrind 1)

View File

@@ -3000,5 +3000,38 @@ DROP TABLE t1;
#
SET DEFAULT_STORAGE_ENGINE=Default;
#
# MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
#
SET NAMES utf8;
SET SESSION character_set_connection= utf16le;
CREATE TABLE kv (v TEXT CHARACTER SET latin1);
CREATE TABLE t (a INT);
CREATE VIEW v AS SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
LOAD DATA INFILE 'MYSQLD_DATADIR/test/v.frm' REPLACE INTO TABLE kv CHARACTER SET latin1;
SELECT LOWER(v) FROM kv WHERE v LIKE _binary'query=%';
LOWER(v)
query=select `information_schema`.`tables`.`table_catalog` as `table_catalog`,`information_schema`.`tables`.`table_schema` as `table_schema`,`information_schema`.`tables`.`table_name` as `table_name`,`information_schema`.`tables`.`table_type` as `table_type`,`information_schema`.`tables`.`engine` as `engine`,`information_schema`.`tables`.`version` as `version`,`information_schema`.`tables`.`row_format` as `row_format`,`information_schema`.`tables`.`table_rows` as `table_rows`,`information_schema`.`tables`.`avg_row_length` as `avg_row_length`,`information_schema`.`tables`.`data_length` as `data_length`,`information_schema`.`tables`.`max_data_length` as `max_data_length`,`information_schema`.`tables`.`index_length` as `index_length`,`information_schema`.`tables`.`data_free` as `data_free`,`information_schema`.`tables`.`auto_increment` as `auto_increment`,`information_schema`.`tables`.`create_time` as `create_time`,`information_schema`.`tables`.`update_time` as `update_time`,`information_schema`.`tables`.`check_time` as `check_time`,`information_schema`.`tables`.`table_collation` as `table_collation`,`information_schema`.`tables`.`checksum` as `checksum`,`information_schema`.`tables`.`create_options` as `create_options`,`information_schema`.`tables`.`table_comment` as `table_comment`,`information_schema`.`tables`.`max_index_length` as `max_index_length`,`information_schema`.`tables`.`temporary` as `temporary` from `information_schema`.`tables` where `information_schema`.`tables`.`table_name` = 't1'
TRUNCATE TABLE kv;
SELECT * FROM v;
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
LOCK TABLE t WRITE;
UNLOCK TABLES;
DROP VIEW v;
DROP TABLE t;
DROP TABLE kv;
CREATE TABLE t (a INT);
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=CONCAT('t',0x00,'1');
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
LOCK TABLE t WRITE;
UNLOCK TABLES;
DROP TABLE t;
CREATE TABLE t (a INT);
SELECT TABLE_NAME, HEX(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=CONCAT('t',0x00,'1');
TABLE_NAME HEX(TABLE_NAME)
SELECT TABLE_NAME, TABLE_SCHEMA, HEX(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=CONCAT('test',0x00,'1');
TABLE_NAME TABLE_SCHEMA HEX(TABLE_NAME)
DROP TABLE t;
SET NAMES utf8;
#
# End of 10.2 tests
#

View File

@@ -3,6 +3,7 @@
-- source include/have_utf32.inc
-- source include/have_utf8mb4.inc
let $MYSQLD_DATADIR= `select @@datadir`;
SET TIME_ZONE='+03:00';
@@ -810,6 +811,42 @@ let $coll='utf16le_nopad_bin';
let $coll_pad='utf16le_bin';
--source include/ctype_pad_all_engines.inc
--echo #
--echo # MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
--echo #
SET NAMES utf8;
SET SESSION character_set_connection= utf16le;
CREATE TABLE kv (v TEXT CHARACTER SET latin1);
CREATE TABLE t (a INT);
CREATE VIEW v AS SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval LOAD DATA INFILE '$MYSQLD_DATADIR/test/v.frm' REPLACE INTO TABLE kv CHARACTER SET latin1;
SELECT LOWER(v) FROM kv WHERE v LIKE _binary'query=%';
TRUNCATE TABLE kv;
SELECT * FROM v;
LOCK TABLE t WRITE;
UNLOCK TABLES;
DROP VIEW v;
DROP TABLE t;
DROP TABLE kv;
CREATE TABLE t (a INT);
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=CONCAT('t',0x00,'1');
LOCK TABLE t WRITE;
UNLOCK TABLES;
DROP TABLE t;
CREATE TABLE t (a INT);
SELECT TABLE_NAME, HEX(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=CONCAT('t',0x00,'1');
SELECT TABLE_NAME, TABLE_SCHEMA, HEX(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=CONCAT('test',0x00,'1');
DROP TABLE t;
SET NAMES utf8;
--echo #
--echo # End of 10.2 tests
--echo #

View File

@@ -11244,6 +11244,23 @@ DROP TABLE t1;
#
SET DEFAULT_STORAGE_ENGINE=Default;
#
# MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
#
SET NAMES utf8;
SET SESSION character_set_connection=latin1;
CREATE VIEW v1 AS SELECT 'ä' AS c1;
SELECT c1, HEX(c1) FROM v1;
c1 HEX(c1)
ä E4
CREATE TABLE kv (v BLOB);
LOAD DATA INFILE 'MYSQLD_DATADIR/test/v1.frm' REPLACE INTO TABLE kv;
SELECT * FROM kv WHERE v LIKE _binary'query=%';
v
query=select 'ä' AS `c1`
DROP TABLE kv;
DROP VIEW v1;
SET NAMES utf8;
#
# End of 10.2 tests
#
#

View File

@@ -2,6 +2,8 @@
# Tests with the utf8 character set
#
let $MYSQLD_DATADIR= `select @@datadir`;
let collation=utf8mb3_unicode_ci;
--source include/have_collation.inc
SET TIME_ZONE='+03:00';
@@ -2166,6 +2168,22 @@ let $coll='utf8_nopad_bin';
let $coll_pad='utf8_bin';
--source include/ctype_pad_all_engines.inc
--echo #
--echo # MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
--echo #
SET NAMES utf8;
SET SESSION character_set_connection=latin1;
CREATE VIEW v1 AS SELECT 'ä' AS c1;
SELECT c1, HEX(c1) FROM v1;
CREATE TABLE kv (v BLOB);
--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
eval LOAD DATA INFILE '$MYSQLD_DATADIR/test/v1.frm' REPLACE INTO TABLE kv;
SELECT * FROM kv WHERE v LIKE _binary'query=%';
DROP TABLE kv;
DROP VIEW v1;
SET NAMES utf8;
--echo #
--echo # End of 10.2 tests
--echo #

View File

@@ -934,6 +934,12 @@ CAST(JSON_EXTRACT('{"x":false}', '$.x') AS DECIMAL) AS cd;
cf cd
0 0
#
# MDEV-24585 Assertion `je->s.cs == nice_js->charset()' failed in json_nice.
#
SELECT JSON_REPLACE( JSON_DETAILED('["x"]'), '$.a', 'xx' );
JSON_REPLACE( JSON_DETAILED('["x"]'), '$.a', 'xx' )
["x"]
#
# End of 10.2 tests
#
#

View File

@@ -551,6 +551,12 @@ SELECT
CAST(JSON_EXTRACT('{"x":false}', '$.x') AS DECIMAL) AS cd;
--echo #
--echo # MDEV-24585 Assertion `je->s.cs == nice_js->charset()' failed in json_nice.
--echo #
SELECT JSON_REPLACE( JSON_DETAILED('["x"]'), '$.a', 'xx' );
--echo #
--echo # End of 10.2 tests
--echo #

View File

@@ -2374,6 +2374,26 @@ SELECT * FROM v LIMIT ROWS EXAMINED 9;
ERROR HY000: Sort aborted:
DROP VIEW v;
#
# MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
#
CREATE TABLE t (a INT);
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=CONCAT('t',0x00,'1');
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=CONCAT('test',0x00,'1');
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY
DROP TABLE t;
CREATE TABLE `a/~.b` (a INT);
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='a/~.b';
TABLE_SCHEMA TABLE_NAME
test a/~.b
DROP TABLE `a/~.b`;
CREATE DATABASE `a/~.b`;
CREATE TABLE `a/~.b`.t1 (a INT);
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='a/~.b';
TABLE_SCHEMA TABLE_NAME
a/~.b t1
DROP DATABASE `a/~.b`;
#
# End of 10.2 Test
#
#

View File

@@ -1949,6 +1949,27 @@ SELECT * FROM v LIMIT ROWS EXAMINED 9;
DROP VIEW v;
--echo #
--echo # MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
--echo #
# Expect empty sets if requested TABLE_NAME or TABLE_SCHEMA with zero bytes
CREATE TABLE t (a INT);
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=CONCAT('t',0x00,'1');
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=CONCAT('test',0x00,'1');
DROP TABLE t;
# Make sure check_table_name() does not reject special characters
CREATE TABLE `a/~.b` (a INT);
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='a/~.b';
DROP TABLE `a/~.b`;
# Make sure check_db_name() does not reject special characters
CREATE DATABASE `a/~.b`;
CREATE TABLE `a/~.b`.t1 (a INT);
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='a/~.b';
DROP DATABASE `a/~.b`;
--echo #
--echo # End of 10.2 Test
--echo #

View File

@@ -0,0 +1 @@
--innodb-page-size=8K

View File

@@ -131,3 +131,6 @@ connection default;
drop table t1;
disconnect con1;
disconnect con2;
# MDEV-20131 Assertion `!pk->has_virtual()' failed
create table t1 (a text, primary key(a(1871))) engine=innodb;
ERROR 42000: Specified key was too long; max key length is 1536 bytes

View File

@@ -138,3 +138,8 @@ connection default;
drop table t1;
disconnect con1;
disconnect con2;
--echo # MDEV-20131 Assertion `!pk->has_virtual()' failed
--error ER_TOO_LONG_KEY
create table t1 (a text, primary key(a(1871))) engine=innodb;

View File

@@ -79,7 +79,7 @@ Database: ``
Table: ``
Org_table: ``
Type: LONG_BLOB (format=json)
Collation: binary (63)
Collation: latin1_swedish_ci (8)
Length: 4294967295
Max_length: 0
Decimals: 0

View File

@@ -1964,6 +1964,180 @@ count(*)
5
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
#
# Ensure that mysql_upgrade accounted for 0 password_last_changed
# and doesn't PASSWORD EXPIRE a user account because < 10.4 zeroed it.
#
# switching from mysql.global_priv to mysql.user
drop view mysql.user_bak;
drop table mysql.user;
truncate table mysql.tables_priv;
FLUSH TABLES mysql.user;
FLUSH PRIVILEGES;
CREATE USER mariadb_102;
UPDATE mysql.user SET password_last_changed=0 WHERE user='mariadb_102';
FLUSH PRIVILEGES;
Phase 1/7: Checking and upgrading mysql database
Processing databases
mysql
mysql.column_stats OK
mysql.columns_priv OK
mysql.db OK
mysql.event OK
mysql.func OK
mysql.global_priv_bak OK
mysql.gtid_slave_pos OK
mysql.help_category OK
mysql.help_keyword OK
mysql.help_relation OK
mysql.help_topic OK
mysql.index_stats OK
mysql.innodb_index_stats OK
mysql.innodb_table_stats OK
mysql.plugin OK
mysql.proc OK
mysql.procs_priv OK
mysql.proxies_priv OK
mysql.roles_mapping OK
mysql.servers OK
mysql.table_stats OK
mysql.tables_priv OK
mysql.time_zone OK
mysql.time_zone_leap_second OK
mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.transaction_registry OK
mysql.user OK
Upgrading from a version before MariaDB-10.1
Phase 2/7: Installing used storage engines
Checking for tables with unknown storage engine
Phase 3/7: Fixing views
sys.host_summary OK
sys.host_summary_by_file_io OK
sys.host_summary_by_file_io_type OK
sys.host_summary_by_stages OK
sys.host_summary_by_statement_latency OK
sys.host_summary_by_statement_type OK
sys.innodb_buffer_stats_by_schema OK
sys.innodb_buffer_stats_by_table OK
sys.innodb_lock_waits OK
sys.io_by_thread_by_latency OK
sys.io_global_by_file_by_bytes OK
sys.io_global_by_file_by_latency OK
sys.io_global_by_wait_by_bytes OK
sys.io_global_by_wait_by_latency OK
sys.latest_file_io OK
sys.memory_by_host_by_current_bytes OK
sys.memory_by_thread_by_current_bytes OK
sys.memory_by_user_by_current_bytes OK
sys.memory_global_by_current_bytes OK
sys.memory_global_total OK
sys.metrics OK
sys.processlist OK
sys.ps_check_lost_instrumentation OK
sys.schema_auto_increment_columns OK
sys.schema_index_statistics OK
sys.schema_object_overview OK
sys.schema_redundant_indexes OK
sys.schema_table_lock_waits OK
sys.schema_table_statistics OK
sys.schema_table_statistics_with_buffer OK
sys.schema_tables_with_full_table_scans OK
sys.schema_unused_indexes OK
sys.session OK
sys.session_ssl_status OK
sys.statement_analysis OK
sys.statements_with_errors_or_warnings OK
sys.statements_with_full_table_scans OK
sys.statements_with_runtimes_in_95th_percentile OK
sys.statements_with_sorting OK
sys.statements_with_temp_tables OK
sys.user_summary OK
sys.user_summary_by_file_io OK
sys.user_summary_by_file_io_type OK
sys.user_summary_by_stages OK
sys.user_summary_by_statement_latency OK
sys.user_summary_by_statement_type OK
sys.version OK
sys.wait_classes_global_by_avg_latency OK
sys.wait_classes_global_by_latency OK
sys.waits_by_host_by_latency OK
sys.waits_by_user_by_latency OK
sys.waits_global_by_latency OK
sys.x$host_summary OK
sys.x$host_summary_by_file_io OK
sys.x$host_summary_by_file_io_type OK
sys.x$host_summary_by_stages OK
sys.x$host_summary_by_statement_latency OK
sys.x$host_summary_by_statement_type OK
sys.x$innodb_buffer_stats_by_schema OK
sys.x$innodb_buffer_stats_by_table OK
sys.x$innodb_lock_waits OK
sys.x$io_by_thread_by_latency OK
sys.x$io_global_by_file_by_bytes OK
sys.x$io_global_by_file_by_latency OK
sys.x$io_global_by_wait_by_bytes OK
sys.x$io_global_by_wait_by_latency OK
sys.x$latest_file_io OK
sys.x$memory_by_host_by_current_bytes OK
sys.x$memory_by_thread_by_current_bytes OK
sys.x$memory_by_user_by_current_bytes OK
sys.x$memory_global_by_current_bytes OK
sys.x$memory_global_total OK
sys.x$processlist OK
sys.x$ps_digest_95th_percentile_by_avg_us OK
sys.x$ps_digest_avg_latency_distribution OK
sys.x$ps_schema_table_statistics_io OK
sys.x$schema_flattened_keys OK
sys.x$schema_index_statistics OK
sys.x$schema_table_lock_waits OK
sys.x$schema_table_statistics OK
sys.x$schema_table_statistics_with_buffer OK
sys.x$schema_tables_with_full_table_scans OK
sys.x$session OK
sys.x$statement_analysis OK
sys.x$statements_with_errors_or_warnings OK
sys.x$statements_with_full_table_scans OK
sys.x$statements_with_runtimes_in_95th_percentile OK
sys.x$statements_with_sorting OK
sys.x$statements_with_temp_tables OK
sys.x$user_summary OK
sys.x$user_summary_by_file_io OK
sys.x$user_summary_by_file_io_type OK
sys.x$user_summary_by_stages OK
sys.x$user_summary_by_statement_latency OK
sys.x$user_summary_by_statement_type OK
sys.x$wait_classes_global_by_avg_latency OK
sys.x$wait_classes_global_by_latency OK
sys.x$waits_by_host_by_latency OK
sys.x$waits_by_user_by_latency OK
sys.x$waits_global_by_latency OK
Phase 4/7: Running 'mysql_fix_privilege_tables'
Phase 5/7: Fixing table and database names
Phase 6/7: Checking and upgrading tables
Processing databases
information_schema
mtr
mtr.global_suppressions OK
mtr.test_suppressions OK
performance_schema
sys
sys.sys_config OK
test
Phase 7/7: Running 'FLUSH PRIVILEGES'
OK
SHOW CREATE USER mariadb_102;
CREATE USER for mariadb_102@%
CREATE USER `mariadb_102`@`%`
connect con1,localhost,mariadb_102;
select current_user();
current_user()
mariadb_102@%
disconnect con1;
connection default;
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
# End of 10.4 tests
#
# Check that mysql_upgrade can be run on mysqldump

View File

@@ -356,6 +356,44 @@ select count(*) from mysql.global_priv;
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
#
# MDEV-26363 Former mysql-5.7 tables have password_last_changed to 0
# on MariaDB updates, resulting in mysql_upgrade leaving them
# with password expired.
#
--echo #
--echo # Ensure that mysql_upgrade accounted for 0 password_last_changed
--echo # and doesn't PASSWORD EXPIRE a user account because < 10.4 zeroed it.
--echo #
--source include/switch_to_mysql_user.inc
drop view mysql.user_bak;
drop table mysql.user;
truncate table mysql.tables_priv;
--copy_file std_data/mysql57user.frm $MYSQLD_DATADIR/mysql/user.frm
--copy_file std_data/mysql57user.MYI $MYSQLD_DATADIR/mysql/user.MYI
--copy_file std_data/mysql57user.MYD $MYSQLD_DATADIR/mysql/user.MYD
FLUSH TABLES mysql.user;
FLUSH PRIVILEGES;
CREATE USER mariadb_102;
# manually set the value like <10.4 previously did for testing mysql_upgrade.
UPDATE mysql.user SET password_last_changed=0 WHERE user='mariadb_102';
FLUSH PRIVILEGES;
--exec $MYSQL_UPGRADE --force 2>&1
# Should not have "PASSWORD EXPIRED"
SHOW CREATE USER mariadb_102;
connect con1,localhost,mariadb_102;
select current_user();
disconnect con1;
connection default;
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
--remove_file $MYSQLD_DATADIR/mysql_upgrade_info
--echo # End of 10.4 tests
#

View File

@@ -972,6 +972,30 @@ DROP PROCEDURE testp_bug11763507;
DROP FUNCTION testf_bug11763507;
#END OF BUG#11763507 test.
#
# MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
#
SET NAMES utf8;
SET SESSION character_set_connection=latin1;
CREATE PROCEDURE p1()
BEGIN
DECLARE a VARCHAR(10) CHARACTER SET utf8;
SET a='ä';
SELECT a, 'ä' AS b;
END;
$$
SHOW PROCEDURE CODE p1;
Pos Instruction
0 set a@0 NULL
1 set a@0 'ä'
2 stmt 0 "SELECT a, 'ä' AS b"
CALL p1;
a b
ä ä
DROP PROCEDURE p1;
#
# End of 10.2 tests
#
#
# MDEV-13581 ROW TYPE OF t1 and t1%ROWTYPE for routine parameters
#
CREATE TABLE t1 (a INT, b TEXT);
@@ -1330,6 +1354,9 @@ Pos Instruction
5 hpop 1
drop function f1;
#
# End of 10.3 tests
#
#
# MDEV-19640 Wrong SHOW PROCEDURE output for SET GLOBAL sysvar1=expr, sysvar2=expr
#
CREATE OR REPLACE PROCEDURE p1()
@@ -1344,3 +1371,6 @@ Pos Instruction
1 stmt 31 "SET GLOBAL max_error_count=60"
2 stmt 0 "SELECT @@GLOBAL.max_allowed_packet, @..."
DROP PROCEDURE p1;
#
# End of 10.5 tests
#

View File

@@ -737,6 +737,30 @@ DROP FUNCTION testf_bug11763507;
--echo #END OF BUG#11763507 test.
--echo #
--echo # MDEV-23408 Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
--echo #
SET NAMES utf8;
SET SESSION character_set_connection=latin1;
DELIMITER $$;
CREATE PROCEDURE p1()
BEGIN
DECLARE a VARCHAR(10) CHARACTER SET utf8;
SET a='ä';
SELECT a, 'ä' AS b;
END;
$$
DELIMITER ;$$
SHOW PROCEDURE CODE p1;
CALL p1;
DROP PROCEDURE p1;
--echo #
--echo # End of 10.2 tests
--echo #
--echo #
--echo # MDEV-13581 ROW TYPE OF t1 and t1%ROWTYPE for routine parameters
--echo #
@@ -948,6 +972,10 @@ delimiter ;|
show function code f1;
drop function f1;
--echo #
--echo # End of 10.3 tests
--echo #
--echo #
--echo # MDEV-19640 Wrong SHOW PROCEDURE output for SET GLOBAL sysvar1=expr, sysvar2=expr
@@ -963,3 +991,7 @@ $$
DELIMITER ;$$
SHOW PROCEDURE CODE p1;
DROP PROCEDURE p1;
--echo #
--echo # End of 10.5 tests
--echo #

View File

@@ -121,8 +121,8 @@ js0 js1 js2 js3
SELECT js0, JSON_COMPACT(js0), JSON_COMPACT('{}') FROM t1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t1 t1 js0 js0 252 (format=json) 4294967295 0 Y 144 0 33
def JSON_COMPACT(js0) 251 (format=json) 4294967295 0 Y 128 0 63
def JSON_COMPACT('{}') 253 (format=json) 6 0 Y 128 0 63
def JSON_COMPACT(js0) 251 (format=json) 4294967295 0 Y 128 0 33
def JSON_COMPACT('{}') 253 (format=json) 6 0 Y 0 0 33
js0 JSON_COMPACT(js0) JSON_COMPACT('{}')
DROP TABLE t1;
#

View File

@@ -6835,6 +6835,17 @@ SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ;
drop view v1;
drop table t1;
#
# MDEV-26299: Some views force server (and mysqldump) to generate
# invalid SQL for their definitions
#
create view v1 as
select * from
(select
"12345678901234567890123456789012345678901234567890123456789012345") as t1;
drop view v1;
CREATE VIEW v1 AS select `t1`.`12345678901234567890123456789012345678901234567890123456789012345` AS `Name_exp_1` from (select '12345678901234567890123456789012345678901234567890123456789012345') `t1`;
drop view v1;
#
# End of 10.2 tests
#
#

View File

@@ -6560,6 +6560,25 @@ SELECT 1 FROM (SELECT count(((SELECT i1 FROM v1))) FROM v1) dt ;
drop view v1;
drop table t1;
--echo #
--echo # MDEV-26299: Some views force server (and mysqldump) to generate
--echo # invalid SQL for their definitions
--echo #
create view v1 as
select * from
(select
"12345678901234567890123456789012345678901234567890123456789012345") as t1;
let $definition=`select VIEW_DEFINITION from information_schema.views where TABLE_NAME="v1"`;
drop view v1;
eval CREATE VIEW v1 AS $definition;
drop view v1;
--echo #
--echo # End of 10.2 tests
--echo #

View File

@@ -454,6 +454,21 @@ Message XAER_RMFAIL: The command cannot be executed when global transaction is i
xa commit 'foo';
drop table t1;
#
# MDEV-22445 Crash on HANDLER READ NEXT after XA PREPARE
#
CREATE TABLE t (a INT KEY) ENGINE=InnoDB;
HANDLER t OPEN AS t;
XA START '0';
SELECT * FROM t;
a
XA END '0';
XA PREPARE '0';
HANDLER t READ NEXT;
ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the PREPARED state
# Cleanup
XA COMMIT '0';
DROP TABLE t;
#
# End of 10.2 tests
#
XA BEGIN 'xid';

View File

@@ -597,6 +597,23 @@ show status like 'foo';
xa commit 'foo';
drop table t1;
--echo #
--echo # MDEV-22445 Crash on HANDLER READ NEXT after XA PREPARE
--echo #
CREATE TABLE t (a INT KEY) ENGINE=InnoDB;
HANDLER t OPEN AS t;
XA START '0';
SELECT * FROM t;
XA END '0';
XA PREPARE '0';
--error ER_XAER_RMFAIL
HANDLER t READ NEXT;
--echo # Cleanup
XA COMMIT '0';
DROP TABLE t;
--echo #
--echo # End of 10.2 tests
--echo #

View File

@@ -1271,6 +1271,7 @@ sub command_line_setup {
{
$path_client_bindir= mtr_path_exists("$bindir/client_release",
"$bindir/client_debug",
"$bindir/client/debug",
"$bindir/client$opt_vs_config",
"$bindir/client",
"$bindir/bin");

View File

@@ -10,9 +10,9 @@ connection node_2;
SET SESSION wsrep_sync_wait = 0;
SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1;
SELECT COUNT(*) = 0 FROM t1;
COUNT(*) = 0
1
SELECT COUNT(*) AS EXPECT_0 FROM t1;
EXPECT_0
0
connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
connection node_2a;
FLUSH TABLES WITH READ LOCK;;
@@ -29,12 +29,12 @@ ERROR HY000: Lock wait timeout exceeded; try restarting transaction
connection node_2a;
UNLOCK TABLES;
connection node_2;
SELECT COUNT(*) = 1 FROM t1;
COUNT(*) = 1
SELECT COUNT(*) AS EXPECT_1 FROM t1;
EXPECT_1
1
INSERT INTO t1 VALUES (3);
connection node_1;
SELECT COUNT(*) = 2 FROM t1;
COUNT(*) = 2
1
SELECT COUNT(*) AS EXPECT_2 FROM t1;
EXPECT_2
2
DROP TABLE t1;

View File

@@ -18,7 +18,8 @@
CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB;
--connection node_2
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'
--source include/wait_condition.inc
--let $galera_sync_point = apply_monitor_slave_enter_sync
--source include/galera_set_sync_point.inc
@@ -31,7 +32,7 @@ SET SESSION wsrep_sync_wait = 0;
# Wait until applier has blocked
--source include/galera_wait_sync_point.inc
SELECT COUNT(*) = 0 FROM t1;
SELECT COUNT(*) AS EXPECT_0 FROM t1;
--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2
--connection node_2a
@@ -61,9 +62,11 @@ INSERT INTO t1 VALUES (2);
UNLOCK TABLES;
--connection node_2
SELECT COUNT(*) = 1 FROM t1;
--let $wait_condition = SELECT COUNT(*) = 1 FROM t1
--source include/wait_condition.inc
SELECT COUNT(*) AS EXPECT_1 FROM t1;
INSERT INTO t1 VALUES (3);
--connection node_1
SELECT COUNT(*) = 2 FROM t1;
SELECT COUNT(*) AS EXPECT_2 FROM t1;
DROP TABLE t1;

View File

@@ -71,35 +71,16 @@ connection node_3a;
SET SESSION wsrep_sync_wait = 0;
SET SESSION wsrep_sync_wait = DEFAULT;
connection node_1a;
Timeout in wait_condition.inc for SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log
Id User Host db Command Time State Info Progress
1 system user NULL Sleep 66 wsrep aborter idle NULL 0.000
2 system user NULL Sleep 66 closing tables NULL 0.000
10 root localhost test Sleep 58 NULL 0.000
11 root localhost:52722 test Sleep 56 NULL 0.000
12 root localhost:52724 test Query 0 starting show full processlist 0.000
SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log;
EXPECT_0
1
0
connection node_2a;
Timeout in wait_condition.inc for SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log
Id User Host db Command Time State Info Progress
1 system user NULL Sleep 96 wsrep aborter idle NULL 0.000
2 system user NULL Sleep 87 closing tables NULL 0.000
10 root localhost:37222 test Sleep 64 NULL 0.000
11 root localhost:37228 test Query 0 starting show full processlist 0.000
SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log;
EXPECT_0
1
0
connection node_3a;
Timeout in wait_condition.inc for SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log
Id User Host db Command Time State Info Progress
1 system user NULL Sleep 122 wsrep aborter idle NULL 0.000
2 system user NULL Sleep 117 closing tables NULL 0.000
10 root localhost:60992 test Sleep 117 NULL 0.000
11 root localhost:60994 test Query 0 starting show full processlist 0.000
SELECT COUNT(*) AS EXPECT_0 FROM mysql.wsrep_streaming_log;
EXPECT_0
1
0
connection node_1;
DROP TABLE t1;

View File

@@ -589,3 +589,14 @@ ALTER TABLE t1 ALTER COLUMN a SET DEFAULT 7,
--disable_info
DROP TABLE t1;
--enable_warnings
--echo #
--echo # MDEV-26262 frm is corrupted after ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
--echo #
--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
CREATE TABLE MDEV_26262 (a INT,b INT AS (b) VIRTUAL);
--let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err
--let SEARCH_PATTERN=Incorrect information in file: './test/MDEV_26262.frm'
--source include/search_pattern_in_file.inc

View File

@@ -703,6 +703,12 @@ ADD COLUMN c INT AS (1 + DEFAULT(a)) VIRTUAL;
affected rows: 1
info: Records: 1 Duplicates: 0 Warnings: 0
DROP TABLE t1;
#
# MDEV-26262 frm is corrupted after ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
#
CREATE TABLE MDEV_26262 (a INT,b INT AS (b) VIRTUAL);
ERROR 01000: Expression for field `b` is referring to uninitialized field `b`
NOT FOUND /Incorrect information in file: './test/MDEV_26262.frm'/ in mysqld.1.err
DROP VIEW IF EXISTS v1,v2;
DROP TABLE IF EXISTS t1,t2,t3;
DROP PROCEDURE IF EXISTS p1;

View File

@@ -703,6 +703,12 @@ ADD COLUMN c INT AS (1 + DEFAULT(a)) VIRTUAL;
affected rows: 1
info: Records: 1 Duplicates: 0 Warnings: 0
DROP TABLE t1;
#
# MDEV-26262 frm is corrupted after ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
#
CREATE TABLE MDEV_26262 (a INT,b INT AS (b) VIRTUAL);
ERROR 01000: Expression for field `b` is referring to uninitialized field `b`
NOT FOUND /Incorrect information in file: './test/MDEV_26262.frm'/ in mysqld.1.err
DROP VIEW IF EXISTS v1,v2;
DROP TABLE IF EXISTS t1,t2,t3;
DROP PROCEDURE IF EXISTS p1;

View File

@@ -20,3 +20,12 @@
SET @save_format = @@GLOBAL.innodb_default_row_format;
SET GLOBAL innodb_default_row_format = redundant;
CREATE TABLE t1 (c1 INT) ENGINE=InnoDB;
@@ -49,7 +49,7 @@
ERROR HY000: Can't create table `test`.`t` (errno: 140 "Wrong create options")
SHOW WARNINGS;
Level Code Message
-Warning 1478 InnoDB: PAGE_COMPRESSED requires PAGE_COMPRESSION_LEVEL or innodb_compression_level > 0
+Warning 140 InnoDB: PAGE_COMPRESSED table can't have ROW_TYPE=REDUNDANT
Error 1005 Can't create table `test`.`t` (errno: 140 "Wrong create options")
Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB
CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1 page_compression_level=1;

View File

@@ -42,3 +42,26 @@ SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
t1 InnoDB # Redundant # # # # # # NULL # NULL NULL latin1_swedish_ci NULL 0 N
DROP TABLE t1;
SET @save_level=@@GLOBAL.innodb_compression_level;
SET GLOBAL innodb_compression_level=0;
CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1;
ERROR HY000: Can't create table `test`.`t` (errno: 140 "Wrong create options")
SHOW WARNINGS;
Level Code Message
Warning 1478 InnoDB: PAGE_COMPRESSED requires PAGE_COMPRESSION_LEVEL or innodb_compression_level > 0
Error 1005 Can't create table `test`.`t` (errno: 140 "Wrong create options")
Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB
CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1 page_compression_level=1;
DROP TABLE IF EXISTS t;
SET GLOBAL innodb_compression_level=1;
CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1;
DROP TABLE IF EXISTS t;
SET GLOBAL innodb_compression_level=1;
CREATE TABLE t(a INT)ENGINE=InnoDB ROW_FORMAT=DYNAMIC page_compressed=1;
SET GLOBAL innodb_compression_level=0;
ALTER TABLE t FORCE, ROW_FORMAT=DEFAULT, ALGORITHM=INPLACE;
ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'PAGE_COMPRESSED'
ALTER TABLE t FORCE, ROW_FORMAT=DEFAULT, ALGORITHM=COPY;
ERROR HY000: Can't create table `test`.`t` (errno: 140 "Wrong create options")
DROP TABLE t;
SET GLOBAL innodb_compression_level=@save_level;

View File

@@ -408,8 +408,8 @@ INSERT INTO t1 VALUES (1,2);
CREATE TABLE x AS SELECT * FROM t1;
ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state
connect con1,localhost,root,,test;
SET foreign_key_checks= OFF, innodb_lock_wait_timeout= 1;
SET lock_wait_timeout=5;
SET foreign_key_checks= OFF, innodb_lock_wait_timeout= 0;
SET lock_wait_timeout=2;
ALTER TABLE t1 ADD FOREIGN KEY f (a) REFERENCES t1 (pk), LOCK=EXCLUSIVE;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
disconnect con1;
@@ -491,7 +491,7 @@ BEGIN;
UPDATE users SET name = 'qux' WHERE id = 1;
connect con1,localhost,root;
connection con1;
SET innodb_lock_wait_timeout= 1;
SET innodb_lock_wait_timeout= 0;
DELETE FROM matchmaking_groups WHERE id = 10;
connection default;
COMMIT;
@@ -531,9 +531,10 @@ connection con1;
BEGIN;
UPDATE t2 SET f = 11 WHERE id = 1;
connection default;
SET innodb_lock_wait_timeout= 1;
SET innodb_lock_wait_timeout= 0;
DELETE FROM t1 WHERE id = 1;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
SET innodb_lock_wait_timeout= 1;
connection con1;
COMMIT;
connection default;
@@ -897,3 +898,31 @@ create or replace table t2 (pk int primary key, a varchar(4096) unique, foreign
ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
drop table t1;
# End of 10.5 tests
#
# MDEV-26554 Table-rebuilding DDL on parent table causes crash
# for INSERT into child table
#
CREATE TABLE parent(a INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE child(a INT PRIMARY KEY REFERENCES parent(a)) ENGINE=InnoDB;
connect con1, localhost, root,,;
BEGIN;
INSERT INTO child SET a=1;
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`))
connection default;
SET innodb_lock_wait_timeout=0, foreign_key_checks=0;
TRUNCATE TABLE parent;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
ALTER TABLE parent FORCE, ALGORITHM=COPY;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
ALTER TABLE parent ADD COLUMN b INT, ALGORITHM=INSTANT;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
disconnect con1;
SET innodb_lock_wait_timeout=DEFAULT;
TRUNCATE TABLE parent;
ALTER TABLE parent FORCE, ALGORITHM=COPY;
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
ALTER TABLE parent ADD COLUMN b INT, ALGORITHM=INSTANT;
DROP TABLE child, parent;
# End of 10.6 tests

View File

@@ -107,3 +107,29 @@ ALTER TABLE t RENAME INDEX i2 to x, ALGORITHM=INPLACE;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
SET DEBUG_DBUG = @saved_debug_dbug;
DROP TABLE t;
#
# MDEV-26772 InnoDB DDL fails with DUPLICATE KEY error
#
create table t1(f1 int not null primary key,
f2 int not null, index idx(f2))engine=innodb;
insert into t1 values(1, 1);
connect con1,localhost,root,,,;
SET DEBUG_SYNC='before_delete_table_stats SIGNAL blocked WAIT_FOR go';
SET innodb_lock_wait_timeout=0;
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
SET DEBUG_SYNC='now SIGNAL go';
connection con1;
connection default;
COMMIT;
SET DEBUG_SYNC=RESET;
connection con1;
ALTER TABLE t1 RENAME KEY idx TO idx1, ALGORITHM=COPY;
disconnect con1;
connection default;
DROP TABLE t1;
# End of 10.6 tests

View File

@@ -75,7 +75,7 @@ DROP TABLE t1;
Warnings:
Warning 1932 Table 'test.t1' doesn't exist in engine
DROP TABLE t2,t3;
FOUND 5 /\[ERROR\] InnoDB: Table test/t1 in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=511\b/ in mysqld.1.err
FOUND 6 /\[ERROR\] InnoDB: Table test/t1 in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=511\b/ in mysqld.1.err
# restart
ib_buffer_pool
ib_logfile0

View File

@@ -43,16 +43,19 @@ SET DEBUG_SYNC='foreign_constraint_check_for_ins SIGNAL fk WAIT_FOR go';
INSERT INTO child SET a=5;
connection default;
SET DEBUG_SYNC='now WAIT_FOR fk';
SET foreign_key_checks=0;
SET foreign_key_checks=0, innodb_lock_wait_timeout=0;
TRUNCATE TABLE parent;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
SET DEBUG_SYNC='now SIGNAL go';
connection dml;
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`) ON UPDATE CASCADE)
SELECT * FROM parent;
a
3
5
SELECT * FROM child;
a
3
5
disconnect dml;
connection default;
SET DEBUG_SYNC = RESET;

View File

@@ -24,8 +24,7 @@ SELECT COUNT(*) FROM information_schema.innodb_buffer_page
WHERE table_name = '`test`.`t`';
COUNT(*)
1
# INSERT lots of data in table 'big': begin
# INSERT lots of data in table 'big': end
INSERT INTO big SELECT REPEAT('a', 1024) FROM seq_1_to_10240;
SELECT COUNT(*) FROM information_schema.innodb_buffer_page
WHERE table_name = '`test`.`t`';
COUNT(*)

View File

@@ -51,3 +51,28 @@ TRUNCATE TABLE t1;
--replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 #
SHOW TABLE STATUS LIKE 't1';
DROP TABLE t1;
SET @save_level=@@GLOBAL.innodb_compression_level;
SET GLOBAL innodb_compression_level=0;
--error ER_CANT_CREATE_TABLE
CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1;
SHOW WARNINGS;
--disable_warnings
--error 0,ER_CANT_CREATE_TABLE
CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1 page_compression_level=1;
DROP TABLE IF EXISTS t;
SET GLOBAL innodb_compression_level=1;
--error 0,ER_CANT_CREATE_TABLE
CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1;
DROP TABLE IF EXISTS t;
--enable_warnings
SET GLOBAL innodb_compression_level=1;
CREATE TABLE t(a INT)ENGINE=InnoDB ROW_FORMAT=DYNAMIC page_compressed=1;
SET GLOBAL innodb_compression_level=0;
--error ER_ILLEGAL_HA_CREATE_OPTION
ALTER TABLE t FORCE, ROW_FORMAT=DEFAULT, ALGORITHM=INPLACE;
--error ER_CANT_CREATE_TABLE
ALTER TABLE t FORCE, ROW_FORMAT=DEFAULT, ALGORITHM=COPY;
DROP TABLE t;
SET GLOBAL innodb_compression_level=@save_level;

View File

@@ -411,8 +411,8 @@ INSERT INTO t1 VALUES (1,2);
--error ER_XAER_RMFAIL
CREATE TABLE x AS SELECT * FROM t1;
--connect (con1,localhost,root,,test)
SET foreign_key_checks= OFF, innodb_lock_wait_timeout= 1;
SET lock_wait_timeout=5;
SET foreign_key_checks= OFF, innodb_lock_wait_timeout= 0;
SET lock_wait_timeout=2;
--error ER_LOCK_WAIT_TIMEOUT
ALTER TABLE t1 ADD FOREIGN KEY f (a) REFERENCES t1 (pk), LOCK=EXCLUSIVE;# Cleanup
--disconnect con1
@@ -506,7 +506,7 @@ UPDATE users SET name = 'qux' WHERE id = 1;
connect (con1,localhost,root);
--connection con1
SET innodb_lock_wait_timeout= 1;
SET innodb_lock_wait_timeout= 0;
DELETE FROM matchmaking_groups WHERE id = 10;
--connection default
@@ -544,9 +544,10 @@ BEGIN;
UPDATE t2 SET f = 11 WHERE id = 1;
--connection default
SET innodb_lock_wait_timeout= 1;
SET innodb_lock_wait_timeout= 0;
--error ER_LOCK_WAIT_TIMEOUT
DELETE FROM t1 WHERE id = 1;
SET innodb_lock_wait_timeout= 1;
--connection con1
COMMIT;
@@ -902,4 +903,36 @@ drop table t1;
--echo # End of 10.5 tests
--echo #
--echo # MDEV-26554 Table-rebuilding DDL on parent table causes crash
--echo # for INSERT into child table
--echo #
CREATE TABLE parent(a INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE child(a INT PRIMARY KEY REFERENCES parent(a)) ENGINE=InnoDB;
connect (con1, localhost, root,,);
BEGIN;
--error ER_NO_REFERENCED_ROW_2
INSERT INTO child SET a=1;
connection default;
SET innodb_lock_wait_timeout=0, foreign_key_checks=0;
--error ER_LOCK_WAIT_TIMEOUT
TRUNCATE TABLE parent;
--error ER_LOCK_WAIT_TIMEOUT
ALTER TABLE parent FORCE, ALGORITHM=COPY;
--error ER_LOCK_WAIT_TIMEOUT
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
--error ER_LOCK_WAIT_TIMEOUT
ALTER TABLE parent ADD COLUMN b INT, ALGORITHM=INSTANT;
disconnect con1;
# Restore the timeout to avoid occasional races with purge.
SET innodb_lock_wait_timeout=DEFAULT;
TRUNCATE TABLE parent;
ALTER TABLE parent FORCE, ALGORITHM=COPY;
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
ALTER TABLE parent ADD COLUMN b INT, ALGORITHM=INSTANT;
DROP TABLE child, parent;
--echo # End of 10.6 tests
--source include/wait_until_count_sessions.inc

View File

@@ -142,5 +142,42 @@ SET DEBUG_DBUG = @saved_debug_dbug;
DROP TABLE t;
--echo #
--echo # MDEV-26772 InnoDB DDL fails with DUPLICATE KEY error
--echo #
create table t1(f1 int not null primary key,
f2 int not null, index idx(f2))engine=innodb;
insert into t1 values(1, 1);
connect(con1,localhost,root,,,);
SET DEBUG_SYNC='before_delete_table_stats SIGNAL blocked WAIT_FOR go';
SET innodb_lock_wait_timeout=0;
send ALTER TABLE t1 FORCE, ALGORITHM=COPY;
connection default;
SET DEBUG_SYNC='now WAIT_FOR blocked';
BEGIN;
SELECT * FROM mysql.innodb_table_stats FOR UPDATE;
SET DEBUG_SYNC='now SIGNAL go';
connection con1;
reap;
connection default;
COMMIT;
SET DEBUG_SYNC=RESET;
connection con1;
ALTER TABLE t1 RENAME KEY idx TO idx1, ALGORITHM=COPY;
disconnect con1;
connection default;
DROP TABLE t1;
--echo # End of 10.6 tests
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc

View File

@@ -52,12 +52,12 @@ send INSERT INTO child SET a=5;
connection default;
SET DEBUG_SYNC='now WAIT_FOR fk';
SET foreign_key_checks=0;
SET foreign_key_checks=0, innodb_lock_wait_timeout=0;
--error ER_LOCK_WAIT_TIMEOUT
TRUNCATE TABLE parent;
SET DEBUG_SYNC='now SIGNAL go';
connection dml;
--error ER_NO_REFERENCED_ROW_2
reap;
SELECT * FROM parent;
SELECT * FROM child;

View File

@@ -1 +1 @@
--innodb-buffer-pool-size=10M
--innodb-buffer-pool-size=5M

View File

@@ -10,6 +10,7 @@
-- source include/not_embedded.inc
# This test is slow on buildbot.
--source include/big_test.inc
--source include/have_sequence.inc
CREATE TABLE t (a INT) ENGINE=INNODB STATS_PERSISTENT=0;
@@ -33,18 +34,7 @@ SELECT COUNT(*) FROM information_schema.innodb_buffer_page
WHERE table_name = '`test`.`t`';
# evict table 't' by inserting as much data as the BP size itself
-- echo # INSERT lots of data in table 'big': begin
-- disable_query_log
BEGIN;
-- let $i = 10240
while ($i)
{
INSERT INTO big VALUES (REPEAT('a', 1024));
dec $i;
}
COMMIT;
-- enable_query_log
-- echo # INSERT lots of data in table 'big': end
INSERT INTO big SELECT REPEAT('a', 1024) FROM seq_1_to_10240;
# confirm that all pages for table 't' have been evicted
SELECT COUNT(*) FROM information_schema.innodb_buffer_page

View File

@@ -313,9 +313,7 @@ FTS_DOC_ID
65536
131071
drop table t1;
call mtr.add_suppression("\\[ERROR\\] InnoDB: Doc ID 20030101000000 is too big. Its difference with largest used Doc ID 0 cannot exceed or equal to 65535");
CREATE TABLE t1 (FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200), FULLTEXT(title)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (NULL, NULL), (20030101000000, 20030102000000);
ERROR HY000: Invalid InnoDB FTS Doc ID
DROP TABLE t1;

View File

@@ -0,0 +1,131 @@
#
# Bug#32831765 SERVER HITS OOM CONDITION WHEN LOADING TWO
# INNODB TABLES WITH FTS INDEXES
#
create table t1 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
create table t2 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
create table t3 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
create table t4 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
#create procedure to inset into the table.
CREATE PROCEDURE `proc_insert`(IN tab_name VARCHAR(40))
BEGIN
DECLARE i INT DEFAULT 1;
SET @insert_tbl =CONCAT('INSERT INTO ', tab_name, '( `col01`, `col02`,
`col03`, `col04`, `col05`, `col06`, `col07`, `col08`, `col09`, `col10`,
`col11`, `col12`, `col13`, `col14`, `col15`, `col16`, `col17`, `col18`,
`col19`, `col20`, `col21`, `col22`, `col23`, `col24`, `col25`, `col26`,
`col27`, `col28`, `col29`, `col30`)
VALUES ( MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()))');
PREPARE ins_stmt FROM @insert_tbl;
while (i <= 2000) DO
EXECUTE ins_stmt;
SET i = i + 1;
END WHILE;
DEALLOCATE PREPARE ins_stmt;
END |
SET @save_dbug= @@GLOBAL.debug_dbug;
SET GLOBAL debug_dbug="+d,fts_optimize_wq_count_check";
connect con1,localhost,root,,;
call proc_insert('t1');
connect con2,localhost,root,,;
call proc_insert('t1');
connect con3,localhost,root,,;
call proc_insert('t2');
connect con4,localhost,root,,;
call proc_insert('t2');
connect con5,localhost,root,,;
call proc_insert('t3');
connect con6,localhost,root,,;
call proc_insert('t3');
connect con7,localhost,root,,;
call proc_insert('t4');
connection default;
call proc_insert('t4');
SET GLOBAL debug_dbug= @save_dbug;
connection con1;
disconnect con1;
connection con2;
disconnect con2;
connection con3;
disconnect con3;
connection con4;
disconnect con4;
connection con5;
disconnect con5;
connection con6;
disconnect con6;
connection con7;
disconnect con7;
connection default;
DROP TABLE t1,t2,t3,t4;
DROP PROCEDURE proc_insert;

View File

@@ -972,3 +972,24 @@ SELECT * FROM information_schema.innodb_ft_deleted;
DOC_ID
DROP TABLE t1;
SET GLOBAL innodb_ft_aux_table=DEFAULT;
#
# MDEV-19522 InnoDB commit fails when FTS_DOC_ID value
# is greater than 4294967295
#
CREATE TABLE t1(
FTS_DOC_ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
f1 TEXT, f2 TEXT, PRIMARY KEY (FTS_DOC_ID),
FULLTEXT KEY (f1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,'txt','bbb');
UPDATE t1 SET FTS_DOC_ID = 4294967298;
SELECT * FROM t1 WHERE match(f1) against("txt");
FTS_DOC_ID f1 f2
4294967298 txt bbb
SET @@session.insert_id = 100000000000;
INSERT INTO t1(f1, f2) VALUES ('aaa', 'bbb');
CREATE FULLTEXT INDEX i ON t1 (f2);
SELECT * FROM t1 WHERE match(f2) against("bbb");
FTS_DOC_ID f1 f2
4294967298 txt bbb
100000000000 aaa bbb
DROP TABLE t1;

View File

@@ -277,9 +277,7 @@ insert into t1(f1, f2) values(3, "This is the third record");
select FTS_DOC_ID from t1;
drop table t1;
call mtr.add_suppression("\\[ERROR\\] InnoDB: Doc ID 20030101000000 is too big. Its difference with largest used Doc ID 0 cannot exceed or equal to 65535");
CREATE TABLE t1 (FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200), FULLTEXT(title)) ENGINE=InnoDB;
--error 182
INSERT INTO t1 VALUES (NULL, NULL), (20030101000000, 20030102000000);
DROP TABLE t1;

View File

@@ -0,0 +1,164 @@
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/big_test.inc
--echo #
--echo # Bug#32831765 SERVER HITS OOM CONDITION WHEN LOADING TWO
--echo # INNODB TABLES WITH FTS INDEXES
--echo #
create table t1 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
create table t2 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
create table t3 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
create table t4 ( `id` int unsigned NOT NULL AUTO_INCREMENT, `col01` text,
`col02` text, `col03` text, `col04` text, `col05` text, `col06` text, `col07`
text, `col08` text, `col09` text, `col10` text, `col11` text, `col12` text,
`col13` text, `col14` text, `col15` text, `col16` text, `col17` text, `col18`
text, `col19` text, `col20` text, `col21` text, `col22` text, `col23` text,
`col24` text, `col25` text, `col26` text, `col27` text, `col28` text, `col29`
text, `col30` text, PRIMARY KEY (`id`), FULLTEXT KEY (`col01`), FULLTEXT KEY
(`col02`), FULLTEXT KEY (`col03`), FULLTEXT KEY (`col04`), FULLTEXT KEY
(`col05`), FULLTEXT KEY (`col06`), FULLTEXT KEY (`col07`), FULLTEXT KEY
(`col08`), FULLTEXT KEY (`col09`), FULLTEXT KEY (`col10`), FULLTEXT KEY
(`col11`), FULLTEXT KEY (`col12`), FULLTEXT KEY (`col13`), FULLTEXT KEY
(`col14`), FULLTEXT KEY (`col15`), FULLTEXT KEY (`col16`), FULLTEXT KEY
(`col17`), FULLTEXT KEY (`col18`), FULLTEXT KEY (`col19`), FULLTEXT KEY
(`col20`), FULLTEXT KEY (`col21`), FULLTEXT KEY (`col22`), FULLTEXT KEY
(`col23`), FULLTEXT KEY (`col24`), FULLTEXT KEY (`col25`), FULLTEXT KEY
(`col26`), FULLTEXT KEY (`col27`), FULLTEXT KEY (`col28`), FULLTEXT KEY
(`col29`), FULLTEXT KEY (`col30`)) engine=innodb;
delimiter |;
--echo #create procedure to inset into the table.
CREATE PROCEDURE `proc_insert`(IN tab_name VARCHAR(40))
BEGIN
DECLARE i INT DEFAULT 1;
SET @insert_tbl =CONCAT('INSERT INTO ', tab_name, '( `col01`, `col02`,
`col03`, `col04`, `col05`, `col06`, `col07`, `col08`, `col09`, `col10`,
`col11`, `col12`, `col13`, `col14`, `col15`, `col16`, `col17`, `col18`,
`col19`, `col20`, `col21`, `col22`, `col23`, `col24`, `col25`, `col26`,
`col27`, `col28`, `col29`, `col30`)
VALUES ( MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()), MD5(RAND()),
MD5(RAND()))');
PREPARE ins_stmt FROM @insert_tbl;
while (i <= 2000) DO
EXECUTE ins_stmt;
SET i = i + 1;
END WHILE;
DEALLOCATE PREPARE ins_stmt;
END |
delimiter ;|
# Ensure that the number of SYNC requests will not exceed 1000.
SET @save_dbug= @@GLOBAL.debug_dbug;
SET GLOBAL debug_dbug="+d,fts_optimize_wq_count_check";
connect (con1,localhost,root,,);
send call proc_insert('t1');
connect (con2,localhost,root,,);
send call proc_insert('t1');
connect (con3,localhost,root,,);
send call proc_insert('t2');
connect (con4,localhost,root,,);
send call proc_insert('t2');
connect (con5,localhost,root,,);
send call proc_insert('t3');
connect (con6,localhost,root,,);
send call proc_insert('t3');
connect (con7,localhost,root,,);
send call proc_insert('t4');
connection default;
call proc_insert('t4');
SET GLOBAL debug_dbug= @save_dbug;
connection con1;
reap;
disconnect con1;
connection con2;
reap;
disconnect con2;
connection con3;
reap;
disconnect con3;
connection con4;
reap;
disconnect con4;
connection con5;
reap;
disconnect con5;
connection con6;
reap;
disconnect con6;
connection con7;
reap;
disconnect con7;
connection default;
DROP TABLE t1,t2,t3,t4;
DROP PROCEDURE proc_insert;

View File

@@ -949,3 +949,21 @@ SET GLOBAL innodb_ft_aux_table='test/t1';
SELECT * FROM information_schema.innodb_ft_deleted;
DROP TABLE t1;
SET GLOBAL innodb_ft_aux_table=DEFAULT;
--echo #
--echo # MDEV-19522 InnoDB commit fails when FTS_DOC_ID value
--echo # is greater than 4294967295
--echo #
CREATE TABLE t1(
FTS_DOC_ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
f1 TEXT, f2 TEXT, PRIMARY KEY (FTS_DOC_ID),
FULLTEXT KEY (f1)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,'txt','bbb');
UPDATE t1 SET FTS_DOC_ID = 4294967298;
SELECT * FROM t1 WHERE match(f1) against("txt");
SET @@session.insert_id = 100000000000;
INSERT INTO t1(f1, f2) VALUES ('aaa', 'bbb');
CREATE FULLTEXT INDEX i ON t1 (f2);
SELECT * FROM t1 WHERE match(f2) against("bbb");
# Cleanup
DROP TABLE t1;

View File

@@ -165,3 +165,23 @@ flush privileges;
uninstall plugin simple_password_check;
create user foo1 identified by 'pwd';
drop user foo1;
#
# MDEV-26650: Failed ALTER USER/GRANT statement removes the
# password from the cache
#
create user foo1@localhost identified by '<GDFH:3ghj';
show grants for foo1@localhost;
Grants for foo1@localhost
GRANT USAGE ON *.* TO `foo1`@`localhost` IDENTIFIED BY PASSWORD '*1D62FA326F98258451ED56A404F15452423DCC1D'
install soname "simple_password_check";
ALTER USER foo1@localhost identified by 'foo1';
ERROR HY000: Operation ALTER USER failed for 'foo1'@'localhost'
show grants for foo1@localhost;
Grants for foo1@localhost
GRANT USAGE ON *.* TO `foo1`@`localhost` IDENTIFIED BY PASSWORD '*1D62FA326F98258451ED56A404F15452423DCC1D'
flush privileges;
show grants for foo1@localhost;
Grants for foo1@localhost
GRANT USAGE ON *.* TO `foo1`@`localhost` IDENTIFIED BY PASSWORD '*1D62FA326F98258451ED56A404F15452423DCC1D'
drop user foo1@localhost;
uninstall plugin simple_password_check;

View File

@@ -122,3 +122,17 @@ uninstall plugin simple_password_check;
create user foo1 identified by 'pwd';
drop user foo1;
--echo #
--echo # MDEV-26650: Failed ALTER USER/GRANT statement removes the
--echo # password from the cache
--echo #
create user foo1@localhost identified by '<GDFH:3ghj';
show grants for foo1@localhost;
install soname "simple_password_check";
--error ER_CANNOT_USER
ALTER USER foo1@localhost identified by 'foo1';
show grants for foo1@localhost;
flush privileges;
show grants for foo1@localhost;
drop user foo1@localhost;
uninstall plugin simple_password_check;

View File

@@ -65,3 +65,269 @@ drop role look, isp, xxx, ppp;
connection default;
disconnect con1;
drop user nnnn@'%';
CREATE USER u@localhost;
CREATE ROLE r1;
CREATE ROLE r2;
CREATE ROLE r3;
CREATE ROLE r4;
CREATE ROLE r5;
CREATE ROLE r6;
CREATE ROLE r7;
CREATE ROLE r8;
CREATE ROLE r9;
CREATE ROLE r10;
CREATE ROLE r11;
CREATE ROLE r12;
CREATE ROLE r13;
CREATE ROLE r14;
CREATE ROLE r15;
CREATE ROLE r16;
CREATE ROLE r17;
CREATE ROLE r18;
CREATE ROLE r19;
CREATE ROLE r20;
CREATE ROLE r21;
CREATE ROLE r22;
CREATE ROLE r23;
CREATE ROLE r24;
CREATE ROLE r25;
CREATE ROLE r26;
CREATE ROLE r27;
CREATE ROLE r28;
CREATE ROLE r29;
CREATE ROLE r30;
CREATE ROLE r31;
CREATE ROLE r32;
CREATE ROLE r33;
CREATE ROLE r34;
CREATE ROLE r35;
CREATE ROLE r36;
CREATE ROLE r37;
CREATE ROLE r38;
CREATE ROLE r39;
CREATE ROLE r40;
CREATE ROLE r41;
CREATE ROLE r42;
CREATE ROLE r43;
CREATE ROLE r44;
CREATE ROLE r45;
CREATE ROLE r46;
CREATE ROLE r47;
CREATE ROLE r48;
CREATE ROLE r49;
CREATE ROLE r50;
CREATE ROLE r51;
CREATE ROLE r52;
CREATE ROLE r53;
CREATE ROLE r54;
CREATE ROLE r55;
CREATE ROLE r56;
CREATE ROLE r57;
CREATE ROLE r58;
CREATE ROLE r59;
CREATE ROLE r60;
CREATE ROLE r61;
CREATE ROLE r62;
CREATE ROLE r63;
CREATE ROLE r64;
CREATE ROLE r65;
CREATE ROLE r66;
CREATE ROLE r67;
CREATE ROLE r68;
CREATE ROLE r69;
CREATE ROLE r70;
CREATE ROLE r71;
CREATE ROLE r72;
CREATE ROLE r73;
CREATE ROLE r74;
CREATE ROLE r75;
CREATE ROLE r76;
CREATE ROLE r77;
CREATE ROLE r78;
CREATE ROLE r79;
CREATE ROLE r80;
CREATE ROLE r81;
CREATE ROLE r82;
CREATE ROLE r83;
CREATE ROLE r84;
CREATE ROLE r85;
CREATE ROLE r86;
CREATE ROLE r87;
CREATE ROLE r88;
CREATE ROLE r89;
CREATE ROLE r90;
CREATE ROLE r91;
CREATE ROLE r92;
CREATE ROLE r93;
CREATE ROLE r94;
CREATE ROLE r95;
CREATE ROLE r96;
CREATE ROLE r97;
CREATE ROLE r98;
CREATE ROLE r99;
CREATE ROLE r100;
CREATE ROLE r101;
CREATE ROLE r102;
CREATE ROLE r103;
CREATE ROLE r104;
CREATE ROLE r105;
CREATE ROLE r106;
CREATE ROLE r107;
CREATE ROLE r108;
CREATE ROLE r109;
CREATE ROLE r110;
CREATE ROLE r111;
CREATE ROLE r112;
CREATE ROLE r113;
CREATE ROLE r114;
CREATE ROLE r115;
CREATE ROLE r116;
CREATE ROLE r117;
CREATE ROLE r118;
CREATE ROLE r119;
CREATE ROLE r120;
CREATE ROLE r121;
CREATE ROLE r122;
CREATE ROLE r123;
CREATE ROLE r124;
CREATE ROLE r125;
CREATE ROLE r126;
CREATE ROLE r127;
CREATE ROLE r128;
CREATE ROLE n;
CREATE ROLE d WITH ADMIN n;
CREATE ROLE '%' WITH ADMIN u@localhost;
DROP ROLE n;
CREATE USER 't';
DROP ROLE r1;
DROP ROLE r2;
DROP ROLE r3;
DROP ROLE r4;
DROP ROLE r5;
DROP ROLE r6;
DROP ROLE r7;
DROP ROLE r8;
DROP ROLE r9;
DROP ROLE r10;
DROP ROLE r11;
DROP ROLE r12;
DROP ROLE r13;
DROP ROLE r14;
DROP ROLE r15;
DROP ROLE r16;
DROP ROLE r17;
DROP ROLE r18;
DROP ROLE r19;
DROP ROLE r20;
DROP ROLE r21;
DROP ROLE r22;
DROP ROLE r23;
DROP ROLE r24;
DROP ROLE r25;
DROP ROLE r26;
DROP ROLE r27;
DROP ROLE r28;
DROP ROLE r29;
DROP ROLE r30;
DROP ROLE r31;
DROP ROLE r32;
DROP ROLE r33;
DROP ROLE r34;
DROP ROLE r35;
DROP ROLE r36;
DROP ROLE r37;
DROP ROLE r38;
DROP ROLE r39;
DROP ROLE r40;
DROP ROLE r41;
DROP ROLE r42;
DROP ROLE r43;
DROP ROLE r44;
DROP ROLE r45;
DROP ROLE r46;
DROP ROLE r47;
DROP ROLE r48;
DROP ROLE r49;
DROP ROLE r50;
DROP ROLE r51;
DROP ROLE r52;
DROP ROLE r53;
DROP ROLE r54;
DROP ROLE r55;
DROP ROLE r56;
DROP ROLE r57;
DROP ROLE r58;
DROP ROLE r59;
DROP ROLE r60;
DROP ROLE r61;
DROP ROLE r62;
DROP ROLE r63;
DROP ROLE r64;
DROP ROLE r65;
DROP ROLE r66;
DROP ROLE r67;
DROP ROLE r68;
DROP ROLE r69;
DROP ROLE r70;
DROP ROLE r71;
DROP ROLE r72;
DROP ROLE r73;
DROP ROLE r74;
DROP ROLE r75;
DROP ROLE r76;
DROP ROLE r77;
DROP ROLE r78;
DROP ROLE r79;
DROP ROLE r80;
DROP ROLE r81;
DROP ROLE r82;
DROP ROLE r83;
DROP ROLE r84;
DROP ROLE r85;
DROP ROLE r86;
DROP ROLE r87;
DROP ROLE r88;
DROP ROLE r89;
DROP ROLE r90;
DROP ROLE r91;
DROP ROLE r92;
DROP ROLE r93;
DROP ROLE r94;
DROP ROLE r95;
DROP ROLE r96;
DROP ROLE r97;
DROP ROLE r98;
DROP ROLE r99;
DROP ROLE r100;
DROP ROLE r101;
DROP ROLE r102;
DROP ROLE r103;
DROP ROLE r104;
DROP ROLE r105;
DROP ROLE r106;
DROP ROLE r107;
DROP ROLE r108;
DROP ROLE r109;
DROP ROLE r110;
DROP ROLE r111;
DROP ROLE r112;
DROP ROLE r113;
DROP ROLE r114;
DROP ROLE r115;
DROP ROLE r116;
DROP ROLE r117;
DROP ROLE r118;
DROP ROLE r119;
DROP ROLE r120;
DROP ROLE r121;
DROP ROLE r122;
DROP ROLE r123;
DROP ROLE r124;
DROP ROLE r125;
DROP ROLE r126;
DROP ROLE r127;
DROP ROLE r128;
DROP ROLE d;
DROP ROLE '%';
DROP USER 't';
DROP USER u@localhost;

View File

@@ -67,3 +67,34 @@ drop role look, isp, xxx, ppp;
connection default;
disconnect con1;
drop user nnnn@'%';
#
# MDEV-17964 Assertion `status == 0' failed in add_role_user_mapping_action
# upon CREATE USER and DROP ROLE
#
CREATE USER u@localhost;
--let $n= 1
while ($n < 129)
{
eval CREATE ROLE r$n;
inc $n;
}
CREATE ROLE n;
CREATE ROLE d WITH ADMIN n;
CREATE ROLE '%' WITH ADMIN u@localhost;
DROP ROLE n;
CREATE USER 't';
--let $n= 1
while ($n < 129)
{
eval DROP ROLE r$n;
inc $n;
}
DROP ROLE d;
DROP ROLE '%';
DROP USER 't';
DROP USER u@localhost;

View File

@@ -0,0 +1,48 @@
# This file ensures that a slave's id filtering variables (i.e. DO_DOMAIN_IDS,
# IGNORE_DOMAIN_IDS, and IGNORE_SERVER_IDS) are cleared after issuing
# `RESET SLAVE ALL`.
#
# param $_do_domain_ids Integer list of values to use for DO_DOMAIN_IDS
# param $_ignore_domain_ids Integer list of values to use for IGNORE_DOMAIN_IDS
# param $_ignore_server_ids Integer list of values to use for IGNORE_SERVER_IDS
#
--echo # Id filtering variable values should be empty initially
let $do_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
let $ignore_server_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Server_Ids, 1);
if (`SELECT "$do_domain_ids_before" != "" OR
"$ignore_domain_ids_before" != "" OR
"$ignore_server_ids_before" != ""`)
{
die("CHANGE MASTER TO id filter variables are not empty initially");
}
--echo # Set id filtering variables
eval CHANGE MASTER TO DO_DOMAIN_IDS=$_do_domain_ids, IGNORE_DOMAIN_IDS=$_ignore_domain_ids, IGNORE_SERVER_IDS=$_ignore_server_ids, MASTER_USE_GTID=SLAVE_POS;
let $do_domain_ids_set= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_set= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
let $ignore_server_ids_set= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Server_Ids, 1);
--echo # do domain id list: $do_domain_ids_set
--echo # ignore domain id list: $ignore_domain_ids_set
--echo # ignore server id list: $ignore_server_ids_set
--echo # RESET SLAVE ALL should clear values for all id filtering variables
RESET SLAVE ALL;
--replace_result $MASTER_MYPORT MASTER_MYPORT
eval change master to master_port=$MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
--source include/start_slave.inc
--source include/stop_slave.inc
let $do_domain_ids_cleared= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1);
let $ignore_domain_ids_cleared= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1);
let $ignore_server_ids_cleared= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Server_Ids, 1);
if (`SELECT "$do_domain_ids_cleared" != "" OR
"$ignore_domain_ids_cleared" != "" OR
"$ignore_server_ids_cleared" != ""`)
{
die("RESET SLAVE ALL did not clear id filtering variables");
}

View File

@@ -0,0 +1,43 @@
include/master-slave.inc
[connection master]
#
# Failed CHANGE MASTER TO should not change relay log status
#
connection slave;
include/stop_slave.inc
SET @@debug_dbug="d,simulate_find_log_pos_error";
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=SLAVE_POS;
ERROR HY000: Target log not found in binlog index
SET @@debug_dbug="";
include/start_slave.inc
#
# Ensure relay log can be updated after a failed CHANGE MASTER
#
FLUSH RELAY LOGS;
include/wait_for_slave_param.inc [Relay_Log_File]
#
# Slave should continue to receive data from old master after failed
# CHANGE MASTER TO
#
connection master;
CREATE TABLE t1 (a int);
insert into t1 values (1);
connection slave;
connection slave;
#
# Future CHANGE MASTER calls should succeed
#
include/stop_slave.inc
CHANGE MASTER TO MASTER_USE_GTID=SLAVE_POS;
include/start_slave.inc
########################
# Cleanup
########################
connection master;
DROP TABLE t1;
connection slave;
include/stop_slave.inc
RESET SLAVE ALL;
change master to master_port=MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
include/start_slave.inc
include/rpl_end.inc

View File

@@ -0,0 +1,54 @@
include/master-slave.inc
[connection master]
connection slave;
include/stop_slave.inc
#
# Category 1) DO_DOMAIN_IDS and IGNORE_SERVER_IDS specified together
#
# Id filtering variable values should be empty initially
# Set id filtering variables
CHANGE MASTER TO DO_DOMAIN_IDS=(1), IGNORE_DOMAIN_IDS=(), IGNORE_SERVER_IDS=(3), MASTER_USE_GTID=SLAVE_POS;
# do domain id list: 1
# ignore domain id list:
# ignore server id list: 3
# RESET SLAVE ALL should clear values for all id filtering variables
RESET SLAVE ALL;
change master to master_port=MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
include/start_slave.inc
include/stop_slave.inc
#
# Category 2) IGNORE_DOMAIN_IDS and IGNORE_SERVER_IDS specified together
#
# Id filtering variable values should be empty initially
# Set id filtering variables
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(2), IGNORE_SERVER_IDS=(3), MASTER_USE_GTID=SLAVE_POS;
# do domain id list:
# ignore domain id list: 2
# ignore server id list: 3
# RESET SLAVE ALL should clear values for all id filtering variables
RESET SLAVE ALL;
change master to master_port=MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
include/start_slave.inc
include/stop_slave.inc
#
# Category 3) Null check - edge case with all empty lists to ensure a
# lack of specification doesn't break anything
#
# Id filtering variable values should be empty initially
# Set id filtering variables
CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(), IGNORE_SERVER_IDS=(), MASTER_USE_GTID=SLAVE_POS;
# do domain id list:
# ignore domain id list:
# ignore server id list:
# RESET SLAVE ALL should clear values for all id filtering variables
RESET SLAVE ALL;
change master to master_port=MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
include/start_slave.inc
include/stop_slave.inc
############################
# Cleanup
############################
connection slave;
change master to master_port=MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
include/start_slave.inc
include/rpl_end.inc

View File

@@ -219,4 +219,65 @@ include/sync_with_master_gtid.inc
connection master;
drop database test_ign;
drop table t1, t2, t3, tm;
#
# MDEV-26682 slave lock timeout with XA and gap locks
#
create table t1 (a int primary key, b int unique) engine=innodb;
insert t1 values (1,1),(3,3),(5,5);
connection slave;
set session tx_isolation='repeatable-read';
start transaction;
select * from t1;
a b
1 1
3 3
5 5
connect m2, localhost, root;
delete from t1 where a=3;
xa start 'x1';
update t1 set b=3 where a=5;
xa end 'x1';
xa prepare 'x1';
connect m3, localhost, root;
insert t1 values (2, 2);
-->slave
connection slave;
commit;
select * from t1;
a b
1 1
2 2
5 5
connection m2;
xa rollback 'x1';
disconnect m2;
disconnect m3;
connection master;
drop table t1;
create table t1 (id int auto_increment primary key, c1 int not null unique)
engine=innodb;
create table t2 (id int auto_increment primary key, c1 int not null,
foreign key(c1) references t1(c1), unique key(c1)) engine=innodb;
insert t1 values (869,1), (871,3), (873,4), (872,5), (870,6), (877,7);
insert t2 values (795,6), (800,7);
xa start '1';
update t2 set id = 9, c1 = 5 where c1 in (null, null, null, null, null, 7, 3);
connect con1, localhost,root;
xa start '2';
delete from t1 where c1 like '3%';
xa end '2';
xa prepare '2';
connection master;
xa end '1';
xa prepare '1';
->slave
connection slave;
connection slave;
include/sync_with_master_gtid.inc
connection con1;
xa commit '2';
disconnect con1;
connection master;
xa commit '1';
drop table t2, t1;
include/rpl_end.inc

View File

@@ -228,6 +228,67 @@ include/sync_with_master_gtid.inc
connection master;
drop database test_ign;
drop table t1, t2, t3, tm;
#
# MDEV-26682 slave lock timeout with XA and gap locks
#
create table t1 (a int primary key, b int unique) engine=innodb;
insert t1 values (1,1),(3,3),(5,5);
connection slave;
set session tx_isolation='repeatable-read';
start transaction;
select * from t1;
a b
1 1
3 3
5 5
connect m2, localhost, root;
delete from t1 where a=3;
xa start 'x1';
update t1 set b=3 where a=5;
xa end 'x1';
xa prepare 'x1';
connect m3, localhost, root;
insert t1 values (2, 2);
-->slave
connection slave;
commit;
select * from t1;
a b
1 1
2 2
5 5
connection m2;
xa rollback 'x1';
disconnect m2;
disconnect m3;
connection master;
drop table t1;
create table t1 (id int auto_increment primary key, c1 int not null unique)
engine=innodb;
create table t2 (id int auto_increment primary key, c1 int not null,
foreign key(c1) references t1(c1), unique key(c1)) engine=innodb;
insert t1 values (869,1), (871,3), (873,4), (872,5), (870,6), (877,7);
insert t2 values (795,6), (800,7);
xa start '1';
update t2 set id = 9, c1 = 5 where c1 in (null, null, null, null, null, 7, 3);
connect con1, localhost,root;
xa start '2';
delete from t1 where c1 like '3%';
xa end '2';
xa prepare '2';
connection master;
xa end '1';
xa prepare '1';
->slave
connection slave;
connection slave;
include/sync_with_master_gtid.inc
connection con1;
xa commit '2';
disconnect con1;
connection master;
xa commit '1';
drop table t2, t1;
connection slave;
include/stop_slave.inc
SET @@global.gtid_pos_auto_engines="";

View File

@@ -0,0 +1,93 @@
#
# Purpose:
# This test ensures that issuing a CHANGE MASTER will not put a replica into
# an inconsistent state if the slave cannot find the log files (i.e. the call to
# find_log_pos in reset_logs fails). More specifically, right before a replica
# purges the relay logs (part of the `CHANGE MASTER TO` logic), the relay log is
# temporarily closed with state LOG_TO_BE_OPENED. If the server is issued a
# CHANGE MASTER and it errors in-between the temporary log closure and purge,
# i.e. during the function find_log_pos, the log should be closed. The bug
# reported by MDEV-25284 revealed the log is not properly closed, such that
# future relay log updates fail, and future CHANGE MASTER calls crash the
# server.
#
# Methodology:
# This test ensures that the relay log is properly closed by ensuring future
# updates and CHANGE MASTER calls succeed.
#
# References:
# MDEV-25284: Assertion `info->type == READ_CACHE ||
# info->type == WRITE_CACHE' failed
#
--source include/master-slave.inc
--source include/have_debug.inc
--echo #
--echo # Failed CHANGE MASTER TO should not change relay log status
--echo #
--connection slave
--source include/stop_slave.inc
SET @@debug_dbug="d,simulate_find_log_pos_error";
error 1373;
CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=SLAVE_POS;
SET @@debug_dbug="";
--source include/start_slave.inc
--echo #
--echo # Ensure relay log can be updated after a failed CHANGE MASTER
--echo #
FLUSH RELAY LOGS;
--let $slave_param= Relay_Log_File
--let $slave_param_value= slave-relay-bin.000003
--source include/wait_for_slave_param.inc
--echo #
--echo # Slave should continue to receive data from old master after failed
--echo # CHANGE MASTER TO
--echo #
--connection master
CREATE TABLE t1 (a int);
insert into t1 values (1);
--let $master_checksum= `CHECKSUM TABLE t1`
--sync_slave_with_master
--connection slave
if ($master_checksum != `CHECKSUM TABLE t1`)
{
die("Replica failed to pull data from primary after failed CHANGE MASTER TO");
}
--echo #
--echo # Future CHANGE MASTER calls should succeed
--echo #
--source include/stop_slave.inc
CHANGE MASTER TO MASTER_USE_GTID=SLAVE_POS;
--source include/start_slave.inc
--echo ########################
--echo # Cleanup
--echo ########################
--connection master
DROP TABLE t1;
--connection slave
--source include/stop_slave.inc
RESET SLAVE ALL;
--replace_result $MASTER_MYPORT MASTER_MYPORT
eval change master to master_port=$MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
--source include/start_slave.inc
--disable_query_log
call mtr.add_suppression("Failed to locate old binlog or relay log files");
--enable_query_log
--source include/rpl_end.inc

View File

@@ -0,0 +1,72 @@
#
# Purpose:
# This test validates that after issuing the `SLAVE RESET ALL` command,
# any corresponding IGNORE_DOMAIN_IDS/DO_DOMAIN_IDS and IGNORE_SERVER_IDS
# values are cleared.
#
#
# Methodology:
# To ensure the filtering variables are properly cleared after issuing
# SLAVE RESET ALL, we categorize different combinations of allowable input
# into three different options, and ensure that the variables are cleared for
# each category. The categories are as follows:
# Category 1) DO_DOMAIN_IDS and IGNORE_SERVER_IDS specified together
# Category 2) IGNORE_DOMAIN_IDS and IGNORE_SERVER_IDS specified together
# Category 3) Null check - edge case with all empty lists to ensure a lack
# of specification doesn't break anything
#
# To specify the values, the variables are set in `CHANGE MASTER TO`. To
# ensure the slave state is correct, we test the domain/server id filtering
# variable values at the following times while testing each category.
#
# Before CHANGE MASTER TO the filtering variables are tested to all be
# empty.
#
# After CHANGE MASTER TO the variables are tested to ensure they reflect
# those set in the CHANGE MASTER command.
#
# After RESET SLAVE ALL the filtering variables are tested to all be
# empty.
#
--source include/master-slave.inc
--source include/have_debug.inc
--connection slave
--source include/stop_slave.inc
--echo #
--echo # Category 1) DO_DOMAIN_IDS and IGNORE_SERVER_IDS specified together
--echo #
--let $_do_domain_ids= (1)
--let $_ignore_domain_ids= ()
--let $_ignore_server_ids= (3)
--source include/rpl_reset_slave_all_check.inc
--echo #
--echo # Category 2) IGNORE_DOMAIN_IDS and IGNORE_SERVER_IDS specified together
--echo #
--let $_do_domain_ids= ()
--let $_ignore_domain_ids= (2)
--let $_ignore_server_ids= (3)
--source include/rpl_reset_slave_all_check.inc
--echo #
--echo # Category 3) Null check - edge case with all empty lists to ensure a
--echo # lack of specification doesn't break anything
--echo #
--let $_do_domain_ids= ()
--let $_ignore_domain_ids= ()
--let $_ignore_server_ids= ()
--source include/rpl_reset_slave_all_check.inc
--echo ############################
--echo # Cleanup
--echo ############################
--connection slave
--replace_result $MASTER_MYPORT MASTER_MYPORT
eval change master to master_port=$MASTER_MYPORT, master_host='127.0.0.1', master_user='root';
--source include/start_slave.inc
--source include/rpl_end.inc

View File

@@ -1,6 +1,6 @@
#
# This "body" file checks general properties of XA transaction replication
# as of MDEV-7974.
# as of MDEV-742.
# Parameters:
# --let rpl_xa_check= SELECT ...
#
@@ -353,3 +353,81 @@ source include/sync_with_master_gtid.inc;
connection master;
--eval drop database test_ign
drop table t1, t2, t3, tm;
--echo #
--echo # MDEV-26682 slave lock timeout with XA and gap locks
--echo #
create table t1 (a int primary key, b int unique) engine=innodb;
insert t1 values (1,1),(3,3),(5,5);
sync_slave_with_master;
# set a strong isolation level to keep the read view below.
# alternatively a long-running select can do that too even in read-committed
set session tx_isolation='repeatable-read';
start transaction;
# opens a read view to disable purge on the slave
select * from t1;
connect m2, localhost, root;
# now, delete a value, purge it on the master, but not on the slave
delete from t1 where a=3;
xa start 'x1';
# this sets a gap lock on <3>, when it exists (so, on the slave)
update t1 set b=3 where a=5;
xa end 'x1';
xa prepare 'x1';
connect m3, localhost, root;
# and this tries to insert straight into the locked gap
insert t1 values (2, 2);
echo -->slave;
sync_slave_with_master;
commit;
select * from t1;
connection m2;
xa rollback 'x1';
disconnect m2;
disconnect m3;
connection master;
drop table t1;
create table t1 (id int auto_increment primary key, c1 int not null unique)
engine=innodb;
create table t2 (id int auto_increment primary key, c1 int not null,
foreign key(c1) references t1(c1), unique key(c1)) engine=innodb;
insert t1 values (869,1), (871,3), (873,4), (872,5), (870,6), (877,7);
insert t2 values (795,6), (800,7);
xa start '1';
update t2 set id = 9, c1 = 5 where c1 in (null, null, null, null, null, 7, 3);
connect con1, localhost,root;
xa start '2';
delete from t1 where c1 like '3%';
xa end '2';
xa prepare '2';
connection master;
xa end '1';
xa prepare '1';
echo ->slave;
sync_slave_with_master;
connection slave;
source include/sync_with_master_gtid.inc;
connection con1;
xa commit '2';
disconnect con1;
connection master;
xa commit '1';
drop table t2, t1;

View File

@@ -169,6 +169,10 @@ TARGET_LINK_LIBRARIES(mysys dbug strings ${ZLIB_LIBRARY}
${LIBNSL} ${LIBM} ${LIBRT} ${CMAKE_DL_LIBS} ${LIBSOCKET} ${LIBEXECINFO})
DTRACE_INSTRUMENT(mysys)
IF (HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
TARGET_LINK_LIBRARIES(mysys atomic)
ENDIF()
IF(HAVE_BFD_H)
TARGET_LINK_LIBRARIES(mysys bfd)
ENDIF(HAVE_BFD_H)

View File

@@ -88,5 +88,32 @@ Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET6'::ff'
DROP TABLE t1;
#
# MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item
#
CREATE TABLE t1 (pk inet6, c text) engine=myisam;
INSERT INTO t1 VALUES ('::',1);
CREATE TABLE t2 (d text, KEY (d)) engine=innodb ;
Warnings:
Note 1071 Specified key was too long; max key length is 3072 bytes
INSERT INTO t2 VALUES (2);
SELECT * FROM t2 JOIN t1 ON ( t1.pk > t2.d);
d pk c
Warnings:
Warning 1292 Incorrect inet6 value: '2'
UPDATE t2 JOIN t1 ON ( t1.pk > t2.d) SET t1.c = 1;
ERROR 22007: Incorrect inet6 value: '2'
SET sql_mode='';
UPDATE t2 JOIN t1 ON ( t1.pk > t2.d) SET t1.c = 1;
Warnings:
Warning 1292 Incorrect inet6 value: '2'
SET sql_mode=DEFAULT;
SELECT * FROM t1;
pk c
:: 1
SELECT * FROM t2;
d
2
DROP TABLE t1, t2;
#
# End of 10.5 tests
#

View File

@@ -12,6 +12,24 @@
SET default_storage_engine=InnoDB;
--source type_inet6_engines.inc
--echo #
--echo # MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item
--echo #
CREATE TABLE t1 (pk inet6, c text) engine=myisam;
INSERT INTO t1 VALUES ('::',1);
CREATE TABLE t2 (d text, KEY (d)) engine=innodb ;
INSERT INTO t2 VALUES (2);
SELECT * FROM t2 JOIN t1 ON ( t1.pk > t2.d);
--error ER_TRUNCATED_WRONG_VALUE
UPDATE t2 JOIN t1 ON ( t1.pk > t2.d) SET t1.c = 1;
SET sql_mode='';
UPDATE t2 JOIN t1 ON ( t1.pk > t2.d) SET t1.c = 1;
SET sql_mode=DEFAULT;
SELECT * FROM t1;
SELECT * FROM t2;
DROP TABLE t1, t2;
--echo #
--echo # End of 10.5 tests

View File

@@ -88,5 +88,24 @@ Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET6'::ff'
DROP TABLE t1;
#
# MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item
#
CREATE TABLE t1 (c varchar(64), key(c)) engine=myisam;
INSERT INTO t1 VALUES ('0::1'),('::1'),('::2');
SELECT * FROM t1 WHERE c>CAST('::1' AS INET6);
c
::2
EXPLAIN SELECT * FROM t1 WHERE c>CAST('::1' AS INET6);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index c c 67 NULL 3 Using where; Using index
SELECT * FROM t1 WHERE c=CAST('::1' AS INET6);
c
0::1
::1
EXPLAIN SELECT * FROM t1 WHERE c=CAST('::1' AS INET6);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index c c 67 NULL 3 Using where; Using index
DROP TABLE t1;
#
# End of 10.5 tests
#

View File

@@ -10,6 +10,18 @@
SET default_storage_engine=MyISAM;
--source type_inet6_engines.inc
--echo #
--echo # MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item
--echo #
CREATE TABLE t1 (c varchar(64), key(c)) engine=myisam;
INSERT INTO t1 VALUES ('0::1'),('::1'),('::2');
SELECT * FROM t1 WHERE c>CAST('::1' AS INET6);
EXPLAIN SELECT * FROM t1 WHERE c>CAST('::1' AS INET6);
SELECT * FROM t1 WHERE c=CAST('::1' AS INET6);
EXPLAIN SELECT * FROM t1 WHERE c=CAST('::1' AS INET6);
DROP TABLE t1;
--echo #
--echo # End of 10.5 tests

View File

@@ -816,7 +816,7 @@ IF 'BASE TABLE' = (select table_type from information_schema.tables where table_
'max_statement_time', max_statement_time,
'plugin', if(plugin>'',plugin,if(length(password)=16,'mysql_old_password','mysql_native_password')),
'authentication_string', if(plugin>'' and authentication_string>'',authentication_string,password),
'password_last_changed', if(password_expired='Y', 0, UNIX_TIMESTAMP(password_last_changed)),
'password_last_changed', if(password_expired='Y', 0, if(password_last_changed, UNIX_TIMESTAMP(password_last_changed), UNIX_TIMESTAMP())),
'password_lifetime', ifnull(password_lifetime, -1),
'account_locked', 'Y'=account_locked,
'default_role', default_role,

View File

@@ -105,7 +105,7 @@ BEGIN
SET @query = 'DELETE
FROM performance_schema.setup_objects
WHERE NOT (OBJECT_TYPE IN (''EVENT'', ''FUNCTION'', ''PROCEDURE'', ''TABLE'', ''TRIGGER'') AND OBJECT_NAME = ''%''
WHERE NOT (OBJECT_TYPE IN (''EVENT'', ''FUNCTION'', ''PROCEDURE'', ''TABLE'', ''TRIGGER'') AND OBJECT_NAME = ''%''
AND (OBJECT_SCHEMA = ''mysql'' AND ENABLED = ''NO'' AND TIMED = ''NO'' )
OR (OBJECT_SCHEMA = ''performance_schema'' AND ENABLED = ''NO'' AND TIMED = ''NO'' )
OR (OBJECT_SCHEMA = ''information_schema'' AND ENABLED = ''NO'' AND TIMED = ''NO'' )

View File

@@ -1276,6 +1276,21 @@ bool Field::can_be_substituted_to_equal_item(const Context &ctx,
}
bool Field::cmp_is_done_using_type_handler_of_this(const Item_bool_func *cond,
const Item *item) const
{
/*
We could eventually take comparison_type_handler() from cond,
instead of calculating it again. But only some descendants of
Item_bool_func has this method. So this needs some hierarchy changes.
Another option is to pass "class Context" to this method.
*/
Type_handler_hybrid_field_type cmp(type_handler_for_comparison());
return !cmp.aggregate_for_comparison(item->type_handler_for_comparison()) &&
cmp.type_handler() == type_handler_for_comparison();
}
/*
This handles all numeric and BIT data types.
*/
@@ -7368,7 +7383,7 @@ bool
Field_longstr::cmp_to_string_with_same_collation(const Item_bool_func *cond,
const Item *item) const
{
return item->cmp_type() == STRING_RESULT &&
return cmp_is_done_using_type_handler_of_this(cond, item) &&
charset() == cond->compare_collation();
}
@@ -7377,7 +7392,7 @@ bool
Field_longstr::cmp_to_string_with_stricter_collation(const Item_bool_func *cond,
const Item *item) const
{
return item->cmp_type() == STRING_RESULT &&
return cmp_is_done_using_type_handler_of_this(cond, item) &&
(charset() == cond->compare_collation() ||
cond->compare_collation()->state & MY_CS_BINSORT);
}

View File

@@ -1651,6 +1651,8 @@ protected:
}
int warn_if_overflow(int op_result);
Copy_func *get_identical_copy_func() const;
bool cmp_is_done_using_type_handler_of_this(const Item_bool_func *cond,
const Item *item) const;
bool can_optimize_scalar_range(const RANGE_OPT_PARAM *param,
const KEY_PART *key_part,
const Item_bool_func *cond,

View File

@@ -3846,8 +3846,48 @@ void Item_string::print(String *str, enum_query_type query_type)
}
else
{
// Caller wants a result in the charset of str_value.
str_value.print(str);
/*
We're restoring a parse-able statement from an Item tree.
Make sure to revert character set conversions that previously
happened in the parser when Item_string was created.
*/
if (print_introducer)
{
/*
Print the string as is, without conversion:
Strings with introducers are not converted in the parser.
*/
str_value.print(str);
}
else
{
/*
Print the string with conversion.
Strings without introducers are converted in the parser,
from character_set_client to character_set_connection.
When restoring a CREATE VIEW statement,
- str_value.charsets() contains parse time character_set_connection
- str->charset() contains parse time character_set_client
So we convert the string back from parse-time character_set_connection
to parse time character_set_client.
In some cases, e.g. SHOW PROCEDURE CODE, it's also possible
that str->charset() is "utf8mb3" instead of parse time
character_set_client. In these cases we convert
here from the parse-time character_set_connection to utf8mb3.
QQ: perhaps the code behind SHOW PROCEDURE CODE should
also request the result in the parse-time character_set_client
(like the code restoring CREATE VIEW statements does),
rather than in utf8mb3:
- utf8mb3 does not work well with non-BMP characters (e.g. emoji).
- Simply changing utf8mb3 to utf8mb4 will not fully help:
some character sets have unassigned characters,
they get lost during during cs->utf8mb4->cs round trip.
*/
str_value.print_with_conversion(str, str->charset());
}
}
str->append('\'');

View File

@@ -3640,6 +3640,7 @@ LEX_CSTRING Item_func_json_format::func_name_cstring() const
bool Item_func_json_format::fix_length_and_dec()
{
decimals= 0;
collation.set(args[0]->collation);
max_length= args[0]->max_length;
set_maybe_null();
return FALSE;

View File

@@ -951,6 +951,20 @@ public:
void unlock_binlog_end_pos() { mysql_mutex_unlock(&LOCK_binlog_end_pos); }
mysql_mutex_t* get_binlog_end_pos_lock() { return &LOCK_binlog_end_pos; }
/*
Ensures the log's state is either LOG_OPEN or LOG_CLOSED. If something
failed along the desired path and left the log in invalid state, i.e.
LOG_TO_BE_OPENED, forces the state to be LOG_CLOSED.
*/
void try_fix_log_state()
{
mysql_mutex_lock(get_log_lock());
/* Only change the log state if it is LOG_TO_BE_OPENED */
if (log_state == LOG_TO_BE_OPENED)
log_state= LOG_CLOSED;
mysql_mutex_unlock(get_log_lock());
}
int wait_for_update_binlog_end_pos(THD* thd, struct timespec * timeout);
/*

View File

@@ -5621,20 +5621,14 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
}
}
#ifdef HAVE_QUERY_CACHE
#ifdef WITH_WSREP
#if defined(WITH_WSREP) && defined(HAVE_QUERY_CACHE)
/*
Moved invalidation right before the call to rows_event_stmt_cleanup(),
to avoid query cache being polluted with stale entries,
*/
if (! (WSREP(thd) && wsrep_thd_is_applying(thd)))
{
#endif /* WITH_WSREP */
query_cache.invalidate_locked_for_write(thd, rgi->tables_to_lock);
#ifdef WITH_WSREP
}
#endif /* WITH_WSREP */
#endif
if (WSREP(thd) && wsrep_thd_is_applying(thd))
query_cache.invalidate_locked_for_write(thd, rgi->tables_to_lock);
#endif /* WITH_WSREP && HAVE_QUERY_CACHE */
}
table= m_table= rgi->m_table_map.get_table(m_table_id);
@@ -5835,19 +5829,20 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
restore_empty_query_table_list(thd->lex);
#if defined(WITH_WSREP) && defined(HAVE_QUERY_CACHE)
if (WSREP(thd) && wsrep_thd_is_applying(thd))
{
query_cache.invalidate_locked_for_write(thd, rgi->tables_to_lock);
}
if (WSREP(thd) && wsrep_thd_is_applying(thd))
query_cache.invalidate_locked_for_write(thd, rgi->tables_to_lock);
#endif /* WITH_WSREP && HAVE_QUERY_CACHE */
if (unlikely(get_flags(STMT_END_F) &&
(error= rows_event_stmt_cleanup(rgi, thd))))
slave_rows_error_report(ERROR_LEVEL,
thd->is_error() ? 0 : error,
rgi, thd, table,
get_type_str(),
RPL_LOG_NAME, log_pos);
if (get_flags(STMT_END_F))
{
if (unlikely((error= rows_event_stmt_cleanup(rgi, thd))))
slave_rows_error_report(ERROR_LEVEL, thd->is_error() ? 0 : error,
rgi, thd, table, get_type_str(),
RPL_LOG_NAME, log_pos);
if (thd->slave_thread)
free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
}
DBUG_RETURN(error);
err:

View File

@@ -260,6 +260,10 @@ void Json_writer::add_str(const String &str)
add_str(str.ptr(), str.length());
}
#ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS
thread_local std::vector<bool> Json_writer_struct::named_items_expectation;
#endif
Json_writer_temp_disable::Json_writer_temp_disable(THD *thd_arg)
{
thd= thd_arg;

View File

@@ -15,8 +15,12 @@
#ifndef JSON_WRITER_INCLUDED
#define JSON_WRITER_INCLUDED
#include "my_base.h"
#include "sql_select.h"
#include <vector>
class Opt_trace_stmt;
class Opt_trace_context;
class Json_writer;
@@ -308,6 +312,9 @@ public:
/* A common base for Json_writer_object and Json_writer_array */
class Json_writer_struct
{
#ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS
static thread_local std::vector<bool> named_items_expectation;
#endif
protected:
Json_writer* my_writer;
Json_value_helper context;
@@ -317,16 +324,35 @@ protected:
bool closed;
public:
explicit Json_writer_struct(THD *thd)
explicit Json_writer_struct(THD *thd, bool expect_named_children)
{
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
}
bool trace_started()
virtual ~Json_writer_struct()
{
#ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS
named_items_expectation.pop_back();
#endif
}
bool trace_started() const
{
return my_writer != 0;
}
#ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS
bool named_item_expected() const
{
return named_items_expectation.size() > 1
&& *(named_items_expectation.rbegin() + 1);
}
#endif
};
@@ -347,15 +373,21 @@ private:
}
public:
explicit Json_writer_object(THD *thd)
: Json_writer_struct(thd)
: Json_writer_struct(thd, true)
{
#ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS
DBUG_ASSERT(!named_item_expected());
#endif
if (unlikely(my_writer))
my_writer->start_object();
}
explicit Json_writer_object(THD* thd, const char *str)
: Json_writer_struct(thd)
: Json_writer_struct(thd, true)
{
#ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS
DBUG_ASSERT(named_item_expected());
#endif
if (unlikely(my_writer))
my_writer->add_member(str).start_object();
}
@@ -519,14 +551,22 @@ public:
class Json_writer_array : public Json_writer_struct
{
public:
Json_writer_array(THD *thd): Json_writer_struct(thd)
Json_writer_array(THD *thd)
: Json_writer_struct(thd, false)
{
#ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS
DBUG_ASSERT(!named_item_expected());
#endif
if (unlikely(my_writer))
my_writer->start_array();
}
Json_writer_array(THD *thd, const char *str) : Json_writer_struct(thd)
Json_writer_array(THD *thd, const char *str)
: Json_writer_struct(thd, false)
{
#ifdef ENABLED_JSON_WRITER_CONSISTENCY_CHECKS
DBUG_ASSERT(named_item_expected());
#endif
if (unlikely(my_writer))
my_writer->add_member(str).start_array();
}

View File

@@ -170,6 +170,8 @@ void Master_info::clear_in_memory_info(bool all)
{
port= MYSQL_PORT;
host[0] = 0; user[0] = 0; password[0] = 0;
domain_id_filter.clear_ids();
reset_dynamic(&ignore_server_ids);
}
}
@@ -1816,6 +1818,12 @@ void Domain_id_filter::reset_filter()
m_filter= false;
}
void Domain_id_filter::clear_ids()
{
reset_dynamic(&m_domain_ids[DO_DOMAIN_IDS]);
reset_dynamic(&m_domain_ids[IGNORE_DOMAIN_IDS]);
}
/**
Update the do/ignore domain id filter lists.

View File

@@ -78,6 +78,11 @@ public:
*/
void reset_filter();
/*
Clear do_ids and ignore_ids to disable domain id filtering
*/
void clear_ids();
/*
Update the do/ignore domain id filter lists.

View File

@@ -3362,24 +3362,24 @@ static int acl_user_update(THD *thd, ACL_USER *acl_user, uint nauth,
const Account_options &options,
const privilege_t privileges)
{
ACL_USER_PARAM::AUTH *work_copy= NULL;
if (nauth)
{
if (acl_user->nauth >= nauth)
acl_user->nauth= nauth;
else
acl_user->alloc_auth(&acl_memroot, nauth);
if (!(work_copy= (ACL_USER_PARAM::AUTH*)
alloc_root(thd->mem_root, nauth * sizeof(ACL_USER_PARAM::AUTH))))
return 1;
USER_AUTH *auth= combo.auth;
for (uint i= 0; i < nauth; i++, auth= auth->next)
{
acl_user->auth[i].plugin= auth->plugin;
acl_user->auth[i].auth_string= safe_lexcstrdup_root(&acl_memroot, auth->auth_str);
if (fix_user_plugin_ptr(acl_user->auth + i))
acl_user->auth[i].plugin= safe_lexcstrdup_root(&acl_memroot, auth->plugin);
LEX_CSTRING host= { acl_user->host.hostname ,
acl_user->hostname_length};
if (set_user_auth(thd, acl_user->user, host,
acl_user->auth + i, auth->pwtext))
work_copy[i].plugin= auth->plugin;
work_copy[i].auth_string= safe_lexcstrdup_root(&acl_memroot,
auth->auth_str);
if (fix_user_plugin_ptr(work_copy + i))
work_copy[i].plugin= safe_lexcstrdup_root(&acl_memroot, auth->plugin);
if (set_user_auth(thd, acl_user->user,
{acl_user->host.hostname, acl_user->hostname_length},
work_copy + i, auth->pwtext))
return 1;
}
}
@@ -3407,11 +3407,34 @@ static int acl_user_update(THD *thd, ACL_USER *acl_user, uint nauth,
if (options.account_locked != ACCOUNTLOCK_UNSPECIFIED)
acl_user->account_locked= options.account_locked == ACCOUNTLOCK_LOCKED;
/* Unexpire the user password */
if (thd->is_error())
{
// If something went wrong (including OOM) we will not spoil acl cache
return 1;
}
/* Unexpire the user password and copy AUTH (when no more errors possible)*/
if (nauth)
{
acl_user->password_expired= false;
acl_user->password_last_changed= thd->query_start();;
acl_user->password_last_changed= thd->query_start();
if (acl_user->nauth >= nauth)
{
acl_user->nauth= nauth;
}
else
{
if (acl_user->alloc_auth(&acl_memroot, nauth))
{
/*
acl_user is a copy, so NULL assigned in case of an error do not
change the acl cache
*/
return 1;
}
}
DBUG_ASSERT(work_copy); // allocated under the same condinition
memcpy(acl_user->auth, work_copy, nauth * sizeof(ACL_USER_PARAM::AUTH));
}
switch (options.password_expire) {
@@ -10208,8 +10231,8 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
LEX_USER *user_from, LEX_USER *user_to)
{
int result= 0;
int idx;
int elements;
bool restart;
const char *UNINIT_VAR(user);
const char *UNINIT_VAR(host);
ACL_USER *acl_user= NULL;
@@ -10317,82 +10340,98 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
DBUG_RETURN(-1);
}
#ifdef EXTRA_DEBUG
DBUG_PRINT("loop",("scan struct: %u search user: '%s' host: '%s'",
struct_no, user_from->user.str, user_from->host.str));
#endif
/* Loop over all elements *backwards* (see the comment below). */
for (idx= elements - 1; idx >= 0; idx--)
{
/*
Get a pointer to the element.
*/
switch (struct_no) {
case USER_ACL:
acl_user= dynamic_element(&acl_users, idx, ACL_USER*);
user= acl_user->user.str;
host= acl_user->host.hostname;
break;
/* Loop over elements backwards as it may reduce the number of mem-moves
for dynamic arrays.
case DB_ACL:
acl_db= &acl_dbs.at(idx);
user= acl_db->user;
host= acl_db->host.hostname;
We restart the loop, if we deleted or updated anything in a hash table
because calling my_hash_delete or my_hash_update shuffles elements indices
and we can miss some if we do only one scan.
*/
do {
restart= false;
for (int idx= elements - 1; idx >= 0; idx--)
{
/*
Get a pointer to the element.
*/
switch (struct_no) {
case USER_ACL:
acl_user= dynamic_element(&acl_users, idx, ACL_USER*);
user= acl_user->user.str;
host= acl_user->host.hostname;
break;
case COLUMN_PRIVILEGES_HASH:
case PROC_PRIVILEGES_HASH:
case FUNC_PRIVILEGES_HASH:
case PACKAGE_SPEC_PRIVILEGES_HASH:
case PACKAGE_BODY_PRIVILEGES_HASH:
grant_name= (GRANT_NAME*) my_hash_element(grant_name_hash, idx);
user= grant_name->user;
host= grant_name->host.hostname;
break;
case DB_ACL:
acl_db= &acl_dbs.at(idx);
user= acl_db->user;
host= acl_db->host.hostname;
break;
case PROXY_USERS_ACL:
acl_proxy_user= dynamic_element(&acl_proxy_users, idx, ACL_PROXY_USER*);
user= acl_proxy_user->get_user();
host= acl_proxy_user->get_host();
break;
case COLUMN_PRIVILEGES_HASH:
case PROC_PRIVILEGES_HASH:
case FUNC_PRIVILEGES_HASH:
case PACKAGE_SPEC_PRIVILEGES_HASH:
case PACKAGE_BODY_PRIVILEGES_HASH:
grant_name= (GRANT_NAME*) my_hash_element(grant_name_hash, idx);
user= grant_name->user;
host= grant_name->host.hostname;
break;
case ROLES_MAPPINGS_HASH:
role_grant_pair= (ROLE_GRANT_PAIR *) my_hash_element(roles_mappings_hash, idx);
user= role_grant_pair->u_uname;
host= role_grant_pair->u_hname;
break;
case PROXY_USERS_ACL:
acl_proxy_user= dynamic_element(&acl_proxy_users, idx, ACL_PROXY_USER*);
user= acl_proxy_user->get_user();
host= acl_proxy_user->get_host();
break;
default:
DBUG_ASSERT(0);
}
if (! host)
host= "";
case ROLES_MAPPINGS_HASH:
role_grant_pair= (ROLE_GRANT_PAIR *) my_hash_element(roles_mappings_hash, idx);
user= role_grant_pair->u_uname;
host= role_grant_pair->u_hname;
break;
default:
DBUG_ASSERT(0);
}
if (! host)
host= "";
#ifdef EXTRA_DEBUG
DBUG_PRINT("loop",("scan struct: %u index: %u user: '%s' host: '%s'",
struct_no, idx, user, host));
DBUG_PRINT("loop",("scan struct: %u index: %u user: '%s' host: '%s'",
struct_no, idx, user, host));
#endif
if (struct_no == ROLES_MAPPINGS_HASH)
{
const char* role= role_grant_pair->r_uname? role_grant_pair->r_uname: "";
if (user_from->is_role())
if (struct_no == ROLES_MAPPINGS_HASH)
{
/* When searching for roles within the ROLES_MAPPINGS_HASH, we have
to check both the user field as well as the role field for a match.
const char* role= role_grant_pair->r_uname? role_grant_pair->r_uname: "";
if (user_from->is_role())
{
/* When searching for roles within the ROLES_MAPPINGS_HASH, we have
to check both the user field as well as the role field for a match.
It is possible to have a role granted to a role. If we are going
to modify the mapping entry, it needs to be done on either on the
"user" end (here represented by a role) or the "role" end. At least
one part must match.
It is possible to have a role granted to a role. If we are going
to modify the mapping entry, it needs to be done on either on the
"user" end (here represented by a role) or the "role" end. At least
one part must match.
If the "user" end has a not-empty host string, it can never match
as we are searching for a role here. A role always has an empty host
string.
*/
if ((*host || strcmp(user_from->user.str, user)) &&
strcmp(user_from->user.str, role))
continue;
If the "user" end has a not-empty host string, it can never match
as we are searching for a role here. A role always has an empty host
string.
*/
if ((*host || strcmp(user_from->user.str, user)) &&
strcmp(user_from->user.str, role))
continue;
}
else
{
if (strcmp(user_from->user.str, user) ||
my_strcasecmp(system_charset_info, user_from->host.str, host))
continue;
}
}
else
{
@@ -10400,157 +10439,134 @@ static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop,
my_strcasecmp(system_charset_info, user_from->host.str, host))
continue;
}
}
else
{
if (strcmp(user_from->user.str, user) ||
my_strcasecmp(system_charset_info, user_from->host.str, host))
continue;
}
result= 1; /* At least one element found. */
if ( drop )
{
elements--;
switch ( struct_no ) {
case USER_ACL:
free_acl_user(dynamic_element(&acl_users, idx, ACL_USER*));
delete_dynamic_element(&acl_users, idx);
break;
result= 1; /* At least one element found. */
if ( drop )
{
elements--;
switch ( struct_no ) {
case USER_ACL:
free_acl_user(dynamic_element(&acl_users, idx, ACL_USER*));
delete_dynamic_element(&acl_users, idx);
break;
case DB_ACL:
acl_dbs.del(idx);
break;
case DB_ACL:
acl_dbs.del(idx);
break;
case COLUMN_PRIVILEGES_HASH:
case PROC_PRIVILEGES_HASH:
case FUNC_PRIVILEGES_HASH:
case PACKAGE_SPEC_PRIVILEGES_HASH:
case PACKAGE_BODY_PRIVILEGES_HASH:
my_hash_delete(grant_name_hash, (uchar*) grant_name);
/*
In our HASH implementation on deletion one elements
is moved into a place where a deleted element was,
and the last element is moved into the empty space.
Thus we need to re-examine the current element, but
we don't have to restart the search from the beginning.
*/
if (idx != elements)
idx++;
break;
case COLUMN_PRIVILEGES_HASH:
case PROC_PRIVILEGES_HASH:
case FUNC_PRIVILEGES_HASH:
case PACKAGE_SPEC_PRIVILEGES_HASH:
case PACKAGE_BODY_PRIVILEGES_HASH:
my_hash_delete(grant_name_hash, (uchar*) grant_name);
restart= true;
break;
case PROXY_USERS_ACL:
delete_dynamic_element(&acl_proxy_users, idx);
break;
case PROXY_USERS_ACL:
delete_dynamic_element(&acl_proxy_users, idx);
break;
case ROLES_MAPPINGS_HASH:
my_hash_delete(roles_mappings_hash, (uchar*) role_grant_pair);
if (idx != elements)
idx++;
break;
case ROLES_MAPPINGS_HASH:
my_hash_delete(roles_mappings_hash, (uchar*) role_grant_pair);
restart= true;
break;
default:
DBUG_ASSERT(0);
break;
default:
DBUG_ASSERT(0);
break;
}
}
}
else if ( user_to )
{
switch ( struct_no ) {
case USER_ACL:
acl_user->user= safe_lexcstrdup_root(&acl_memroot, user_to->user);
update_hostname(&acl_user->host, strdup_root(&acl_memroot, user_to->host.str));
acl_user->hostname_length= strlen(acl_user->host.hostname);
break;
else if ( user_to )
{
switch ( struct_no ) {
case USER_ACL:
acl_user->user= safe_lexcstrdup_root(&acl_memroot, user_to->user);
update_hostname(&acl_user->host, strdup_root(&acl_memroot, user_to->host.str));
acl_user->hostname_length= strlen(acl_user->host.hostname);
break;
case DB_ACL:
acl_db->user= strdup_root(&acl_memroot, user_to->user.str);
update_hostname(&acl_db->host, strdup_root(&acl_memroot, user_to->host.str));
break;
case DB_ACL:
acl_db->user= strdup_root(&acl_memroot, user_to->user.str);
update_hostname(&acl_db->host, strdup_root(&acl_memroot, user_to->host.str));
break;
case COLUMN_PRIVILEGES_HASH:
case PROC_PRIVILEGES_HASH:
case FUNC_PRIVILEGES_HASH:
case PACKAGE_SPEC_PRIVILEGES_HASH:
case PACKAGE_BODY_PRIVILEGES_HASH:
{
/*
Save old hash key and its length to be able to properly update
element position in hash.
*/
char *old_key= grant_name->hash_key;
size_t old_key_length= grant_name->key_length;
case COLUMN_PRIVILEGES_HASH:
case PROC_PRIVILEGES_HASH:
case FUNC_PRIVILEGES_HASH:
case PACKAGE_SPEC_PRIVILEGES_HASH:
case PACKAGE_BODY_PRIVILEGES_HASH:
{
/*
Save old hash key and its length to be able to properly update
element position in hash.
*/
char *old_key= grant_name->hash_key;
size_t old_key_length= grant_name->key_length;
/*
Update the grant structure with the new user name and host name.
*/
grant_name->set_user_details(user_to->host.str, grant_name->db,
user_to->user.str, grant_name->tname,
TRUE);
/*
Update the grant structure with the new user name and host name.
*/
grant_name->set_user_details(user_to->host.str, grant_name->db,
user_to->user.str, grant_name->tname,
TRUE);
/*
Since username is part of the hash key, when the user name
is renamed, the hash key is changed. Update the hash to
ensure that the position matches the new hash key value
*/
my_hash_update(grant_name_hash, (uchar*) grant_name, (uchar*) old_key,
old_key_length);
/*
hash_update() operation could have moved element from the tail or
the head of the hash to the current position. But it can never
move an element from the head to the tail or from the tail to the
head over the current element.
So we need to examine the current element once again, but
we don't need to restart the search from the beginning.
*/
idx++;
/*
Since username is part of the hash key, when the user name
is renamed, the hash key is changed. Update the hash to
ensure that the position matches the new hash key value
*/
my_hash_update(grant_name_hash, (uchar*) grant_name, (uchar*) old_key,
old_key_length);
restart= true;
break;
}
case PROXY_USERS_ACL:
acl_proxy_user->set_user (&acl_memroot, user_to->user.str);
acl_proxy_user->set_host (&acl_memroot, user_to->host.str);
break;
case ROLES_MAPPINGS_HASH:
{
/*
Save old hash key and its length to be able to properly update
element position in hash.
*/
char *old_key= role_grant_pair->hashkey.str;
size_t old_key_length= role_grant_pair->hashkey.length;
bool oom;
if (user_to->is_role())
oom= role_grant_pair->init(&acl_memroot, role_grant_pair->u_uname,
role_grant_pair->u_hname,
user_to->user.str, false);
else
oom= role_grant_pair->init(&acl_memroot, user_to->user.str,
user_to->host.str,
role_grant_pair->r_uname, false);
if (oom)
DBUG_RETURN(-1);
my_hash_update(roles_mappings_hash, (uchar*) role_grant_pair,
(uchar*) old_key, old_key_length);
restart= true;
break;
}
default:
DBUG_ASSERT(0);
break;
}
case PROXY_USERS_ACL:
acl_proxy_user->set_user (&acl_memroot, user_to->user.str);
acl_proxy_user->set_host (&acl_memroot, user_to->host.str);
break;
case ROLES_MAPPINGS_HASH:
{
/*
Save old hash key and its length to be able to properly update
element position in hash.
*/
char *old_key= role_grant_pair->hashkey.str;
size_t old_key_length= role_grant_pair->hashkey.length;
bool oom;
if (user_to->is_role())
oom= role_grant_pair->init(&acl_memroot, role_grant_pair->u_uname,
role_grant_pair->u_hname,
user_to->user.str, false);
else
oom= role_grant_pair->init(&acl_memroot, user_to->user.str,
user_to->host.str,
role_grant_pair->r_uname, false);
if (oom)
DBUG_RETURN(-1);
my_hash_update(roles_mappings_hash, (uchar*) role_grant_pair,
(uchar*) old_key, old_key_length);
idx++; // see the comment above
break;
}
default:
DBUG_ASSERT(0);
}
else
{
/* If search is requested, we do not need to search further. */
break;
}
}
else
{
/* If search is requested, we do not need to search further. */
break;
}
}
} while (restart);
#ifdef EXTRA_DEBUG
DBUG_PRINT("loop",("scan struct: %u result %d", struct_no, result));
#endif

View File

@@ -796,6 +796,9 @@ retry:
if (!(handler= mysql_ha_find_handler(thd, &tables->alias)))
goto err0;
if (thd->transaction->xid_state.check_has_uncommitted_xa())
goto err0;
table= handler->table;
tables->table= table; // This is used by fix_fields
table->pos_in_table_list= tables;

View File

@@ -3959,6 +3959,16 @@ err:
mi->unlock_slave_threads();
if (ret == FALSE)
my_ok(thd);
else
{
/*
Depending on where CHANGE MASTER failed, the logs may be waiting to be
reopened. This would break future log updates and CHANGE MASTER calls.
`try_fix_log_state()` allows the relay log to fix its state to no longer
expect to be reopened.
*/
mi->rli.relay_log.try_fix_log_state();
}
DBUG_RETURN(ret);
}

View File

@@ -28244,6 +28244,11 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
//Item List
bool first= 1;
/*
outer_select() can not be used here because it is for name resolution
and will return NULL at any end of name resolution chain (view/derived)
*/
bool top_level= (get_master()->get_master() == 0);
List_iterator_fast<Item> it(item_list);
Item *item;
while ((item= it++))
@@ -28253,7 +28258,8 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
else
str->append(',');
if (is_subquery_function() && !item->is_explicit_name())
if ((is_subquery_function() && !item->is_explicit_name()) ||
!item->name.str)
{
/*
Do not print auto-generated aliases in subqueries. It has no purpose
@@ -28262,7 +28268,20 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
item->print(str, query_type);
}
else
item->print_item_w_name(str, query_type);
{
/*
Do not print illegal names (if it is not top level SELECT).
Top level view checked (and correct name are assigned),
other cases of top level SELECT are not important, because
it is not "table field".
*/
if (top_level ||
item->is_explicit_name() ||
!check_column_name(item->name.str))
item->print_item_w_name(str, query_type);
else
item->print(str, query_type);
}
}
/*

View File

@@ -4479,7 +4479,9 @@ make_table_name_list(THD *thd, Dynamic_array<LEX_CSTRING*> *table_names,
if (!lookup_field_vals->wild_table_value &&
lookup_field_vals->table_value.str)
{
if (lookup_field_vals->table_value.length > NAME_LEN)
if (check_table_name(lookup_field_vals->table_value.str,
lookup_field_vals->table_value.length,
false))
{
/*
Impossible value for a table name,
@@ -4516,6 +4518,9 @@ make_table_name_list(THD *thd, Dynamic_array<LEX_CSTRING*> *table_names,
return (schema_tables_add(thd, table_names,
lookup_field_vals->table_value.str));
if (check_db_name((LEX_STRING*)db_name))
return 0; // Impossible TABLE_SCHEMA name
find_files_result res= find_files(thd, table_names, db_name, path,
&lookup_field_vals->table_value);
if (res != FIND_FILES_OK)

View File

@@ -3246,8 +3246,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
/* Align key length to multibyte char boundary */
key_part_length-= key_part_length % sql_field->charset->mbmaxlen;
}
else
is_hash_field_needed= true;
}
}
// Catch invalid use of partial keys
@@ -3293,11 +3291,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
else
{
if (key->type == Key::UNIQUE)
{
is_hash_field_needed= true;
}
else
if (key->type != Key::UNIQUE)
{
key_part_length= MY_MIN(max_key_length, file->max_key_part_length());
my_error(ER_TOO_LONG_KEY, MYF(0), key_part_length);
@@ -3306,6 +3300,11 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
}
if (key->type == Key::UNIQUE
&& key_part_length > MY_MIN(max_key_length,
file->max_key_part_length()))
is_hash_field_needed= true;
/* We can not store key_part_length more then 2^16 - 1 in frm */
if (is_hash_field_needed && column->length > UINT_MAX16)
{
@@ -3340,7 +3339,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
unique_key=1;
key_info->key_length=(uint16) key_length;
if (key_info->key_length > max_key_length && key->type == Key::UNIQUE)
is_hash_field_needed= true;
is_hash_field_needed= true; // for case "a BLOB UNIQUE"
if (key_length > max_key_length && key->type != Key::FULLTEXT &&
!is_hash_field_needed)
{

View File

@@ -5040,6 +5040,21 @@ bool check_table_name(const char *name, size_t length, bool check_for_path_chars
if (check_for_path_chars &&
(*name == '/' || *name == '\\' || *name == '~' || *name == FN_EXTCHAR))
return 1;
/*
We don't allow zero byte in table/schema names:
- Some code still uses NULL-terminated strings.
Zero bytes will confuse this code.
- There is a little practical use of zero bytes in names anyway.
Note, if the string passed as "name" comes here
from the parser as an identifier, it does not contain zero bytes,
as the parser rejects zero bytes in identifiers.
But "name" can also come here from queries like this:
SELECT * FROM I_S.TABLES WHERE TABLE_NAME='str';
In this case "name" is a general string expression
and it can have any arbitrary bytes, including zero bytes.
*/
if (*name == 0x00)
return 1;
name++;
name_length++;
}

View File

@@ -268,14 +268,14 @@ bool TYPBLK<TYPE>::Init(PGLOBAL g, bool check)
template <class TYPE>
char *TYPBLK<TYPE>::GetCharString(char *p, int n)
{
sprintf(p, Fmt, Typp[n]);
sprintf(p, Fmt, UnalignedRead(n));
return p;
} // end of GetCharString
template <>
char *TYPBLK<double>::GetCharString(char *p, int n)
{
sprintf(p, Fmt, Prec, Typp[n]);
sprintf(p, Fmt, Prec, UnalignedRead(n));
return p;
} // end of GetCharString
@@ -291,7 +291,7 @@ void TYPBLK<TYPE>::SetValue(PVAL valp, int n)
ChkTyp(valp);
if (!(b = valp->IsNull()))
Typp[n] = GetTypedValue(valp);
UnalignedWrite(n, GetTypedValue(valp));
else
Reset(n);
@@ -353,9 +353,9 @@ void TYPBLK<TYPE>::SetValue(PCSZ p, int n)
ulonglong val = CharToNumber(p, strlen(p), maxval, Unsigned, &minus);
if (minus && val < maxval)
Typp[n] = (TYPE)(-(signed)val);
UnalignedWrite(n, (TYPE)(-(signed)val));
else
Typp[n] = (TYPE)val;
UnalignedWrite(n, (TYPE)val);
SetNull(n, false);
} // end of SetValue
@@ -398,7 +398,7 @@ void TYPBLK<double>::SetValue(PCSZ p, int n)
throw Type;
} // endif Check
Typp[n] = atof(p);
UnalignedWrite(n, atof(p));
SetNull(n, false);
} // end of SetValue
@@ -430,7 +430,7 @@ void TYPBLK<TYPE>::SetValue(PVBLK pv, int n1, int n2)
ChkTyp(pv);
if (!(b = pv->IsNull(n2) && Nullable))
Typp[n1] = GetTypedValue(pv, n2);
UnalignedWrite(n1, GetTypedValue(pv, n2));
else
Reset(n1);
@@ -481,10 +481,10 @@ void TYPBLK<TYPE>::SetMin(PVAL valp, int n)
{
CheckParms(valp, n)
TYPE tval = GetTypedValue(valp);
TYPE& tmin = Typp[n];
TYPE tmin = UnalignedRead(n);
if (tval < tmin)
tmin = tval;
UnalignedWrite(n, tval);
} // end of SetMin
@@ -496,10 +496,10 @@ void TYPBLK<TYPE>::SetMax(PVAL valp, int n)
{
CheckParms(valp, n)
TYPE tval = GetTypedValue(valp);
TYPE& tmin = Typp[n];
TYPE tmin = UnalignedRead(n);
if (tval > tmin)
tmin = tval;
UnalignedWrite(n, tval);
} // end of SetMax
@@ -513,8 +513,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, int k, int n)
CheckType(pv)
TYPE *lp = ((TYPBLK*)pv)->Typp;
for (int i = k; i < n; i++) // TODO
Typp[i] = lp[i];
memcpy(Typp + k, lp + k, sizeof(TYPE) * n);
} // end of SetValues
#endif // 0
@@ -525,7 +524,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, int k, int n)
template <class TYPE>
void TYPBLK<TYPE>::Move(int i, int j)
{
Typp[j] = Typp[i];
UnalignedWrite(j, UnalignedRead(i));
MoveNull(i, j);
} // end of Move
@@ -539,7 +538,7 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n)
ChkIndx(n);
ChkTyp(vp);
#endif // _DEBUG
TYPE mlv = Typp[n];
TYPE mlv = UnalignedRead(n);
TYPE vlv = GetTypedValue(vp);
return (vlv > mlv) ? 1 : (vlv < mlv) ? (-1) : 0;
@@ -551,8 +550,8 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n)
template <class TYPE>
int TYPBLK<TYPE>::CompVal(int i1, int i2)
{
TYPE lv1 = Typp[i1];
TYPE lv2 = Typp[i2];
TYPE lv1 = UnalignedRead(i1);
TYPE lv2 = UnalignedRead(i2);
return (lv1 > lv2) ? 1 : (lv1 < lv2) ? (-1) : 0;
} // end of CompVal
@@ -589,7 +588,7 @@ int TYPBLK<TYPE>::Find(PVAL vp)
TYPE n = GetTypedValue(vp);
for (i = 0; i < Nval; i++)
if (n == Typp[i])
if (n == UnalignedRead(i))
break;
return (i < Nval) ? i : (-1);
@@ -605,7 +604,7 @@ int TYPBLK<TYPE>::GetMaxLength(void)
int i, n, m;
for (i = n = 0; i < Nval; i++) {
m = sprintf(buf, Fmt, Typp[i]);
m = sprintf(buf, Fmt, UnalignedRead(i));
n = MY_MAX(n, m);
} // endfor i
@@ -1335,7 +1334,7 @@ char *DATBLK::GetCharString(char *p, int n)
char *vp;
if (Dvalp) {
Dvalp->SetValue(Typp[n]);
Dvalp->SetValue(UnalignedRead(n));
vp = Dvalp->GetCharString(p);
} else
vp = TYPBLK<int>::GetCharString(p, n);
@@ -1351,7 +1350,7 @@ void DATBLK::SetValue(PCSZ p, int n)
if (Dvalp) {
// Decode the string according to format
Dvalp->SetValue_psz(p);
Typp[n] = Dvalp->GetIntValue();
UnalignedWrite(n, Dvalp->GetIntValue());
} else
TYPBLK<int>::SetValue(p, n);

View File

@@ -151,40 +151,41 @@ class TYPBLK : public VALBLK {
// Implementation
virtual bool Init(PGLOBAL g, bool check);
virtual int GetVlen(void) {return sizeof(TYPE);}
virtual char GetTinyValue(int n) {return (char)Typp[n];}
virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];}
virtual short GetShortValue(int n) {return (short)Typp[n];}
virtual ushort GetUShortValue(int n) {return (ushort)Typp[n];}
virtual int GetIntValue(int n) {return (int)Typp[n];}
virtual uint GetUIntValue(int n) {return (uint)Typp[n];}
virtual longlong GetBigintValue(int n) {return (longlong)Typp[n];}
virtual ulonglong GetUBigintValue(int n) {return (ulonglong)Typp[n];}
virtual double GetFloatValue(int n) {return (double)Typp[n];}
virtual char GetTinyValue(int n) {return (char)UnalignedRead(n);}
virtual uchar GetUTinyValue(int n) {return (uchar)UnalignedRead(n);}
virtual short GetShortValue(int n) {return (short)UnalignedRead(n);}
virtual ushort GetUShortValue(int n) {return (ushort)UnalignedRead(n);}
virtual int GetIntValue(int n) {return (int)UnalignedRead(n);}
virtual uint GetUIntValue(int n) {return (uint)UnalignedRead(n);}
virtual longlong GetBigintValue(int n) {return (longlong)UnalignedRead(n);}
virtual ulonglong GetUBigintValue(int n) {return (ulonglong)UnalignedRead(n);}
virtual double GetFloatValue(int n) {return (double)UnalignedRead(n);}
virtual char *GetCharString(char *p, int n);
virtual void Reset(int n) {Typp[n] = 0;}
virtual void Reset(int n) {UnalignedWrite(n, 0);}
// Methods
using VALBLK::SetValue;
virtual void SetValue(PCSZ sp, int n);
virtual void SetValue(const char *sp, uint len, int n);
virtual void SetValue(short sval, int n)
{Typp[n] = (TYPE)sval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)sval); SetNull(n, false);}
virtual void SetValue(ushort sval, int n)
{Typp[n] = (TYPE)sval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)sval); SetNull(n, false);}
virtual void SetValue(int lval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
virtual void SetValue(uint lval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
virtual void SetValue(longlong lval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
virtual void SetValue(ulonglong lval, int n)
{Typp[n] = (TYPE)lval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
virtual void SetValue(double fval, int n)
{Typp[n] = (TYPE)fval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)fval); SetNull(n, false);}
virtual void SetValue(char cval, int n)
{Typp[n] = (TYPE)cval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)cval); SetNull(n, false);}
virtual void SetValue(uchar cval, int n)
{Typp[n] = (TYPE)cval; SetNull(n, false);}
{UnalignedWrite(n, (TYPE)cval); SetNull(n, false);}
virtual void SetValue(PVAL valp, int n);
virtual void SetValue(PVBLK pv, int n1, int n2);
virtual void SetMin(PVAL valp, int n);
@@ -206,6 +207,17 @@ class TYPBLK : public VALBLK {
// Members
TYPE* const &Typp;
const char *Fmt;
// Unaligned access
TYPE UnalignedRead(int n) const {
TYPE result;
memcpy(&result, Typp + n, sizeof(TYPE));
return result;
}
void UnalignedWrite(int n, TYPE value) {
memcpy(Typp + n, &value, sizeof(TYPE));
}
}; // end of class TYPBLK
/***********************************************************************/

View File

@@ -148,7 +148,7 @@ SET(INNOBASE_SOURCES
include/fts0tokenize.h
include/fts0types.h
include/fts0types.ic
include/fts0vlc.ic
include/fts0vlc.h
include/fut0fut.h
include/fut0lst.h
include/gis0geo.h

View File

@@ -1069,6 +1069,7 @@ top_loop:
/** Clear the index tree and reinitialize the root page, in the
rollback of TRX_UNDO_EMPTY. The BTR_SEG_LEAF is freed and reinitialized.
@param thr query thread */
TRANSACTIONAL_TARGET
void dict_index_t::clear(que_thr_t *thr)
{
mtr_t mtr;

View File

@@ -856,9 +856,10 @@ PageBulk::latch()
ut_ad(m_block->page.buf_fix_count());
/* In case the block is S-latched by page_cleaner. */
/* In case the block is U-latched by page_cleaner. */
if (!buf_page_optimistic_get(RW_X_LATCH, m_block, m_modify_clock,
&m_mtr)) {
/* FIXME: avoid another lookup */
m_block = buf_page_get_gen(page_id_t(m_index->table->space_id,
m_page_no),
0, RW_X_LATCH,

View File

@@ -1214,6 +1214,7 @@ If mode is PAGE_CUR_LE , cursor is left at the place where an insert of the
search tuple should be performed in the B-tree. InnoDB does an insert
immediately after the cursor. Thus, the cursor may end up on a user record,
or on a page infimum record. */
TRANSACTIONAL_TARGET
dberr_t
btr_cur_search_to_nth_level_func(
dict_index_t* index, /*!< in: index */
@@ -1630,6 +1631,9 @@ retry_page_get:
ut_ad(cursor->thr);
switch (btr_op) {
default:
ut_error;
break;
case BTR_INSERT_OP:
case BTR_INSERT_IGNORE_UNIQUE_OP:
ut_ad(buf_mode == BUF_GET_IF_IN_POOL);
@@ -1662,6 +1666,8 @@ retry_page_get:
case BTR_DELETE_OP:
ut_ad(buf_mode == BUF_GET_IF_IN_POOL_OR_WATCH);
ut_ad(!dict_index_is_spatial(index));
auto& chain = buf_pool.page_hash.cell_get(
page_id.fold());
if (!row_purge_poss_sec(cursor->purge_node,
index, tuple)) {
@@ -1676,15 +1682,12 @@ retry_page_get:
cursor->flag = BTR_CUR_DELETE_IBUF;
} else {
/* The purge could not be buffered. */
buf_pool.watch_unset(page_id);
buf_pool.watch_unset(page_id, chain);
break;
}
buf_pool.watch_unset(page_id);
buf_pool.watch_unset(page_id, chain);
goto func_exit;
default:
ut_error;
}
/* Insert to the insert/delete buffer did not succeed, we
@@ -1992,16 +1995,15 @@ retry_page_get:
&& mode != PAGE_CUR_RTREE_INSERT
&& mode != PAGE_CUR_RTREE_LOCATE
&& mode >= PAGE_CUR_CONTAIN) {
trx_t* trx = thr_get_trx(cursor->thr);
lock_prdt_t prdt;
lock_sys.rd_lock(SRW_LOCK_CALL);
trx->mutex_lock();
lock_init_prdt_from_mbr(
&prdt, &cursor->rtr_info->mbr, mode,
trx->lock.lock_heap);
lock_sys.rd_unlock();
trx->mutex_unlock();
{
trx_t* trx = thr_get_trx(cursor->thr);
TMLockTrxGuard g{TMLockTrxArgs(*trx)};
lock_init_prdt_from_mbr(
&prdt, &cursor->rtr_info->mbr, mode,
trx->lock.lock_heap);
}
if (rw_latch == RW_NO_LATCH && height != 0) {
block->lock.s_lock();
@@ -6743,11 +6745,10 @@ static void btr_blob_free(buf_block_t *block, bool all, mtr_t *mtr)
ut_ad(mtr->memo_contains_flagged(block, MTR_MEMO_PAGE_X_FIX));
mtr->commit();
const ulint fold= page_id.fold();
buf_pool_t::hash_chain &chain= buf_pool.page_hash.cell_get(page_id.fold());
mysql_mutex_lock(&buf_pool.mutex);
if (buf_page_t *bpage= buf_pool.page_hash_get_low(page_id, fold))
if (buf_page_t *bpage= buf_pool.page_hash.get(page_id, chain))
if (!buf_LRU_free_page(bpage, all) && all && bpage->zip.data)
/* Attempt to deallocate the redundant copy of the uncompressed page
if the whole ROW_FORMAT=COMPRESSED block cannot be deallocted. */

View File

@@ -1007,6 +1007,7 @@ both have sensible values.
or NULL
@param[in] mtr mini transaction
@return whether the search succeeded */
TRANSACTIONAL_TARGET
bool
btr_search_guess_on_hash(
dict_index_t* index,
@@ -1090,26 +1091,34 @@ fail:
buf_block_t* block = buf_pool.block_from_ahi(rec);
if (!ahi_latch) {
page_hash_latch* hash_lock = buf_pool.hash_lock_get(
block->page.id());
hash_lock->read_lock();
buf_pool_t::hash_chain& chain = buf_pool.page_hash.cell_get(
block->page.id().fold());
bool fail;
{
transactional_shared_lock_guard<page_hash_latch> g{
buf_pool.page_hash.lock_get(chain)};
if (block->page.state() == BUF_BLOCK_REMOVE_HASH) {
/* Another thread is just freeing the block
from the LRU list of the buffer pool: do not
try to access this page. */
hash_lock->read_unlock();
goto fail;
switch (block->page.state()) {
case BUF_BLOCK_REMOVE_HASH:
/* Another thread is just freeing the block
from the LRU list of the buffer pool: do not
try to access this page. */
goto fail;
case BUF_BLOCK_FILE_PAGE:
break;
default:
#ifndef NO_ELISION
xend();
#endif
ut_error;
}
block->fix();
fail = index != block->index
&& index_id == block->index->id;
}
const bool fail = index != block->index
&& index_id == block->index->id;
ut_a(!fail || block->index->freed());
ut_ad(block->page.state() == BUF_BLOCK_FILE_PAGE);
DBUG_ASSERT(fail || block->page.status != buf_page_t::FREED);
buf_block_buf_fix_inc(block);
hash_lock->read_unlock();
block->page.set_accessed();
buf_page_make_young_if_needed(&block->page);
@@ -1136,6 +1145,8 @@ got_no_latch:
if (UNIV_UNLIKELY(fail)) {
goto fail_and_release_page;
}
DBUG_ASSERT(block->page.status != buf_page_t::FREED);
} else if (UNIV_UNLIKELY(index != block->index
&& index_id == block->index->id)) {
ut_a(block->index->freed());
@@ -2209,8 +2220,9 @@ btr_search_hash_table_validate(ulint hash_table_id)
assertion and the comment below) */
const page_id_t id(block->page.id());
if (const buf_page_t* hash_page
= buf_pool.page_hash_get_low(
id, id.fold())) {
= buf_pool.page_hash.get(
id, buf_pool.page_hash.cell_get(
id.fold()))) {
ut_ad(hash_page == &block->page);
goto state_ok;
}

View File

@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2020, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2020, MariaDB Corporation.
Copyright (c) 2020, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License, version 2.0, as published by the
@@ -28,6 +28,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include "buf0block_hint.h"
namespace buf {
TRANSACTIONAL_TARGET
void Block_hint::buffer_fix_block_if_still_valid()
{
/* To check if m_block belongs to the current buf_pool, we must
@@ -46,14 +47,14 @@ void Block_hint::buffer_fix_block_if_still_valid()
validate m_block->state() to ensure that the block is not being freed. */
if (m_block)
{
const ulint fold= m_page_id.fold();
page_hash_latch *hash_lock= buf_pool.page_hash.lock<false>(fold);
auto &cell= buf_pool.page_hash.cell_get(m_page_id.fold());
transactional_shared_lock_guard<page_hash_latch> g
{buf_pool.page_hash.lock_get(cell)};
if (buf_pool.is_uncompressed(m_block) && m_page_id == m_block->page.id() &&
m_block->page.state() == BUF_BLOCK_FILE_PAGE)
buf_block_buf_fix_inc(m_block);
m_block->fix();
else
clear();
hash_lock->read_unlock();
}
}
} // namespace buf

View File

@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, 2020, MariaDB Corporation.
Copyright (c) 2018, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -499,9 +499,10 @@ static bool buf_buddy_relocate(void* src, void* dst, ulint i, bool force)
ut_ad(space != BUF_BUDDY_STAMP_FREE);
const page_id_t page_id(space, offset);
const ulint fold= page_id.fold();
/* FIXME: we are computing this while holding buf_pool.mutex */
auto &cell= buf_pool.page_hash.cell_get(page_id.fold());
bpage = buf_pool.page_hash_get_low(page_id, fold);
bpage = buf_pool.page_hash.get(page_id, cell);
if (!bpage || bpage->zip.data != src) {
/* The block has probably been freshly
@@ -546,8 +547,11 @@ static bool buf_buddy_relocate(void* src, void* dst, ulint i, bool force)
return false;
}
page_hash_latch *hash_lock = buf_pool.page_hash.lock_get(fold);
hash_lock->write_lock();
page_hash_latch &hash_lock = buf_pool.page_hash.lock_get(cell);
/* It does not make sense to use transactional_lock_guard here,
because the memcpy() of 1024 to 16384 bytes would likely make the
memory transaction too large. */
hash_lock.lock();
if (bpage->can_relocate()) {
/* Relocate the compressed page. */
@@ -558,7 +562,7 @@ static bool buf_buddy_relocate(void* src, void* dst, ulint i, bool force)
memcpy(dst, src, size);
bpage->zip.data = reinterpret_cast<page_zip_t*>(dst);
hash_lock->write_unlock();
hash_lock.unlock();
buf_buddy_mem_invalid(
reinterpret_cast<buf_buddy_free_t*>(src), i);
@@ -569,7 +573,7 @@ static bool buf_buddy_relocate(void* src, void* dst, ulint i, bool force)
return(true);
}
hash_lock->write_unlock();
hash_lock.unlock();
return(false);
}

File diff suppressed because it is too large Load Diff

View File

@@ -947,7 +947,9 @@ static bool buf_flush_check_neighbor(const page_id_t id, ulint fold, bool lru)
mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(fold == id.fold());
buf_page_t *bpage= buf_pool.page_hash_get_low(id, fold);
/* FIXME: cell_get() is being invoked while holding buf_pool.mutex */
const buf_page_t *bpage=
buf_pool.page_hash.get(id, buf_pool.page_hash.cell_get(fold));
if (!bpage || buf_pool.watch_is_sentinel(*bpage))
return false;
@@ -1107,9 +1109,10 @@ static ulint buf_flush_try_neighbors(fil_space_t *space,
id_fold= id.fold();
}
const buf_pool_t::hash_chain &chain= buf_pool.page_hash.cell_get(id_fold);
mysql_mutex_lock(&buf_pool.mutex);
if (buf_page_t *bpage= buf_pool.page_hash_get_low(id, id_fold))
if (buf_page_t *bpage= buf_pool.page_hash.get(id, chain))
{
ut_ad(bpage->in_file());
/* We avoid flushing 'non-old' blocks in an LRU flush,

View File

@@ -113,7 +113,7 @@ the object will be freed.
@param bpage buffer block
@param id page identifier
@param hash_lock buf_pool.page_hash latch (will be released here)
@param chain locked buf_pool.page_hash chain (will be released here)
@param zip whether bpage->zip of BUF_BLOCK_FILE_PAGE should be freed
If a compressed page is freed other compressed pages may be relocated.
@@ -122,7 +122,8 @@ caller needs to free the page to the free list
@retval false if BUF_BLOCK_ZIP_PAGE was removed from page_hash. In
this case the block is already returned to the buddy allocator. */
static bool buf_LRU_block_remove_hashed(buf_page_t *bpage, const page_id_t id,
page_hash_latch *hash_lock, bool zip);
buf_pool_t::hash_chain &chain,
bool zip);
/** Free a block to buf_pool */
static void buf_LRU_block_free_hashed_page(buf_block_t *block)
@@ -807,9 +808,11 @@ bool buf_LRU_free_page(buf_page_t *bpage, bool zip)
/* We must hold an exclusive hash_lock to prevent
bpage->can_relocate() from changing due to a concurrent
execution of buf_page_get_low(). */
const ulint fold = id.fold();
page_hash_latch* hash_lock = buf_pool.page_hash.lock_get(fold);
hash_lock->write_lock();
buf_pool_t::hash_chain& chain= buf_pool.page_hash.cell_get(id.fold());
page_hash_latch& hash_lock = buf_pool.page_hash.lock_get(chain);
/* We cannot use transactional_lock_guard here,
because buf_buddy_relocate() in buf_buddy_free() could get stuck. */
hash_lock.lock();
lsn_t oldest_modification = bpage->oldest_modification_acquire();
if (UNIV_UNLIKELY(!bpage->can_relocate())) {
@@ -839,7 +842,7 @@ bool buf_LRU_free_page(buf_page_t *bpage, bool zip)
} else if (oldest_modification
&& bpage->state() != BUF_BLOCK_FILE_PAGE) {
func_exit:
hash_lock->write_unlock();
hash_lock.unlock();
return(false);
} else if (bpage->state() == BUF_BLOCK_FILE_PAGE) {
@@ -859,7 +862,7 @@ func_exit:
ut_ad(bpage->can_relocate());
if (!buf_LRU_block_remove_hashed(bpage, id, hash_lock, zip)) {
if (!buf_LRU_block_remove_hashed(bpage, id, chain, zip)) {
ut_ad(!b);
mysql_mutex_assert_not_owner(&buf_pool.flush_list_mutex);
return(true);
@@ -875,7 +878,7 @@ func_exit:
if (UNIV_LIKELY_NULL(b)) {
buf_page_t* prev_b = UT_LIST_GET_PREV(LRU, b);
ut_ad(!buf_pool.page_hash_get_low(id, fold));
ut_ad(!buf_pool.page_hash.get(id, chain));
ut_ad(b->zip_size());
/* The field in_LRU_list of
@@ -894,8 +897,10 @@ func_exit:
ut_ad(!b->in_zip_hash);
ut_ad(b->in_LRU_list);
ut_ad(b->in_page_hash);
ut_d(b->in_page_hash = false);
b->hash = nullptr;
HASH_INSERT(buf_page_t, hash, &buf_pool.page_hash, fold, b);
buf_pool.page_hash.append(chain, b);
/* Insert b where bpage was in the LRU list. */
if (prev_b) {
@@ -951,9 +956,10 @@ func_exit:
decompressing the block while we release
hash_lock. */
b->set_io_fix(BUF_IO_PIN);
hash_lock->write_unlock();
goto release;
} else if (!zip) {
hash_lock->write_unlock();
release:
hash_lock.unlock();
}
buf_block_t* block = reinterpret_cast<buf_block_t*>(bpage);
@@ -1063,7 +1069,7 @@ the object will be freed.
@param bpage buffer block
@param id page identifier
@param hash_lock buf_pool.page_hash latch (will be released here)
@param chain locked buf_pool.page_hash chain (will be released here)
@param zip whether bpage->zip of BUF_BLOCK_FILE_PAGE should be freed
If a compressed page is freed other compressed pages may be relocated.
@@ -1072,10 +1078,11 @@ caller needs to free the page to the free list
@retval false if BUF_BLOCK_ZIP_PAGE was removed from page_hash. In
this case the block is already returned to the buddy allocator. */
static bool buf_LRU_block_remove_hashed(buf_page_t *bpage, const page_id_t id,
page_hash_latch *hash_lock, bool zip)
buf_pool_t::hash_chain &chain,
bool zip)
{
mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(hash_lock->is_write_locked());
ut_ad(buf_pool.page_hash.lock_get(chain).is_write_locked());
ut_a(bpage->io_fix() == BUF_IO_NONE);
ut_a(!bpage->buf_fix_count());
@@ -1155,7 +1162,8 @@ static bool buf_LRU_block_remove_hashed(buf_page_t *bpage, const page_id_t id,
}
ut_ad(!bpage->in_zip_hash);
HASH_DELETE(buf_page_t, hash, &buf_pool.page_hash, id.fold(), bpage);
buf_pool.page_hash.remove(chain, bpage);
page_hash_latch& hash_lock = buf_pool.page_hash.lock_get(chain);
switch (bpage->state()) {
case BUF_BLOCK_ZIP_PAGE:
@@ -1165,7 +1173,7 @@ static bool buf_LRU_block_remove_hashed(buf_page_t *bpage, const page_id_t id,
ut_a(bpage->zip.ssize);
ut_ad(!bpage->oldest_modification());
hash_lock->write_unlock();
hash_lock.unlock();
buf_pool_mutex_exit_forbid();
buf_buddy_free(bpage->zip.data, bpage->zip_size());
@@ -1209,7 +1217,7 @@ static bool buf_LRU_block_remove_hashed(buf_page_t *bpage, const page_id_t id,
and by the time we'll release it in the caller we'd
have inserted the compressed only descriptor in the
page_hash. */
hash_lock->write_unlock();
hash_lock.unlock();
if (bpage->zip.data) {
/* Free the compressed page. */
@@ -1240,20 +1248,38 @@ static bool buf_LRU_block_remove_hashed(buf_page_t *bpage, const page_id_t id,
return(false);
}
/** Remove one page from LRU list and put it to free list.
@param bpage file page to be freed
@param id page identifier
@param hash_lock buf_pool.page_hash latch (will be released here) */
void buf_LRU_free_one_page(buf_page_t *bpage, const page_id_t id,
page_hash_latch *hash_lock)
/** Release and evict a corrupted page.
@param bpage page that was being read */
ATTRIBUTE_COLD void buf_pool_t::corrupted_evict(buf_page_t *bpage)
{
const page_id_t id(bpage->id());
buf_pool_t::hash_chain &chain= buf_pool.page_hash.cell_get(id.fold());
page_hash_latch &hash_lock= buf_pool.page_hash.lock_get(chain);
mysql_mutex_lock(&mutex);
hash_lock.lock();
ut_ad(bpage->io_fix() == BUF_IO_READ);
ut_ad(!bpage->oldest_modification());
bpage->set_corrupt_id();
bpage->io_unfix();
if (bpage->state() == BUF_BLOCK_FILE_PAGE)
reinterpret_cast<buf_block_t*>(bpage)->lock.x_unlock(true);
while (bpage->buf_fix_count())
/* Wait for other threads to release the fix count
before releasing the bpage from LRU list. */
(void) LF_BACKOFF();
if (buf_LRU_block_remove_hashed(bpage, id, hash_lock, true))
/* remove from LRU and page_hash */
if (buf_LRU_block_remove_hashed(bpage, id, chain, true))
buf_LRU_block_free_hashed_page(reinterpret_cast<buf_block_t*>(bpage));
mysql_mutex_unlock(&mutex);
ut_d(auto n=) n_pend_reads--;
ut_ad(n > 0);
}
/** Update buf_pool.LRU_old_ratio.

Some files were not shown because too many files have changed in this diff Show More