Skip to content

Commit 99556d0

Browse files
Merge branch 'mysql-5.6' into mysql-5.7
2 parents 6b02940 + 7476823 commit 99556d0

20 files changed

+523
-73
lines changed
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#
2+
# Bug #19183565 CREATE DYNAMIC INNODB_TMPDIR VARIABLE TO CONTROL
3+
# WHERE INNODB WRITES TEMP FILES
4+
#
5+
# If innodb_tmpdir is NULL or "", temporary file will be created in
6+
# server configuration variable location(--tmpdir)
7+
create table t1(a int primary key)engine=innodb;
8+
show session variables like 'innodb_tmpdir';
9+
Variable_name Value
10+
innodb_tmpdir
11+
alter table t1 add column b int not null;
12+
set global innodb_tmpdir=NULL;
13+
# Connection con1
14+
show session variables like 'innodb_tmpdir';
15+
Variable_name Value
16+
innodb_tmpdir
17+
alter table t1 add key(b);
18+
drop table t1;
19+
# innodb_tmpdir with invalid path.
20+
create table t1(a int primary key)engine=innodb;
21+
set global innodb_tmpdir='wrong_value';
22+
ERROR 42000: Variable 'innodb_tmpdir' can't be set to the value of 'wrong_value'
23+
show warnings;
24+
Level Code Message
25+
Warning 1210 InnoDB: Path doesn't exist.
26+
Error 1231 Variable 'innodb_tmpdir' can't be set to the value of 'wrong_value'
27+
drop table t1;
28+
# innodb_tmpdir with mysql data directory path.
29+
create table t1(a text, b text, fulltext(a,b))engine=innodb;
30+
insert into t1 values('test1', 'test2');
31+
insert into t1 values('text1', 'text2');
32+
set global innodb_tmpdir = @@global.datadir;
33+
ERROR 42000: Variable 'innodb_tmpdir' can't be set to the value of 'MYSQL_DATADIR'
34+
show warnings;
35+
Level Code Message
36+
Warning 1210 InnoDB: Path location should not be same as mysql data directory location.
37+
Error 1231 DATADIR/data/'
38+
drop table t1;
39+
# innodb_tmpdir with valid location.
40+
create table t1(a text, b text, fulltext(a,b))engine=innodb;
41+
insert into t1 values('test1', 'test2');
42+
insert into t1 values('text1', 'text2');
43+
set @tmpdir = @@global.tmpdir;
44+
set global innodb_tmpdir = @tmpdir;
45+
show session variables like 'innodb_tmpdir';
46+
Variable_name Value
47+
innodb_tmpdir
48+
# Connection con3
49+
show session variables like 'innodb_tmpdir';
50+
Variable_name Value
51+
innodb_tmpdir mysqld.1
52+
alter table t1 add fulltext(b);
53+
set global innodb_tmpdir=NULL;
54+
drop table t1;

