Merge 10.4 into 10.5

This commit is contained in:
Marko Mäkelä 2020-04-29 15:40:51 +03:00
commit 496d0372ef
98 changed files with 2800 additions and 1292 deletions

View File

@ -128,6 +128,8 @@ SET(INSTALL_SUPPORTFILESDIR_STANDALONE "support-files")
SET(INSTALL_MYSQLDATADIR_STANDALONE "data")
SET(INSTALL_UNIX_ADDRDIR_STANDALONE "/tmp/mysql.sock")
SET(INSTALL_PAMDIR_STANDALONE "share")
SET(INSTALL_PAMDATADIR_STANDALONE "share")
#
# RPM layout
#
@ -164,6 +166,7 @@ SET(INSTALL_SYSTEMD_UNITDIR_RPM "/usr/lib/systemd/system")
SET(INSTALL_SYSTEMD_SYSUSERSDIR_RPM "/usr/lib/sysusers.d")
SET(INSTALL_SYSTEMD_TMPFILESDIR_RPM "/usr/lib/tmpfiles.d")
SET(INSTALL_PAMDIR_RPM "/${INSTALL_LIBDIR_RPM}/security")
SET(INSTALL_PAMDATADIR_RPM "/etc/security")
#
# DEB layout
@ -197,6 +200,7 @@ SET(INSTALL_SYSTEMD_UNITDIR_DEB "/lib/systemd/system")
SET(INSTALL_SYSTEMD_SYSUSERSDIR_DEB "/usr/lib/sysusers.d")
SET(INSTALL_SYSTEMD_TMPFILESDIR_DEB "/usr/lib/tmpfiles.d")
SET(INSTALL_PAMDIR_DEB "/lib/${CMAKE_CXX_LIBRARY_ARCHITECTURE}/security")
SET(INSTALL_PAMDATADIR_DEB "/etc/security")
#
# SVR4 layout

View File

@ -30,7 +30,7 @@ mysql_upgradedir=/var/lib/mysql-upgrade
stop_server() {
# Return immediately if there are no mysql processes running
# as there is no point in trying to shutdown in that case.
if ! pgrep -x mysqld > /dev/null; then return; fi
if ! pgrep -x --ns $$ mysqld > /dev/null; then return; fi
set +e
systemctl stop mysql

View File

@ -875,54 +875,66 @@ Function acquires either a backup tables lock, if supported
by the server, or a global read lock (FLUSH TABLES WITH READ LOCK)
otherwise.
@returns true if lock acquired */
bool
lock_tables(MYSQL *connection)
bool lock_tables(MYSQL *connection)
{
if (have_lock_wait_timeout) {
/* Set the maximum supported session value for
lock_wait_timeout to prevent unnecessary timeouts when the
global value is changed from the default */
xb_mysql_query(connection,
"SET SESSION lock_wait_timeout=31536000", false);
}
if (have_lock_wait_timeout || opt_lock_wait_timeout)
{
char buf[FN_REFLEN];
/* Set the maximum supported session value for
lock_wait_timeout if opt_lock_wait_timeout is not set to prevent
unnecessary timeouts when the global value is changed from the default */
snprintf(buf, sizeof(buf), "SET SESSION lock_wait_timeout=%u",
opt_lock_wait_timeout ? opt_lock_wait_timeout : 31536000);
xb_mysql_query(connection, buf, false);
}
if (have_backup_locks) {
msg("Executing LOCK TABLES FOR BACKUP...");
xb_mysql_query(connection, "LOCK TABLES FOR BACKUP", false);
return(true);
}
if (have_backup_locks)
{
msg("Executing LOCK TABLES FOR BACKUP...");
xb_mysql_query(connection, "LOCK TABLES FOR BACKUP", false);
return (true);
}
if (opt_lock_wait_timeout) {
if (!wait_for_no_updates(connection, opt_lock_wait_timeout,
opt_lock_wait_threshold)) {
return(false);
}
}
if (opt_lock_wait_timeout)
{
if (!wait_for_no_updates(connection, opt_lock_wait_timeout,
opt_lock_wait_threshold))
{
return (false);
}
}
msg("Acquiring BACKUP LOCKS...");
msg("Acquiring BACKUP LOCKS...");
if (opt_kill_long_queries_timeout) {
start_query_killer();
}
if (opt_kill_long_queries_timeout)
{
start_query_killer();
}
if (have_galera_enabled) {
xb_mysql_query(connection,
"SET SESSION wsrep_causal_reads=0", false);
}
if (have_galera_enabled)
{
xb_mysql_query(connection, "SET SESSION wsrep_causal_reads=0", false);
}
xb_mysql_query(connection, "BACKUP STAGE START", true);
//xb_mysql_query(connection, "BACKUP STAGE FLUSH", true);
//xb_mysql_query(connection, "BACKUP STAGE BLOCK_DDL", true);
xb_mysql_query(connection, "BACKUP STAGE BLOCK_COMMIT", true);
xb_mysql_query(connection, "BACKUP STAGE START", true);
// xb_mysql_query(connection, "BACKUP STAGE FLUSH", true);
// xb_mysql_query(connection, "BACKUP STAGE BLOCK_DDL", true);
xb_mysql_query(connection, "BACKUP STAGE BLOCK_COMMIT", true);
/* Set the maximum supported session value for
lock_wait_timeout to prevent unnecessary timeouts when the
global value is changed from the default */
if (opt_lock_wait_timeout)
xb_mysql_query(connection, "SET SESSION lock_wait_timeout=31536000",
false);
if (opt_kill_long_queries_timeout) {
stop_query_killer();
}
if (opt_kill_long_queries_timeout)
{
stop_query_killer();
}
return(true);
return (true);
}
/*********************************************************************//**
If backup locks are used, execute LOCK BINLOG FOR BACKUP provided that we are
not in the --no-lock mode and the lock has not been acquired already.

View File

@ -730,13 +730,14 @@ struct st_my_thread_var
#endif
};
extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
struct st_my_thread_var *_my_thread_var(void);
extern void **my_thread_var_dbug(void);
extern safe_mutex_t **my_thread_var_mutex_in_use(void);
extern uint my_thread_end_wait_time;
extern my_bool safe_mutex_deadlock_detector;
#define my_thread_var (_my_thread_var())
#define my_errno my_thread_var->thr_errno
int set_mysys_var(struct st_my_thread_var *mysys_var);
/*

View File

@ -3,7 +3,7 @@
--let $galera_have_debug_sync = `SELECT 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_debug_sync_waiters'`
--if (!$galera_have_debug_sync) {
--skip "Test requires Galera debug library with debug_sync functionality"
--skip Test requires Galera debug library with debug_sync functionality
}
--enable_query_log

View File

@ -1,4 +0,0 @@
#
# suite.pm will make sure that all tests including this file
# will be skipped as needed
#

View File

@ -1,4 +0,0 @@
#
# suite.pm will make sure that all tests including this file
# will be skipped as needed
#

View File

@ -1,3 +1,4 @@
echo # switching back from mysql.user to mysql.global_priv;
disable_query_log;
drop table mysql.user;
rename table mysql.user_bak to mysql.user;

View File

@ -1,3 +1,4 @@
echo # switching from mysql.global_priv to mysql.user;
disable_query_log;
rename table mysql.user to mysql.user_bak;
CREATE TABLE mysql.user (

View File

@ -100,8 +100,6 @@ else
$bindir = getcwd();
}
our $wsrep_check_version;
# Find the safe process binary or script
sub find_bin {
if (IS_WIN32PERL or IS_CYGWIN)
@ -121,10 +119,6 @@ sub find_bin {
"my_safe_process");
push(@safe_process_cmd, $exe);
}
# Wsrep version check utility:
$wsrep_check_version=
my_find_bin($bindir, ["lib/My/SafeProcess", "My/SafeProcess"],
"wsrep_check_version", NOT_REQUIRED);
}

View File

@ -14,6 +14,8 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
IF (WIN32)
ADD_EXECUTABLE(my_safe_process safe_process_win.cc)
ADD_EXECUTABLE(my_safe_kill safe_kill_win.cc)

View File

@ -13,122 +13,39 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include <stdlib.h>
#include <stdio.h>
#include <my_global.h>
#include <string.h>
#include <errno.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef _WIN32
#include <windows.h>
#define dlsym(lib, name) GetProcAddress((HMODULE)lib, name)
#define dlopen(libname, unused) LoadLibraryEx(libname, NULL, 0)
#define dlclose(lib) FreeLibrary((HMODULE)lib)
#elif defined(HAVE_DLFCN_H)
#include <dlfcn.h>
#else
#define NO_DLL
#endif
#ifndef NO_DLL
#include "../../../../wsrep-lib/wsrep-API/v26/wsrep_api.h"
/**************************************************************************
* Library loader
**************************************************************************/
static int wsrep_check_iface_version(const char *found, const char *iface_ver)
{
if (strcmp(found, iface_ver)) {
return ERANGE;
}
return 0;
}
typedef int (*wsrep_loader_fun)(wsrep_t*);
static wsrep_loader_fun wsrep_dlf(void *dlh, const char *sym)
{
union {
wsrep_loader_fun dlfun;
void *obj;
} alias;
alias.obj = dlsym(dlh, sym);
return alias.dlfun;
}
static int wsrep_check_version_symbol(void *dlh)
{
char** dlversion = NULL;
dlversion = (char**) dlsym(dlh, "wsrep_interface_version");
if (dlversion == NULL)
return EINVAL;
return wsrep_check_iface_version(*dlversion, WSREP_INTERFACE_VERSION);
}
static int wsrep_print_version(void *dlh)
{
char** dlversion = NULL;
dlversion = (char**) dlsym(dlh, "wsrep_interface_version");
if (dlversion == NULL)
return EINVAL;
printf("found: %s, need: %s\n", *dlversion, WSREP_INTERFACE_VERSION);
return 0;
}
int main(int argc, char **argv)
{
int rc = EINVAL;
void *dlh;
wsrep_loader_fun dlfun;
const char *provider= getenv("WSREP_PROVIDER");
int rc= 1;
void *dlh;
const char *provider= getenv("WSREP_PROVIDER");
char** dlversion= NULL;
if (!provider)
{
fprintf(stderr, "WSREP_PROVIDER is not set\n");
return 1;
}
if (!(dlh = dlopen(provider, RTLD_NOW | RTLD_LOCAL)))
{
fprintf(stderr, "Can't open WSREP_PROVIDER (%s) library, error: %s\n",
provider, dlerror());
goto err;
}
if (!(dlfun = wsrep_dlf(dlh, "wsrep_loader")))
{
fprintf(stderr, "Can't find 'wsrep_loader' symbol in %s\n",
provider);
goto err;
}
if (argc < 2 || strcmp(argv[1], "-p")) {
rc = wsrep_check_version_symbol(dlh);
}
else {
rc = wsrep_print_version(dlh);
}
err:
if (dlh) dlclose(dlh);
if (rc == 0)
return 0;
else if (rc == ERANGE)
return 2;
else
return 1;
}
#else
int main(void)
{
if (!provider || !*provider)
{
printf("WSREP_PROVIDER is not set\n");
return 1;
}
}
if (!(dlh= dlopen(provider, RTLD_NOW | RTLD_LOCAL)))
{
printf("Can't open WSREP_PROVIDER (%s) library, error: %s\n",
provider, dlerror());
return 1;
}
#endif
dlversion= (char**) dlsym(dlh, "wsrep_interface_version");
if (dlversion && *dlversion)
{
rc= strcmp(*dlversion, WSREP_INTERFACE_VERSION) ? 2 : 0;
if (rc)
printf("Wrong wsrep provider library version, found: %s, need: %s\n", *dlversion, WSREP_INTERFACE_VERSION);
}
else
printf("Galera library does not contain a version symbol");
dlclose(dlh);
return rc;
}

View File

@ -99,6 +99,7 @@ ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES)
connect(localhost,test,zorro,test,MASTER_PORT,MASTER_SOCKET);
connect fail_con,localhost,test,zorro,;
ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES)
# switching from mysql.global_priv to mysql.user
update mysql.user set plugin="", authentication_string="", password=old_password("gambling2") where user=_binary"test";
flush privileges;
show grants for test@localhost;
@ -168,6 +169,7 @@ ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES)
connect(localhost,test,zorro,test,MASTER_PORT,MASTER_SOCKET);
connect fail_con,localhost,test,zorro,;
ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES)
# switching back from mysql.user to mysql.global_priv
delete from mysql.user where user=_binary"test";
connect con7,localhost,root,,test;
create table t1 (id integer not null auto_increment primary key);
@ -363,6 +365,7 @@ connect(localhost,mysqltest_nouser,,test,MASTER_PORT,MASTER_SOCKET);
connect pcon5,localhost,mysqltest_nouser,,,$MASTER_MYPORT,;
ERROR 28000: Access denied for user 'mysqltest_nouser'@'localhost' (using password: NO)
connection default;
# switching from mysql.global_priv to mysql.user
update mysql.user set plugin='mysql_native_password' where user = 'mysqltest_up1';
update mysql.user set plugin='mysql_old_password' where user = 'mysqltest_up2';
select user, password, plugin, authentication_string from mysql.user
@ -382,6 +385,7 @@ user() current_user()
mysqltest_up2@localhost mysqltest_up2@%
disconnect pcon7;
connection default;
# switching back from mysql.user to mysql.global_priv
DROP USER mysqltest_up1@'%';
DROP USER mysqltest_up2@'%';
#

View File

@ -7,8 +7,10 @@ Got one of the listed errors
insert mysql.global_priv select * from t1;
drop table t1;
flush privileges;
# switching from mysql.global_priv to mysql.user
truncate table mysql.user;
flush privileges;
connect(localhost,u1,,test,MASTER_PORT,MASTER_SOCKET);
connect fail,localhost,u1;
Got one of the listed errors
# switching back from mysql.user to mysql.global_priv

View File

@ -2764,6 +2764,7 @@ DROP USER dummy@localhost;
#
# MDEV-19948 'show grants' return privileges individually
#
# switching from mysql.global_priv to mysql.user
CREATE USER ten2;
GRANT ALL ON *.* TO ten2;
SHOW GRANTS FOR ten2;
@ -2774,6 +2775,7 @@ SHOW GRANTS FOR ten2;
Grants for ten2@%
GRANT ALL PRIVILEGES ON *.* TO `ten2`@`%`
DROP USER ten2;
# switching back from mysql.user to mysql.global_priv
#
# End of 10.3 tests
#

View File

@ -129,6 +129,7 @@ connection default;
disconnect con1;
drop database mysqltest_db1;
drop user mysqltest_u1@localhost;
# switching from mysql.global_priv to mysql.user
call mtr.add_suppression("Table 'mysql.user' doesn't exist");
call mtr.add_suppression("'mysql.user' is not of type 'TABLE'");
rename table mysql.user to mysql.user1;
@ -141,6 +142,8 @@ flush privileges;
ERROR 42S02: Table 'mysql.user' doesn't exist
drop temporary table mysql.user;
rename table mysql.user1 to mysql.user;
# switching back from mysql.user to mysql.global_priv
# switching from mysql.global_priv to mysql.user
call mtr.add_suppression('mysql.user table is damaged');
rename table mysql.user to mysql.user1;
create table mysql.user (Host char(100), User char(100));
@ -148,6 +151,7 @@ flush privileges;
ERROR HY000: Unknown error
drop table mysql.user;
rename table mysql.user1 to mysql.user;
# switching back from mysql.user to mysql.global_priv
End of 5.5 tests
#
# Additional coverage for refactoring which is made as part

View File

@ -1,3 +1,4 @@
# switching from mysql.global_priv to mysql.user
set global sql_mode="";
set local sql_mode="";
alter table mysql.user modify User char(16) binary not null default '';
@ -33,3 +34,4 @@ def user() 253 141 14 N 1 39 8
user()
root@localhost
set global sql_mode=default;
# switching back from mysql.user to mysql.global_priv

View File

@ -0,0 +1,9 @@
call mtr.add_suppression("mysql.user");
# switching from mysql.global_priv to mysql.user
flush tables;
flush privileges;
Warnings:
Error 145 Table './mysql/user' is marked as crashed and should be repaired
Warning 1034 12544 clients are using or haven't closed the table properly
Note 1034 Table is fixed
# switching back from mysql.user to mysql.global_priv

View File

@ -0,0 +1,21 @@
#
# MDEV-20257 Server crashes in Grant_table_base::init_read_record upon crash-upgrade
#
source include/not_embedded.inc;
call mtr.add_suppression("mysql.user");
source include/switch_to_mysql_user.inc;
let mysql_datadir=`select @@datadir`;
flush tables;
perl;
$f=$ENV{mysql_datadir} . '/mysql/user.MAI';
sysopen F, $f, 2 or die "sysopen $f: $!";
# set the open_count to 1, "table was not closed properly"
sysseek F, 24, O_RDWR or die "sysseek: $!";
syswrite F, 1, 1 or die "syswrite: $!";
EOF
replace_result \\ /;
flush privileges;
source include/switch_to_mysql_global_priv.inc;

View File

@ -575,6 +575,7 @@ SET GLOBAL enforce_storage_engine=NULL;
# Ensure that mysql_upgrade correctly sets truncate_versioning_priv
# on upgrade from 10.2
#
# switching from mysql.global_priv to mysql.user
drop view mysql.user_bak;
CREATE USER 'user3'@'%';
GRANT USAGE ON *.* TO 'user3'@'%';
@ -593,6 +594,7 @@ update mysql.db set Delete_history_priv='Y' where db like 'test%';
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
# End of 10.3 tests
# switching from mysql.global_priv to mysql.user
drop view mysql.user_bak;
create user 'user3'@'localhost' identified with mysql_native_password as password('a_password');
show create user user3@localhost;
@ -625,9 +627,19 @@ connection default;
drop user user3@localhost;
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
# switching from mysql.global_priv to mysql.user
drop view mysql.user_bak;
drop table mysql.innodb_index_stats, mysql.innodb_table_stats;
# mysql_upgrade --force --silent 2>&1
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
# switching from mysql.global_priv to mysql.user
drop view mysql.user_bak;
alter table mysql.user change authentication_string auth_string text collate utf8_bin not null;
# mysql_upgrade --force --silent 2>&1
select count(*) from mysql.global_priv;
count(*)
4
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
# End of 10.4 tests

View File

@ -282,4 +282,17 @@ drop table mysql.innodb_index_stats, mysql.innodb_table_stats;
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
#
# MDEV-21244 mysql_upgrade creating empty global_priv table
#
--source include/switch_to_mysql_user.inc
drop view mysql.user_bak;
alter table mysql.user change authentication_string auth_string text collate utf8_bin not null;
--echo # mysql_upgrade --force --silent 2>&1
--exec $MYSQL_UPGRADE --force --silent 2>&1
--remove_file $MYSQLD_DATADIR/mysql_upgrade_info
select count(*) from mysql.global_priv;
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
--echo # End of 10.4 tests

View File

@ -1,3 +1,4 @@
# switching from mysql.global_priv to mysql.user
drop view mysql.user_bak;
install soname 'ha_blackhole';
install soname 'ha_archive';
@ -144,6 +145,7 @@ Code 1286
Message Unknown storage engine 'ARCHIVE'
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
# switching from mysql.global_priv to mysql.user
drop view mysql.user_bak;
alter table mysql.user drop column default_role, drop column max_statement_time;
Phase 1/7: Checking and upgrading mysql database
@ -236,6 +238,7 @@ Code 1286
Message Unknown storage engine 'ARCHIVE'
drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv;
# switching from mysql.global_priv to mysql.user
drop view mysql.user_bak;
alter table mysql.user drop column default_role, drop column max_statement_time;
Phase 1/7: Checking and upgrading mysql database

View File

@ -1,6 +1,7 @@
#
# MDEV-22057 REPLICATION MASTER ADMIN is missing in root account after upgrade
#
# switching from mysql.global_priv to mysql.user
DROP VIEW mysql.user_bak;
FLUSH PRIVILEGES;
CREATE USER user_all@localhost;

View File

@ -138,6 +138,7 @@ ERROR HY000: Incorrect DAY value: '0'
#
# Password expiration fields are loaded properly on 10.3 tables
#
# switching from mysql.global_priv to mysql.user
create user user1@localhost;
show create user user1@localhost;
CREATE USER for user1@localhost
@ -205,6 +206,7 @@ connection default;
drop user user1@localhost;
set global disconnect_on_expired_password=default;
set global default_password_lifetime=default;
# switching back from mysql.user to mysql.global_priv
#
# PASSWORD EXPIRE DEFAULT should use the default_password_lifetime
# system var to set the number of days till expiration

View File

@ -354,6 +354,7 @@ uplain@localhost uplain@localhost
connection default;
disconnect cleartext_con;
DROP USER uplain@localhost;
# switching from mysql.global_priv to mysql.user
drop view mysql.user_bak;
#
# Bug #59038 : mysql.user.authentication_string column

View File

@ -158,6 +158,7 @@ connection default;
drop user natauth@localhost, newpass@localhost, newpassnat@localhost;
drop user oldauth@localhost, oldpass@localhost, oldpassold@localhost;
set global secure_auth=default;
# switching from mysql.global_priv to mysql.user
create user foo@localhost identified with mysql_native_password;
update mysql.user set authentication_string=password('foo'), plugin='mysql_native_password' where user='foo' and host='localhost';
set password for 'foo'@'localhost' = password('bar');
@ -179,3 +180,4 @@ select user,host,password,plugin,authentication_string from mysql.user where use
user host password plugin authentication_string
foo localhost mysql_native_password
drop user foo@localhost;
# switching back from mysql.user to mysql.global_priv

View File

