Skip to content

Commit 5afd594

Browse files
gkodinovbjornmu
authored andcommitted
Bug #20504142 MYSQLD OPTION --INITIALIZE SHOULD WORK WITH EMPTY DATADIR
Added an empty writable data directory as an acceptable destination for --initialize. Test case added. (cherry picked from commit 6d46ebccd08510774d4dee7897a39fa69213f66c)
1 parent 0e2b51a commit 5afd594

File tree

5 files changed

+290
-21
lines changed

5 files changed

+290
-21
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# We don't care about innodb warnings at this point
2+
CALL mtr.add_suppression("InnoDB:");
3+
# Save the count of columns in mysql
4+
# shut server down
5+
# Server is down
6+
#
7+
# Start of test for Bug #20504142
8+
# MYSQLD OPTION --INITIALIZE SHOULD WORK WITH EMPTY DATADIR
9+
#
10+
#
11+
# Try --initialize-insecure with an existing empty data dir
12+
#
13+
# create bootstrap file
14+
# make the data dir
15+
# Run the server with --initialize-insecure
16+
# Restart the server against DDIR
17+
# connect as root
18+
# must pass: no password expiration
19+
SELECT 1;
20+
1
21+
1
22+
# shut server down
23+
# Server is down
24+
# close the test connection
25+
# delete mysqld log
26+
# delete bootstrap file
27+
# delete datadir
28+
#
29+
# Try --initialize-insecure with an exising non-empty data dir
30+
#
31+
# make the data dir
32+
# add afile to the data dir
33+
# Run the server with --initialize-insecure
34+
# look for the mysql directory. should not be there
35+
# delete mysqld log
36+
# delete datadir
37+
#
38+
# Try --initialize-insecure with an exising file as datadir
39+
#
40+
# add a file as the data dir
41+
# Run the server with --initialize-insecure
42+
# delete mysqld log
43+
# delete datadir
44+
#
45+
# End of test for Bug #20504142
46+
# MYSQLD OPTION --INITIALIZE SHOULD WORK WITH EMPTY DATADIR
47+
#
48+
#
49+
# Cleanup
50+
#
51+
# Restarting the server
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
--source include/big_test.inc
2+
--source include/not_embedded.inc
3+
--source include/have_no_undo_tablespaces.inc
4+
5+
6+
let BASEDIR= `select @@basedir`;
7+
let DDIR=$MYSQL_TMP_DIR/installdb_test;
8+
let MYSQLD_LOG=$MYSQL_TMP_DIR/server.log;
9+
let extra_args=--no-defaults --console --log-syslog=0 --loose-skip-auto_generate_certs --loose-skip-sha256_password_auto_generate_rsa_keys --skip-ssl --basedir=$BASEDIR --lc-messages-dir=$MYSQL_SHAREDIR;
10+
let BOOTSTRAP_SQL=$MYSQL_TMP_DIR/tiny_bootstrap.sql;
11+
let PASSWD_FILE=$MYSQL_TMP_DIR/password_file.txt;
12+
13+
--echo # We don't care about innodb warnings at this point
14+
CALL mtr.add_suppression("InnoDB:");
15+
16+
--echo # Save the count of columns in mysql
17+
--let $mysql_cnt=`SELECT COUNT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='mysql'`
18+
19+
--echo # shut server down
20+
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
21+
--shutdown_server
22+
--source include/wait_until_disconnected.inc
23+
--echo # Server is down
24+
25+
26+
--echo #
27+
--echo # Start of test for Bug #20504142
28+
--echo # MYSQLD OPTION --INITIALIZE SHOULD WORK WITH EMPTY DATADIR
29+
--echo #
30+
31+
--echo #
32+
--echo # Try --initialize-insecure with an existing empty data dir
33+
--echo #
34+
35+
--echo # create bootstrap file
36+
write_file $BOOTSTRAP_SQL;
37+
CREATE DATABASE test;
38+
CREATE TABLE mysql.t1(a INT) ENGINE=innodb;
39+
INSERT INTO mysql.t1 VALUES (1);
40+
INSERT INTO mysql.t1 VALUES (2);
41+
EOF
42+
43+
--echo # make the data dir
44+
mkdir $DDIR;
45+
46+
--echo # Run the server with --initialize-insecure
47+
--exec $MYSQLD $extra_args --initialize-insecure --datadir=$DDIR --init-file=$BOOTSTRAP_SQL > $MYSQLD_LOG 2>&1
48+
49+
50+
--echo # Restart the server against DDIR
51+
--exec echo "restart:--datadir=$DDIR " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
52+
--enable_reconnect
53+
--source include/wait_until_connected_again.inc
54+
55+
--echo # connect as root
56+
connect(root_con,localhost,root,,mysql);
57+
58+
--echo # must pass: no password expiration
59+
SELECT 1;
60+
61+
--echo # shut server down
62+
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
63+
--shutdown_server
64+
--source include/wait_until_disconnected.inc
65+
--echo # Server is down
66+
67+
--echo # close the test connection
68+
connection default;
69+
disconnect root_con;
70+
71+
--echo # delete mysqld log
72+
remove_file $MYSQLD_LOG;
73+
74+
--echo # delete bootstrap file
75+
remove_file $BOOTSTRAP_SQL;
76+
77+
--echo # delete datadir
78+
--perl
79+
use File::Path 'rmtree';
80+
$DDIR=$ENV{"DDIR"};
81+
rmtree([ "$DDIR" ]);
82+
EOF
83+
84+
85+
--echo #
86+
--echo # Try --initialize-insecure with an exising non-empty data dir
87+
--echo #
88+
89+
--echo # make the data dir
90+
mkdir $DDIR;
91+
92+
let $AFILE=$DDIR/afile;
93+
94+
--echo # add afile to the data dir
95+
write_file $AFILE;
96+
some text
97+
EOF
98+
99+
--echo # Run the server with --initialize-insecure
100+
--error 1
101+
--exec $MYSQLD $extra_args --initialize-insecure --datadir=$DDIR > $MYSQLD_LOG 2>&1
102+
103+
--echo # look for the mysql directory. should not be there
104+
perl;
105+
use strict;
106+
my $mysqldir="$ENV{'DDIR'}/mysql";
107+
if (opendir(my $dh, $mysqldir))
108+
{
109+
print "Data directory $mysqldir not empty\n";
110+
closedir($dh);
111+
}
112+
EOF
113+
114+
--echo # delete mysqld log
115+
remove_file $MYSQLD_LOG;
116+
117+
--echo # delete datadir
118+
--perl
119+
use File::Path 'rmtree';
120+
$DDIR=$ENV{"DDIR"};
121+
rmtree([ "$DDIR" ]);
122+
EOF
123+
124+
125+
--echo #
126+
--echo # Try --initialize-insecure with an exising file as datadir
127+
--echo #
128+
129+
--echo # add a file as the data dir
130+
write_file $DDIR;
131+
some text
132+
EOF
133+
134+
--echo # Run the server with --initialize-insecure
135+
--error 1
136+
--exec $MYSQLD $extra_args --initialize-insecure --datadir=$DDIR > $MYSQLD_LOG 2>&1
137+
138+
--echo # delete mysqld log
139+
remove_file $MYSQLD_LOG;
140+
141+
--echo # delete datadir
142+
--perl
143+
use File::Path 'rmtree';
144+
$DDIR=$ENV{"DDIR"};
145+
rmtree([ "$DDIR" ]);
146+
EOF
147+
148+
--echo #
149+
--echo # End of test for Bug #20504142
150+
--echo # MYSQLD OPTION --INITIALIZE SHOULD WORK WITH EMPTY DATADIR
151+
--echo #
152+
153+
154+
--echo #
155+
--echo # Cleanup
156+
--echo #
157+
--echo # Restarting the server
158+
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
159+
--enable_reconnect
160+
--source include/wait_until_connected_again.inc