mysql-test/suite/innodb/t/tmpdir.test

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
--source include/have_innodb.inc
2+
--source include/count_sessions.inc
3+
4+
--echo #
5+
--echo # Bug #19183565 CREATE DYNAMIC INNODB_TMPDIR VARIABLE TO CONTROL
6+
--echo # WHERE INNODB WRITES TEMP FILES
7+
--echo #
8+
9+
--echo # If innodb_tmpdir is NULL or "", temporary file will be created in
10+
--echo # server configuration variable location(--tmpdir)
11+
12+
create table t1(a int primary key)engine=innodb;
13+
show session variables like 'innodb_tmpdir';
14+
alter table t1 add column b int not null;
15+
set global innodb_tmpdir=NULL;
16+
--echo # Connection con1
17+
connect (con1,localhost,root);
18+
show session variables like 'innodb_tmpdir';
19+
alter table t1 add key(b);
20+
connection default;
21+
disconnect con1;
22+
drop table t1;
23+
24+
--echo # innodb_tmpdir with invalid path.
25+
26+
create table t1(a int primary key)engine=innodb;
27+
--error ER_WRONG_VALUE_FOR_VAR
28+
set global innodb_tmpdir='wrong_value';
29+
show warnings;
30+
drop table t1;
31+
32+
33+
--echo # innodb_tmpdir with mysql data directory path.
34+
35+
let $MYSQLD_DATADIR= `select @@datadir`;
36+
create table t1(a text, b text, fulltext(a,b))engine=innodb;
37+
insert into t1 values('test1', 'test2');
38+
insert into t1 values('text1', 'text2');
39+
--replace_result $MYSQLD_DATADIR MYSQL_DATADIR
40+
--error ER_WRONG_VALUE_FOR_VAR
41+
set global innodb_tmpdir = @@global.datadir;
42+
--replace_regex /.*mysqld.1*/DATADIR/
43+
show warnings;
44+
drop table t1;
45+
46+
--echo # innodb_tmpdir with valid location.
47+
let $MYSQL_TMP_DIR= `select @@tmpdir`;
48+
create table t1(a text, b text, fulltext(a,b))engine=innodb;
49+
insert into t1 values('test1', 'test2');
50+
insert into t1 values('text1', 'text2');
51+
set @tmpdir = @@global.tmpdir;
52+
set global innodb_tmpdir = @tmpdir;
53+
show session variables like 'innodb_tmpdir';
54+
--echo # Connection con3
55+
connect (con3,localhost,root);
56+
--replace_regex /.*mysqld.1/mysqld.1/
57+
show session variables like 'innodb_tmpdir';
58+
alter table t1 add fulltext(b);
59+
disconnect con3;
60+
connection default;
61+
set global innodb_tmpdir=NULL;
62+
drop table t1;
63+
64+
--source include/wait_until_count_sessions.inc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
SET @start_global_value = @@global.innodb_tmpdir;
2+
SELECT @start_global_value;
3+
@start_global_value
4+
NULL
5+
select @@session.innodb_tmpdir;
6+
@@session.innodb_tmpdir
7+
NULL
8+
show global variables like 'innodb_tmpdir';
9+
Variable_name Value
10+
innodb_tmpdir
11+
show session variables like 'innodb_tmpdir';
12+
Variable_name Value
13+
innodb_tmpdir
14+
select * from information_schema.global_variables where variable_name='innodb_tmpdir';
15+
VARIABLE_NAME VARIABLE_VALUE
16+
INNODB_TMPDIR
17+
Warnings:
18+
Warning 1287 'INFORMATION_SCHEMA.GLOBAL_VARIABLES' is deprecated and will be removed in a future release. Please use performance_schema.global_variables instead
19+
select * from information_schema.session_variables where variable_name='innodb_tmpdir';
20+
VARIABLE_NAME VARIABLE_VALUE
21+
INNODB_TMPDIR
22+
Warnings:
23+
Warning 1287 'INFORMATION_SCHEMA.SESSION_VARIABLES' is deprecated and will be removed in a future release. Please use performance_schema.session_variables instead
24+
set global innodb_tmpdir=@@global.tmpdir;
25+
set session innodb_tmpdir=@@global.tmpdir;
26+
set global innodb_tmpdir=1.1;
27+
ERROR 42000: Incorrect argument type to variable 'innodb_tmpdir'
28+
set global innodb_tmpdir=1e1;
29+
ERROR 42000: Incorrect argument type to variable 'innodb_tmpdir'
30+
set global innodb_tmpdir=repeat('a',1000);
31+
ERROR 42000: Variable 'innodb_tmpdir' can't be set to the value of 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
32+
show warnings;
33+
Level Code Message
34+
Warning 1210 Path length should not exceed 512 bytes
35+
Error 1231 Variable 'innodb_tmpdir' can't be set to the value of 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
36+
SET @@global.innodb_tmpdir = @start_global_value;
37+
SELECT @@global.innodb_tmpdir;
38+
@@global.innodb_tmpdir
39+
NULL
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--source include/have_innodb.inc
2+
3+
SET @start_global_value = @@global.innodb_tmpdir;
4+
SELECT @start_global_value;
5+
6+
#
7+
# exists as global and session
8+
#
9+
select @@session.innodb_tmpdir;
10+
11+
show global variables like 'innodb_tmpdir';
12+
show session variables like 'innodb_tmpdir';
13+
14+
select * from information_schema.global_variables where variable_name='innodb_tmpdir';
15+
select * from information_schema.session_variables where variable_name='innodb_tmpdir';
16+
#
17+
# Show that it is writable
18+
#
19+
20+
set global innodb_tmpdir=@@global.tmpdir;
21+
set session innodb_tmpdir=@@global.tmpdir;
22+
23+
#
24+
# incorrect types
25+
#
26+
--error ER_WRONG_TYPE_FOR_VAR
27+
set global innodb_tmpdir=1.1;
28+
--error ER_WRONG_TYPE_FOR_VAR
29+
set global innodb_tmpdir=1e1;
30+
31+
#
32+
# path len more than 512
33+
#
34+
--error ER_WRONG_VALUE_FOR_VAR
35+
set global innodb_tmpdir=repeat('a',1000);
36+
show warnings;
37+
38+
#
39+
# Cleanup
40+
#
41+
42+
SET @@global.innodb_tmpdir = @start_global_value;
43+
SELECT @@global.innodb_tmpdir;

sql/sql_class.cc

+2-20
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "sql_prepare.h" // Prepared_statement
4646
#include "sql_time.h" // my_timeval_trunc
4747
#include "sql_timer.h" // thd_timer_destroy
48+
#include "sql_thd_internal_api.h"
4849
#include "transaction.h" // trans_rollback
4950
#ifdef HAVE_REPLICATION
5051
#include "rpl_rli_pdb.h" // Slave_worker
@@ -728,26 +729,7 @@ ulong get_max_connections(void)
728729

