diff options
author | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2021-07-18 19:39:45 +0300 |
---|---|---|
committer | Vicențiu Ciorbaru <cvicentiu@gmail.com> | 2021-07-18 19:58:43 +0300 |
commit | b32b1f2b19ee0974464a0f8a75209d119452e740 (patch) | |
tree | 92c4d0e8995b71c018a4c5ab4816d1ececa2cece | |
parent | 2c4d1fb544039d86c516c8a37ce60ca07a02ca33 (diff) | |
parent | 74f5aa164eee447fe37d9bbdb8465dffc03164af (diff) | |
download | mariadb-git-b32b1f2b19ee0974464a0f8a75209d119452e740.tar.gz |
Merge remote-tracking branch '10.6' into 10.7
Update debian changes to 10.7 to enable debian packaging to work again.
48 files changed, 774 insertions, 76 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000000..0a1bf5bff71 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,270 @@ +--- +# This Gitlab-CI pipeline offers basic validation that a commit did not +# introduce easily detectable regressions. Builds run primairly on a new Fedora, +# which has all the latest upstream build dependencies and thus is the primary +# testing target, as eventually everything in Fedora becomes the next CentOS and +# Red Hat releases. +# +# In addition test building on CentOS 7 and 8 to ensure that the code base +# remains reasonably backwards compatible. +# +# This is now intentionally simple, to keep it fast and accurate with minimal +# false positive failures. If one wants to extend it, see debian/salsa-ci.yml +# for inspiration on more integration tests to run. +# +# Also make sure the pipeline stays within the bounds of what CI workers on +# Gitlab-CI are capable of executing, thus ensuring that any potential +# contributor can at any point in time fork to their own Gitlab account and +# start working towards meaningful contributions! +# +# NOTE TO MERGERS: Most of the contents in the Gitlab-CI configuration has been +# tailored for a specific release or MariaDB. As a general rule, do not merge +# changes in this file across MariaDB branches to avoid breaking the CI. Updates +# the Gitlab-CI pipeline are most of the time better done manually per major +# release branch. + +stages: + - build + - test + - Salsa-CI + +# Base image for builds and tests unless otherwise defined +# @TODO: Fedora 34 is latest, but fails to start on Gitlab.com with error "shell not found" +image: fedora:33 + +# Define common CMAKE_FLAGS for all builds. Skim down build by omitting all +# submodules (a commit in this repo does not affect their builds anyway) and +# many components that are otherwise slow to build. +variables: + CMAKE_FLAGS: "-DWITH_SSL=system -DPLUGIN_COLUMNSTORE=NO -DPLUGIN_ROCKSDB=NO -DPLUGIN_S3=NO -DPLUGIN_MROONGA=NO -DPLUGIN_CONNECT=NO -DPLUGIN_MROONGA=NO -DPLUGIN_TOKUDB=NO -DPLUGIN_PERFSCHEMA=NO -DWITH_WSREP=OFF" + # Major version dictates which branches share the same ccache + MARIADB_MAJOR_VERSION: "10.6" + # Most steps don't need the source code, only artifacts + GIT_STRATEGY: none + # Hack to satisfy directory name length requirement by CPackRPM in CMake 3.x + # https://cmake.org/cmake/help/v3.7/module/CPackRPM.html#variable:CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX + GIT_CLONE_PATH: $CI_BUILDS_DIR/CPACK_BUILD_SOURCE_DIRS_LONG_NAME_REQUIREMENT + +# Define once, use many times +.rpm_listfiles: &rpm_listfiles + - | + echo "Generating rpmlist-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log ..." + for package in *.rpm + do + echo "$package" + rpm -qlpv "$package" | awk '{print $1 " " $3 "/" $4 " ." $9 " " $10 " " $11}' | sort -k 3 + echo "------------------------------------------------" + done >> ../rpmlist-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log + # CPackRPM lists contents in build log, so no need to show the output of this, + # just store it as a build artifact that can be downloaded and diffed against + # other builds to detect which files where added/removed/moved + +fedora: + stage: build + variables: + GIT_STRATEGY: fetch + GIT_SUBMODULE_STRATEGY: normal + script: + - yum install -y yum-utils rpm-build ccache openssl-devel + - source /etc/profile.d/ccache.sh + - export CCACHE_DIR="$(pwd)/.ccache"; ccache -s + # Accelerate builds with unsafe disk access, as we can afford to loose the entire build anyway + - yum install -y https://github.com/stewartsmith/libeatmydata/releases/download/v129/libeatmydata-129-1.fc33.x86_64.rpm + # This repository does not have any .spec files, so install dependencies based on Fedora spec file + - yum-builddep -y mariadb-server + - mkdir builddir; cd builddir + - cmake -DRPM=$CI_JOB_NAME $CMAKE_FLAGS .. 2>&1 | tee -a ../build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log + - eatmydata make package 2>&1 | tee -a ../build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log + # @TODO: Don't use -j on Gitlab.com as builds just get stuck when running + # multi-proc, needs more debugging + - make test || true # Unit tests constantly fail, see https://jira.mariadb.org/browse/MDEV-25820 + # - make test-force || true # mysql-test-runner takes too long, run it in a separate job instead + - *rpm_listfiles + - mkdir ../rpm; mv *.rpm ../rpm + - ccache -s + artifacts: + when: always # Must be able to see logs + paths: + - build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log + - rpmlist-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log + - rpm + - builddir/_CPack_Packages/Linux/RPM/SPECS/ + cache: + key: $MARIADB_MAJOR_VERSION-$CI_JOB_NAME + paths: + - .ccache + # policy: pull + # @TODO: It would be enough to only download the cache. There is no need for + # every job to upload a new cache every time. A monthly or weekly scheduled + # run could update the cache for all other builds to us. + +centos8: + stage: build + image: centos:8 + variables: + GIT_STRATEGY: fetch + GIT_SUBMODULE_STRATEGY: normal + script: + - yum install -y yum-utils rpm-build openssl-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 + # Error: + # Problem: conflicting requests + # - 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 + # 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 + - source /etc/profile.d/ccache.sh + - export CCACHE_DIR="$(pwd)/.ccache"; ccache -s + # This repository does not have any .spec files, so install dependencies based on CentOS spec file + - yum-builddep -y mariadb-server + - mkdir builddir; cd builddir + - cmake -DRPM=$CI_JOB_NAME $CMAKE_FLAGS .. 2>&1 | tee -a ../build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log + - eatmydata make package 2>&1 | tee -a ../build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log + # @TODO: Don't use -j on Gitlab.com as builds just get stuck when running + # multi-proc and out of memory, see https://jira.mariadb.org/browse/MDEV-25968 + - make test || true # Unit tests constantly fail, see https://jira.mariadb.org/browse/MDEV-25820 + # - make test-force || true # mysql-test-runner takes too long, run it in a separate job instead + - *rpm_listfiles + - mkdir ../rpm; mv *.rpm ../rpm + - ccache -s + artifacts: + when: always # Must be able to see logs + paths: + - build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log + - rpmlist-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log + - rpm + - builddir/_CPack_Packages/Linux/RPM/SPECS/ + cache: + key: $MARIADB_MAJOR_VERSION-$CI_JOB_NAME + paths: + - .ccache + +centos7: + stage: build + image: centos:7 + variables: + GIT_STRATEGY: fetch + GIT_SUBMODULE_STRATEGY: normal + script: + # 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 + - 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 2>&1 | tee -a ../build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log + # @TODO: Don't use -j on Gitlab.com as builds just get stuck when running + # multi-proc and out of memory, see https://jira.mariadb.org/browse/MDEV-25968 + - make test || true # Unit tests constantly fail, see https://jira.mariadb.org/browse/MDEV-25820 + # - make test-force || true # mysql-test-runner takes too long, run it in a separate job instead + - *rpm_listfiles + - mkdir ../rpm; mv *.rpm ../rpm + artifacts: + when: always # Must be able to see logs + paths: + - build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log + - rpmlist-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log + - rpm + - builddir/_CPack_Packages/Linux/RPM/SPECS/ + +mysql-test-run: + stage: test + dependencies: + - fedora + script: + # Install packages so tests and the dependencies install + # @TODO: RPM missing 'patch' as dependency, so installing it manually for now + - yum install -y rpm/*.rpm patch + # @TODO: Fix on packaging level for /usr/share/mariadb to work and errormsg.sys be found + - rm -rf /usr/share/mariadb; ln -s /usr/share/mysql /usr/share/mariadb + # mtr expects to be launched in-place and with write access to it's own directories + - cd /usr/share/mysql-test + - | + echo " + main.mysqldump : flaky on Gitlab-CI + main.flush_logs_not_windows : flaky in containers in general + main.mysql_upgrade_noengine : requires diff but diffutils is not a dependency + " > skiplist + # @TODO: Flaky tests are skipped for now, but should be fixed + - ./mtr --suite=main --force --xml-report=$CI_PROJECT_DIR/junit.xml --skip-test-list=skiplist + artifacts: + when: always # Also show results when tests fail + reports: + junit: + - junit.xml + +rpmlint: + stage: test + dependencies: + - fedora + script: + - yum install -y rpmlint + - rm -f rpm/*debuginfo* # Not relevant in this test + # Limit output to 1000 lines as Gitlab-CI max output is 4194304 bytes + # Save everything in a log file so it can be viewed in full via artifacts + - rpmlint --info rpm/*.rpm | tee -a rpmlint-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log + artifacts: + when: always # Also show results when tests fail + paths: + - rpmlint-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log + allow_failure: true + # @TODO: The package is not rpmlint clean, must allow failure for now + +fedora install: + stage: test + dependencies: + - fedora + script: + - rm -f rpm/*debuginfo* # Not relevant in this test + # Nothing provides galera-4 on Fedora, so this step fails if built with wsrep + - yum install -y rpm/*.rpm + # Fedora does not support running services in Docker (like Debian packages do) so start it manually + - /usr/bin/mariadb-install-db -u mysql + - sudo -u mysql /usr/sbin/mariadbd & sleep 10 + # @TODO: Since we did a manual start, we also need to run upgrade manually + - /usr/bin/mariadb-upgrade -u root --socket /var/lib/mysql/mysql.sock + - | + mysql --skip-column-names -e "SELECT @@version, @@version_comment" | tee /tmp/version + grep $MARIADB_MAJOR_VERSION /tmp/version || echo "MariaDB didn't upgrade properly" + +fedora upgrade: + stage: test + dependencies: + - fedora + script: + - yum install -y mariadb-server + # Fedora does not support running services in Docker (like Debian packages do) so start it manually + - /usr/libexec/mysql-check-socket + - /usr/libexec/mysql-prepare-db-dir + - sudo -u mysql /usr/libexec/mysqld --basedir=/usr & sleep 10 + - /usr/libexec/mysql-check-upgrade + - mysql --skip-column-names -e "SELECT @@version, @@version_comment" # Show version + # @TODO: Upgrade from Fedora 33 MariaDB 10.4 to MariaDB.org latest does not work + # so do this manual step to remove conflicts until packaging is fixed + - > + yum remove -y mariadb-server-utils mariadb-gssapi-server mariadb-cracklib-password-check + mariadb-backup mariadb-connector-c-config + - rm -f rpm/*debuginfo* # Not relevant in this test + - yum install -y rpm/*.rpm procps # procps provides pkill + # nothing provides galera-4 on Fedora, so this step fails if built with wsrep + - pkill mysqld || true; sleep 5; pkill mysqld || true; sleep 5 + - /usr/bin/mariadb-install-db -u mysql + - sudo -u mysql /usr/sbin/mariadbd & sleep 10 + # @TODO: Since we did a manual start, we also need to run upgrade manually + - /usr/bin/mariadb-upgrade -u root --socket /var/lib/mysql/mysql.sock + - | + mysql --skip-column-names -e "SELECT @@version, @@version_comment" | tee /tmp/version + grep $MARIADB_MAJOR_VERSION /tmp/version || echo "MariaDB didn't upgrade properly" + +# Once all RPM builds and tests have passed, also run the DEB builds and tests +# @NOTE: This is likely to work well only on salsa.debian.org as the Gitlab.com +# runners are too small for everything this stage does. +# build_deb: +# stage: Salsa-CI +# trigger: +# include: debian/salsa-ci.yml diff --git a/client/mysqltest.cc b/client/mysqltest.cc index c4b6aad6346..5008a048148 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -8416,7 +8416,7 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, append_session_track_info(ds, mysql); - if (!disable_warnings) + if (!disable_warnings && !mysql_more_results(stmt->mysql)) { /* Get the warnings from execute */ diff --git a/mysql-test/include/have_pool_of_threads.inc b/mysql-test/include/have_pool_of_threads.inc index 432c6216804..62460127d88 100644 --- a/mysql-test/include/have_pool_of_threads.inc +++ b/mysql-test/include/have_pool_of_threads.inc @@ -1,4 +1,5 @@ --- require include/have_pool_of_threads.require +--source include/not_aix.inc +--require include/have_pool_of_threads.require disable_query_log; show variables like 'thread_handling'; enable_query_log; diff --git a/mysql-test/include/maybe_pool_of_threads.inc b/mysql-test/include/maybe_pool_of_threads.inc index 51a179b4426..d25e3864333 100644 --- a/mysql-test/include/maybe_pool_of_threads.inc +++ b/mysql-test/include/maybe_pool_of_threads.inc @@ -1 +1,2 @@ # run with and without threadpool +--source include/not_aix.inc diff --git a/mysql-test/include/protocol.combinations b/mysql-test/include/protocol.combinations new file mode 100644 index 00000000000..fa5b08c0e51 --- /dev/null +++ b/mysql-test/include/protocol.combinations @@ -0,0 +1,3 @@ +[nm] + +[ps] diff --git a/mysql-test/include/protocol.inc b/mysql-test/include/protocol.inc new file mode 100644 index 00000000000..02f8c3f3dec --- /dev/null +++ b/mysql-test/include/protocol.inc @@ -0,0 +1,2 @@ +# The goal of including this file is to enable protocol +# combinations (see include/protocol.combinations) diff --git a/mysql-test/main/features,ps.rdiff b/mysql-test/main/features,ps.rdiff new file mode 100644 index 00000000000..9065c132714 --- /dev/null +++ b/mysql-test/main/features,ps.rdiff @@ -0,0 +1,21 @@ +--- features.result ++++ features,ps.result +@@ -46,7 +46,7 @@ + 1212 + show status like "feature_dynamic_columns"; + Variable_name Value +-Feature_dynamic_columns 2 ++Feature_dynamic_columns 4 + # + # Feature fulltext + # +@@ -93,7 +93,7 @@ + drop table t1; + show status like "feature_subquery"; + Variable_name Value +-Feature_subquery 4 ++Feature_subquery 5 + # + # Feature timezone + # + diff --git a/mysql-test/main/features.test b/mysql-test/main/features.test index 0dd0be20c9e..14c86255c37 100644 --- a/mysql-test/main/features.test +++ b/mysql-test/main/features.test @@ -1,10 +1,7 @@ # Testing of feature statistics -if (`SELECT $PS_PROTOCOL != 0`) -{ - --skip Test temporarily disabled for ps-protocol -} -- source include/have_geometry.inc +-- source include/protocol.inc --disable_warnings drop table if exists t1; diff --git a/mysql-test/main/join_outer_innodb.result b/mysql-test/main/join_outer_innodb.result index 0b34a399d77..09a37a29702 100644 --- a/mysql-test/main/join_outer_innodb.result +++ b/mysql-test/main/join_outer_innodb.result @@ -496,3 +496,22 @@ natural right outer join t3; drop table t1,t2,t3; set optimizer_prune_level=@mdev4270_opl; set optimizer_search_depth=@mdev4270_osd; +# +# Bug #20939184:INNODB: UNLOCK ROW COULD NOT FIND A 2 MODE LOCK ON THE +# RECORD +# +CREATE TABLE t1 (c1 INT, c2 INT, c3 INT, PRIMARY KEY (c1,c2) ) engine=innodb; +CREATE TABLE t2 (c1 INT, c2 INT, c3 INT, PRIMARY KEY (c1), KEY (c2)) engine=innodb; +INSERT INTO t1 VALUES (1,2,3),(2,3,4),(3,4,5); +INSERT INTO t2 SELECT * FROM t1; +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +START TRANSACTION; +SELECT * FROM t1 LEFT JOIN t2 ON t1.c2=t2.c2 AND t2.c1=1 FOR UPDATE; +c1 c2 c3 c1 c2 c3 +1 2 3 1 2 3 +2 3 4 NULL NULL NULL +3 4 5 NULL NULL NULL +UPDATE t1 LEFT JOIN t2 ON t1.c1 = t2.c2 AND t2.c1 = 3 SET t1.c3 = RAND()*10; +COMMIT; +SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +DROP TABLE t1,t2; diff --git a/mysql-test/main/join_outer_innodb.test b/mysql-test/main/join_outer_innodb.test index c26cd62fbc7..6b332f3d155 100644 --- a/mysql-test/main/join_outer_innodb.test +++ b/mysql-test/main/join_outer_innodb.test @@ -374,3 +374,20 @@ drop table t1,t2,t3; set optimizer_prune_level=@mdev4270_opl; set optimizer_search_depth=@mdev4270_osd; +--echo # +--echo # Bug #20939184:INNODB: UNLOCK ROW COULD NOT FIND A 2 MODE LOCK ON THE +--echo # RECORD +--echo # +CREATE TABLE t1 (c1 INT, c2 INT, c3 INT, PRIMARY KEY (c1,c2) ) engine=innodb; +CREATE TABLE t2 (c1 INT, c2 INT, c3 INT, PRIMARY KEY (c1), KEY (c2)) engine=innodb; +INSERT INTO t1 VALUES (1,2,3),(2,3,4),(3,4,5); +INSERT INTO t2 SELECT * FROM t1; +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +START TRANSACTION; +#unlocks rows in table t2 where c1 = 1 +SELECT * FROM t1 LEFT JOIN t2 ON t1.c2=t2.c2 AND t2.c1=1 FOR UPDATE; +UPDATE t1 LEFT JOIN t2 ON t1.c1 = t2.c2 AND t2.c1 = 3 SET t1.c3 = RAND()*10; +COMMIT; +SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +DROP TABLE t1,t2; + diff --git a/mysql-test/main/limit_rows_examined.test b/mysql-test/main/limit_rows_examined.test index 8dc595ab594..2315580410f 100644 --- a/mysql-test/main/limit_rows_examined.test +++ b/mysql-test/main/limit_rows_examined.test @@ -2,11 +2,6 @@ # Tests for LIMIT ROWS EXAMINED, MDEV-28 # -if (`SELECT $PS_PROTOCOL != 0`) -{ - --skip Test temporarily disabled for ps-protocol -} - --source include/default_optimizer_switch.inc call mtr.add_suppression("Sort aborted.*"); diff --git a/mysql-test/main/mysqld--defaults-file.test b/mysql-test/main/mysqld--defaults-file.test index 4859cc17b42..9ca427568ef 100644 --- a/mysql-test/main/mysqld--defaults-file.test +++ b/mysql-test/main/mysqld--defaults-file.test @@ -4,6 +4,7 @@ source include/not_embedded.inc; source include/not_windows.inc; +source include/not_aix.inc; # All these tests refer to configuration files that do not exist diff --git a/mysql-test/main/mysqld--help,aix.rdiff b/mysql-test/main/mysqld--help,aix.rdiff index e69de29bb2d..972f8b1844b 100644 --- a/mysql-test/main/mysqld--help,aix.rdiff +++ b/mysql-test/main/mysqld--help,aix.rdiff @@ -0,0 +1,76 @@ +diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result +index 7b0ce27ead3..38176dcaa86 100644 +--- a/mysql-test/main/mysqld--help.result ++++ b/mysql-test/main/mysqld--help.result +@@ -1301,8 +1301,6 @@ The following specify which files/extra groups are read (specified before remain + WHERE clause, or a LIMIT clause, or else they will + aborted. Prevents the common mistake of accidentally + deleting or updating every row in a table. +- --stack-trace Print a symbolic stack trace on failure +- (Defaults to on; use --skip-stack-trace to disable.) + --standard-compliant-cte + Allow only CTEs compliant to SQL standard + (Defaults to on; use --skip-standard-compliant-cte to disable.) +@@ -1367,39 +1365,6 @@ The following specify which files/extra groups are read (specified before remain + --thread-cache-size=# + How many threads we should keep in a cache for reuse. + These are freed after 5 minutes of idle time +- --thread-pool-dedicated-listener +- If set to 1,listener thread will not pick up queries +- --thread-pool-exact-stats +- If set to 1, provides better statistics in +- information_schema threadpool tables +- --thread-pool-idle-timeout=# +- Timeout in seconds for an idle thread in the thread +- pool.Worker thread will be shut down after timeout +- --thread-pool-max-threads=# +- Maximum allowed number of worker threads in the thread +- pool +- --thread-pool-oversubscribe=# +- How many additional active worker threads in a group are +- allowed. +- --thread-pool-prio-kickup-timer=# +- The number of milliseconds before a dequeued low-priority +- statement is moved to the high-priority queue +- --thread-pool-priority=name +- Threadpool priority. High priority connections usually +- start executing earlier than low priority.If priority set +- to 'auto', the the actual priority(low or high) is +- determined based on whether or not connection is inside +- transaction. +- --thread-pool-size=# +- Number of thread groups in the pool. This parameter is +- roughly equivalent to maximum number of concurrently +- executing threads (threads in a waiting state do not +- count as executing). +- --thread-pool-stall-limit=# +- Maximum query execution time in milliseconds,before an +- executing non-yielding thread is considered stalled.If a +- worker thread is stalled, additional worker thread may be +- created to handle remaining clients. + --thread-stack=# The stack size for each thread + --time-format=name The TIME format (ignored) + --tls-version=name TLS protocol version for secure connections.. Any +@@ -1788,7 +1753,6 @@ slow-query-log FALSE + sort-buffer-size 2097152 + sql-mode STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION + sql-safe-updates FALSE +-stack-trace TRUE + standard-compliant-cte TRUE + stored-program-cache 256 + strict-password-validation TRUE +@@ -1807,14 +1771,6 @@ tcp-keepalive-probes 0 + tcp-keepalive-time 0 + tcp-nodelay TRUE + thread-cache-size 151 +-thread-pool-dedicated-listener FALSE +-thread-pool-exact-stats FALSE +-thread-pool-idle-timeout 60 +-thread-pool-max-threads 65536 +-thread-pool-oversubscribe 3 +-thread-pool-prio-kickup-timer 1000 +-thread-pool-priority auto +-thread-pool-stall-limit 500 + thread-stack 299008 + time-format %H:%i:%s + tmp-disk-table-size 18446744073709551615 diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test index 35a1f99236f..e0c65723012 100644 --- a/mysql-test/main/opt_trace.test +++ b/mysql-test/main/opt_trace.test @@ -1,9 +1,6 @@ -if (`SELECT $PS_PROTOCOL != 0`) -{ - --skip Test temporarily disabled for ps-protocol -} --source include/not_embedded.inc --source include/have_sequence.inc +--source include/protocol.inc SELECT table_name, column_name FROM information_schema.columns where table_name="OPTIMIZER_TRACE"; show variables like 'optimizer_trace'; set optimizer_trace="enabled=on"; @@ -267,12 +264,14 @@ begin return a; end| +--enable_prepare_warnings create function f2(a int) returns int begin declare a int default 0; select count(*) from t2 into a; return a; end| +--disable_prepare_warnings delimiter ;| set optimizer_trace='enabled=on'; diff --git a/mysql-test/mariadb-test-run.pl b/mysql-test/mariadb-test-run.pl index becf799c825..7b9422565ab 100755 --- a/mysql-test/mariadb-test-run.pl +++ b/mysql-test/mariadb-test-run.pl @@ -244,7 +244,7 @@ my $opt_ssl; my $opt_skip_ssl; my @opt_skip_test_list; our $opt_ssl_supported; -my $opt_ps_protocol; +our $opt_ps_protocol; my $opt_sp_protocol; my $opt_cursor_protocol; my $opt_view_protocol; diff --git a/mysql-test/suite.pm b/mysql-test/suite.pm index 5100b4137a2..4cc6b410fa1 100644 --- a/mysql-test/suite.pm +++ b/mysql-test/suite.pm @@ -25,6 +25,12 @@ sub skip_combinations { $skip{'include/platform.combinations'} = [ 'aix', 'win' ]; } + if ( $::opt_ps_protocol ) { + $skip{'include/protocol.combinations'} = [ 'nm' ]; + } else { + $skip{'include/protocol.combinations'} = [ 'ps' ]; + } + $skip{'include/maybe_debug.combinations'} = [ defined $::mysqld_variables{'debug-dbug'} ? 'release' : 'debug' ]; diff --git a/mysql-test/suite/innodb/t/innodb_bug53756-master.opt b/mysql-test/suite/innodb/t/innodb_bug53756-master.opt index 425fda95086..590d44a6d12 100644 --- a/mysql-test/suite/innodb/t/innodb_bug53756-master.opt +++ b/mysql-test/suite/innodb/t/innodb_bug53756-master.opt @@ -1 +1 @@ ---skip-stack-trace --skip-core-file +--loose-skip-stack-trace --skip-core-file diff --git a/mysql-test/suite/sys_vars/r/stored_program_cache_func,ps.rdiff b/mysql-test/suite/sys_vars/r/stored_program_cache_func,ps.rdiff new file mode 100644 index 00000000000..f07e82c3472 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/stored_program_cache_func,ps.rdiff @@ -0,0 +1,18 @@ +--- stored_program_cache_func.result ++++ stored_program_cache_func,ps.result +@@ -21,13 +21,13 @@ + 1 + show status like 'handler_read_key'; + Variable_name Value +-Handler_read_key 2 ++Handler_read_key 3 + call p1; + 1 + 1 + show status like 'handler_read_key'; + Variable_name Value +-Handler_read_key 3 ++Handler_read_key 5 + drop procedure p1; + set global stored_program_cache=default; + create procedure pr(i int) begin diff --git a/mysql-test/suite/sys_vars/t/stored_program_cache_func.test b/mysql-test/suite/sys_vars/t/stored_program_cache_func.test index 86cdd56a6de..611c33b530e 100644 --- a/mysql-test/suite/sys_vars/t/stored_program_cache_func.test +++ b/mysql-test/suite/sys_vars/t/stored_program_cache_func.test @@ -1,7 +1,5 @@ -if (`SELECT $PS_PROTOCOL != 0`) -{ - --skip Test temporarily disabled for ps-protocol -} +--source include/protocol.inc + create procedure p1() select 1; flush status; diff --git a/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_basic.test b/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_basic.test index 4afcc0379f0..b06a5069514 100644 --- a/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_basic.test +++ b/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_basic.test @@ -1,6 +1,7 @@ # uint global --source include/not_windows.inc --source include/not_embedded.inc +--source include/not_aix.inc SET @start_global_value = @@global.thread_pool_idle_timeout; # diff --git a/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_grant.test b/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_grant.test index 71b007bde23..8f5f2491e12 100644 --- a/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_grant.test +++ b/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_grant.test @@ -1,5 +1,6 @@ --source include/not_windows.inc --source include/not_embedded.inc +--source include/not_aix.inc SET @global=@@global.thread_pool_idle_timeout; diff --git a/mysql-test/suite/sys_vars/t/thread_pool_max_threads_basic.test b/mysql-test/suite/sys_vars/t/thread_pool_max_threads_basic.test index 3d5cd5f5198..392dbd3a145 100644 --- a/mysql-test/suite/sys_vars/t/thread_pool_max_threads_basic.test +++ b/mysql-test/suite/sys_vars/t/thread_pool_max_threads_basic.test @@ -1,5 +1,6 @@ # uint global --source include/not_embedded.inc +--source include/not_aix.inc SET @start_global_value = @@global.thread_pool_max_threads; # diff --git a/mysql-test/suite/sys_vars/t/thread_pool_max_threads_grant.test b/mysql-test/suite/sys_vars/t/thread_pool_max_threads_grant.test index 29a9ac42ea0..299d5ff4f44 100644 --- a/mysql-test/suite/sys_vars/t/thread_pool_max_threads_grant.test +++ b/mysql-test/suite/sys_vars/t/thread_pool_max_threads_grant.test @@ -1,5 +1,6 @@ # uint global --source include/not_embedded.inc +--source include/not_aix.inc SET @global=@@global.thread_pool_max_threads; diff --git a/mysql-test/suite/sys_vars/t/thread_pool_min_threads_basic.test b/mysql-test/suite/sys_vars/t/thread_pool_min_threads_basic.test index 131fbe98502..1447c83d39c 100644 --- a/mysql-test/suite/sys_vars/t/thread_pool_min_threads_basic.test +++ b/mysql-test/suite/sys_vars/t/thread_pool_min_threads_basic.test @@ -1,6 +1,7 @@ # uint global --source include/not_embedded.inc --source include/windows.inc +--source include/not_aix.inc SET @start_global_value = @@global.thread_pool_min_threads; # diff --git a/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_basic.test b/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_basic.test index 74f0f5e6ea7..43817febafd 100644 --- a/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_basic.test +++ b/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_basic.test @@ -1,6 +1,7 @@ # uint global --source include/not_windows.inc --source include/not_embedded.inc +--source include/not_aix.inc SET @start_global_value = @@global.thread_pool_oversubscribe; # diff --git a/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_grant.test b/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_grant.test index cbffb94c297..f3a96c69e8a 100644 --- a/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_grant.test +++ b/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_grant.test @@ -1,5 +1,6 @@ --source include/not_windows.inc --source include/not_embedded.inc +--source include/not_aix.inc SET @global=@@global.thread_pool_oversubscribe; diff --git a/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_basic.test b/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_basic.test index 1ab27907535..2d1dc59476c 100644 --- a/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_basic.test +++ b/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_basic.test @@ -1,5 +1,6 @@ # uint global --source include/not_embedded.inc +--source include/not_aix.inc SET @start_global_value = @@global.thread_pool_stall_limit; # diff --git a/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_grant.test b/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_grant.test index 8c0908fe2c0..ae0ed8a785b 100644 --- a/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_grant.test +++ b/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_grant.test @@ -1,5 +1,6 @@ # uint global --source include/not_embedded.inc +--source include/not_aix.inc SET @global=@@global.thread_pool_stall_limit; diff --git a/sql/myskel.m4 b/sql/myskel.m4 index b26fe46d342..8239b983f04 100644 --- a/sql/myskel.m4 +++ b/sql/myskel.m4 @@ -2,15 +2,10 @@ # fix the #line directives in the generated .cc files # to refer to the original sql_yacc.yy # -m4_define([yyfile],m4_bpatsubst(__file__,[[a-z.0-9]+$],sql_yacc.yy)) - m4_define([b4_syncline], -[m4_if(m4_index([$2],[.yy]),[-1], -[b4_sync_start([$1], [$2])[]dnl - -],[b4_sync_start([$1], ["yyfile"])[]dnl +[b4_sync_start([$1], m4_bpatsubst([$2],[yy_[a-z]+\.yy],sql_yacc.yy))[]dnl -])]) +]) # try both paths for different bison versions m4_sinclude(skeletons/c-skel.m4) diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 8b0f1eed46d..39b4290a161 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -179,14 +179,26 @@ my_bool my_net_init(NET *net, Vio *vio, void *thd, uint my_flags) DBUG_RETURN(0); } + +/** + Allocate and assign new net buffer + + @note In case of error the old buffer left + + @retval TRUE error + @retval FALSE success +*/ + my_bool net_allocate_new_packet(NET *net, void *thd, uint my_flags) { + uchar *tmp; DBUG_ENTER("net_allocate_new_packet"); - if (!(net->buff=(uchar*) my_malloc(key_memory_NET_buff, - (size_t) net->max_packet + - NET_HEADER_SIZE + COMP_HEADER_SIZE + 1, - MYF(MY_WME | my_flags)))) + if (!(tmp= (uchar*) my_malloc(key_memory_NET_buff, + (size_t) net->max_packet + + NET_HEADER_SIZE + COMP_HEADER_SIZE + 1, + MYF(MY_WME | my_flags)))) DBUG_RETURN(1); + net->buff= tmp; net->buff_end=net->buff+net->max_packet; net->write_pos=net->read_pos = net->buff; DBUG_RETURN(0); diff --git a/sql/protocol.cc b/sql/protocol.cc index c0a5f2327a0..7886ecd3043 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -597,6 +597,7 @@ void Protocol::end_statement() thd->get_stmt_da()->get_sqlstate()); break; case Diagnostics_area::DA_EOF: + case Diagnostics_area::DA_EOF_BULK: error= send_eof(thd->server_status, thd->get_stmt_da()->statement_warn_count()); break; @@ -1135,7 +1136,8 @@ static bool should_send_column_info(THD* thd, List<Item>* list, uint flags) auto cmd= thd->get_command(); #endif - DBUG_ASSERT(cmd == COM_STMT_EXECUTE || cmd == COM_STMT_PREPARE); + DBUG_ASSERT(cmd == COM_STMT_EXECUTE || cmd == COM_STMT_PREPARE + || cmd == COM_STMT_BULK_EXECUTE); DBUG_ASSERT(cmd != COM_STMT_PREPARE || !column_info_state.initialized); bool ret= metadata_columns_changed(column_info_state, thd, *list); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 34fa14d4324..0a2db2ea93a 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -709,7 +709,12 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, !table->prepare_triggers_for_delete_stmt_or_event()) will_batch= !table->file->start_bulk_delete(); - if (returning) + /* + thd->get_stmt_da()->is_set() means first iteration of prepared statement + with array binding operation execution (non optimized so it is not + INSERT) + */ + if (returning && !thd->get_stmt_da()->is_set()) { if (result->send_result_set_metadata(returning->item_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) diff --git a/sql/sql_error.cc b/sql/sql_error.cc index bb47502b3ce..cef9e6cec00 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -371,7 +371,7 @@ Diagnostics_area::set_eof_status(THD *thd) { DBUG_ENTER("set_eof_status"); /* Only allowed to report eof if has not yet reported an error */ - DBUG_ASSERT(! is_set()); + DBUG_ASSERT(!is_set() || (m_status == DA_EOF_BULK && is_bulk_op())); /* In production, refuse to overwrite an error or a custom response with an EOF packet. @@ -384,11 +384,23 @@ Diagnostics_area::set_eof_status(THD *thd) number of warnings, since they are not available to the client anyway. */ - m_statement_warn_count= (thd->spcont ? - 0 : - current_statement_warn_count()); + if (m_status == DA_EOF_BULK) + { + if (!thd->spcont) + m_statement_warn_count+= current_statement_warn_count(); + } + else + { + if (thd->spcont) + { + m_statement_warn_count= 0; + m_affected_rows= 0; + } + else + m_statement_warn_count= current_statement_warn_count(); + m_status= (is_bulk_op() ? DA_EOF_BULK : DA_EOF); + } - m_status= DA_EOF; DBUG_VOID_RETURN; } diff --git a/sql/sql_error.h b/sql/sql_error.h index a3782048c79..6b0d4d7749c 100644 --- a/sql/sql_error.h +++ b/sql/sql_error.h @@ -970,6 +970,8 @@ public: DA_EOF, /** Set whenever one calls my_ok() in PS bulk mode. */ DA_OK_BULK, + /** Set whenever one calls my_eof() in PS bulk mode. */ + DA_EOF_BULK, /** Set whenever one calls my_error() or my_message(). */ DA_ERROR, /** Set in case of a custom response, such as one from COM_STMT_PREPARE. */ @@ -1029,8 +1031,11 @@ public: enum_diagnostics_status status() const { return m_status; } const char *message() const - { DBUG_ASSERT(m_status == DA_ERROR || m_status == DA_OK || - m_status == DA_OK_BULK); return m_message; } + { + DBUG_ASSERT(m_status == DA_ERROR || m_status == DA_OK || + m_status == DA_OK_BULK || m_status == DA_EOF_BULK); + return m_message; + } uint sql_errno() const @@ -1057,7 +1062,7 @@ public: uint statement_warn_count() const { DBUG_ASSERT(m_status == DA_OK || m_status == DA_OK_BULK || - m_status == DA_EOF); + m_status == DA_EOF ||m_status == DA_EOF_BULK ); return m_statement_warn_count; } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 24ffad7368a..e258d46f78a 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -710,6 +710,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, Name_resolution_context *context; Name_resolution_context_state ctx_state; SELECT_LEX *returning= thd->lex->has_returning() ? thd->lex->returning() : 0; + unsigned char *readbuff= NULL; #ifndef EMBEDDED_LIBRARY char *query= thd->query(); @@ -786,7 +787,25 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, /* Prepares LEX::returing_list if it is not empty */ if (returning) + { result->prepare(returning->item_list, NULL); + if (thd->is_bulk_op()) + { + /* + It is RETURNING which needs network buffer to write result set and + it is array binfing which need network buffer to read parameters. + So we allocate yet another network buffer. + The old buffer will be freed at the end of operation. + */ + DBUG_ASSERT(thd->protocol == &thd->protocol_binary); + readbuff= thd->net.buff; // old buffer + if (net_allocate_new_packet(&thd->net, thd, MYF(MY_THREAD_SPECIFIC))) + { + readbuff= NULL; // failure, net_allocate_new_packet keeps old buffer + goto abort; + } + } + } context= &thd->lex->first_select_lex()->context; /* @@ -1322,7 +1341,8 @@ values_loop_end: thd->lex->current_select->save_leaf_tables(thd); thd->lex->current_select->first_cond_optimization= 0; } - + if (readbuff) + my_free(readbuff); DBUG_RETURN(FALSE); abort: @@ -1336,6 +1356,8 @@ abort: if (!joins_freed) free_underlaid_joins(thd, thd->lex->first_select_lex()); thd->abort_on_warning= 0; + if (readbuff) + my_free(readbuff); DBUG_RETURN(retval); } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 2f5470db123..e7d02aaeb0d 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -903,6 +903,9 @@ static bool insert_bulk_params(Prepared_statement *stmt, case STMT_INDICATOR_IGNORE: param->set_ignore(); break; + default: + DBUG_ASSERT(0); + DBUG_RETURN(1); } } else @@ -4680,6 +4683,7 @@ Prepared_statement::execute_bulk_loop(String *expanded_query, uchar *packet_end_arg) { Reprepare_observer reprepare_observer; + unsigned char *readbuff= NULL; bool error= 0; packet= packet_arg; packet_end= packet_end_arg; @@ -4693,24 +4697,37 @@ Prepared_statement::execute_bulk_loop(String *expanded_query, if (state == Query_arena::STMT_ERROR) { my_message(last_errno, last_error, MYF(0)); - thd->set_bulk_execution(0); - return TRUE; + goto err; } /* Check for non zero parameter count*/ if (param_count == 0) { DBUG_PRINT("error", ("Statement with no parameters for bulk execution.")); my_error(ER_UNSUPPORTED_PS, MYF(0)); - thd->set_bulk_execution(0); - return TRUE; + goto err; } if (!(sql_command_flags[lex->sql_command] & CF_PS_ARRAY_BINDING_SAFE)) { DBUG_PRINT("error", ("Command is not supported in bulk execution.")); my_error(ER_UNSUPPORTED_PS, MYF(0)); - thd->set_bulk_execution(0); - return TRUE; + goto err; + } + /* + Here second buffer for not optimized commands, + optimized commands do it inside thier internal loop. + */ + if (!(sql_command_flags[lex->sql_command] & CF_PS_ARRAY_BINDING_OPTIMIZED) && + this->lex->has_returning()) + { + // Above check can be true for SELECT in future + DBUG_ASSERT(lex->sql_command != SQLCOM_SELECT); + readbuff= thd->net.buff; // old buffer + if (net_allocate_new_packet(&thd->net, thd, MYF(MY_THREAD_SPECIFIC))) + { + readbuff= NULL; // failure, net_allocate_new_packet keeps old buffer + goto err; + } } #ifndef EMBEDDED_LIBRARY @@ -4722,9 +4739,7 @@ Prepared_statement::execute_bulk_loop(String *expanded_query, { my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysqld_stmt_bulk_execute"); - reset_stmt_params(this); - thd->set_bulk_execution(0); - return true; + goto err; } read_types= FALSE; @@ -4741,8 +4756,7 @@ Prepared_statement::execute_bulk_loop(String *expanded_query, { if (set_bulk_parameters(TRUE)) { - thd->set_bulk_execution(0); - return true; + goto err; } } @@ -4806,8 +4820,16 @@ reexecute: } reset_stmt_params(this); thd->set_bulk_execution(0); - + if (readbuff) + my_free(readbuff); return error; + +err: + reset_stmt_params(this); + thd->set_bulk_execution(0); + if (readbuff) + my_free(readbuff); + return true; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5a02218bb4a..08de2565caf 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -190,6 +190,7 @@ static int join_read_system(JOIN_TAB *tab); static int join_read_const(JOIN_TAB *tab); static int join_read_key(JOIN_TAB *tab); static void join_read_key_unlock_row(st_join_table *tab); +static void join_const_unlock_row(JOIN_TAB *tab); static int join_read_always_key(JOIN_TAB *tab); static int join_read_last_key(JOIN_TAB *tab); static int join_no_more_records(READ_RECORD *info); @@ -11189,8 +11190,12 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, else j->type=JT_EQ_REF; - j->read_record.unlock_row= (j->type == JT_EQ_REF)? - join_read_key_unlock_row : rr_unlock_row; + if (j->type == JT_EQ_REF) + j->read_record.unlock_row= join_read_key_unlock_row; + else if (j->type == JT_CONST) + j->read_record.unlock_row= join_const_unlock_row; + else + j->read_record.unlock_row= rr_unlock_row; DBUG_RETURN(0); } @@ -13455,6 +13460,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) /* Only happens with outer joins */ tab->read_first_record= tab->type == JT_SYSTEM ? join_read_system : join_read_const; + tab->read_record.unlock_row= join_const_unlock_row; if (!(table->covering_keys.is_set(tab->ref.key) && !table->no_keyread) && (!jcl || jcl > 4) && !tab->ref.is_access_triggered()) push_index_cond(tab, tab->ref.key); @@ -21726,6 +21732,19 @@ join_read_key_unlock_row(st_join_table *tab) tab->ref.use_count--; } +/** + Rows from const tables are read once but potentially used + multiple times during execution of a query. + Ensure such rows are never unlocked during query execution. +*/ + +void +join_const_unlock_row(JOIN_TAB *tab) +{ + DBUG_ASSERT(tab->type == JT_CONST); +} + + /* ref access method implementation: "read_first" function @@ -24178,8 +24197,12 @@ check_reverse_order: else if (select && select->quick) select->quick->need_sorted_output(); - tab->read_record.unlock_row= (tab->type == JT_EQ_REF) ? - join_read_key_unlock_row : rr_unlock_row; + if (tab->type == JT_EQ_REF) + tab->read_record.unlock_row= join_read_key_unlock_row; + else if (tab->type == JT_CONST) + tab->read_record.unlock_row= join_const_unlock_row; + else + tab->read_record.unlock_row= rr_unlock_row; } // QEP has been modified diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 44db9986df6..447fba38323 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -674,8 +674,7 @@ void buf_dblwr_t::flush_buffered_writes_completed(const IORequest &request) static_cast<const byte*>(frame))); ut_ad(lsn); ut_ad(lsn >= bpage->oldest_modification()); - if (lsn > log_sys.get_flushed_lsn()) - log_write_up_to(lsn, true); + log_write_up_to(lsn, true); e.request.node->space->io(e.request, bpage->physical_offset(), e_size, frame, bpage); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 2a91106ba22..65dc7fcae1a 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -15432,7 +15432,7 @@ ha_innobase::extra( case HA_EXTRA_END_ALTER_COPY: m_prebuilt->table->skip_alter_undo = 0; if (!m_prebuilt->table->is_temporary()) { - log_write_up_to(LSN_MAX, true); + log_buffer_flush_to_disk(); } break; default:/* Do nothing */ diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index 89cef8d69ed..0fe7b22fb04 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -705,15 +705,6 @@ public: /** Shut down the redo log subsystem. */ void close(); - - /** Initiate a write of the log buffer to the file if needed. - @param flush whether to initiate a durable write */ - inline void initiate_write(bool flush) - { - const lsn_t lsn= get_lsn(); - if (!flush || get_flushed_lsn() < lsn) - log_write_up_to(lsn, flush); - } }; /** Redo log system */ diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 5e64007ef84..1c0a617191e 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -791,6 +791,7 @@ void log_write_up_to(lsn_t lsn, bool flush_to_disk, bool rotate_key, { ut_ad(!srv_read_only_mode); ut_ad(!rotate_key || flush_to_disk); + ut_ad(lsn != LSN_MAX); if (recv_no_ibuf_operations) { diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index d7bb3ce886b..76a703b7496 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -702,7 +702,7 @@ static lsn_t log_reserve_and_open(size_t len) DEBUG_SYNC_C("log_buf_size_exceeded"); /* Not enough free space, do a write of the log buffer */ - log_sys.initiate_write(false); + log_write_up_to(log_sys.get_lsn(), false); srv_stats.log_waits.inc(); diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index bb85e82cbb8..b8f78775624 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2672,7 +2672,7 @@ rollback: ALTER TABLE...DISCARD TABLESPACE operation altogether. */ err= row_discard_tablespace(trx, table); DBUG_EXECUTE_IF("ib_discard_before_commit_crash", - log_write_up_to(LSN_MAX, true); DBUG_SUICIDE();); + log_buffer_flush_to_disk(); DBUG_SUICIDE();); /* FTS_ tables may be deleted */ std::vector<pfs_os_file_t> deleted; trx->commit(deleted); diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index ce020a6b88d..8692eaa0e89 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -1477,7 +1477,7 @@ static void srv_sync_log_buffer_in_background() srv_main_thread_op_info = "flushing log"; if (difftime(current_time, srv_last_log_flush_time) >= srv_flush_log_at_timeout) { - log_sys.initiate_write(true); + log_buffer_flush_to_disk(); srv_last_log_flush_time = current_time; srv_log_writes_and_flush++; } diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index d0596cded6b..bac9a3b25b5 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -328,7 +328,7 @@ static dberr_t create_log_file(bool create_new_db, lsn_t lsn, mysql_mutex_unlock(&log_sys.mutex); log_make_checkpoint(); - log_write_up_to(LSN_MAX, true); + log_buffer_flush_to_disk(); return DB_SUCCESS; } diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index 40fa8172e6f..609e058ca52 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -777,7 +777,7 @@ not_free: DBUG_EXECUTE_IF("ib_undo_trunc", ib::info() << "ib_undo_trunc"; - log_write_up_to(LSN_MAX, true); + log_buffer_flush_to_disk(); DBUG_SUICIDE();); for (auto& rseg : trx_sys.rseg_array) { diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc index 1bb712f64cc..3e9198a6b6c 100644 --- a/storage/perfschema/pfs.cc +++ b/storage/perfschema/pfs.cc @@ -5466,6 +5466,7 @@ void pfs_end_statement_v1(PSI_statement_locker *locker, void *stmt_da) switch(da->status()) { case Diagnostics_area::DA_OK_BULK: + case Diagnostics_area::DA_EOF_BULK: case Diagnostics_area::DA_EMPTY: break; case Diagnostics_area::DA_OK: @@ -5706,6 +5707,7 @@ void pfs_end_statement_v1(PSI_statement_locker *locker, void *stmt_da) switch (da->status()) { case Diagnostics_area::DA_OK_BULK: + case Diagnostics_area::DA_EOF_BULK: case Diagnostics_area::DA_EMPTY: break; case Diagnostics_area::DA_OK: diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 77ebf0ae3b8..e6c5f4ab654 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -20547,6 +20547,178 @@ static void test_bulk_replace() rc= mysql_query(mysql, "DROP TABLE t1"); myquery(rc); } + + +static void test_bulk_insert_returning() +{ + int rc; + MYSQL_STMT *stmt; + MYSQL_BIND bind[2], res_bind[2]; + MYSQL_ROW row; + MYSQL_RES *result; + int i, + id[]= {1, 2, 3, 4}, + val[]= {1, 1, 1, 1}, + count= sizeof(id)/sizeof(id[0]); + unsigned long length[2]; + my_bool is_null[2]; + my_bool error[2]; + int32 res[2]; + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + myquery(rc); + rc= mysql_query(mysql, + "CREATE TABLE t1 (id int not null primary key, active int)"); + myquery(rc); + + stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(stmt, + "insert into t1 values (?, ?) returning id, active", + -1); + check_execute(stmt, rc); + + memset(bind, 0, sizeof(bind)); + bind[0].buffer_type = MYSQL_TYPE_LONG; + bind[0].buffer = (void *)id; + bind[0].buffer_length = 0; + bind[1].buffer_type = MYSQL_TYPE_LONG; + bind[1].buffer = (void *)val; + bind[1].buffer_length = 0; + + mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count); + rc= mysql_stmt_bind_param(stmt, bind); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + myquery(rc); + + memset(res_bind, 0, sizeof(res_bind)); + for (i= 0; i < 2; i++) + { + res_bind[i].buffer_type= MYSQL_TYPE_LONG; + res_bind[i].buffer= (char *)&res[i]; + res_bind[i].is_null= &is_null[i]; + res_bind[i].length= &length[i]; + res_bind[i].error= &error[i]; + } + rc= mysql_stmt_bind_result(stmt, res_bind); + myquery(rc); + rc= mysql_stmt_store_result(stmt); + myquery(rc); + + i= 0; + while (!mysql_stmt_fetch(stmt)) + { + i++; + DIE_IF(is_null[0] || is_null[1]); + DIE_IF(res[0] != i); + DIE_IF(res[1] != 1); + } + DIE_IF(i != 4); + + mysql_stmt_close(stmt); + + rc= mysql_query(mysql, "SELECT id,active FROM t1"); + myquery(rc); + + result= mysql_store_result(mysql); + mytest(result); + + i= 0; + while ((row= mysql_fetch_row(result))) + { + i++; + DIE_IF(atoi(row[0]) != i); + DIE_IF(atoi(row[1]) != 1); + } + DIE_IF(i != 4); + mysql_free_result(result); + + + rc= mysql_query(mysql, "DROP TABLE t1"); + myquery(rc); +} + +static void test_bulk_delete_returning() +{ + int rc; + MYSQL_STMT *stmt; + MYSQL_BIND bind[2], res_bind[2]; + MYSQL_ROW row; + MYSQL_RES *result; + int i, + id[]= {1, 2, 3, 4}, + count= sizeof(id)/sizeof(id[0]); + unsigned long length[1]; + my_bool is_null[1]; + my_bool error[1]; + int32 res[1]; + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + myquery(rc); + rc= mysql_query(mysql, "CREATE TABLE t1 (id int not null primary key)"); + myquery(rc); + rc= mysql_query(mysql, "insert into t1 values (1), (2), (3), (4)"); + myquery(rc); + verify_affected_rows(4); + + stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(stmt, "DELETE FROM t1 WHERE id=? RETURNING id", -1); + check_execute(stmt, rc); + + memset(bind, 0, sizeof(bind)); + bind[0].buffer_type = MYSQL_TYPE_LONG; + bind[0].buffer = (void *)id; + bind[0].buffer_length = 0; + + mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count); + rc= mysql_stmt_bind_param(stmt, bind); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + myquery(rc); + + memset(res_bind, 0, sizeof(res_bind)); + res_bind[0].buffer_type= MYSQL_TYPE_LONG; + res_bind[0].buffer= (char *)&res[0]; + res_bind[0].is_null= &is_null[0]; + res_bind[0].length= &length[0]; + res_bind[0].error= &error[0]; + rc= mysql_stmt_bind_result(stmt, res_bind); + myquery(rc); + rc= mysql_stmt_store_result(stmt); + myquery(rc); + + i= 0; + while (!mysql_stmt_fetch(stmt)) + { + i++; + DIE_IF(is_null[0]); + DIE_IF(res[0] != i); + } + DIE_IF(i != 4); + + mysql_stmt_close(stmt); + + rc= mysql_query(mysql, "SELECT id FROM t1"); + myquery(rc); + + result= mysql_store_result(mysql); + mytest(result); + + i= 0; + while ((row= mysql_fetch_row(result))) + { + i++; + printf("\nResult (SHOULD NOT BE HERE!!!) %d %s \n", i, row[0]); + } + DIE_IF(i != 0 ); + mysql_free_result(result); + + + rc= mysql_query(mysql, "DROP TABLE t1"); + myquery(rc); +} #endif @@ -21556,6 +21728,8 @@ static struct my_tests_st my_tests[]= { { "test_bulk_autoinc", test_bulk_autoinc}, { "test_bulk_delete", test_bulk_delete }, { "test_bulk_replace", test_bulk_replace }, + { "test_bulk_insert_returning", test_bulk_insert_returning }, + { "test_bulk_delete_returning", test_bulk_delete_returning }, #endif { "test_ps_params_in_ctes", test_ps_params_in_ctes }, { "test_explain_meta", test_explain_meta }, |