sql/mysqld.cc

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3154,27 +3154,9 @@ int init_common_variables()
31543154
return 1;
31553155

31563156
/* create the data directory if requested */
3157-
if (unlikely(opt_initialize))
3158-
{
3159-
MY_STAT dummy_stat;
3160-
int flags=
3161-
#ifdef _WIN32
3162-
0
3163-
#else
3164-
S_IRWXU | S_IRGRP | S_IXGRP
3165-
#endif
3166-
;
3167-
3168-
if (my_stat(mysql_real_data_home, &dummy_stat, MYF(0)))
3169-
{
3170-
sql_print_error("--initialize specified but the data directory exists. Aborting.");
3171-
return 1; /* purecov: inspected */
3172-
}
3173-
3174-
sql_print_information("Creating the data directory %s", mysql_real_data_home);
3175-
if (my_mkdir(mysql_real_data_home, flags, MYF(MY_WME)))
3176-
return 1; /* purecov: inspected */
3177-
}
3157+
if (unlikely(opt_initialize) &&
3158+
initialize_create_data_directory(mysql_real_data_home))
3159+
return 1;
31783160

31793161

31803162
/*

sql/sql_initialize.cc

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,78 @@ void Compiled_in_command_iterator::end(void)
249249
is_active= false;
250250
}
251251
}
252+
253+
254+
/**
255+
Create the data directory
256+
257+
Creates the data directory when --initialize is specified.
258+
The directory is created when it does not exist.
259+
If it exists, is empty and the process can write into it
260+
no action is taken and the directory is accepted.
261+
Otherwise an error is thrown.
262+
263+
@param data_home the normalized path to the data directory
264+
@return status
265+
@retval true failed to create. Error printed.
266+
@retval false success
267+
*/
268+
bool initialize_create_data_directory(const char *data_home)
269+
{
270+
MY_DIR *dir;
271+
int flags=
272+
#ifdef _WIN32
273+
0
274+
#else
275+
S_IRWXU | S_IRGRP | S_IXGRP
276+
#endif
277+
;
278+
279+
if (NULL != (dir= my_dir(data_home, MYF(MY_DONT_SORT))))
280+
{
281+
bool no_files;
282+
char path[FN_REFLEN];
283+
File fd;
284+
285+
no_files= dir->number_off_files == 2; /* "." and ".." */
286+
my_dirend(dir);
287+
288+
if (!no_files)
289+
{
290+
sql_print_error("--initialize specified but the data directory"
291+
" has files in it. Aborting.");
292+
return true; /* purecov: inspected */
293+
}
294+
295+
sql_print_information("--initialize specifed on an existing data directory.");
296+
297+
if (NULL == fn_format(path, "is_writable", data_home, "",
298+
MY_UNPACK_FILENAME | MY_SAFE_PATH))
299+
{
300+
sql_print_error("--initialize specified but the data directory"
301+
" exists and the path is too long. Aborting.");
302+
return true; /* purecov: inspected */
303+
304+
}
305+
if (-1 != (fd= my_create(path, 0, flags, MYF(MY_WME))))
306+
{
307+
my_close(fd, MYF(MY_WME));
308+
my_delete(path, MYF(MY_WME));
309+
}
310+
else
311+
{
312+
sql_print_error("--initialize specified but the data directory"
313+
" exists and is not writable. Aborting.");
314+
return true; /* purecov: inspected */
315+
}
316+
317+
/* the data dir found is usable */
318+
return false;
319+
}
320+
321+
sql_print_information("Creating the data directory %s", data_home);
322+
if (my_mkdir(data_home, flags, MYF(MY_WME)))
323+
return true; /* purecov: inspected */
324+
325+
return false;
326+
}

sql/sql_initialize.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,6 @@ class Compiled_in_command_iterator : public Command_iterator
3535
};
3636

3737
extern my_bool opt_initialize_insecure;
38+
bool initialize_create_data_directory(const char *data_home);
3839

3940
#endif /* SQL_INITIALIZE_H */

0 commit comments

Comments
 (0)