729730
extern "C" int mysql_tmpfile(const char *prefix)
730731
{
731-
char filename[FN_REFLEN];
732-
File fd = create_temp_file(filename, mysql_tmpdir, prefix,
733-
#ifdef _WIN32
734-
O_BINARY | O_TRUNC | O_SEQUENTIAL |
735-
O_SHORT_LIVED |
736-
#endif /* _WIN32 */
737-
O_CREAT | O_EXCL | O_RDWR | O_TEMPORARY,
738-
MYF(MY_WME));
739-
if (fd >= 0) {
740-
#ifndef _WIN32
741-
/*
742-
This can be removed once the following bug is fixed:
743-
Bug #28903 create_temp_file() doesn't honor O_TEMPORARY option
744-
(file not removed) (Unix)
745-
*/
746-
unlink(filename);
747-
#endif /* !_WIN32 */
748-
}
749-
750-
return fd;
732+
return mysql_tmpfile_path(mysql_tmpdir, prefix);
751733
}
752734

753735

sql/sql_thd_internal_api.cc

+53
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,56 @@ void thd_set_thread_stack(THD *thd, const char *stack_start)
8585
{
8686
thd->thread_stack= stack_start;
8787
}
88+
89+
bool is_mysql_datadir_path(const char *path)
90+
{
91+
if (path == NULL || strlen(path) >= FN_REFLEN)
92+
return false;
93+
94+
char mysql_data_dir[FN_REFLEN], path_dir[FN_REFLEN];
95+
convert_dirname(path_dir, path, NullS);
96+
convert_dirname(mysql_data_dir, mysql_unpacked_real_data_home, NullS);
97+
size_t mysql_data_home_len= dirname_length(mysql_data_dir);
98+
size_t path_len= dirname_length(path_dir);
99+
100+
if (path_len < mysql_data_home_len)
101+
return true;
102+
103+
if (!lower_case_file_system)
104+
return memcmp(mysql_data_dir, path_dir, mysql_data_home_len);
105+
106+
return files_charset_info->coll->strnncoll(files_charset_info,
107+
reinterpret_cast<uchar*>(path_dir),
108+
path_len,
109+
reinterpret_cast<uchar*>(mysql_data_dir),
110+
mysql_data_home_len,
111+
TRUE);
112+
}
113+
114+
115+
int mysql_tmpfile_path(const char *path, const char *prefix)
116+
{
117+
DBUG_ASSERT(path != NULL);
118+
DBUG_ASSERT((strlen(path) + strlen(prefix)) <= FN_REFLEN);
119+
120+
char filename[FN_REFLEN];
121+
File fd = create_temp_file(filename, path, prefix,
122+
#ifdef _WIN32
123+
O_BINARY | O_TRUNC | O_SEQUENTIAL |
124+
O_SHORT_LIVED |
125+
#endif /* _WIN32 */
126+
O_CREAT | O_EXCL | O_RDWR | O_TEMPORARY,
127+
MYF(MY_WME));
128+
if (fd >= 0) {
129+
#ifndef _WIN32
130+
/*
131+
This can be removed once the following bug is fixed:
132+
Bug #28903 create_temp_file() doesn't honor O_TEMPORARY option
133+
(file not removed) (Unix)
134+
*/
135+
unlink(filename);
136+
#endif /* !_WIN32 */
137+
}
138+
139+
return fd;
140+
}

sql/sql_thd_internal_api.h

+28
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,32 @@ void destroy_thd(THD *thd);
7171
*/
7272
void thd_set_thread_stack(THD *thd, const char *stack_start);
7373

74+
/**
75+
Test a file path whether it is same as mysql data directory path.
76+
77+
@param path null terminated character string
78+
79+
@return
80+
@retval true The path is different from mysql data directory.
81+
@retval false The path is same as mysql data directory.
82+
*/
83+
bool is_mysql_datadir_path(const char *path);
84+
85+
/**
86+
Create a temporary file.
87+
88+
@details
89+
The temporary file is created in a location specified by the parameter
90+
path. if path is null, then it will be created on the location given
91+
by the mysql server configuration (--tmpdir option). The caller
92+
does not need to delete the file, it will be deleted automatically.
93+
94+
@param path location for creating temporary file
95+
@param prefix prefix for temporary file name
96+
@retval -1 error
97+
@retval >=0 a file handle that can be passed to dup or my_close
98+
*/
99+
100+
int mysql_tmpfile_path(const char *path, const char *prefix);
101+
74102
#endif // SQL_THD_INTERNAL_API_INCLUDED

storage/innobase/dict/dict0dict.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1184,7 +1184,7 @@ dict_init(void)
11841184
dict_operation_lock, SYNC_DICT_OPERATION);
11851185

11861186
if (!srv_read_only_mode) {
1187-
dict_foreign_err_file = os_file_create_tmpfile();
1187+
dict_foreign_err_file = os_file_create_tmpfile(NULL);
11881188
ut_a(dict_foreign_err_file);
11891189
}
11901190

0 commit comments

Comments
 (0)