mirror of
https://github.com/MariaDB/server.git
synced 2025-12-09 08:01:34 +03:00
Merge 10.11 into 11.0
This commit is contained in:
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -1,2 +0,0 @@
|
||||
/debian @ottok
|
||||
|
||||
@@ -316,7 +316,7 @@ ELSEIF(RPM MATCHES "sles")
|
||||
ENDIF()
|
||||
|
||||
# MDEV-24629, we need it outside of ELSIFs
|
||||
IF(RPM MATCHES "fedora3[234]")
|
||||
IF(RPM MATCHES "fedora")
|
||||
ALTERNATIVE_NAME("common" "mariadb-connector-c-config" ${MARIADB_CONNECTOR_C_VERSION}-1)
|
||||
ENDIF()
|
||||
|
||||
|
||||
35
debian/additions/innotop/innotop
vendored
Normal file → Executable file
35
debian/additions/innotop/innotop
vendored
Normal file → Executable file
@@ -20,6 +20,9 @@
|
||||
# Street, Fifth Floor, Boston, MA 02110-1335 USA
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
use feature ':5.16';
|
||||
use warnings FATAL => 'all';
|
||||
|
||||
our $VERSION = '1.11.4';
|
||||
@@ -265,7 +268,7 @@ sub get_dbh {
|
||||
$dbh->do($sql);
|
||||
MKDEBUG && _d('Enabling charset for STDOUT');
|
||||
if ( $charset eq 'utf8' ) {
|
||||
binmode(STDOUT, ':utf8')
|
||||
binmode(STDOUT, ':encoding(UTF-8)')
|
||||
or die "Can't binmode(STDOUT, ':utf8'): $OS_ERROR";
|
||||
}
|
||||
else {
|
||||
@@ -612,6 +615,9 @@ sub ts_to_string {
|
||||
|
||||
sub parse_innodb_timestamp {
|
||||
my $text = shift;
|
||||
if ( ! defined $text ) {
|
||||
return (0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
my ( $y, $m, $d, $h, $i, $s )
|
||||
= $text =~ m/^(\d\d)(\d\d)(\d\d) +(\d+):(\d+):(\d+)$/;
|
||||
die("Can't get timestamp from $text\n") unless $y;
|
||||
@@ -803,7 +809,8 @@ sub parse_fk_transaction_error {
|
||||
# TODO: write some tests for this
|
||||
sub parse_innodb_record_dump {
|
||||
my ( $dump, $complete, $debug ) = @_;
|
||||
return undef unless $dump;
|
||||
# Use bare return as recommend in page 199 of PBP
|
||||
return unless $dump;
|
||||
|
||||
my $result = {};
|
||||
|
||||
@@ -6769,6 +6776,9 @@ sub set_precision {
|
||||
my ( $num, $precision ) = @_;
|
||||
$num = 0 unless defined $num;
|
||||
$precision = $config{num_digits}->{val} if !defined $precision;
|
||||
if ( $num eq "" ) {
|
||||
$num = int(0);
|
||||
}
|
||||
sprintf("%.${precision}f", $num);
|
||||
}
|
||||
|
||||
@@ -6777,6 +6787,9 @@ sub set_precision {
|
||||
sub percent {
|
||||
my ( $num ) = @_;
|
||||
$num = 0 unless defined $num;
|
||||
if ( $num eq "" ) {
|
||||
$num = int(0);
|
||||
}
|
||||
my $digits = $config{num_digits}->{val};
|
||||
return sprintf("%.${digits}f", $num * 100)
|
||||
. ($config{show_percent}->{val} ? '%' : '');
|
||||
@@ -6841,7 +6854,7 @@ sub make_color_func {
|
||||
push @criteria,
|
||||
"( defined \$set->{$spec->{col}} && \$set->{$spec->{col}} $spec->{op} $val ) { return '$spec->{color}'; }";
|
||||
}
|
||||
return undef unless @criteria;
|
||||
return unless @criteria;
|
||||
my $sub = eval 'sub { my ( $set ) = @_; if ' . join(" elsif ", @criteria) . '}';
|
||||
die if $EVAL_ERROR;
|
||||
return $sub;
|
||||
@@ -7521,10 +7534,10 @@ sub choose_connections {
|
||||
sub do_stmt {
|
||||
my ( $cxn, $stmt_name, @args ) = @_;
|
||||
|
||||
return undef if $file;
|
||||
return if $file;
|
||||
|
||||
# Test if the cxn should not even be tried
|
||||
return undef if $dbhs{$cxn}
|
||||
return if $dbhs{$cxn}
|
||||
&& $dbhs{$cxn}->{failed}
|
||||
&& ( !$dbhs{$cxn}->{dbh} || !$dbhs{$cxn}->{dbh}->{Active} || $dbhs{$cxn}->{mode} eq $config{mode}->{val} );
|
||||
|
||||
@@ -7596,10 +7609,10 @@ sub handle_cxn_error {
|
||||
sub do_query {
|
||||
my ( $cxn, $query ) = @_;
|
||||
|
||||
return undef if $file;
|
||||
return if $file;
|
||||
|
||||
# Test if the cxn should not even be tried
|
||||
return undef if $dbhs{$cxn}
|
||||
return if $dbhs{$cxn}
|
||||
&& $dbhs{$cxn}->{failed}
|
||||
&& ( !$dbhs{$cxn}->{dbh} || !$dbhs{$cxn}->{dbh}->{Active} || $dbhs{$cxn}->{mode} eq $config{mode}->{val} );
|
||||
|
||||
@@ -7781,7 +7794,7 @@ sub compile_select_stmt {
|
||||
sub compile_filter {
|
||||
my ( $text ) = @_;
|
||||
my ( $sub, $err );
|
||||
eval "\$sub = sub { my \$set = shift; $text }";
|
||||
eval { $sub = sub { my $set = shift; $text } };
|
||||
if ( $EVAL_ERROR ) {
|
||||
$EVAL_ERROR =~ s/at \(eval.*$//;
|
||||
$sub = sub { return $EVAL_ERROR };
|
||||
@@ -8013,7 +8026,7 @@ sub load_config_plugins {
|
||||
|
||||
# First, find a list of all plugins that exist on disk, and get information about them.
|
||||
my $dir = $config{plugin_dir}->{val};
|
||||
foreach my $p_file ( <$dir/*.pm> ) {
|
||||
foreach my $p_file (glob($dir."/*.pm")) {
|
||||
my ($package, $desc);
|
||||
eval {
|
||||
open my $p_in, "<", $p_file or die $OS_ERROR;
|
||||
@@ -9192,7 +9205,7 @@ sub switch_var_set {
|
||||
# edit_stmt_sleep_times {{{3
|
||||
sub edit_stmt_sleep_times {
|
||||
$clear_screen_sub->();
|
||||
my $stmt = prompt_list('Specify a statement', '', sub { return sort keys %stmt_maker_for });
|
||||
my $stmt = prompt_list('Specify a statement', '', sub { my @tmparray = sort keys %stmt_maker_for; return @tmparray });
|
||||
return unless $stmt && exists $stmt_maker_for{$stmt};
|
||||
$clear_screen_sub->();
|
||||
my $curr_val = $stmt_sleep_time_for{$stmt} || 0;
|
||||
@@ -9843,7 +9856,7 @@ sub get_slave_status {
|
||||
sub is_func {
|
||||
my ( $word ) = @_;
|
||||
return defined(&$word)
|
||||
|| eval "my \$x= sub { $word }; 1"
|
||||
|| eval { my $x = sub { $word }; 1 }
|
||||
|| $EVAL_ERROR !~ m/^Bareword/;
|
||||
}
|
||||
|
||||
|
||||
14
debian/autobake-deb.sh
vendored
14
debian/autobake-deb.sh
vendored
@@ -115,7 +115,6 @@ case "${LSBNAME}"
|
||||
in
|
||||
# Debian
|
||||
"buster")
|
||||
add_lsb_base_depends
|
||||
disable_libfmt
|
||||
replace_uring_with_aio
|
||||
if [ ! "$architecture" = amd64 ]
|
||||
@@ -123,11 +122,10 @@ in
|
||||
disable_pmem
|
||||
fi
|
||||
;&
|
||||
"bullseye"|"bookworm")
|
||||
if [[ "${LSBNAME}" == "bullseye" ]]
|
||||
then
|
||||
"bullseye")
|
||||
add_lsb_base_depends
|
||||
fi
|
||||
;&
|
||||
"bookworm")
|
||||
# mariadb-plugin-rocksdb in control is 4 arches covered by the distro rocksdb-tools
|
||||
# so no removal is necessary.
|
||||
if [[ ! "$architecture" =~ amd64|arm64|ppc64el ]]
|
||||
@@ -145,17 +143,17 @@ in
|
||||
;;
|
||||
# Ubuntu
|
||||
"bionic")
|
||||
add_lsb_base_depends
|
||||
remove_rocksdb_tools
|
||||
[ "$architecture" != amd64 ] && disable_pmem
|
||||
;&
|
||||
"focal")
|
||||
add_lsb_base_depends
|
||||
replace_uring_with_aio
|
||||
disable_libfmt
|
||||
;&
|
||||
"impish"|"jammy"|"kinetic"|"lunar")
|
||||
"jammy"|"kinetic")
|
||||
add_lsb_base_depends
|
||||
;&
|
||||
"lunar"|"mantic")
|
||||
# mariadb-plugin-rocksdb s390x not supported by us (yet)
|
||||
# ubuntu doesn't support mips64el yet, so keep this just
|
||||
# in case something changes.
|
||||
|
||||
111
debian/mariadb-server.postinst
vendored
111
debian/mariadb-server.postinst
vendored
@@ -1,9 +1,15 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /usr/share/debconf/confmodule
|
||||
|
||||
if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi
|
||||
if [ -n "$DEBIAN_SCRIPT_DEBUG" ]
|
||||
then
|
||||
set -v -x
|
||||
DEBIAN_SCRIPT_TRACE=1
|
||||
fi
|
||||
|
||||
${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*" 1>&2 }
|
||||
|
||||
export PATH=$PATH:/sbin:/usr/sbin:/bin:/usr/bin
|
||||
@@ -21,7 +27,9 @@ case "$1" in
|
||||
# and because changed configuration options should take effect immediately.
|
||||
# In case the server wasn't running at all it should be ok if the stop
|
||||
# script fails. I can't tell at this point because of the cleaned /run.
|
||||
set +e; invoke-rc.d mariadb stop; set -e
|
||||
set +e
|
||||
invoke-rc.d mariadb stop
|
||||
set -e
|
||||
|
||||
# An existing /etc/init.d/mysql might be on the system if there was a
|
||||
# previous MySQL or MariaDB installation, since /etc/init.d files are
|
||||
@@ -61,21 +69,26 @@ case "$1" in
|
||||
# If the following symlink exists, it is a preserved copy the old data dir
|
||||
# created by the preinst script during a upgrade that would have otherwise
|
||||
# been replaced by an empty mysql dir. This should restore it.
|
||||
for dir in DATADIR LOGDIR; do
|
||||
for dir in DATADIR LOGDIR
|
||||
do
|
||||
|
||||
if [ "$dir" = "DATADIR" ]; then
|
||||
if [ "$dir" = "DATADIR" ]
|
||||
then
|
||||
targetdir=$mysql_datadir
|
||||
else
|
||||
targetdir=$mysql_logdir
|
||||
fi
|
||||
|
||||
savelink="$mysql_upgradedir/$dir.link"
|
||||
if [ -L "$savelink" ]; then
|
||||
if [ -L "$savelink" ]
|
||||
then
|
||||
# If the targetdir was a symlink before we upgraded it is supposed
|
||||
# to be either still be present or not existing anymore now.
|
||||
if [ -L "$targetdir" ]; then
|
||||
if [ -L "$targetdir" ]
|
||||
then
|
||||
rm "$savelink"
|
||||
elif [ ! -d "$targetdir" ]; then
|
||||
elif [ ! -d "$targetdir" ]
|
||||
then
|
||||
mv "$savelink" "$targetdir"
|
||||
else
|
||||
# this should never even happen, but just in case...
|
||||
@@ -109,17 +122,29 @@ EOF
|
||||
# This direct update is needed to enable an authentication mechanism to
|
||||
# perform mariadb-upgrade, (MDEV-22678). To keep the impact minimal, we
|
||||
# skip innodb and set key-buffer-size to 0 as it isn't reused.
|
||||
if [ -f "$mysql_datadir"/auto.cnf ] && [ -f "$mysql_datadir"/mysql/user.MYD ] &&
|
||||
[ ! lsof -nt "$mysql_datadir"/mysql/user.MYD > /dev/null ] && [ ! -f "$mysql_datadir"/undo_001 ]; then
|
||||
if [ -f "$mysql_datadir/auto.cnf" ] &&
|
||||
[ -f "$mysql_datadir/mysql/user.MYD" ] &&
|
||||
! lsof -nt "$mysql_datadir"/mysql/user.MYD > /dev/null &&
|
||||
[ ! -f "$mysql_datadir/undo_001" ]
|
||||
then
|
||||
echo "UPDATE mysql.user SET plugin='unix_socket' WHERE plugin='auth_socket';" |
|
||||
mariadbd --skip-innodb --key_buffer_size=0 --default-storage-engine=MyISAM --bootstrap 2> /dev/null
|
||||
fi
|
||||
|
||||
# Ensure the existence and right permissions for the database and
|
||||
# log files. Use mkdir option 'Z' to create with correct SELinux context.
|
||||
if [ ! -d "$mysql_statedir" ] && [ ! -L "$mysql_statedir" ]; then mkdir -Z "$mysql_statedir"; fi
|
||||
if [ ! -d "$mysql_datadir" ] && [ ! -L "$mysql_datadir" ]; then mkdir -Z "$mysql_datadir" ; fi
|
||||
if [ ! -d "$mysql_logdir" ] && [ ! -L "$mysql_logdir" ]; then mkdir -Z "$mysql_logdir" ; fi
|
||||
if [ ! -d "$mysql_statedir" ] && [ ! -L "$mysql_statedir" ]
|
||||
then
|
||||
mkdir -Z "$mysql_statedir"
|
||||
fi
|
||||
if [ ! -d "$mysql_datadir" ] && [ ! -L "$mysql_datadir" ]
|
||||
then
|
||||
mkdir -Z "$mysql_datadir"
|
||||
fi
|
||||
if [ ! -d "$mysql_logdir" ] && [ ! -L "$mysql_logdir" ]
|
||||
then
|
||||
mkdir -Z "$mysql_logdir"
|
||||
fi
|
||||
# When creating an ext3 jounal on an already mounted filesystem like e.g.
|
||||
# /var/lib/mysql, you get a .journal file that is not modifiable by chown.
|
||||
# The mysql_statedir must not be writable by the mysql user under any
|
||||
@@ -180,26 +205,30 @@ EOF
|
||||
# --defaults-file option for tools (for the sake of upgrades)
|
||||
# and thus need /etc/mysql/debian.cnf to exist, even if it's empty.
|
||||
# In the long run the goal is to obsolete this file.
|
||||
dc=$mysql_cfgdir/debian.cnf;
|
||||
if [ ! -d "$mysql_cfgdir" ]; then
|
||||
dc="$mysql_cfgdir/debian.cnf"
|
||||
if [ ! -d "$mysql_cfgdir" ]
|
||||
then
|
||||
install -o 0 -g 0 -m 0755 -d $mysql_cfgdir
|
||||
fi
|
||||
if [ ! -e "$dc" ]; then
|
||||
if [ ! -e "$dc" ]
|
||||
then
|
||||
cat /dev/null > $dc
|
||||
echo "# THIS FILE IS OBSOLETE. STOP USING IT IF POSSIBLE." >>$dc
|
||||
echo "# This file exists only for backwards compatibility for" >>$dc
|
||||
echo "# tools that run '--defaults-file=/etc/mysql/debian.cnf'" >>$dc
|
||||
echo "# and have root level access to the local filesystem." >>$dc
|
||||
echo "# With those permissions one can run 'mariadb' directly" >>$dc
|
||||
echo "# anyway thanks to unix socket authentication and hence" >>$dc
|
||||
echo "# this file is useless. See package README for more info." >>$dc
|
||||
echo "[client]" >>$dc
|
||||
echo "host = localhost" >>$dc
|
||||
echo "user = root" >>$dc
|
||||
echo "[mysql_upgrade]" >>$dc
|
||||
echo "host = localhost" >>$dc
|
||||
echo "user = root" >>$dc
|
||||
echo "# THIS FILE WILL BE REMOVED IN A FUTURE DEBIAN RELEASE." >>$dc
|
||||
{
|
||||
echo "# THIS FILE IS OBSOLETE. STOP USING IT IF POSSIBLE.";
|
||||
echo "# This file exists only for backwards compatibility for";
|
||||
echo "# tools that run '--defaults-file=/etc/mysql/debian.cnf'";
|
||||
echo "# and have root level access to the local filesystem.";
|
||||
echo "# With those permissions one can run 'mariadb' directly";
|
||||
echo "# anyway thanks to unix socket authentication and hence";
|
||||
echo "# this file is useless. See package README for more info.";
|
||||
echo "[client]";
|
||||
echo "host = localhost";
|
||||
echo "user = root";
|
||||
echo "[mysql_upgrade]";
|
||||
echo "host = localhost";
|
||||
echo "user = root";
|
||||
echo "# THIS FILE WILL BE REMOVED IN A FUTURE DEBIAN RELEASE.";
|
||||
} >> $dc
|
||||
fi
|
||||
# Keep it only root-readable, as it always was
|
||||
chown 0:0 $dc
|
||||
@@ -212,8 +241,10 @@ EOF
|
||||
# on by default) to work both to disable a default profile, and to keep
|
||||
# any profile installed and maintained by users themselves.
|
||||
profile="/etc/apparmor.d/usr.sbin.mariadbd"
|
||||
if [ -f "$profile" ] && aa-status --enabled 2>/dev/null; then
|
||||
if grep -q /usr/sbin/mariadbd "$profile" 2>/dev/null ; then
|
||||
if [ -f "$profile" ] && aa-status --enabled 2>/dev/null
|
||||
then
|
||||
if grep -q /usr/sbin/mariadbd "$profile" 2>/dev/null
|
||||
then
|
||||
apparmor_parser -r "$profile" || true
|
||||
else
|
||||
echo "/usr/sbin/mariadbd { }" | apparmor_parser --remove 2>/dev/null || true
|
||||
@@ -232,14 +263,14 @@ EOF
|
||||
# Note that file cannot be empty, otherwise systemd version in Ubuntu Bionic
|
||||
# will think the service is masked
|
||||
echo "# empty placeholder" > /etc/systemd/system/mariadb.service.d/migrated-from-my.cnf-settings.conf
|
||||
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-configure)
|
||||
;;
|
||||
|
||||
triggered)
|
||||
if [ -d /run/systemd/system ]; then
|
||||
if [ -d /run/systemd/system ]
|
||||
then
|
||||
systemctl --system daemon-reload
|
||||
else
|
||||
invoke-rc.d mariadb restart
|
||||
@@ -259,19 +290,23 @@ db_stop # in case invoke fails
|
||||
# systemctl. If we upgrade from MySQL mysql.service may be masked, which also
|
||||
# means init.d script is disabled. Unmask mysql service explicitly.
|
||||
# Check first that the command exists, to avoid emitting any warning messages.
|
||||
if [ -x "$(command -v deb-systemd-helper)" ]; then
|
||||
if [ -x "$(command -v deb-systemd-helper)" ]
|
||||
then
|
||||
deb-systemd-helper unmask mysql.service > /dev/null
|
||||
fi
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
# Modified dh_systemd_start snippet that's not added automatically
|
||||
if [ -d /run/systemd/system ]; then
|
||||
if [ -d /run/systemd/system ]
|
||||
then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
deb-systemd-invoke start mariadb.service >/dev/null || true
|
||||
# Modified dh_installinit snippet to only run with sysvinit
|
||||
elif [ -x "/etc/init.d/mariadb" ]; then
|
||||
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ]; then
|
||||
# Modified dh_installinit snippet to only run with sysvinit
|
||||
elif [ -x "/etc/init.d/mariadb" ]
|
||||
then
|
||||
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ]
|
||||
then
|
||||
invoke-rc.d mariadb start || exit $?
|
||||
fi
|
||||
fi
|
||||
|
||||
28
debian/mariadb-server.postrm
vendored
28
debian/mariadb-server.postrm
vendored
@@ -1,9 +1,15 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /usr/share/debconf/confmodule
|
||||
|
||||
if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi
|
||||
if [ -n "$DEBIAN_SCRIPT_DEBUG" ]
|
||||
then
|
||||
set -v -x
|
||||
DEBIAN_SCRIPT_TRACE=1
|
||||
fi
|
||||
|
||||
${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*" 1>&2 }
|
||||
|
||||
MYADMIN="/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf"
|
||||
@@ -14,7 +20,10 @@ MYADMIN="/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf"
|
||||
stop_server() {
|
||||
# Return immediately if there are no mysqld processes running
|
||||
# as there is no point in trying to shutdown in that case.
|
||||
if ! pgrep -x --nslist pid --ns $$ "mysqld|mariadbd" > /dev/null; then return; fi
|
||||
if ! pgrep -x --nslist pid --ns $$ "mysqld|mariadbd" > /dev/null
|
||||
then
|
||||
return
|
||||
fi
|
||||
|
||||
set +e
|
||||
invoke-rc.d mariadb stop
|
||||
@@ -23,7 +32,8 @@ stop_server() {
|
||||
set -e
|
||||
|
||||
# systemctl could emit exit code 100=no init script (fresh install)
|
||||
if [ "$errno" != 0 -a "$errno" != 100 ]; then
|
||||
if [ "$errno" != 0 ] && [ "$errno" != 100 ]
|
||||
then
|
||||
echo "Attempt to stop MariaDB/MySQL server returned exitcode $errno" 1>&2
|
||||
echo "There is a MariaDB/MySQL server running, but we failed in our attempts to stop it." 1>&2
|
||||
echo "Stop it yourself and try again!" 1>&2
|
||||
@@ -35,7 +45,8 @@ stop_server() {
|
||||
|
||||
case "$1" in
|
||||
purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
||||
if [ -n "`$MYADMIN ping 2>/dev/null`" ]; then
|
||||
if [ -n "$($MYADMIN ping 2>/dev/null)" ]
|
||||
then
|
||||
stop_server
|
||||
sleep 2
|
||||
fi
|
||||
@@ -51,7 +62,8 @@ esac
|
||||
# - Remove the mysql user only after all his owned files are purged.
|
||||
# - Cleanup the initscripts only if this was the last provider of them
|
||||
#
|
||||
if [ "$1" = "purge" ] && [ -f "/var/lib/mysql/debian-__MARIADB_MAJOR_VER__.flag" ]; then
|
||||
if [ "$1" = "purge" ] && [ -f "/var/lib/mysql/debian-__MARIADB_MAJOR_VER__.flag" ]
|
||||
then
|
||||
# we remove the mysql user only after all his owned files are purged
|
||||
rm -f /var/log/mysql.{log,err}{,.0,.[1234567].gz}
|
||||
rm -rf /var/log/mysql
|
||||
@@ -59,7 +71,8 @@ if [ "$1" = "purge" ] && [ -f "/var/lib/mysql/debian-__MARIADB_MAJOR_VER__.flag"
|
||||
db_input high "mariadb-server/postrm_remove_databases" || true
|
||||
db_go || true
|
||||
db_get "mariadb-server/postrm_remove_databases" || true
|
||||
if [ "$RET" = "true" ]; then
|
||||
if [ "$RET" = "true" ]
|
||||
then
|
||||
# never remove the debian.cnf when the databases are still existing
|
||||
# else we ran into big trouble on the next install!
|
||||
rm -f /etc/mysql/debian.cnf
|
||||
@@ -89,6 +102,7 @@ fi
|
||||
#DEBHELPER#
|
||||
|
||||
# Modified dh_systemd_start snippet that's not added automatically
|
||||
if [ -d /run/systemd/system ]; then
|
||||
if [ -d /run/systemd/system ]
|
||||
then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
fi
|
||||
|
||||
58
debian/mariadb-server.preinst
vendored
58
debian/mariadb-server.preinst
vendored
@@ -7,14 +7,20 @@
|
||||
# * <old-preinst> abort-upgrade <new-version>
|
||||
#
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. /usr/share/debconf/confmodule
|
||||
|
||||
# Just kill the invalid insserv.conf.d directory without fallback
|
||||
if [ -d "/etc/insserv.conf.d/mariadb/" ]; then
|
||||
if [ -d "/etc/insserv.conf.d/mariadb/" ]
|
||||
then
|
||||
rm -rf "/etc/insserv.conf.d/mariadb/"
|
||||
fi
|
||||
|
||||
if [ -n "$DEBIAN_SCRIPT_DEBUG" ]; then set -v -x; DEBIAN_SCRIPT_TRACE=1; fi
|
||||
if [ -n "$DEBIAN_SCRIPT_DEBUG" ]
|
||||
then
|
||||
set -v -x
|
||||
DEBIAN_SCRIPT_TRACE=1
|
||||
fi
|
||||
${DEBIAN_SCRIPT_TRACE:+ echo "#42#DEBUG# RUNNING $0 $*" 1>&2 }
|
||||
|
||||
export PATH=$PATH:/sbin:/usr/sbin:/bin:/usr/bin
|
||||
@@ -28,7 +34,10 @@ stop_server() {
|
||||
# Return immediately if there are no mysqld processes running on a host
|
||||
# (leave containerized processes with the same name in other namespaces)
|
||||
# as there is no point in trying to shutdown in that case.
|
||||
if ! pgrep -x --nslist pid --ns $$ "mysqld|mariadbd" > /dev/null; then return; fi
|
||||
if ! pgrep -x --nslist pid --ns $$ "mysqld|mariadbd" > /dev/null
|
||||
then
|
||||
return
|
||||
fi
|
||||
|
||||
set +e
|
||||
invoke-rc.d mariadb stop
|
||||
@@ -37,7 +46,8 @@ stop_server() {
|
||||
set -e
|
||||
|
||||
# systemctl could emit exit code 100=no init script (fresh install)
|
||||
if [ "$errno" != 0 -a "$errno" != 100 ]; then
|
||||
if [ "$errno" != 0 ] && [ "$errno" != 100 ]
|
||||
then
|
||||
echo "Attempt to stop MariaDB/MySQL server returned exitcode $errno" 1>&2
|
||||
echo "There is a MariaDB/MySQL server running, but we failed in our attempts to stop it." 1>&2
|
||||
echo "Stop it yourself and try again!" 1>&2
|
||||
@@ -56,7 +66,7 @@ max_upgradeable_version=5.7
|
||||
# Check if a flag file is found that indicates a previous MariaDB or MySQL
|
||||
# version was installed. If multiple flags are found, check which one was
|
||||
# the biggest version number.
|
||||
for flag in $mysql_datadir/debian-*.flag
|
||||
for flag in "$mysql_datadir"/debian-*.flag
|
||||
do
|
||||
|
||||
# The for loop leaves $flag as the query string if there are no results,
|
||||
@@ -91,7 +101,7 @@ done
|
||||
# Downgrade is detected if the flag version is bigger than $this_version
|
||||
# (e.g. 10.1 > 10.0) or the flag version is smaller than 10.0 but bigger
|
||||
# than $max_upgradeable_version.
|
||||
if [ ! -z "$found_version" ]
|
||||
if [ -n "$found_version" ]
|
||||
then
|
||||
|
||||
# MySQL 8.0 in Ubuntu has a bug in packaging and the file is name wrongly
|
||||
@@ -133,7 +143,7 @@ fi
|
||||
|
||||
# Don't abort dpkg if downgrade is detected (as was done previously).
|
||||
# Instead simply move the old datadir and create a new for this_version.
|
||||
if [ ! -z "$downgrade_detected" ]
|
||||
if [ -n "$downgrade_detected" ]
|
||||
then
|
||||
db_input critical "mariadb-server/old_data_directory_saved" || true
|
||||
db_go
|
||||
@@ -154,7 +164,8 @@ stop_server
|
||||
# If we use NIS then errors should be tolerated. It's up to the
|
||||
# user to ensure that the mysql user is correctly setup.
|
||||
# Beware that there are two ypwhich one of them needs the 2>/dev/null!
|
||||
if test -n "$(which ypwhich 2>/dev/null)" && ypwhich >/dev/null 2>&1; then
|
||||
if test -n "$(which ypwhich 2>/dev/null)" && ypwhich >/dev/null 2>&1
|
||||
then
|
||||
set +e
|
||||
fi
|
||||
|
||||
@@ -169,13 +180,15 @@ fi
|
||||
#
|
||||
|
||||
# creating mysql group if he isn't already there
|
||||
if ! getent group mysql >/dev/null; then
|
||||
if ! getent group mysql >/dev/null
|
||||
then
|
||||
# Adding system group: mysql.
|
||||
addgroup --system mysql >/dev/null
|
||||
fi
|
||||
|
||||
# creating mysql user if he isn't already there
|
||||
if ! getent passwd mysql >/dev/null; then
|
||||
if ! getent passwd mysql >/dev/null
|
||||
then
|
||||
# Adding system user: mysql.
|
||||
adduser \
|
||||
--system \
|
||||
@@ -193,7 +206,8 @@ set -e
|
||||
|
||||
# if there's a symlink, let's store where it's pointing, because otherwise
|
||||
# it's going to be lost in some situations
|
||||
for dir in DATADIR LOGDIR; do
|
||||
for dir in DATADIR LOGDIR
|
||||
do
|
||||
checkdir=$(eval echo "$"$dir)
|
||||
if [ -L "$checkdir" ]; then
|
||||
# Use mkdir option 'Z' to create with correct SELinux context.
|
||||
@@ -203,18 +217,29 @@ for dir in DATADIR LOGDIR; do
|
||||
done
|
||||
|
||||
# creating mysql home directory
|
||||
if [ ! -d $mysql_datadir ] && [ ! -L $mysql_datadir ]; then
|
||||
if [ ! -d $mysql_datadir ] && [ ! -L $mysql_datadir ]
|
||||
then
|
||||
# Use mkdir option 'Z' to create with correct SELinux context.
|
||||
mkdir -Z $mysql_datadir
|
||||
fi
|
||||
|
||||
# As preset blocksize of GNU df is 1024 then available bytes is $df_available_blocks * 1024
|
||||
# 4096 blocks is then lower than 4 MB
|
||||
df_available_blocks="$(LC_ALL=C BLOCKSIZE='' df --output=avail "$mysql_datadir" | tail -n 1)"
|
||||
if [ "$df_available_blocks" -lt "4096" ]; then
|
||||
# Check if MariaDB datadir is available if not fails.
|
||||
# There should be symlink or directory available or something will fail.
|
||||
if [ -d "$mysql_datadir" ] || [ -L "$mysql_datadir" ]
|
||||
then
|
||||
# As preset blocksize of GNU df is 1024 then available bytes is $df_available_blocks * 1024
|
||||
# 4096 blocks is then lower than 4 MB
|
||||
df_available_blocks="$(LC_ALL=C BLOCKSIZE='' df --output=avail "$mysql_datadir" | tail -n 1)"
|
||||
if [ "$df_available_blocks" -lt "4096" ]
|
||||
then
|
||||
echo "ERROR: There's not enough space in $mysql_datadir/" 1>&2
|
||||
db_stop
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "ERROR: There's no directory or symlink available: $mysql_datadir/" 1>&2
|
||||
db_stop
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Since the home directory was created before putting the user into
|
||||
@@ -230,7 +255,6 @@ find $mysql_datadir -follow -not -group mysql -print0 2>/dev/null \
|
||||
| xargs -0 --no-run-if-empty chgrp mysql
|
||||
set -e
|
||||
|
||||
|
||||
db_stop
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
8
debian/mariadb-server.prerm
vendored
8
debian/mariadb-server.prerm
vendored
@@ -4,9 +4,11 @@ set -e
|
||||
#DEBHELPER#
|
||||
|
||||
# Modified dh_systemd_start snippet that's not added automatically
|
||||
if [ -d /run/systemd/system ]; then
|
||||
if [ -d /run/systemd/system ]
|
||||
then
|
||||
deb-systemd-invoke stop mariadb.service >/dev/null
|
||||
# Modified dh_installinit snippet to only run with sysvinit
|
||||
elif [ -x "/etc/init.d/mariadb" ]; then
|
||||
# Modified dh_installinit snippet to only run with sysvinit
|
||||
elif [ -x "/etc/init.d/mariadb" ]
|
||||
then
|
||||
invoke-rc.d mariadb stop || exit $?
|
||||
fi
|
||||
|
||||
1
debian/mariadb-test.install
vendored
1
debian/mariadb-test.install
vendored
@@ -26,6 +26,7 @@ usr/lib/mysql/plugin/qa_auth_interface.so
|
||||
usr/lib/mysql/plugin/qa_auth_server.so
|
||||
usr/lib/mysql/plugin/test_sql_service.so
|
||||
usr/lib/mysql/plugin/test_versioning.so
|
||||
usr/lib/mysql/plugin/type_mysql_timestamp.so
|
||||
usr/share/man/man1/mariadb-client-test-embedded.1
|
||||
usr/share/man/man1/mariadb-client-test.1
|
||||
usr/share/man/man1/mariadb-test-embedded.1
|
||||
|
||||
@@ -849,26 +849,48 @@ void mdl_lock_all()
|
||||
|
||||
|
||||
// Convert non-null terminated filename to space name
|
||||
// Note that in 10.6 the filename may be an undo file name
|
||||
static std::string filename_to_spacename(const void *filename, size_t len)
|
||||
{
|
||||
// null- terminate filename
|
||||
char *f = (char *)malloc(len + 1);
|
||||
ut_a(f);
|
||||
memcpy(f, filename, len);
|
||||
f[len] = 0;
|
||||
char f[FN_REFLEN];
|
||||
char *p= 0, *table, *db;
|
||||
DBUG_ASSERT(len < FN_REFLEN);
|
||||
|
||||
strmake(f, (const char*) filename, len);
|
||||
|
||||
#ifdef _WIN32
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
if (f[i] == '\\')
|
||||
f[i] = '/';
|
||||
char *p = strrchr(f, '.');
|
||||
ut_a(p);
|
||||
*p = 0;
|
||||
char *table = strrchr(f, '/');
|
||||
ut_a(table);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Remove extension, if exists */
|
||||
if (!(p= strrchr(f, '.')))
|
||||
goto err;
|
||||
*p= 0;
|
||||
|
||||
/* Find table name */
|
||||
if (!(table= strrchr(f, '/')))
|
||||
goto err;
|
||||
*table = 0;
|
||||
char *db = strrchr(f, '/');
|
||||
|
||||
/* Find database name */
|
||||
db= strrchr(f, '/');
|
||||
*table = '/';
|
||||
std::string s(db ? db+1 : f);
|
||||
free(f);
|
||||
if (!db)
|
||||
goto err;
|
||||
{
|
||||
std::string s(db+1);
|
||||
return s;
|
||||
}
|
||||
|
||||
err:
|
||||
/* Not a database/table. Return original (converted) name */
|
||||
if (p)
|
||||
*p= '.'; // Restore removed extension
|
||||
std::string s(f);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -3137,7 +3159,7 @@ static bool xtrabackup_copy_logfile()
|
||||
if (log_sys.buf[recv_sys.offset] <= 1)
|
||||
break;
|
||||
|
||||
if (recv_sys.parse_mtr(STORE_NO) == recv_sys_t::OK)
|
||||
if (recv_sys.parse_mtr<false>(false) == recv_sys_t::OK)
|
||||
{
|
||||
do
|
||||
{
|
||||
@@ -3147,7 +3169,7 @@ static bool xtrabackup_copy_logfile()
|
||||
sequence_offset));
|
||||
*seq= 1;
|
||||
}
|
||||
while ((r= recv_sys.parse_mtr(STORE_NO)) == recv_sys_t::OK);
|
||||
while ((r= recv_sys.parse_mtr<false>(false)) == recv_sys_t::OK);
|
||||
|
||||
if (ds_write(dst_log_file, log_sys.buf + start_offset,
|
||||
recv_sys.offset - start_offset))
|
||||
|
||||
@@ -249,14 +249,15 @@ static inline void lex_string_set3(LEX_CSTRING *lex_str, const char *c_str,
|
||||
*/
|
||||
static inline int safe_strcpy(char *dst, size_t dst_size, const char *src)
|
||||
{
|
||||
memset(dst, '\0', dst_size);
|
||||
strncpy(dst, src, dst_size - 1);
|
||||
/*
|
||||
If the first condition is true, we are guaranteed to have src length
|
||||
>= (dst_size - 1), hence safe to access src[dst_size - 1].
|
||||
*/
|
||||
if (dst[dst_size - 2] != '\0' && src[dst_size - 1] != '\0')
|
||||
return 1; /* Truncation of src. */
|
||||
DBUG_ASSERT(dst_size > 0);
|
||||
/* Note, strncpy will zerofill end of dst if src shorter than dst_size */
|
||||
strncpy(dst, src, dst_size);
|
||||
if (dst[dst_size-1])
|
||||
{
|
||||
/* Ensure string is zero terminated */
|
||||
dst[dst_size-1]= 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ typedef struct st_myrg_info
|
||||
ulong cache_size;
|
||||
uint merge_insert_method;
|
||||
uint tables,options,reclength,keys;
|
||||
uint key_parts;
|
||||
my_bool cache_in_use;
|
||||
/* If MERGE children attached to parent. See top comment in ha_myisammrg.cc */
|
||||
my_bool children_attached;
|
||||
|
||||
@@ -48,6 +48,7 @@ extern "C" {
|
||||
#define MYSQL_AUDIT_GENERAL_ERROR 1
|
||||
#define MYSQL_AUDIT_GENERAL_RESULT 2
|
||||
#define MYSQL_AUDIT_GENERAL_STATUS 3
|
||||
#define MYSQL_AUDIT_GENERAL_WARNING 4
|
||||
|
||||
struct mysql_event_general
|
||||
{
|
||||
|
||||
@@ -57,6 +57,7 @@ extern struct wsrep_service_st {
|
||||
my_bool (*wsrep_on_func)(const MYSQL_THD thd);
|
||||
bool (*wsrep_prepare_key_for_innodb_func)(MYSQL_THD thd, const unsigned char*, size_t, const unsigned char*, size_t, struct wsrep_buf*, size_t*);
|
||||
void (*wsrep_thd_LOCK_func)(const MYSQL_THD thd);
|
||||
int (*wsrep_thd_TRYLOCK_func)(const MYSQL_THD thd);
|
||||
void (*wsrep_thd_UNLOCK_func)(const MYSQL_THD thd);
|
||||
const char * (*wsrep_thd_query_func)(const MYSQL_THD thd);
|
||||
int (*wsrep_thd_retry_counter_func)(const MYSQL_THD thd);
|
||||
@@ -89,7 +90,6 @@ extern struct wsrep_service_st {
|
||||
ulong (*wsrep_OSU_method_get_func)(const MYSQL_THD thd);
|
||||
my_bool (*wsrep_thd_has_ignored_error_func)(const MYSQL_THD thd);
|
||||
void (*wsrep_thd_set_ignored_error_func)(MYSQL_THD thd, my_bool val);
|
||||
bool (*wsrep_thd_set_wsrep_aborter_func)(MYSQL_THD bf_thd, MYSQL_THD thd);
|
||||
void (*wsrep_report_bf_lock_wait_func)(const MYSQL_THD thd,
|
||||
unsigned long long trx_id);
|
||||
void (*wsrep_thd_kill_LOCK_func)(const MYSQL_THD thd);
|
||||
@@ -111,6 +111,7 @@ extern struct wsrep_service_st {
|
||||
#define wsrep_on(thd) (thd) && WSREP_ON && wsrep_service->wsrep_on_func(thd)
|
||||
#define wsrep_prepare_key_for_innodb(A,B,C,D,E,F,G) wsrep_service->wsrep_prepare_key_for_innodb_func(A,B,C,D,E,F,G)
|
||||
#define wsrep_thd_LOCK(T) wsrep_service->wsrep_thd_LOCK_func(T)
|
||||
#define wsrep_thd_TRYLOCK(T) wsrep_service->wsrep_thd_TRYLOCK_func(T)
|
||||
#define wsrep_thd_UNLOCK(T) wsrep_service->wsrep_thd_UNLOCK_func(T)
|
||||
#define wsrep_thd_kill_LOCK(T) wsrep_service->wsrep_thd_kill_LOCK_func(T)
|
||||
#define wsrep_thd_kill_UNLOCK(T) wsrep_service->wsrep_thd_kill_UNLOCK_func(T)
|
||||
@@ -141,7 +142,6 @@ extern struct wsrep_service_st {
|
||||
#define wsrep_OSU_method_get(T) wsrep_service->wsrep_OSU_method_get_func(T)
|
||||
#define wsrep_thd_has_ignored_error(T) wsrep_service->wsrep_thd_has_ignored_error_func(T)
|
||||
#define wsrep_thd_set_ignored_error(T,V) wsrep_service->wsrep_thd_set_ignored_error_func(T,V)
|
||||
#define wsrep_thd_set_wsrep_aborter(T) wsrep_service->wsrep_thd_set_wsrep_aborter_func(T1, T2)
|
||||
#define wsrep_report_bf_lock_wait(T,I) wsrep_service->wsrep_report_bf_lock_wait(T,I)
|
||||
#define wsrep_thd_set_PA_unsafe(T) wsrep_service->wsrep_thd_set_PA_unsafe_func(T)
|
||||
#else
|
||||
@@ -175,6 +175,8 @@ void wsrep_set_data_home_dir(const char *data_dir);
|
||||
extern "C" my_bool wsrep_on(const MYSQL_THD thd);
|
||||
/* Lock thd wsrep lock */
|
||||
extern "C" void wsrep_thd_LOCK(const MYSQL_THD thd);
|
||||
/* Try thd wsrep lock. Return non-zero if lock could not be taken. */
|
||||
extern "C" int wsrep_thd_TRYLOCK(const MYSQL_THD thd);
|
||||
/* Unlock thd wsrep lock */
|
||||
extern "C" void wsrep_thd_UNLOCK(const MYSQL_THD thd);
|
||||
|
||||
@@ -197,8 +199,6 @@ extern "C" my_bool wsrep_thd_is_local(const MYSQL_THD thd);
|
||||
/* Return true if thd is in high priority mode */
|
||||
/* todo: rename to is_high_priority() */
|
||||
extern "C" my_bool wsrep_thd_is_applying(const MYSQL_THD thd);
|
||||
/* set wsrep_aborter for the target THD */
|
||||
extern "C" bool wsrep_thd_set_wsrep_aborter(MYSQL_THD bf_thd, MYSQL_THD victim_thd);
|
||||
/* Return true if thd is in TOI mode */
|
||||
extern "C" my_bool wsrep_thd_is_toi(const MYSQL_THD thd);
|
||||
/* Return true if thd is in replicating TOI mode */
|
||||
@@ -249,7 +249,6 @@ extern "C" my_bool wsrep_thd_is_applying(const MYSQL_THD thd);
|
||||
extern "C" ulong wsrep_OSU_method_get(const MYSQL_THD thd);
|
||||
extern "C" my_bool wsrep_thd_has_ignored_error(const MYSQL_THD thd);
|
||||
extern "C" void wsrep_thd_set_ignored_error(MYSQL_THD thd, my_bool val);
|
||||
extern "C" bool wsrep_thd_set_wsrep_aborter(MYSQL_THD bf_thd, MYSQL_THD victim_thd);
|
||||
extern "C" void wsrep_report_bf_lock_wait(const THD *thd,
|
||||
unsigned long long trx_id);
|
||||
/* declare parallel applying unsafety for the THD */
|
||||
|
||||
@@ -34,7 +34,7 @@ use strict;
|
||||
|
||||
use Exporter;
|
||||
use base "Exporter";
|
||||
our @EXPORT= qw /rmtree mkpath copytree/;
|
||||
our @EXPORT= qw /rmtree mkpath copytree make_readonly/;
|
||||
|
||||
use File::Find;
|
||||
use File::Copy;
|
||||
@@ -184,6 +184,10 @@ sub copytree {
|
||||
# Only copy plain files
|
||||
next unless -f "$from_dir/$_";
|
||||
copy("$from_dir/$_", "$to_dir/$_");
|
||||
if (!$use_umask)
|
||||
{
|
||||
chmod(0666, "$to_dir/$_");
|
||||
}
|
||||
}
|
||||
closedir(DIR);
|
||||
|
||||
@@ -193,4 +197,29 @@ sub copytree {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub make_readonly {
|
||||
my ($dir) = @_;
|
||||
|
||||
die "Usage: make_readonly(<dir>])"
|
||||
unless @_ == 1;
|
||||
|
||||
opendir(DIR, "$dir")
|
||||
or croak("Can't find $dir$!");
|
||||
for(readdir(DIR)) {
|
||||
|
||||
next if "$_" eq "." or "$_" eq "..";
|
||||
|
||||
if ( -d "$dir/$_" )
|
||||
{
|
||||
make_readonly("$dir/$_");
|
||||
next;
|
||||
}
|
||||
|
||||
# Only copy plain files
|
||||
next unless -f "$dir/$_";
|
||||
chmod 0444, "$dir/$_";
|
||||
}
|
||||
closedir(DIR);
|
||||
}
|
||||
1;
|
||||
|
||||
@@ -40,7 +40,7 @@ our @EXPORT= qw(create_process);
|
||||
# Retry a couple of times if fork returns EAGAIN
|
||||
#
|
||||
sub _safe_fork {
|
||||
my $retries= 5;
|
||||
my $retries= 100;
|
||||
my $pid;
|
||||
|
||||
FORK:
|
||||
|
||||
@@ -470,7 +470,7 @@ t1 CREATE TABLE `t1` (
|
||||
KEY `a126_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`),
|
||||
KEY `a127_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`),
|
||||
KEY `a128_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
flush tables;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
@@ -619,7 +619,7 @@ t1 CREATE TABLE `t1` (
|
||||
KEY `a126_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`),
|
||||
KEY `a127_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`),
|
||||
KEY `a128_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
drop table t1;
|
||||
create table t1 (c1 int, c2 int, c3 int, c4 int, c5 int, c6 int, c7 int,
|
||||
c8 int, c9 int, c10 int, c11 int, c12 int, c13 int, c14 int, c15 int, c16 int);
|
||||
@@ -1092,7 +1092,7 @@ t1 CREATE TABLE `t1` (
|
||||
KEY `a126_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`),
|
||||
KEY `a127_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`),
|
||||
KEY `a128_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
flush tables;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
@@ -1241,7 +1241,7 @@ t1 CREATE TABLE `t1` (
|
||||
KEY `a126_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`),
|
||||
KEY `a127_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`),
|
||||
KEY `a128_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
alter table t1 add key
|
||||
a129_long_123456789_123456789_123456789_123456789_123456789_1234 (
|
||||
c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16);
|
||||
|
||||
@@ -1161,3 +1161,27 @@ explain select * from t1 limit 0 offset 10;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Zero limit
|
||||
drop table t1, t2;
|
||||
#
|
||||
# MDEV-28285 Unexpected result when combining DISTINCT, subselect
|
||||
# and LIMIT
|
||||
#
|
||||
create table t1 (a int primary key);
|
||||
create table t2 (a int primary key, b int not null);
|
||||
insert into t1 select seq from seq_1_to_10;
|
||||
insert into t2 select seq,seq from seq_1_to_10;
|
||||
select distinct a from t1 where t1.a=1 and t1.a in (select a from t2 where t2.b in (1,2));
|
||||
a
|
||||
1
|
||||
explain select distinct a from t1 where t1.a=1 and t1.a in (select a+0 from t2 where t2.b in (1,2)) limit 10,10;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using index; Using temporary
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where; FirstMatch(t1)
|
||||
select distinct a from t1 where t1.a=1 and t1.a in (select a+0 from t2 where t2.b in (1,2)) limit 10,10;
|
||||
a
|
||||
select distinct a from t1 where t1.a=1 and t1.a in (select a+0 from t2 where t2.b in (1,2)) limit 0,1;
|
||||
a
|
||||
1
|
||||
drop table t1,t2;
|
||||
#
|
||||
# end of 10.5 tests
|
||||
#
|
||||
|
||||
@@ -893,3 +893,24 @@ explain select * from t1 limit 0;
|
||||
explain select * from t1 limit 0 offset 10;
|
||||
|
||||
drop table t1, t2;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-28285 Unexpected result when combining DISTINCT, subselect
|
||||
--echo # and LIMIT
|
||||
--echo #
|
||||
|
||||
create table t1 (a int primary key);
|
||||
create table t2 (a int primary key, b int not null);
|
||||
|
||||
insert into t1 select seq from seq_1_to_10;
|
||||
insert into t2 select seq,seq from seq_1_to_10;
|
||||
|
||||
select distinct a from t1 where t1.a=1 and t1.a in (select a from t2 where t2.b in (1,2));
|
||||
explain select distinct a from t1 where t1.a=1 and t1.a in (select a+0 from t2 where t2.b in (1,2)) limit 10,10;
|
||||
select distinct a from t1 where t1.a=1 and t1.a in (select a+0 from t2 where t2.b in (1,2)) limit 10,10;
|
||||
select distinct a from t1 where t1.a=1 and t1.a in (select a+0 from t2 where t2.b in (1,2)) limit 0,1;
|
||||
drop table t1,t2;
|
||||
|
||||
--echo #
|
||||
--echo # end of 10.5 tests
|
||||
--echo #
|
||||
|
||||
@@ -2578,5 +2578,29 @@ SELECT JSON_EXTRACT('{ "my-key": 1 }', '$.my-key');
|
||||
JSON_EXTRACT('{ "my-key": 1 }', '$.my-key')
|
||||
1
|
||||
#
|
||||
# MDEV-23187: Assorted assertion failures in json_find_path with certain collations
|
||||
#
|
||||
SET @save_collation_connection= @@collation_connection;
|
||||
SET @json='{ "A": [ [{"k":"v"},[1]],true],"B": {"C": 1} }';
|
||||
SELECT JSON_VALUE(@json,'$.A[last-1][last-1].key1');
|
||||
JSON_VALUE(@json,'$.A[last-1][last-1].key1')
|
||||
NULL
|
||||
SET @json='{ "A": [ [{"k":"v"},[1]],true],"B": {"C": 1} }';
|
||||
SET collation_connection='ucs2_bin';
|
||||
SELECT JSON_VALUE(@json,'$.A[last-1][last-1].key1');
|
||||
JSON_VALUE(@json,'$.A[last-1][last-1].key1')
|
||||
NULL
|
||||
SET @json='{ "A": [ [{"k":"v"},[15]],true],"B": {"C": 1} }';
|
||||
SET sql_mode=0,character_set_connection=utf32;
|
||||
SELECT JSON_VALUE(@json,'$.A[last-1][last-1].key1');
|
||||
JSON_VALUE(@json,'$.A[last-1][last-1].key1')
|
||||
NULL
|
||||
SET @json='{ "A": [ [{"k":"v"},[15]],true],"B": {"C": 1} }';
|
||||
SET sql_mode=0,character_set_connection=utf32;
|
||||
SELECT JSON_VALUE(@json,'$.A[last-1][last-1].key1');
|
||||
JSON_VALUE(@json,'$.A[last-1][last-1].key1')
|
||||
NULL
|
||||
SET @@collation_connection= @save_collation_connection;
|
||||
#
|
||||
# End of 10.9 Test
|
||||
#
|
||||
|
||||
@@ -1772,6 +1772,32 @@ DROP TABLE t1;
|
||||
SELECT JSON_EXTRACT('{ "my-key": 1 }', '$."my-key"');
|
||||
SELECT JSON_EXTRACT('{ "my-key": 1 }', '$.my-key');
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-23187: Assorted assertion failures in json_find_path with certain collations
|
||||
--echo #
|
||||
|
||||
|
||||
SET @save_collation_connection= @@collation_connection;
|
||||
|
||||
SET @json='{ "A": [ [{"k":"v"},[1]],true],"B": {"C": 1} }';
|
||||
SELECT JSON_VALUE(@json,'$.A[last-1][last-1].key1');
|
||||
|
||||
SET @json='{ "A": [ [{"k":"v"},[1]],true],"B": {"C": 1} }';
|
||||
SET collation_connection='ucs2_bin';
|
||||
SELECT JSON_VALUE(@json,'$.A[last-1][last-1].key1');
|
||||
|
||||
SET @json='{ "A": [ [{"k":"v"},[15]],true],"B": {"C": 1} }';
|
||||
SET sql_mode=0,character_set_connection=utf32;
|
||||
SELECT JSON_VALUE(@json,'$.A[last-1][last-1].key1');
|
||||
|
||||
|
||||
SET @json='{ "A": [ [{"k":"v"},[15]],true],"B": {"C": 1} }';
|
||||
SET sql_mode=0,character_set_connection=utf32;
|
||||
SELECT JSON_VALUE(@json,'$.A[last-1][last-1].key1');
|
||||
|
||||
SET @@collation_connection= @save_collation_connection;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.9 Test
|
||||
--echo #
|
||||
|
||||
@@ -434,7 +434,7 @@ create table t1 as select sformat(_ucs2 x'003D007B007D003D', _ucs2 x'04420435044
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`x` varchar(8) CHARACTER SET ucs2 COLLATE ucs2_general_ci DEFAULT NULL
|
||||
`x` longtext CHARACTER SET ucs2 COLLATE ucs2_general_ci DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
drop table t1;
|
||||
set names latin1;
|
||||
@@ -468,3 +468,26 @@ set names latin1;
|
||||
#
|
||||
# End of 10.7 tests
|
||||
#
|
||||
#
|
||||
# Start of 10.8 tests
|
||||
#
|
||||
#
|
||||
# MDEV-29646 sformat('Num [{:20}]', 42) gives incorrect result in view
|
||||
#
|
||||
create view v1 as select sformat('Num [{:20}]', 42);
|
||||
select * from v1;
|
||||
sformat('Num [{:20}]', 42)
|
||||
Num [ 42]
|
||||
drop view v1;
|
||||
create view v1 as SELECT sformat('Square root of [{:d}] is [{:.20}]', 2, sqrt(2));
|
||||
select * from v1;
|
||||
sformat('Square root of [{:d}] is [{:.20}]', 2, sqrt(2))
|
||||
Square root of [2] is [1.4142135623730951455]
|
||||
drop view v1;
|
||||
create table t1 (a text, b int, c text);
|
||||
insert t1 values ('[{} -> {}]', 10, '{}'), ('[{:20} <- {}]', 1, '{:30}');
|
||||
select sformat(a,b,c) from t1;
|
||||
sformat(a,b,c)
|
||||
[10 -> {}]
|
||||
[ 1 <- {:30}]
|
||||
drop table t1;
|
||||
|
||||
@@ -253,3 +253,24 @@ set names latin1;
|
||||
echo #;
|
||||
echo # End of 10.7 tests;
|
||||
echo #;
|
||||
|
||||
echo #;
|
||||
echo # Start of 10.8 tests;
|
||||
echo #;
|
||||
|
||||
echo #;
|
||||
echo # MDEV-29646 sformat('Num [{:20}]', 42) gives incorrect result in view;
|
||||
echo #;
|
||||
|
||||
create view v1 as select sformat('Num [{:20}]', 42);
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
|
||||
create view v1 as SELECT sformat('Square root of [{:d}] is [{:.20}]', 2, sqrt(2));
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
|
||||
create table t1 (a text, b int, c text);
|
||||
insert t1 values ('[{} -> {}]', 10, '{}'), ('[{:20} <- {}]', 1, '{:30}');
|
||||
select sformat(a,b,c) from t1;
|
||||
drop table t1;
|
||||
|
||||
@@ -4129,6 +4129,140 @@ MIN(pk) a
|
||||
5 10
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-6768 Wrong result with agregate with join with no resultset
|
||||
#
|
||||
create table t1
|
||||
(
|
||||
PARENT_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
PARENT_FIELD VARCHAR(10),
|
||||
PRIMARY KEY (PARENT_ID)
|
||||
) engine=innodb;
|
||||
create table t2
|
||||
(
|
||||
CHILD_ID INT NOT NULL AUTO_INCREMENT,
|
||||
PARENT_ID INT NOT NULL,
|
||||
CHILD_FIELD varchar(10),
|
||||
PRIMARY KEY (CHILD_ID)
|
||||
)engine=innodb;
|
||||
INSERT INTO t1 (PARENT_FIELD)
|
||||
SELECT 'AAAA';
|
||||
INSERT INTO t2 (PARENT_ID, CHILD_FIELD)
|
||||
SELECT 1, 'BBBB';
|
||||
explain select
|
||||
t1.PARENT_ID,
|
||||
min(CHILD_FIELD)
|
||||
from t1 straight_join t2
|
||||
where t1.PARENT_ID = 1
|
||||
and t1.PARENT_ID = t2.PARENT_ID
|
||||
and t2.CHILD_FIELD = "ZZZZ";
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where
|
||||
select
|
||||
t1.PARENT_ID,
|
||||
min(CHILD_FIELD)
|
||||
from t1 straight_join t2
|
||||
where t1.PARENT_ID = 1
|
||||
and t1.PARENT_ID = t2.PARENT_ID
|
||||
and t2.CHILD_FIELD = "ZZZZ";
|
||||
PARENT_ID min(CHILD_FIELD)
|
||||
NULL NULL
|
||||
select
|
||||
1,
|
||||
min(CHILD_FIELD)
|
||||
from t1 straight_join t2
|
||||
where t1.PARENT_ID = 1
|
||||
and t1.PARENT_ID = t2.PARENT_ID
|
||||
and t2.CHILD_FIELD = "ZZZZ";
|
||||
1 min(CHILD_FIELD)
|
||||
1 NULL
|
||||
select
|
||||
IFNULL(t1.PARENT_ID,1),
|
||||
min(CHILD_FIELD)
|
||||
from t1 straight_join t2
|
||||
where t1.PARENT_ID = 1
|
||||
and t1.PARENT_ID = t2.PARENT_ID
|
||||
and t2.CHILD_FIELD = "ZZZZ";
|
||||
IFNULL(t1.PARENT_ID,1) min(CHILD_FIELD)
|
||||
1 NULL
|
||||
# Check that things works with MyISAM (which has different explain)
|
||||
alter table t1 engine=myisam;
|
||||
alter table t2 engine=myisam;
|
||||
explain select
|
||||
t1.PARENT_ID,
|
||||
min(CHILD_FIELD)
|
||||
from t1 straight_join t2
|
||||
where t1.PARENT_ID = 1
|
||||
and t1.PARENT_ID = t2.PARENT_ID
|
||||
and t2.CHILD_FIELD = "ZZZZ";
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
select
|
||||
t1.PARENT_ID,
|
||||
min(CHILD_FIELD)
|
||||
from t1 straight_join t2
|
||||
where t1.PARENT_ID = 1
|
||||
and t1.PARENT_ID = t2.PARENT_ID
|
||||
and t2.CHILD_FIELD = "ZZZZ";
|
||||
PARENT_ID min(CHILD_FIELD)
|
||||
NULL NULL
|
||||
drop table t1,t2;
|
||||
# Check that things works if sub queries are re-executed
|
||||
create table t1 (a int primary key, b int);
|
||||
create table t2 (a int primary key, b int);
|
||||
create table t3 (a int primary key, b int);
|
||||
insert into t1 values (1,1),(2,2),(3,3);
|
||||
insert into t2 values (1,1),(2,2),(3,3);
|
||||
insert into t3 values (1,1),(3,3);
|
||||
explain
|
||||
select *,
|
||||
(select
|
||||
CONCAT('t2:', IFNULL(t2.a, 't2a-null'), ';',
|
||||
'min_t3_b:', IFNULL(min(t3.b), 't3b-null'))
|
||||
from t2,t3
|
||||
where t2.a=1 and t1.b = t3.a) as s1
|
||||
from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
|
||||
2 DEPENDENT SUBQUERY t2 const PRIMARY PRIMARY 4 const 1 Using index
|
||||
2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1
|
||||
select *,
|
||||
(select
|
||||
CONCAT('t2:', IFNULL(t2.a, 't2a-null'), ';',
|
||||
'min_t3_b:', IFNULL(min(t3.b), 't3b-null'))
|
||||
from t2,t3
|
||||
where t2.a=1 and t1.b = t3.a) as s1
|
||||
from t1;
|
||||
a b s1
|
||||
1 1 t2:1;min_t3_b:1
|
||||
2 2 t2:t2a-null;min_t3_b:t3b-null
|
||||
3 3 t2:1;min_t3_b:3
|
||||
drop table t1,t2,t3;
|
||||
#
|
||||
# MDEV-31380: Assertion `s->table->opt_range_condition_rows <= s->found_records' failed
|
||||
# (assertion in 10.6+, DBL_MAX costs in 10.5)
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY(a), KEY(b)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 SELECT seq, seq FROM seq_1_to_100;
|
||||
SET
|
||||
@tmp=@@optimizer_use_condition_selectivity,
|
||||
optimizer_use_condition_selectivity = 1,
|
||||
@tmp2=@@optimizer_trace,
|
||||
optimizer_trace=1;
|
||||
SELECT DISTINCT * FROM t1 WHERE a IN (1, 2);
|
||||
a b
|
||||
1 1
|
||||
2 2
|
||||
select
|
||||
CAST(json_value(json_extract(trace, '$**.chosen_access_method.cost'), '$[0]')
|
||||
as DOUBLE) < 1.0e100
|
||||
from information_schema.optimizer_trace;
|
||||
CAST(json_value(json_extract(trace, '$**.chosen_access_method.cost'), '$[0]')
|
||||
as DOUBLE) < 1.0e100
|
||||
1
|
||||
set optimizer_use_condition_selectivity = @tmp, optimizer_trace=@tmp2;
|
||||
drop table t1;
|
||||
#
|
||||
# End of 10.5 tests
|
||||
#
|
||||
#
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
--source include/default_optimizer_switch.inc
|
||||
--source include/have_sequence.inc
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_sequence.inc
|
||||
#
|
||||
# TODO:
|
||||
# Add queries with:
|
||||
@@ -1756,6 +1757,140 @@ SELECT MIN(pk), a FROM t1 WHERE pk <> 1 GROUP BY a;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-6768 Wrong result with agregate with join with no resultset
|
||||
--echo #
|
||||
|
||||
create table t1
|
||||
(
|
||||
PARENT_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
PARENT_FIELD VARCHAR(10),
|
||||
PRIMARY KEY (PARENT_ID)
|
||||
) engine=innodb;
|
||||
|
||||
create table t2
|
||||
(
|
||||
CHILD_ID INT NOT NULL AUTO_INCREMENT,
|
||||
PARENT_ID INT NOT NULL,
|
||||
CHILD_FIELD varchar(10),
|
||||
PRIMARY KEY (CHILD_ID)
|
||||
)engine=innodb;
|
||||
|
||||
INSERT INTO t1 (PARENT_FIELD)
|
||||
SELECT 'AAAA';
|
||||
|
||||
INSERT INTO t2 (PARENT_ID, CHILD_FIELD)
|
||||
SELECT 1, 'BBBB';
|
||||
|
||||
explain select
|
||||
t1.PARENT_ID,
|
||||
min(CHILD_FIELD)
|
||||
from t1 straight_join t2
|
||||
where t1.PARENT_ID = 1
|
||||
and t1.PARENT_ID = t2.PARENT_ID
|
||||
and t2.CHILD_FIELD = "ZZZZ";
|
||||
|
||||
select
|
||||
t1.PARENT_ID,
|
||||
min(CHILD_FIELD)
|
||||
from t1 straight_join t2
|
||||
where t1.PARENT_ID = 1
|
||||
and t1.PARENT_ID = t2.PARENT_ID
|
||||
and t2.CHILD_FIELD = "ZZZZ";
|
||||
|
||||
select
|
||||
1,
|
||||
min(CHILD_FIELD)
|
||||
from t1 straight_join t2
|
||||
where t1.PARENT_ID = 1
|
||||
and t1.PARENT_ID = t2.PARENT_ID
|
||||
and t2.CHILD_FIELD = "ZZZZ";
|
||||
|
||||
select
|
||||
IFNULL(t1.PARENT_ID,1),
|
||||
min(CHILD_FIELD)
|
||||
from t1 straight_join t2
|
||||
where t1.PARENT_ID = 1
|
||||
and t1.PARENT_ID = t2.PARENT_ID
|
||||
and t2.CHILD_FIELD = "ZZZZ";
|
||||
|
||||
|
||||
--echo # Check that things works with MyISAM (which has different explain)
|
||||
|
||||
alter table t1 engine=myisam;
|
||||
alter table t2 engine=myisam;
|
||||
|
||||
explain select
|
||||
t1.PARENT_ID,
|
||||
min(CHILD_FIELD)
|
||||
from t1 straight_join t2
|
||||
where t1.PARENT_ID = 1
|
||||
and t1.PARENT_ID = t2.PARENT_ID
|
||||
and t2.CHILD_FIELD = "ZZZZ";
|
||||
|
||||
select
|
||||
t1.PARENT_ID,
|
||||
min(CHILD_FIELD)
|
||||
from t1 straight_join t2
|
||||
where t1.PARENT_ID = 1
|
||||
and t1.PARENT_ID = t2.PARENT_ID
|
||||
and t2.CHILD_FIELD = "ZZZZ";
|
||||
|
||||
drop table t1,t2;
|
||||
|
||||
--echo # Check that things works if sub queries are re-executed
|
||||
|
||||
create table t1 (a int primary key, b int);
|
||||
create table t2 (a int primary key, b int);
|
||||
create table t3 (a int primary key, b int);
|
||||
|
||||
insert into t1 values (1,1),(2,2),(3,3);
|
||||
insert into t2 values (1,1),(2,2),(3,3);
|
||||
insert into t3 values (1,1),(3,3);
|
||||
|
||||
explain
|
||||
select *,
|
||||
(select
|
||||
CONCAT('t2:', IFNULL(t2.a, 't2a-null'), ';',
|
||||
'min_t3_b:', IFNULL(min(t3.b), 't3b-null'))
|
||||
from t2,t3
|
||||
where t2.a=1 and t1.b = t3.a) as s1
|
||||
from t1;
|
||||
|
||||
select *,
|
||||
(select
|
||||
CONCAT('t2:', IFNULL(t2.a, 't2a-null'), ';',
|
||||
'min_t3_b:', IFNULL(min(t3.b), 't3b-null'))
|
||||
from t2,t3
|
||||
where t2.a=1 and t1.b = t3.a) as s1
|
||||
from t1;
|
||||
|
||||
drop table t1,t2,t3;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-31380: Assertion `s->table->opt_range_condition_rows <= s->found_records' failed
|
||||
--echo # (assertion in 10.6+, DBL_MAX costs in 10.5)
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY(a), KEY(b)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 SELECT seq, seq FROM seq_1_to_100;
|
||||
|
||||
SET
|
||||
@tmp=@@optimizer_use_condition_selectivity,
|
||||
optimizer_use_condition_selectivity = 1,
|
||||
@tmp2=@@optimizer_trace,
|
||||
optimizer_trace=1;
|
||||
|
||||
SELECT DISTINCT * FROM t1 WHERE a IN (1, 2);
|
||||
|
||||
select
|
||||
CAST(json_value(json_extract(trace, '$**.chosen_access_method.cost'), '$[0]')
|
||||
as DOUBLE) < 1.0e100
|
||||
from information_schema.optimizer_trace;
|
||||
|
||||
set optimizer_use_condition_selectivity = @tmp, optimizer_trace=@tmp2;
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.5 tests
|
||||
--echo #
|
||||
|
||||
@@ -608,7 +608,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
#
|
||||
explain select count(*) from t3 as t1,t3 where t1.period=t3.period order by t3.period;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index period period 4 NULL 41810 Using index
|
||||
1 SIMPLE t1 index period period 4 NULL 41810 Using where; Using index
|
||||
1 SIMPLE t3 ref period period 4 test.t1.period 4181 Using index
|
||||
explain select sum(t1.price+t3.price) from t3 as t1,t3 where t1.period=t3.period order by t3.period;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
|
||||
@@ -619,7 +619,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
#
|
||||
explain select count(*) from t3 as t1,t3 where t1.period=t3.period order by t3.period;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index period period 4 NULL 41810 Using index
|
||||
1 SIMPLE t1 index period period 4 NULL 41810 Using where; Using index
|
||||
1 SIMPLE t3 ref period period 4 test.t1.period 4181 Using index
|
||||
explain select sum(t1.price+t3.price) from t3 as t1,t3 where t1.period=t3.period order by t3.period;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
|
||||
@@ -608,7 +608,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
#
|
||||
explain select count(*) from t3 as t1,t3 where t1.period=t3.period order by t3.period;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index period period 4 NULL 41810 Using index
|
||||
1 SIMPLE t1 index period period 4 NULL 41810 Using where; Using index
|
||||
1 SIMPLE t3 ref period period 4 test.t1.period 4181 Using index
|
||||
explain select sum(t1.price+t3.price) from t3 as t1,t3 where t1.period=t3.period order by t3.period;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
|
||||
@@ -1860,7 +1860,6 @@ test.t1 analyze status Table is already up to date
|
||||
test.t2 analyze status Engine-independent statistics collected
|
||||
test.t2 analyze status Table is already up to date
|
||||
set optimizer_switch='exists_to_in=off';
|
||||
set optimizer_use_condition_selectivity=2;
|
||||
SELECT * FROM t1
|
||||
WHERE
|
||||
EXISTS (SELECT * FROM t1 A INNER JOIN t2 ON t2.a = A.id
|
||||
@@ -1885,18 +1884,39 @@ id a
|
||||
17 17
|
||||
18 18
|
||||
19 19
|
||||
explain SELECT * FROM t1
|
||||
set statement optimizer_use_condition_selectivity=2 for explain SELECT * FROM t1
|
||||
WHERE
|
||||
EXISTS (SELECT * FROM t1 A INNER JOIN t2 ON t2.a = A.id
|
||||
WHERE A.a=t1.a AND t2.b < 20);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 100 Using where
|
||||
2 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1
|
||||
2 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
|
||||
EXPLAIN SELECT * FROM t1 A, t1 B WHERE A.a = B.a and A.id = 65;
|
||||
3 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1
|
||||
3 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
|
||||
set statement optimizer_use_condition_selectivity=4 for explain SELECT * FROM t1
|
||||
WHERE
|
||||
EXISTS (SELECT * FROM t1 A INNER JOIN t2 ON t2.a = A.id
|
||||
WHERE A.a=t1.a AND t2.b < 20);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE A const PRIMARY,a PRIMARY 4 const 1
|
||||
1 SIMPLE B ref a a 5 const 1
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 100 Using where
|
||||
3 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1
|
||||
3 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
|
||||
set @query="EXPLAIN SELECT * FROM t1 A, t1 B WHERE A.a = B.a and A.id = 65";
|
||||
set statement optimizer_use_condition_selectivity=2 for explain SELECT * FROM t1
|
||||
WHERE
|
||||
EXISTS (SELECT * FROM t1 A INNER JOIN t2 ON t2.a = A.id
|
||||
WHERE A.a=t1.a AND t2.b < 20);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 100 Using where
|
||||
3 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1
|
||||
3 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
|
||||
set statement optimizer_use_condition_selectivity=4 for explain SELECT * FROM t1
|
||||
WHERE
|
||||
EXISTS (SELECT * FROM t1 A INNER JOIN t2 ON t2.a = A.id
|
||||
WHERE A.a=t1.a AND t2.b < 20);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 100 Using where
|
||||
3 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1
|
||||
3 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
|
||||
explain SELECT * FROM t1
|
||||
WHERE
|
||||
EXISTS (SELECT * FROM t1 A INNER JOIN t2 ON t2.a = A.id
|
||||
@@ -1906,7 +1926,6 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
2 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1
|
||||
2 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
|
||||
set optimizer_switch= @save_optimizer_switch;
|
||||
set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
|
||||
drop table t1,t2;
|
||||
#
|
||||
# MDEV-21495: Conditional jump or move depends on uninitialised value in sel_arg_range_seq_next
|
||||
|
||||
@@ -1262,7 +1262,6 @@ insert into t2 select seq,seq,seq from seq_1_to_100;
|
||||
analyze table t1,t2 persistent for all;
|
||||
|
||||
set optimizer_switch='exists_to_in=off';
|
||||
set optimizer_use_condition_selectivity=2;
|
||||
|
||||
let $query= SELECT * FROM t1
|
||||
WHERE
|
||||
@@ -1270,14 +1269,16 @@ let $query= SELECT * FROM t1
|
||||
WHERE A.a=t1.a AND t2.b < 20);
|
||||
|
||||
eval $query;
|
||||
eval explain $query;
|
||||
eval set statement optimizer_use_condition_selectivity=2 for explain $query;
|
||||
eval set statement optimizer_use_condition_selectivity=4 for explain $query;
|
||||
|
||||
EXPLAIN SELECT * FROM t1 A, t1 B WHERE A.a = B.a and A.id = 65;
|
||||
set @query="EXPLAIN SELECT * FROM t1 A, t1 B WHERE A.a = B.a and A.id = 65";
|
||||
eval set statement optimizer_use_condition_selectivity=2 for explain $query;
|
||||
eval set statement optimizer_use_condition_selectivity=4 for explain $query;
|
||||
|
||||
eval explain $query;
|
||||
|
||||
set optimizer_switch= @save_optimizer_switch;
|
||||
set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
|
||||
drop table t1,t2;
|
||||
|
||||
--echo #
|
||||
|
||||
@@ -1867,7 +1867,6 @@ test.t1 analyze status OK
|
||||
test.t2 analyze status Engine-independent statistics collected
|
||||
test.t2 analyze status OK
|
||||
set optimizer_switch='exists_to_in=off';
|
||||
set optimizer_use_condition_selectivity=2;
|
||||
SELECT * FROM t1
|
||||
WHERE
|
||||
EXISTS (SELECT * FROM t1 A INNER JOIN t2 ON t2.a = A.id
|
||||
@@ -1892,18 +1891,39 @@ id a
|
||||
17 17
|
||||
18 18
|
||||
19 19
|
||||
explain SELECT * FROM t1
|
||||
set statement optimizer_use_condition_selectivity=2 for explain SELECT * FROM t1
|
||||
WHERE
|
||||
EXISTS (SELECT * FROM t1 A INNER JOIN t2 ON t2.a = A.id
|
||||
WHERE A.a=t1.a AND t2.b < 20);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index NULL a 5 NULL 100 Using where; Using index
|
||||
2 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1 Using index
|
||||
2 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
|
||||
EXPLAIN SELECT * FROM t1 A, t1 B WHERE A.a = B.a and A.id = 65;
|
||||
3 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1 Using index
|
||||
3 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
|
||||
set statement optimizer_use_condition_selectivity=4 for explain SELECT * FROM t1
|
||||
WHERE
|
||||
EXISTS (SELECT * FROM t1 A INNER JOIN t2 ON t2.a = A.id
|
||||
WHERE A.a=t1.a AND t2.b < 20);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE A const PRIMARY,a PRIMARY 4 const 1
|
||||
1 SIMPLE B ref a a 5 const 1 Using index
|
||||
1 PRIMARY t1 index NULL a 5 NULL 100 Using where; Using index
|
||||
3 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1 Using index
|
||||
3 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
|
||||
set @query="EXPLAIN SELECT * FROM t1 A, t1 B WHERE A.a = B.a and A.id = 65";
|
||||
set statement optimizer_use_condition_selectivity=2 for explain SELECT * FROM t1
|
||||
WHERE
|
||||
EXISTS (SELECT * FROM t1 A INNER JOIN t2 ON t2.a = A.id
|
||||
WHERE A.a=t1.a AND t2.b < 20);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index NULL a 5 NULL 100 Using where; Using index
|
||||
3 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1 Using index
|
||||
3 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
|
||||
set statement optimizer_use_condition_selectivity=4 for explain SELECT * FROM t1
|
||||
WHERE
|
||||
EXISTS (SELECT * FROM t1 A INNER JOIN t2 ON t2.a = A.id
|
||||
WHERE A.a=t1.a AND t2.b < 20);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index NULL a 5 NULL 100 Using where; Using index
|
||||
3 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1 Using index
|
||||
3 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
|
||||
explain SELECT * FROM t1
|
||||
WHERE
|
||||
EXISTS (SELECT * FROM t1 A INNER JOIN t2 ON t2.a = A.id
|
||||
@@ -1913,7 +1933,6 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
2 DEPENDENT SUBQUERY A ref PRIMARY,a a 5 test.t1.a 1 Using index
|
||||
2 DEPENDENT SUBQUERY t2 ref a,b a 5 test.A.id 1 Using where
|
||||
set optimizer_switch= @save_optimizer_switch;
|
||||
set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
|
||||
drop table t1,t2;
|
||||
#
|
||||
# MDEV-21495: Conditional jump or move depends on uninitialised value in sel_arg_range_seq_next
|
||||
|
||||
@@ -1230,6 +1230,8 @@ SELECT * FROM t1 HAVING MIN(t1.c1) >= ALL(SELECT 'a' UNION SELECT 'r');
|
||||
c1
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect datetime value: 'r'
|
||||
SELECT * FROM t1 HAVING MIN(t1.c1) > 0;
|
||||
c1
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 timestamp);
|
||||
INSERT INTO t1 VALUES ('2010-01-01 00:00:00');
|
||||
|
||||
@@ -810,6 +810,7 @@ DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 timestamp);
|
||||
SELECT MIN(t1.c1) AS k1 FROM t1 HAVING (k1 >= ALL(SELECT 'a' UNION SELECT 'r'));
|
||||
SELECT * FROM t1 HAVING MIN(t1.c1) >= ALL(SELECT 'a' UNION SELECT 'r');
|
||||
SELECT * FROM t1 HAVING MIN(t1.c1) > 0;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (c1 timestamp);
|
||||
|
||||
@@ -410,8 +410,11 @@ sub main {
|
||||
|
||||
mark_time_used('collect');
|
||||
|
||||
mysql_install_db(default_mysqld(), "$opt_vardir/install.db") unless using_extern();
|
||||
|
||||
if (!using_extern())
|
||||
{
|
||||
mysql_install_db(default_mysqld(), "$opt_vardir/install.db");
|
||||
make_readonly("$opt_vardir/install.db");
|
||||
}
|
||||
if ($opt_dry_run)
|
||||
{
|
||||
for (@$tests) {
|
||||
|
||||
@@ -46,15 +46,23 @@ Warning 1076 The current gtid binlog state is incompatible with a former one mis
|
||||
Warning 1076 The gtid domain being deleted ('1') is not in the current binlog state
|
||||
FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0);
|
||||
ERROR HY000: Could not delete gtid domain. Reason: binlog files may contain gtids from the domain ('1') being deleted. Make sure to first purge those files.
|
||||
MDEV-31140: Missing error from DELETE_DOMAIN_ID when gtid_binlog_state partially matches GTID_LIST.
|
||||
FLUSH BINARY LOGS;
|
||||
PURGE BINARY LOGS TO 'master-bin.000005';
|
||||
SET @@SESSION.gtid_domain_id=8;
|
||||
SET @@SESSION.server_id=10*8 + 1;
|
||||
INSERT INTO t SELECT 1+MAX(a) FROM t;
|
||||
FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0);
|
||||
ERROR HY000: Could not delete gtid domain. Reason: binlog files may contain gtids from the domain ('8') being deleted. Make sure to first purge those files.
|
||||
FLUSH BINARY LOGS;
|
||||
PURGE BINARY LOGS TO 'master-bin.000006';
|
||||
FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0);
|
||||
Warnings:
|
||||
Warning 1076 The gtid domain being deleted ('0') is not in the current binlog state
|
||||
Gtid_list of the current binlog does not contain 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0:
|
||||
show binlog events in 'master-bin.000006' limit 1,1;
|
||||
show binlog events in 'master-bin.000007' limit 1,1;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000006 # Gtid_list 1 # []
|
||||
master-bin.000007 # Gtid_list 1 # []
|
||||
SET @@SESSION.gtid_domain_id=1;;
|
||||
SET @@SESSION.server_id=1;
|
||||
SET @@SESSION.gtid_seq_no=1;
|
||||
@@ -75,7 +83,7 @@ INSERT INTO t SET a=1;
|
||||
SELECT @gtid_binlog_state_saved "as original state", @@GLOBAL.gtid_binlog_state as "out of order for 11 domain state";
|
||||
as original state out of order for 11 domain state
|
||||
1-1-1,1-2-2,11-11-11 1-1-1,1-2-2,11-11-1
|
||||
PURGE BINARY LOGS TO 'master-bin.000007';
|
||||
PURGE BINARY LOGS TO 'master-bin.000008';
|
||||
the following command succeeds with warnings
|
||||
FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1);
|
||||
Warnings:
|
||||
|
||||
@@ -21,7 +21,6 @@ FLUSH BINARY LOGS DELETE_DOMAIN_ID = ();
|
||||
--echo but with a warning
|
||||
--let $binlog_pre_flush=query_get_value(SHOW MASTER STATUS, Position, 1)
|
||||
FLUSH BINARY LOGS DELETE_DOMAIN_ID = (99);
|
||||
--let $binlog_start=$binlog_pre_flush
|
||||
--source include/show_binary_logs.inc
|
||||
|
||||
# Log one event in a specified domain and try to delete the domain
|
||||
@@ -62,6 +61,8 @@ FLUSH BINARY LOGS DELETE_DOMAIN_ID = (1);
|
||||
# expected overrun of the static buffers of underlying dynamic arrays is doing.
|
||||
--let $domain_cnt=17
|
||||
--let $server_in_domain_cnt=3
|
||||
--let $err_domain_id=`SELECT FLOOR($domain_cnt/2)`
|
||||
--let $err_server_id=`SELECT FLOOR($server_in_domain_cnt/2)`
|
||||
--let $domain_list=
|
||||
--disable_query_log
|
||||
while ($domain_cnt)
|
||||
@@ -86,6 +87,16 @@ while ($domain_cnt)
|
||||
--error ER_BINLOG_CANT_DELETE_GTID_DOMAIN
|
||||
--eval FLUSH BINARY LOGS DELETE_DOMAIN_ID = ($domain_list)
|
||||
|
||||
--echo MDEV-31140: Missing error from DELETE_DOMAIN_ID when gtid_binlog_state partially matches GTID_LIST.
|
||||
FLUSH BINARY LOGS;
|
||||
--let $purge_to_binlog= query_get_value(SHOW MASTER STATUS, File, 1)
|
||||
--eval PURGE BINARY LOGS TO '$purge_to_binlog'
|
||||
--eval SET @@SESSION.gtid_domain_id=$err_domain_id
|
||||
--eval SET @@SESSION.server_id=10*$err_domain_id + $err_server_id
|
||||
eval INSERT INTO t SELECT 1+MAX(a) FROM t;
|
||||
--error ER_BINLOG_CANT_DELETE_GTID_DOMAIN
|
||||
--eval FLUSH BINARY LOGS DELETE_DOMAIN_ID = ($domain_list)
|
||||
|
||||
# Now satisfy the safety condtion to purge log files containing $domain list
|
||||
FLUSH BINARY LOGS;
|
||||
--let $purge_to_binlog= query_get_value(SHOW MASTER STATUS, File, 1)
|
||||
|
||||
@@ -27,3 +27,5 @@ galera_bf_kill_debug : timeout after 900 seconds
|
||||
galera_ssl_upgrade : [Warning] Failed to load slave replication state from table mysql.gtid_slave_pos: 130: Incorrect file format 'gtid_slave_pos'
|
||||
galera_parallel_simple : timeout related to wsrep_sync_wait
|
||||
galera_insert_bulk : MDEV-30536 no expected deadlock in galera_insert_bulk test
|
||||
MDEV-27713 : test is using get_lock(), which is now rejected in cluster
|
||||
galera_bf_abort_group_commit : MDEV-30855 PR to remove the test exists
|
||||
|
||||
21
mysql-test/suite/galera/r/MDEV-29293.result
Normal file
21
mysql-test/suite/galera/r/MDEV-29293.result
Normal file
@@ -0,0 +1,21 @@
|
||||
connection node_2;
|
||||
connection node_1;
|
||||
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
set wsrep_sync_wait = 0;
|
||||
CREATE TABLE t1(a int not null primary key auto_increment, b int) engine=InnoDB;
|
||||
INSERT INTO t1 VALUES (1,2);
|
||||
connection node_1a;
|
||||
BEGIN;
|
||||
UPDATE t1 SET b=3 WHERE a=1;
|
||||
connection node_1;
|
||||
set debug_sync='wsrep_kill_before_awake_no_mutex SIGNAL before_kill WAIT_FOR continue';
|
||||
connection node_1b;
|
||||
set debug_sync= 'now WAIT_FOR before_kill';
|
||||
connection node_2;
|
||||
UPDATE t1 SET b=7 WHERE a=1;
|
||||
connection node_1b;
|
||||
set debug_sync= 'now SIGNAL continue';
|
||||
connection node_1;
|
||||
DROP TABLE t1;
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
@@ -82,6 +82,7 @@ connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
LOCK TABLE t2 WRITE;
|
||||
connection node_1;
|
||||
CREATE TABLE t1 AS SELECT * FROM t2;;
|
||||
connection node_1a;
|
||||
connection node_2;
|
||||
SELECT COUNT(*) = 5 FROM t2;
|
||||
COUNT(*) = 5
|
||||
|
||||
@@ -134,6 +134,3 @@ connection node_1;
|
||||
call mtr.add_suppression("Error in Log_event::read_log_event():.*");
|
||||
CALL mtr.add_suppression("conflict state 7 after post commit");
|
||||
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
|
||||
connection node_2;
|
||||
call mtr.add_suppression("Error in Log_event::read_log_event():.*");
|
||||
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
|
||||
|
||||
27
mysql-test/suite/galera/r/galera_kill_group_commit.result
Normal file
27
mysql-test/suite/galera/r/galera_kill_group_commit.result
Normal file
@@ -0,0 +1,27 @@
|
||||
connection node_2;
|
||||
connection node_1;
|
||||
connect node_1_kill, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
connect node_1_ctrl, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
connect node_1_follower, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
connection node_1;
|
||||
CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB;
|
||||
SET SESSION DEBUG_SYNC = "commit_before_enqueue SIGNAL leader_before_enqueue_reached WAIT_FOR leader_before_enqueue_continue";
|
||||
INSERT INTO t1 VALUES (1);
|
||||
connection node_1_ctrl;
|
||||
SET DEBUG_SYNC = "now WAIT_FOR leader_before_enqueue_reached";
|
||||
connection node_1_follower;
|
||||
INSERT INTO t1 VALUES (2);;
|
||||
connection node_1_ctrl;
|
||||
connection node_1_kill;
|
||||
# Execute KILL QUERY for group commit follower
|
||||
SET DEBUG_SYNC = "now SIGNAL leader_before_enqueue_continue";
|
||||
connection node_1_follower;
|
||||
connection node_1;
|
||||
SELECT * FROM t1;
|
||||
f1
|
||||
1
|
||||
2
|
||||
SET DEBUG_SYNC = "RESET";
|
||||
DROP TABLE t1;
|
||||
@@ -36,7 +36,10 @@ SET DEBUG_SYNC = 'now SIGNAL wsrep_retry_autocommit_continue';
|
||||
connection node_1;
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
1
|
||||
connection node_1;
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
SET DEBUG_SYNC = 'RESET';
|
||||
SET GLOBAL debug_dbug = NULL;
|
||||
DROP TABLE t1;
|
||||
|
||||
41
mysql-test/suite/galera/t/MDEV-29293.test
Normal file
41
mysql-test/suite/galera/t/MDEV-29293.test
Normal file
@@ -0,0 +1,41 @@
|
||||
--source include/galera_cluster.inc
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_debug_sync.inc
|
||||
--source include/galera_have_debug_sync.inc
|
||||
|
||||
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
set wsrep_sync_wait = 0;
|
||||
|
||||
CREATE TABLE t1(a int not null primary key auto_increment, b int) engine=InnoDB;
|
||||
INSERT INTO t1 VALUES (1,2);
|
||||
|
||||
--connection node_1a
|
||||
--let $victim_id = `SELECT CONNECTION_ID()`
|
||||
BEGIN;
|
||||
UPDATE t1 SET b=3 WHERE a=1;
|
||||
|
||||
--connection node_1
|
||||
set debug_sync='wsrep_kill_before_awake_no_mutex SIGNAL before_kill WAIT_FOR continue';
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
--send_eval KILL CONNECTION $victim_id
|
||||
--enable_result_log
|
||||
--enable_query_log
|
||||
|
||||
--connection node_1b
|
||||
set debug_sync= 'now WAIT_FOR before_kill';
|
||||
|
||||
--connection node_2
|
||||
UPDATE t1 SET b=7 WHERE a=1;
|
||||
|
||||
--connection node_1b
|
||||
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE User = 'system user' AND State LIKE 'Update_rows_log_event%';
|
||||
--source include/wait_condition.inc
|
||||
set debug_sync= 'now SIGNAL continue';
|
||||
|
||||
--connection node_1
|
||||
--reap
|
||||
DROP TABLE t1;
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
|
||||
@@ -113,6 +113,10 @@ LOCK TABLE t2 WRITE;
|
||||
--connection node_1
|
||||
--send CREATE TABLE t1 AS SELECT * FROM t2;
|
||||
|
||||
--connection node_1a
|
||||
--let $wait_condition = SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE STATE LIKE 'Waiting for table metadata lock%'
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection node_2
|
||||
SELECT COUNT(*) = 5 FROM t2;
|
||||
CREATE TABLE t1 AS SELECT * FROM t2;
|
||||
@@ -121,7 +125,7 @@ CREATE TABLE t1 AS SELECT * FROM t2;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--connection node_1
|
||||
--error ER_TABLE_EXISTS_ERROR,ER_LOCK_DEADLOCK
|
||||
--error ER_TABLE_EXISTS_ERROR,ER_QUERY_INTERRUPTED
|
||||
--reap
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
5
mysql-test/suite/galera/t/galera_kill_group_commit.cnf
Normal file
5
mysql-test/suite/galera/t/galera_kill_group_commit.cnf
Normal file
@@ -0,0 +1,5 @@
|
||||
!include ../galera_2nodes.cnf
|
||||
|
||||
[mysqld]
|
||||
log-bin
|
||||
log-slave-updates
|
||||
69
mysql-test/suite/galera/t/galera_kill_group_commit.test
Normal file
69
mysql-test/suite/galera/t/galera_kill_group_commit.test
Normal file
@@ -0,0 +1,69 @@
|
||||
#
|
||||
# Verify that transaction which has reached group commit queue
|
||||
# cannot be killed. If the kill succeeds, assertion for
|
||||
# wsrep transaction state will fail.
|
||||
#
|
||||
# If the bug is present, i.e. wsrep transaction gets killed during
|
||||
# group commit wait, this test is enough to reproduce the crash
|
||||
# most of the time.
|
||||
#
|
||||
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_debug_sync.inc
|
||||
--source include/galera_cluster.inc
|
||||
|
||||
# Connection for KILL commands
|
||||
--connect node_1_kill, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
# Connection for sync point control
|
||||
--connect node_1_ctrl, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
# Connection for group commit follower
|
||||
--connect node_1_follower, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
# Need to disable sync wait to reach commit queue when leader
|
||||
# is blocked.
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
--let $follower_id = `SELECT CONNECTION_ID()`
|
||||
|
||||
--connection node_1
|
||||
CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB;
|
||||
|
||||
SET SESSION DEBUG_SYNC = "commit_before_enqueue SIGNAL leader_before_enqueue_reached WAIT_FOR leader_before_enqueue_continue";
|
||||
--send INSERT INTO t1 VALUES (1)
|
||||
|
||||
--connection node_1_ctrl
|
||||
SET DEBUG_SYNC = "now WAIT_FOR leader_before_enqueue_reached";
|
||||
|
||||
--connection node_1_follower
|
||||
# SET SESSION DEBUG_SYNC = "group_commit_waiting_for_prior SIGNAL follower_waiting_for_prior_reached WAIT_FOR follower_waiting_for_prior_continue";
|
||||
--send INSERT INTO t1 VALUES (2);
|
||||
|
||||
--connection node_1_ctrl
|
||||
# TODO: Is it possible to use sync points to enforce group commit to happen?
|
||||
# The leader will hold commit monitor in commit_before_enqueue sync point,
|
||||
# which prevents the follower to reach the group commit wait state.
|
||||
# We now sleep and expect the follower to reach group commit, but this
|
||||
# may cause false negatives.
|
||||
--sleep 1
|
||||
|
||||
--connection node_1_kill
|
||||
--echo # Execute KILL QUERY for group commit follower
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
# Because it is currently impossible to verify that the
|
||||
# follower has reached group commit queue, the KILL may
|
||||
# sometimes return success.
|
||||
--error 0,ER_KILL_DENIED_ERROR
|
||||
--eval KILL QUERY $follower_id
|
||||
--enable_result_log
|
||||
--enable_query_log
|
||||
|
||||
SET DEBUG_SYNC = "now SIGNAL leader_before_enqueue_continue";
|
||||
--connection node_1_follower
|
||||
--reap
|
||||
|
||||
--connection node_1
|
||||
--reap
|
||||
SELECT * FROM t1;
|
||||
|
||||
SET DEBUG_SYNC = "RESET";
|
||||
DROP TABLE t1;
|
||||
@@ -64,6 +64,7 @@ SELECT COUNT(*) FROM t1;
|
||||
SET DEBUG_SYNC = 'now SIGNAL wsrep_retry_autocommit_continue';
|
||||
|
||||
--connection node_1
|
||||
--error 0,ER_LOCK_DEADLOCK
|
||||
--reap
|
||||
SELECT COUNT(*) FROM t1;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ INSERT INTO t1 (f1, f2) VALUES(1,2);
|
||||
set global debug_dbug="+d,ib_purge_virtual_index_callback";
|
||||
connection con1;
|
||||
COMMIT;
|
||||
InnoDB 0 transactions not purged
|
||||
SET GLOBAL innodb_max_purge_lag_wait=1;
|
||||
connection con2;
|
||||
commit;
|
||||
disconnect con1;
|
||||
|
||||
@@ -78,7 +78,7 @@ SET DEBUG_SYNC= 'now WAIT_FOR uncommitted';
|
||||
# enable purge
|
||||
COMMIT;
|
||||
# wait for purge to process the deleted records.
|
||||
InnoDB 0 transactions not purged
|
||||
InnoDB 1 transactions not purged
|
||||
SET DEBUG_SYNC= 'now SIGNAL purged';
|
||||
connection default;
|
||||
/* connection default */ ALTER TABLE t1 ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=SHARED;
|
||||
|
||||
@@ -23,7 +23,7 @@ set global debug_dbug="+d,ib_purge_virtual_index_callback";
|
||||
connection con1;
|
||||
COMMIT;
|
||||
|
||||
--source ../innodb/include/wait_all_purged.inc
|
||||
SET GLOBAL innodb_max_purge_lag_wait=1;
|
||||
|
||||
connection con2;
|
||||
commit;
|
||||
|
||||
@@ -113,7 +113,9 @@ SET DEBUG_SYNC= 'now WAIT_FOR uncommitted';
|
||||
COMMIT;
|
||||
|
||||
--echo # wait for purge to process the deleted records.
|
||||
let $wait_all_purged = 1;
|
||||
--source ../../innodb/include/wait_all_purged.inc
|
||||
let $wait_all_purged = 0;
|
||||
|
||||
SET DEBUG_SYNC= 'now SIGNAL purged';
|
||||
|
||||
|
||||
@@ -1,31 +1,34 @@
|
||||
SET @save_freq=@@GLOBAL.innodb_purge_rseg_truncate_frequency;
|
||||
SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
|
||||
CREATE TABLE t (a int PRIMARY KEY, b int NOT NULL UNIQUE) engine = InnoDB;
|
||||
CREATE TABLE t (a int PRIMARY KEY, b int NOT NULL UNIQUE) engine = InnoDB, STATS_PERSISTENT=0;
|
||||
InnoDB 0 transactions not purged
|
||||
connect prevent_purge,localhost,root,,;
|
||||
start transaction with consistent snapshot;
|
||||
connect con_del_1,localhost,root,,;
|
||||
INSERT INTO t VALUES (20,20);
|
||||
SET DEBUG_SYNC = 'innodb_row_search_for_mysql_exit SIGNAL first_del_row_search_mvcc_finished WAIT_FOR first_del_cont';
|
||||
DELETE FROM t WHERE b = 20;
|
||||
DELETE FROM t WHERE b = 20 # trx_1;
|
||||
connect con_ins_1,localhost,root,,;
|
||||
SET DEBUG_SYNC = 'now WAIT_FOR first_del_row_search_mvcc_finished';
|
||||
SET DEBUG_SYNC = 'lock_wait_start SIGNAL first_ins_locked';
|
||||
SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL first_ins_row_inserted WAIT_FOR first_ins_cont';
|
||||
INSERT INTO t VALUES(10, 20);
|
||||
INSERT INTO t VALUES(10, 20) # trx_2;
|
||||
connect con_del_2,localhost,root,,;
|
||||
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
SET DEBUG_SYNC = 'now WAIT_FOR first_ins_locked';
|
||||
SET DEBUG_SYNC = 'lock_wait_start SIGNAL second_del_locked';
|
||||
DELETE FROM t WHERE b = 20;
|
||||
DELETE FROM t WHERE b = 20 # trx_3;
|
||||
connection default;
|
||||
SET DEBUG_SYNC = 'now WAIT_FOR second_del_locked';
|
||||
SET @saved_dbug = @@GLOBAL.debug_dbug;
|
||||
SET @@GLOBAL.debug_dbug="d,enable_row_purge_del_mark_exit_sync_point";
|
||||
SET DEBUG_SYNC = 'now SIGNAL first_del_cont';
|
||||
SET DEBUG_SYNC = 'now WAIT_FOR first_ins_row_inserted';
|
||||
connection con_del_1;
|
||||
connection default;
|
||||
disconnect prevent_purge;
|
||||
InnoDB 0 transactions not purged
|
||||
SET DEBUG_SYNC = 'now WAIT_FOR row_purge_del_mark_finished';
|
||||
SET @@GLOBAL.debug_dbug = @saved_dbug;
|
||||
SET DEBUG_SYNC = 'now SIGNAL first_ins_cont';
|
||||
connection con_del_2;
|
||||
connection con_ins_1;
|
||||
|
||||
@@ -19,7 +19,7 @@ BEGIN;
|
||||
UPDATE t1 SET b=4 WHERE a=3;
|
||||
disconnect prevent_purge;
|
||||
connection default;
|
||||
InnoDB 0 transactions not purged
|
||||
SET GLOBAL innodb_max_purge_lag_wait=1;
|
||||
connection con1;
|
||||
ROLLBACK;
|
||||
disconnect con1;
|
||||
|
||||
@@ -392,11 +392,12 @@ connection stop_purge;
|
||||
COMMIT;
|
||||
disconnect stop_purge;
|
||||
connection default;
|
||||
InnoDB 0 transactions not purged
|
||||
InnoDB 1 transactions not purged
|
||||
SET DEBUG_SYNC='now SIGNAL s2';
|
||||
connection dml;
|
||||
disconnect dml;
|
||||
connection default;
|
||||
InnoDB 0 transactions not purged
|
||||
SET DEBUG_SYNC=RESET;
|
||||
DROP TABLE t1;
|
||||
# End of 10.3 tests
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
|
||||
SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
|
||||
InnoDB 0 transactions not purged
|
||||
#
|
||||
# MDEV-17793 Crash in purge after instant DROP and emptying the table
|
||||
#
|
||||
@@ -16,7 +17,7 @@ COMMIT;
|
||||
START TRANSACTION WITH CONSISTENT SNAPSHOT;
|
||||
connection default;
|
||||
ALTER TABLE t1 ADD COLUMN extra TINYINT UNSIGNED NOT NULL DEFAULT 42;
|
||||
InnoDB 1 transactions not purged
|
||||
SET GLOBAL innodb_max_purge_lag_wait=1;
|
||||
ALTER TABLE t1 DROP extra;
|
||||
disconnect prevent_purge;
|
||||
InnoDB 0 transactions not purged
|
||||
|
||||
@@ -26,4 +26,60 @@ UPDATE mysql.innodb_table_stats SET last_update=NULL WHERE table_name='t1';
|
||||
XA END 'test';
|
||||
XA ROLLBACK 'test';
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-30483 After upgrade to 10.6 from Mysql 5.7 seeing "InnoDB: Column last_update in table mysql.innodb_table_stats is BINARY(4) NOT NULL but should be INT UNSIGNED NOT NULL"
|
||||
#
|
||||
#
|
||||
# Testing a non-default format: Field_timestamp0 - UINT4 based
|
||||
#
|
||||
SET @@global.mysql56_temporal_format=0;
|
||||
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
SHOW COLUMNS FROM mysql.innodb_table_stats LIKE 'last_update';
|
||||
Field Type Null Key Default Extra
|
||||
last_update timestamp /* mariadb-5.3 */ NO current_timestamp() on update current_timestamp()
|
||||
SHOW COLUMNS FROM mysql.innodb_index_stats LIKE 'last_update';
|
||||
Field Type Null Key Default Extra
|
||||
last_update timestamp /* mariadb-5.3 */ NO current_timestamp() on update current_timestamp()
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=1;
|
||||
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_table_stats
|
||||
WHERE database_name='test' AND table_name='t1';
|
||||
TIMESTAMPDIFF(DAY,last_update,now())<=1
|
||||
1
|
||||
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_index_stats
|
||||
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
|
||||
TIMESTAMPDIFF(DAY,last_update,now())<=1
|
||||
1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Now as the table t1 is dropped, expect no statistics
|
||||
#
|
||||
SELECT * FROM mysql.innodb_table_stats
|
||||
WHERE database_name='test' AND table_name='t1';
|
||||
database_name table_name last_update n_rows clustered_index_size sum_of_other_index_sizes
|
||||
SELECT * FROM mysql.innodb_index_stats
|
||||
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
|
||||
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
||||
#
|
||||
# Testing with the default format: Field_timestampf - BINARY(4) based with the UNSIGNED_FLAG
|
||||
#
|
||||
SET @@global.mysql56_temporal_format=1;
|
||||
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
SHOW COLUMNS FROM mysql.innodb_table_stats LIKE 'last_update';
|
||||
Field Type Null Key Default Extra
|
||||
last_update timestamp NO current_timestamp() on update current_timestamp()
|
||||
SHOW COLUMNS FROM mysql.innodb_index_stats LIKE 'last_update';
|
||||
Field Type Null Key Default Extra
|
||||
last_update timestamp NO current_timestamp() on update current_timestamp()
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=1;
|
||||
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_table_stats
|
||||
WHERE database_name='test' AND table_name='t1';
|
||||
TIMESTAMPDIFF(DAY,last_update,now())<=1
|
||||
1
|
||||
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_index_stats
|
||||
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
|
||||
TIMESTAMPDIFF(DAY,last_update,now())<=1
|
||||
1
|
||||
DROP TABLE t1;
|
||||
# End of 10.6 tests
|
||||
|
||||
@@ -5,7 +5,7 @@ source include/have_debug_sync.inc;
|
||||
|
||||
SET @save_freq=@@GLOBAL.innodb_purge_rseg_truncate_frequency;
|
||||
SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
|
||||
CREATE TABLE t (a int PRIMARY KEY, b int NOT NULL UNIQUE) engine = InnoDB;
|
||||
CREATE TABLE t (a int PRIMARY KEY, b int NOT NULL UNIQUE) engine = InnoDB, STATS_PERSISTENT=0;
|
||||
|
||||
--source include/wait_all_purged.inc
|
||||
--connect(prevent_purge,localhost,root,,)
|
||||
@@ -14,20 +14,20 @@ start transaction with consistent snapshot;
|
||||
--connect(con_del_1,localhost,root,,)
|
||||
INSERT INTO t VALUES (20,20);
|
||||
SET DEBUG_SYNC = 'innodb_row_search_for_mysql_exit SIGNAL first_del_row_search_mvcc_finished WAIT_FOR first_del_cont';
|
||||
--send DELETE FROM t WHERE b = 20
|
||||
--send DELETE FROM t WHERE b = 20 # trx_1
|
||||
|
||||
--connect(con_ins_1,localhost,root,,)
|
||||
SET DEBUG_SYNC = 'now WAIT_FOR first_del_row_search_mvcc_finished';
|
||||
# It's supposed the following INSERT will be suspended just after
|
||||
# lock_wait_start syncpoint, and will be awaken
|
||||
# after the previous DELETE commits. ib_after_row_insert will be executed
|
||||
# after the INSERT is woken up. The previous DELETE will wait for
|
||||
# after trx_1 DELETE commits. ib_after_row_insert will be executed
|
||||
# after the trx_2 INSERT is woken up. The trx_1 DELETE will wait for
|
||||
# first_del_cont signal before commit, and this signal will be sent later.
|
||||
# So it's safe to use two signals in a row here, it's guaranted the first
|
||||
# signal will be received before the second signal is sent.
|
||||
SET DEBUG_SYNC = 'lock_wait_start SIGNAL first_ins_locked';
|
||||
SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL first_ins_row_inserted WAIT_FOR first_ins_cont';
|
||||
--send INSERT INTO t VALUES(10, 20)
|
||||
--send INSERT INTO t VALUES(10, 20) # trx_2
|
||||
|
||||
--connect(con_del_2,localhost,root,,)
|
||||
# After MDEV-30225 is fixed, the following DELETE creates next-key lock for
|
||||
@@ -36,24 +36,26 @@ SET DEBUG_SYNC = 'ib_after_row_insert SIGNAL first_ins_row_inserted WAIT_FOR fir
|
||||
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
SET DEBUG_SYNC = 'now WAIT_FOR first_ins_locked';
|
||||
SET DEBUG_SYNC = 'lock_wait_start SIGNAL second_del_locked';
|
||||
###############################################################################
|
||||
# This DELETE is locked by the previous DELETE, after that DELETE is
|
||||
# committed, it will still be locked by the next INSERT on delete-marked
|
||||
# heap_no 2 record. After that INSERT inserted the record with heap_no 3,
|
||||
# and after heap_no 2 record is purged, this DELETE will be unlocked and
|
||||
##############################################################################
|
||||
# trx_3 DELETE is locked by trx_1 DELETE, after trx_1 DELETE is
|
||||
# committed, it will still be locked by trx_2 INSERT on delete-marked
|
||||
# heap_no 2 record. After trx_2 INSERT inserted the record with heap_no 3,
|
||||
# and after heap_no 2 record is purged, trx_3 DELETE will be unlocked and
|
||||
# must restore persistent cursor position at heap_no 3 record, as it has the
|
||||
# same secondary key value as former heap_no 2 record. Then it must be blocked
|
||||
# by the previous INSERT, and after the INSERT is committed, it must
|
||||
# delete the record, inserted by the previous INSERT, and the last INSERT(see
|
||||
# by trx_2 INSERT, and after trx_2 INSERT is committed, it must
|
||||
# delete the record, inserted by trx_2 INSERT, and trx_4 INSERT(see
|
||||
# below) must be finished without error. But instead this DELETE restores
|
||||
# persistent cursor position to supremum, as a result, it does not delete the
|
||||
# record, inserted by the previous INSERT, and the last INSERT is finished with
|
||||
# record, inserted by trx_2 INSERT, and trx_4 INSERT is finished with
|
||||
# duplicate key check error.
|
||||
###############################################################################
|
||||
--send DELETE FROM t WHERE b = 20
|
||||
--send DELETE FROM t WHERE b = 20 # trx_3
|
||||
|
||||
--connection default
|
||||
SET DEBUG_SYNC = 'now WAIT_FOR second_del_locked';
|
||||
SET @saved_dbug = @@GLOBAL.debug_dbug;
|
||||
SET @@GLOBAL.debug_dbug="d,enable_row_purge_del_mark_exit_sync_point";
|
||||
SET DEBUG_SYNC = 'now SIGNAL first_del_cont';
|
||||
SET DEBUG_SYNC = 'now WAIT_FOR first_ins_row_inserted';
|
||||
--connection con_del_1
|
||||
@@ -61,7 +63,8 @@ SET DEBUG_SYNC = 'now WAIT_FOR first_ins_row_inserted';
|
||||
|
||||
--connection default
|
||||
--disconnect prevent_purge
|
||||
--source include/wait_all_purged.inc
|
||||
SET DEBUG_SYNC = 'now WAIT_FOR row_purge_del_mark_finished';
|
||||
SET @@GLOBAL.debug_dbug = @saved_dbug;
|
||||
SET DEBUG_SYNC = 'now SIGNAL first_ins_cont';
|
||||
|
||||
--connection con_del_2
|
||||
@@ -74,7 +77,7 @@ SET DEBUG_SYNC = 'now SIGNAL first_ins_cont';
|
||||
###############################################################################
|
||||
# Duplicate key error is expected if the bug is not fixed.
|
||||
###############################################################################
|
||||
INSERT INTO t VALUES(30, 20);
|
||||
INSERT INTO t VALUES(30, 20); # trx_4
|
||||
|
||||
--disconnect con_ins_1
|
||||
--disconnect con_del_1
|
||||
|
||||
@@ -32,7 +32,7 @@ UPDATE t1 SET b=4 WHERE a=3;
|
||||
|
||||
--connection default
|
||||
# Initiate a full purge, which should reset the DB_TRX_ID except for a=3.
|
||||
--source include/wait_all_purged.inc
|
||||
SET GLOBAL innodb_max_purge_lag_wait=1;
|
||||
# Initiate a ROLLBACK of the update, which should reset the DB_TRX_ID for a=3.
|
||||
--connection con1
|
||||
ROLLBACK;
|
||||
|
||||
@@ -450,7 +450,9 @@ COMMIT;
|
||||
disconnect stop_purge;
|
||||
|
||||
connection default;
|
||||
let $wait_all_purged = 1;
|
||||
--source include/wait_all_purged.inc
|
||||
let $wait_all_purged = 0;
|
||||
SET DEBUG_SYNC='now SIGNAL s2';
|
||||
|
||||
connection dml;
|
||||
@@ -458,6 +460,7 @@ reap;
|
||||
disconnect dml;
|
||||
|
||||
connection default;
|
||||
--source include/wait_all_purged.inc
|
||||
SET DEBUG_SYNC=RESET;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ if ($have_debug) {
|
||||
|
||||
SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
|
||||
SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
|
||||
--source include/wait_all_purged.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-17793 Crash in purge after instant DROP and emptying the table
|
||||
@@ -27,8 +28,7 @@ START TRANSACTION WITH CONSISTENT SNAPSHOT;
|
||||
connection default;
|
||||
|
||||
ALTER TABLE t1 ADD COLUMN extra TINYINT UNSIGNED NOT NULL DEFAULT 42;
|
||||
let $wait_all_purged= 1;
|
||||
--source include/wait_all_purged.inc
|
||||
SET GLOBAL innodb_max_purge_lag_wait=1;
|
||||
ALTER TABLE t1 DROP extra;
|
||||
disconnect prevent_purge;
|
||||
let $wait_all_purged= 0;
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_sequence.inc
|
||||
|
||||
--disable_query_log
|
||||
call mtr.add_suppression("InnoDB: Difficult to find free blocks in the buffer pool");
|
||||
--enable_query_log
|
||||
|
||||
# Ensure that the history list length will actually be decremented by purge.
|
||||
SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
|
||||
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
|
||||
|
||||
@@ -28,4 +28,57 @@ XA END 'test';
|
||||
XA ROLLBACK 'test';
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30483 After upgrade to 10.6 from Mysql 5.7 seeing "InnoDB: Column last_update in table mysql.innodb_table_stats is BINARY(4) NOT NULL but should be INT UNSIGNED NOT NULL"
|
||||
--echo #
|
||||
|
||||
# The following tests demonstrate that these columns:
|
||||
# - innodb_table_stats.last_update
|
||||
# - innodb_index_stats.last_update
|
||||
# have sane values close to NOW(), rather than any garbage,
|
||||
# with all TIMESTAMP formats.
|
||||
|
||||
--echo #
|
||||
--echo # Testing a non-default format: Field_timestamp0 - UINT4 based
|
||||
--echo #
|
||||
|
||||
SET @@global.mysql56_temporal_format=0;
|
||||
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
SHOW COLUMNS FROM mysql.innodb_table_stats LIKE 'last_update';
|
||||
SHOW COLUMNS FROM mysql.innodb_index_stats LIKE 'last_update';
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=1;
|
||||
|
||||
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_table_stats
|
||||
WHERE database_name='test' AND table_name='t1';
|
||||
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_index_stats
|
||||
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Now as the table t1 is dropped, expect no statistics
|
||||
--echo #
|
||||
|
||||
SELECT * FROM mysql.innodb_table_stats
|
||||
WHERE database_name='test' AND table_name='t1';
|
||||
SELECT * FROM mysql.innodb_index_stats
|
||||
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
|
||||
|
||||
--echo #
|
||||
--echo # Testing with the default format: Field_timestampf - BINARY(4) based with the UNSIGNED_FLAG
|
||||
--echo #
|
||||
|
||||
SET @@global.mysql56_temporal_format=1;
|
||||
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
SHOW COLUMNS FROM mysql.innodb_table_stats LIKE 'last_update';
|
||||
SHOW COLUMNS FROM mysql.innodb_index_stats LIKE 'last_update';
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=1;
|
||||
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_table_stats
|
||||
WHERE database_name='test' AND table_name='t1';
|
||||
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_index_stats
|
||||
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
--echo # End of 10.6 tests
|
||||
|
||||
@@ -3898,6 +3898,18 @@ DROP TABLE t1;
|
||||
DROP TABLE m1;
|
||||
set global default_storage_engine=@save_default_storage_engine;
|
||||
#
|
||||
# MDEV-31083 ASAN use-after-poison in myrg_attach_children
|
||||
#
|
||||
CREATE TABLE t1 (f TEXT, FULLTEXT (f)) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES ('foo'),('bar');
|
||||
CREATE TABLE mrg (f TEXT) ENGINE=MERGE, UNION(t1);
|
||||
SELECT * FROM mrg;
|
||||
f
|
||||
foo
|
||||
bar
|
||||
DROP TABLE mrg, t1;
|
||||
End of 10.5 tests
|
||||
#
|
||||
# End of 10.0 tests
|
||||
#
|
||||
#
|
||||
|
||||
@@ -2859,6 +2859,18 @@ set global default_storage_engine=@save_default_storage_engine;
|
||||
# gone so execution of other tests won't be affected by their presence.
|
||||
--source include/wait_until_count_sessions.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-31083 ASAN use-after-poison in myrg_attach_children
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (f TEXT, FULLTEXT (f)) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES ('foo'),('bar');
|
||||
CREATE TABLE mrg (f TEXT) ENGINE=MERGE, UNION(t1);
|
||||
SELECT * FROM mrg;
|
||||
DROP TABLE mrg, t1;
|
||||
|
||||
--echo End of 10.5 tests
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.0 tests
|
||||
--echo #
|
||||
|
||||
26
mysql-test/suite/parts/r/partition_purge.result
Normal file
26
mysql-test/suite/parts/r/partition_purge.result
Normal file
@@ -0,0 +1,26 @@
|
||||
CREATE TABLE t1(f1 INT, f2 INT, INDEX(f1))ENGINE=InnoDB
|
||||
PARTITION BY LIST(f1) (
|
||||
PARTITION p1 VALUES in (1, 2, 3),
|
||||
PARTITION p2 VALUES in (4, 5, 6));
|
||||
INSERT INTO t1 VALUES(1, 1), (1, 1), (6, 1);
|
||||
connect con1,localhost,root,,,;
|
||||
START TRANSACTION WITH CONSISTENT SNAPSHOT;
|
||||
connect con2,localhost,root,,,;
|
||||
SET DEBUG_SYNC="innodb_rollback_inplace_alter_table SIGNAL default_resume WAIT_FOR alter_resume";
|
||||
ALTER TABLE t1 ADD UNIQUE INDEX(f1);
|
||||
connection default;
|
||||
set DEBUG_SYNC="now WAIT_FOR default_resume";
|
||||
SET DEBUG_SYNC="innodb_row_update_for_mysql_begin SIGNAL alter_resume WAIT_FOR alter_finish";
|
||||
DELETE FROM t1;
|
||||
connection con2;
|
||||
ERROR 23000: Duplicate entry '1' for key 'f1_2'
|
||||
SET DEBUG_SYNC="now SIGNAL alter_finish";
|
||||
connection default;
|
||||
connection con1;
|
||||
commit;
|
||||
connection default;
|
||||
disconnect con1;
|
||||
disconnect con2;
|
||||
InnoDB 0 transactions not purged
|
||||
drop table t1;
|
||||
SET DEBUG_SYNC=reset;
|
||||
1
mysql-test/suite/parts/t/partition_purge.opt
Normal file
1
mysql-test/suite/parts/t/partition_purge.opt
Normal file
@@ -0,0 +1 @@
|
||||
--innodb_purge_threads=1
|
||||
37
mysql-test/suite/parts/t/partition_purge.test
Normal file
37
mysql-test/suite/parts/t/partition_purge.test
Normal file
@@ -0,0 +1,37 @@
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_partition.inc
|
||||
--source include/have_debug.inc
|
||||
--source include/have_debug_sync.inc
|
||||
|
||||
CREATE TABLE t1(f1 INT, f2 INT, INDEX(f1))ENGINE=InnoDB
|
||||
PARTITION BY LIST(f1) (
|
||||
PARTITION p1 VALUES in (1, 2, 3),
|
||||
PARTITION p2 VALUES in (4, 5, 6));
|
||||
INSERT INTO t1 VALUES(1, 1), (1, 1), (6, 1);
|
||||
connect(con1,localhost,root,,,);
|
||||
START TRANSACTION WITH CONSISTENT SNAPSHOT;
|
||||
|
||||
connect(con2,localhost,root,,,);
|
||||
SET DEBUG_SYNC="innodb_rollback_inplace_alter_table SIGNAL default_resume WAIT_FOR alter_resume";
|
||||
send ALTER TABLE t1 ADD UNIQUE INDEX(f1);
|
||||
|
||||
connection default;
|
||||
set DEBUG_SYNC="now WAIT_FOR default_resume";
|
||||
SET DEBUG_SYNC="innodb_row_update_for_mysql_begin SIGNAL alter_resume WAIT_FOR alter_finish";
|
||||
send DELETE FROM t1;
|
||||
|
||||
connection con2;
|
||||
--error ER_DUP_ENTRY
|
||||
reap;
|
||||
SET DEBUG_SYNC="now SIGNAL alter_finish";
|
||||
|
||||
connection default;
|
||||
reap;
|
||||
connection con1;
|
||||
commit;
|
||||
connection default;
|
||||
disconnect con1;
|
||||
disconnect con2;
|
||||
--source ../../innodb/include/wait_all_purged.inc
|
||||
drop table t1;
|
||||
SET DEBUG_SYNC=reset;
|
||||
@@ -14,6 +14,7 @@ Audit_null_called 9
|
||||
Audit_null_general_error 1
|
||||
Audit_null_general_log 3
|
||||
Audit_null_general_result 2
|
||||
Audit_null_general_warning 1
|
||||
create procedure au1(x char(16)) select concat("test1", x);
|
||||
call au1("-12");
|
||||
concat("test1", x)
|
||||
@@ -24,6 +25,7 @@ Audit_null_called 22
|
||||
Audit_null_general_error 1
|
||||
Audit_null_general_log 7
|
||||
Audit_null_general_result 5
|
||||
Audit_null_general_warning 1
|
||||
create table t1 (a int);
|
||||
insert t1 values (1), (2);
|
||||
select * from t1;
|
||||
|
||||
@@ -268,6 +268,13 @@ drop database sa_db;
|
||||
select length('01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789');
|
||||
length('0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456
|
||||
2750
|
||||
CREATE TABLE test.t1 (a char(4));
|
||||
set sql_mode="";
|
||||
insert into test.t1 value("12345");
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'a' at row 1
|
||||
set sql_mode=default;
|
||||
drop table test.t1;
|
||||
set global server_audit_file_path='.';
|
||||
show status like 'server_audit_current_log';
|
||||
Variable_name Value
|
||||
@@ -505,6 +512,21 @@ TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,proc,
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,event,
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop database sa_db',0
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'select length(\'012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567',0
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,CREATE,test,t1,
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE TABLE test.t1 (a char(4))',0
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set sql_mode=""',0
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,test,t1,
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,READ,mysql,table_stats,
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,READ,mysql,column_stats,
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,READ,mysql,index_stats,
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'insert into test.t1 value("12345")',0
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SHOW WARNINGS',0
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set sql_mode=default',0
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,table_stats,
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,column_stats,
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,index_stats,
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,DROP,test,t1,
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop table test.t1',0
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global server_audit_file_path=\'.\'',0
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global server_audit_file_path=\'.\'',0
|
||||
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'show status like \'server_audit_current_log\'',0
|
||||
|
||||
@@ -44,6 +44,13 @@ END|
|
||||
CALL e1();
|
||||
ERROR 42S02: Table 'test.non_exists' doesn't exist
|
||||
DROP PROCEDURE e1;
|
||||
CREATE TABLE t1 (a char(4));
|
||||
set sql_mode="";
|
||||
insert into t1 value("12345");
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'a' at row 1
|
||||
set sql_mode=default;
|
||||
drop table t1;
|
||||
uninstall plugin SQL_ERROR_LOG;
|
||||
Warnings:
|
||||
Warning 1620 Plugin is busy and will be uninstalled on shutdown
|
||||
@@ -55,3 +62,5 @@ MYSQL_ERRNO = 1000,
|
||||
MESSAGE_TEXT = 'new message'
|
||||
TIME HOSTNAME ERROR 1366: Incorrect integer value: 'aa' for column `test`.`t1`.`id` at row 1 : insert into t1 values ('aa')
|
||||
TIME HOSTNAME ERROR 1146: Table 'test.non_exists' doesn't exist : INSERT INTO test.non_exists VALUES (0,0,0) /* e1 */
|
||||
TIME HOSTNAME WARNING 1265: Data truncated for column 'a' at row 1 : insert into t1 value("12345")
|
||||
TIME HOSTNAME WARNING 1620: Plugin is busy and will be uninstalled on shutdown : uninstall plugin SQL_ERROR_LOG
|
||||
|
||||
@@ -218,6 +218,12 @@ drop database sa_db;
|
||||
|
||||
select length('01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789');
|
||||
|
||||
CREATE TABLE test.t1 (a char(4));
|
||||
set sql_mode="";
|
||||
insert into test.t1 value("12345");
|
||||
set sql_mode=default;
|
||||
drop table test.t1;
|
||||
|
||||
set global server_audit_file_path='.';
|
||||
--replace_regex /\.[\\\/]/HOME_DIR\//
|
||||
show status like 'server_audit_current_log';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
--source include/not_embedded.inc
|
||||
|
||||
if (!$SQL_ERRLOG_SO) {
|
||||
@@ -66,10 +65,16 @@ DELIMITER ;|
|
||||
CALL e1();
|
||||
DROP PROCEDURE e1;
|
||||
|
||||
CREATE TABLE t1 (a char(4));
|
||||
set sql_mode="";
|
||||
insert into t1 value("12345");
|
||||
set sql_mode=default;
|
||||
drop table t1;
|
||||
|
||||
uninstall plugin SQL_ERROR_LOG;
|
||||
|
||||
let $MYSQLD_DATADIR= `SELECT @@datadir`;
|
||||
# replace the timestamp and the hostname with constant values
|
||||
--replace_regex /[1-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [^E]*/TIME HOSTNAME /
|
||||
--replace_regex /[1-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [^EW]*/TIME HOSTNAME /
|
||||
cat_file $MYSQLD_DATADIR/sql_errors.log;
|
||||
|
||||
remove_file $MYSQLD_DATADIR/sql_errors.log;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
static volatile int ncalls; /* for SHOW STATUS, see below */
|
||||
static volatile int ncalls_general_log;
|
||||
static volatile int ncalls_general_error;
|
||||
static volatile int ncalls_general_warning;
|
||||
static volatile int ncalls_general_result;
|
||||
|
||||
FILE *f;
|
||||
@@ -53,6 +54,7 @@ static int audit_null_plugin_init(void *arg __attribute__((unused)))
|
||||
ncalls= 0;
|
||||
ncalls_general_log= 0;
|
||||
ncalls_general_error= 0;
|
||||
ncalls_general_warning= 0;
|
||||
ncalls_general_result= 0;
|
||||
|
||||
f = fopen("audit_null_tables.log", "w");
|
||||
@@ -113,6 +115,9 @@ static void audit_null_notify(MYSQL_THD thd __attribute__((unused)),
|
||||
case MYSQL_AUDIT_GENERAL_ERROR:
|
||||
ncalls_general_error++;
|
||||
break;
|
||||
case MYSQL_AUDIT_GENERAL_WARNING:
|
||||
ncalls_general_warning++;
|
||||
break;
|
||||
case MYSQL_AUDIT_GENERAL_RESULT:
|
||||
ncalls_general_result++;
|
||||
break;
|
||||
@@ -179,6 +184,7 @@ static struct st_mysql_show_var simple_status[]=
|
||||
{ "general_error", (char *) &ncalls_general_error, SHOW_INT },
|
||||
{ "general_log", (char *) &ncalls_general_log, SHOW_INT },
|
||||
{ "general_result", (char *) &ncalls_general_result, SHOW_INT },
|
||||
{ "general_warning", (char *) &ncalls_general_error, SHOW_INT },
|
||||
{ 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
@@ -84,8 +84,11 @@ static void log_sql_errors(MYSQL_THD thd __attribute__((unused)),
|
||||
const struct mysql_event_general *event =
|
||||
(const struct mysql_event_general*)ev;
|
||||
if (rate &&
|
||||
event->event_subclass == MYSQL_AUDIT_GENERAL_ERROR)
|
||||
(event->event_subclass == MYSQL_AUDIT_GENERAL_ERROR ||
|
||||
event->event_subclass == MYSQL_AUDIT_GENERAL_WARNING))
|
||||
{
|
||||
const char *type= (event->event_subclass == MYSQL_AUDIT_GENERAL_ERROR ?
|
||||
"ERROR" : "WARNING");
|
||||
if (++count >= rate)
|
||||
{
|
||||
struct tm t;
|
||||
@@ -94,10 +97,10 @@ static void log_sql_errors(MYSQL_THD thd __attribute__((unused)),
|
||||
count = 0;
|
||||
(void) localtime_r(&event_time, &t);
|
||||
logger_printf(logfile, "%04d-%02d-%02d %2d:%02d:%02d "
|
||||
"%s ERROR %d: %s : %s\n",
|
||||
"%s %s %d: %s : %s\n",
|
||||
t.tm_year + 1900, t.tm_mon + 1,
|
||||
t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec,
|
||||
event->general_user, event->general_error_code,
|
||||
event->general_user, type, event->general_error_code,
|
||||
event->general_command, event->general_query);
|
||||
}
|
||||
}
|
||||
|
||||
17
plugin/type_mysql_timestamp/CMakeLists.txt
Normal file
17
plugin/type_mysql_timestamp/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2019, 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 Foundation; version 2 of the License.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
|
||||
|
||||
MYSQL_ADD_PLUGIN(type_mysql_timestamp plugin.cc RECOMPILE_FOR_EMBEDDED
|
||||
MODULE_ONLY COMPONENT Test)
|
||||
@@ -0,0 +1 @@
|
||||
--plugin-load-add=$TYPE_MYSQL_TIMESTAMP_SO
|
||||
@@ -0,0 +1,10 @@
|
||||
package My::Suite::Type_test;
|
||||
|
||||
@ISA = qw(My::Suite);
|
||||
|
||||
return "No TYPE_TEST plugin" unless $ENV{TYPE_MYSQL_TIMESTAMP_SO};
|
||||
|
||||
sub is_default { 1 }
|
||||
|
||||
bless { };
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#
|
||||
# MDEV-30483 After upgrade to 10.6 from Mysql 5.7 seeing "InnoDB: Column last_update in table mysql.innodb_table_stats is BINARY(4) NOT NULL but should be INT UNSIGNED NOT NULL"
|
||||
#
|
||||
SELECT
|
||||
PLUGIN_NAME,
|
||||
PLUGIN_VERSION,
|
||||
PLUGIN_STATUS,
|
||||
PLUGIN_TYPE,
|
||||
PLUGIN_AUTHOR,
|
||||
PLUGIN_DESCRIPTION,
|
||||
PLUGIN_LICENSE,
|
||||
PLUGIN_MATURITY,
|
||||
PLUGIN_AUTH_VERSION
|
||||
FROM INFORMATION_SCHEMA.PLUGINS
|
||||
WHERE PLUGIN_TYPE='DATA TYPE'
|
||||
AND PLUGIN_NAME LIKE 'type_mysql_timestamp';
|
||||
PLUGIN_NAME type_mysql_timestamp
|
||||
PLUGIN_VERSION 1.0
|
||||
PLUGIN_STATUS ACTIVE
|
||||
PLUGIN_TYPE DATA TYPE
|
||||
PLUGIN_AUTHOR MariaDB Corporation
|
||||
PLUGIN_DESCRIPTION Data type TYPE_MYSQL_TIMESTAMP
|
||||
PLUGIN_LICENSE GPL
|
||||
PLUGIN_MATURITY Experimental
|
||||
PLUGIN_AUTH_VERSION 1.0
|
||||
CREATE TABLE t1 (a TYPE_MYSQL_TIMESTAMP);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` type_mysql_timestamp NULL DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a TIMESTAMP);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` timestamp NULL DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
ALTER TABLE t1 MODIFY a TYPE_MYSQL_TIMESTAMP;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` type_mysql_timestamp NULL DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
DROP TABLE t1;
|
||||
@@ -0,0 +1,31 @@
|
||||
--source include/have_innodb.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30483 After upgrade to 10.6 from Mysql 5.7 seeing "InnoDB: Column last_update in table mysql.innodb_table_stats is BINARY(4) NOT NULL but should be INT UNSIGNED NOT NULL"
|
||||
--echo #
|
||||
|
||||
--vertical_results
|
||||
SELECT
|
||||
PLUGIN_NAME,
|
||||
PLUGIN_VERSION,
|
||||
PLUGIN_STATUS,
|
||||
PLUGIN_TYPE,
|
||||
PLUGIN_AUTHOR,
|
||||
PLUGIN_DESCRIPTION,
|
||||
PLUGIN_LICENSE,
|
||||
PLUGIN_MATURITY,
|
||||
PLUGIN_AUTH_VERSION
|
||||
FROM INFORMATION_SCHEMA.PLUGINS
|
||||
WHERE PLUGIN_TYPE='DATA TYPE'
|
||||
AND PLUGIN_NAME LIKE 'type_mysql_timestamp';
|
||||
--horizontal_results
|
||||
|
||||
CREATE TABLE t1 (a TYPE_MYSQL_TIMESTAMP);
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a TIMESTAMP);
|
||||
SHOW CREATE TABLE t1;
|
||||
ALTER TABLE t1 MODIFY a TYPE_MYSQL_TIMESTAMP;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
@@ -0,0 +1,108 @@
|
||||
#
|
||||
# MDEV-30483 After upgrade to 10.6 from Mysql 5.7 seeing "InnoDB: Column last_update in table mysql.innodb_table_stats is BINARY(4) NOT NULL but should be INT UNSIGNED NOT NULL"
|
||||
#
|
||||
SET @@global.innodb_stats_persistent=0;
|
||||
SHOW CREATE TABLE mysql.innodb_table_stats;
|
||||
Table Create Table
|
||||
innodb_table_stats CREATE TABLE `innodb_table_stats` (
|
||||
`database_name` varchar(64) NOT NULL,
|
||||
`table_name` varchar(199) NOT NULL,
|
||||
`last_update` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
`n_rows` bigint(20) unsigned NOT NULL,
|
||||
`clustered_index_size` bigint(20) unsigned NOT NULL,
|
||||
`sum_of_other_index_sizes` bigint(20) unsigned NOT NULL,
|
||||
PRIMARY KEY (`database_name`,`table_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0
|
||||
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
SHOW CREATE TABLE mysql.innodb_table_stats;
|
||||
Table Create Table
|
||||
innodb_table_stats CREATE TABLE `innodb_table_stats` (
|
||||
`database_name` varchar(64) NOT NULL,
|
||||
`table_name` varchar(199) NOT NULL,
|
||||
`last_update` type_mysql_timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
`n_rows` bigint(20) unsigned NOT NULL,
|
||||
`clustered_index_size` bigint(20) unsigned NOT NULL,
|
||||
`sum_of_other_index_sizes` bigint(20) unsigned NOT NULL,
|
||||
PRIMARY KEY (`database_name`,`table_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0
|
||||
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
SHOW CREATE TABLE mysql.innodb_index_stats;
|
||||
Table Create Table
|
||||
innodb_index_stats CREATE TABLE `innodb_index_stats` (
|
||||
`database_name` varchar(64) NOT NULL,
|
||||
`table_name` varchar(199) NOT NULL,
|
||||
`index_name` varchar(64) NOT NULL,
|
||||
`last_update` type_mysql_timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
`stat_name` varchar(64) NOT NULL,
|
||||
`stat_value` bigint(20) unsigned NOT NULL,
|
||||
`sample_size` bigint(20) unsigned DEFAULT NULL,
|
||||
`stat_description` varchar(1024) NOT NULL,
|
||||
PRIMARY KEY (`database_name`,`table_name`,`index_name`,`stat_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0
|
||||
SET @@global.innodb_stats_persistent=1;
|
||||
CREATE TABLE t1 (a INT, KEY(a)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (10);
|
||||
DROP TABLE t1;
|
||||
SET @@global.innodb_stats_persistent=0;
|
||||
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
SHOW CREATE TABLE mysql.innodb_table_stats;
|
||||
Table Create Table
|
||||
innodb_table_stats CREATE TABLE `innodb_table_stats` (
|
||||
`database_name` varchar(64) NOT NULL,
|
||||
`table_name` varchar(199) NOT NULL,
|
||||
`last_update` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
`n_rows` bigint(20) unsigned NOT NULL,
|
||||
`clustered_index_size` bigint(20) unsigned NOT NULL,
|
||||
`sum_of_other_index_sizes` bigint(20) unsigned NOT NULL,
|
||||
PRIMARY KEY (`database_name`,`table_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0
|
||||
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
SHOW CREATE TABLE mysql.innodb_index_stats;
|
||||
Table Create Table
|
||||
innodb_index_stats CREATE TABLE `innodb_index_stats` (
|
||||
`database_name` varchar(64) NOT NULL,
|
||||
`table_name` varchar(199) NOT NULL,
|
||||
`index_name` varchar(64) NOT NULL,
|
||||
`last_update` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
`stat_name` varchar(64) NOT NULL,
|
||||
`stat_value` bigint(20) unsigned NOT NULL,
|
||||
`sample_size` bigint(20) unsigned DEFAULT NULL,
|
||||
`stat_description` varchar(1024) NOT NULL,
|
||||
PRIMARY KEY (`database_name`,`table_name`,`index_name`,`stat_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0
|
||||
SET @@global.innodb_stats_persistent=1;
|
||||
#
|
||||
# Testing MySQL-5.6-alike Field_timestampf: BINARY(4) based, without UNSIGNED_FLAG
|
||||
#
|
||||
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
SHOW COLUMNS FROM mysql.innodb_table_stats LIKE 'last_update';
|
||||
Field Type Null Key Default Extra
|
||||
last_update type_mysql_timestamp NO current_timestamp() on update current_timestamp()
|
||||
SHOW COLUMNS FROM mysql.innodb_index_stats LIKE 'last_update';
|
||||
Field Type Null Key Default Extra
|
||||
last_update type_mysql_timestamp NO current_timestamp() on update current_timestamp()
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=1;
|
||||
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_table_stats
|
||||
WHERE database_name='test' AND table_name='t1';
|
||||
TIMESTAMPDIFF(DAY,last_update,now())<=1
|
||||
1
|
||||
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_index_stats
|
||||
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
|
||||
TIMESTAMPDIFF(DAY,last_update,now())<=1
|
||||
1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Now as the table t1 is dropped, expect no statistics
|
||||
#
|
||||
SELECT * FROM mysql.innodb_table_stats
|
||||
WHERE database_name='test' AND table_name='t1';
|
||||
database_name table_name last_update n_rows clustered_index_size sum_of_other_index_sizes
|
||||
SELECT * FROM mysql.innodb_index_stats
|
||||
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
|
||||
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
||||
#
|
||||
# Restore the structure of the tables
|
||||
#
|
||||
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
@@ -0,0 +1,62 @@
|
||||
--source include/have_innodb.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30483 After upgrade to 10.6 from Mysql 5.7 seeing "InnoDB: Column last_update in table mysql.innodb_table_stats is BINARY(4) NOT NULL but should be INT UNSIGNED NOT NULL"
|
||||
--echo #
|
||||
|
||||
SET @@global.innodb_stats_persistent=0;
|
||||
SHOW CREATE TABLE mysql.innodb_table_stats;
|
||||
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
SHOW CREATE TABLE mysql.innodb_table_stats;
|
||||
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
SHOW CREATE TABLE mysql.innodb_index_stats;
|
||||
SET @@global.innodb_stats_persistent=1;
|
||||
|
||||
CREATE TABLE t1 (a INT, KEY(a)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (10);
|
||||
DROP TABLE t1;
|
||||
|
||||
SET @@global.innodb_stats_persistent=0;
|
||||
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
SHOW CREATE TABLE mysql.innodb_table_stats;
|
||||
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
SHOW CREATE TABLE mysql.innodb_index_stats;
|
||||
SET @@global.innodb_stats_persistent=1;
|
||||
|
||||
|
||||
# The following test demonstrate that these columns:
|
||||
# - innodb_table_stats.last_update
|
||||
# - innodb_index_stats.last_update
|
||||
# have sane values close to NOW(), rather than any garbage,
|
||||
# with MySQL-alike Field_timestampf
|
||||
|
||||
--echo #
|
||||
--echo # Testing MySQL-5.6-alike Field_timestampf: BINARY(4) based, without UNSIGNED_FLAG
|
||||
--echo #
|
||||
|
||||
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
SHOW COLUMNS FROM mysql.innodb_table_stats LIKE 'last_update';
|
||||
SHOW COLUMNS FROM mysql.innodb_index_stats LIKE 'last_update';
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=1;
|
||||
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_table_stats
|
||||
WHERE database_name='test' AND table_name='t1';
|
||||
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_index_stats
|
||||
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Now as the table t1 is dropped, expect no statistics
|
||||
--echo #
|
||||
|
||||
SELECT * FROM mysql.innodb_table_stats
|
||||
WHERE database_name='test' AND table_name='t1';
|
||||
SELECT * FROM mysql.innodb_index_stats
|
||||
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
|
||||
|
||||
--echo #
|
||||
--echo # Restore the structure of the tables
|
||||
--echo #
|
||||
|
||||
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
|
||||
177
plugin/type_mysql_timestamp/plugin.cc
Normal file
177
plugin/type_mysql_timestamp/plugin.cc
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
Copyright (c) 2023, 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 Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include <my_global.h>
|
||||
#include <sql_class.h>
|
||||
#include <mysql/plugin_data_type.h>
|
||||
#include "sql_type.h"
|
||||
|
||||
|
||||
class Type_collection_local: public Type_collection
|
||||
{
|
||||
protected:
|
||||
const Type_handler *aggregate_common(const Type_handler *h1,
|
||||
const Type_handler *h2) const;
|
||||
public:
|
||||
const Type_handler *handler_by_name(const LEX_CSTRING &name) const override
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const Type_handler *aggregate_for_result(const Type_handler *h1,
|
||||
const Type_handler *h2)
|
||||
const override
|
||||
{
|
||||
return aggregate_common(h1, h2);
|
||||
}
|
||||
|
||||
const Type_handler *aggregate_for_comparison(const Type_handler *h1,
|
||||
const Type_handler *h2)
|
||||
const override
|
||||
{
|
||||
return aggregate_common(h1, h2);
|
||||
}
|
||||
|
||||
const Type_handler *aggregate_for_min_max(const Type_handler *h1,
|
||||
const Type_handler *h2)
|
||||
const override
|
||||
{
|
||||
return aggregate_common(h1, h2);
|
||||
}
|
||||
|
||||
const Type_handler *aggregate_for_num_op(const Type_handler *h1,
|
||||
const Type_handler *h2)
|
||||
const override
|
||||
{
|
||||
return aggregate_common(h1, h2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static Type_collection_local type_collection_local;
|
||||
|
||||
|
||||
/*
|
||||
A more MySQL compatible Field:
|
||||
it does not set the UNSIGNED_FLAG.
|
||||
This is how MySQL's Field_timestampf works.
|
||||
*/
|
||||
class Field_mysql_timestampf :public Field_timestampf
|
||||
{
|
||||
public:
|
||||
Field_mysql_timestampf(const LEX_CSTRING &name,
|
||||
const Record_addr &addr,
|
||||
enum utype unireg_check_arg,
|
||||
TABLE_SHARE *share, decimal_digits_t dec_arg)
|
||||
:Field_timestampf(addr.ptr(), addr.null_ptr(), addr.null_bit(),
|
||||
unireg_check_arg, &name, share, dec_arg)
|
||||
{
|
||||
flags&= ~UNSIGNED_FLAG; // MySQL compatibility
|
||||
}
|
||||
void sql_type(String &str) const override
|
||||
{
|
||||
sql_type_opt_dec_comment(str,
|
||||
Field_mysql_timestampf::type_handler()->name(),
|
||||
dec, type_version_mysql56());
|
||||
}
|
||||
const Type_handler *type_handler() const override;
|
||||
};
|
||||
|
||||
|
||||
class Type_handler_mysql_timestamp2: public Type_handler_timestamp2
|
||||
{
|
||||
public:
|
||||
const Type_collection *type_collection() const override
|
||||
{
|
||||
return &type_collection_local;
|
||||
}
|
||||
Field *make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *root,
|
||||
const LEX_CSTRING *name,
|
||||
const Record_addr &rec, const Bit_addr &bit,
|
||||
const Column_definition_attributes *attr,
|
||||
uint32 flags) const override
|
||||
{
|
||||
return new (root)
|
||||
Field_mysql_timestampf(*name, rec, attr->unireg_check, share,
|
||||
attr->temporal_dec(MAX_DATETIME_WIDTH));
|
||||
}
|
||||
void Column_definition_implicit_upgrade(Column_definition *c) const override
|
||||
{
|
||||
/*
|
||||
Suppress the automatic upgrade depending on opt_mysql56_temporal_format,
|
||||
derived from Type_handler_timestamp_common.
|
||||
*/
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static Type_handler_mysql_timestamp2 type_handler_mysql_timestamp2;
|
||||
|
||||
|
||||
const Type_handler *Field_mysql_timestampf::type_handler() const
|
||||
{
|
||||
return &type_handler_mysql_timestamp2;
|
||||
}
|
||||
|
||||
|
||||
const Type_handler *
|
||||
Type_collection_local::aggregate_common(const Type_handler *h1,
|
||||
const Type_handler *h2) const
|
||||
{
|
||||
if (h1 == h2)
|
||||
return h1;
|
||||
|
||||
static const Type_aggregator::Pair agg[]=
|
||||
{
|
||||
{
|
||||
&type_handler_timestamp2,
|
||||
&type_handler_mysql_timestamp2,
|
||||
&type_handler_mysql_timestamp2
|
||||
},
|
||||
{NULL,NULL,NULL}
|
||||
};
|
||||
|
||||
return Type_aggregator::find_handler_in_array(agg, h1, h2, true);
|
||||
}
|
||||
|
||||
|
||||
static struct st_mariadb_data_type plugin_descriptor_type_mysql_timestamp=
|
||||
{
|
||||
MariaDB_DATA_TYPE_INTERFACE_VERSION,
|
||||
&type_handler_mysql_timestamp2
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
maria_declare_plugin(type_mysql_timestamp)
|
||||
{
|
||||
MariaDB_DATA_TYPE_PLUGIN, // the plugin type (see include/mysql/plugin.h)
|
||||
&plugin_descriptor_type_mysql_timestamp, // pointer to type-specific plugin descriptor
|
||||
"type_mysql_timestamp", // plugin name
|
||||
"MariaDB Corporation", // plugin author
|
||||
"Data type TYPE_MYSQL_TIMESTAMP", // the plugin description
|
||||
PLUGIN_LICENSE_GPL, // the plugin license (see include/mysql/plugin.h)
|
||||
0, // Pointer to plugin initialization function
|
||||
0, // Pointer to plugin deinitialization function
|
||||
0x0100, // Numeric version 0xAABB means AA.BB version
|
||||
NULL, // Status variables
|
||||
NULL, // System variables
|
||||
"1.0", // String version representation
|
||||
MariaDB_PLUGIN_MATURITY_EXPERIMENTAL // Maturity(see include/mysql/plugin.h)*/
|
||||
}
|
||||
maria_declare_plugin_end;
|
||||
@@ -3354,7 +3354,7 @@ public:
|
||||
/**
|
||||
TIMESTAMP(0..6) - MySQL56 version
|
||||
*/
|
||||
class Field_timestampf final :public Field_timestamp_with_dec {
|
||||
class Field_timestampf :public Field_timestamp_with_dec {
|
||||
void store_TIMEVAL(const timeval &tv) override;
|
||||
public:
|
||||
Field_timestampf(uchar *ptr_arg,
|
||||
|
||||
@@ -8144,6 +8144,9 @@ Compare_keys handler::compare_key_parts(const Field &old_field,
|
||||
concurrent accesses. And it's an overkill to take LOCK_plugin and
|
||||
iterate the whole installed_htons[] array every time.
|
||||
|
||||
@note Object victim_thd is not guaranteed to exist after this
|
||||
function returns.
|
||||
|
||||
@param bf_thd brute force THD asking for the abort
|
||||
@param victim_thd victim THD to be aborted
|
||||
|
||||
@@ -8157,6 +8160,8 @@ int ha_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal)
|
||||
if (!WSREP(bf_thd) &&
|
||||
!(bf_thd->variables.wsrep_OSU_method == WSREP_OSU_RSU &&
|
||||
wsrep_thd_is_toi(bf_thd))) {
|
||||
mysql_mutex_unlock(&victim_thd->LOCK_thd_data);
|
||||
mysql_mutex_unlock(&victim_thd->LOCK_thd_kill);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
@@ -8168,6 +8173,8 @@ int ha_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal)
|
||||
else
|
||||
{
|
||||
WSREP_WARN("Cannot abort InnoDB transaction");
|
||||
mysql_mutex_unlock(&victim_thd->LOCK_thd_data);
|
||||
mysql_mutex_unlock(&victim_thd->LOCK_thd_kill);
|
||||
}
|
||||
|
||||
DBUG_RETURN(0);
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "sql_sequence.h"
|
||||
#include "mem_root_array.h"
|
||||
#include <utility> // pair
|
||||
#include <my_attribute.h> /* __attribute__ */
|
||||
|
||||
class Alter_info;
|
||||
class Virtual_column_info;
|
||||
@@ -1463,9 +1464,9 @@ struct handlerton
|
||||
const char *query, uint query_length,
|
||||
const char *db, const char *table_name);
|
||||
|
||||
void (*abort_transaction)(handlerton *hton, THD *bf_thd,
|
||||
THD *victim_thd, my_bool signal);
|
||||
int (*set_checkpoint)(handlerton *hton, const XID* xid);
|
||||
void (*abort_transaction)(handlerton *hton, THD *bf_thd, THD *victim_thd,
|
||||
my_bool signal) __attribute__((nonnull));
|
||||
int (*set_checkpoint)(handlerton *hton, const XID *xid);
|
||||
int (*get_checkpoint)(handlerton *hton, XID* xid);
|
||||
/**
|
||||
Check if the version of the table matches the version in the .frm
|
||||
|
||||
@@ -373,7 +373,7 @@ public:
|
||||
{
|
||||
for (uint i= 0; i < arg_count; i++)
|
||||
{
|
||||
args[i]->no_rows_in_result();
|
||||
args[i]->restore_to_before_no_rows_in_result();
|
||||
}
|
||||
}
|
||||
void convert_const_compared_to_int_field(THD *thd);
|
||||
|
||||
@@ -1373,13 +1373,13 @@ bool Item_func_sformat::fix_length_and_dec(THD *thd)
|
||||
|
||||
for (uint i=0 ; i < arg_count ; i++)
|
||||
{
|
||||
char_length+= args[i]->max_char_length();
|
||||
if (args[i]->result_type() == STRING_RESULT &&
|
||||
Type_std_attributes::agg_item_set_converter(c, func_name_cstring(),
|
||||
args+i, 1, flags, 1))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char_length= MAX_BLOB_WIDTH;
|
||||
fix_char_length_ulonglong(char_length);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1747,6 +1747,11 @@ static void close_connections(void)
|
||||
(void) unlink(mysqld_unix_port);
|
||||
}
|
||||
}
|
||||
/*
|
||||
The following is needed to the threads stuck in
|
||||
setup_connection_thread_globals()
|
||||
to continue.
|
||||
*/
|
||||
listen_sockets.free_memory();
|
||||
mysql_mutex_unlock(&LOCK_start_thread);
|
||||
|
||||
@@ -2033,6 +2038,7 @@ static void clean_up(bool print_message)
|
||||
end_ssl();
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
vio_end();
|
||||
listen_sockets.free_memory();
|
||||
#endif /*!EMBEDDED_LIBRARY*/
|
||||
#if defined(ENABLED_DEBUG_SYNC)
|
||||
/* End the debug sync facility. See debug_sync.cc. */
|
||||
|
||||
@@ -2209,18 +2209,16 @@ rpl_binlog_state::drop_domain(DYNAMIC_ARRAY *ids,
|
||||
|
||||
/*
|
||||
For each domain_id from ids
|
||||
when no such domain in binlog state
|
||||
warn && continue
|
||||
For each domain.server's last gtid
|
||||
when not locate the last gtid in glev.list
|
||||
error out binlog state can't change
|
||||
otherwise continue
|
||||
If the domain is already absent from the binlog state
|
||||
Warn && continue
|
||||
If any GTID with that domain in binlog state is missing from glev.list
|
||||
Error out binlog state can't change
|
||||
*/
|
||||
for (ulong i= 0; i < ids->elements; i++)
|
||||
{
|
||||
rpl_binlog_state::element *elem= NULL;
|
||||
uint32 *ptr_domain_id;
|
||||
bool not_match;
|
||||
bool all_found;
|
||||
|
||||
ptr_domain_id= (uint32*) dynamic_array_ptr(ids, i);
|
||||
elem= (rpl_binlog_state::element *)
|
||||
@@ -2235,14 +2233,18 @@ rpl_binlog_state::drop_domain(DYNAMIC_ARRAY *ids,
|
||||
continue;
|
||||
}
|
||||
|
||||
for (not_match= true, k= 0; k < elem->hash.records; k++)
|
||||
all_found= true;
|
||||
for (k= 0; k < elem->hash.records && all_found; k++)
|
||||
{
|
||||
rpl_gtid *d_gtid= (rpl_gtid *)my_hash_element(&elem->hash, k);
|
||||
for (ulong l= 0; l < glev->count && not_match; l++)
|
||||
not_match= !(*d_gtid == glev->list[l]);
|
||||
bool match_found= false;
|
||||
for (ulong l= 0; l < glev->count && !match_found; l++)
|
||||
match_found= match_found || (*d_gtid == glev->list[l]);
|
||||
if (!match_found)
|
||||
all_found= false;
|
||||
}
|
||||
|
||||
if (not_match)
|
||||
if (!all_found)
|
||||
{
|
||||
sprintf(errbuf, "binlog files may contain gtids from the domain ('%u') "
|
||||
"being deleted. Make sure to first purge those files",
|
||||
|
||||
@@ -32,6 +32,11 @@ extern "C" void wsrep_thd_LOCK(const THD *thd)
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
}
|
||||
|
||||
extern "C" int wsrep_thd_TRYLOCK(const THD *thd)
|
||||
{
|
||||
return mysql_mutex_trylock(&thd->LOCK_thd_data);
|
||||
}
|
||||
|
||||
extern "C" void wsrep_thd_UNLOCK(const THD *thd)
|
||||
{
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
@@ -196,6 +201,7 @@ extern "C" void wsrep_handle_SR_rollback(THD *bf_thd,
|
||||
|
||||
/* Note: do not store/reset globals before wsrep_bf_abort() call
|
||||
to avoid losing BF thd context. */
|
||||
mysql_mutex_lock(&victim_thd->LOCK_thd_data);
|
||||
if (!(bf_thd && bf_thd != victim_thd))
|
||||
{
|
||||
DEBUG_SYNC(victim_thd, "wsrep_before_SR_rollback");
|
||||
@@ -208,6 +214,7 @@ extern "C" void wsrep_handle_SR_rollback(THD *bf_thd,
|
||||
{
|
||||
wsrep_thd_self_abort(victim_thd);
|
||||
}
|
||||
mysql_mutex_unlock(&victim_thd->LOCK_thd_data);
|
||||
if (bf_thd)
|
||||
{
|
||||
wsrep_store_threadvars(bf_thd);
|
||||
@@ -218,7 +225,7 @@ extern "C" my_bool wsrep_thd_bf_abort(THD *bf_thd, THD *victim_thd,
|
||||
my_bool signal)
|
||||
{
|
||||
mysql_mutex_assert_owner(&victim_thd->LOCK_thd_kill);
|
||||
mysql_mutex_assert_not_owner(&victim_thd->LOCK_thd_data);
|
||||
mysql_mutex_assert_owner(&victim_thd->LOCK_thd_data);
|
||||
my_bool ret= wsrep_bf_abort(bf_thd, victim_thd);
|
||||
/*
|
||||
Send awake signal if victim was BF aborted or does not
|
||||
@@ -227,19 +234,8 @@ extern "C" my_bool wsrep_thd_bf_abort(THD *bf_thd, THD *victim_thd,
|
||||
*/
|
||||
if ((ret || !wsrep_on(victim_thd)) && signal)
|
||||
{
|
||||
mysql_mutex_lock(&victim_thd->LOCK_thd_data);
|
||||
|
||||
if (victim_thd->wsrep_aborter && victim_thd->wsrep_aborter != bf_thd->thread_id)
|
||||
{
|
||||
WSREP_DEBUG("victim is killed already by %llu, skipping awake",
|
||||
victim_thd->wsrep_aborter);
|
||||
mysql_mutex_unlock(&victim_thd->LOCK_thd_data);
|
||||
return false;
|
||||
}
|
||||
|
||||
victim_thd->wsrep_aborter= bf_thd->thread_id;
|
||||
victim_thd->awake_no_mutex(KILL_QUERY_HARD);
|
||||
mysql_mutex_unlock(&victim_thd->LOCK_thd_data);
|
||||
} else {
|
||||
WSREP_DEBUG("wsrep_thd_bf_abort skipped awake, signal %d", signal);
|
||||
}
|
||||
@@ -368,25 +364,6 @@ extern "C" ulong wsrep_OSU_method_get(const MYSQL_THD thd)
|
||||
return(global_system_variables.wsrep_OSU_method);
|
||||
}
|
||||
|
||||
extern "C" bool wsrep_thd_set_wsrep_aborter(THD *bf_thd, THD *victim_thd)
|
||||
{
|
||||
mysql_mutex_assert_owner(&victim_thd->LOCK_thd_data);
|
||||
if (!bf_thd)
|
||||
{
|
||||
victim_thd->wsrep_aborter= 0;
|
||||
WSREP_DEBUG("wsrep_thd_set_wsrep_aborter resetting wsrep_aborter");
|
||||
return false;
|
||||
}
|
||||
if (victim_thd->wsrep_aborter && victim_thd->wsrep_aborter != bf_thd->thread_id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
victim_thd->wsrep_aborter= bf_thd->thread_id;
|
||||
WSREP_DEBUG("wsrep_thd_set_wsrep_aborter setting wsrep_aborter %u",
|
||||
victim_thd->wsrep_aborter);
|
||||
return false;
|
||||
}
|
||||
|
||||
extern "C" void wsrep_report_bf_lock_wait(const THD *thd,
|
||||
unsigned long long trx_id)
|
||||
{
|
||||
|
||||
@@ -1082,19 +1082,13 @@ Sql_condition* THD::raise_condition(const Sql_condition *cond)
|
||||
goto ret;
|
||||
|
||||
switch (level) {
|
||||
case Sql_condition::WARN_LEVEL_NOTE:
|
||||
case Sql_condition::WARN_LEVEL_WARN:
|
||||
mysql_audit_general(this, MYSQL_AUDIT_GENERAL_WARNING, sql_errno, msg);
|
||||
/* fall through */
|
||||
case Sql_condition::WARN_LEVEL_NOTE:
|
||||
got_warning= 1;
|
||||
break;
|
||||
case Sql_condition::WARN_LEVEL_ERROR:
|
||||
break;
|
||||
case Sql_condition::WARN_LEVEL_END:
|
||||
/* Impossible */
|
||||
break;
|
||||
}
|
||||
|
||||
if (level == Sql_condition::WARN_LEVEL_ERROR)
|
||||
{
|
||||
mysql_audit_general(this, MYSQL_AUDIT_GENERAL_ERROR, sql_errno, msg);
|
||||
|
||||
is_slave_error= 1; // needed to catch query errors during replication
|
||||
@@ -1118,6 +1112,10 @@ Sql_condition* THD::raise_condition(const Sql_condition *cond)
|
||||
da->set_error_status(sql_errno, msg, sqlstate, *cond, raised);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Sql_condition::WARN_LEVEL_END:
|
||||
/* Impossible */
|
||||
break;
|
||||
}
|
||||
|
||||
query_cache_abort(this, &query_cache_tls);
|
||||
@@ -1294,6 +1292,11 @@ void THD::init()
|
||||
wsrep_affected_rows = 0;
|
||||
m_wsrep_next_trx_id = WSREP_UNDEFINED_TRX_ID;
|
||||
wsrep_aborter = 0;
|
||||
wsrep_abort_by_kill = NOT_KILLED;
|
||||
wsrep_abort_by_kill_err = 0;
|
||||
#ifndef DBUG_OFF
|
||||
wsrep_killed_state = 0;
|
||||
#endif /* DBUG_OFF */
|
||||
wsrep_desynced_backup_stage= false;
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
@@ -1642,6 +1645,13 @@ void THD::reset_for_reuse()
|
||||
#endif
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_free_status(this);
|
||||
wsrep_cs().reset_error();
|
||||
wsrep_aborter= 0;
|
||||
wsrep_abort_by_kill= NOT_KILLED;
|
||||
wsrep_abort_by_kill_err= 0;
|
||||
#ifndef DBUG_OFF
|
||||
wsrep_killed_state= 0;
|
||||
#endif /* DBUG_OFF */
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
|
||||
@@ -1898,7 +1908,9 @@ void THD::awake_no_mutex(killed_state state_to_set)
|
||||
}
|
||||
|
||||
/* Interrupt target waiting inside a storage engine. */
|
||||
if (state_to_set != NOT_KILLED && !wsrep_is_bf_aborted(this))
|
||||
if (state_to_set != NOT_KILLED &&
|
||||
IF_WSREP(!wsrep_is_bf_aborted(this) && wsrep_abort_by_kill == NOT_KILLED,
|
||||
true))
|
||||
ha_kill_query(this, thd_kill_level(this));
|
||||
|
||||
abort_current_cond_wait(false);
|
||||
@@ -2126,6 +2138,17 @@ void THD::reset_killed()
|
||||
mysql_mutex_unlock(&LOCK_thd_kill);
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_NNULL(this))
|
||||
{
|
||||
if (wsrep_abort_by_kill != NOT_KILLED)
|
||||
{
|
||||
mysql_mutex_assert_not_owner(&LOCK_thd_kill);
|
||||
mysql_mutex_lock(&LOCK_thd_kill);
|
||||
wsrep_abort_by_kill= NOT_KILLED;
|
||||
wsrep_abort_by_kill_err= 0;
|
||||
mysql_mutex_unlock(&LOCK_thd_kill);
|
||||
}
|
||||
}
|
||||
mysql_mutex_assert_not_owner(&LOCK_thd_data);
|
||||
mysql_mutex_lock(&LOCK_thd_data);
|
||||
wsrep_aborter= 0;
|
||||
|
||||
@@ -5384,7 +5384,14 @@ public:
|
||||
bool wsrep_ignore_table;
|
||||
/* thread who has started kill for this THD protected by LOCK_thd_data*/
|
||||
my_thread_id wsrep_aborter;
|
||||
|
||||
/* Kill signal used, if thread was killed by manual KILL. Protected by
|
||||
LOCK_thd_kill. */
|
||||
std::atomic<killed_state> wsrep_abort_by_kill;
|
||||
/* */
|
||||
struct err_info* wsrep_abort_by_kill_err;
|
||||
#ifndef DBUG_OFF
|
||||
int wsrep_killed_state;
|
||||
#endif /* DBUG_OFF */
|
||||
/* true if BF abort is observed in do_command() right after reading
|
||||
client's packet, and if the client has sent PS execute command. */
|
||||
bool wsrep_delayed_BF_abort;
|
||||
|
||||
@@ -61,6 +61,15 @@ class Select_limit_counters
|
||||
with_ties= false;
|
||||
}
|
||||
|
||||
/* Send the first row, still honoring offset_limit_cnt */
|
||||
void send_first_row()
|
||||
{
|
||||
/* Guard against overflow */
|
||||
if ((select_limit_cnt= offset_limit_cnt +1 ) == 0)
|
||||
select_limit_cnt= offset_limit_cnt;
|
||||
// with_ties= false; Remove // on merge to 10.6
|
||||
}
|
||||
|
||||
bool is_unlimited() const
|
||||
{ return select_limit_cnt == HA_POS_ERROR; }
|
||||
/*
|
||||
|
||||
@@ -9224,23 +9224,20 @@ kill_one_thread(THD *thd, my_thread_id id, killed_state kill_signal, killed_type
|
||||
thd->security_ctx->user_matches(tmp->security_ctx))
|
||||
#endif /* WITH_WSREP */
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
DEBUG_SYNC(thd, "before_awake_no_mutex");
|
||||
if (tmp->wsrep_aborter && tmp->wsrep_aborter != thd->thread_id)
|
||||
{
|
||||
/* victim is in hit list already, bail out */
|
||||
WSREP_DEBUG("victim %lld has wsrep aborter: %lu, skipping awake()",
|
||||
id, tmp->wsrep_aborter);
|
||||
error= 0;
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(tmp))
|
||||
{
|
||||
error = wsrep_kill_thd(thd, tmp, kill_signal);
|
||||
}
|
||||
else
|
||||
#endif /* WITH_WSREP */
|
||||
{
|
||||
WSREP_DEBUG("kill_one_thread victim: %lld wsrep_aborter %lu"
|
||||
" by signal %d",
|
||||
id, tmp->wsrep_aborter, kill_signal);
|
||||
#endif /* WITH_WSREP */
|
||||
tmp->awake_no_mutex(kill_signal);
|
||||
error= 0;
|
||||
#ifdef WITH_WSREP
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -9363,18 +9360,6 @@ static
|
||||
void sql_kill(THD *thd, my_thread_id id, killed_state state, killed_type type)
|
||||
{
|
||||
uint error;
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
{
|
||||
WSREP_DEBUG("sql_kill called");
|
||||
if (thd->wsrep_applier)
|
||||
{
|
||||
WSREP_DEBUG("KILL in applying, bailing out here");
|
||||
return;
|
||||
}
|
||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
if (likely(!(error= kill_one_thread(thd, id, state, type))))
|
||||
{
|
||||
if (!thd->killed)
|
||||
@@ -9384,11 +9369,6 @@ void sql_kill(THD *thd, my_thread_id id, killed_state state, killed_type type)
|
||||
}
|
||||
else
|
||||
my_error(error, MYF(0), id);
|
||||
#ifdef WITH_WSREP
|
||||
return;
|
||||
wsrep_error_label:
|
||||
my_error(ER_KILL_DENIED_ERROR, MYF(0), (long long) thd->thread_id);
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
|
||||
|
||||
@@ -9397,18 +9377,6 @@ sql_kill_user(THD *thd, LEX_USER *user, killed_state state)
|
||||
{
|
||||
uint error;
|
||||
ha_rows rows;
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
{
|
||||
WSREP_DEBUG("sql_kill_user called");
|
||||
if (thd->wsrep_applier)
|
||||
{
|
||||
WSREP_DEBUG("KILL in applying, bailing out here");
|
||||
return;
|
||||
}
|
||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
switch (error= kill_threads_for_user(thd, user, state, &rows))
|
||||
{
|
||||
case 0:
|
||||
@@ -9424,11 +9392,6 @@ sql_kill_user(THD *thd, LEX_USER *user, killed_state state)
|
||||
default:
|
||||
my_error(error, MYF(0));
|
||||
}
|
||||
#ifdef WITH_WSREP
|
||||
return;
|
||||
wsrep_error_label:
|
||||
my_error(ER_KILL_DENIED_ERROR, MYF(0), (long long) thd->thread_id);
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -151,6 +151,7 @@ static struct wsrep_service_st wsrep_handler = {
|
||||
wsrep_on,
|
||||
wsrep_prepare_key_for_innodb,
|
||||
wsrep_thd_LOCK,
|
||||
wsrep_thd_TRYLOCK,
|
||||
wsrep_thd_UNLOCK,
|
||||
wsrep_thd_query,
|
||||
wsrep_thd_retry_counter,
|
||||
@@ -179,7 +180,6 @@ static struct wsrep_service_st wsrep_handler = {
|
||||
wsrep_OSU_method_get,
|
||||
wsrep_thd_has_ignored_error,
|
||||
wsrep_thd_set_ignored_error,
|
||||
wsrep_thd_set_wsrep_aborter,
|
||||
wsrep_report_bf_lock_wait,
|
||||
wsrep_thd_kill_LOCK,
|
||||
wsrep_thd_kill_UNLOCK,
|
||||
|
||||
@@ -185,10 +185,10 @@ static void update_depend_map_for_order(JOIN *join, ORDER *order);
|
||||
static ORDER *remove_const(JOIN *join,ORDER *first_order,COND *cond,
|
||||
bool change_list, bool *simple_order);
|
||||
static int return_zero_rows(JOIN *join, select_result *res,
|
||||
List<TABLE_LIST> &tables,
|
||||
List<Item> &fields, bool send_row,
|
||||
List<TABLE_LIST> *tables,
|
||||
List<Item> *fields, bool send_row,
|
||||
ulonglong select_options, const char *info,
|
||||
Item *having, List<Item> &all_fields);
|
||||
Item *having, List<Item> *all_fields);
|
||||
static COND *build_equal_items(JOIN *join, COND *cond,
|
||||
COND_EQUAL *inherited,
|
||||
List<TABLE_LIST> *join_list,
|
||||
@@ -1341,11 +1341,40 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
Check fields, find best join, do the select and output fields.
|
||||
mysql_select assumes that all tables are already opened
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
Check if we have a field reference. If yes, we have to use
|
||||
mixed_implicit_grouping.
|
||||
*/
|
||||
|
||||
static bool check_list_for_field(List<Item> *items)
|
||||
{
|
||||
List_iterator_fast <Item> select_it(*items);
|
||||
Item *select_el;
|
||||
|
||||
while ((select_el= select_it++))
|
||||
{
|
||||
if (select_el->with_field())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool check_list_for_field(ORDER *order)
|
||||
{
|
||||
for (; order; order= order->next)
|
||||
{
|
||||
if (order->item[0]->with_field())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Prepare of whole select (including sub queries in future).
|
||||
@@ -1427,52 +1456,43 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num,
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
/*
|
||||
TRUE if the SELECT list mixes elements with and without grouping,
|
||||
and there is no GROUP BY clause. Mixing non-aggregated fields with
|
||||
aggregate functions in the SELECT list is a MySQL extenstion that
|
||||
is allowed only if the ONLY_FULL_GROUP_BY sql mode is not set.
|
||||
mixed_implicit_grouping will be set to TRUE if the SELECT list
|
||||
mixes elements with and without grouping, and there is no GROUP BY
|
||||
clause.
|
||||
Mixing non-aggregated fields with aggregate functions in the
|
||||
SELECT list or HAVING is a MySQL extension that is allowed only if
|
||||
the ONLY_FULL_GROUP_BY sql mode is not set.
|
||||
*/
|
||||
mixed_implicit_grouping= false;
|
||||
if ((~thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) &&
|
||||
select_lex->with_sum_func && !group_list)
|
||||
{
|
||||
List_iterator_fast <Item> select_it(fields_list);
|
||||
Item *select_el; /* Element of the SELECT clause, can be an expression. */
|
||||
bool found_field_elem= false;
|
||||
bool found_sum_func_elem= false;
|
||||
|
||||
while ((select_el= select_it++))
|
||||
if (check_list_for_field(&fields_list) ||
|
||||
check_list_for_field(order))
|
||||
{
|
||||
if (select_el->with_sum_func())
|
||||
found_sum_func_elem= true;
|
||||
if (select_el->with_field())
|
||||
found_field_elem= true;
|
||||
if (found_sum_func_elem && found_field_elem)
|
||||
{
|
||||
mixed_implicit_grouping= true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table_count= select_lex->leaf_tables.elements;
|
||||
|
||||
TABLE_LIST *tbl;
|
||||
List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables);
|
||||
while ((tbl= li++))
|
||||
|
||||
mixed_implicit_grouping= true; // mark for future
|
||||
|
||||
while (TABLE_LIST *tbl= li++)
|
||||
{
|
||||
/*
|
||||
If the query uses implicit grouping where the select list contains both
|
||||
aggregate functions and non-aggregate fields, any non-aggregated field
|
||||
may produce a NULL value. Set all fields of each table as nullable before
|
||||
semantic analysis to take into account this change of nullability.
|
||||
If the query uses implicit grouping where the select list
|
||||
contains both aggregate functions and non-aggregate fields,
|
||||
any non-aggregated field may produce a NULL value. Set all
|
||||
fields of each table as nullable before semantic analysis to
|
||||
take into account this change of nullability.
|
||||
|
||||
Note: this loop doesn't touch tables inside merged semi-joins, because
|
||||
subquery-to-semijoin conversion has not been done yet. This is intended.
|
||||
Note: this loop doesn't touch tables inside merged
|
||||
semi-joins, because subquery-to-semijoin conversion has not
|
||||
been done yet. This is intended.
|
||||
*/
|
||||
if (mixed_implicit_grouping && tbl->table)
|
||||
if (tbl->table)
|
||||
tbl->table->maybe_null= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
table_count= select_lex->leaf_tables.elements;
|
||||
|
||||
uint real_og_num= og_num;
|
||||
if (skip_order_by &&
|
||||
@@ -1493,7 +1513,7 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num,
|
||||
|
||||
{
|
||||
List_iterator_fast<TABLE_LIST> it(select_lex->leaf_tables);
|
||||
while ((tbl= it++))
|
||||
while (TABLE_LIST *tbl= it++)
|
||||
{
|
||||
if (tbl->table_function &&
|
||||
tbl->table_function->setup(thd, tbl, select_lex_arg))
|
||||
@@ -4135,7 +4155,7 @@ bool JOIN::make_aggr_tables_info()
|
||||
set_items_ref_array(items0);
|
||||
if (join_tab)
|
||||
join_tab[exec_join_tab_cnt() + aggr_tables - 1].next_select=
|
||||
setup_end_select_func(this, NULL);
|
||||
setup_end_select_func(this);
|
||||
group= has_group_by;
|
||||
|
||||
DBUG_RETURN(false);
|
||||
@@ -4537,13 +4557,7 @@ JOIN::reinit()
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset of sum functions */
|
||||
if (sum_funcs)
|
||||
{
|
||||
Item_sum *func, **func_ptr= sum_funcs;
|
||||
while ((func= *(func_ptr++)))
|
||||
func->clear();
|
||||
}
|
||||
clear_sum_funcs();
|
||||
|
||||
if (no_rows_in_result_called)
|
||||
{
|
||||
@@ -4828,12 +4842,12 @@ int JOIN::exec_inner()
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) return_zero_rows(this, result, select_lex->leaf_tables,
|
||||
*columns_list,
|
||||
(void) return_zero_rows(this, result, &select_lex->leaf_tables,
|
||||
columns_list,
|
||||
send_row_on_empty_set(),
|
||||
select_options,
|
||||
zero_result_cause,
|
||||
having ? having : tmp_having, all_fields);
|
||||
having ? having : tmp_having, &all_fields);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
}
|
||||
@@ -9099,7 +9113,7 @@ best_access_path(JOIN *join,
|
||||
{
|
||||
Json_writer_object trace_access_hash(thd);
|
||||
double refills, row_copy_cost, copy_cost, cur_cost, where_cost;
|
||||
double matching_combinations, fanout, join_sel;
|
||||
double matching_combinations, fanout= 0.0, join_sel;
|
||||
trace_access_hash.add("type", "hash");
|
||||
trace_access_hash.add("index", "hj-key");
|
||||
/* Estimate the cost of the hash join access to the table */
|
||||
@@ -16773,10 +16787,36 @@ ORDER *simple_remove_const(ORDER *order, COND *where)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Set all fields in the table to have a null value
|
||||
|
||||
@param tables Table list
|
||||
*/
|
||||
|
||||
static void make_tables_null_complemented(List<TABLE_LIST> *tables)
|
||||
{
|
||||
List_iterator<TABLE_LIST> ti(*tables);
|
||||
TABLE_LIST *table;
|
||||
while ((table= ti++))
|
||||
{
|
||||
/*
|
||||
Don't touch semi-join materialization tables, as the a join_free()
|
||||
call may have freed them (and HAVING clause can't have references to
|
||||
them anyway).
|
||||
*/
|
||||
if (!table->is_jtbm())
|
||||
{
|
||||
TABLE *tbl= table->table;
|
||||
mark_as_null_row(tbl); // Set fields to NULL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables,
|
||||
List<Item> &fields, bool send_row, ulonglong select_options,
|
||||
const char *info, Item *having, List<Item> &all_fields)
|
||||
return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> *tables,
|
||||
List<Item> *fields, bool send_row, ulonglong select_options,
|
||||
const char *info, Item *having, List<Item> *all_fields)
|
||||
{
|
||||
DBUG_ENTER("return_zero_rows");
|
||||
|
||||
@@ -16792,24 +16832,15 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables,
|
||||
Set all tables to have NULL row. This is needed as we will be evaluating
|
||||
HAVING condition.
|
||||
*/
|
||||
List_iterator<TABLE_LIST> ti(tables);
|
||||
TABLE_LIST *table;
|
||||
while ((table= ti++))
|
||||
{
|
||||
/*
|
||||
Don't touch semi-join materialization tables, as the above join_free()
|
||||
call has freed them (and HAVING clause can't have references to them
|
||||
anyway).
|
||||
*/
|
||||
if (!table->is_jtbm())
|
||||
mark_as_null_row(table->table); // All fields are NULL
|
||||
}
|
||||
List_iterator_fast<Item> it(all_fields);
|
||||
make_tables_null_complemented(tables);
|
||||
|
||||
List_iterator_fast<Item> it(*all_fields);
|
||||
Item *item;
|
||||
/*
|
||||
Inform all items (especially aggregating) to calculate HAVING correctly,
|
||||
also we will need it for sending results.
|
||||
*/
|
||||
join->no_rows_in_result_called= 1;
|
||||
while ((item= it++))
|
||||
item->no_rows_in_result();
|
||||
if (having && having->val_int() == 0)
|
||||
@@ -16823,12 +16854,12 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables,
|
||||
join->thd->limit_found_rows= 0;
|
||||
}
|
||||
|
||||
if (!(result->send_result_set_metadata(fields,
|
||||
if (!(result->send_result_set_metadata(*fields,
|
||||
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)))
|
||||
{
|
||||
bool send_error= FALSE;
|
||||
if (send_row)
|
||||
send_error= result->send_data_with_check(fields, join->unit, 0) > 0;
|
||||
send_error= result->send_data_with_check(*fields, join->unit, 0) > 0;
|
||||
if (likely(!send_error))
|
||||
result->send_eof(); // Should be safe
|
||||
}
|
||||
@@ -16844,31 +16875,25 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables,
|
||||
}
|
||||
|
||||
/**
|
||||
used only in JOIN::clear (always) and in do_select()
|
||||
(if there where no matching rows)
|
||||
Reset table rows to contain a null-complement row (all fields are null)
|
||||
|
||||
Used only in JOIN::clear() and in do_select() if there where no matching rows.
|
||||
|
||||
@param join JOIN
|
||||
@param cleared_tables If not null, clear also const tables and mark all
|
||||
cleared tables in the map. cleared_tables is only
|
||||
set when called from do_select() when there is a
|
||||
group function and there where no matching rows.
|
||||
@param cleared_tables Used to mark all cleared tables in the map. Needed for
|
||||
unclear_tables() to know which tables to restore to
|
||||
their original state.
|
||||
*/
|
||||
|
||||
static void clear_tables(JOIN *join, table_map *cleared_tables)
|
||||
{
|
||||
/*
|
||||
must clear only the non-const tables as const tables are not re-calculated.
|
||||
*/
|
||||
DBUG_ASSERT(cleared_tables);
|
||||
for (uint i= 0 ; i < join->table_count ; i++)
|
||||
{
|
||||
TABLE *table= join->table[i];
|
||||
|
||||
if (table->null_row)
|
||||
continue; // Nothing more to do
|
||||
if (!(table->map & join->const_table_map) || cleared_tables)
|
||||
{
|
||||
if (cleared_tables)
|
||||
{
|
||||
(*cleared_tables)|= (((table_map) 1) << i);
|
||||
if (table->s->null_bytes)
|
||||
{
|
||||
@@ -16878,15 +16903,14 @@ static void clear_tables(JOIN *join, table_map *cleared_tables)
|
||||
*/
|
||||
memcpy(table->record[1], table->null_flags, table->s->null_bytes);
|
||||
}
|
||||
}
|
||||
mark_as_null_row(table); // All fields are NULL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Reverse null marking for tables and restore null bits.
|
||||
This return the tables to the state of before clear_tables().
|
||||
|
||||
We have to do this because the tables may be re-used in a sub query
|
||||
and the subquery will assume that the const tables contains the original
|
||||
@@ -22699,9 +22723,9 @@ void set_postjoin_aggr_write_func(JOIN_TAB *tab)
|
||||
end_select function to use. This function can't fail.
|
||||
*/
|
||||
|
||||
Next_select_func setup_end_select_func(JOIN *join, JOIN_TAB *tab)
|
||||
Next_select_func setup_end_select_func(JOIN *join)
|
||||
{
|
||||
TMP_TABLE_PARAM *tmp_tbl= tab ? tab->tmp_table_param : &join->tmp_table_param;
|
||||
TMP_TABLE_PARAM *tmp_tbl= &join->tmp_table_param;
|
||||
|
||||
/*
|
||||
Choose method for presenting result to user. Use end_send_group
|
||||
@@ -22774,7 +22798,7 @@ do_select(JOIN *join, Procedure *procedure)
|
||||
|
||||
if (join->only_const_tables() && !join->need_tmp)
|
||||
{
|
||||
Next_select_func end_select= setup_end_select_func(join, NULL);
|
||||
Next_select_func end_select= setup_end_select_func(join);
|
||||
|
||||
/*
|
||||
HAVING will be checked after processing aggregate functions,
|
||||
@@ -23264,6 +23288,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore state if mark_as_null_row() have been called */
|
||||
if (join_tab->last_inner)
|
||||
{
|
||||
JOIN_TAB *last_inner_tab= join_tab->last_inner;
|
||||
@@ -24715,6 +24740,12 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
|
||||
{
|
||||
int idx= -1;
|
||||
enum_nested_loop_state ok_code= NESTED_LOOP_OK;
|
||||
/*
|
||||
join_tab can be 0 in the case all tables are const tables and we did not
|
||||
need a temporary table to store the result.
|
||||
In this case we use the original given fields, which is stored in
|
||||
join->fields.
|
||||
*/
|
||||
List<Item> *fields= join_tab ? (join_tab-1)->fields : join->fields;
|
||||
DBUG_ENTER("end_send_group");
|
||||
|
||||
@@ -24724,10 +24755,12 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
|
||||
if (!join->first_record || end_of_records ||
|
||||
(idx=test_if_group_changed(join->group_fields)) >= 0)
|
||||
{
|
||||
|
||||
if (!join->group_sent &&
|
||||
(join->first_record ||
|
||||
(end_of_records && !join->group && !join->group_optimized_away)))
|
||||
{
|
||||
table_map cleared_tables= (table_map) 0;
|
||||
if (join->procedure)
|
||||
join->procedure->end_group();
|
||||
/* Test if there was a group change. */
|
||||
@@ -24752,11 +24785,13 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
|
||||
/* Reset all sum functions on group change. */
|
||||
if (!join->first_record)
|
||||
{
|
||||
List_iterator_fast<Item> it(*join->fields);
|
||||
Item *item;
|
||||
/* No matching rows for group function */
|
||||
join->clear();
|
||||
|
||||
List_iterator_fast<Item> it(*fields);
|
||||
Item *item;
|
||||
join->no_rows_in_result_called= 1;
|
||||
|
||||
join->clear(&cleared_tables);
|
||||
while ((item= it++))
|
||||
item->no_rows_in_result();
|
||||
}
|
||||
@@ -24784,6 +24819,13 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
|
||||
if (join->rollup_send_data((uint) (idx+1)))
|
||||
error= 1;
|
||||
}
|
||||
if (join->no_rows_in_result_called)
|
||||
{
|
||||
/* Restore null tables to original state */
|
||||
join->no_rows_in_result_called= 0;
|
||||
if (cleared_tables)
|
||||
unclear_tables(join, &cleared_tables);
|
||||
}
|
||||
}
|
||||
if (unlikely(error > 0))
|
||||
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
|
||||
@@ -25100,6 +25142,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
||||
{
|
||||
if (join->first_record || (end_of_records && !join->group))
|
||||
{
|
||||
table_map cleared_tables= (table_map) 0;
|
||||
if (join->procedure)
|
||||
join->procedure->end_group();
|
||||
int send_group_parts= join->send_group_parts;
|
||||
@@ -25108,7 +25151,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
||||
if (!join->first_record)
|
||||
{
|
||||
/* No matching rows for group function */
|
||||
join->clear();
|
||||
join->clear(&cleared_tables);
|
||||
}
|
||||
copy_sum_funcs(join->sum_funcs,
|
||||
join->sum_funcs_end[send_group_parts]);
|
||||
@@ -25131,6 +25174,8 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
||||
DBUG_RETURN(NESTED_LOOP_ERROR);
|
||||
}
|
||||
}
|
||||
if (cleared_tables)
|
||||
unclear_tables(join, &cleared_tables);
|
||||
if (end_of_records)
|
||||
goto end;
|
||||
}
|
||||
@@ -26864,7 +26909,7 @@ JOIN_TAB::remove_duplicates()
|
||||
!(join->select_options & OPTION_FOUND_ROWS))
|
||||
{
|
||||
// only const items with no OPTION_FOUND_ROWS
|
||||
join->unit->lim.set_single_row(); // Only send first row
|
||||
join->unit->lim.send_first_row(); // Only send first row
|
||||
my_free(sortorder);
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
@@ -29279,11 +29324,8 @@ int JOIN::rollup_write_data(uint idx, TMP_TABLE_PARAM *tmp_table_param_arg,
|
||||
(end_send_group/end_write_group)
|
||||
*/
|
||||
|
||||
void JOIN::clear()
|
||||
void inline JOIN::clear_sum_funcs()
|
||||
{
|
||||
clear_tables(this, 0);
|
||||
copy_fields(&tmp_table_param);
|
||||
|
||||
if (sum_funcs)
|
||||
{
|
||||
Item_sum *func, **func_ptr= sum_funcs;
|
||||
@@ -29293,6 +29335,22 @@ void JOIN::clear()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Prepare for returning 'empty row' when there is no matching row.
|
||||
|
||||
- Mark all tables with mark_as_null_row()
|
||||
- Make a copy of of all simple SELECT items
|
||||
- Reset all sum functions to NULL or 0.
|
||||
*/
|
||||
|
||||
void JOIN::clear(table_map *cleared_tables)
|
||||
{
|
||||
clear_tables(this, cleared_tables);
|
||||
copy_fields(&tmp_table_param);
|
||||
clear_sum_funcs();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Print an EXPLAIN line with all NULLs and given message in the 'Extra' column
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ enum sj_strategy_enum
|
||||
|
||||
typedef enum_nested_loop_state
|
||||
(*Next_select_func)(JOIN *, struct st_join_table *, bool);
|
||||
Next_select_func setup_end_select_func(JOIN *join, JOIN_TAB *tab);
|
||||
Next_select_func setup_end_select_func(JOIN *join);
|
||||
int rr_sequential(READ_RECORD *info);
|
||||
int read_record_func_for_rr_and_unpack(READ_RECORD *info);
|
||||
Item *remove_pushed_top_conjuncts(THD *thd, Item *cond);
|
||||
@@ -1812,7 +1812,8 @@ public:
|
||||
void join_free();
|
||||
/** Cleanup this JOIN, possibly for reuse */
|
||||
void cleanup(bool full);
|
||||
void clear();
|
||||
void clear(table_map *cleared_tables);
|
||||
void inline clear_sum_funcs();
|
||||
bool send_row_on_empty_set()
|
||||
{
|
||||
return (do_send_rows && implicit_grouping && !group_optimized_away &&
|
||||
|
||||
@@ -7574,8 +7574,9 @@ extern Named_type_handler<Type_handler_time> type_handler_time;
|
||||
extern Named_type_handler<Type_handler_time2> type_handler_time2;
|
||||
extern Named_type_handler<Type_handler_datetime> type_handler_datetime;
|
||||
extern Named_type_handler<Type_handler_datetime2> type_handler_datetime2;
|
||||
extern Named_type_handler<Type_handler_timestamp> type_handler_timestamp;
|
||||
extern Named_type_handler<Type_handler_timestamp2> type_handler_timestamp2;
|
||||
|
||||
extern MYSQL_PLUGIN_IMPORT Named_type_handler<Type_handler_timestamp> type_handler_timestamp;
|
||||
extern MYSQL_PLUGIN_IMPORT Named_type_handler<Type_handler_timestamp2> type_handler_timestamp2;
|
||||
|
||||
extern Type_handler_interval_DDhhmmssff type_handler_interval_DDhhmmssff;
|
||||
|
||||
|
||||
10
sql/table.h
10
sql/table.h
@@ -3445,10 +3445,16 @@ inline void mark_as_null_row(TABLE *table)
|
||||
bfill(table->null_flags,table->s->null_bytes,255);
|
||||
}
|
||||
|
||||
/*
|
||||
Restore table to state before mark_as_null_row() call.
|
||||
This assumes that the caller has restored table->null_flags,
|
||||
as is done in unclear_tables().
|
||||
*/
|
||||
|
||||
inline void unmark_as_null_row(TABLE *table)
|
||||
{
|
||||
table->null_row=0;
|
||||
table->status= STATUS_NO_RECORD;
|
||||
table->null_row= 0;
|
||||
table->status&= ~STATUS_NULL_ROW;
|
||||
}
|
||||
|
||||
bool is_simple_order(ORDER *order);
|
||||
|
||||
@@ -56,6 +56,11 @@ my_bool wsrep_on(const THD *)
|
||||
void wsrep_thd_LOCK(const THD *)
|
||||
{ }
|
||||
|
||||
int wsrep_thd_TRYLOCK(const THD *)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wsrep_thd_UNLOCK(const THD *)
|
||||
{ }
|
||||
|
||||
@@ -154,8 +159,6 @@ void wsrep_thd_set_ignored_error(THD*, my_bool)
|
||||
{ }
|
||||
ulong wsrep_OSU_method_get(const THD*)
|
||||
{ return 0;}
|
||||
bool wsrep_thd_set_wsrep_aborter(THD*, THD*)
|
||||
{ return 0;}
|
||||
|
||||
void wsrep_report_bf_lock_wait(const THD*,
|
||||
unsigned long long)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user