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_MYSQLDATADIR_STANDALONE "data")
SET(INSTALL_UNIX_ADDRDIR_STANDALONE "/tmp/mysql.sock") SET(INSTALL_UNIX_ADDRDIR_STANDALONE "/tmp/mysql.sock")
SET(INSTALL_PAMDIR_STANDALONE "share")
SET(INSTALL_PAMDATADIR_STANDALONE "share")
# #
# RPM layout # 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_SYSUSERSDIR_RPM "/usr/lib/sysusers.d")
SET(INSTALL_SYSTEMD_TMPFILESDIR_RPM "/usr/lib/tmpfiles.d") SET(INSTALL_SYSTEMD_TMPFILESDIR_RPM "/usr/lib/tmpfiles.d")
SET(INSTALL_PAMDIR_RPM "/${INSTALL_LIBDIR_RPM}/security") SET(INSTALL_PAMDIR_RPM "/${INSTALL_LIBDIR_RPM}/security")
SET(INSTALL_PAMDATADIR_RPM "/etc/security")
# #
# DEB layout # 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_SYSUSERSDIR_DEB "/usr/lib/sysusers.d")
SET(INSTALL_SYSTEMD_TMPFILESDIR_DEB "/usr/lib/tmpfiles.d") SET(INSTALL_SYSTEMD_TMPFILESDIR_DEB "/usr/lib/tmpfiles.d")
SET(INSTALL_PAMDIR_DEB "/lib/${CMAKE_CXX_LIBRARY_ARCHITECTURE}/security") SET(INSTALL_PAMDIR_DEB "/lib/${CMAKE_CXX_LIBRARY_ARCHITECTURE}/security")
SET(INSTALL_PAMDATADIR_DEB "/etc/security")
# #
# SVR4 layout # SVR4 layout

View File