@ -212,6 +212,7 @@ disconnect rl_contender;
drop procedure p1;
drop table t1;
set session low_priority_updates=default;
# switching from mysql.global_priv to mysql.user
INSERT IGNORE INTO mysql.user (Host, User, Password, Select_priv, Insert_priv, Update_priv,
Delete_priv, Create_priv, Drop_priv, Reload_priv, Shutdown_priv, Process_priv, File_priv,
Grant_priv, References_priv, Index_priv, Alter_priv, Show_db_priv, Super_priv,
@ -231,6 +232,7 @@ CREATE PROCEDURE p1(i INT) BEGIN END;
disconnect con1;
connection default;
DROP PROCEDURE p1;
# switching back from mysql.user to mysql.global_priv
#
# Bug#44521 Prepared Statement: CALL p() - crashes: `! thd->main_da.is_sent' failed et.al.
#
@ -323,6 +325,7 @@ DROP EVENT teste_bug11763507;
# ------------------------------------------------------------------
# -- End of 5.1 tests
# ------------------------------------------------------------------
# switching from mysql.global_priv to mysql.user
grant create routine on test.* to foo1@localhost identified by 'foo';
update mysql.user set authentication_string = replace(authentication_string, '*', '-') where user='foo1';
connect foo,localhost,foo1,foo;
@ -347,4 +350,5 @@ connection default;
disconnect foo;
drop procedure spfoo;
drop user foo1@localhost;
# switching back from mysql.user to mysql.global_priv
set @@global.concurrent_insert= @old_concurrent_insert;

View File

@ -3,6 +3,7 @@
# Fatal error: mysql.user table is damaged or in
# unsupported 3.20 format
#
# switching from mysql.global_priv to mysql.user
#
# Original mysql.user table
#
@ -221,3 +222,4 @@ drop user user@localhost;
#
# Reset to final original state.
#
# switching back from mysql.user to mysql.global_priv

View File

@ -141,10 +141,6 @@ my $opt_start_dirty;
my $opt_start_exit;
my $start_only;
my $file_wsrep_provider;
my $extra_path;
my $mariabackup_path;
my $mariabackup_exe;
my $garbd_exe;
our @global_suppressions;
@ -383,170 +379,6 @@ $| = 1; # Automatically flush STDOUT
main();
sub have_wsrep() {
my $wsrep_on= $mysqld_variables{'wsrep-on'};
return defined $wsrep_on
}
sub have_wsrep_provider() {
return $file_wsrep_provider ne "";
}
sub have_mariabackup() {
return $mariabackup_path ne "";
}
sub have_garbd() {
return $garbd_exe ne "";
}
sub check_wsrep_version() {
if ($My::SafeProcess::wsrep_check_version ne "") {
system($My::SafeProcess::wsrep_check_version);
return ($? >> 8) == 0;
}
else {
return 0;
}
}
sub wsrep_version_message() {
if ($My::SafeProcess::wsrep_check_version ne "") {
my $output= `$My::SafeProcess::wsrep_check_version -p`;
if (($? >> 8) == 0) {
$output =~ s/\s+\z//;
return "Wsrep provider version mismatch (".$output.")";
}
else {
return "Galera library does not contain a version symbol";
}
}
else {
return "Unable to find a wsrep version check utility";
}
}
sub which($) { return `sh -c "command -v $_[0]"` }
sub check_garbd_support() {
if (defined $ENV{'MTR_GARBD_EXE'}) {
if (mtr_file_exists($ENV{'MTR_GARBD_EXE'}) ne "") {
$garbd_exe= $ENV{'MTR_GARBD_EXE'};
} else {
mtr_error("MTR_GARBD_EXE env set to an invalid path");
}
}
else {
my $wsrep_path= dirname($file_wsrep_provider);
$garbd_exe=
mtr_file_exists($wsrep_path."/garb/garbd",
$wsrep_path."/../../bin/garb/garbd");
if ($garbd_exe ne "") {
$ENV{MTR_GARBD_EXE}= $garbd_exe;
}
}
}
sub check_wsrep_support() {
$garbd_exe= "";
if (have_wsrep()) {
mtr_report(" - binaries built with wsrep patch");
# ADD scripts to $PATH to that wsrep_sst_* can be found
my ($spath) = grep { -f "$_/wsrep_sst_rsync"; } "$bindir/scripts", $path_client_bindir;
mtr_error("No SST scripts") unless $spath;
my $separator= (IS_WINDOWS) ? ';' : ':';
$ENV{PATH}="$spath$separator$ENV{PATH}";
# ADD mysql client library path to path so that wsrep_notify_cmd can find mysql
# client for loading the tables. (Don't assume each machine has mysql install)
my ($cpath) = grep { -f "$_/mysql"; } "$bindir/scripts", $path_client_bindir;
mtr_error("No scritps") unless $cpath;
$ENV{PATH}="$cpath$separator$ENV{PATH}" unless $cpath eq $spath;
# ADD my_print_defaults script path to path so that SST scripts can find it
my $my_print_defaults_exe=
mtr_exe_maybe_exists(
"$bindir/extra/my_print_defaults",
"$path_client_bindir/my_print_defaults");
my $epath= "";
if ($my_print_defaults_exe ne "") {
$epath= dirname($my_print_defaults_exe);
}
mtr_error("No my_print_defaults") unless $epath;
$ENV{PATH}="$epath$separator$ENV{PATH}" unless ($epath eq $spath) or
($epath eq $cpath);
$extra_path= $epath;
if (!IS_WINDOWS) {
if (which("socat")) {
$ENV{MTR_GALERA_TFMT}="socat";
} elsif (which("nc")) {
$ENV{MTR_GALERA_TFMT}="nc";
}
}
# Check whether WSREP_PROVIDER environment variable is set.
if (defined $ENV{'WSREP_PROVIDER'}) {
$file_wsrep_provider= "";
if ($ENV{'WSREP_PROVIDER'} ne "none") {
if (mtr_file_exists($ENV{'WSREP_PROVIDER'}) ne "") {
$file_wsrep_provider= $ENV{'WSREP_PROVIDER'};
} else {
mtr_error("WSREP_PROVIDER env set to an invalid path");
}
check_garbd_support();
}
# WSREP_PROVIDER is valid; set to a valid path or "none").
mtr_verbose("WSREP_PROVIDER env set to $ENV{'WSREP_PROVIDER'}");
} else {
# WSREP_PROVIDER env not defined. Lets try to locate the wsrep provider
# library.
$file_wsrep_provider=
mtr_file_exists("/usr/lib64/galera-4/libgalera_smm.so",
"/usr/lib64/galera/libgalera_smm.so",
"/usr/lib/galera-4/libgalera_smm.so",
"/usr/lib/galera/libgalera_smm.so");
if ($file_wsrep_provider ne "") {
# wsrep provider library found !
mtr_verbose("wsrep provider library found : $file_wsrep_provider");
$ENV{'WSREP_PROVIDER'}= $file_wsrep_provider;
check_garbd_support();
} else {
mtr_verbose("Could not find wsrep provider library, setting it to 'none'");
$ENV{'WSREP_PROVIDER'}= "none";
}
}
} else {
$file_wsrep_provider= "";
$extra_path= "";
}
}
sub check_mariabackup_support() {
$mariabackup_path= "";
$mariabackup_exe=
mtr_exe_maybe_exists(
"$bindir/extra/mariabackup$opt_vs_config/mariabackup",
"$path_client_bindir/mariabackup");
if ($mariabackup_exe ne "") {
my $bpath= dirname($mariabackup_exe);
my $separator= (IS_WINDOWS) ? ';' : ':';
$ENV{PATH}="$bpath$separator$ENV{PATH}" unless $bpath eq $extra_path;
$mariabackup_path= $bpath;
$ENV{XTRABACKUP}= $mariabackup_exe;
$ENV{XBSTREAM}= mtr_exe_maybe_exists(
"$bindir/extra/mariabackup/$opt_vs_config/mbstream",
"$path_client_bindir/mbstream");
$ENV{INNOBACKUPEX}= "$mariabackup_exe --innobackupex";
}
}
sub main {
$ENV{MTR_PERL}=$^X;
@ -591,8 +423,7 @@ sub main {
}
check_ssl_support();
check_debug_support();
check_wsrep_support();
check_mariabackup_support();
environment_setup();
if (!$opt_suites) {
$opt_suites= join ',', collect_default_suites(@DEFAULT_SUITES);
@ -2602,10 +2433,23 @@ sub environment_setup {
my $exe_innochecksum=
mtr_exe_maybe_exists("$bindir/extra$opt_vs_config/innochecksum",
"$path_client_bindir/innochecksum");
if ($exe_innochecksum)
{
$ENV{'INNOCHECKSUM'}= native_path($exe_innochecksum);
}
$ENV{'INNOCHECKSUM'}= native_path($exe_innochecksum) if $exe_innochecksum;
# ----------------------------------------------------
# mariabackup
# ----------------------------------------------------
my $exe_mariabackup= mtr_exe_maybe_exists(
"$bindir/extra/mariabackup$opt_vs_config/mariabackup",
"$path_client_bindir/mariabackup");
$ENV{XTRABACKUP}= native_path($exe_mariabackup) if $exe_mariabackup;
my $exe_xbstream= mtr_exe_maybe_exists(
"$bindir/extra/mariabackup/$opt_vs_config/mbstream",
"$path_client_bindir/mbstream");
$ENV{XBSTREAM}= native_path($exe_xbstream) if $exe_xbstream;
$ENV{INNOBACKUPEX}= "$exe_mariabackup --innobackupex";
# Create an environment variable to make it possible
# to detect that valgrind is being used from test cases
@ -3404,7 +3248,8 @@ sub mysql_install_db {
# ----------------------------------------------------------------------
# export MYSQLD_BOOTSTRAP_CMD variable containing <path>/mysqld <args>
# ----------------------------------------------------------------------
$ENV{'MYSQLD_BOOTSTRAP_CMD'}= "$exe_mysqld_bootstrap " . join(" ", @$args);
$ENV{'MYSQLD_BOOTSTRAP_CMD'}= "$exe_mysqld_bootstrap " . join(" ", @$args)
unless defined $ENV{'MYSQLD_BOOTSTRAP_CMD'};
# Extra options can come not only from the command line, but also
# from option files or combinations. We want them on a command line

View File

@ -47,21 +47,6 @@ sub skip_combinations {
$skip{'main/plugin_loaderr.test'} = 'needs compiled-in innodb'
unless $::mysqld_variables{'innodb'} eq "ON";
$skip{'include/have_mariabackup.inc'} = 'Need mariabackup'
unless ::have_mariabackup();
$skip{'include/have_mariabackup.inc'} = 'Need socket statistics utility'
unless IS_WINDOWS || ::which("ss");
$skip{'include/have_mariabackup.inc'} = 'Need socat or nc'
unless IS_WINDOWS || $ENV{MTR_GALERA_TFMT};
$skip{'include/have_garbd.inc'} = 'Need garbd'
unless ::have_garbd();
$skip{'include/have_file_key_management.inc'} = 'Needs file_key_management plugin'
unless $ENV{FILE_KEY_MANAGEMENT_SO};
# disable tests that use ipv6, if unsupported
sub ipv6_ok() {
use Socket;

View File

@ -0,0 +1,7 @@
if (!$XTRABACKUP) {
skip Needs mariabackup;
}
if (!$MTR_GALERA_TFMT) {
skip Needs socat or nc;
}

View File

@ -1,16 +1,11 @@
package My::Suite::Galera;
use File::Basename;
use My::Find;
use lib 'suite';
use wsrep::common;
@ISA = qw(My::Suite);
return "Not run for embedded server" if $::opt_embedded_server;
return "WSREP is not compiled in" if not ::have_wsrep();
return "No wsrep provider library" unless ::have_wsrep_provider();
return ::wsrep_version_message() unless ::check_wsrep_version();
return wsrep_not_ok() if wsrep_not_ok();
push @::global_suppressions,
(
@ -69,4 +64,10 @@ push @::global_suppressions,
qr(WSREP: wsrep_sst_method is set to 'mysqldump' yet mysqld bind_address is set to .*),
);
sub skip_combinations {
my %skip = ();
$skip{'include/have_mariabackup.inc'} = 'Need ss' unless `ss -V`;
%skip;
}
bless { };

View File

@ -10,3 +10,6 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true'
[mysqld.2]
wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true'
[sst]
transferfmt=@ENV.MTR_GALERA_TFMT
streamfmt=xbstream

View File

@ -12,3 +12,6 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true'
[mysqld.2]
wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true'
[sst]
transferfmt=@ENV.MTR_GALERA_TFMT
streamfmt=xbstream

View File

@ -0,0 +1,3 @@
if (!$MTR_GARBD_EXE) {
skip Needs garbd;
}

View File

@ -1,16 +1,11 @@
package My::Suite::GALERA_3NODES;
use File::Basename;
use My::Find;
use lib 'suite';
use wsrep::common;
@ISA = qw(My::Suite);
return "Not run for embedded server" if $::opt_embedded_server;
return "WSREP is not compiled in" if not ::have_wsrep();
return "No wsrep provider library" unless ::have_wsrep_provider();
return ::wsrep_version_message() unless ::check_wsrep_version();
return wsrep_not_ok() if wsrep_not_ok();
push @::global_suppressions,
(

View File

@ -4,7 +4,7 @@
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/have_mariabackup.inc
--source suite/galera/include/have_mariabackup.inc
--let $galera_connection_name = node_3
--let $galera_server_number = 3

View File

@ -1,16 +1,11 @@
package My::Suite::Galera_sr;
use File::Basename;
use My::Find;
use lib 'suite';
use wsrep::common;
@ISA = qw(My::Suite);
return "Not run for embedded server" if $::opt_embedded_server;
return "WSREP is not compiled in" if not ::have_wsrep();
return "No wsrep provider library" unless ::have_wsrep_provider();
return ::wsrep_version_message() unless ::check_wsrep_version();
return wsrep_not_ok() if wsrep_not_ok();
push @::global_suppressions,
(

View File

@ -124,3 +124,18 @@ SELECT DISTINCT (CURRENT_TIMESTAMP()-d4) <= 60 FROM t1;
(CURRENT_TIMESTAMP()-d4) <= 60
1
DROP TABLE t1;
CREATE TABLE t1(f1 int) ENGINE=InnoDB;
INSERT INTO t1 SELECT * FROM seq_1_to_4096;
connect purge_control,localhost,root,,;
START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default;
DELETE FROM t1;
SET sql_mode='STRICT_ALL_TABLES,STRICT_TRANS_TABLES,NO_ZERO_DATE';
ALTER TABLE t1 ADD f2 DATE NOT NULL, ALGORITHM=INPLACE;
INSERT INTO t1 VALUES (1, now());
Warnings:
Note 1265 Data truncated for column 'f2' at row 1
ALTER TABLE t1 ADD f3 DATE NOT NULL, ALGORITHM=INPLACE;
ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY
DROP TABLE t1;
disconnect purge_control;

View File

@ -0,0 +1,73 @@
#
# Bug #29717909 MEMORY LIFETIME OF VARIABLES BETWEEN CHECK AND UPDATE INCORRECTLY MANAGED
#
select @@innodb_ft_server_stopword_table;
@@innodb_ft_server_stopword_table
NULL
create table user_stopword_1(value varchar(30)) engine = innodb;
create table user_stopword_2(value varchar(30)) engine = innodb;
set @blah = 'test/user_stopword_1';
SET GLOBAL innodb_ft_server_stopword_table= @blah;
select @@innodb_ft_server_stopword_table;
@@innodb_ft_server_stopword_table
test/user_stopword_1
set @blah = 'test/user_stopword_2';
SET GLOBAL innodb_ft_server_stopword_table= @blah;
select @@innodb_ft_server_stopword_table;
@@innodb_ft_server_stopword_table
test/user_stopword_2
SET GLOBAL innodb_ft_server_stopword_table= NULL;
select @@innodb_ft_server_stopword_table;
@@innodb_ft_server_stopword_table
NULL
SET GLOBAL innodb_ft_server_stopword_table= default;
select @@innodb_ft_server_stopword_table;
@@innodb_ft_server_stopword_table
NULL
drop table user_stopword_1, user_stopword_2;
select @@innodb_buffer_pool_filename;
@@innodb_buffer_pool_filename
ib_buffer_pool
set @blah='hello';
set global innodb_buffer_pool_filename = @blah;
select @@innodb_buffer_pool_filename;
@@innodb_buffer_pool_filename
hello
set global innodb_buffer_pool_filename="bye";
select @@innodb_buffer_pool_filename;
@@innodb_buffer_pool_filename
bye
set global innodb_buffer_pool_filename=NULL;
ERROR 42000: Variable 'innodb_buffer_pool_filename' can't be set to the value of 'NULL'
select @@innodb_buffer_pool_filename;
@@innodb_buffer_pool_filename
bye
set global innodb_buffer_pool_filename=default;
select @@innodb_buffer_pool_filename;
@@innodb_buffer_pool_filename
ib_buffer_pool
CREATE TABLE t1 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
opening_line TEXT(500), author VARCHAR(200), title VARCHAR(200), FULLTEXT idx
(opening_line)) ENGINE=InnoDB;
CREATE TABLE t2 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
opening_line TEXT(500), author VARCHAR(200), title VARCHAR(200), FULLTEXT idx
(opening_line)) ENGINE=InnoDB;
select @@innodb_ft_aux_table;
@@innodb_ft_aux_table
NULL
set @blah = 'test/t1';
SET GLOBAL innodb_ft_aux_table = @blah;
select @@innodb_ft_aux_table;
@@innodb_ft_aux_table
test/t1
set @blah = 'test/t2';
SET GLOBAL innodb_ft_aux_table = @blah;
SET GLOBAL innodb_ft_aux_table = NULL;
select @@innodb_ft_aux_table;
@@innodb_ft_aux_table
NULL
SET GLOBAL innodb_ft_aux_table =default;
select @@innodb_ft_aux_table;
@@innodb_ft_aux_table
NULL
drop table t1,t2;

View File

@ -1,4 +1,5 @@
--source include/have_innodb.inc
--source include/have_sequence.inc
CREATE TABLE t1 (i1 INT UNSIGNED NULL DEFAULT 42) ENGINE=innodb;
INSERT INTO t1 VALUES(NULL);
@ -82,3 +83,23 @@ ALTER TABLE t1 ADD COLUMN d4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
SELECT COUNT(DISTINCT d4),COUNT(d4),COUNT(*) FROM t1;
SELECT DISTINCT (CURRENT_TIMESTAMP()-d4) <= 60 FROM t1;
DROP TABLE t1;
# MDEV-19611 INPLACE ALTER does not fail on bad implicit default value
# Empty-table
CREATE TABLE t1(f1 int) ENGINE=InnoDB;
INSERT INTO t1 SELECT * FROM seq_1_to_4096;
connect(purge_control,localhost,root,,);
START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default;
DELETE FROM t1;
SET sql_mode='STRICT_ALL_TABLES,STRICT_TRANS_TABLES,NO_ZERO_DATE';
ALTER TABLE t1 ADD f2 DATE NOT NULL, ALGORITHM=INPLACE;
# Non-empty table
INSERT INTO t1 VALUES (1, now());
--error ER_ALTER_OPERATION_NOT_SUPPORTED
ALTER TABLE t1 ADD f3 DATE NOT NULL, ALGORITHM=INPLACE;
DROP TABLE t1;
disconnect purge_control;

View File

@ -0,0 +1,70 @@
--source include/have_innodb.inc
--echo #
--echo # Bug #29717909 MEMORY LIFETIME OF VARIABLES BETWEEN CHECK AND UPDATE INCORRECTLY MANAGED
--echo #
#Test innodb_ft_server_stopword_table (global variable)
select @@innodb_ft_server_stopword_table;
create table user_stopword_1(value varchar(30)) engine = innodb;
create table user_stopword_2(value varchar(30)) engine = innodb;
set @blah = 'test/user_stopword_1';
SET GLOBAL innodb_ft_server_stopword_table= @blah;
select @@innodb_ft_server_stopword_table;
set @blah = 'test/user_stopword_2';
SET GLOBAL innodb_ft_server_stopword_table= @blah;
select @@innodb_ft_server_stopword_table;
SET GLOBAL innodb_ft_server_stopword_table= NULL;
select @@innodb_ft_server_stopword_table;
SET GLOBAL innodb_ft_server_stopword_table= default;
select @@innodb_ft_server_stopword_table;
drop table user_stopword_1, user_stopword_2;
#Test innodb_buffer_pool_filename (global variable)
select @@innodb_buffer_pool_filename;
set @blah='hello';
set global innodb_buffer_pool_filename = @blah;
select @@innodb_buffer_pool_filename;
set global innodb_buffer_pool_filename="bye";
select @@innodb_buffer_pool_filename;
--error ER_WRONG_VALUE_FOR_VAR
set global innodb_buffer_pool_filename=NULL;
select @@innodb_buffer_pool_filename;
set global innodb_buffer_pool_filename=default;
select @@innodb_buffer_pool_filename;
#Test innodb_ft_aux_table (global variable)
CREATE TABLE t1 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
opening_line TEXT(500), author VARCHAR(200), title VARCHAR(200), FULLTEXT idx
(opening_line)) ENGINE=InnoDB;
CREATE TABLE t2 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
opening_line TEXT(500), author VARCHAR(200), title VARCHAR(200), FULLTEXT idx
(opening_line)) ENGINE=InnoDB;
select @@innodb_ft_aux_table;
set @blah = 'test/t1';
SET GLOBAL innodb_ft_aux_table = @blah;
select @@innodb_ft_aux_table;
set @blah = 'test/t2';
SET GLOBAL innodb_ft_aux_table = @blah;
SET GLOBAL innodb_ft_aux_table = NULL;
select @@innodb_ft_aux_table;
SET GLOBAL innodb_ft_aux_table =default;
select @@innodb_ft_aux_table;
drop table t1,t2;

View File

@ -705,6 +705,11 @@ FULLTEXT(f2),
FOREIGN KEY(f1) REFERENCES mdev20987_1(f1))ENGINE=InnoDB;
INSERT INTO mdev20987_1 VALUES(1);
INSERT INTO mdev20987_2 VALUES(1, 'mariadb');
CREATE TABLE mdev22358 (a INT, b TEXT, FULLTEXT KEY ftidx (b)) ENGINE=InnoDB;
ALTER TABLE mdev22358 DROP KEY ftidx;
INSERT INTO mdev22358 (a) VALUES (2),(2);
ALTER TABLE mdev22358 ADD UNIQUE KEY uidx (a), ADD FULLTEXT KEY ftidx (b);
ERROR 23000: Duplicate entry '2' for key 'uidx'
# restart
SHOW CREATE TABLE t2;
Table Create Table
@ -713,7 +718,7 @@ t2 CREATE TABLE `t2` (
PRIMARY KEY (`FTS_DOC_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb');
DROP TABLE t1, t2, mdev20987_2, mdev20987_1;
DROP TABLE t1, t2, mdev20987_2, mdev20987_1, mdev22358;
"----------Test28---------"
create table `fts_test`(`a` text,fulltext key(`a`))engine=innodb;
set session autocommit=0;

View File

@ -0,0 +1,748 @@
call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table not_defined does not exist.");
call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table test/user_stopword_session does not exist.");
select * from information_schema.innodb_ft_default_stopword;
value
a
about
an
are
as
at
be
by
com
de
en
for
from
how
i
in
is
it
la
of
on
or
that
the
this
to
was
what
when
where
who
will
with
und
the
www
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title,body)
) ENGINE=InnoDB;
INSERT INTO articles (title,body) VALUES
('MySQL Tutorial','DBMS stands for DataBase ...') ,
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
SELECT * FROM articles WHERE MATCH (title,body)
AGAINST ('the' IN NATURAL LANGUAGE MODE);
id title body
SET @innodb_ft_server_stopword_table_orig=@@innodb_ft_server_stopword_table;
SET @innodb_ft_enable_stopword_orig=@@innodb_ft_enable_stopword;
SET @innodb_ft_user_stopword_table_orig=@@innodb_ft_user_stopword_table;
set global innodb_ft_server_stopword_table = "not_defined";
ERROR 42000: Variable 'innodb_ft_server_stopword_table' can't be set to the value of 'not_defined'
set global innodb_ft_server_stopword_table = NULL;
create table user_stopword(value varchar(30)) engine = innodb;
set global innodb_ft_server_stopword_table = "test/user_stopword";
drop index title on articles;
create fulltext index idx on articles(title, body);
SELECT * FROM articles WHERE MATCH (title,body)
AGAINST ('the' IN NATURAL LANGUAGE MODE);
id title body
5 MySQL vs. YourSQL In the following database comparison ...
CREATE TABLE articles_2 (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title,body)
) ENGINE=InnoDB;
INSERT INTO articles_2 (title, body)
VALUES ('test for stopwords','this is it...');
SELECT * FROM articles_2 WHERE MATCH (title,body)
AGAINST ('this' IN NATURAL LANGUAGE MODE);
id title body
1 test for stopwords this is it...
insert into user_stopword values("this");
CREATE TABLE articles_3 (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title,body)
) ENGINE=InnoDB;
INSERT INTO articles_3 (title, body)
VALUES ('test for stopwords','this is it...');
SELECT * FROM articles_3 WHERE MATCH (title,body)
AGAINST ('this' IN NATURAL LANGUAGE MODE);
id title body
create table user_stopword_session(value varchar(30)) engine = innodb;
insert into user_stopword_session values("session");
set session innodb_ft_user_stopword_table="test/user_stopword_session";
CREATE TABLE articles_4 (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title,body)
) ENGINE=InnoDB;
INSERT INTO articles_4 (title, body)
VALUES ('test for session stopwords','this should also be excluded...');
SELECT * FROM articles_4 WHERE MATCH (title,body)
AGAINST ('session' IN NATURAL LANGUAGE MODE);
id title body
SELECT * FROM articles_4 WHERE MATCH (title,body)
AGAINST ('this' IN NATURAL LANGUAGE MODE);
id title body
1 test for session stopwords this should also be excluded...
connect con1,localhost,root,,;
CREATE TABLE articles_5 (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title,body)
) ENGINE=InnoDB;
INSERT INTO articles_5 (title, body)
VALUES ('test for session stopwords','this should also be excluded...');
SELECT * FROM articles_5 WHERE MATCH (title,body)
AGAINST ('session' IN NATURAL LANGUAGE MODE);
id title body
1 test for session stopwords this should also be excluded...
connection default;
drop table articles;
drop table articles_2;
drop table articles_3;
drop table articles_4;
drop table articles_5;
drop table user_stopword;
drop table user_stopword_session;
SET GLOBAL innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
SET GLOBAL innodb_ft_server_stopword_table=default;
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT `idx` (title,body)
) ENGINE=InnoDB;
SHOW CREATE TABLE articles;
Table Create Table
articles CREATE TABLE `articles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(200) DEFAULT NULL,
`body` text DEFAULT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `idx` (`title`,`body`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
INSERT INTO articles (title,body) VALUES
('MySQL from Tutorial','DBMS stands for DataBase ...') ,
('when To Use MySQL Well','After that you went through a ...'),
('where will Optimizing MySQL','In what tutorial we will show ...'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
id title body
INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
id title body
UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
WHERE id = 7;
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
id title body
DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE id = 7;
id title body
7 update the record to see will is indexed or not
DELETE FROM articles WHERE id = 7;
SET global innodb_ft_server_stopword_table = NULL;
SET SESSION innodb_ft_enable_stopword = 0;
select @@innodb_ft_enable_stopword;
@@innodb_ft_enable_stopword
0
SET global innodb_ft_user_stopword_table = NULL;
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
id title body
INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
id title body
UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
WHERE id = 8;
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
id title body
SELECT * FROM articles WHERE id = 8;
id title body
8 update the record to see will is indexed or not
DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE id = 8;
id title body
8 update the record to see will is indexed or not
DELETE FROM articles WHERE id = 8;
ALTER TABLE articles DROP INDEX idx;
SHOW CREATE TABLE articles;
Table Create Table
articles CREATE TABLE `articles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(200) DEFAULT NULL,
`body` text DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
ANALYZE TABLE articles;
Table Op Msg_type Msg_text
test.articles analyze status Engine-independent statistics collected
test.articles analyze Warning Engine-independent statistics are not collected for column 'body'
test.articles analyze status OK
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
id title body
2 when To Use MySQL Well After that you went through a ...
6 MySQL Security When configured properly, MySQL ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
1 MySQL from Tutorial DBMS stands for DataBase ...
6 MySQL Security When configured properly, MySQL ...
2 when To Use MySQL Well After that you went through a ...
4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ...
5 MySQL vs. YourSQL In the following database comparison ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
id title body
2 when To Use MySQL Well After that you went through a ...
3 where will Optimizing MySQL In what tutorial we will show ...
6 MySQL Security When configured properly, MySQL ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
id title body
1 MySQL from Tutorial DBMS stands for DataBase ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
id title body
9 the record will not index the , will words
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
id title body
9 the record will not index the , will words
UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT COUNT(*),max(id) FROM articles;
COUNT(*) max(id)
7 9
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
id title body
9 update the record to see will is indexed or not
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
9 update the record to see will is indexed or not
DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE id = 9;
id title body
DROP TABLE articles;
SET SESSION innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
SET GLOBAL innodb_ft_server_stopword_table=@innodb_ft_server_stopword_table_orig;
SET GLOBAL innodb_ft_user_stopword_table=@innodb_ft_user_stopword_table_orig;
SET SESSION innodb_ft_user_stopword_table=default;
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT `idx` (title,body)
) ENGINE=InnoDB;
INSERT INTO articles (title,body) VALUES
('MySQL from Tutorial','DBMS stands for DataBase ...') ,
('when To Use MySQL Well','After that you went through a ...'),
('where will Optimizing MySQL','In what tutorial we will show ...'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
id title body
create table user_stopword(value varchar(30)) engine = innodb;
set session innodb_ft_user_stopword_table = "test/user_stopword";
create table server_stopword(value varchar(30)) engine = innodb;
set global innodb_ft_server_stopword_table = "test/server_stopword";
insert into user_stopword values("this"),("will"),("the");
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
id title body
insert into server_stopword values("what"),("where");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
DELETE FROM user_stopword;
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
insert into user_stopword values("this"),("will"),("the");
ALTER TABLE articles DROP INDEX idx;
SET SESSION innodb_ft_enable_stopword = 0;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SET SESSION innodb_ft_enable_stopword = 1;
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
id title body
SET SESSION innodb_ft_enable_stopword = 1;
SET SESSION innodb_ft_user_stopword_table = default;
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
DROP TABLE articles,user_stopword,server_stopword;
SET innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
SET GLOBAL innodb_ft_server_stopword_table=default;
SET SESSION innodb_ft_user_stopword_table=default;
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT `idx` (title,body)
) ENGINE=InnoDB;
SHOW CREATE TABLE articles;
Table Create Table
articles CREATE TABLE `articles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(200) DEFAULT NULL,
`body` text DEFAULT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `idx` (`title`,`body`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
INSERT INTO articles (title,body) VALUES
('MySQL from Tutorial','DBMS stands for DataBase ...') ,
('when To Use MySQL Well','After that you went through a ...'),
('where will Optimizing MySQL','In what tutorial we will show ...'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
id title body
create table user_stopword(value varchar(30)) engine = innodb;
set session innodb_ft_user_stopword_table = "test/user_stopword";
insert into user_stopword values("mysqld"),("DBMS");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE);
id title body
1 MySQL from Tutorial DBMS stands for DataBase ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld');
id title body
4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ...
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld');
id title body
set session innodb_ft_user_stopword_table = default;
create table server_stopword(value varchar(30)) engine = innodb;
set global innodb_ft_server_stopword_table = "test/server_stopword";
insert into server_stopword values("root"),("properly");
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly');
id title body
set session innodb_ft_user_stopword_table = "test/user_stopword";
set global innodb_ft_server_stopword_table = "test/server_stopword";
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE);
id title body
4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly');
id title body
6 MySQL Security When configured properly, MySQL ...
set session innodb_ft_user_stopword_table = "test/user_stopword";
DELETE FROM user_stopword;
set global innodb_ft_server_stopword_table = "test/server_stopword";
DELETE FROM server_stopword;
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE);
id title body
4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly');
id title body
6 MySQL Security When configured properly, MySQL ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE);
id title body
1 MySQL from Tutorial DBMS stands for DataBase ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld');
id title body
4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ...
DROP TABLE articles,user_stopword,server_stopword;
SET SESSION innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
SET GLOBAL innodb_ft_server_stopword_table=default;
SET SESSION innodb_ft_user_stopword_table=default;
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT `idx` (title,body)
) ENGINE=InnoDB;
SHOW CREATE TABLE articles;
Table Create Table
articles CREATE TABLE `articles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(200) DEFAULT NULL,
`body` text DEFAULT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `idx` (`title`,`body`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
INSERT INTO articles (title,body) VALUES
('MySQL from Tutorial','DBMS stands for DataBase ...') ,
('when To Use MySQL Well','After that you went through a ...'),
('where will Optimizing MySQL','In what tutorial we will show ...'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
SET SESSION innodb_ft_enable_stopword = 0;
select @@innodb_ft_enable_stopword;
@@innodb_ft_enable_stopword
0
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
"In connection 1"
connection con1;
select @@innodb_ft_enable_stopword;
@@innodb_ft_enable_stopword
1
ANALYZE TABLE articles;
Table Op Msg_type Msg_text
test.articles analyze status Engine-independent statistics collected
test.articles analyze Warning Engine-independent statistics are not collected for column 'body'
test.articles analyze status OK
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
id title body
2 when To Use MySQL Well After that you went through a ...
6 MySQL Security When configured properly, MySQL ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
1 MySQL from Tutorial DBMS stands for DataBase ...
6 MySQL Security When configured properly, MySQL ...
2 when To Use MySQL Well After that you went through a ...
4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ...
5 MySQL vs. YourSQL In the following database comparison ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
id title body
2 when To Use MySQL Well After that you went through a ...
3 where will Optimizing MySQL In what tutorial we will show ...
6 MySQL Security When configured properly, MySQL ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
id title body
1 MySQL from Tutorial DBMS stands for DataBase ...
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SET SESSION innodb_ft_enable_stopword = 1;
select @@innodb_ft_enable_stopword;
@@innodb_ft_enable_stopword
1
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
id title body
"In connection default"
connection default;
select @@innodb_ft_enable_stopword;
@@innodb_ft_enable_stopword
0
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
id title body
INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
id title body
SET SESSION innodb_ft_enable_stopword = 1;
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
id title body
"In connection 1"
connection con1;
SET SESSION innodb_ft_enable_stopword = 1;
create table user_stopword(value varchar(30)) engine = innodb;
set session innodb_ft_user_stopword_table = "test/user_stopword";
insert into user_stopword values("this"),("will"),("the");
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
id title body
"In connection default"
connection default;
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
id title body
select @@innodb_ft_user_stopword_table;
@@innodb_ft_user_stopword_table
NULL
create table user_stopword_1(value varchar(30)) engine = innodb;
set session innodb_ft_user_stopword_table = "test/user_stopword_1";
insert into user_stopword_1 values("when");
SET SESSION innodb_ft_enable_stopword = 1;
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
id title body
2 when To Use MySQL Well After that you went through a ...
6 MySQL Security When configured properly, MySQL ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('when');
id title body
2 when To Use MySQL Well After that you went through a ...
6 MySQL Security When configured properly, MySQL ...
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('when');
id title body
"In connection 1"
connection con1;
SET SESSION innodb_ft_enable_stopword = 1;
SET SESSION innodb_ft_user_stopword_table=default;
select @@innodb_ft_user_stopword_table;
@@innodb_ft_user_stopword_table
NULL
select @@innodb_ft_server_stopword_table;
@@innodb_ft_server_stopword_table
NULL
create table server_stopword(value varchar(30)) engine = innodb;
SET GLOBAL innodb_ft_server_stopword_table = "test/server_stopword";
select @@innodb_ft_server_stopword_table;
@@innodb_ft_server_stopword_table
test/server_stopword
insert into server_stopword values("when"),("the");
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('the');
id title body
disconnect con1;
"In connection default"
connection default;
SET SESSION innodb_ft_enable_stopword = 1;
SET SESSION innodb_ft_user_stopword_table=default;
select @@innodb_ft_server_stopword_table;
@@innodb_ft_server_stopword_table
test/server_stopword
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where');
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
insert into server_stopword values("where"),("will");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE);
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where');
id title body
3 where will Optimizing MySQL In what tutorial we will show ...
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('the');
id title body
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE);
id title body
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where');
id title body
DROP TABLE articles,user_stopword,user_stopword_1,server_stopword;
SET GLOBAL innodb_ft_user_stopword_table=@innodb_ft_user_stopword_table_orig;
SET GLOBAL innodb_ft_server_stopword_table=@innodb_ft_server_stopword_table_orig;

View File

@ -672,10 +672,16 @@ CREATE TABLE mdev20987_2(f1 INT NOT NULL, f2 CHAR(100),
FOREIGN KEY(f1) REFERENCES mdev20987_1(f1))ENGINE=InnoDB;
INSERT INTO mdev20987_1 VALUES(1);
INSERT INTO mdev20987_2 VALUES(1, 'mariadb');
CREATE TABLE mdev22358 (a INT, b TEXT, FULLTEXT KEY ftidx (b)) ENGINE=InnoDB;
ALTER TABLE mdev22358 DROP KEY ftidx;
INSERT INTO mdev22358 (a) VALUES (2),(2);
--error ER_DUP_ENTRY
ALTER TABLE mdev22358 ADD UNIQUE KEY uidx (a), ADD FULLTEXT KEY ftidx (b);
--source include/restart_mysqld.inc
SHOW CREATE TABLE t2;
DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb');
DROP TABLE t1, t2, mdev20987_2, mdev20987_1;
DROP TABLE t1, t2, mdev20987_2, mdev20987_1, mdev22358;
--echo "----------Test28---------"
create table `fts_test`(`a` text,fulltext key(`a`))engine=innodb;

View File

@ -0,0 +1 @@
--innodb-ft-default-stopword

View File

@ -0,0 +1,657 @@
# This is the basic function tests for innodb FTS
-- source include/have_innodb.inc
call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table not_defined does not exist.");
call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table test/user_stopword_session does not exist.");
select * from information_schema.innodb_ft_default_stopword;
# Create FTS table
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title,body)
) ENGINE=InnoDB;
# Insert six rows
INSERT INTO articles (title,body) VALUES
('MySQL Tutorial','DBMS stands for DataBase ...') ,
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
# "the" is in the default stopword, it would not be selected
SELECT * FROM articles WHERE MATCH (title,body)
AGAINST ('the' IN NATURAL LANGUAGE MODE);
SET @innodb_ft_server_stopword_table_orig=@@innodb_ft_server_stopword_table;
SET @innodb_ft_enable_stopword_orig=@@innodb_ft_enable_stopword;
SET @innodb_ft_user_stopword_table_orig=@@innodb_ft_user_stopword_table;
# Provide user defined stopword table, if not (correctly) defined,
# it will be rejected
--error ER_WRONG_VALUE_FOR_VAR
set global innodb_ft_server_stopword_table = "not_defined";
set global innodb_ft_server_stopword_table = NULL;
# Define a correct formated user stopword table
create table user_stopword(value varchar(30)) engine = innodb;
# The set operation should be successful
set global innodb_ft_server_stopword_table = "test/user_stopword";
drop index title on articles;
create fulltext index idx on articles(title, body);
# Now we should be able to find "the"
SELECT * FROM articles WHERE MATCH (title,body)
AGAINST ('the' IN NATURAL LANGUAGE MODE);
# Nothing inserted into the default stopword, so essentially
# nothing get screened. The new stopword could only be
# effective for table created thereafter
CREATE TABLE articles_2 (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title,body)
) ENGINE=InnoDB;
INSERT INTO articles_2 (title, body)
VALUES ('test for stopwords','this is it...');
# Now we can find record with "this"
SELECT * FROM articles_2 WHERE MATCH (title,body)
AGAINST ('this' IN NATURAL LANGUAGE MODE);
# Ok, let's instantiate some value into user supplied stop word
# table
insert into user_stopword values("this");
# Ok, let's repeat with the new table again.
CREATE TABLE articles_3 (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title,body)
) ENGINE=InnoDB;
INSERT INTO articles_3 (title, body)
VALUES ('test for stopwords','this is it...');
# Now we should NOT find record with "this"
SELECT * FROM articles_3 WHERE MATCH (title,body)
AGAINST ('this' IN NATURAL LANGUAGE MODE);
# Test session level stopword control "innodb_user_stopword_table"
create table user_stopword_session(value varchar(30)) engine = innodb;
insert into user_stopword_session values("session");
set session innodb_ft_user_stopword_table="test/user_stopword_session";
CREATE TABLE articles_4 (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title,body)
) ENGINE=InnoDB;
INSERT INTO articles_4 (title, body)
VALUES ('test for session stopwords','this should also be excluded...');
# "session" is excluded
SELECT * FROM articles_4 WHERE MATCH (title,body)
AGAINST ('session' IN NATURAL LANGUAGE MODE);
# But we can find record with "this"
SELECT * FROM articles_4 WHERE MATCH (title,body)
AGAINST ('this' IN NATURAL LANGUAGE MODE);
--connect (con1,localhost,root,,)
CREATE TABLE articles_5 (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title,body)
) ENGINE=InnoDB;
INSERT INTO articles_5 (title, body)
VALUES ('test for session stopwords','this should also be excluded...');
# "session" should be found since the stopword table is session specific
SELECT * FROM articles_5 WHERE MATCH (title,body)
AGAINST ('session' IN NATURAL LANGUAGE MODE);
--connection default
drop table articles;
drop table articles_2;
drop table articles_3;
drop table articles_4;
drop table articles_5;
drop table user_stopword;
drop table user_stopword_session;
SET GLOBAL innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
SET GLOBAL innodb_ft_server_stopword_table=default;
#---------------------------------------------------------------------------------------
# Behavior :
# The stopword is loaded into memory at
# 1) create fulltext index time,
# 2) boot server,
# 3) first time FTs is used
# So if you already created a FTS index, and then turn off stopword
# or change stopword table content it won't affect the FTS
# that already created since the stopword list are already loaded.
# It will only affect the new FTS index created after you changed
# the settings.
# Create FTS table
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT `idx` (title,body)
) ENGINE=InnoDB;
SHOW CREATE TABLE articles;
# Insert six rows
INSERT INTO articles (title,body) VALUES
('MySQL from Tutorial','DBMS stands for DataBase ...') ,
('when To Use MySQL Well','After that you went through a ...'),
('where will Optimizing MySQL','In what tutorial we will show ...'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
# Case : server_stopword=default
# Try to Search default stopword from innodb, "where", "will", "what"
# and "when" are all stopwords
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
# boolean No result expected
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
# no result expected
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
# no result expected
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
# Not going to update as where condition can not find record
UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
# Update the record
UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
WHERE id = 7;
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
# Delete will not work as where condition do not return
DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE id = 7;
DELETE FROM articles WHERE id = 7;
# Case : Turn OFF stopword list variable and search stopword on OLD index.
# disable stopword list
SET global innodb_ft_server_stopword_table = NULL;
SET SESSION innodb_ft_enable_stopword = 0;
select @@innodb_ft_enable_stopword;
SET global innodb_ft_user_stopword_table = NULL;
# search default stopword with innodb_ft_enable_stopword is OFF.
# No records expected even though we turned OFF stopwod filtering
# (refer Behavior (at the top of the test) for explanation )
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
# Not going to update as where condition can not find record
UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
# Update the record
UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
WHERE id = 8;
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
SELECT * FROM articles WHERE id = 8;
# Delete will not work as where condition do not return
DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE id = 8;
DELETE FROM articles WHERE id = 8;
# Case : Turn OFF stopword list variable and search stopword on NEW index.
# Drop index
ALTER TABLE articles DROP INDEX idx;
SHOW CREATE TABLE articles;
# Create the FTS index Using Alter Table.
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
ANALYZE TABLE articles;
# search default stopword with innodb_ft_enable_stopword is OFF.
# All records expected as stopwod filtering is OFF and we created
# new FTS index.
# (refer Behavior (at the top of the test) for explanation )
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
# Update will succeed.
UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT COUNT(*),max(id) FROM articles;
# Update the record - uncommet on fix
#UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
#WHERE id = 9;
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
# Delete will succeed.
DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE id = 9;
DROP TABLE articles;
SET SESSION innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
SET GLOBAL innodb_ft_server_stopword_table=@innodb_ft_server_stopword_table_orig;
SET GLOBAL innodb_ft_user_stopword_table=@innodb_ft_user_stopword_table_orig;
SET SESSION innodb_ft_user_stopword_table=default;
# Create FTS table
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT `idx` (title,body)
) ENGINE=InnoDB;
# Insert six rows
INSERT INTO articles (title,body) VALUES
('MySQL from Tutorial','DBMS stands for DataBase ...') ,
('when To Use MySQL Well','After that you went through a ...'),
('where will Optimizing MySQL','In what tutorial we will show ...'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
# No records expeced for select
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
# Define a correct formated user stopword table
create table user_stopword(value varchar(30)) engine = innodb;
# The set operation should be successful
set session innodb_ft_user_stopword_table = "test/user_stopword";
# Define a correct formated server stopword table
create table server_stopword(value varchar(30)) engine = innodb;
# The set operation should be successful
set global innodb_ft_server_stopword_table = "test/server_stopword";
# Add values into user supplied stop word table
insert into user_stopword values("this"),("will"),("the");
# Drop existing index and create the FTS index Using Alter Table.
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
# Add values into server supplied stop word table
insert into server_stopword values("what"),("where");
# Follwoing should return result as server stopword list was empty at create index time
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
# Delete stopword from user list
DELETE FROM user_stopword;
# Drop existing index and create the FTS index Using Alter Table.
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
# Follwoing should return result even though to server stopword list
# conatin these words. Session level stopword list takes priority
# Here user_stopword is set using innodb_ft_user_stopword_table
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
# Follwoing should return result as user stopword list was empty at create index time
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
# Add values into user supplied stop word table
insert into user_stopword values("this"),("will"),("the");
# Drop existing index and create the FTS index Using Alter Table.
ALTER TABLE articles DROP INDEX idx;
SET SESSION innodb_ft_enable_stopword = 0;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
# Session level stopword list takes priority
SET SESSION innodb_ft_enable_stopword = 1;
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
# Make user stopword list deafult so as to server stopword list takes priority
SET SESSION innodb_ft_enable_stopword = 1;
SET SESSION innodb_ft_user_stopword_table = default;
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
DROP TABLE articles,user_stopword,server_stopword;
# Restore Defaults
SET innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
SET GLOBAL innodb_ft_server_stopword_table=default;
SET SESSION innodb_ft_user_stopword_table=default;
#---------------------------------------------------------------------------------------
# Create FTS table
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT `idx` (title,body)
) ENGINE=InnoDB;
SHOW CREATE TABLE articles;
# Insert six rows
INSERT INTO articles (title,body) VALUES
('MySQL from Tutorial','DBMS stands for DataBase ...') ,
('when To Use MySQL Well','After that you went through a ...'),
('where will Optimizing MySQL','In what tutorial we will show ...'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
# No records expeced for select
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
# Define a correct formated user stopword table
create table user_stopword(value varchar(30)) engine = innodb;
# The set operation should be successful
set session innodb_ft_user_stopword_table = "test/user_stopword";
insert into user_stopword values("mysqld"),("DBMS");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld');
# Drop existing index and create the FTS index Using Alter Table.
# user stopword list will take effect.
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld');
# set user stopword list empty
set session innodb_ft_user_stopword_table = default;
# Define a correct formated user stopword table
create table server_stopword(value varchar(30)) engine = innodb;
# The set operation should be successful
set global innodb_ft_server_stopword_table = "test/server_stopword";
insert into server_stopword values("root"),("properly");
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly');
# set user stopword list empty
set session innodb_ft_user_stopword_table = "test/user_stopword";
# The set operation should be successful
set global innodb_ft_server_stopword_table = "test/server_stopword";
# user stopword list take effect as its session level
# Result expected for select
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly');
# set user stopword list
set session innodb_ft_user_stopword_table = "test/user_stopword";
DELETE FROM user_stopword;
# The set operation should be successful
set global innodb_ft_server_stopword_table = "test/server_stopword";
DELETE FROM server_stopword;
# user stopword list take affect as its session level
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld');
DROP TABLE articles,user_stopword,server_stopword;
# Restore Values
SET SESSION innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
SET GLOBAL innodb_ft_server_stopword_table=default;
SET SESSION innodb_ft_user_stopword_table=default;
#------------------------------------------------------------------------------
# FTS stopword list test - check varaibles across sessions
# Create FTS table
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT `idx` (title,body)
) ENGINE=InnoDB;
SHOW CREATE TABLE articles;
# Insert six rows
INSERT INTO articles (title,body) VALUES
('MySQL from Tutorial','DBMS stands for DataBase ...') ,
('when To Use MySQL Well','After that you went through a ...'),
('where will Optimizing MySQL','In what tutorial we will show ...'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
# session varaible innodb_ft_enable_stopword=0 will take effect for new FTS index
SET SESSION innodb_ft_enable_stopword = 0;
select @@innodb_ft_enable_stopword;
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
--echo "In connection 1"
--connection con1
select @@innodb_ft_enable_stopword;
ANALYZE TABLE articles;
# result expected as index created before setting innodb_ft_enable_stopword varaible off
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
SET SESSION innodb_ft_enable_stopword = 1;
select @@innodb_ft_enable_stopword;
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
# no result expected turned innodb_ft_enable_stopword is ON
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
--echo "In connection default"
--connection default
select @@innodb_ft_enable_stopword;
# no result expected as word not indexed from connection 1
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
SET SESSION innodb_ft_enable_stopword = 1;
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
--echo "In connection 1"
--connection con1
SET SESSION innodb_ft_enable_stopword = 1;
# Define a correct formated user stopword table
create table user_stopword(value varchar(30)) engine = innodb;
# The set operation should be successful
set session innodb_ft_user_stopword_table = "test/user_stopword";
# Add values into user supplied stop word table
insert into user_stopword values("this"),("will"),("the");
# Drop existing index and create the FTS index Using Alter Table.
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
# no result expected as innodb_ft_user_stopword_table filter it
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
--echo "In connection default"
--connection default
# no result expected as innodb_ft_user_stopword_table filter it from connection1
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
select @@innodb_ft_user_stopword_table;
# Define a correct formated user stopword table
create table user_stopword_1(value varchar(30)) engine = innodb;
# The set operation should be successful
set session innodb_ft_user_stopword_table = "test/user_stopword_1";
insert into user_stopword_1 values("when");
SET SESSION innodb_ft_enable_stopword = 1;
# result expected
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('when');
# Drop existing index and create the FTS index Using Alter Table.
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
# no result expected
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('when');
--echo "In connection 1"
--connection con1
SET SESSION innodb_ft_enable_stopword = 1;
SET SESSION innodb_ft_user_stopword_table=default;
select @@innodb_ft_user_stopword_table;
select @@innodb_ft_server_stopword_table;
# Define a correct formated server stopword table
create table server_stopword(value varchar(30)) engine = innodb;
# The set operation should be successful
SET GLOBAL innodb_ft_server_stopword_table = "test/server_stopword";
select @@innodb_ft_server_stopword_table;
insert into server_stopword values("when"),("the");
# Drop existing index and create the FTS index Using Alter Table.
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
# no result expected
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('the');
disconnect con1;
--source include/wait_until_disconnected.inc
--echo "In connection default"
--connection default
SET SESSION innodb_ft_enable_stopword = 1;
SET SESSION innodb_ft_user_stopword_table=default;
select @@innodb_ft_server_stopword_table;
# result expected
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where');
insert into server_stopword values("where"),("will");
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where');
ALTER TABLE articles DROP INDEX idx;
ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
# no result expected
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('the');
SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE);
SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where');
DROP TABLE articles,user_stopword,user_stopword_1,server_stopword;
# Restore Values
SET GLOBAL innodb_ft_user_stopword_table=@innodb_ft_user_stopword_table_orig;
SET GLOBAL innodb_ft_server_stopword_table=@innodb_ft_server_stopword_table_orig;

View File

@ -1,52 +1,24 @@
create table t1 (c1 int, c2 geometry not null, spatial index (c2))engine=innodb;
insert into t1 values(1, Point(1,1));
insert into t1 values(2, Point(2,2));
insert into t1 values(3, Point(3,3));
insert into t1 values(4, Point(4,4));
insert into t1 values(5, Point(5,5));
insert into t1 values(6, Point(6,6));
insert into t1 values(7, Point(7,7));
insert into t1 values(8, Point(8,8));
insert into t1 values(9, Point(9,9));
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
begin;
insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
from seq_1_to_576;
SET @saved_dbug = @@SESSION.debug_dbug;
SET debug_dbug = '+d, rtr_page_need_second_split';
insert into t1 select * from t1;
SET debug_dbug = '+d,rtr_page_need_second_split';
insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
from seq_1_to_576;
SET debug_dbug = @saved_dbug;
delete from t1;
insert into t1 values(1, Point(1,1));
insert into t1 values(2, Point(2,2));
insert into t1 values(3, Point(3,3));
insert into t1 values(4, Point(4,4));
insert into t1 values(5, Point(5,5));
insert into t1 values(6, Point(6,6));
insert into t1 values(7, Point(7,7));
insert into t1 values(8, Point(8,8));
insert into t1 values(9, Point(9,9));
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
start transaction;
insert into t1 select * from t1;
rollback;
insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
from seq_1_to_2304;
begin;
insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
from seq_1_to_2304;
rollback;
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
from seq_1_to_71424;
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK

View File

@ -1,5 +1,5 @@
# WL#6745 InnoDB R-tree support
# This test case will test R-tree split, mostly on duplciate records.
# This test case will test R-tree split, mostly on duplicate records.
# Not supported in embedded
--source include/not_embedded.inc
@ -8,66 +8,34 @@
--source include/big_test.inc
--source include/not_valgrind.inc
--source include/have_debug.inc
--source include/have_sequence.inc
let $restart_noprint=2;
# Create table with R-tree index.
create table t1 (c1 int, c2 geometry not null, spatial index (c2))engine=innodb;
begin;
# Insert enough values to let R-tree split.
insert into t1 values(1, Point(1,1));
insert into t1 values(2, Point(2,2));
insert into t1 values(3, Point(3,3));
insert into t1 values(4, Point(4,4));
insert into t1 values(5, Point(5,5));
insert into t1 values(6, Point(6,6));
insert into t1 values(7, Point(7,7));
insert into t1 values(8, Point(8,8));
insert into t1 values(9, Point(9,9));
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
from seq_1_to_576;
#Check second round spliting.
SET @saved_dbug = @@SESSION.debug_dbug;
SET debug_dbug = '+d, rtr_page_need_second_split';
insert into t1 select * from t1;
SET debug_dbug = '+d,rtr_page_need_second_split';
insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
from seq_1_to_576;
SET debug_dbug = @saved_dbug;
rollback;
delete from t1;
insert into t1 values(1, Point(1,1));
insert into t1 values(2, Point(2,2));
insert into t1 values(3, Point(3,3));
insert into t1 values(4, Point(4,4));
insert into t1 values(5, Point(5,5));
insert into t1 values(6, Point(6,6));
insert into t1 values(7, Point(7,7));
insert into t1 values(8, Point(8,8));
insert into t1 values(9, Point(9,9));
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
start transaction;
insert into t1 select * from t1;
insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
from seq_1_to_2304;
begin;
insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
from seq_1_to_2304;
rollback;
check table t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
from seq_1_to_71424;
check table t1;
select count(*) from t1;

View File

@ -0,0 +1,11 @@
CREATE TABLE t(i INT) ENGINE INNODB;
connect con1,localhost,root,,;
BEGIN;
LOCK TABLES t WRITE;
connection default;
# xtrabackup backup
connection con1;
COMMIT;
connection default;
disconnect con1;
DROP TABLE t;

View File

@ -0,0 +1,28 @@
--source include/have_innodb.inc
--source include/count_sessions.inc
CREATE TABLE t(i INT) ENGINE INNODB;
connect (con1,localhost,root,,);
BEGIN;
LOCK TABLES t WRITE;
--connection default
echo # xtrabackup backup;
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
--disable_result_log
--error 1
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --ftwrl-wait-timeout=1 --target-dir=$targetdir;
--enable_result_log
--connection con1
COMMIT;
--connection default
--disconnect con1
DROP TABLE t;
rmdir $targetdir;
--source include/wait_until_count_sessions.inc

View File

@ -7,12 +7,13 @@ use strict;
return "Not run for embedded server" if $::opt_embedded_server;
return "No mariabackup" unless ::have_mariabackup();
return "No mariabackup" unless $ENV{XTRABACKUP};
my $have_qpress = index(`qpress 2>&1`,"Compression") > 0;
sub skip_combinations {
my %skip;
$skip{'include/have_file_key_management.inc'} = 'needs file_key_management plugin' unless $ENV{FILE_KEY_MANAGEMENT_SO};
$skip{'compress_qpress.test'}= 'needs qpress executable in PATH' unless $have_qpress;
%skip;
}

View File

@ -153,8 +153,10 @@ show create user mysqltest1;
CREATE USER for mysqltest1@%
CREATE USER `mysqltest1`@`%` IDENTIFIED VIA mysql_native_password USING '*BFE3F4604CFD21E6595080A261D92EF0183B5971' OR unix_socket
drop user mysqltest1;
# switching from mysql.global_priv to mysql.user
create user mysqltest1 identified via ed25519 as password("good") OR unix_socket OR mysql_native_password as password("works");
ERROR HY000: Column count of mysql.user is wrong. Expected 3, found 47. Created with MariaDB XX.YY.ZZ, now running XX.YY.ZZ. Please use mariadb-upgrade to fix this error
# switching back from mysql.user to mysql.global_priv
create user USER identified via mysql_native_password as '1234567890123456789012345678901234567890a' OR unix_socket;
create user mysqltest1 identified via mysql_native_password as '1234567890123456789012345678901234567890a' OR unix_socket;
update mysql.global_priv set priv=replace(priv, '1234567890123456789012345678901234567890a', 'invalid password');
@ -192,3 +194,16 @@ user() current_user() database()
mysqltest1@localhost mysqltest1@% test
drop user mysqltest1;
uninstall soname 'auth_ed25519';
create user mysqltest1 identified via mysql_native_password as password("good") OR unix_socket;
show create user mysqltest1;
CREATE USER for mysqltest1@%
CREATE USER `mysqltest1`@`%` IDENTIFIED VIA mysql_native_password USING '*8409037B3E362D6DAE24C8E667F4D3B66716144E' OR unix_socket
alter user mysqltest1 identified via mysql_native_password as password("better");
show create user mysqltest1;
CREATE USER for mysqltest1@%
CREATE USER `mysqltest1`@`%` IDENTIFIED BY PASSWORD '*6E6CABC9967AB586F009616BA69DAC2953849C88'
flush privileges;
show create user mysqltest1;
CREATE USER for mysqltest1@%
CREATE USER `mysqltest1`@`%` IDENTIFIED BY PASSWORD '*6E6CABC9967AB586F009616BA69DAC2953849C88'
drop user mysqltest1;

View File

@ -198,3 +198,14 @@ drop user mysqltest1;
uninstall soname 'auth_ed25519';
--remove_file $MYSQLTEST_VARDIR/tmp/peercred_test.txt
#
# MDEV-21928 ALTER USER doesn't remove excess authentication plugins from mysql.global_priv
#
create user mysqltest1 identified via mysql_native_password as password("good") OR unix_socket;
show create user mysqltest1;
alter user mysqltest1 identified via mysql_native_password as password("better");
show create user mysqltest1;
flush privileges;
show create user mysqltest1;
drop user mysqltest1;

View File

@ -1,3 +1,4 @@
# switching from mysql.global_priv to mysql.user
connect mysql, localhost, root,,;
use mysql;
alter table user drop column is_role;
@ -26,3 +27,4 @@ update user set is_role='N';
flush privileges;
create role test_role;
drop role test_role;
# switching back from mysql.user to mysql.global_priv

View File

@ -1,4 +1,5 @@
--source include/have_innodb.inc
--source include/have_perfschema.inc
--echo #
--echo # MDEV-15977 Assertion `! thd->in_sub_stmt' failed in trans_commit_stmt

View File

@ -0,0 +1,117 @@
package wsrep::common;
use base qw(Exporter);
our @EXPORT= qw(wsrep_not_ok);
use File::Basename;
use Memoize;
memoize 'wrong_wsrep_version';
memoize 'check_garbd_support';
memoize 'check_wsrep_support';
memoize 'wsrep_not_ok';
use mtr_report;
my $extra_path;
my $mariabackup_path;
my $mariabackup_exe;
my $garbd_exe;
my $file_wsrep_provider;
sub wrong_wsrep_version() {
my $check_version= dirname($My::SafeProcess::safe_process_cmd[0]) . '/wsrep_check_version';
my $checked = `$check_version -p`;
chomp($checked);
return $? ? $checked : undef;
}
sub which($) { return `sh -c "command -v $_[0]"` }
sub check_garbd_support() {
my $wsrep_path= dirname($file_wsrep_provider);
$garbd_exe= ::mtr_file_exists($wsrep_path."/garb/garbd",
$wsrep_path."/../../bin/garb/garbd",
'/usr/bin/garbd');
$ENV{MTR_GARBD_EXE}= $garbd_exe if $garbd_exe;
}
sub check_wsrep_support() {
mtr_report(" - binaries built with wsrep patch");
# ADD scripts to $PATH to that wsrep_sst_* can be found
my ($spath) = grep { -f "$_/wsrep_sst_rsync"; } "$::bindir/scripts", $::path_client_bindir;
mtr_error("No SST scripts") unless $spath;
$ENV{PATH}="$spath:$ENV{PATH}";
# ADD mysql client library path to path so that wsrep_notify_cmd can find mysql
# client for loading the tables. (Don't assume each machine has mysql install)
my ($cpath) = grep { -f "$_/mysql"; } "$::bindir/scripts", $::path_client_bindir;
mtr_error("No scritps") unless $cpath;
$ENV{PATH}="$cpath:$ENV{PATH}" unless $cpath eq $spath;
# ADD my_print_defaults script path to path so that SST scripts can find it
my $my_print_defaults_exe=
::mtr_exe_maybe_exists(
"$::bindir/extra/my_print_defaults",
"$::path_client_bindir/my_print_defaults");
my $epath= "";
if ($my_print_defaults_exe ne "") {
$epath= dirname($my_print_defaults_exe);
}
mtr_error("No my_print_defaults") unless $epath;
$ENV{PATH}="$epath:$ENV{PATH}" unless ($epath eq $spath) or
($epath eq $cpath);
$extra_path= $epath;
if (which("socat")) {
$ENV{MTR_GALERA_TFMT}="socat";
} elsif (which("nc")) {
$ENV{MTR_GALERA_TFMT}="nc";
}
$ENV{PATH}=dirname($ENV{XTRABACKUP}).":$ENV{PATH}" if $ENV{XTRABACKUP};
# Check whether WSREP_PROVIDER environment variable is set.
if (defined $ENV{'WSREP_PROVIDER'}) {
$file_wsrep_provider= "";
if ($ENV{'WSREP_PROVIDER'} ne "none") {
if (::mtr_file_exists($ENV{'WSREP_PROVIDER'}) ne "") {
$file_wsrep_provider= $ENV{'WSREP_PROVIDER'};
} else {
mtr_error("WSREP_PROVIDER env set to an invalid path");
}
check_garbd_support();
}
# WSREP_PROVIDER is valid; set to a valid path or "none").
mtr_verbose("WSREP_PROVIDER env set to $ENV{'WSREP_PROVIDER'}");
} else {
# WSREP_PROVIDER env not defined. Lets try to locate the wsrep provider
# library.
$file_wsrep_provider=
::mtr_file_exists("/usr/lib64/galera-4/libgalera_smm.so",
"/usr/lib64/galera/libgalera_smm.so",
"/usr/lib/galera-4/libgalera_smm.so",
"/usr/lib/galera/libgalera_smm.so");
if ($file_wsrep_provider ne "") {
# wsrep provider library found !
mtr_verbose("wsrep provider library found : $file_wsrep_provider");
$ENV{'WSREP_PROVIDER'}= $file_wsrep_provider;
check_garbd_support();
} else {
mtr_verbose("Could not find wsrep provider library, setting it to 'none'");
$ENV{'WSREP_PROVIDER'}= "none";
}
}
}
sub wsrep_not_ok() {
return "Not run for embedded server" if $::opt_embedded_server;
return "WSREP is not compiled in" if not $::mysqld_variables{'wsrep-on'};
check_wsrep_support();
return "No wsrep provider library" unless $file_wsrep_provider;
return wrong_wsrep_version() if wrong_wsrep_version();
undef;
}
1;

View File

@ -1,16 +1,11 @@
package My::Suite::WSREP;
use File::Basename;
use My::Find;
use lib 'suite';
use wsrep::common;
@ISA = qw(My::Suite);
return "Not run for embedded server" if $::opt_embedded_server;
return "WSREP is not compiled in" unless ::have_wsrep();
return "No wsrep provider library" unless ::have_wsrep_provider();
return ::wsrep_version_message() unless ::check_wsrep_version();
return wsrep_not_ok() if wsrep_not_ok();
push @::global_suppressions,
(

View File

@ -137,7 +137,7 @@ void my_thread_global_reinit(void)
my_thread_destroy_internal_mutex();
my_thread_init_internal_mutex();
tmp= my_pthread_getspecific(struct st_my_thread_var*, THR_KEY_mysys);
tmp= my_thread_var;
DBUG_ASSERT(tmp);
my_thread_destory_thr_mutex(tmp);
@ -274,7 +274,7 @@ my_bool my_thread_init(void)
fprintf(stderr,"my_thread_init(): pthread_self: %p\n", pthread_self());
#endif
if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys))
if (my_thread_var)
{
#ifdef EXTRA_DEBUG_THREADS
fprintf(stderr,"my_thread_init() called more than once in thread 0x%lx\n",
@ -292,7 +292,7 @@ my_bool my_thread_init(void)
error= 1;
goto end;
}
pthread_setspecific(THR_KEY_mysys,tmp);
set_mysys_var(tmp);
tmp->pthread_self= pthread_self();
my_thread_init_thr_mutex(tmp);
@ -329,7 +329,7 @@ end:
void my_thread_end(void)
{
struct st_my_thread_var *tmp;
tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
tmp= my_thread_var;
#ifdef EXTRA_DEBUG_THREADS
fprintf(stderr,"my_thread_end(): tmp: %p pthread_self: %p thread_id: %ld\n",
@ -350,7 +350,7 @@ void my_thread_end(void)
as the key is used by DBUG.
*/
DBUG_POP();
pthread_setspecific(THR_KEY_mysys,0);
set_mysys_var(NULL);
if (tmp && tmp->init)
{
@ -434,7 +434,7 @@ extern void **my_thread_var_dbug()
struct st_my_thread_var *tmp;
if (!my_thread_global_init_done)
return NULL;
tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
tmp= my_thread_var;
return tmp && tmp->init ? &tmp->dbug : 0;
}
#endif /* DBUG_OFF */
@ -446,7 +446,7 @@ safe_mutex_t **my_thread_var_mutex_in_use()
struct st_my_thread_var *tmp;
if (!my_thread_global_init_done)
return NULL;
tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
tmp= my_thread_var;
return tmp ? &tmp->mutex_in_use : 0;
}

View File

@ -22,7 +22,7 @@ IF(HAVE_PAM_APPL_H)
IF(HAVE_STRNDUP)
ADD_DEFINITIONS(-DHAVE_STRNDUP)
ENDIF(HAVE_STRNDUP)
FIND_LIBRARY(PAM_LIBRARY pam)
FIND_LIBRARY(PAM_LIBRARY pam) # for srpm build-depends detection
ADD_DEFINITIONS(-D_GNU_SOURCE)
MYSQL_ADD_PLUGIN(auth_pam_v1 auth_pam_v1.c LINK_LIBRARIES pam MODULE_ONLY)
MYSQL_ADD_PLUGIN(auth_pam auth_pam.c LINK_LIBRARIES pam dl MODULE_ONLY)
@ -42,7 +42,7 @@ IF(HAVE_PAM_APPL_H)
SET_TARGET_PROPERTIES (pam_user_map PROPERTIES PREFIX "")
IF(INSTALL_PAMDIR)
INSTALL(TARGETS pam_user_map DESTINATION ${INSTALL_PAMDIR} COMPONENT Server)
INSTALL(FILES mapper/user_map.conf DESTINATION /etc/security COMPONENT Server)
INSTALL(FILES mapper/user_map.conf DESTINATION ${INSTALL_PAMDATADIR} COMPONENT Server)
ENDIF()
ENDIF()
ENDIF(HAVE_PAM_APPL_H)

View File

@ -4,15 +4,9 @@ use My::Find;
@ISA = qw(My::Suite);
return "Not run for embedded server" if $::opt_embedded_server;
return "WSREP is not compiled in" if not ::have_wsrep();
return "No wsrep provider library" unless ::have_wsrep_provider();
return ::wsrep_version_message() unless ::check_wsrep_version();
return "No WSREP_INFO plugin" unless $ENV{WSREP_INFO_SO};
use lib 'suite';
use wsrep::common;
return wsrep_not_ok() if wsrep_not_ok();
push @::global_suppressions,
(

View File

@ -648,6 +648,7 @@ UPDATE user SET Delete_history_priv = Super_priv WHERE @had_user_delete_history_
ALTER TABLE user ADD plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL,
ADD authentication_string TEXT NOT NULL;
ALTER TABLE user CHANGE auth_string authentication_string TEXT NOT NULL;
ALTER TABLE user MODIFY plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL,
MODIFY authentication_string TEXT NOT NULL;
ALTER TABLE user ADD password_expired ENUM('N', 'Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL;

View File

@ -4803,7 +4803,7 @@ Alter_inplace_info::Alter_inplace_info(HA_CREATE_INFO *create_info_arg,
Alter_info *alter_info_arg,
KEY *key_info_arg, uint key_count_arg,
partition_info *modified_part_info_arg,
bool ignore_arg)
bool ignore_arg, bool error_non_empty)
: create_info(create_info_arg),
alter_info(alter_info_arg),
key_info_buffer(key_info_arg),
@ -4819,7 +4819,8 @@ Alter_inplace_info::Alter_inplace_info(HA_CREATE_INFO *create_info_arg,
modified_part_info(modified_part_info_arg),
ignore(ignore_arg),
online(false),
unsupported_reason(nullptr)
unsupported_reason(nullptr),
error_if_not_empty(error_non_empty)
{}
void Alter_inplace_info::report_unsupported_error(const char *not_supported,

View File

@ -2496,11 +2496,14 @@ public:
*/
const char *unsupported_reason;
/** true when InnoDB should abort the alter when table is not empty */
bool error_if_not_empty;
Alter_inplace_info(HA_CREATE_INFO *create_info_arg,
Alter_info *alter_info_arg,
KEY *key_info_arg, uint key_count_arg,
partition_info *modified_part_info_arg,
bool ignore_arg);
bool ignore_arg, bool error_non_empty);
~Alter_inplace_info()
{

View File

@ -2572,19 +2572,20 @@ void Item_func_rand::seed_random(Item *arg)
TODO: do not do reinit 'rand' for every execute of PS/SP if
args[0] is a constant.
*/
uint32 tmp;
uint32 tmp= (uint32) arg->val_int();
#ifdef WITH_WSREP
THD *thd= current_thd;
if (WSREP(thd))
if (WSREP_ON)
{
if (wsrep_thd_is_applying(thd))
tmp= thd->wsrep_rand;
else
tmp= thd->wsrep_rand= (uint32) arg->val_int();
}
else
THD *thd= current_thd;
if (WSREP(thd))
{
if (wsrep_thd_is_applying(thd))
tmp= thd->wsrep_rand;
else
thd->wsrep_rand= tmp;
}
}
#endif /* WITH_WSREP */
tmp= (uint32) arg->val_int();
my_rnd_init(rand, (uint32) (tmp*0x10001L+55555555L),
(uint32) (tmp*0x10000001L));

View File

@ -2120,7 +2120,8 @@ Query_log_event::do_shall_skip(rpl_group_info *rgi)
}
}
#ifdef WITH_WSREP
else if (WSREP(thd) && wsrep_mysql_replication_bundle && opt_slave_domain_parallel_threads == 0 &&
else if (WSREP(thd) && wsrep_mysql_replication_bundle &&
opt_slave_domain_parallel_threads == 0 &&
thd->wsrep_mysql_replicated > 0 &&
(is_begin() || is_commit()))
{

View File

@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
Copyright (c) 2008, 2020, MariaDB Corporation.
Copyright (c) 2008, 2020, MariaDB
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
@ -1947,10 +1947,10 @@ static void mysqld_exit(int exit_code)
set_malloc_size_cb(NULL);
if (global_status_var.global_memory_used)
{
#ifdef SAFEMALLOC
sf_report_leaked_memory(0);
#endif
DBUG_SLOW_ASSERT(global_status_var.global_memory_used == 0);
fprintf(stderr, "Warning: Memory not freed: %lld\n",
(longlong) global_status_var.global_memory_used);
if (exit_code == 0)
SAFEMALLOC_REPORT_MEMORY(0);
}
cleanup_tls();
DBUG_LEAVE;

View File

@ -1450,9 +1450,12 @@ class User_table_json: public User_table
bool set_auth(const ACL_USER &u) const
{
StringBuffer<JSON_SIZE> json(m_table->field[2]->charset());
if (u.nauth == 1)
size_t array_len;
const char *array;
if (u.nauth == 1 && get_value("auth_or", JSV_ARRAY, &array, &array_len))
return set_auth1(u, 0);
StringBuffer<JSON_SIZE> json(m_table->field[2]->charset());
bool top_done = false;
json.append('[');
for (uint i=0; i < u.nauth; i++)
@ -1949,10 +1952,13 @@ class Grant_tables
int res= really_open(thd, first, &counter);
/* if User_table_json wasn't found, let's try User_table_tabular */
if (!res && (which_tables & Table_user) && !(tables[USER_TABLE].table))
if (!res && (which_tables & Table_user) && !tables[USER_TABLE].table)
{
uint unused;
TABLE_LIST *tl= tables + USER_TABLE;
TABLE *backup_open_tables= thd->open_tables;
thd->set_open_tables(NULL);
tl->init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_TABLE_NAME_USER,
NULL, lock_type);
tl->open_type= OT_BASE_ONLY;
@ -1961,6 +1967,12 @@ class Grant_tables
p_user_table= &m_user_table_tabular;
counter++;
res= really_open(thd, tl, &unused);
thd->set_open_tables(backup_open_tables);
if (tables[USER_TABLE].table)
{
tables[USER_TABLE].table->next= backup_open_tables;
thd->set_open_tables(tables[USER_TABLE].table);
}
}
if (res)
DBUG_RETURN(res);

View File

@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
Copyright (c) 2010, 2019, MariaDB
Copyright (c) 2010, 2020, MariaDB
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

View File

@ -10332,7 +10332,7 @@ do_continue:;
Alter_inplace_info ha_alter_info(create_info, alter_info,
key_info, key_count,
IF_PARTITIONING(thd->work_part_info, NULL),
ignore);
ignore, alter_ctx.error_if_not_empty);
TABLE_SHARE altered_share;
TABLE altered_table;
bool use_inplace= true;
@ -10863,7 +10863,8 @@ err_new_table_cleanup:
thd->get_stmt_da()->current_row_for_warning()))
{
Abort_on_warning_instant_set aws(thd, true);
alter_ctx.report_implicit_default_value_error(thd, new_table->s);
alter_ctx.report_implicit_default_value_error(thd, new_table
? new_table->s : table->s);
}
if (new_table)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2012, 2020, MariaDB Corporation.
/* Copyright (C) 2012, 2020, MariaDB
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
@ -50,7 +50,6 @@ static void threadpool_remove_connection(THD *thd);
static int threadpool_process_request(THD *thd);
static THD* threadpool_add_connection(CONNECT *connect, void *scheduler_data);
extern "C" pthread_key(struct st_my_thread_var*, THR_KEY_mysys);
extern bool do_command(THD*);
static inline TP_connection *get_TP_connection(THD *thd)
@ -89,14 +88,14 @@ struct Worker_thread_context
void save()
{
psi_thread = PSI_CALL_get_thread();
mysys_var= (st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
psi_thread= PSI_CALL_get_thread();
mysys_var= my_thread_var;
}
void restore()
{
PSI_CALL_set_thread(psi_thread);
pthread_setspecific(THR_KEY_mysys,mysys_var);
set_mysys_var(mysys_var);
pthread_setspecific(THR_THD, 0);
}
};
@ -147,7 +146,7 @@ static void thread_attach(THD* thd)
attaching the thd. */
wsrep_wait_rollback_complete_and_acquire_ownership(thd);
#endif /* WITH_WSREP */
pthread_setspecific(THR_KEY_mysys,thd->mysys_var);
set_mysys_var(thd->mysys_var);
thd->thread_stack=(char*)&thd;
thd->store_globals();
PSI_CALL_set_thread(thd->get_psi());
@ -231,9 +230,9 @@ static THD* threadpool_add_connection(CONNECT *connect, void *scheduler_data)
Store them in THD.
*/
pthread_setspecific(THR_KEY_mysys, 0);
set_mysys_var(NULL);
my_thread_init();
st_my_thread_var* mysys_var= (st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
st_my_thread_var* mysys_var= my_thread_var;
PSI_CALL_set_thread(PSI_CALL_new_thread(key_thread_one_connection, connect, 0));
if (!mysys_var ||!(thd= connect->create_thd(NULL)))
{

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2014 SkySQL Ab.
/* Copyright (C) 2014, 2020, MariaDB
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
@ -136,6 +136,10 @@ my_bool wsrep_get_debug()
void wsrep_commit_ordered(THD* )
{ }
void wsrep_log(void (*)(const char *, ...), const char *, ...)
{
}
my_bool wsrep_thd_is_applying(const THD*)
{ return 0;}

View File

@ -25,6 +25,7 @@ Created April 08, 2011 Vasil Dimov
*******************************************************/
#include "my_global.h"
#include "mysqld.h"
#include "my_sys.h"
#include "mysql/psi/mysql_stage.h"
@ -175,7 +176,7 @@ get_buf_dump_dir()
/* The dump file should be created in the default data directory if
innodb_data_home_dir is set as an empty string. */
if (strcmp(srv_data_home, "") == 0) {
if (!*srv_data_home) {
dump_dir = fil_path_to_mysql_datadir;
} else {
dump_dir = srv_data_home;
@ -187,16 +188,14 @@ get_buf_dump_dir()
/** Generate the path to the buffer pool dump/load file.
@param[out] path generated path
@param[in] path_size size of 'path', used as in snprintf(3). */
static
void
buf_dump_generate_path(
char* path,
size_t path_size)
static void buf_dump_generate_path(char *path, size_t path_size)
{
char buf[FN_REFLEN];
mysql_mutex_lock(&LOCK_global_system_variables);
snprintf(buf, sizeof(buf), "%s%c%s", get_buf_dump_dir(),
OS_PATH_SEPARATOR, srv_buf_dump_filename);
mysql_mutex_unlock(&LOCK_global_system_variables);
os_file_type_t type;
bool exists = false;

View File

@ -32,6 +32,7 @@ Created Apr 25, 2012 Vasil Dimov
#include "srv0start.h"
#include "fil0fil.h"
#ifdef WITH_WSREP
# include "trx0trx.h"
# include "mysql/service_wsrep.h"
# include "wsrep.h"
# include "log.h"
@ -137,12 +138,12 @@ dict_stats_recalc_pool_add(
schedule new estimates for table and index statistics to be calculated.
@param[in,out] table persistent or temporary table
@param[in] thd current session */
void dict_stats_update_if_needed(dict_table_t* table, THD* thd)
void dict_stats_update_if_needed(dict_table_t *table, const trx_t &trx)
#else
/** Update the table modification counter and if necessary,
schedule new estimates for table and index statistics to be calculated.
@param[in,out] table persistent or temporary table */
void dict_stats_update_if_needed_func(dict_table_t* table)
void dict_stats_update_if_needed_func(dict_table_t *table)
#endif
{
ut_ad(table->stat_initialized);
@ -169,9 +170,9 @@ void dict_stats_update_if_needed_func(dict_table_t* table)
generated row locks and allow BF thread
lock waits to be enqueued at head of waiting
queue. */
if (wsrep_on(thd)
&& !wsrep_thd_is_applying(thd)
&& wsrep_thd_is_BF(thd, 0)) {
if (trx.is_wsrep()
&& !wsrep_thd_is_applying(trx.mysql_thd)
&& wsrep_thd_is_BF(trx.mysql_thd, 0)) {
WSREP_DEBUG("Avoiding background statistics"
" calculation for table %s.",
table->name.m_name);

View File

@ -444,9 +444,9 @@ fts_read_stopword(
/******************************************************************//**
Load user defined stopword from designated user table
@return TRUE if load operation is successful */
@return whether the operation is successful */
static
ibool
bool
fts_load_user_stopword(
/*===================*/
fts_t* fts, /*!< in: FTS struct */
@ -454,27 +454,26 @@ fts_load_user_stopword(
name */
fts_stopword_t* stopword_info) /*!< in: Stopword info */
{
pars_info_t* info;
que_t* graph;
dberr_t error = DB_SUCCESS;
ibool ret = TRUE;
trx_t* trx;
ibool has_lock = fts->dict_locked;
trx = trx_create();
trx->op_info = "Load user stopword table into FTS cache";
if (!has_lock) {
if (!fts->dict_locked) {
mutex_enter(&dict_sys.mutex);
}
/* Validate the user table existence and in the right
format */
/* Validate the user table existence in the right format */
bool ret= false;
stopword_info->charset = fts_valid_stopword_table(stopword_table_name);
if (!stopword_info->charset) {
ret = FALSE;
goto cleanup;
} else if (!stopword_info->cached_stopword) {
cleanup:
if (!fts->dict_locked) {
mutex_exit(&dict_sys.mutex);
}
return ret;
}
trx_t* trx = trx_create();
trx->op_info = "Load user stopword table into FTS cache";
if (!stopword_info->cached_stopword) {
/* Create the stopword RB tree with the stopword column
charset. All comparison will use this charset */
stopword_info->cached_stopword = rbt_create_arg_cmp(
@ -483,14 +482,14 @@ fts_load_user_stopword(
}
info = pars_info_create();
pars_info_t* info = pars_info_create();
pars_info_bind_id(info, TRUE, "table_stopword", stopword_table_name);
pars_info_bind_function(info, "my_func", fts_read_stopword,
stopword_info);
graph = fts_parse_sql_no_dict_lock(
que_t* graph = fts_parse_sql_no_dict_lock(
info,
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
@ -508,14 +507,13 @@ fts_load_user_stopword(
"CLOSE c;");
for (;;) {
error = fts_eval_sql(trx, graph);
dberr_t error = fts_eval_sql(trx, graph);
if (error == DB_SUCCESS) {
fts_sql_commit(trx);
stopword_info->status = STOPWORD_USER_TABLE;
break;
} else {
fts_sql_rollback(trx);
if (error == DB_LOCK_WAIT_TIMEOUT) {
@ -534,14 +532,9 @@ fts_load_user_stopword(
}
que_graph_free(graph);
cleanup:
if (!has_lock) {
mutex_exit(&dict_sys.mutex);
}
trx_free(trx);
return(ret);
ret = true;
goto cleanup;
}
/******************************************************************//**
@ -3359,7 +3352,7 @@ fts_add_doc_from_tuple(
if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) {
fts_load_stopword(table, NULL, NULL,
NULL, TRUE, TRUE);
true, true);
}
fts_cache_add_doc(
@ -3523,8 +3516,8 @@ fts_add_doc_by_id(
if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) {
fts_load_stopword(table, NULL, NULL,
NULL, TRUE, TRUE);
fts_load_stopword(table, NULL,
NULL, true, true);
}
fts_cache_add_doc(
@ -7045,20 +7038,18 @@ This function loads the stopword into the FTS cache. It also
records/fetches stopword configuration to/from FTS configure
table, depending on whether we are creating or reloading the
FTS.
@return TRUE if load operation is successful */
ibool
@return true if load operation is successful */
bool
fts_load_stopword(
/*==============*/
const dict_table_t*
table, /*!< in: Table with FTS */
trx_t* trx, /*!< in: Transactions */
const char* global_stopword_table, /*!< in: Global stopword table
name */
const char* session_stopword_table, /*!< in: Session stopword table
name */
ibool stopword_is_on, /*!< in: Whether stopword
bool stopword_is_on, /*!< in: Whether stopword
option is turned on/off */
ibool reload) /*!< in: Whether it is
bool reload) /*!< in: Whether it is
for reloading FTS table */
{
fts_table_t fts_table;
@ -7074,9 +7065,8 @@ fts_load_stopword(
cache = table->fts->cache;
if (!reload && !(cache->stopword_info.status
& STOPWORD_NOT_INIT)) {
return(TRUE);
if (!reload && !(cache->stopword_info.status & STOPWORD_NOT_INIT)) {
return true;
}
if (!trx) {
@ -7126,12 +7116,11 @@ fts_load_stopword(
goto cleanup;
}
if (strlen((char*) str.f_str) > 0) {
if (*str.f_str) {
stopword_to_use = (const char*) str.f_str;
}
} else {
stopword_to_use = (session_stopword_table)
? session_stopword_table : global_stopword_table;
stopword_to_use = session_stopword_table;
}
if (stopword_to_use
@ -7169,7 +7158,7 @@ cleanup:
&my_charset_latin1);
}
return(error == DB_SUCCESS);
return error == DB_SUCCESS;
}
/**********************************************************************//**
@ -7370,7 +7359,7 @@ fts_init_index(
} else {
if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) {
fts_load_stopword(table, NULL, NULL, NULL, TRUE, TRUE);
fts_load_stopword(table, NULL, NULL, true, true);
}
for (ulint i = 0; i < ib_vector_size(cache->get_docs); ++i) {

View File

@ -683,6 +683,121 @@ rtr_page_get_father(
mem_heap_free(heap);
}
/********************************************************************//**
Returns the upper level node pointer to a R-Tree page. It is assumed
that mtr holds an x-latch on the tree. */
static void rtr_get_father_node(
dict_index_t* index, /*!< in: index */
ulint level, /*!< in: the tree level of search */
const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
tuple must be set so that it cannot get
compared to the node ptr page number field! */
btr_cur_t* sea_cur,/*!< in: search cursor */
btr_cur_t* btr_cur,/*!< in/out: tree cursor; the cursor page is
s- or x-latched, but see also above! */
ulint page_no,/*!< Current page no */
mtr_t* mtr) /*!< in: mtr */
{
mem_heap_t* heap = NULL;
bool ret = false;
const rec_t* rec;
ulint n_fields;
bool new_rtr = false;
/* Try to optimally locate the parent node. Level should always
less than sea_cur->tree_height unless the root is splitting */
if (sea_cur && sea_cur->tree_height > level) {
ut_ad(mtr_memo_contains_flagged(mtr,
dict_index_get_lock(index),
MTR_MEMO_X_LOCK
| MTR_MEMO_SX_LOCK));
ret = rtr_cur_restore_position(
BTR_CONT_MODIFY_TREE, sea_cur, level, mtr);
/* Once we block shrink tree nodes while there are
active search on it, this optimal locating should always
succeeds */
ut_ad(ret);
if (ret) {
btr_pcur_t* r_cursor = rtr_get_parent_cursor(
sea_cur, level, false);
rec = btr_pcur_get_rec(r_cursor);
ut_ad(r_cursor->rel_pos == BTR_PCUR_ON);
page_cur_position(rec,
btr_pcur_get_block(r_cursor),
btr_cur_get_page_cur(btr_cur));
btr_cur->rtr_info = sea_cur->rtr_info;
btr_cur->tree_height = sea_cur->tree_height;
ut_ad(rtr_compare_cursor_rec(
index, btr_cur, page_no, &heap));
goto func_exit;
}
}
/* We arrive here in one of two scenario
1) check table and btr_valide
2) index root page being raised */
ut_ad(!sea_cur || sea_cur->tree_height == level);
if (btr_cur->rtr_info) {
rtr_clean_rtr_info(btr_cur->rtr_info, true);
} else {
new_rtr = true;
}
btr_cur->rtr_info = rtr_create_rtr_info(false, false, btr_cur, index);
if (sea_cur && sea_cur->tree_height == level) {
/* root split, and search the new root */
btr_cur_search_to_nth_level(
index, level, tuple, PAGE_CUR_RTREE_LOCATE,
BTR_CONT_MODIFY_TREE, btr_cur, 0,
__FILE__, __LINE__, mtr);
} else {
/* btr_validate */
ut_ad(level >= 1);
ut_ad(!sea_cur);
btr_cur_search_to_nth_level(
index, level, tuple, PAGE_CUR_RTREE_LOCATE,
BTR_CONT_MODIFY_TREE, btr_cur, 0,
__FILE__, __LINE__, mtr);
rec = btr_cur_get_rec(btr_cur);
n_fields = dtuple_get_n_fields_cmp(tuple);
if (page_rec_is_infimum(rec)
|| (btr_cur->low_match != n_fields)) {
ret = rtr_pcur_getnext_from_path(
tuple, PAGE_CUR_RTREE_LOCATE, btr_cur,
level, BTR_CONT_MODIFY_TREE,
true, mtr);
ut_ad(ret && btr_cur->low_match == n_fields);
}
}
ret = rtr_compare_cursor_rec(
index, btr_cur, page_no, &heap);
ut_ad(ret);
func_exit:
if (heap) {
mem_heap_free(heap);
}
if (new_rtr && btr_cur->rtr_info) {
rtr_clean_rtr_info(btr_cur->rtr_info, true);
btr_cur->rtr_info = NULL;
}
}
/** Returns the upper level node pointer to a R-Tree page. It is assumed
that mtr holds an SX-latch or X-latch on the tree.
@return rec_get_offsets() of the node pointer record */
@ -803,123 +918,6 @@ rtr_page_get_father_block(
cursor, mtr));
}
/********************************************************************//**
Returns the upper level node pointer to a R-Tree page. It is assumed
that mtr holds an x-latch on the tree. */
void
rtr_get_father_node(
/*================*/
dict_index_t* index, /*!< in: index */
ulint level, /*!< in: the tree level of search */
const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
tuple must be set so that it cannot get
compared to the node ptr page number field! */
btr_cur_t* sea_cur,/*!< in: search cursor */
btr_cur_t* btr_cur,/*!< in/out: tree cursor; the cursor page is
s- or x-latched, but see also above! */
ulint page_no,/*!< Current page no */
mtr_t* mtr) /*!< in: mtr */
{
mem_heap_t* heap = NULL;
bool ret = false;
const rec_t* rec;
ulint n_fields;
bool new_rtr = false;
/* Try to optimally locate the parent node. Level should always
less than sea_cur->tree_height unless the root is splitting */
if (sea_cur && sea_cur->tree_height > level) {
ut_ad(mtr_memo_contains_flagged(mtr,
dict_index_get_lock(index),
MTR_MEMO_X_LOCK
| MTR_MEMO_SX_LOCK));
ret = rtr_cur_restore_position(
BTR_CONT_MODIFY_TREE, sea_cur, level, mtr);
/* Once we block shrink tree nodes while there are
active search on it, this optimal locating should always
succeeds */
ut_ad(ret);
if (ret) {
btr_pcur_t* r_cursor = rtr_get_parent_cursor(
sea_cur, level, false);
rec = btr_pcur_get_rec(r_cursor);
ut_ad(r_cursor->rel_pos == BTR_PCUR_ON);
page_cur_position(rec,
btr_pcur_get_block(r_cursor),
btr_cur_get_page_cur(btr_cur));
btr_cur->rtr_info = sea_cur->rtr_info;
btr_cur->tree_height = sea_cur->tree_height;
ut_ad(rtr_compare_cursor_rec(
index, btr_cur, page_no, &heap));
goto func_exit;
}
}
/* We arrive here in one of two scenario
1) check table and btr_valide
2) index root page being raised */
ut_ad(!sea_cur || sea_cur->tree_height == level);
if (btr_cur->rtr_info) {
rtr_clean_rtr_info(btr_cur->rtr_info, true);
} else {
new_rtr = true;
}
btr_cur->rtr_info = rtr_create_rtr_info(false, false, btr_cur, index);
if (sea_cur && sea_cur->tree_height == level) {
/* root split, and search the new root */
btr_cur_search_to_nth_level(
index, level, tuple, PAGE_CUR_RTREE_LOCATE,
BTR_CONT_MODIFY_TREE, btr_cur, 0,
__FILE__, __LINE__, mtr);
} else {
/* btr_validate */
ut_ad(level >= 1);
ut_ad(!sea_cur);
btr_cur_search_to_nth_level(
index, level, tuple, PAGE_CUR_RTREE_LOCATE,
BTR_CONT_MODIFY_TREE, btr_cur, 0,
__FILE__, __LINE__, mtr);
rec = btr_cur_get_rec(btr_cur);
n_fields = dtuple_get_n_fields_cmp(tuple);
if (page_rec_is_infimum(rec)
|| (btr_cur->low_match != n_fields)) {
ret = rtr_pcur_getnext_from_path(
tuple, PAGE_CUR_RTREE_LOCATE, btr_cur,
level, BTR_CONT_MODIFY_TREE,
true, mtr);
ut_ad(ret && btr_cur->low_match == n_fields);
}
}
ret = rtr_compare_cursor_rec(
index, btr_cur, page_no, &heap);
ut_ad(ret);
func_exit:
if (heap) {
mem_heap_free(heap);
}
if (new_rtr && btr_cur->rtr_info) {
rtr_clean_rtr_info(btr_cur->rtr_info, true);
btr_cur->rtr_info = NULL;
}
}
/*******************************************************************//**
Create a RTree search info structure */
rtr_info_t*

View File

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
@ -1560,19 +1560,13 @@ thd_trx_is_auto_commit(
/** Enter InnoDB engine after checking the max number of user threads
allowed, else the thread is put into sleep.
@param[in,out] prebuilt row prebuilt handler */
static inline
void
innobase_srv_conc_enter_innodb(
row_prebuilt_t* prebuilt)
static inline void innobase_srv_conc_enter_innodb(row_prebuilt_t *prebuilt)
{
#ifdef WITH_WSREP
if (wsrep_on(prebuilt->trx->mysql_thd) &&
wsrep_thd_is_BF(prebuilt->trx->mysql_thd, FALSE)) {
return;
}
#endif /* WITH_WSREP */
trx_t* trx = prebuilt->trx;
trx_t* trx = prebuilt->trx;
#ifdef WITH_WSREP
if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
#endif /* WITH_WSREP */
if (srv_thread_concurrency) {
if (trx->n_tickets_to_enter_innodb > 0) {
@ -1600,21 +1594,15 @@ innobase_srv_conc_enter_innodb(
/** Note that the thread wants to leave InnoDB only if it doesn't have
any spare tickets.
@param[in,out] m_prebuilt row prebuilt handler */
static inline
void
innobase_srv_conc_exit_innodb(
row_prebuilt_t* prebuilt)
static inline void innobase_srv_conc_exit_innodb(row_prebuilt_t *prebuilt)
{
ut_ad(!sync_check_iterate(sync_check()));
#ifdef WITH_WSREP
if (wsrep_on(prebuilt->trx->mysql_thd) &&
wsrep_thd_is_BF(prebuilt->trx->mysql_thd, FALSE)) {
return;
}
#endif /* WITH_WSREP */
trx_t* trx = prebuilt->trx;
trx_t* trx = prebuilt->trx;
#ifdef WITH_WSREP
if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
#endif /* WITH_WSREP */
/* This is to avoid making an unnecessary function call. */
if (trx->declared_to_be_inside_innodb
@ -2485,6 +2473,9 @@ innobase_trx_init(
trx->check_unique_secondary = !thd_test_options(
thd, OPTION_RELAXED_UNIQUE_CHECKS);
#ifdef WITH_WSREP
trx->wsrep = wsrep_on(thd);
#endif
DBUG_VOID_RETURN;
}
@ -4142,19 +4133,17 @@ innobase_commit_low(
trx_t* trx) /*!< in: transaction handle */
{
#ifdef WITH_WSREP
THD* thd = (THD*)trx->mysql_thd;
const char* tmp = 0;
if (wsrep_on(thd)) {
if (trx->is_wsrep()) {
#ifdef WSREP_PROC_INFO
char info[64];
info[sizeof(info) - 1] = '\0';
snprintf(info, sizeof(info) - 1,
"innobase_commit_low():trx_commit_for_mysql(%lld)",
(long long) wsrep_thd_trx_seqno(thd));
tmp = thd_proc_info(thd, info);
(long long) wsrep_thd_trx_seqno(trx->mysql_thd));
tmp = thd_proc_info(trx->mysql_thd, info);
#else
tmp = thd_proc_info(thd, "innobase_commit_low()");
tmp = thd_proc_info(trx->mysql_thd, "innobase_commit_low()");
#endif /* WSREP_PROC_INFO */
}
#endif /* WITH_WSREP */
@ -4164,7 +4153,7 @@ innobase_commit_low(
}
trx->will_lock = 0;
#ifdef WITH_WSREP
if (wsrep_on(thd)) { thd_proc_info(thd, tmp); }
if (trx->is_wsrep()) { thd_proc_info(trx->mysql_thd, tmp); }
#endif /* WITH_WSREP */
}
@ -4277,7 +4266,7 @@ innobase_commit_ordered_2(
#ifdef WITH_WSREP
/* If the transaction is not run in 2pc, we must assign wsrep
XID here in order to get it written in rollback segment. */
if (wsrep_on(thd)) {
if (trx->is_wsrep()) {
thd_get_xid(thd, (MYSQL_XID*)trx->xid);
}
#endif /* WITH_WSREP */
@ -4856,28 +4845,25 @@ UNIV_INTERN void lock_cancel_waiting_and_release(lock_t* lock);
/** Cancel any pending lock request associated with the current THD.
@sa THD::awake() @sa ha_kill_query() */
static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels)
static void innobase_kill_query(handlerton*, THD *thd, enum thd_kill_levels)
{
DBUG_ENTER("innobase_kill_query");
DBUG_ENTER("innobase_kill_query");
if (trx_t *trx= thd_to_trx(thd))
{
ut_ad(trx->mysql_thd == thd);
#ifdef WITH_WSREP
if (wsrep_on(thd) && wsrep_thd_is_aborting(thd)) {
/* if victim has been signaled by BF thread and/or aborting
is already progressing, following query aborting is not necessary
any more.
Also, BF thread should own trx mutex for the victim, which would
conflict with trx_mutex_enter() below
*/
DBUG_VOID_RETURN;
}
if (trx->is_wsrep() && wsrep_thd_is_aborting(thd))
/* if victim has been signaled by BF thread and/or aborting is already
progressing, following query aborting is not necessary any more.
Also, BF thread should own trx mutex for the victim. */
DBUG_VOID_RETURN;
#endif /* WITH_WSREP */
/* Cancel a pending lock request if there are any */
lock_trx_handle_wait(trx);
}
if (trx_t* trx = thd_to_trx(thd)) {
ut_ad(trx->mysql_thd == thd);
/* Cancel a pending lock request if there are any */
lock_trx_handle_wait(trx);
}
DBUG_VOID_RETURN;
DBUG_VOID_RETURN;
}
@ -7680,7 +7666,7 @@ ha_innobase::write_row(
{
dberr_t error;
#ifdef WITH_WSREP
ibool auto_inc_inserted= FALSE; /* if NULL was inserted */
bool wsrep_auto_inc_inserted= false;
#endif
int error_result = 0;
bool auto_inc_used = false;
@ -7710,7 +7696,9 @@ ha_innobase::write_row(
m_prebuilt->autoinc_error = DB_SUCCESS;
#ifdef WITH_WSREP
auto_inc_inserted= (table->next_number_field->val_int() == 0);
wsrep_auto_inc_inserted = trx->is_wsrep()
&& wsrep_drupal_282555_workaround
&& table->next_number_field->val_int() == 0;
#endif
if ((error_result = update_auto_increment())) {
@ -7807,18 +7795,14 @@ ha_innobase::write_row(
m_prebuilt->autoinc_offset,
m_prebuilt->autoinc_increment);
if (wsrep_on(m_user_thd) &&
auto_inc_inserted &&
wsrep_drupal_282555_workaround &&
if (wsrep_auto_inc_inserted &&
wsrep_thd_retry_counter(m_user_thd) == 0 &&
!thd_test_options(m_user_thd,
OPTION_NOT_AUTOCOMMIT |
OPTION_BEGIN)) {
WSREP_DEBUG(
"retrying insert: %s",
(*wsrep_thd_query(m_user_thd)) ?
wsrep_thd_query(m_user_thd) :
(char *)"void");
wsrep_thd_query(m_user_thd));
error= DB_SUCCESS;
wsrep_thd_self_abort(m_user_thd);
innobase_srv_conc_exit_innodb(
@ -7858,7 +7842,7 @@ set_max_autoinc:
m_prebuilt autoinc values don't get
properly assigned. Fetch values from
server side. */
if (wsrep_on(m_user_thd) &&
if (trx->is_wsrep() &&
wsrep_thd_is_applying(m_user_thd))
{
wsrep_thd_auto_increment_variables(
@ -7905,8 +7889,7 @@ report_error:
error, m_prebuilt->table->flags, m_user_thd);
#ifdef WITH_WSREP
if (!error_result
&& wsrep_on(m_user_thd)
if (!error_result && trx->is_wsrep()
&& wsrep_thd_is_local(m_user_thd)
&& !wsrep_thd_ignore_table(m_user_thd)
&& !wsrep_consistency_check(m_user_thd)
@ -7918,10 +7901,9 @@ report_error:
NULL)) {
DBUG_PRINT("wsrep", ("row key failed"));
error_result = HA_ERR_INTERNAL_ERROR;
goto wsrep_error;
goto func_exit;
}
}
wsrep_error:
#endif /* WITH_WSREP */
if (error_result == HA_FTS_INVALID_DOCID) {
@ -8574,8 +8556,7 @@ ha_innobase::update_row(
m_prebuilt autoinc values don't get
properly assigned. Fetch values from
server side. */
if (wsrep_on(m_user_thd) &&
wsrep_thd_is_applying(m_user_thd))
if (trx->is_wsrep() && wsrep_thd_is_applying(m_user_thd))
wsrep_thd_auto_increment_variables(
m_user_thd, &offset, &increment);
else
@ -8619,11 +8600,9 @@ func_exit:
innobase_active_small();
#ifdef WITH_WSREP
if (error == DB_SUCCESS
&& wsrep_on(m_user_thd)
if (error == DB_SUCCESS && trx->is_wsrep()
&& wsrep_thd_is_local(m_user_thd)
&& !wsrep_thd_ignore_table(m_user_thd)) {
DBUG_PRINT("wsrep", ("update row key"));
if (wsrep_append_keys(m_user_thd,
@ -8633,14 +8612,11 @@ func_exit:
old_row, new_row)){
WSREP_DEBUG("WSREP: UPDATE_ROW_KEY FAILED");
DBUG_PRINT("wsrep", ("row key failed"));
err = HA_ERR_INTERNAL_ERROR;
goto wsrep_error;
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
}
}
wsrep_error:
#endif /* WITH_WSREP */
DBUG_RETURN(err);
}
@ -8690,20 +8666,16 @@ ha_innobase::delete_row(
innobase_active_small();
#ifdef WITH_WSREP
if (error == DB_SUCCESS
&& wsrep_on(m_user_thd)
if (error == DB_SUCCESS && trx->is_wsrep()
&& wsrep_thd_is_local(m_user_thd)
&& !wsrep_thd_ignore_table(m_user_thd)) {
if (wsrep_append_keys(m_user_thd, WSREP_SERVICE_KEY_EXCLUSIVE,
record,
NULL)) {
DBUG_PRINT("wsrep", ("delete fail"));
error = (dberr_t) HA_ERR_INTERNAL_ERROR;
goto wsrep_error;
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
}
}
wsrep_error:
#endif /* WITH_WSREP */
DBUG_RETURN(convert_error_code_to_mysql(
error, m_prebuilt->table->flags, m_user_thd));
@ -9879,29 +9851,26 @@ wsrep_append_foreign_key(
Wsrep_service_key_type key_type) /*!< in: access type of this key
(shared, exclusive, reference...) */
{
ut_a(trx);
THD* thd = (THD*)trx->mysql_thd;
ulint rcode = DB_SUCCESS;
char cache_key[513] = {'\0'};
size_t cache_key_len=0;
if (!wsrep_on(trx->mysql_thd) ||
wsrep_thd_is_local(trx->mysql_thd) == false) {
if (!trx->is_wsrep() || !wsrep_thd_is_local(trx->mysql_thd)) {
return DB_SUCCESS;
}
if (!thd || !foreign ||
THD* thd = trx->mysql_thd;
if (!foreign ||
(!foreign->referenced_table && !foreign->foreign_table)) {
WSREP_INFO("FK: %s missing in: %s",
(!thd) ? "thread" :
((!foreign) ? "constraint" :
((!foreign->referenced_table) ?
(!foreign ? "constraint" :
(!foreign->referenced_table ?
"referenced table" : "foreign table")),
(thd && wsrep_thd_query(thd)) ?
wsrep_thd_query(thd) : "void");
wsrep_thd_query(thd));
return DB_ERROR;
}
ulint rcode = DB_SUCCESS;
char cache_key[513] = {'\0'};
size_t cache_key_len = 0;
if ( !((referenced) ?
foreign->referenced_table : foreign->foreign_table)) {
WSREP_DEBUG("pulling %s table into cache",
@ -11417,10 +11386,17 @@ innobase_fts_load_stopword(
trx_t* trx, /*!< in: transaction */
THD* thd) /*!< in: current thread */
{
return(fts_load_stopword(table, trx,
innobase_server_stopword_table,
THDVAR(thd, ft_user_stopword_table),
THDVAR(thd, ft_enable_stopword), FALSE));
const char *stopword_table= THDVAR(thd, ft_user_stopword_table);
if (!stopword_table)
{
mysql_mutex_lock(&LOCK_global_system_variables);
if (innobase_server_stopword_table)
stopword_table= thd_strdup(thd, innobase_server_stopword_table);
mysql_mutex_unlock(&LOCK_global_system_variables);
}
return fts_load_stopword(table, trx, stopword_table,
THDVAR(thd, ft_enable_stopword), false);
}
/** Parse the table name into normal name and remote path if needed.
@ -15832,9 +15808,7 @@ ha_innobase::external_lock(
DBUG_PRINT("enter",("lock_type: %d", lock_type));
update_thd(thd);
trx_t* trx = m_prebuilt->trx;
trx_t* trx = m_prebuilt->trx;
ut_ad(m_prebuilt->table);
/* Statement based binlogging does not work in isolation level
@ -15849,25 +15823,20 @@ ha_innobase::external_lock(
&& thd_binlog_format(thd) == BINLOG_FORMAT_STMT
&& thd_binlog_filter_ok(thd)
&& thd_sqlcom_can_generate_row_events(thd)) {
bool skip = false;
bool skip = false;
#ifdef WITH_WSREP
skip = trx->is_wsrep() && !wsrep_thd_is_local(thd);
#endif /* WITH_WSREP */
/* used by test case */
DBUG_EXECUTE_IF("no_innodb_binlog_errors", skip = true;);
if (!skip) {
#ifdef WITH_WSREP
if (!wsrep_on(thd) || wsrep_thd_is_local(m_user_thd)) {
#endif /* WITH_WSREP */
my_error(ER_BINLOG_STMT_MODE_AND_ROW_ENGINE, MYF(0),
" InnoDB is limited to row-logging when"
" transaction isolation level is"
" READ COMMITTED or READ UNCOMMITTED.");
DBUG_RETURN(HA_ERR_LOGGING_IMPOSSIBLE);
#ifdef WITH_WSREP
}
#endif /* WITH_WSREP */
}
}
@ -17587,7 +17556,6 @@ innodb_stopword_table_validate(
char buff[STRING_BUFFER_USUAL_SIZE];
int len = sizeof(buff);
trx_t* trx;
int ret = 1;
ut_a(save != NULL);
ut_a(value != NULL);
@ -17600,14 +17568,22 @@ innodb_stopword_table_validate(
/* Validate the stopword table's (if supplied) existence and
of the right format */
if (!stopword_table_name
|| fts_valid_stopword_table(stopword_table_name)) {
*static_cast<const char**>(save) = stopword_table_name;
ret = 0;
}
int ret = stopword_table_name && !fts_valid_stopword_table(
stopword_table_name);
row_mysql_unlock_data_dictionary(trx);
if (!ret) {
if (stopword_table_name == buff) {
ut_ad(static_cast<size_t>(len) < sizeof buff);
stopword_table_name = thd_strmake(thd,
stopword_table_name,
len);
}
*static_cast<const char**>(save) = stopword_table_name;
}
return(ret);
}
@ -17636,9 +17612,10 @@ innodb_buffer_pool_size_update(THD*,st_mysql_sys_var*,void*, const void* save)
static char* innodb_ft_aux_table;
/** Update innodb_ft_aux_table_id on SET GLOBAL innodb_ft_aux_table.
@param[in,out] thd connection
@param[out] save new value of innodb_ft_aux_table
@param[in] value user-specified value */
static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*,
static int innodb_ft_aux_table_validate(THD *thd, st_mysql_sys_var*,
void* save, st_mysql_value* value)
{
char buf[STRING_BUFFER_USUAL_SIZE];
@ -17652,6 +17629,15 @@ static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*,
dict_table_close(table, FALSE, FALSE);
if (id) {
innodb_ft_aux_table_id = id;
if (table_name == buf) {
ut_ad(static_cast<size_t>(len)
< sizeof buf);
table_name = thd_strmake(thd,
table_name,
len);
}
*static_cast<const char**>(save) = table_name;
return 0;
}
@ -18195,49 +18181,43 @@ exit:
return;
}
#ifdef _WIN32
/*************************************************************//**
Validate if passed-in "value" is a valid value for
innodb_buffer_pool_filename. On Windows, file names with colon (:)
are not allowed.
@return 0 for valid name */
static
int
innodb_srv_buf_dump_filename_validate(
/*==================================*/
THD* thd, /*!< in: thread handle */
struct st_mysql_sys_var* var, /*!< in: pointer to system
variable */
void* save, /*!< out: immediate result
for update function */
struct st_mysql_value* value) /*!< in: incoming string */
/** Validate SET GLOBAL innodb_buffer_pool_filename.
On Windows, file names with colon (:) are not allowed.
@param thd connection
@param save &srv_buf_dump_filename
@param value new value to be validated
@return 0 for valid name */
static int innodb_srv_buf_dump_filename_validate(THD *thd, st_mysql_sys_var*,
void *save,
st_mysql_value *value)
{
char buff[OS_FILE_MAX_PATH];
int len = sizeof(buff);
char buff[OS_FILE_MAX_PATH];
int len= sizeof buff;
ut_a(save != NULL);
ut_a(value != NULL);
if (const char* buf_name = value->val_str(value, buff, &len)) {
if (is_filename_allowed(buf_name, len, FALSE)){
*static_cast<const char**>(save) = buf_name;
return(0);
} else {
push_warning_printf(thd,
Sql_condition::WARN_LEVEL_WARN,
ER_WRONG_ARGUMENTS,
"InnoDB: innodb_buffer_pool_filename"
" cannot have colon (:) in the file name.");
}
}
return(1);
}
#else /* _WIN32 */
# define innodb_srv_buf_dump_filename_validate NULL
if (const char *buf_name= value->val_str(value, buff, &len))
{
#ifdef _WIN32
if (!is_filename_allowed(buf_name, len, FALSE))
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WRONG_ARGUMENTS,
"InnoDB: innodb_buffer_pool_filename "
"cannot have colon (:) in the file name.");
return 1;
}
#endif /* _WIN32 */
if (buf_name == buff)
{
ut_ad(static_cast<size_t>(len) < sizeof buff);
buf_name= thd_strmake(thd, buf_name, len);
}
*static_cast<const char**>(save)= buf_name;
return 0;
}
return 1;
}
#ifdef UNIV_DEBUG
static char* srv_buffer_pool_evict;
@ -18246,9 +18226,7 @@ static char* srv_buffer_pool_evict;
Evict all uncompressed pages of compressed tables from the buffer pool.
Keep the compressed pages in the buffer pool.
@return whether all uncompressed pages were evicted */
static MY_ATTRIBUTE((warn_unused_result))
bool
innodb_buffer_pool_evict_uncompressed()
static bool innodb_buffer_pool_evict_uncompressed()
{
bool all_evicted = true;
@ -18263,8 +18241,13 @@ innodb_buffer_pool_evict_uncompressed()
if (!buf_LRU_free_page(&block->page, false)) {
all_evicted = false;
block = prev_block;
} else {
/* Because buf_LRU_free_page() may release
and reacquire buf_pool.mutex, prev_block
may be invalid. */
block = UT_LIST_GET_LAST(buf_pool.unzip_LRU);
}
block = prev_block;
}
mutex_exit(&buf_pool.mutex);

View File

@ -1872,6 +1872,62 @@ innobase_fts_check_doc_id_col(
return(false);
}
/** Check whether the table is empty.
@param[in] table table to be checked
@return true if table is empty */
static bool innobase_table_is_empty(const dict_table_t *table)
{
dict_index_t *clust_index= dict_table_get_first_index(table);
mtr_t mtr;
btr_pcur_t pcur;
buf_block_t *block;
page_cur_t *cur;
const rec_t *rec;
bool next_page= false;
mtr.start();
btr_pcur_open_at_index_side(true, clust_index, BTR_SEARCH_LEAF,
&pcur, true, 0, &mtr);
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
if (!rec_is_metadata(btr_pcur_get_rec(&pcur), *clust_index))
btr_pcur_move_to_prev_on_page(&pcur);
scan_leaf:
cur= btr_pcur_get_page_cur(&pcur);
page_cur_move_to_next(cur);
next_page:
if (next_page)
{
uint32_t next_page_no= btr_page_get_next(page_cur_get_page(cur));
if (next_page_no == FIL_NULL)
{
mtr.commit();
return true;
}
next_page= false;
block= page_cur_get_block(cur);
block= btr_block_get(*clust_index, next_page_no, BTR_SEARCH_LEAF, false,
&mtr);
btr_leaf_page_release(page_cur_get_block(cur), BTR_SEARCH_LEAF, &mtr);
page_cur_set_before_first(block, cur);
page_cur_move_to_next(cur);
}
rec= page_cur_get_rec(cur);
if (rec_get_deleted_flag(rec, dict_table_is_comp(table)));
else if (!page_rec_is_supremum(rec))
{
mtr.commit();
return false;
}
else
{
next_page= true;
goto next_page;
}
goto scan_leaf;
}
/** Check if InnoDB supports a particular alter table in-place
@param altered_table TABLE object for new version of table.
@param ha_alter_info Structure describing changes to be done
@ -2095,6 +2151,13 @@ innodb_instant_alter_column_allowed_reason:
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
/* '0000-00-00' value isn't allowed for datetime datatype
for newly added column when table is not empty */
if (ha_alter_info->error_if_not_empty
&& !innobase_table_is_empty(m_prebuilt->table)) {
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
const bool add_drop_v_cols = !!(ha_alter_info->handler_flags
& (ALTER_ADD_VIRTUAL_COLUMN
| ALTER_DROP_VIRTUAL_COLUMN
@ -6926,7 +6989,7 @@ op_ok:
goto error_handling;
}
trx_commit(ctx->trx);
ctx->trx->commit();
trx_start_for_ddl(ctx->trx, op);
if (!ctx->new_table->fts
@ -10877,7 +10940,7 @@ ha_innobase::commit_inplace_alter_table(
} else {
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
ut_ad(trx->has_logged());
trx_commit(trx);
trx->commit();
}
/* If server crashes here, the dictionary in

View File

@ -115,16 +115,16 @@ dict_stats_deinit(
/** Update the table modification counter and if necessary,
schedule new estimates for table and index statistics to be calculated.
@param[in,out] table persistent or temporary table
@param[in] thd current session */
void dict_stats_update_if_needed(dict_table_t* table, THD* thd)
MY_ATTRIBUTE((nonnull(1)));
@param[in] trx transaction */
void dict_stats_update_if_needed(dict_table_t *table, const trx_t &trx)
MY_ATTRIBUTE((nonnull));
#else
/** Update the table modification counter and if necessary,
schedule new estimates for table and index statistics to be calculated.
@param[in,out] table persistent or temporary table */
void dict_stats_update_if_needed_func(dict_table_t* table)
void dict_stats_update_if_needed_func(dict_table_t *table)
MY_ATTRIBUTE((nonnull));
# define dict_stats_update_if_needed(t,thd) dict_stats_update_if_needed_func(t)
# define dict_stats_update_if_needed(t,trx) dict_stats_update_if_needed_func(t)
#endif
/*********************************************************************//**

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2019, MariaDB Corporation.
Copyright (c) 2016, 2020, 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
@ -880,20 +880,18 @@ fts_valid_stopword_table(
name */
/****************************************************************//**
This function loads specified stopword into FTS cache
@return TRUE if success */
ibool
@return true if success */
bool
fts_load_stopword(
/*==============*/
const dict_table_t*
table, /*!< in: Table with FTS */
trx_t* trx, /*!< in: Transaction */
const char* global_stopword_table, /*!< in: Global stopword table
name */
const char* session_stopword_table, /*!< in: Session stopword table
name */
ibool stopword_is_on, /*!< in: Whether stopword
bool stopword_is_on, /*!< in: Whether stopword
option is turned on/off */
ibool reload); /*!< in: Whether it is during
bool reload); /*!< in: Whether it is during
reload of FTS table */
/****************************************************************//**

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation.
Copyright (c) 2017, 2020, 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
@ -162,22 +162,6 @@ rtr_ins_enlarge_mbr(
btr_cur_t* cursor, /*!< in: btr cursor */
mtr_t* mtr); /*!< in: mtr */
/********************************************************************//**
*/
void
rtr_get_father_node(
/*================*/
dict_index_t* index, /*!< in: index */
ulint level, /*!< in: the tree level of search */
const dtuple_t* tuple, /*!< in: data tuple; NOTE: n_fields_cmp in
tuple must be set so that it cannot get
compared to the node ptr page number field! */
btr_cur_t* sea_cur,/*!< in: search cursor */
btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
s- or x-latched */
ulint page_no,/*!< in: current page no */
mtr_t* mtr); /*!< in: mtr */
/**************************************************************//**
push a nonleaf index node to the search path */
UNIV_INLINE

View File

@ -980,10 +980,6 @@ std::string
lock_get_info(
const lock_t*);
/*******************************************************************//**
@return whether wsrep_on is true on trx->mysql_thd*/
#define wsrep_on_trx(trx) wsrep_on((trx)->mysql_thd)
#endif /* WITH_WSREP */
#include "lock0lock.ic"

View File

@ -298,16 +298,6 @@ row_upd_changes_some_index_ord_field_binary(
/*========================================*/
const dict_table_t* table, /*!< in: table */
const upd_t* update);/*!< in: update vector for the row */
/** Stores to the heap the row on which the node->pcur is positioned.
@param[in] node row update node
@param[in] thd mysql thread handle
@param[in,out] mysql_table NULL, or mysql table object when
user thread invokes dml */
void
row_upd_store_row(
upd_node_t* node,
THD* thd,
TABLE* mysql_table);
/***********************************************************//**
Updates a row in a table. This is a high-level function used
in SQL execution graphs.

View File

@ -180,17 +180,6 @@ trx_start_for_ddl_low(
trx_start_for_ddl_low((t), (o))
#endif /* UNIV_DEBUG */
/****************************************************************//**
Commits a transaction. */
void
trx_commit(
/*=======*/
trx_t* trx); /*!< in/out: transaction */
/** Commit a transaction and a mini-transaction.
@param[in,out] trx transaction
@param[in,out] mtr mini-transaction (NULL if no modifications) */
void trx_commit_low(trx_t* trx, mtr_t* mtr);
/**********************************************************************//**
Does the transaction commit for MySQL.
@return DB_SUCCESS or error number */
@ -839,6 +828,13 @@ public:
Transitions to COMMITTED are protected by trx_t::mutex. */
trx_state_t state;
#ifdef WITH_WSREP
/** whether wsrep_on(mysql_thd) held at the start of transaction */
bool wsrep;
bool is_wsrep() const { return UNIV_UNLIKELY(wsrep); }
#else /* WITH_WSREP */
bool is_wsrep() const { return false; }
#endif /* WITH_WSREP */
ReadView read_view; /*!< consistent read view used in the
transaction, or NULL if not yet set */
@ -890,10 +886,10 @@ public:
defer flush of the logs to disk
until after we release the
mutex. */
bool must_flush_log_later;/*!< this flag is set to TRUE in
trx_commit() if flush_log_later was
TRUE, and there were modifications by
the transaction; in that case we must
bool must_flush_log_later;/*!< set in commit()
if flush_log_later was
set and redo log was written;
in that case we will
flush the log in
trx_commit_complete_for_mysql() */
ulint duplicates; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */
@ -1105,11 +1101,22 @@ public:
@param[in] table_id table identifier */
void evict_table(table_id_t table_id);
/** Finish rollback.
@return whether the rollback was completed normally
@retval false if the rollback was aborted by shutdown */
inline bool rollback_finish();
private:
/** Mark a transaction committed in the main memory data structures. */
inline void commit_in_memory(const mtr_t *mtr);
/** Commit the transaction in a mini-transaction.
@param mtr mini-transaction (if there are any persistent modifications) */
void commit_low(mtr_t *mtr= nullptr);
public:
/** Commit the transaction. */
void commit();
bool is_referenced()
{
return n_ref > 0;
}
bool is_referenced() const { return n_ref > 0; }
void reference()

View File

@ -1073,9 +1073,7 @@ wsrep_kill_victim(
ut_ad(trx_mutex_own(lock->trx));
/* quit for native mysql */
if (!wsrep_on(trx->mysql_thd)) {
return;
}
if (!trx->is_wsrep()) return;
if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
return;
@ -1157,7 +1155,7 @@ lock_rec_other_has_conflicting(
if (lock_rec_has_to_wait(true, trx, mode, lock, is_supremum)) {
#ifdef WITH_WSREP
if (wsrep_on_trx(trx)) {
if (trx->is_wsrep()) {
trx_mutex_enter(lock->trx);
/* Below function will roll back either trx
or lock->trx depending on priority of the
@ -1399,7 +1397,7 @@ lock_rec_create_low(
ut_ad(index->table->get_ref_count() > 0 || !index->table->can_be_evicted);
#ifdef WITH_WSREP
if (c_lock && wsrep_on_trx(trx)
if (c_lock && trx->is_wsrep()
&& wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
lock_t *hash = (lock_t *)c_lock->hash;
lock_t *prev = NULL;
@ -1805,8 +1803,7 @@ lock_rec_add_to_queue(
#ifdef WITH_WSREP
//ut_a(!other_lock || (wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
// wsrep_thd_is_BF(other_lock->trx->mysql_thd, TRUE)));
if (other_lock &&
wsrep_on(trx->mysql_thd) &&
if (other_lock && trx->is_wsrep() &&
!wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
!wsrep_thd_is_BF(other_lock->trx->mysql_thd, TRUE)) {
@ -3502,7 +3499,7 @@ lock_table_create(
UT_LIST_ADD_LAST(trx->lock.trx_locks, lock);
#ifdef WITH_WSREP
if (c_lock && wsrep_on_trx(trx)) {
if (c_lock && trx->is_wsrep()) {
if (wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
ut_list_insert(table->locks, c_lock, lock,
TableLockGetNode());
@ -3732,7 +3729,7 @@ lock_table_enqueue_waiting(
}
#ifdef WITH_WSREP
if (trx->lock.was_chosen_as_deadlock_victim && wsrep_on_trx(trx)) {
if (trx->is_wsrep() && trx->lock.was_chosen_as_deadlock_victim) {
return(DB_DEADLOCK);
}
#endif /* WITH_WSREP */
@ -3805,7 +3802,7 @@ lock_table_other_has_incompatible(
&& (wait || !lock_get_wait(lock))) {
#ifdef WITH_WSREP
if (wsrep_on(lock->trx->mysql_thd)) {
if (lock->trx->is_wsrep()) {
if (wsrep_debug) {
ib::info() << "WSREP: table lock abort for table:"
<< table->name.m_name;
@ -4872,7 +4869,7 @@ func_exit:
explicit granted lock. */
#ifdef WITH_WSREP
if (wsrep_on(other_lock->trx->mysql_thd)) {
if (other_lock->trx->is_wsrep()) {
if (!lock_get_wait(other_lock) ) {
ib::info() << "WSREP impl BF lock conflict for my impl lock:\n BF:" <<
((wsrep_thd_is_BF(impl_trx->mysql_thd, FALSE)) ? "BF" : "normal") << " exec: " <<
@ -6754,7 +6751,7 @@ DeadlockChecker::trx_rollback()
print("*** WE ROLL BACK TRANSACTION (1)\n");
#ifdef WITH_WSREP
if (wsrep_on(trx->mysql_thd) && wsrep_thd_is_SR(trx->mysql_thd)) {
if (trx->is_wsrep() && wsrep_thd_is_SR(trx->mysql_thd)) {
wsrep_handle_SR_rollback(m_start->mysql_thd, trx->mysql_thd);
}
#endif
@ -6847,8 +6844,7 @@ DeadlockChecker::check_and_resolve(const lock_t* lock, trx_t* trx)
print("*** WE ROLL BACK TRANSACTION (2)\n");
#ifdef WITH_WSREP
if (wsrep_on(trx->mysql_thd)
&& wsrep_thd_is_SR(trx->mysql_thd)) {
if (trx->is_wsrep() && wsrep_thd_is_SR(trx->mysql_thd)) {
wsrep_handle_SR_rollback(trx->mysql_thd,
victim_trx->mysql_thd);
}

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2014, 2019, MariaDB Corporation.
Copyright (c) 2014, 2020, 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
@ -195,8 +195,7 @@ wsrep_is_BF_lock_timeout(
const trx_t* trx,
bool locked = true)
{
if (wsrep_on_trx(trx)
&& wsrep_thd_is_BF(trx->mysql_thd, FALSE)
if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)
&& trx->error_state != DB_DEADLOCK) {
ib::info() << "WSREP: BF lock wait long for trx:" << ib::hex(trx->id)
<< " query: " << wsrep_thd_query(trx->mysql_thd);
@ -403,8 +402,9 @@ lock_wait_suspend_thread(
if (lock_wait_timeout < 100000000
&& wait_time > (double) lock_wait_timeout
#ifdef WITH_WSREP
&& (!wsrep_on_trx(trx) ||
(!wsrep_is_BF_lock_timeout(trx, false) && trx->error_state != DB_DEADLOCK))
&& (!trx->is_wsrep()
|| (!wsrep_is_BF_lock_timeout(trx, false)
&& trx->error_state != DB_DEADLOCK))
#endif /* WITH_WSREP */
) {

View File

@ -1038,7 +1038,7 @@ row_prebuilt_free(
rtr_clean_rtr_info(prebuilt->rtr_info, true);
}
if (prebuilt->table) {
dict_table_close(prebuilt->table, dict_locked, TRUE);
dict_table_close(prebuilt->table, dict_locked, FALSE);
}
mem_heap_free(prebuilt->heap);
@ -1574,7 +1574,7 @@ error_exit:
memcpy(prebuilt->row_id, node->sys_buf, DATA_ROW_ID_LEN);
}
dict_stats_update_if_needed(table, trx->mysql_thd);
dict_stats_update_if_needed(table, *trx);
trx->op_info = "";
if (blob_heap != NULL) {
@ -1958,7 +1958,7 @@ row_update_for_mysql(row_prebuilt_t* prebuilt)
}
if (update_statistics) {
dict_stats_update_if_needed(prebuilt->table, trx->mysql_thd);
dict_stats_update_if_needed(prebuilt->table, *trx);
} else {
/* Always update the table modification counter. */
prebuilt->table->stat_modified_counter++;
@ -2199,7 +2199,7 @@ static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node)
case DB_SUCCESS:
srv_stats.n_rows_inserted.inc(
static_cast<size_t>(trx->id));
dict_stats_update_if_needed(table, trx->mysql_thd);
dict_stats_update_if_needed(table, *trx);
goto exit;
}
}
@ -2293,8 +2293,7 @@ row_update_cascade_for_mysql(
}
if (stats) {
dict_stats_update_if_needed(node->table,
trx->mysql_thd);
dict_stats_update_if_needed(node->table, *trx);
} else {
/* Always update the table
modification counter. */

View File

@ -1051,8 +1051,7 @@ row_purge_record_func(
if (node->table->stat_initialized
&& srv_stats_include_delete_marked) {
dict_stats_update_if_needed(
node->table,
thr->graph->trx->mysql_thd);
node->table, *thr->graph->trx);
}
MONITOR_INC(MONITOR_N_DEL_ROW_PURGE);
}

View File

@ -578,8 +578,8 @@ row_undo_ins(
already be holding dict_sys.mutex, which
would be acquired when updating statistics. */
if (!dict_locked) {
dict_stats_update_if_needed(
node->table, node->trx->mysql_thd);
dict_stats_update_if_needed(node->table,
*node->trx);
}
}
break;

View File

@ -1399,8 +1399,8 @@ rollback_clust:
already be holding dict_sys.mutex, which
would be acquired when updating statistics. */
if (update_statistics && !dict_locked) {
dict_stats_update_if_needed(
node->table, node->trx->mysql_thd);
dict_stats_update_if_needed(node->table,
*node->trx);
} else {
node->table->stat_modified_counter++;
}

View File

@ -432,7 +432,7 @@ func_exit:
inline bool wsrep_must_process_fk(const upd_node_t* node, const trx_t* trx)
{
if (!wsrep_on_trx(trx)) {
if (!trx->is_wsrep()) {
return false;
}
return que_node_get_type(node->common.parent) != QUE_NODE_UPDATE
@ -1884,6 +1884,7 @@ row_upd_store_v_row(
@param[in] thd mysql thread handle
@param[in,out] mysql_table NULL, or mysql table object when
user thread invokes dml */
static
void
row_upd_store_row(
upd_node_t* node,
@ -2498,9 +2499,8 @@ check_fk:
mtr_commit(mtr);
err = row_ins_clust_index_entry(index, entry, thr, node->upd_ext
? node->upd_ext->n_ext
: dtuple_get_n_ext(entry));
err = row_ins_clust_index_entry(index, entry, thr,
dtuple_get_n_ext(entry));
node->state = UPD_NODE_INSERT_CLUSTERED;
mem_heap_free(heap);

View File

@ -606,7 +606,6 @@ row_vers_build_cur_vrow_low(
/** Check a virtual column value index secondary virtual index matches
that of current cluster index record, which is recreated from information
stored in undo log
@param[in] in_purge called by purge thread
@param[in] rec record in the clustered index
@param[in] icentry the index entry built from a cluster row
@param[in] clust_index cluster index
@ -622,7 +621,6 @@ stored in undo log
static
bool
row_vers_vc_matches_cluster(
bool in_purge,
const rec_t* rec,
const dtuple_t* icentry,
dict_index_t* clust_index,
@ -683,12 +681,6 @@ row_vers_vc_matches_cluster(
version = rec;
/* If this is called by purge thread, set TRX_UNDO_PREV_IN_PURGE
bit to search the undo log until we hit the current undo log with
roll_ptr */
ulint status = (in_purge ? TRX_UNDO_PREV_IN_PURGE : 0)
| TRX_UNDO_GET_OLD_V_VALUE;
while (n_cmp_v_col < n_fields - n_non_v_col) {
heap2 = heap;
heap = mem_heap_create(1024);
@ -696,11 +688,12 @@ row_vers_vc_matches_cluster(
version, clust_index, clust_offsets);
ut_ad(cur_roll_ptr != 0);
ut_ad(in_purge == (roll_ptr != 0));
ut_ad(roll_ptr != 0);
trx_undo_prev_version_build(
rec, mtr, version, clust_index, clust_offsets,
heap, &prev_version, NULL, vrow, status);
heap, &prev_version, NULL, vrow,
TRX_UNDO_PREV_IN_PURGE | TRX_UNDO_GET_OLD_V_VALUE);
if (heap2) {
mem_heap_free(heap2);
@ -958,7 +951,7 @@ row_vers_old_has_index_entry(
secondary indexes.) */
if (entry && row_vers_vc_matches_cluster(
also_curr, rec, entry,
rec, entry,
clust_index, clust_offsets,
index, ientry, roll_ptr,
trx_id, NULL, &vrow, mtr)) {

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, 2018, MariaDB Corporation.
Copyright (c) 2015, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@ -119,8 +119,7 @@ srv_conc_enter_innodb_with_atomics(
for (;;) {
ulint sleep_in_us;
#ifdef WITH_WSREP
if (wsrep_on(trx->mysql_thd) &&
wsrep_thd_is_aborting(trx->mysql_thd)) {
if (trx->is_wsrep() && wsrep_thd_is_aborting(trx->mysql_thd)) {
if (wsrep_get_debug()) {
ib::info() <<
"srv_conc_enter due to MUST_ABORT";

View File

@ -55,45 +55,43 @@ bool trx_rollback_is_active;
const trx_t* trx_roll_crash_recv_trx;
/** Finish transaction rollback.
@param[in,out] trx transaction
@return whether the rollback was completed normally
@retval false if the rollback was aborted by shutdown */
static bool trx_rollback_finish(trx_t* trx)
inline bool trx_t::rollback_finish()
{
trx->mod_tables.clear();
bool finished = trx->error_state == DB_SUCCESS;
if (UNIV_LIKELY(finished)) {
trx_commit(trx);
} else {
ut_a(trx->error_state == DB_INTERRUPTED);
ut_ad(!srv_is_being_started);
ut_a(!srv_undo_sources);
ut_ad(srv_fast_shutdown);
ut_d(trx->in_rollback = false);
if (trx_undo_t*& undo = trx->rsegs.m_redo.old_insert) {
UT_LIST_REMOVE(trx->rsegs.m_redo.rseg->old_insert_list,
undo);
ut_free(undo);
undo = NULL;
}
if (trx_undo_t*& undo = trx->rsegs.m_redo.undo) {
UT_LIST_REMOVE(trx->rsegs.m_redo.rseg->undo_list,
undo);
ut_free(undo);
undo = NULL;
}
if (trx_undo_t*& undo = trx->rsegs.m_noredo.undo) {
UT_LIST_REMOVE(trx->rsegs.m_noredo.rseg->undo_list,
undo);
ut_free(undo);
undo = NULL;
}
trx_commit_low(trx, NULL);
}
mod_tables.clear();
if (UNIV_LIKELY(error_state == DB_SUCCESS))
{
commit();
return true;
}
trx->lock.que_state = TRX_QUE_RUNNING;
return finished;
ut_a(error_state == DB_INTERRUPTED);
ut_ad(!srv_is_being_started);
ut_a(!srv_undo_sources);
ut_ad(srv_fast_shutdown);
ut_d(in_rollback= false);
if (trx_undo_t *&undo= rsegs.m_redo.old_insert)
{
UT_LIST_REMOVE(rsegs.m_redo.rseg->old_insert_list, undo);
ut_free(undo);
undo= nullptr;
}
if (trx_undo_t *&undo= rsegs.m_redo.undo)
{
UT_LIST_REMOVE(rsegs.m_redo.rseg->undo_list, undo);
ut_free(undo);
undo= nullptr;
}
if (trx_undo_t *&undo= rsegs.m_noredo.undo)
{
UT_LIST_REMOVE(rsegs.m_noredo.rseg->undo_list, undo);
ut_free(undo);
undo= nullptr;
}
commit_low();
lock.que_state = TRX_QUE_RUNNING;
return false;
}
/*******************************************************************//**
@ -144,8 +142,8 @@ trx_rollback_to_savepoint_low(
roll_node->undo_thr->common.parent));
}
if (savept == NULL) {
trx_rollback_finish(trx);
if (!savept) {
trx->rollback_finish();
MONITOR_INC(MONITOR_TRX_ROLLBACK);
} else {
ut_a(trx->error_state == DB_SUCCESS);
@ -182,8 +180,7 @@ trx_rollback_to_savepoint(
complete rollback */
{
#ifdef WITH_WSREP
if (savept == NULL && wsrep_on(trx->mysql_thd)
&& wsrep_thd_is_SR(trx->mysql_thd)) {
if (!savept && trx->is_wsrep() && wsrep_thd_is_SR(trx->mysql_thd)) {
wsrep_handle_SR_rollback(NULL, trx->mysql_thd);
}
#endif /* WITH_WSREP */
@ -454,7 +451,7 @@ trx_rollback_to_savepoint_for_mysql_low(
trx->op_info = "";
#ifdef WITH_WSREP
trx->lock.was_chosen_as_wsrep_victim = FALSE;
trx->lock.was_chosen_as_wsrep_victim = false;
#endif
return(err);
}
@ -668,7 +665,7 @@ trx_rollback_active(
que_graph_free(
static_cast<que_t*>(roll_node->undo_thr->common.parent));
if (UNIV_UNLIKELY(!trx_rollback_finish(trx))) {
if (UNIV_UNLIKELY(!trx->rollback_finish())) {
ut_ad(!dictionary_locked);
goto func_exit;
}

View File

@ -109,6 +109,9 @@ trx_init(
trx->state = TRX_STATE_NOT_STARTED;
trx->is_recovered = false;
#ifdef WITH_WSREP
trx->wsrep = false;
#endif /* WITH_WSREP */
trx->op_info = "";
@ -1320,318 +1323,255 @@ void trx_t::evict_table(table_id_t table_id)
}
}
/****************************************************************//**
Commits a transaction in memory. */
static
void
trx_commit_in_memory(
/*=================*/
trx_t* trx, /*!< in/out: transaction */
const mtr_t* mtr) /*!< in: mini-transaction of
trx_write_serialisation_history(), or NULL if
the transaction did not modify anything */
/** Mark a transaction committed in the main memory data structures. */
inline void trx_t::commit_in_memory(const mtr_t *mtr)
{
trx->must_flush_log_later = false;
trx->read_view.close();
must_flush_log_later= false;
read_view.close();
if (trx_is_autocommit_non_locking(trx)) {
ut_ad(trx->id == 0);
ut_ad(trx->read_only);
ut_a(!trx->is_recovered);
ut_ad(trx->rsegs.m_redo.rseg == NULL);
if (trx_is_autocommit_non_locking(this))
{
ut_ad(id == 0);
ut_ad(read_only);
ut_a(!is_recovered);
ut_ad(!rsegs.m_redo.rseg);
/* Note: We are asserting without holding the lock mutex. But
that is OK because this transaction is not waiting and cannot
be rolled back and no new locks can (or should) be added
because it is flagged as a non-locking read-only transaction. */
/* Note: We are asserting without holding the lock mutex. But
that is OK because this transaction is not waiting and cannot
be rolled back and no new locks can (or should) be added
because it is flagged as a non-locking read-only transaction. */
ut_a(UT_LIST_GET_LEN(lock.trx_locks) == 0);
ut_a(UT_LIST_GET_LEN(trx->lock.trx_locks) == 0);
/* This state change is not protected by any mutex, therefore
there is an inherent race here around state transition during
printouts. We ignore this race for the sake of efficiency.
However, the trx_sys_t::mutex will protect the trx_t instance
and it cannot be removed from the trx_list and freed
without first acquiring the trx_sys_t::mutex. */
ut_ad(trx_state_eq(this, TRX_STATE_ACTIVE));
/* This state change is not protected by any mutex, therefore
there is an inherent race here around state transition during
printouts. We ignore this race for the sake of efficiency.
However, the trx_sys_t::mutex will protect the trx_t instance
and it cannot be removed from the trx_list and freed
without first acquiring the trx_sys_t::mutex. */
MONITOR_INC(MONITOR_TRX_NL_RO_COMMIT);
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
MONITOR_INC(MONITOR_TRX_NL_RO_COMMIT);
DBUG_LOG("trx", "Autocommit in memory: " << trx);
trx->state = TRX_STATE_NOT_STARTED;
} else {
DBUG_LOG("trx", "Autocommit in memory: " << this);
state= TRX_STATE_NOT_STARTED;
}
else
{
#ifdef UNIV_DEBUG
if (!UT_LIST_GET_LEN(trx->lock.trx_locks)) {
for (lock_list::iterator it
= trx->lock.table_locks.begin();
it != trx->lock.table_locks.end();
it++) {
ut_ad(!*it);
}
}
if (!UT_LIST_GET_LEN(lock.trx_locks))
for (auto l : lock.table_locks)
ut_ad(!l);
#endif /* UNIV_DEBUG */
trx->commit_state();
commit_state();
if (trx->id) {
trx_sys.deregister_rw(trx);
if (id)
{
trx_sys.deregister_rw(this);
/* Wait for any implicit-to-explicit lock
conversions to cease, so that there will be no
race condition in lock_release(). */
while (UNIV_UNLIKELY(trx->is_referenced())) {
ut_delay(srv_spin_wait_delay);
}
/* Wait for any implicit-to-explicit lock conversions to cease,
so that there will be no race condition in lock_release(). */
while (UNIV_UNLIKELY(is_referenced()))
ut_delay(srv_spin_wait_delay);
release_locks();
id= 0;
}
else
{
ut_ad(read_only || !rsegs.m_redo.rseg);
release_locks();
}
trx->release_locks();
trx->id = 0;
} else {
ut_ad(trx->read_only || !trx->rsegs.m_redo.rseg);
trx->release_locks();
}
DEBUG_SYNC_C("after_trx_committed_in_memory");
DEBUG_SYNC_C("after_trx_committed_in_memory");
if (read_only || !rsegs.m_redo.rseg)
{
MONITOR_INC(MONITOR_TRX_RO_COMMIT);
}
else
{
trx_update_mod_tables_timestamp(this);
MONITOR_INC(MONITOR_TRX_RW_COMMIT);
is_recovered= false;
}
if (trx->read_only || !trx->rsegs.m_redo.rseg) {
MONITOR_INC(MONITOR_TRX_RO_COMMIT);
} else {
trx_update_mod_tables_timestamp(trx);
MONITOR_INC(MONITOR_TRX_RW_COMMIT);
trx->is_recovered = false;
}
while (dict_table_t *table= UT_LIST_GET_FIRST(lock.evicted_tables))
{
UT_LIST_REMOVE(lock.evicted_tables, table);
dict_mem_table_free(table);
}
}
while (dict_table_t* table = UT_LIST_GET_FIRST(
trx->lock.evicted_tables)) {
UT_LIST_REMOVE(trx->lock.evicted_tables, table);
dict_mem_table_free(table);
}
}
ut_ad(!rsegs.m_redo.undo);
ut_ad(UT_LIST_GET_LEN(lock.evicted_tables) == 0);
ut_ad(!trx->rsegs.m_redo.undo);
ut_ad(UT_LIST_GET_LEN(trx->lock.evicted_tables) == 0);
if (trx_rseg_t *rseg= rsegs.m_redo.rseg)
{
mutex_enter(&rseg->mutex);
ut_ad(rseg->trx_ref_count > 0);
--rseg->trx_ref_count;
mutex_exit(&rseg->mutex);
if (trx_rseg_t* rseg = trx->rsegs.m_redo.rseg) {
mutex_enter(&rseg->mutex);
ut_ad(rseg->trx_ref_count > 0);
--rseg->trx_ref_count;
mutex_exit(&rseg->mutex);
if (trx_undo_t *&insert= rsegs.m_redo.old_insert)
{
ut_ad(insert->rseg == rseg);
trx_undo_commit_cleanup(insert, false);
insert= nullptr;
}
}
if (trx_undo_t*& insert = trx->rsegs.m_redo.old_insert) {
ut_ad(insert->rseg == rseg);
trx_undo_commit_cleanup(insert, false);
insert = NULL;
}
}
ut_ad(!rsegs.m_redo.old_insert);
ut_ad(!trx->rsegs.m_redo.old_insert);
if (mtr)
{
if (trx_undo_t *&undo= rsegs.m_noredo.undo)
{
ut_ad(undo->rseg == rsegs.m_noredo.rseg);
trx_undo_commit_cleanup(undo, true);
undo= nullptr;
}
if (mtr != NULL) {
if (trx_undo_t*& undo = trx->rsegs.m_noredo.undo) {
ut_ad(undo->rseg == trx->rsegs.m_noredo.rseg);
trx_undo_commit_cleanup(undo, true);
undo = NULL;
}
/* NOTE that we could possibly make a group commit more efficient
here: call os_thread_yield here to allow also other trxs to come
to commit! */
/* NOTE that we could possibly make a group commit more
efficient here: call os_thread_yield here to allow also other
trxs to come to commit! */
/*-------------------------------------*/
/*-------------------------------------*/
/* Depending on the my.cnf options, we may now write the log
buffer to the log files, making the transaction durable if the OS
does not crash. We may also flush the log files to disk, making
the transaction durable also at an OS crash or a power outage.
/* Depending on the my.cnf options, we may now write the log
buffer to the log files, making the transaction durable if
the OS does not crash. We may also flush the log files to
disk, making the transaction durable also at an OS crash or a
power outage.
The idea in InnoDB's group commit is that a group of transactions
gather behind a trx doing a physical disk write to log files, and
when that physical write has been completed, one of those
transactions does a write which commits the whole group. Note that
this group commit will only bring benefit if there are > 2 users
in the database. Then at least 2 users can gather behind one doing
the physical log write to disk.
The idea in InnoDB's group commit is that a group of
transactions gather behind a trx doing a physical disk write
to log files, and when that physical write has been completed,
one of those transactions does a write which commits the whole
group. Note that this group commit will only bring benefit if
there are > 2 users in the database. Then at least 2 users can
gather behind one doing the physical log write to disk.
If we are calling trx_t::commit() under prepare_commit_mutex, we
will delay possible log write and flush to a separate function
trx_commit_complete_for_mysql(), which is only called when the
thread has released the mutex. This is to make the group commit
algorithm to work. Otherwise, the prepare_commit mutex would
serialize all commits and prevent a group of transactions from
gathering. */
If we are calling trx_commit() under prepare_commit_mutex, we
will delay possible log write and flush to a separate function
trx_commit_complete_for_mysql(), which is only called when the
thread has released the mutex. This is to make the
group commit algorithm to work. Otherwise, the prepare_commit
mutex would serialize all commits and prevent a group of
transactions from gathering. */
commit_lsn= mtr->commit_lsn();
if (!commit_lsn)
/* Nothing to be done. */;
else if (flush_log_later)
/* Do nothing yet */
must_flush_log_later= true;
else if (srv_flush_log_at_trx_commit)
trx_flush_log_if_needed(commit_lsn, this);
lsn_t lsn = mtr->commit_lsn();
/* Tell server some activity has happened, since the trx does
changes something. Background utility threads like master thread,
purge thread or page_cleaner thread might have some work to do. */
srv_active_wake_master_thread();
}
if (lsn == 0) {
/* Nothing to be done. */
} else if (trx->flush_log_later) {
/* Do nothing yet */
trx->must_flush_log_later = true;
} else if (srv_flush_log_at_trx_commit == 0) {
/* Do nothing */
} else {
trx_flush_log_if_needed(lsn, trx);
}
ut_ad(!rsegs.m_noredo.undo);
trx->commit_lsn = lsn;
/* Free all savepoints, starting from the first. */
trx_named_savept_t *savep= UT_LIST_GET_FIRST(trx_savepoints);
/* Tell server some activity has happened, since the trx
does changes something. Background utility threads like
master thread, purge thread or page_cleaner thread might
have some work to do. */
srv_active_wake_master_thread();
}
trx_roll_savepoints_free(this, savep);
ut_ad(!trx->rsegs.m_noredo.undo);
if (fts_trx)
trx_finalize_for_fts(this, undo_no != 0);
/* Free all savepoints, starting from the first. */
trx_named_savept_t* savep = UT_LIST_GET_FIRST(trx->trx_savepoints);
trx_mutex_enter(this);
dict_operation= TRX_DICT_OP_NONE;
lock.was_chosen_as_deadlock_victim= false;
trx_roll_savepoints_free(trx, savep);
DBUG_LOG("trx", "Commit in memory: " << this);
state= TRX_STATE_NOT_STARTED;
if (trx->fts_trx != NULL) {
trx_finalize_for_fts(trx, trx->undo_no != 0);
}
assert_trx_is_free(this);
trx_init(this);
trx_mutex_exit(this);
trx_mutex_enter(trx);
trx->dict_operation = TRX_DICT_OP_NONE;
#ifdef WITH_WSREP
trx->lock.was_chosen_as_wsrep_victim = FALSE;
#endif
DBUG_LOG("trx", "Commit in memory: " << trx);
trx->state = TRX_STATE_NOT_STARTED;
assert_trx_is_free(trx);
trx_init(trx);
trx_mutex_exit(trx);
ut_a(trx->error_state == DB_SUCCESS);
if (!srv_read_only_mode) {
srv_wake_purge_thread_if_not_active();
}
ut_a(error_state == DB_SUCCESS);
if (!srv_read_only_mode)
srv_wake_purge_thread_if_not_active();
}
/** Commit a transaction and a mini-transaction.
@param[in,out] trx transaction
@param[in,out] mtr mini-transaction (NULL if no modifications) */
void trx_commit_low(trx_t* trx, mtr_t* mtr)
/** Commit the transaction in a mini-transaction.
@param mtr mini-transaction (if there are any persistent modifications) */
void trx_t::commit_low(mtr_t *mtr)
{
assert_trx_nonlocking_or_in_list(trx);
ut_ad(!trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY));
ut_ad(!mtr || mtr->is_active());
ut_d(bool aborted = trx->in_rollback
&& trx->error_state == DB_DEADLOCK);
ut_ad(!mtr == (aborted || !trx->has_logged_or_recovered()));
ut_ad(!mtr || !aborted);
assert_trx_nonlocking_or_in_list(this);
ut_ad(!trx_state_eq(this, TRX_STATE_COMMITTED_IN_MEMORY));
ut_ad(!mtr || mtr->is_active());
ut_d(bool aborted = in_rollback && error_state == DB_DEADLOCK);
ut_ad(!mtr == (aborted || !has_logged_or_recovered()));
ut_ad(!mtr || !aborted);
/* undo_no is non-zero if we're doing the final commit. */
if (trx->fts_trx != NULL && trx->undo_no != 0) {
dberr_t error;
ut_a(!trx_is_autocommit_non_locking(trx));
error = fts_commit(trx);
/* FTS-FIXME: Temporarily tolerate DB_DUPLICATE_KEY
instead of dying. This is a possible scenario if there
is a crash between insert to DELETED table committing
and transaction committing. The fix would be able to
return error from this function */
if (error != DB_SUCCESS && error != DB_DUPLICATE_KEY) {
/* FTS-FIXME: once we can return values from this
function, we should do so and signal an error
instead of just dying. */
ut_error;
}
}
/* undo_no is non-zero if we're doing the final commit. */
if (fts_trx && undo_no)
{
ut_a(!trx_is_autocommit_non_locking(this));
dberr_t error= fts_commit(this);
/* FTS-FIXME: Temporarily tolerate DB_DUPLICATE_KEY instead of
dying. This is a possible scenario if there is a crash between
insert to DELETED table committing and transaction committing. The
fix would be able to return error from this function */
ut_a(error == DB_SUCCESS || error == DB_DUPLICATE_KEY);
}
#ifndef DBUG_OFF
const bool debug_sync = trx->mysql_thd && trx->has_logged_persistent();
const bool debug_sync= mysql_thd && has_logged_persistent();
#endif
if (mtr != NULL) {
trx_write_serialisation_history(trx, mtr);
if (mtr)
{
trx_write_serialisation_history(this, mtr);
/* The following call commits the mini-transaction, making the
whole transaction committed in the file-based world, at this
log sequence number. The transaction becomes 'durable' when
we write the log to disk, but in the logical sense the commit
in the file-based data structures (undo logs etc.) happens
here.
/* The following call commits the mini-transaction, making the
whole transaction committed in the file-based world, at this log
sequence number. The transaction becomes 'durable' when we write
the log to disk, but in the logical sense the commit in the
file-based data structures (undo logs etc.) happens here.
NOTE that transaction numbers, which are assigned only to
transactions with an update undo log, do not necessarily come
in exactly the same order as commit lsn's, if the transactions
have different rollback segments. To get exactly the same
order we should hold the kernel mutex up to this point,
adding to the contention of the kernel mutex. However, if
a transaction T2 is able to see modifications made by
a transaction T1, T2 will always get a bigger transaction
number and a bigger commit lsn than T1. */
NOTE that transaction numbers, which are assigned only to
transactions with an update undo log, do not necessarily come in
exactly the same order as commit lsn's, if the transactions have
different rollback segments. To get exactly the same order we
should hold the kernel mutex up to this point, adding to the
contention of the kernel mutex. However, if a transaction T2 is
able to see modifications made by a transaction T1, T2 will always
get a bigger transaction number and a bigger commit lsn than T1. */
/*--------------*/
mtr_commit(mtr);
DBUG_EXECUTE_IF("ib_crash_during_trx_commit_in_mem",
if (trx->has_logged()) {
log_write_up_to(mtr->commit_lsn(),
true);
DBUG_SUICIDE();
});
/*--------------*/
}
mtr->commit();
}
#ifndef DBUG_OFF
/* In case of this function is called from a stack executing
THD::release_resources -> ...
innobase_connection_close() ->
trx_rollback_for_mysql... -> .
mysql's thd does not seem to have
thd->debug_sync_control defined any longer. However the stack
is possible only with a prepared trx not updating any data.
*/
if (debug_sync) {
DEBUG_SYNC_C("before_trx_state_committed_in_memory");
}
if (debug_sync)
DEBUG_SYNC_C("before_trx_state_committed_in_memory");
#endif
trx_commit_in_memory(trx, mtr);
commit_in_memory(mtr);
}
/****************************************************************//**
Commits a transaction. */
void
trx_commit(
/*=======*/
trx_t* trx) /*!< in/out: transaction */
void trx_t::commit()
{
mtr_t* mtr;
mtr_t local_mtr;
mtr_t *mtr= nullptr;
mtr_t local_mtr;
DBUG_EXECUTE_IF("ib_trx_commit_crash_before_trx_commit_start",
DBUG_SUICIDE(););
if (trx->has_logged_or_recovered()) {
mtr = &local_mtr;
mtr->start();
} else {
mtr = NULL;
}
trx_commit_low(trx, mtr);
if (has_logged_or_recovered())
{
mtr= &local_mtr;
local_mtr.start();
}
commit_low(mtr);
#ifdef WITH_WSREP
/* Serialization history has been written and the
transaction is committed in memory, which makes
this commit ordered. Release commit order critical
section. */
if (wsrep_on(trx->mysql_thd))
{
wsrep_commit_ordered(trx->mysql_thd);
}
/* Serialization history has been written and the transaction is
committed in memory, which makes this commit ordered. Release commit
order critical section. */
if (mtr && is_wsrep())
wsrep_commit_ordered(mysql_thd);
#endif /* WITH_WSREP */
}
@ -1725,11 +1665,8 @@ trx_commit_step(
trx_commit_or_rollback_prepare(trx);
trx->lock.que_state = TRX_QUE_COMMITTING;
trx_commit(trx);
trx->commit();
ut_ad(trx->lock.wait_thr == NULL);
trx->lock.que_state = TRX_QUE_RUNNING;
thr = NULL;
@ -1767,9 +1704,7 @@ trx_commit_for_mysql(
case TRX_STATE_PREPARED:
case TRX_STATE_PREPARED_RECOVERED:
trx->op_info = "committing";
trx_commit(trx);
trx->commit();
MONITOR_DEC(MONITOR_TRX_ACTIVE);
trx->op_info = "";
return(DB_SUCCESS);

View File

@ -297,7 +297,7 @@ static MYSQL_SYSVAR_BOOL(encrypt_tables, maria_encrypt_tables, PLUGIN_VAR_OPCMDA
"and not FIXED/DYNAMIC)",
0, 0, 0);
#ifdef HAVE_PSI_INTERFACE
#if defined HAVE_PSI_INTERFACE && !defined EMBEDDED_LIBRARY
static PSI_mutex_info all_aria_mutexes[]=
{

View File

@ -156,7 +156,7 @@ struct st_pagecache_hash_link
/* simple states of a block */
#define PCBLOCK_ERROR 1 /* an error occurred when performing disk i/o */
#define PCBLOCK_READ 2 /* the is page in the block buffer */
#define PCBLOCK_READ 2 /* there is an active page in the block buffer */
/*
A tread is reading the data to the page.
@ -3752,6 +3752,7 @@ restart:
*/
if (reg_request)
unreg_request(pagecache, block, 1);
dec_counter_for_resize_op(pagecache);
pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
DBUG_PRINT("info", ("restarting..."));
goto restart;
@ -4028,6 +4029,7 @@ my_bool pagecache_delete_by_link(PAGECACHE *pagecache,
DBUG_ASSERT((block->status &
(PCBLOCK_IN_SWITCH | PCBLOCK_REASSIGNED)) == 0);
/* This lock is deleted in pagecache_delete_internal() called below */
inc_counter_for_resize_op(pagecache);
/*
make_lock_and_pin() can't fail here, because we are keeping pin on the
@ -4172,6 +4174,7 @@ restart:
*/
if (pin == PAGECACHE_PIN)
unreg_request(pagecache, block, 1);
dec_counter_for_resize_op(pagecache);
pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
DBUG_PRINT("info", ("restarting..."));
goto restart;