diff options
25 files changed, 286 insertions, 56 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cd22fc5dd8c..6db89cd332f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -172,12 +172,12 @@ fedora-clang: centos8: stage: build - image: centos:8 + image: quay.io/centos/centos:stream8 # CentOS 8 is deprecated, use this Stream8 instead variables: GIT_STRATEGY: fetch GIT_SUBMODULE_STRATEGY: normal script: - - yum install -y yum-utils rpm-build openssl-devel + - yum install -y yum-utils rpm-build openssl-devel pcre2-devel - yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm # dnf --enablerepo=powertools install Judy-devel #--> not found - dnf config-manager --set-enabled powertools @@ -186,7 +186,7 @@ centos8: # - package Judy-devel-1.0.5-18.module_el8.3.0+757+d382997d.i686 is filtered out by modular filtering # - package Judy-devel-1.0.5-18.module_el8.3.0+757+d382997d.x86_64 is filtered out by modular filtering # Solution: install Judy-devel directly from downloaded rpm file: - - yum install -y http://mirror.centos.org/centos/8/PowerTools/x86_64/os/Packages/Judy-devel-1.0.5-18.module_el8.3.0+757+d382997d.x86_64.rpm + - yum install -y http://vault.centos.org/centos/8/PowerTools/x86_64/os/Packages/Judy-devel-1.0.5-18.module_el8.3.0+757+d382997d.x86_64.rpm # Use eatmydata to speed up build - yum install -y https://github.com/stewartsmith/libeatmydata/releases/download/v129/libeatmydata-129-1.fc33.x86_64.rpm - yum install -y ccache # From EPEL @@ -226,7 +226,7 @@ centos7: # This repository does not have any .spec files, so install dependencies based on Fedora spec file - yum-builddep -y mariadb-server # ..with a few extra ones, as CentOS 7 is very old and these are added in newer MariaDB releases - - yum install -y yum-utils rpm-build gcc gcc-c++ bison libxml2-devel libevent-devel openssl-devel + - yum install -y yum-utils rpm-build gcc gcc-c++ bison libxml2-devel libevent-devel openssl-devel pcre2-devel - mkdir builddir; cd builddir - cmake -DRPM=$CI_JOB_NAME $CMAKE_FLAGS .. 2>&1 | tee -a ../build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log - make package -j 2 2>&1 | tee -a ../build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log diff --git a/CMakeLists.txt b/CMakeLists.txt index d07c25349af..091fb329686 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (c) 2006, 2017, Oracle and/or its affiliates. -# Copyright (c) 2008, 2021, MariaDB Corporation. +# Copyright (c) 2008, 2022, 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 @@ -80,9 +80,11 @@ SET(MYSQL_PROJECT_NAME_DOCSTRING "MySQL project name") IF(CMAKE_VERSION VERSION_LESS "3.1") IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") ENDIF() ELSE() + SET(CMAKE_C_STANDARD 99) SET(CMAKE_CXX_STANDARD 11) ENDIF() diff --git a/debian/autobake-deb.sh b/debian/autobake-deb.sh index 7403591b6a0..7b1efbeab6f 100755 --- a/debian/autobake-deb.sh +++ b/debian/autobake-deb.sh @@ -13,6 +13,14 @@ set -e source ./VERSION +CODENAME="$(lsb_release -sc)" +case "${CODENAME}" in + stretch) + # MDEV-28022 libzstd-dev-1.1.3 minimum version + sed -i -e '/libzstd-dev/d' debian/control + ;; +esac + # This file is invoked from Buildbot and Travis-CI to build deb packages. # As both of those CI systems have many parallel jobs that include different # parts of the test suite, we don't need to run the mysql-test-run at all when @@ -106,7 +114,6 @@ echo "Incrementing changelog and starting build scripts" UPSTREAM="${MYSQL_VERSION_MAJOR}.${MYSQL_VERSION_MINOR}.${MYSQL_VERSION_PATCH}${MYSQL_VERSION_EXTRA}" PATCHLEVEL="+maria" LOGSTRING="MariaDB build" -CODENAME="$(lsb_release -sc)" EPOCH="1:" VERSION="${EPOCH}${UPSTREAM}${PATCHLEVEL}~${CODENAME}" diff --git a/mysql-test/main/create_or_replace.result b/mysql-test/main/create_or_replace.result index e1670aff9ce..294b0623fc1 100644 --- a/mysql-test/main/create_or_replace.result +++ b/mysql-test/main/create_or_replace.result @@ -353,7 +353,8 @@ drop table test.t1; # create table t1 (i int); lock table t1 write; -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_schema!='mysql' or table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_BACKUP_DDL NULL Backup lock # MDL_BACKUP_DML NULL Backup lock @@ -364,7 +365,8 @@ ERROR 22001: Data too long for column 'a' at row 1 show tables; Tables_in_test t2 -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_schema!='mysql' or table_name not like 'innodb_%_stats'; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME create table t1 (i int); drop table t1; diff --git a/mysql-test/main/create_or_replace.test b/mysql-test/main/create_or_replace.test index 4b954263a87..7fa08d13847 100644 --- a/mysql-test/main/create_or_replace.test +++ b/mysql-test/main/create_or_replace.test @@ -285,13 +285,15 @@ create table t1 (i int); lock table t1 write; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_schema!='mysql' or table_name not like 'innodb_%_stats'; --error ER_DATA_TOO_LONG create or replace table t1 (a char(1)) engine=Innodb select 'foo' as a; show tables; --replace_column 1 # --sorted_result -select * from information_schema.metadata_lock_info; +select * from information_schema.metadata_lock_info +where table_schema!='mysql' or table_name not like 'innodb_%_stats'; create table t1 (i int); drop table t1; diff --git a/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result b/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result index 135271d325e..971fae6208f 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result +++ b/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result @@ -104,6 +104,17 @@ Note 1592 Unsafe statement written to the binary log using statement format sinc SHOW WARNINGS; Level Code Message Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column. Inserted values cannot be logged correctly +CREATE TABLE t3 (a INT(11) DEFAULT NULL); +INSERT INTO t3 VALUES (1); +CREATE TABLE t4 (a INT(11) DEFAULT NULL, b BIGINT(20) DEFAULT uuid_short()) SELECT * FROM t3; +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave +SHOW WARNINGS; +Level Code Message +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave +CREATE OR REPLACE TABLE t4 (a INT(11) DEFAULT NULL) SELECT * FROM t3; +SHOW WARNINGS; +Level Code Message DROP FUNCTION sf_bug50192; DROP TRIGGER tr_bug50192; -DROP TABLE t1, t2; +DROP TABLE t1, t2, t3, t4; diff --git a/mysql-test/suite/binlog/r/innodb_autoinc_lock_mode_binlog.result b/mysql-test/suite/binlog/r/innodb_autoinc_lock_mode_binlog.result new file mode 100644 index 00000000000..d0132931968 --- /dev/null +++ b/mysql-test/suite/binlog/r/innodb_autoinc_lock_mode_binlog.result @@ -0,0 +1,33 @@ +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +select @@innodb_autoinc_lock_mode; +@@innodb_autoinc_lock_mode +2 +select @@binlog_format; +@@binlog_format +MIXED +create table t1 (a int not null auto_increment,b int, primary key (a)) engine=InnoDB; +insert into t1 values (NULL,1); +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT' COLLATE 'latin1_swedish_ci')) +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create table t1 (a int not null auto_increment,b int, primary key (a)) engine=InnoDB +master-bin.000001 # Gtid # # BEGIN GTID #-#-# +master-bin.000001 # Annotate_rows # # insert into t1 values (NULL,1) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +set global binlog_format=STATEMENT; +connect con1,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK; +insert into t1 values (NULL,1); +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system variable that may have a different value on the slave +insert into t1 values (NULL,1); +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system variable that may have a different value on the slave +disconnect con1; +connection default; +set global binlog_format=MIXED; +DROP TABLE t1; diff --git a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test index 70566da4cfa..578f0ff5fc8 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test +++ b/mysql-test/suite/binlog/t/binlog_stm_unsafe_warning.test @@ -189,8 +189,20 @@ SHOW WARNINGS; SELECT sf_bug50192(); SHOW WARNINGS; +# The test proves MDEV-24617 fixes leave in force +# unsafe warnings in non-deterministic CREATE..SELECT cases. +# Below an inserted default value to `b` of the target table is replication +# unsafe. A warning must be out. +CREATE TABLE t3 (a INT(11) DEFAULT NULL); +INSERT INTO t3 VALUES (1); +CREATE TABLE t4 (a INT(11) DEFAULT NULL, b BIGINT(20) DEFAULT uuid_short()) SELECT * FROM t3; +SHOW WARNINGS; +# no warning out of a deterministic "rhs" of SELECT +CREATE OR REPLACE TABLE t4 (a INT(11) DEFAULT NULL) SELECT * FROM t3; +SHOW WARNINGS; + # cleanup DROP FUNCTION sf_bug50192; DROP TRIGGER tr_bug50192; -DROP TABLE t1, t2; +DROP TABLE t1, t2, t3, t4; diff --git a/mysql-test/suite/binlog/t/innodb_autoinc_lock_mode_binlog.opt b/mysql-test/suite/binlog/t/innodb_autoinc_lock_mode_binlog.opt new file mode 100644 index 00000000000..824f656cbd5 --- /dev/null +++ b/mysql-test/suite/binlog/t/innodb_autoinc_lock_mode_binlog.opt @@ -0,0 +1 @@ +--innodb_autoinc_lock_mode=2 diff --git a/mysql-test/suite/binlog/t/innodb_autoinc_lock_mode_binlog.test b/mysql-test/suite/binlog/t/innodb_autoinc_lock_mode_binlog.test new file mode 100644 index 00000000000..a7d43db4c1b --- /dev/null +++ b/mysql-test/suite/binlog/t/innodb_autoinc_lock_mode_binlog.test @@ -0,0 +1,21 @@ +--source include/have_innodb.inc +--source include/have_binlog_format_mixed.inc + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); + +select @@innodb_autoinc_lock_mode; +select @@binlog_format; + +create table t1 (a int not null auto_increment,b int, primary key (a)) engine=InnoDB; +insert into t1 values (NULL,1); +--source include/show_binlog_events.inc + +set global binlog_format=STATEMENT; +--connect (con1,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK) +insert into t1 values (NULL,1); +insert into t1 values (NULL,1); +--disconnect con1 +--connection default + +set global binlog_format=MIXED; +DROP TABLE t1; diff --git a/mysql-test/suite/sql_sequence/binlog.result b/mysql-test/suite/sql_sequence/binlog.result index f01b3234e96..843cf74c2fa 100644 --- a/mysql-test/suite/sql_sequence/binlog.result +++ b/mysql-test/suite/sql_sequence/binlog.result @@ -12,6 +12,21 @@ select next value for s1, minimum_value from s1 where maximum_value> 4; next value for s1 minimum_value 4 1 alter sequence s1 maxvalue 1000; +optimize table s1; +Table Op Msg_type Msg_text +test.s1 optimize note The storage engine for the table doesn't support optimize +analyze table s1; +Table Op Msg_type Msg_text +test.s1 analyze status Engine-independent statistics collected +test.s1 analyze note The storage engine for the table doesn't support analyze +repair table s1; +Table Op Msg_type Msg_text +test.s1 repair status OK +check table s1; +Table Op Msg_type Msg_text +test.s1 check note The storage engine for the table doesn't support check +rename table s1 to tmp_s; +rename table tmp_s to s1; drop sequence s1; include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info @@ -30,4 +45,14 @@ master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; alter sequence s1 maxvalue 1000 master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; optimize table s1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; analyze table s1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; repair table s1 +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; rename table s1 to tmp_s +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; rename table tmp_s to s1 +master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; DROP SEQUENCE `s1` /* generated by server */ diff --git a/mysql-test/suite/sql_sequence/binlog.test b/mysql-test/suite/sql_sequence/binlog.test index 5f2d52d7864..6a12e670a1e 100644 --- a/mysql-test/suite/sql_sequence/binlog.test +++ b/mysql-test/suite/sql_sequence/binlog.test @@ -1,5 +1,5 @@ ---source include/have_udf.inc ---source include/have_log_bin.inc +--source include/have_sequence.inc +--source include/have_binlog_format_mixed_or_row.inc --source include/binlog_start_pos.inc # @@ -21,6 +21,17 @@ select next value for s1, minimum_value from s1 where maximum_value> 4; # alter sequence s1 maxvalue 1000; +# MDEV-24617 OPTIMIZE on a sequence causes unexpected +# ER_BINLOG_UNSAFE_STATEMENT The test below verifies no unsafe +# warnings anymore for any relavant commands that like OPTIMIZE can +# not produce ROW format events therefore the unsafe warning either. +optimize table s1; +analyze table s1; +repair table s1; +check table s1; +rename table s1 to tmp_s; +rename table tmp_s to s1; + drop sequence s1; --let $binlog_file = LAST diff --git a/sql/handler.h b/sql/handler.h index 8ad521e189a..052554d5747 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -5102,6 +5102,11 @@ public: const uchar *pack_frm_data, size_t pack_frm_len) { return HA_ERR_WRONG_COMMAND; } + /* @return true if it's necessary to switch current statement log format from + STATEMENT to ROW if binary log format is MIXED and autoincrement values + are changed in the statement */ + virtual bool autoinc_lock_mode_stmt_unsafe() const + { return false; } virtual int drop_partitions(const char *path) { return HA_ERR_WRONG_COMMAND; } virtual int rename_partitions(const char *path) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 9a6bd71f92a..b40c00356eb 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -6229,6 +6229,10 @@ int THD::decide_logging_format(TABLE_LIST *tables) bool is_write= FALSE; // If any write tables bool has_read_tables= FALSE; // If any read only tables bool has_auto_increment_write_tables= FALSE; // Write with auto-increment + /* true if it's necessary to switch current statement log format from + STATEMENT to ROW if binary log format is MIXED and autoincrement values + are changed in the statement */ + bool has_unsafe_stmt_autoinc_lock_mode= false; /* If a write table that doesn't have auto increment part first */ bool has_write_table_auto_increment_not_first_in_pk= FALSE; bool has_auto_increment_write_tables_not_first= FALSE; @@ -6351,6 +6355,8 @@ int THD::decide_logging_format(TABLE_LIST *tables) has_auto_increment_write_tables_not_first= found_first_not_own_table; if (share->next_number_keypart != 0) has_write_table_auto_increment_not_first_in_pk= true; + has_unsafe_stmt_autoinc_lock_mode= + table->file->autoinc_lock_mode_stmt_unsafe(); } } @@ -6365,7 +6371,8 @@ int THD::decide_logging_format(TABLE_LIST *tables) blackhole_table_found= 1; if (share->non_determinstic_insert && - !(sql_command_flags[lex->sql_command] & CF_SCHEMA_CHANGE)) + (sql_command_flags[lex->sql_command] & CF_CAN_GENERATE_ROW_EVENTS + && !(sql_command_flags[lex->sql_command] & CF_SCHEMA_CHANGE))) has_write_tables_with_unsafe_statements= true; trans= table->file->has_transactions(); @@ -6422,6 +6429,9 @@ int THD::decide_logging_format(TABLE_LIST *tables) if (has_write_tables_with_unsafe_statements) lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); + if (has_unsafe_stmt_autoinc_lock_mode) + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_LOCK_MODE); + /* A query that modifies autoinc column in sub-statement can make the master and slave inconsistent. diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 97165790e70..c9da83e3903 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2019, Oracle and/or its affiliates. - Copyright (c) 2009, 2021, MariaDB Corporation. + Copyright (c) 2009, 2022, 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 @@ -615,6 +615,13 @@ Query_tables_list::binlog_stmt_unsafe_errcode[BINLOG_STMT_UNSAFE_COUNT] = ER_BINLOG_UNSAFE_UPDATE_IGNORE, ER_BINLOG_UNSAFE_INSERT_TWO_KEYS, ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST, + /* + There is no need to add new error code as we plan to get rid of auto + increment lock mode variable, so we use existing error code below, add + the correspondent text to the existing error message during merging to + non-GA release. + */ + ER_BINLOG_UNSAFE_SYSTEM_VARIABLE, ER_BINLOG_UNSAFE_SKIP_LOCKED }; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 79d48528574..e8bac90fe5a 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2019, Oracle and/or its affiliates. - Copyright (c) 2010, 2021, MariaDB Corporation + Copyright (c) 2010, 2022, 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 @@ -1948,6 +1948,11 @@ public: BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST, /** + Autoincrement lock mode is incompatible with STATEMENT binlog format. + */ + BINLOG_STMT_UNSAFE_AUTOINC_LOCK_MODE, + + /** INSERT .. SELECT ... SKIP LOCKED is unlikely to have the same rows locked on the replica. primary key. diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index 702bb843729..3d4f4d04ae8 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -380,6 +380,19 @@ IF(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" COMPILE_FLAGS "-O0" ) ENDIF() + +# Older gcc version insist on -mhtm flag for including the +# htmxlintrin.h header. This is also true for new gcc versions +# like 11.2.0 in Debian Sid +# s390x because of the way it defines the high level intrinsics +# as not-inline in the header file can only be included by one +# source file that has -mhtm enabled. +IF(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64|powerpc64|s390x") + ADD_COMPILE_FLAGS( + sync/srw_lock.cc + COMPILE_FLAGS "-mhtm" + ) +ENDIF() IF(MSVC) IF(CMAKE_SIZEOF_VOID_P EQUAL 8) ADD_COMPILE_FLAGS( diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 37c61a2807e..a92902e4a46 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -2667,7 +2667,8 @@ ignore_block: after buf_zip_decompress() in this function. */ block->page.lock.s_lock(); state = block->page.state(); - ut_ad(state < buf_page_t::READ_FIX); + ut_ad(state < buf_page_t::READ_FIX + || state >= buf_page_t::WRITE_FIX); const page_id_t id{block->page.id()}; block->page.lock.s_unlock(); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 17a92a242fd..a062f94e75f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -9248,6 +9248,14 @@ ha_innobase::change_active_index( DBUG_RETURN(0); } +/* @return true if it's necessary to switch current statement log format from +STATEMENT to ROW if binary log format is MIXED and autoincrement values +are changed in the statement */ +bool ha_innobase::autoinc_lock_mode_stmt_unsafe() const +{ + return innobase_autoinc_lock_mode == AUTOINC_NO_LOCKING; +} + /***********************************************************************//** Reads the next or previous row from a cursor, which must have previously been positioned using index_read. diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 08501859ec9..ca54785feed 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -462,6 +462,10 @@ protected: int general_fetch(uchar* buf, uint direction, uint match_mode); int change_active_index(uint keynr); + /* @return true if it's necessary to switch current statement log + format from STATEMENT to ROW if binary log format is MIXED and + autoincrement values are changed in the statement */ + bool autoinc_lock_mode_stmt_unsafe() const; dict_index_t* innobase_get_index(uint keynr); #ifdef WITH_WSREP diff --git a/storage/innobase/include/transactional_lock_guard.h b/storage/innobase/include/transactional_lock_guard.h index 3167055630c..168a68977a7 100644 --- a/storage/innobase/include/transactional_lock_guard.h +++ b/storage/innobase/include/transactional_lock_guard.h @@ -18,8 +18,8 @@ this program; if not, write to the Free Software Foundation, Inc., #pragma once -#if defined __powerpc64__ && defined __clang__ && defined __linux__ -#elif defined __powerpc64__&&defined __GNUC__&&defined __linux__&&__GNUC__ > 4 +#if defined __powerpc64__ +#elif defined __s390__ #elif defined _MSC_VER && (defined _M_IX86 || defined _M_X64) && !defined(__clang__) #elif defined __GNUC__ && (defined __i386__ || defined __x86_64__) # if __GNUC__ >= 8 @@ -45,8 +45,8 @@ bool transactional_lock_enabled(); # include <immintrin.h> # if defined __GNUC__ && !defined __INTEL_COMPILER -# define TRANSACTIONAL_TARGET __attribute__((target("rtm"))) -# define TRANSACTIONAL_INLINE __attribute__((target("rtm"),always_inline)) +# define TRANSACTIONAL_TARGET __attribute__((target("rtm"),hot)) +# define TRANSACTIONAL_INLINE __attribute__((target("rtm"),hot,always_inline)) # else # define TRANSACTIONAL_TARGET /* nothing */ # define TRANSACTIONAL_INLINE /* nothing */ @@ -69,26 +69,33 @@ static inline bool xtest() { return have_transactional_memory && _xtest(); } TRANSACTIONAL_INLINE static inline void xabort() { _xabort(0); } TRANSACTIONAL_INLINE static inline void xend() { _xend(); } -# elif defined __powerpc64__ -# include <htmxlintrin.h> +# elif defined __powerpc64__ || defined __s390__ extern bool have_transactional_memory; bool transactional_lock_enabled(); -# define TRANSACTIONAL_TARGET __attribute__((target("htm"))) -# define TRANSACTIONAL_INLINE __attribute__((target("htm"),always_inline)) - -TRANSACTIONAL_INLINE static inline bool xbegin() -{ - return have_transactional_memory && - __TM_simple_begin() == _HTM_TBEGIN_STARTED; -} - +# define TRANSACTIONAL_TARGET __attribute__((hot)) +# define TRANSACTIONAL_INLINE __attribute__((hot,always_inline)) + +/** + Newer gcc compilers only provide __builtin_{htm} + functions when the -mhtm CFLAG is actually provided. So + we've got the option of including it globally, or + pushing down the inclusion of htmxlintrin.h to one + file with -mhtm enabled and removing the inline + optimization. + + Per FIXME in s390x's htmxlintrin.h, the __TM_simple_begin + isn't always_inline resulting in duplicate definitions if + it where included more than once. While xabort and xend + could be implemented here, we keep the implementation the + same as ppc64. + */ +TRANSACTIONAL_TARGET bool xbegin(); +TRANSACTIONAL_TARGET void xabort(); +TRANSACTIONAL_TARGET void xend(); # ifdef UNIV_DEBUG bool xtest(); # endif -TRANSACTIONAL_INLINE static inline void xabort() { __TM_abort(); } - -TRANSACTIONAL_INLINE static inline void xend() { __TM_end(); } # endif #endif diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index dbfca57be54..12607017b27 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Google Inc. -Copyright (c) 2014, 2021, MariaDB Corporation. +Copyright (c) 2014, 2022, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described diff --git a/storage/innobase/sync/srw_lock.cc b/storage/innobase/sync/srw_lock.cc index f406b04712a..339b431522c 100644 --- a/storage/innobase/sync/srw_lock.cc +++ b/storage/innobase/sync/srw_lock.cc @@ -54,32 +54,68 @@ bool transactional_lock_enabled() TRANSACTIONAL_TARGET bool xtest() { return have_transactional_memory && _xtest(); } # endif -#elif defined __powerpc64__ -# ifdef __linux__ -# include <sys/auxv.h> +#elif defined __powerpc64__ || defined __s390__ +# include <htmxlintrin.h> +# include <setjmp.h> +# include <signal.h> -# ifndef PPC_FEATURE2_HTM_NOSC -# define PPC_FEATURE2_HTM_NOSC 0x01000000 -# endif -# ifndef PPC_FEATURE2_HTM_NO_SUSPEND -# define PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000 -# endif +__attribute__((target("htm"),hot)) +bool xbegin() +{ + return have_transactional_memory && + __TM_simple_begin() == _HTM_TBEGIN_STARTED; +} + +__attribute__((target("htm"),hot)) +void xabort() { __TM_abort(); } + +__attribute__((target("htm"),hot)) +void xend() { __TM_end(); } -# ifndef AT_HWCAP2 -# define AT_HWCAP2 26 -# endif -# endif bool have_transactional_memory; +static sigjmp_buf ill_jmp; +static void ill_handler(int sig) +{ + siglongjmp(ill_jmp, sig); +} +/** + Here we are testing we can do a transaction without SIGILL + and a 1 instruction store can succeed. +*/ +__attribute__((noinline)) +static void test_tm(bool *r) +{ + if (__TM_simple_begin() == _HTM_TBEGIN_STARTED) + { + *r= true; + __TM_end(); + } +} bool transactional_lock_enabled() { -# ifdef __linux__ - return getauxval(AT_HWCAP2) & - (PPC_FEATURE2_HTM_NOSC | PPC_FEATURE2_HTM_NO_SUSPEND); -# endif + bool r= false; + sigset_t oset; + struct sigaction ill_act, oact_ill; + + memset(&ill_act, 0, sizeof(ill_act)); + ill_act.sa_handler = ill_handler; + sigfillset(&ill_act.sa_mask); + sigdelset(&ill_act.sa_mask, SIGILL); + + sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); + sigaction(SIGILL, &ill_act, &oact_ill); + if (sigsetjmp(ill_jmp, 1) == 0) + { + test_tm(&r); + } + sigaction(SIGILL, &oact_ill, NULL); + sigprocmask(SIG_SETMASK, &oset, NULL); + return r; } # ifdef UNIV_DEBUG -TRANSACTIONAL_TARGET bool xtest() +__attribute__((target("htm"),hot)) +bool xtest() { return have_transactional_memory && _HTM_STATE (__builtin_ttest ()) == _HTM_TRANSACTIONAL; diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index 6bd21b0f5b9..bfad53e691b 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -1951,7 +1951,7 @@ dberr_t trx_undo_report_rename(trx_t* trx, const dict_table_t* table) return err; } -TRANSACTIONAL_TARGET ATTRIBUTE_COLD ATTRIBUTE_NOINLINE +TRANSACTIONAL_TARGET ATTRIBUTE_NOINLINE /** @return whether the transaction holds an exclusive lock on a table */ static bool trx_has_lock_x(const trx_t &trx, dict_table_t& table) { diff --git a/storage/innobase/unittest/CMakeLists.txt b/storage/innobase/unittest/CMakeLists.txt index 1ab6157b4a9..7dd7c111baa 100644 --- a/storage/innobase/unittest/CMakeLists.txt +++ b/storage/innobase/unittest/CMakeLists.txt @@ -21,6 +21,13 @@ ADD_EXECUTABLE(innodb_fts-t innodb_fts-t.cc) TARGET_LINK_LIBRARIES(innodb_fts-t mysys mytap) ADD_DEPENDENCIES(innodb_fts-t GenError) MY_ADD_TEST(innodb_fts) +# See explanation in innobase/CmakeLists.txt +IF(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64|powerpc64|s390x") + ADD_COMPILE_FLAGS( + ../sync/srw_lock.cc + COMPILE_FLAGS "-mhtm" + ) +ENDIF() ADD_EXECUTABLE(innodb_sync-t innodb_sync-t.cc ../sync/srw_lock.cc) TARGET_LINK_LIBRARIES(innodb_sync-t mysys mytap) ADD_DEPENDENCIES(innodb_sync-t GenError) |