@ -30,7 +30,7 @@ mysql_upgradedir=/var/lib/mysql-upgrade
stop_server() { stop_server() {
# Return immediately if there are no mysql processes running # Return immediately if there are no mysql processes running
# as there is no point in trying to shutdown in that case. # 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 set +e
systemctl stop mysql 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) by the server, or a global read lock (FLUSH TABLES WITH READ LOCK)
otherwise. otherwise.
@returns true if lock acquired */ @returns true if lock acquired */
bool bool lock_tables(MYSQL *connection)
lock_tables(MYSQL *connection)
{ {
if (have_lock_wait_timeout) { if (have_lock_wait_timeout || opt_lock_wait_timeout)
{
char buf[FN_REFLEN];
/* Set the maximum supported session value for /* Set the maximum supported session value for
lock_wait_timeout to prevent unnecessary timeouts when the lock_wait_timeout if opt_lock_wait_timeout is not set to prevent
global value is changed from the default */ unnecessary timeouts when the global value is changed from the default */
xb_mysql_query(connection, snprintf(buf, sizeof(buf), "SET SESSION lock_wait_timeout=%u",
"SET SESSION lock_wait_timeout=31536000", false); opt_lock_wait_timeout ? opt_lock_wait_timeout : 31536000);
xb_mysql_query(connection, buf, false);
} }
if (have_backup_locks) { if (have_backup_locks)
{
msg("Executing LOCK TABLES FOR BACKUP..."); msg("Executing LOCK TABLES FOR BACKUP...");
xb_mysql_query(connection, "LOCK TABLES FOR BACKUP", false); xb_mysql_query(connection, "LOCK TABLES FOR BACKUP", false);
return (true); return (true);
} }
if (opt_lock_wait_timeout) { if (opt_lock_wait_timeout)
{
if (!wait_for_no_updates(connection, opt_lock_wait_timeout, if (!wait_for_no_updates(connection, opt_lock_wait_timeout,
opt_lock_wait_threshold)) { opt_lock_wait_threshold))
{
return (false); return (false);
} }
} }
msg("Acquiring BACKUP LOCKS..."); msg("Acquiring BACKUP LOCKS...");
if (opt_kill_long_queries_timeout) { if (opt_kill_long_queries_timeout)
{
start_query_killer(); start_query_killer();
} }
if (have_galera_enabled) { if (have_galera_enabled)
xb_mysql_query(connection, {
"SET SESSION wsrep_causal_reads=0", false); 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 START", true);
// xb_mysql_query(connection, "BACKUP STAGE FLUSH", 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_DDL", true);
xb_mysql_query(connection, "BACKUP STAGE BLOCK_COMMIT", 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) { if (opt_kill_long_queries_timeout)
{
stop_query_killer(); stop_query_killer();
} }
return (true); return (true);
} }
/*********************************************************************//** /*********************************************************************//**
If backup locks are used, execute LOCK BINLOG FOR BACKUP provided that we are 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. 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 #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 void **my_thread_var_dbug(void);
extern safe_mutex_t **my_thread_var_mutex_in_use(void); extern safe_mutex_t **my_thread_var_mutex_in_use(void);
extern uint my_thread_end_wait_time; extern uint my_thread_end_wait_time;
extern my_bool safe_mutex_deadlock_detector; extern my_bool safe_mutex_deadlock_detector;
#define my_thread_var (_my_thread_var()) #define my_thread_var (_my_thread_var())
#define my_errno my_thread_var->thr_errno #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'` --let $galera_have_debug_sync = `SELECT 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_debug_sync_waiters'`
--if (!$galera_have_debug_sync) { --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 --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; disable_query_log;
drop table mysql.user; drop table mysql.user;
rename table mysql.user_bak to 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; disable_query_log;
rename table mysql.user to mysql.user_bak; rename table mysql.user to mysql.user_bak;
CREATE TABLE mysql.user ( CREATE TABLE mysql.user (

View File

@ -100,8 +100,6 @@ else
$bindir = getcwd(); $bindir = getcwd();
} }
our $wsrep_check_version;
# Find the safe process binary or script # Find the safe process binary or script
sub find_bin { sub find_bin {
if (IS_WIN32PERL or IS_CYGWIN) if (IS_WIN32PERL or IS_CYGWIN)
@ -121,10 +119,6 @@ sub find_bin {
"my_safe_process"); "my_safe_process");
push(@safe_process_cmd, $exe); 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 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
IF (WIN32) IF (WIN32)
ADD_EXECUTABLE(my_safe_process safe_process_win.cc) ADD_EXECUTABLE(my_safe_process safe_process_win.cc)
ADD_EXECUTABLE(my_safe_kill safe_kill_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 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/ */
#include <stdlib.h> #include <my_global.h>
#include <stdio.h>
#include <string.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" #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 main(int argc, char **argv)
{ {
int rc = EINVAL; int rc= 1;
void *dlh; void *dlh;
wsrep_loader_fun dlfun;
const char *provider= getenv("WSREP_PROVIDER"); const char *provider= getenv("WSREP_PROVIDER");
char** dlversion= NULL;
if (!provider) if (!provider || !*provider)
{ {
fprintf(stderr, "WSREP_PROVIDER is not set\n"); printf("WSREP_PROVIDER is not set\n");
return 1; return 1;
} }
if (!(dlh= dlopen(provider, RTLD_NOW | RTLD_LOCAL))) if (!(dlh= dlopen(provider, RTLD_NOW | RTLD_LOCAL)))
{ {
fprintf(stderr, "Can't open WSREP_PROVIDER (%s) library, error: %s\n", printf("Can't open WSREP_PROVIDER (%s) library, error: %s\n",
provider, dlerror()); provider, dlerror());
goto err; return 1;
} }
if (!(dlfun = wsrep_dlf(dlh, "wsrep_loader"))) dlversion= (char**) dlsym(dlh, "wsrep_interface_version");
if (dlversion && *dlversion)
{ {
fprintf(stderr, "Can't find 'wsrep_loader' symbol in %s\n", rc= strcmp(*dlversion, WSREP_INTERFACE_VERSION) ? 2 : 0;
provider); if (rc)
goto err; printf("Wrong wsrep provider library version, found: %s, need: %s\n", *dlversion, WSREP_INTERFACE_VERSION);
} }
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 else
return 1; printf("Galera library does not contain a version symbol");
dlclose(dlh);
return rc;
} }
#else
int main(void)
{
return 1;
}
#endif

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

View File

@ -7,8 +7,10 @@ Got one of the listed errors
insert mysql.global_priv select * from t1; insert mysql.global_priv select * from t1;
drop table t1; drop table t1;
flush privileges; flush privileges;
# switching from mysql.global_priv to mysql.user
truncate table mysql.user; truncate table mysql.user;
flush privileges; flush privileges;
connect(localhost,u1,,test,MASTER_PORT,MASTER_SOCKET); connect(localhost,u1,,test,MASTER_PORT,MASTER_SOCKET);
connect fail,localhost,u1; connect fail,localhost,u1;
Got one of the listed errors 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 # MDEV-19948 'show grants' return privileges individually
# #
# switching from mysql.global_priv to mysql.user
CREATE USER ten2; CREATE USER ten2;
GRANT ALL ON *.* TO ten2; GRANT ALL ON *.* TO ten2;
SHOW GRANTS FOR ten2; SHOW GRANTS FOR ten2;
@ -2774,6 +2775,7 @@ SHOW GRANTS FOR ten2;
Grants for ten2@% Grants for ten2@%
GRANT ALL PRIVILEGES ON *.* TO `ten2`@`%` GRANT ALL PRIVILEGES ON *.* TO `ten2`@`%`
DROP USER ten2; DROP USER ten2;
# switching back from mysql.user to mysql.global_priv
# #
# End of 10.3 tests # End of 10.3 tests
# #

View File

@ -129,6 +129,7 @@ connection default;
disconnect con1; disconnect con1;
drop database mysqltest_db1; drop database mysqltest_db1;
drop user mysqltest_u1@localhost; 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("Table 'mysql.user' doesn't exist");
call mtr.add_suppression("'mysql.user' is not of type 'TABLE'"); call mtr.add_suppression("'mysql.user' is not of type 'TABLE'");
rename table mysql.user to mysql.user1; rename table mysql.user to mysql.user1;
@ -141,6 +142,8 @@ flush privileges;
ERROR 42S02: Table 'mysql.user' doesn't exist ERROR 42S02: Table 'mysql.user' doesn't exist
drop temporary table mysql.user; drop temporary table mysql.user;
rename table mysql.user1 to 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'); call mtr.add_suppression('mysql.user table is damaged');
rename table mysql.user to mysql.user1; rename table mysql.user to mysql.user1;
create table mysql.user (Host char(100), User char(100)); create table mysql.user (Host char(100), User char(100));
@ -148,6 +151,7 @@ flush privileges;
ERROR HY000: Unknown error ERROR HY000: Unknown error
drop table mysql.user; drop table mysql.user;
rename table mysql.user1 to mysql.user; rename table mysql.user1 to mysql.user;
# switching back from mysql.user to mysql.global_priv
End of 5.5 tests End of 5.5 tests
# #
# Additional coverage for refactoring which is made as part # 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 global sql_mode="";
set local sql_mode=""; set local sql_mode="";
alter table mysql.user modify User char(16) binary not null default ''; 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() user()
root@localhost root@localhost
set global sql_mode=default; 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 # Ensure that mysql_upgrade correctly sets truncate_versioning_priv
# on upgrade from 10.2 # on upgrade from 10.2
# #
# switching from mysql.global_priv to mysql.user
drop view mysql.user_bak; drop view mysql.user_bak;
CREATE USER 'user3'@'%'; CREATE USER 'user3'@'%';
GRANT USAGE ON *.* TO '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; drop table mysql.global_priv;
rename table mysql.global_priv_bak to mysql.global_priv; rename table mysql.global_priv_bak to mysql.global_priv;
# End of 10.3 tests # End of 10.3 tests
# switching from mysql.global_priv to mysql.user
drop view mysql.user_bak; drop view mysql.user_bak;
create user 'user3'@'localhost' identified with mysql_native_password as password('a_password'); create user 'user3'@'localhost' identified with mysql_native_password as password('a_password');
show create user user3@localhost; show create user user3@localhost;
@ -625,9 +627,19 @@ connection default;
drop user user3@localhost; drop user user3@localhost;
drop table mysql.global_priv; drop table mysql.global_priv;
rename table mysql.global_priv_bak to 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 view mysql.user_bak;
drop table mysql.innodb_index_stats, mysql.innodb_table_stats; drop table mysql.innodb_index_stats, mysql.innodb_table_stats;
# mysql_upgrade --force --silent 2>&1 # mysql_upgrade --force --silent 2>&1
drop table mysql.global_priv; drop table mysql.global_priv;
rename table mysql.global_priv_bak to 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 # 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; drop table mysql.global_priv;
rename table mysql.global_priv_bak to 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 --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; drop view mysql.user_bak;
install soname 'ha_blackhole'; install soname 'ha_blackhole';
install soname 'ha_archive'; install soname 'ha_archive';
@ -144,6 +145,7 @@ Code 1286
Message Unknown storage engine 'ARCHIVE' Message Unknown storage engine 'ARCHIVE'
drop table mysql.global_priv; drop table mysql.global_priv;
rename table mysql.global_priv_bak to 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 view mysql.user_bak;
alter table mysql.user drop column default_role, drop column max_statement_time; alter table mysql.user drop column default_role, drop column max_statement_time;
Phase 1/7: Checking and upgrading mysql database Phase 1/7: Checking and upgrading mysql database
@ -236,6 +238,7 @@ Code 1286
Message Unknown storage engine 'ARCHIVE' Message Unknown storage engine 'ARCHIVE'
drop table mysql.global_priv; drop table mysql.global_priv;
rename table mysql.global_priv_bak to 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 view mysql.user_bak;
alter table mysql.user drop column default_role, drop column max_statement_time; alter table mysql.user drop column default_role, drop column max_statement_time;
Phase 1/7: Checking and upgrading mysql database 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 # 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; DROP VIEW mysql.user_bak;
FLUSH PRIVILEGES; FLUSH PRIVILEGES;
CREATE USER user_all@localhost; 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 # Password expiration fields are loaded properly on 10.3 tables
# #
# switching from mysql.global_priv to mysql.user
create user user1@localhost; create user user1@localhost;
show create user user1@localhost; show create user user1@localhost;
CREATE USER for user1@localhost CREATE USER for user1@localhost
@ -205,6 +206,7 @@ connection default;
drop user user1@localhost; drop user user1@localhost;
set global disconnect_on_expired_password=default; set global disconnect_on_expired_password=default;
set global default_password_lifetime=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 # PASSWORD EXPIRE DEFAULT should use the default_password_lifetime
# system var to set the number of days till expiration # system var to set the number of days till expiration

View File

@ -354,6 +354,7 @@ uplain@localhost uplain@localhost
connection default; connection default;
disconnect cleartext_con; disconnect cleartext_con;
DROP USER uplain@localhost; DROP USER uplain@localhost;
# switching from mysql.global_priv to mysql.user
drop view mysql.user_bak; drop view mysql.user_bak;
# #
# Bug #59038 : mysql.user.authentication_string column # 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 natauth@localhost, newpass@localhost, newpassnat@localhost;
drop user oldauth@localhost, oldpass@localhost, oldpassold@localhost; drop user oldauth@localhost, oldpass@localhost, oldpassold@localhost;
set global secure_auth=default; set global secure_auth=default;
# switching from mysql.global_priv to mysql.user
create user foo@localhost identified with mysql_native_password; 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'; 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'); 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 user host password plugin authentication_string
foo localhost mysql_native_password foo localhost mysql_native_password
drop user foo@localhost; 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 procedure p1;
drop table t1; drop table t1;
set session low_priority_updates=default; 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, 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, 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, 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; disconnect con1;
connection default; connection default;
DROP PROCEDURE p1; 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. # 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 # -- End of 5.1 tests
# ------------------------------------------------------------------ # ------------------------------------------------------------------
# switching from mysql.global_priv to mysql.user
grant create routine on test.* to foo1@localhost identified by 'foo'; grant create routine on test.* to foo1@localhost identified by 'foo';
update mysql.user set authentication_string = replace(authentication_string, '*', '-') where user='foo1'; update mysql.user set authentication_string = replace(authentication_string, '*', '-') where user='foo1';
connect foo,localhost,foo1,foo; connect foo,localhost,foo1,foo;
@ -347,4 +350,5 @@ connection default;
disconnect foo; disconnect foo;
drop procedure spfoo; drop procedure spfoo;
drop user foo1@localhost; drop user foo1@localhost;
# switching back from mysql.user to mysql.global_priv
set @@global.concurrent_insert= @old_concurrent_insert; set @@global.concurrent_insert= @old_concurrent_insert;

View File

@ -3,6 +3,7 @@
# Fatal error: mysql.user table is damaged or in # Fatal error: mysql.user table is damaged or in
# unsupported 3.20 format # unsupported 3.20 format
# #
# switching from mysql.global_priv to mysql.user
# #
# Original mysql.user table # Original mysql.user table
# #
@ -221,3 +222,4 @@ drop user user@localhost;
# #
# Reset to final original state. # 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 $opt_start_exit;
my $start_only; my $start_only;
my $file_wsrep_provider; my $file_wsrep_provider;
my $extra_path;
my $mariabackup_path;
my $mariabackup_exe;
my $garbd_exe;
our @global_suppressions; our @global_suppressions;
@ -383,170 +379,6 @@ $| = 1; # Automatically flush STDOUT
main(); 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 { sub main {
$ENV{MTR_PERL}=$^X; $ENV{MTR_PERL}=$^X;
@ -591,8 +423,7 @@ sub main {
} }
check_ssl_support(); check_ssl_support();
check_debug_support(); check_debug_support();
check_wsrep_support(); environment_setup();
check_mariabackup_support();
if (!$opt_suites) { if (!$opt_suites) {
$opt_suites= join ',', collect_default_suites(@DEFAULT_SUITES); $opt_suites= join ',', collect_default_suites(@DEFAULT_SUITES);
@ -2602,10 +2433,23 @@ sub environment_setup {
my $exe_innochecksum= my $exe_innochecksum=
mtr_exe_maybe_exists("$bindir/extra$opt_vs_config/innochecksum", mtr_exe_maybe_exists("$bindir/extra$opt_vs_config/innochecksum",
"$path_client_bindir/innochecksum"); "$path_client_bindir/innochecksum");
if ($exe_innochecksum) $ENV{'INNOCHECKSUM'}= native_path($exe_innochecksum) if $exe_innochecksum;
{
$ENV{'INNOCHECKSUM'}= native_path($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 # Create an environment variable to make it possible
# to detect that valgrind is being used from test cases # 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> # 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 # Extra options can come not only from the command line, but also
# from option files or combinations. We want them on a command line # 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' $skip{'main/plugin_loaderr.test'} = 'needs compiled-in innodb'
unless $::mysqld_variables{'innodb'} eq "ON"; 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 # disable tests that use ipv6, if unsupported
sub ipv6_ok() { sub ipv6_ok() {
use Socket; 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; package My::Suite::Galera;
use File::Basename;
use My::Find; use lib 'suite';
use wsrep::common;
@ISA = qw(My::Suite); @ISA = qw(My::Suite);
return "Not run for embedded server" if $::opt_embedded_server; return wsrep_not_ok() if wsrep_not_ok();
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();
push @::global_suppressions, 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 .*), 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 { }; bless { };

View File

@ -10,3 +10,6 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true'
[mysqld.2] [mysqld.2]
wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true' 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] [mysqld.2]
wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true' 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; package My::Suite::GALERA_3NODES;
use File::Basename;
use My::Find; use lib 'suite';
use wsrep::common;
@ISA = qw(My::Suite); @ISA = qw(My::Suite);
return "Not run for embedded server" if $::opt_embedded_server; return wsrep_not_ok() if wsrep_not_ok();
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();
push @::global_suppressions, push @::global_suppressions,
( (

View File

@ -4,7 +4,7 @@
--source include/galera_cluster.inc --source include/galera_cluster.inc
--source include/have_innodb.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_connection_name = node_3
--let $galera_server_number = 3 --let $galera_server_number = 3

View File

@ -1,16 +1,11 @@
package My::Suite::Galera_sr; package My::Suite::Galera_sr;
use File::Basename;
use My::Find; use lib 'suite';
use wsrep::common;
@ISA = qw(My::Suite); @ISA = qw(My::Suite);
return "Not run for embedded server" if $::opt_embedded_server; return wsrep_not_ok() if wsrep_not_ok();
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();
push @::global_suppressions, push @::global_suppressions,
( (

View File

@ -124,3 +124,18 @@ SELECT DISTINCT (CURRENT_TIMESTAMP()-d4) <= 60 FROM t1;
(CURRENT_TIMESTAMP()-d4) <= 60 (CURRENT_TIMESTAMP()-d4) <= 60
1 1
DROP TABLE t1; 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_innodb.inc
--source include/have_sequence.inc
CREATE TABLE t1 (i1 INT UNSIGNED NULL DEFAULT 42) ENGINE=innodb; CREATE TABLE t1 (i1 INT UNSIGNED NULL DEFAULT 42) ENGINE=innodb;
INSERT INTO t1 VALUES(NULL); 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 COUNT(DISTINCT d4),COUNT(d4),COUNT(*) FROM t1;
SELECT DISTINCT (CURRENT_TIMESTAMP()-d4) <= 60 FROM t1; SELECT DISTINCT (CURRENT_TIMESTAMP()-d4) <= 60 FROM t1;
DROP TABLE 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; FOREIGN KEY(f1) REFERENCES mdev20987_1(f1))ENGINE=InnoDB;
INSERT INTO mdev20987_1 VALUES(1); INSERT INTO mdev20987_1 VALUES(1);
INSERT INTO mdev20987_2 VALUES(1, 'mariadb'); 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 # restart
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -713,7 +718,7 @@ t2 CREATE TABLE `t2` (
PRIMARY KEY (`FTS_DOC_ID`) PRIMARY KEY (`FTS_DOC_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb'); 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---------" "----------Test28---------"
create table `fts_test`(`a` text,fulltext key(`a`))engine=innodb; create table `fts_test`(`a` text,fulltext key(`a`))engine=innodb;
set session autocommit=0; 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; FOREIGN KEY(f1) REFERENCES mdev20987_1(f1))ENGINE=InnoDB;
INSERT INTO mdev20987_1 VALUES(1); INSERT INTO mdev20987_1 VALUES(1);
INSERT INTO mdev20987_2 VALUES(1, 'mariadb'); 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 --source include/restart_mysqld.inc
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
DELETE FROM t1 WHERE MATCH(char_column) AGAINST ('bbb'); 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---------" --echo "----------Test28---------"
create table `fts_test`(`a` text,fulltext key(`a`))engine=innodb; 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; create table t1 (c1 int, c2 geometry not null, spatial index (c2))engine=innodb;
insert into t1 values(1, Point(1,1)); begin;
insert into t1 values(2, Point(2,2)); insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
insert into t1 values(3, Point(3,3)); from seq_1_to_576;
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;
SET @saved_dbug = @@SESSION.debug_dbug; SET @saved_dbug = @@SESSION.debug_dbug;
SET debug_dbug = '+d,rtr_page_need_second_split'; SET debug_dbug = '+d,rtr_page_need_second_split';
insert into t1 select * from t1; insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
from seq_1_to_576;
SET debug_dbug = @saved_dbug; SET debug_dbug = @saved_dbug;
delete from t1; rollback;
insert into t1 values(1, Point(1,1)); insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
insert into t1 values(2, Point(2,2)); from seq_1_to_2304;
insert into t1 values(3, Point(3,3)); begin;
insert into t1 values(4, Point(4,4)); insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
insert into t1 values(5, Point(5,5)); from seq_1_to_2304;
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; rollback;
check table t1; check table t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
insert into t1 select * from t1; insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
insert into t1 select * from t1; from seq_1_to_71424;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
check table t1; check table t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK

View File

@ -1,5 +1,5 @@
# WL#6745 InnoDB R-tree support # 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 # Not supported in embedded
--source include/not_embedded.inc --source include/not_embedded.inc
@ -8,66 +8,34 @@
--source include/big_test.inc --source include/big_test.inc
--source include/not_valgrind.inc --source include/not_valgrind.inc
--source include/have_debug.inc --source include/have_debug.inc
--source include/have_sequence.inc
let $restart_noprint=2; let $restart_noprint=2;
# Create table with R-tree index. # Create table with R-tree index.
create table t1 (c1 int, c2 geometry not null, spatial index (c2))engine=innodb; create table t1 (c1 int, c2 geometry not null, spatial index (c2))engine=innodb;
begin;
# Insert enough values to let R-tree split. # Insert enough values to let R-tree split.
insert into t1 values(1, Point(1,1)); insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
insert into t1 values(2, Point(2,2)); from seq_1_to_576;
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;
#Check second round spliting. #Check second round spliting.
SET @saved_dbug = @@SESSION.debug_dbug; SET @saved_dbug = @@SESSION.debug_dbug;
SET debug_dbug = '+d,rtr_page_need_second_split'; SET debug_dbug = '+d,rtr_page_need_second_split';
insert into t1 select * from t1; insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
from seq_1_to_576;
SET debug_dbug = @saved_dbug; SET debug_dbug = @saved_dbug;
rollback;
delete from t1; insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
from seq_1_to_2304;
insert into t1 values(1, Point(1,1)); begin;
insert into t1 values(2, Point(2,2)); insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
insert into t1 values(3, Point(3,3)); from seq_1_to_2304;
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; rollback;
check table t1; check table t1;
insert into t1 select * from t1; insert into t1 select @s:=1+(seq mod 9), point(@s, @s)
insert into t1 select * from t1; from seq_1_to_71424;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
check table t1; check table t1;
select count(*) from 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 "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; my $have_qpress = index(`qpress 2>&1`,"Compression") > 0;
sub skip_combinations { sub skip_combinations {
my %skip; 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{'compress_qpress.test'}= 'needs qpress executable in PATH' unless $have_qpress;
%skip; %skip;
} }

View File

@ -153,8 +153,10 @@ show create user mysqltest1;
CREATE USER for mysqltest1@% CREATE USER for mysqltest1@%
CREATE USER `mysqltest1`@`%` IDENTIFIED VIA mysql_native_password USING '*BFE3F4604CFD21E6595080A261D92EF0183B5971' OR unix_socket CREATE USER `mysqltest1`@`%` IDENTIFIED VIA mysql_native_password USING '*BFE3F4604CFD21E6595080A261D92EF0183B5971' OR unix_socket
drop user mysqltest1; 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"); 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 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 USER identified via mysql_native_password as '1234567890123456789012345678901234567890a' OR unix_socket;
create user mysqltest1 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'); update mysql.global_priv set priv=replace(priv, '1234567890123456789012345678901234567890a', 'invalid password');
@ -192,3 +194,16 @@ user() current_user() database()
mysqltest1@localhost mysqltest1@% test mysqltest1@localhost mysqltest1@% test
drop user mysqltest1; drop user mysqltest1;
uninstall soname 'auth_ed25519'; 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'; uninstall soname 'auth_ed25519';
--remove_file $MYSQLTEST_VARDIR/tmp/peercred_test.txt --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,,; connect mysql, localhost, root,,;
use mysql; use mysql;
alter table user drop column is_role; alter table user drop column is_role;
@ -26,3 +27,4 @@ update user set is_role='N';
flush privileges; flush privileges;
create role test_role; create role test_role;
drop 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_innodb.inc
--source include/have_perfschema.inc
--echo # --echo #
--echo # MDEV-15977 Assertion `! thd->in_sub_stmt' failed in trans_commit_stmt --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; package My::Suite::WSREP;
use File::Basename;
use My::Find; use lib 'suite';
use wsrep::common;
@ISA = qw(My::Suite); @ISA = qw(My::Suite);
return "Not run for embedded server" if $::opt_embedded_server; return wsrep_not_ok() if wsrep_not_ok();
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();
push @::global_suppressions, push @::global_suppressions,
( (

View File

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

View File

@ -22,7 +22,7 @@ IF(HAVE_PAM_APPL_H)
IF(HAVE_STRNDUP) IF(HAVE_STRNDUP)
ADD_DEFINITIONS(-DHAVE_STRNDUP) ADD_DEFINITIONS(-DHAVE_STRNDUP)
ENDIF(HAVE_STRNDUP) ENDIF(HAVE_STRNDUP)
FIND_LIBRARY(PAM_LIBRARY pam) FIND_LIBRARY(PAM_LIBRARY pam) # for srpm build-depends detection
ADD_DEFINITIONS(-D_GNU_SOURCE) 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_v1 auth_pam_v1.c LINK_LIBRARIES pam MODULE_ONLY)
MYSQL_ADD_PLUGIN(auth_pam auth_pam.c LINK_LIBRARIES pam dl 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 "") SET_TARGET_PROPERTIES (pam_user_map PROPERTIES PREFIX "")
IF(INSTALL_PAMDIR) IF(INSTALL_PAMDIR)
INSTALL(TARGETS pam_user_map DESTINATION ${INSTALL_PAMDIR} COMPONENT Server) 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() ENDIF()
ENDIF(HAVE_PAM_APPL_H) ENDIF(HAVE_PAM_APPL_H)

View File

@ -4,15 +4,9 @@ use My::Find;
@ISA = qw(My::Suite); @ISA = qw(My::Suite);
return "Not run for embedded server" if $::opt_embedded_server; use lib 'suite';
use wsrep::common;
return "WSREP is not compiled in" if not ::have_wsrep(); return wsrep_not_ok() if wsrep_not_ok();
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};
push @::global_suppressions, 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, ALTER TABLE user ADD plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL,
ADD authentication_string TEXT 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, ALTER TABLE user MODIFY plugin char(64) CHARACTER SET latin1 DEFAULT '' NOT NULL,
MODIFY authentication_string TEXT 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; 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, Alter_info *alter_info_arg,
KEY *key_info_arg, uint key_count_arg, KEY *key_info_arg, uint key_count_arg,
partition_info *modified_part_info_arg, partition_info *modified_part_info_arg,
bool ignore_arg) bool ignore_arg, bool error_non_empty)
: create_info(create_info_arg), : create_info(create_info_arg),
alter_info(alter_info_arg), alter_info(alter_info_arg),
key_info_buffer(key_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), modified_part_info(modified_part_info_arg),
ignore(ignore_arg), ignore(ignore_arg),
online(false), 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, void Alter_inplace_info::report_unsupported_error(const char *not_supported,

View File

@ -2496,11 +2496,14 @@ public:
*/ */
const char *unsupported_reason; 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_inplace_info(HA_CREATE_INFO *create_info_arg,
Alter_info *alter_info_arg, Alter_info *alter_info_arg,
KEY *key_info_arg, uint key_count_arg, KEY *key_info_arg, uint key_count_arg,
partition_info *modified_part_info_arg, partition_info *modified_part_info_arg,
bool ignore_arg); bool ignore_arg, bool error_non_empty);
~Alter_inplace_info() ~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 TODO: do not do reinit 'rand' for every execute of PS/SP if
args[0] is a constant. args[0] is a constant.
*/ */
uint32 tmp; uint32 tmp= (uint32) arg->val_int();
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (WSREP_ON)
{
THD *thd= current_thd; THD *thd= current_thd;
if (WSREP(thd)) if (WSREP(thd))
{ {
if (wsrep_thd_is_applying(thd)) if (wsrep_thd_is_applying(thd))
tmp= thd->wsrep_rand; tmp= thd->wsrep_rand;
else else
tmp= thd->wsrep_rand= (uint32) arg->val_int(); thd->wsrep_rand= tmp;
}
} }
else
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
tmp= (uint32) arg->val_int();
my_rnd_init(rand, (uint32) (tmp*0x10001L+55555555L), my_rnd_init(rand, (uint32) (tmp*0x10001L+55555555L),
(uint32) (tmp*0x10000001L)); (uint32) (tmp*0x10000001L));

View File

@ -2120,7 +2120,8 @@ Query_log_event::do_shall_skip(rpl_group_info *rgi)
} }
} }
#ifdef WITH_WSREP #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 && thd->wsrep_mysql_replicated > 0 &&
(is_begin() || is_commit())) (is_begin() || is_commit()))
{ {

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. /* 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 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 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, Alter_inplace_info ha_alter_info(create_info, alter_info,
key_info, key_count, key_info, key_count,
IF_PARTITIONING(thd->work_part_info, NULL), IF_PARTITIONING(thd->work_part_info, NULL),
ignore); ignore, alter_ctx.error_if_not_empty);
TABLE_SHARE altered_share; TABLE_SHARE altered_share;
TABLE altered_table; TABLE altered_table;
bool use_inplace= true; bool use_inplace= true;
@ -10863,7 +10863,8 @@ err_new_table_cleanup:
thd->get_stmt_da()->current_row_for_warning())) thd->get_stmt_da()->current_row_for_warning()))
{ {
Abort_on_warning_instant_set aws(thd, true); 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) 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 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 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 int threadpool_process_request(THD *thd);
static THD* threadpool_add_connection(CONNECT *connect, void *scheduler_data); 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*); extern bool do_command(THD*);
static inline TP_connection *get_TP_connection(THD *thd) static inline TP_connection *get_TP_connection(THD *thd)
@ -90,13 +89,13 @@ struct Worker_thread_context
void save() void save()
{ {
psi_thread= PSI_CALL_get_thread(); psi_thread= PSI_CALL_get_thread();
mysys_var= (st_my_thread_var *)pthread_getspecific(THR_KEY_mysys); mysys_var= my_thread_var;
} }
void restore() void restore()
{ {
PSI_CALL_set_thread(psi_thread); PSI_CALL_set_thread(psi_thread);
pthread_setspecific(THR_KEY_mysys,mysys_var); set_mysys_var(mysys_var);
pthread_setspecific(THR_THD, 0); pthread_setspecific(THR_THD, 0);
} }
}; };
@ -147,7 +146,7 @@ static void thread_attach(THD* thd)
attaching the thd. */ attaching the thd. */
wsrep_wait_rollback_complete_and_acquire_ownership(thd); wsrep_wait_rollback_complete_and_acquire_ownership(thd);
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
pthread_setspecific(THR_KEY_mysys,thd->mysys_var); set_mysys_var(thd->mysys_var);
thd->thread_stack=(char*)&thd; thd->thread_stack=(char*)&thd;
thd->store_globals(); thd->store_globals();
PSI_CALL_set_thread(thd->get_psi()); 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. Store them in THD.
*/ */
pthread_setspecific(THR_KEY_mysys, 0); set_mysys_var(NULL);
my_thread_init(); 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)); PSI_CALL_set_thread(PSI_CALL_new_thread(key_thread_one_connection, connect, 0));
if (!mysys_var ||!(thd= connect->create_thd(NULL))) 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 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 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_commit_ordered(THD* )
{ } { }
void wsrep_log(void (*)(const char *, ...), const char *, ...)
{
}
my_bool wsrep_thd_is_applying(const THD*) my_bool wsrep_thd_is_applying(const THD*)
{ return 0;} { return 0;}

View File

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

View File

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

View File

@ -444,9 +444,9 @@ fts_read_stopword(
/******************************************************************//** /******************************************************************//**
Load user defined stopword from designated user table Load user defined stopword from designated user table
@return TRUE if load operation is successful */ @return whether the operation is successful */
static static
ibool bool
fts_load_user_stopword( fts_load_user_stopword(
/*===================*/ /*===================*/
fts_t* fts, /*!< in: FTS struct */ fts_t* fts, /*!< in: FTS struct */
@ -454,27 +454,26 @@ fts_load_user_stopword(
name */ name */
fts_stopword_t* stopword_info) /*!< in: Stopword info */ fts_stopword_t* stopword_info) /*!< in: Stopword info */
{ {
pars_info_t* info; if (!fts->dict_locked) {
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) {
mutex_enter(&dict_sys.mutex); mutex_enter(&dict_sys.mutex);
} }
/* Validate the user table existence and in the right /* Validate the user table existence in the right format */
format */ bool ret= false;
stopword_info->charset = fts_valid_stopword_table(stopword_table_name); stopword_info->charset = fts_valid_stopword_table(stopword_table_name);
if (!stopword_info->charset) { if (!stopword_info->charset) {
ret = FALSE; cleanup:
goto cleanup; if (!fts->dict_locked) {
} else if (!stopword_info->cached_stopword) { 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 /* Create the stopword RB tree with the stopword column
charset. All comparison will use this charset */ charset. All comparison will use this charset */
stopword_info->cached_stopword = rbt_create_arg_cmp( 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_id(info, TRUE, "table_stopword", stopword_table_name);
pars_info_bind_function(info, "my_func", fts_read_stopword, pars_info_bind_function(info, "my_func", fts_read_stopword,
stopword_info); stopword_info);
graph = fts_parse_sql_no_dict_lock( que_t* graph = fts_parse_sql_no_dict_lock(
info, info,
"DECLARE FUNCTION my_func;\n" "DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS" "DECLARE CURSOR c IS"
@ -508,14 +507,13 @@ fts_load_user_stopword(
"CLOSE c;"); "CLOSE c;");
for (;;) { for (;;) {
error = fts_eval_sql(trx, graph); dberr_t error = fts_eval_sql(trx, graph);
if (error == DB_SUCCESS) { if (error == DB_SUCCESS) {
fts_sql_commit(trx); fts_sql_commit(trx);
stopword_info->status = STOPWORD_USER_TABLE; stopword_info->status = STOPWORD_USER_TABLE;
break; break;
} else { } else {
fts_sql_rollback(trx); fts_sql_rollback(trx);
if (error == DB_LOCK_WAIT_TIMEOUT) { if (error == DB_LOCK_WAIT_TIMEOUT) {
@ -534,14 +532,9 @@ fts_load_user_stopword(
} }
que_graph_free(graph); que_graph_free(graph);
cleanup:
if (!has_lock) {
mutex_exit(&dict_sys.mutex);
}
trx_free(trx); 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 if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) { & STOPWORD_NOT_INIT) {
fts_load_stopword(table, NULL, NULL, fts_load_stopword(table, NULL, NULL,
NULL, TRUE, TRUE); true, true);
} }
fts_cache_add_doc( fts_cache_add_doc(
@ -3523,8 +3516,8 @@ fts_add_doc_by_id(
if (table->fts->cache->stopword_info.status if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) { & STOPWORD_NOT_INIT) {
fts_load_stopword(table, NULL, NULL, fts_load_stopword(table, NULL,
NULL, TRUE, TRUE); NULL, true, true);
} }
fts_cache_add_doc( 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 records/fetches stopword configuration to/from FTS configure
table, depending on whether we are creating or reloading the table, depending on whether we are creating or reloading the
FTS. FTS.
@return TRUE if load operation is successful */ @return true if load operation is successful */
ibool bool
fts_load_stopword( fts_load_stopword(
/*==============*/ /*==============*/
const dict_table_t* const dict_table_t*
table, /*!< in: Table with FTS */ table, /*!< in: Table with FTS */
trx_t* trx, /*!< in: Transactions */ trx_t* trx, /*!< in: Transactions */
const char* global_stopword_table, /*!< in: Global stopword table
name */
const char* session_stopword_table, /*!< in: Session stopword table const char* session_stopword_table, /*!< in: Session stopword table
name */ name */
ibool stopword_is_on, /*!< in: Whether stopword bool stopword_is_on, /*!< in: Whether stopword
option is turned on/off */ option is turned on/off */
ibool reload) /*!< in: Whether it is bool reload) /*!< in: Whether it is
for reloading FTS table */ for reloading FTS table */
{ {
fts_table_t fts_table; fts_table_t fts_table;
@ -7074,9 +7065,8 @@ fts_load_stopword(
cache = table->fts->cache; cache = table->fts->cache;
if (!reload && !(cache->stopword_info.status if (!reload && !(cache->stopword_info.status & STOPWORD_NOT_INIT)) {
& STOPWORD_NOT_INIT)) { return true;
return(TRUE);
} }
if (!trx) { if (!trx) {
@ -7126,12 +7116,11 @@ fts_load_stopword(
goto cleanup; goto cleanup;
} }
if (strlen((char*) str.f_str) > 0) { if (*str.f_str) {
stopword_to_use = (const char*) str.f_str; stopword_to_use = (const char*) str.f_str;
} }
} else { } else {
stopword_to_use = (session_stopword_table) stopword_to_use = session_stopword_table;
? session_stopword_table : global_stopword_table;
} }
if (stopword_to_use if (stopword_to_use
@ -7169,7 +7158,7 @@ cleanup:
&my_charset_latin1); &my_charset_latin1);
} }
return(error == DB_SUCCESS); return error == DB_SUCCESS;
} }
/**********************************************************************//** /**********************************************************************//**
@ -7370,7 +7359,7 @@ fts_init_index(
} else { } else {
if (table->fts->cache->stopword_info.status if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) { & 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) { 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); 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 /** 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. that mtr holds an SX-latch or X-latch on the tree.
@return rec_get_offsets() of the node pointer record */ @return rec_get_offsets() of the node pointer record */
@ -803,123 +918,6 @@ rtr_page_get_father_block(
cursor, mtr)); 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 */ Create a RTree search info structure */
rtr_info_t* 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) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc. Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc. Copyright (c) 2012, Facebook Inc.
@ -1560,20 +1560,14 @@ thd_trx_is_auto_commit(
/** Enter InnoDB engine after checking the max number of user threads /** Enter InnoDB engine after checking the max number of user threads
allowed, else the thread is put into sleep. allowed, else the thread is put into sleep.
@param[in,out] prebuilt row prebuilt handler */ @param[in,out] prebuilt row prebuilt handler */
static inline static inline void innobase_srv_conc_enter_innodb(row_prebuilt_t *prebuilt)
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 (srv_thread_concurrency) {
if (trx->n_tickets_to_enter_innodb > 0) { if (trx->n_tickets_to_enter_innodb > 0) {
@ -1600,22 +1594,16 @@ innobase_srv_conc_enter_innodb(
/** Note that the thread wants to leave InnoDB only if it doesn't have /** Note that the thread wants to leave InnoDB only if it doesn't have
any spare tickets. any spare tickets.
@param[in,out] m_prebuilt row prebuilt handler */ @param[in,out] m_prebuilt row prebuilt handler */
static inline static inline void innobase_srv_conc_exit_innodb(row_prebuilt_t *prebuilt)
void
innobase_srv_conc_exit_innodb(
row_prebuilt_t* prebuilt)
{ {
ut_ad(!sync_check_iterate(sync_check())); 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. */ /* This is to avoid making an unnecessary function call. */
if (trx->declared_to_be_inside_innodb if (trx->declared_to_be_inside_innodb
&& trx->n_tickets_to_enter_innodb == 0) { && trx->n_tickets_to_enter_innodb == 0) {
@ -2485,6 +2473,9 @@ innobase_trx_init(
trx->check_unique_secondary = !thd_test_options( trx->check_unique_secondary = !thd_test_options(
thd, OPTION_RELAXED_UNIQUE_CHECKS); thd, OPTION_RELAXED_UNIQUE_CHECKS);
#ifdef WITH_WSREP
trx->wsrep = wsrep_on(thd);
#endif
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -4142,19 +4133,17 @@ innobase_commit_low(
trx_t* trx) /*!< in: transaction handle */ trx_t* trx) /*!< in: transaction handle */
{ {
#ifdef WITH_WSREP #ifdef WITH_WSREP
THD* thd = (THD*)trx->mysql_thd;
const char* tmp = 0; const char* tmp = 0;
if (wsrep_on(thd)) { if (trx->is_wsrep()) {
#ifdef WSREP_PROC_INFO #ifdef WSREP_PROC_INFO
char info[64]; char info[64];
info[sizeof(info) - 1] = '\0'; info[sizeof(info) - 1] = '\0';
snprintf(info, sizeof(info) - 1, snprintf(info, sizeof(info) - 1,
"innobase_commit_low():trx_commit_for_mysql(%lld)", "innobase_commit_low():trx_commit_for_mysql(%lld)",
(long long) wsrep_thd_trx_seqno(thd)); (long long) wsrep_thd_trx_seqno(trx->mysql_thd));
tmp = thd_proc_info(thd, info); tmp = thd_proc_info(trx->mysql_thd, info);
#else #else
tmp = thd_proc_info(thd, "innobase_commit_low()"); tmp = thd_proc_info(trx->mysql_thd, "innobase_commit_low()");
#endif /* WSREP_PROC_INFO */ #endif /* WSREP_PROC_INFO */
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
@ -4164,7 +4153,7 @@ innobase_commit_low(
} }
trx->will_lock = 0; trx->will_lock = 0;
#ifdef WITH_WSREP #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 */ #endif /* WITH_WSREP */
} }
@ -4277,7 +4266,7 @@ innobase_commit_ordered_2(
#ifdef WITH_WSREP #ifdef WITH_WSREP
/* If the transaction is not run in 2pc, we must assign wsrep /* If the transaction is not run in 2pc, we must assign wsrep
XID here in order to get it written in rollback segment. */ 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); thd_get_xid(thd, (MYSQL_XID*)trx->xid);
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
@ -4859,20 +4848,17 @@ UNIV_INTERN void lock_cancel_waiting_and_release(lock_t* lock);
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");
#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;
}
#endif /* WITH_WSREP */
if (trx_t* trx = thd_to_trx(thd)) { if (trx_t *trx= thd_to_trx(thd))
{
ut_ad(trx->mysql_thd == thd); ut_ad(trx->mysql_thd == thd);
#ifdef WITH_WSREP
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 */ /* Cancel a pending lock request if there are any */
lock_trx_handle_wait(trx); lock_trx_handle_wait(trx);
} }
@ -7680,7 +7666,7 @@ ha_innobase::write_row(
{ {
dberr_t error; dberr_t error;
#ifdef WITH_WSREP #ifdef WITH_WSREP
ibool auto_inc_inserted= FALSE; /* if NULL was inserted */ bool wsrep_auto_inc_inserted= false;
#endif #endif
int error_result = 0; int error_result = 0;
bool auto_inc_used = false; bool auto_inc_used = false;
@ -7710,7 +7696,9 @@ ha_innobase::write_row(
m_prebuilt->autoinc_error = DB_SUCCESS; m_prebuilt->autoinc_error = DB_SUCCESS;
#ifdef WITH_WSREP #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 #endif
if ((error_result = update_auto_increment())) { if ((error_result = update_auto_increment())) {
@ -7807,18 +7795,14 @@ ha_innobase::write_row(
m_prebuilt->autoinc_offset, m_prebuilt->autoinc_offset,
m_prebuilt->autoinc_increment); m_prebuilt->autoinc_increment);
if (wsrep_on(m_user_thd) && if (wsrep_auto_inc_inserted &&
auto_inc_inserted &&
wsrep_drupal_282555_workaround &&
wsrep_thd_retry_counter(m_user_thd) == 0 && wsrep_thd_retry_counter(m_user_thd) == 0 &&
!thd_test_options(m_user_thd, !thd_test_options(m_user_thd,
OPTION_NOT_AUTOCOMMIT | OPTION_NOT_AUTOCOMMIT |
OPTION_BEGIN)) { OPTION_BEGIN)) {
WSREP_DEBUG( WSREP_DEBUG(
"retrying insert: %s", "retrying insert: %s",
(*wsrep_thd_query(m_user_thd)) ? wsrep_thd_query(m_user_thd));
wsrep_thd_query(m_user_thd) :
(char *)"void");
error= DB_SUCCESS; error= DB_SUCCESS;
wsrep_thd_self_abort(m_user_thd); wsrep_thd_self_abort(m_user_thd);
innobase_srv_conc_exit_innodb( innobase_srv_conc_exit_innodb(
@ -7858,7 +7842,7 @@ set_max_autoinc:
m_prebuilt autoinc values don't get m_prebuilt autoinc values don't get
properly assigned. Fetch values from properly assigned. Fetch values from
server side. */ server side. */
if (wsrep_on(m_user_thd) && if (trx->is_wsrep() &&
wsrep_thd_is_applying(m_user_thd)) wsrep_thd_is_applying(m_user_thd))
{ {
wsrep_thd_auto_increment_variables( wsrep_thd_auto_increment_variables(
@ -7905,8 +7889,7 @@ report_error:
error, m_prebuilt->table->flags, m_user_thd); error, m_prebuilt->table->flags, m_user_thd);
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (!error_result if (!error_result && trx->is_wsrep()
&& wsrep_on(m_user_thd)
&& wsrep_thd_is_local(m_user_thd) && wsrep_thd_is_local(m_user_thd)
&& !wsrep_thd_ignore_table(m_user_thd) && !wsrep_thd_ignore_table(m_user_thd)
&& !wsrep_consistency_check(m_user_thd) && !wsrep_consistency_check(m_user_thd)
@ -7918,10 +7901,9 @@ report_error:
NULL)) { NULL)) {
DBUG_PRINT("wsrep", ("row key failed")); DBUG_PRINT("wsrep", ("row key failed"));
error_result = HA_ERR_INTERNAL_ERROR; error_result = HA_ERR_INTERNAL_ERROR;
goto wsrep_error; goto func_exit;
} }
} }
wsrep_error:
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
if (error_result == HA_FTS_INVALID_DOCID) { if (error_result == HA_FTS_INVALID_DOCID) {
@ -8574,8 +8556,7 @@ ha_innobase::update_row(
m_prebuilt autoinc values don't get m_prebuilt autoinc values don't get
properly assigned. Fetch values from properly assigned. Fetch values from
server side. */ server side. */
if (wsrep_on(m_user_thd) && if (trx->is_wsrep() && wsrep_thd_is_applying(m_user_thd))
wsrep_thd_is_applying(m_user_thd))
wsrep_thd_auto_increment_variables( wsrep_thd_auto_increment_variables(
m_user_thd, &offset, &increment); m_user_thd, &offset, &increment);
else else
@ -8619,11 +8600,9 @@ func_exit:
innobase_active_small(); innobase_active_small();
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (error == DB_SUCCESS if (error == DB_SUCCESS && trx->is_wsrep()
&& wsrep_on(m_user_thd)
&& wsrep_thd_is_local(m_user_thd) && wsrep_thd_is_local(m_user_thd)
&& !wsrep_thd_ignore_table(m_user_thd)) { && !wsrep_thd_ignore_table(m_user_thd)) {
DBUG_PRINT("wsrep", ("update row key")); DBUG_PRINT("wsrep", ("update row key"));
if (wsrep_append_keys(m_user_thd, if (wsrep_append_keys(m_user_thd,
@ -8633,14 +8612,11 @@ func_exit:
old_row, new_row)){ old_row, new_row)){
WSREP_DEBUG("WSREP: UPDATE_ROW_KEY FAILED"); WSREP_DEBUG("WSREP: UPDATE_ROW_KEY FAILED");
DBUG_PRINT("wsrep", ("row key failed")); DBUG_PRINT("wsrep", ("row key failed"));
err = HA_ERR_INTERNAL_ERROR; DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
goto wsrep_error;
} }
} }
wsrep_error:
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
DBUG_RETURN(err); DBUG_RETURN(err);
} }
@ -8690,20 +8666,16 @@ ha_innobase::delete_row(
innobase_active_small(); innobase_active_small();
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (error == DB_SUCCESS if (error == DB_SUCCESS && trx->is_wsrep()
&& wsrep_on(m_user_thd)
&& wsrep_thd_is_local(m_user_thd) && wsrep_thd_is_local(m_user_thd)
&& !wsrep_thd_ignore_table(m_user_thd)) { && !wsrep_thd_ignore_table(m_user_thd)) {
if (wsrep_append_keys(m_user_thd, WSREP_SERVICE_KEY_EXCLUSIVE, if (wsrep_append_keys(m_user_thd, WSREP_SERVICE_KEY_EXCLUSIVE,
record, record,
NULL)) { NULL)) {
DBUG_PRINT("wsrep", ("delete fail")); DBUG_PRINT("wsrep", ("delete fail"));
error = (dberr_t) HA_ERR_INTERNAL_ERROR; DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
goto wsrep_error;
} }
} }
wsrep_error:
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
DBUG_RETURN(convert_error_code_to_mysql( DBUG_RETURN(convert_error_code_to_mysql(
error, m_prebuilt->table->flags, m_user_thd)); 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 Wsrep_service_key_type key_type) /*!< in: access type of this key
(shared, exclusive, reference...) */ (shared, exclusive, reference...) */
{ {
ut_a(trx); if (!trx->is_wsrep() || !wsrep_thd_is_local(trx->mysql_thd)) {
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) {
return DB_SUCCESS; return DB_SUCCESS;
} }
if (!thd || !foreign || THD* thd = trx->mysql_thd;
if (!foreign ||
(!foreign->referenced_table && !foreign->foreign_table)) { (!foreign->referenced_table && !foreign->foreign_table)) {
WSREP_INFO("FK: %s missing in: %s", WSREP_INFO("FK: %s missing in: %s",
(!thd) ? "thread" : (!foreign ? "constraint" :
((!foreign) ? "constraint" : (!foreign->referenced_table ?
((!foreign->referenced_table) ?
"referenced table" : "foreign table")), "referenced table" : "foreign table")),
(thd && wsrep_thd_query(thd)) ? wsrep_thd_query(thd));
wsrep_thd_query(thd) : "void");
return DB_ERROR; return DB_ERROR;
} }
ulint rcode = DB_SUCCESS;
char cache_key[513] = {'\0'};
size_t cache_key_len = 0;
if ( !((referenced) ? if ( !((referenced) ?
foreign->referenced_table : foreign->foreign_table)) { foreign->referenced_table : foreign->foreign_table)) {
WSREP_DEBUG("pulling %s table into cache", WSREP_DEBUG("pulling %s table into cache",
@ -11417,10 +11386,17 @@ innobase_fts_load_stopword(
trx_t* trx, /*!< in: transaction */ trx_t* trx, /*!< in: transaction */
THD* thd) /*!< in: current thread */ THD* thd) /*!< in: current thread */
{ {
return(fts_load_stopword(table, trx, const char *stopword_table= THDVAR(thd, ft_user_stopword_table);
innobase_server_stopword_table, if (!stopword_table)
THDVAR(thd, ft_user_stopword_table), {
THDVAR(thd, ft_enable_stopword), FALSE)); 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. /** 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)); DBUG_PRINT("enter",("lock_type: %d", lock_type));
update_thd(thd); update_thd(thd);
trx_t* trx = m_prebuilt->trx; trx_t* trx = m_prebuilt->trx;
ut_ad(m_prebuilt->table); ut_ad(m_prebuilt->table);
/* Statement based binlogging does not work in isolation level /* 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_format(thd) == BINLOG_FORMAT_STMT
&& thd_binlog_filter_ok(thd) && thd_binlog_filter_ok(thd)
&& thd_sqlcom_can_generate_row_events(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 */ /* used by test case */
DBUG_EXECUTE_IF("no_innodb_binlog_errors", skip = true;); DBUG_EXECUTE_IF("no_innodb_binlog_errors", skip = true;);
if (!skip) { 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), my_error(ER_BINLOG_STMT_MODE_AND_ROW_ENGINE, MYF(0),
" InnoDB is limited to row-logging when" " InnoDB is limited to row-logging when"
" transaction isolation level is" " transaction isolation level is"
" READ COMMITTED or READ UNCOMMITTED."); " READ COMMITTED or READ UNCOMMITTED.");
DBUG_RETURN(HA_ERR_LOGGING_IMPOSSIBLE); 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]; char buff[STRING_BUFFER_USUAL_SIZE];
int len = sizeof(buff); int len = sizeof(buff);
trx_t* trx; trx_t* trx;
int ret = 1;
ut_a(save != NULL); ut_a(save != NULL);
ut_a(value != NULL); ut_a(value != NULL);
@ -17600,14 +17568,22 @@ innodb_stopword_table_validate(
/* Validate the stopword table's (if supplied) existence and /* Validate the stopword table's (if supplied) existence and
of the right format */ of the right format */
if (!stopword_table_name int ret = stopword_table_name && !fts_valid_stopword_table(
|| fts_valid_stopword_table(stopword_table_name)) { stopword_table_name);
*static_cast<const char**>(save) = stopword_table_name;
ret = 0;
}
row_mysql_unlock_data_dictionary(trx); 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); 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; static char* innodb_ft_aux_table;
/** Update innodb_ft_aux_table_id on SET GLOBAL 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[out] save new value of innodb_ft_aux_table
@param[in] value user-specified value */ @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) void* save, st_mysql_value* value)
{ {
char buf[STRING_BUFFER_USUAL_SIZE]; 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); dict_table_close(table, FALSE, FALSE);
if (id) { if (id) {
innodb_ft_aux_table_id = 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; *static_cast<const char**>(save) = table_name;
return 0; return 0;
} }
@ -18195,49 +18181,43 @@ exit:
return; return;
} }
#ifdef _WIN32 /** Validate SET GLOBAL innodb_buffer_pool_filename.
/*************************************************************//** On Windows, file names with colon (:) are not allowed.
Validate if passed-in "value" is a valid value for @param thd connection
innodb_buffer_pool_filename. On Windows, file names with colon (:) @param save &srv_buf_dump_filename
are not allowed. @param value new value to be validated
@return 0 for valid name */ @return 0 for valid name */
static static int innodb_srv_buf_dump_filename_validate(THD *thd, st_mysql_sys_var*,
int void *save,
innodb_srv_buf_dump_filename_validate( st_mysql_value *value)
/*==================================*/
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 */
{ {
char buff[OS_FILE_MAX_PATH]; char buff[OS_FILE_MAX_PATH];
int len = sizeof(buff); int len= sizeof buff;
ut_a(save != NULL); if (const char *buf_name= value->val_str(value, buff, &len))
ut_a(value != NULL); {
#ifdef _WIN32
if (const char* buf_name = value->val_str(value, buff, &len)) { if (!is_filename_allowed(buf_name, len, FALSE))
if (is_filename_allowed(buf_name, len, FALSE)){ {
*static_cast<const char**>(save) = buf_name; push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
return(0);
} else {
push_warning_printf(thd,
Sql_condition::WARN_LEVEL_WARN,
ER_WRONG_ARGUMENTS, ER_WRONG_ARGUMENTS,
"InnoDB: innodb_buffer_pool_filename " "InnoDB: innodb_buffer_pool_filename "
"cannot have colon (:) in the file name."); "cannot have colon (:) in the file name.");
return 1;
} }
}
return(1);
}
#else /* _WIN32 */
# define innodb_srv_buf_dump_filename_validate NULL
#endif /* _WIN32 */ #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 #ifdef UNIV_DEBUG
static char* srv_buffer_pool_evict; 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. Evict all uncompressed pages of compressed tables from the buffer pool.
Keep the compressed pages in the buffer pool. Keep the compressed pages in the buffer pool.
@return whether all uncompressed pages were evicted */ @return whether all uncompressed pages were evicted */
static MY_ATTRIBUTE((warn_unused_result)) static bool innodb_buffer_pool_evict_uncompressed()
bool
innodb_buffer_pool_evict_uncompressed()
{ {
bool all_evicted = true; bool all_evicted = true;
@ -18263,8 +18241,13 @@ innodb_buffer_pool_evict_uncompressed()
if (!buf_LRU_free_page(&block->page, false)) { if (!buf_LRU_free_page(&block->page, false)) {
all_evicted = false; all_evicted = false;
}
block = prev_block; 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);
}
} }
mutex_exit(&buf_pool.mutex); mutex_exit(&buf_pool.mutex);

View File

@ -1872,6 +1872,62 @@ innobase_fts_check_doc_id_col(
return(false); 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 /** Check if InnoDB supports a particular alter table in-place
@param altered_table TABLE object for new version of table. @param altered_table TABLE object for new version of table.
@param ha_alter_info Structure describing changes to be done @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); 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 const bool add_drop_v_cols = !!(ha_alter_info->handler_flags
& (ALTER_ADD_VIRTUAL_COLUMN & (ALTER_ADD_VIRTUAL_COLUMN
| ALTER_DROP_VIRTUAL_COLUMN | ALTER_DROP_VIRTUAL_COLUMN
@ -6926,7 +6989,7 @@ op_ok:
goto error_handling; goto error_handling;
} }
trx_commit(ctx->trx); ctx->trx->commit();
trx_start_for_ddl(ctx->trx, op); trx_start_for_ddl(ctx->trx, op);
if (!ctx->new_table->fts if (!ctx->new_table->fts
@ -10877,7 +10940,7 @@ ha_innobase::commit_inplace_alter_table(
} else { } else {
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)); ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
ut_ad(trx->has_logged()); ut_ad(trx->has_logged());
trx_commit(trx); trx->commit();
} }
/* If server crashes here, the dictionary in /* If server crashes here, the dictionary in

View File

@ -115,16 +115,16 @@ dict_stats_deinit(
/** Update the table modification counter and if necessary, /** Update the table modification counter and if necessary,
schedule new estimates for table and index statistics to be calculated. schedule new estimates for table and index statistics to be calculated.
@param[in,out] table persistent or temporary table @param[in,out] table persistent or temporary table
@param[in] thd current session */ @param[in] trx transaction */
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)
MY_ATTRIBUTE((nonnull(1))); MY_ATTRIBUTE((nonnull));
#else #else
/** Update the table modification counter and if necessary, /** Update the table modification counter and if necessary,
schedule new estimates for table and index statistics to be calculated. schedule new estimates for table and index statistics to be calculated.
@param[in,out] table persistent or temporary table */ @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)); 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 #endif
/*********************************************************************//** /*********************************************************************//**

View File

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

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 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 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 */ btr_cur_t* cursor, /*!< in: btr cursor */
mtr_t* mtr); /*!< in: mtr */ 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 */ push a nonleaf index node to the search path */
UNIV_INLINE UNIV_INLINE

View File

@ -980,10 +980,6 @@ std::string
lock_get_info( lock_get_info(
const lock_t*); 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 */ #endif /* WITH_WSREP */
#include "lock0lock.ic" #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 dict_table_t* table, /*!< in: table */
const upd_t* update);/*!< in: update vector for the row */ 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 Updates a row in a table. This is a high-level function used
in SQL execution graphs. in SQL execution graphs.

View File

@ -180,17 +180,6 @@ trx_start_for_ddl_low(
trx_start_for_ddl_low((t), (o)) trx_start_for_ddl_low((t), (o))
#endif /* UNIV_DEBUG */ #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. Does the transaction commit for MySQL.
@return DB_SUCCESS or error number */ @return DB_SUCCESS or error number */
@ -839,6 +828,13 @@ public:
Transitions to COMMITTED are protected by trx_t::mutex. */ Transitions to COMMITTED are protected by trx_t::mutex. */
trx_state_t state; 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 ReadView read_view; /*!< consistent read view used in the
transaction, or NULL if not yet set */ transaction, or NULL if not yet set */
@ -890,10 +886,10 @@ public:
defer flush of the logs to disk defer flush of the logs to disk
until after we release the until after we release the
mutex. */ mutex. */
bool must_flush_log_later;/*!< this flag is set to TRUE in bool must_flush_log_later;/*!< set in commit()
trx_commit() if flush_log_later was if flush_log_later was
TRUE, and there were modifications by set and redo log was written;
the transaction; in that case we must in that case we will
flush the log in flush the log in
trx_commit_complete_for_mysql() */ trx_commit_complete_for_mysql() */
ulint duplicates; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */ ulint duplicates; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */
@ -1105,11 +1101,22 @@ public:
@param[in] table_id table identifier */ @param[in] table_id table identifier */
void evict_table(table_id_t table_id); 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()
{ bool is_referenced() const { return n_ref > 0; }
return n_ref > 0;
}
void reference() void reference()

View File

@ -1073,9 +1073,7 @@ wsrep_kill_victim(
ut_ad(trx_mutex_own(lock->trx)); ut_ad(trx_mutex_own(lock->trx));
/* quit for native mysql */ /* quit for native mysql */
if (!wsrep_on(trx->mysql_thd)) { if (!trx->is_wsrep()) return;
return;
}
if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { if (!wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
return; return;
@ -1157,7 +1155,7 @@ lock_rec_other_has_conflicting(
if (lock_rec_has_to_wait(true, trx, mode, lock, is_supremum)) { if (lock_rec_has_to_wait(true, trx, mode, lock, is_supremum)) {
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (wsrep_on_trx(trx)) { if (trx->is_wsrep()) {
trx_mutex_enter(lock->trx); trx_mutex_enter(lock->trx);
/* Below function will roll back either trx /* Below function will roll back either trx
or lock->trx depending on priority of the 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); ut_ad(index->table->get_ref_count() > 0 || !index->table->can_be_evicted);
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (c_lock && wsrep_on_trx(trx) if (c_lock && trx->is_wsrep()
&& wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
lock_t *hash = (lock_t *)c_lock->hash; lock_t *hash = (lock_t *)c_lock->hash;
lock_t *prev = NULL; lock_t *prev = NULL;
@ -1805,8 +1803,7 @@ lock_rec_add_to_queue(
#ifdef WITH_WSREP #ifdef WITH_WSREP
//ut_a(!other_lock || (wsrep_thd_is_BF(trx->mysql_thd, FALSE) && //ut_a(!other_lock || (wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
// wsrep_thd_is_BF(other_lock->trx->mysql_thd, TRUE))); // wsrep_thd_is_BF(other_lock->trx->mysql_thd, TRUE)));
if (other_lock && if (other_lock && trx->is_wsrep() &&
wsrep_on(trx->mysql_thd) &&
!wsrep_thd_is_BF(trx->mysql_thd, FALSE) && !wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
!wsrep_thd_is_BF(other_lock->trx->mysql_thd, TRUE)) { !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); UT_LIST_ADD_LAST(trx->lock.trx_locks, lock);
#ifdef WITH_WSREP #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)) { if (wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
ut_list_insert(table->locks, c_lock, lock, ut_list_insert(table->locks, c_lock, lock,
TableLockGetNode()); TableLockGetNode());
@ -3732,7 +3729,7 @@ lock_table_enqueue_waiting(
} }
#ifdef WITH_WSREP #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); return(DB_DEADLOCK);
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
@ -3805,7 +3802,7 @@ lock_table_other_has_incompatible(
&& (wait || !lock_get_wait(lock))) { && (wait || !lock_get_wait(lock))) {
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (wsrep_on(lock->trx->mysql_thd)) { if (lock->trx->is_wsrep()) {
if (wsrep_debug) { if (wsrep_debug) {
ib::info() << "WSREP: table lock abort for table:" ib::info() << "WSREP: table lock abort for table:"
<< table->name.m_name; << table->name.m_name;
@ -4872,7 +4869,7 @@ func_exit:
explicit granted lock. */ explicit granted lock. */
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (wsrep_on(other_lock->trx->mysql_thd)) { if (other_lock->trx->is_wsrep()) {
if (!lock_get_wait(other_lock) ) { if (!lock_get_wait(other_lock) ) {
ib::info() << "WSREP impl BF lock conflict for my impl lock:\n BF:" << 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: " << ((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"); print("*** WE ROLL BACK TRANSACTION (1)\n");
#ifdef WITH_WSREP #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); wsrep_handle_SR_rollback(m_start->mysql_thd, trx->mysql_thd);
} }
#endif #endif
@ -6847,8 +6844,7 @@ DeadlockChecker::check_and_resolve(const lock_t* lock, trx_t* trx)
print("*** WE ROLL BACK TRANSACTION (2)\n"); print("*** WE ROLL BACK TRANSACTION (2)\n");
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (wsrep_on(trx->mysql_thd) if (trx->is_wsrep() && wsrep_thd_is_SR(trx->mysql_thd)) {
&& wsrep_thd_is_SR(trx->mysql_thd)) {
wsrep_handle_SR_rollback(trx->mysql_thd, wsrep_handle_SR_rollback(trx->mysql_thd,
victim_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) 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 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 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, const trx_t* trx,
bool locked = true) bool locked = true)
{ {
if (wsrep_on_trx(trx) if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)
&& wsrep_thd_is_BF(trx->mysql_thd, FALSE)
&& trx->error_state != DB_DEADLOCK) { && trx->error_state != DB_DEADLOCK) {
ib::info() << "WSREP: BF lock wait long for trx:" << ib::hex(trx->id) ib::info() << "WSREP: BF lock wait long for trx:" << ib::hex(trx->id)
<< " query: " << wsrep_thd_query(trx->mysql_thd); << " query: " << wsrep_thd_query(trx->mysql_thd);
@ -403,8 +402,9 @@ lock_wait_suspend_thread(
if (lock_wait_timeout < 100000000 if (lock_wait_timeout < 100000000
&& wait_time > (double) lock_wait_timeout && wait_time > (double) lock_wait_timeout
#ifdef WITH_WSREP #ifdef WITH_WSREP
&& (!wsrep_on_trx(trx) || && (!trx->is_wsrep()
(!wsrep_is_BF_lock_timeout(trx, false) && trx->error_state != DB_DEADLOCK)) || (!wsrep_is_BF_lock_timeout(trx, false)
&& trx->error_state != DB_DEADLOCK))
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
) { ) {

View File

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

View File

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

View File

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

View File

@ -1399,8 +1399,8 @@ rollback_clust:
already be holding dict_sys.mutex, which already be holding dict_sys.mutex, which
would be acquired when updating statistics. */ would be acquired when updating statistics. */
if (update_statistics && !dict_locked) { if (update_statistics && !dict_locked) {
dict_stats_update_if_needed( dict_stats_update_if_needed(node->table,
node->table, node->trx->mysql_thd); *node->trx);
} else { } else {
node->table->stat_modified_counter++; 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) 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 false;
} }
return que_node_get_type(node->common.parent) != QUE_NODE_UPDATE 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] thd mysql thread handle
@param[in,out] mysql_table NULL, or mysql table object when @param[in,out] mysql_table NULL, or mysql table object when
user thread invokes dml */ user thread invokes dml */
static
void void
row_upd_store_row( row_upd_store_row(
upd_node_t* node, upd_node_t* node,
@ -2498,9 +2499,8 @@ check_fk:
mtr_commit(mtr); mtr_commit(mtr);
err = row_ins_clust_index_entry(index, entry, thr, node->upd_ext err = row_ins_clust_index_entry(index, entry, thr,
? node->upd_ext->n_ext dtuple_get_n_ext(entry));
: dtuple_get_n_ext(entry));
node->state = UPD_NODE_INSERT_CLUSTERED; node->state = UPD_NODE_INSERT_CLUSTERED;
mem_heap_free(heap); 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 /** Check a virtual column value index secondary virtual index matches
that of current cluster index record, which is recreated from information that of current cluster index record, which is recreated from information
stored in undo log stored in undo log
@param[in] in_purge called by purge thread
@param[in] rec record in the clustered index @param[in] rec record in the clustered index
@param[in] icentry the index entry built from a cluster row @param[in] icentry the index entry built from a cluster row
@param[in] clust_index cluster index @param[in] clust_index cluster index
@ -622,7 +621,6 @@ stored in undo log
static static
bool bool
row_vers_vc_matches_cluster( row_vers_vc_matches_cluster(
bool in_purge,
const rec_t* rec, const rec_t* rec,
const dtuple_t* icentry, const dtuple_t* icentry,
dict_index_t* clust_index, dict_index_t* clust_index,
@ -683,12 +681,6 @@ row_vers_vc_matches_cluster(
version = rec; 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) { while (n_cmp_v_col < n_fields - n_non_v_col) {
heap2 = heap; heap2 = heap;
heap = mem_heap_create(1024); heap = mem_heap_create(1024);
@ -696,11 +688,12 @@ row_vers_vc_matches_cluster(
version, clust_index, clust_offsets); version, clust_index, clust_offsets);
ut_ad(cur_roll_ptr != 0); ut_ad(cur_roll_ptr != 0);
ut_ad(in_purge == (roll_ptr != 0)); ut_ad(roll_ptr != 0);
trx_undo_prev_version_build( trx_undo_prev_version_build(
rec, mtr, version, clust_index, clust_offsets, 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) { if (heap2) {
mem_heap_free(heap2); mem_heap_free(heap2);
@ -958,7 +951,7 @@ row_vers_old_has_index_entry(
secondary indexes.) */ secondary indexes.) */
if (entry && row_vers_vc_matches_cluster( if (entry && row_vers_vc_matches_cluster(
also_curr, rec, entry, rec, entry,
clust_index, clust_offsets, clust_index, clust_offsets,
index, ientry, roll_ptr, index, ientry, roll_ptr,
trx_id, NULL, &vrow, mtr)) { 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) 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 Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described Google, Inc. Those modifications are gratefully acknowledged and are described
@ -119,8 +119,7 @@ srv_conc_enter_innodb_with_atomics(
for (;;) { for (;;) {
ulint sleep_in_us; ulint sleep_in_us;
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (wsrep_on(trx->mysql_thd) && if (trx->is_wsrep() && wsrep_thd_is_aborting(trx->mysql_thd)) {
wsrep_thd_is_aborting(trx->mysql_thd)) {
if (wsrep_get_debug()) { if (wsrep_get_debug()) {
ib::info() << ib::info() <<
"srv_conc_enter due to MUST_ABORT"; "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; const trx_t* trx_roll_crash_recv_trx;
/** Finish transaction rollback. /** Finish transaction rollback.
@param[in,out] trx transaction
@return whether the rollback was completed normally @return whether the rollback was completed normally
@retval false if the rollback was aborted by shutdown */ @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(); mod_tables.clear();
bool finished = trx->error_state == DB_SUCCESS; if (UNIV_LIKELY(error_state == DB_SUCCESS))
if (UNIV_LIKELY(finished)) { {
trx_commit(trx); commit();
} else { return true;
ut_a(trx->error_state == DB_INTERRUPTED); }
ut_a(error_state == DB_INTERRUPTED);
ut_ad(!srv_is_being_started); ut_ad(!srv_is_being_started);
ut_a(!srv_undo_sources); ut_a(!srv_undo_sources);
ut_ad(srv_fast_shutdown); ut_ad(srv_fast_shutdown);
ut_d(trx->in_rollback = false); ut_d(in_rollback= false);
if (trx_undo_t*& undo = trx->rsegs.m_redo.old_insert) { if (trx_undo_t *&undo= rsegs.m_redo.old_insert)
UT_LIST_REMOVE(trx->rsegs.m_redo.rseg->old_insert_list, {
undo); UT_LIST_REMOVE(rsegs.m_redo.rseg->old_insert_list, undo);
ut_free(undo); ut_free(undo);
undo = NULL; undo= nullptr;
} }
if (trx_undo_t*& undo = trx->rsegs.m_redo.undo) { if (trx_undo_t *&undo= rsegs.m_redo.undo)
UT_LIST_REMOVE(trx->rsegs.m_redo.rseg->undo_list, {
undo); UT_LIST_REMOVE(rsegs.m_redo.rseg->undo_list, undo);
ut_free(undo); ut_free(undo);
undo = NULL; undo= nullptr;
} }
if (trx_undo_t*& undo = trx->rsegs.m_noredo.undo) { if (trx_undo_t *&undo= rsegs.m_noredo.undo)
UT_LIST_REMOVE(trx->rsegs.m_noredo.rseg->undo_list, {
undo); UT_LIST_REMOVE(rsegs.m_noredo.rseg->undo_list, undo);
ut_free(undo); ut_free(undo);
undo = NULL; undo= nullptr;
} }
trx_commit_low(trx, NULL); commit_low();
} lock.que_state = TRX_QUE_RUNNING;
return false;
trx->lock.que_state = TRX_QUE_RUNNING;
return finished;
} }
/*******************************************************************//** /*******************************************************************//**
@ -144,8 +142,8 @@ trx_rollback_to_savepoint_low(
roll_node->undo_thr->common.parent)); roll_node->undo_thr->common.parent));
} }
if (savept == NULL) { if (!savept) {
trx_rollback_finish(trx); trx->rollback_finish();
MONITOR_INC(MONITOR_TRX_ROLLBACK); MONITOR_INC(MONITOR_TRX_ROLLBACK);
} else { } else {
ut_a(trx->error_state == DB_SUCCESS); ut_a(trx->error_state == DB_SUCCESS);
@ -182,8 +180,7 @@ trx_rollback_to_savepoint(
complete rollback */ complete rollback */
{ {
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (savept == NULL && wsrep_on(trx->mysql_thd) if (!savept && trx->is_wsrep() && wsrep_thd_is_SR(trx->mysql_thd)) {
&& wsrep_thd_is_SR(trx->mysql_thd)) {
wsrep_handle_SR_rollback(NULL, trx->mysql_thd); wsrep_handle_SR_rollback(NULL, trx->mysql_thd);
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
@ -454,7 +451,7 @@ trx_rollback_to_savepoint_for_mysql_low(
trx->op_info = ""; trx->op_info = "";
#ifdef WITH_WSREP #ifdef WITH_WSREP
trx->lock.was_chosen_as_wsrep_victim = FALSE; trx->lock.was_chosen_as_wsrep_victim = false;
#endif #endif
return(err); return(err);
} }
@ -668,7 +665,7 @@ trx_rollback_active(
que_graph_free( que_graph_free(
static_cast<que_t*>(roll_node->undo_thr->common.parent)); 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); ut_ad(!dictionary_locked);
goto func_exit; goto func_exit;
} }

View File

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

View File

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