30
30
#include " client/mysqltest/error_names.h"
31
31
#include " client/mysqltest/expected_errors.h"
32
32
#include " client/mysqltest/secondary_engine.h"
33
+ #include " client/mysqltest/utils.h"
33
34
34
35
#include < algorithm>
35
36
#include < cmath> // std::isinf
@@ -151,6 +152,7 @@ enum {
151
152
OPT_EXPLAIN_PROTOCOL,
152
153
OPT_JSON_EXPLAIN_PROTOCOL,
153
154
OPT_LOG_DIR,
155
+ OPT_OFFLOAD_COUNT_FILE,
154
156
OPT_MARK_PROGRESS,
155
157
OPT_MAX_CONNECT_RETRIES,
156
158
OPT_MAX_CONNECTIONS,
@@ -160,7 +162,6 @@ enum {
160
162
#ifdef _WIN32
161
163
OPT_SAFEPROCESS_PID,
162
164
#endif
163
- OPT_SECONDARY_ENGINE,
164
165
OPT_SP_PROTOCOL,
165
166
OPT_TAIL_LINES,
166
167
OPT_TRACE_EXEC,
@@ -209,8 +210,9 @@ static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos = line_buffer;
209
210
static bool can_handle_expired_passwords = true ;
210
211
211
212
// Secondary engine options
213
+ static const char *opt_offload_count_file;
212
214
static int opt_change_propagation;
213
- static const char *opt_secondary_engine ;
215
+ Secondary_engine secondary_engine ;
214
216
215
217
#ifdef _WIN32
216
218
static DWORD opt_safe_process_pid;
@@ -1365,6 +1367,18 @@ static void free_used_memory() {
1365
1367
}
1366
1368
1367
1369
static void cleanup_and_exit (int exit_code) {
1370
+ if (opt_offload_count_file) {
1371
+ // Check if the current connection is active, if not create one.
1372
+ if (cur_con->mysql .net .vio == 0 ) {
1373
+ mysql_real_connect (&cur_con->mysql , opt_host, opt_user, opt_pass, opt_db,
1374
+ opt_port, unix_sock,
1375
+ CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS);
1376
+ }
1377
+ // Save the final value of secondary engine execution status.
1378
+ if (secondary_engine.offload_count (&cur_con->mysql , " after" )) exit_code = 1 ;
1379
+ secondary_engine.report_offload_count (opt_offload_count_file);
1380
+ }
1381
+
1368
1382
free_used_memory ();
1369
1383
my_end (my_end_arg);
1370
1384
@@ -2981,31 +2995,6 @@ static void do_exec(struct st_command *command, bool run_in_background) {
2981
2995
2982
2996
enum enum_operator { DO_DEC, DO_INC };
2983
2997
2984
- // / Use stoi function to get the integer value from a string.
2985
- // /
2986
- // / @param str String which may contain an integer or an alphanumeric
2987
- // / string.
2988
- // /
2989
- // / @retval Integer value corresponding to the contents of the string,
2990
- // / if conversion is successful, or -1 if integer is out of
2991
- // / range, or if the conversion fails.
2992
- static int get_int_val (const char *str) {
2993
- int value;
2994
- size_t size;
2995
-
2996
- try {
2997
- value = std::stoi (str, &size, 10 );
2998
- if (size != std::strlen (str)) value = -1 ;
2999
- } catch (const std::out_of_range &) {
3000
- fprintf (stderr, " Interger value '%s' is out of range. " , str);
3001
- value = -1 ;
3002
- } catch (const std::invalid_argument &) {
3003
- value = -1 ;
3004
- }
3005
-
3006
- return value;
3007
- }
3008
-
3009
2998
// / Template function that frees memory of the dynamic string
3010
2999
// / passed to the function.
3011
3000
// /
@@ -5164,32 +5153,6 @@ static void do_disable_testcase(struct st_command *command) {
5164
5153
free_dynamic_strings (&ds_bug_number);
5165
5154
}
5166
5155
5167
- /*
5168
- Run query and return one field in the result set from the
5169
- first row and <column>
5170
- */
5171
-
5172
- static int query_get_string (MYSQL *mysql, const char *query, int column,
5173
- std::string *ds) {
5174
- MYSQL_RES *res = NULL ;
5175
- MYSQL_ROW row;
5176
-
5177
- if (mysql_query (mysql, query))
5178
- die (" '%s' failed: %d %s" , query, mysql_errno (mysql), mysql_error (mysql));
5179
- if ((res = mysql_store_result (mysql)) == NULL )
5180
- die (" Failed to store result: %d %s" , mysql_errno (mysql),
5181
- mysql_error (mysql));
5182
-
5183
- if ((row = mysql_fetch_row (res)) == NULL ) {
5184
- mysql_free_result (res);
5185
- ds = 0 ;
5186
- return 1 ;
5187
- }
5188
- ds->assign (row[column] ? row[column] : " NULL" );
5189
- mysql_free_result (res);
5190
- return 0 ;
5191
- }
5192
-
5193
5156
/* *
5194
5157
Check if process is active.
5195
5158
@@ -5293,85 +5256,91 @@ static void abort_process(int pid, const char *path MY_ATTRIBUTE((unused))) {
5293
5256
#endif
5294
5257
}
5295
5258
5296
- /* *
5297
- Shutdown or kill the server.
5298
- If timeout is set to 0 the server is killed/terminated
5299
- immediately. Otherwise the shutdown command is first sent
5300
- and then it waits for the server to terminate within
5301
- @<timeout@> seconds. If it has not terminated before @<timeout@>
5302
- seconds the command will fail.
5303
-
5304
- @note Currently only works with local server
5305
-
5306
- @param command Optionally including a timeout else the
5307
- default of 60 seconds is used.
5308
- */
5309
-
5259
+ // / Shutdown or kill the server. If timeout is set to 0 the server is
5260
+ // / killed or terminated immediately. Otherwise the shutdown command
5261
+ // / is first sent and then it waits for the server to terminate within
5262
+ // / 'timeout' seconds. If it has not terminated before 'timeout'
5263
+ // / seconds the command will fail.
5264
+ // /
5265
+ // / @note
5266
+ // / Currently only works with local server
5267
+ // /
5268
+ // / @param command Pointer to the st_command structure which holds the
5269
+ // / arguments and information for the command. Optionally
5270
+ // / including a timeout else the default of 60 seconds
5271
+ // / is used.
5310
5272
static void do_shutdown_server (struct st_command *command) {
5311
- long timeout = 60 ;
5312
- int pid, error = 0 ;
5313
- std::string ds_file_name;
5314
- MYSQL *mysql = &cur_con->mysql ;
5315
5273
static DYNAMIC_STRING ds_timeout;
5316
5274
const struct command_arg shutdown_args[] = {
5317
5275
{" timeout" , ARG_STRING, false , &ds_timeout,
5318
5276
" Timeout before killing server" }};
5319
- DBUG_ENTER (" do_shutdown_server" );
5320
5277
5321
5278
check_command_args (command, command->first_argument , shutdown_args,
5322
5279
sizeof (shutdown_args) / sizeof (struct command_arg ), ' ' );
5323
5280
5281
+ if (opt_offload_count_file) {
5282
+ // Save the value of secondary engine execution status
5283
+ // before shutting down the server.
5284
+ if (secondary_engine.offload_count (&cur_con->mysql , " after" ))
5285
+ cleanup_and_exit (1 );
5286
+ }
5287
+
5288
+ long timeout = 60 ;
5324
5289
if (ds_timeout.length ) {
5325
5290
char *endptr;
5326
- timeout = strtol (ds_timeout.str , &endptr, 10 );
5291
+ timeout = std:: strtol (ds_timeout.str , &endptr, 10 );
5327
5292
if (*endptr != ' \0 ' )
5328
5293
die (" Illegal argument for timeout: '%s'" , ds_timeout.str );
5329
5294
}
5295
+
5330
5296
dynstr_free (&ds_timeout);
5331
5297
5332
- /* Get the servers pid_file name and use it to read pid */
5298
+ MYSQL *mysql = &cur_con->mysql ;
5299
+ std::string ds_file_name;
5300
+
5301
+ // Get the servers pid_file name and use it to read pid.
5333
5302
if (query_get_string (mysql, " SHOW VARIABLES LIKE 'pid_file'" , 1 ,
5334
5303
&ds_file_name))
5335
5304
die (" Failed to get pid_file from server" );
5336
5305
5337
- /* Read the pid from the file */
5338
- {
5339
- int fd;
5340
- char buff[32 ];
5306
+ // Read the pid from the file
5307
+ int fd;
5308
+ char buff[32 ];
5341
5309
5342
- if ((fd = my_open (ds_file_name.c_str (), O_RDONLY, MYF (0 ))) < 0 )
5343
- die (" Failed to open file '%s'" , ds_file_name.c_str ());
5310
+ if ((fd = my_open (ds_file_name.c_str (), O_RDONLY, MYF (0 ))) < 0 )
5311
+ die (" Failed to open file '%s'" , ds_file_name.c_str ());
5344
5312
5345
- if (my_read (fd, (uchar *)&buff, sizeof (buff), MYF (0 )) <= 0 ) {
5346
- my_close (fd, MYF (0 ));
5347
- die (" pid file was empty" );
5348
- }
5313
+ if (my_read (fd, (uchar *)&buff, sizeof (buff), MYF (0 )) <= 0 ) {
5349
5314
my_close (fd, MYF (0 ));
5350
-
5351
- pid = atoi (buff);
5352
- if (pid == 0 ) die (" Pidfile didn't contain a valid number" );
5315
+ die (" pid file was empty" );
5353
5316
}
5354
- DBUG_PRINT (" info" , (" Got pid %d" , pid));
5355
5317
5318
+ my_close (fd, MYF (0 ));
5319
+
5320
+ int pid = std::atoi (buff);
5321
+ if (pid == 0 ) die (" Pidfile didn't contain a valid number" );
5322
+
5323
+ int error = 0 ;
5356
5324
if (timeout) {
5357
- /* Check if we should generate a minidump on timeout. */
5325
+ // Check if we should generate a minidump on timeout.
5358
5326
if (query_get_string (mysql, " SHOW VARIABLES LIKE 'core_file'" , 1 ,
5359
5327
&ds_file_name) ||
5360
5328
std::strcmp (" ON" , ds_file_name.c_str ())) {
5361
5329
} else {
5362
- /* Get the data dir and use it as path for a minidump if needed. */
5330
+ // Get the data dir and use it as path for a minidump if needed.
5363
5331
if (query_get_string (mysql, " SHOW VARIABLES LIKE 'datadir'" , 1 ,
5364
5332
&ds_file_name))
5365
- die (" Failed to get datadir from server" );
5333
+ die (" Failed to get datadir from server. " );
5366
5334
}
5367
5335
5368
- /* Tell server to shutdown if timeout > 0. */
5336
+ // Tell server to shutdown if timeout > 0.
5369
5337
if (timeout > 0 && mysql_query (mysql, " shutdown" )) {
5370
- error = 1 ; /* Failed to issue shutdown command. */
5338
+ // Failed to issue shutdown command.
5339
+ error = 1 ;
5371
5340
goto end;
5372
5341
}
5373
5342
5374
- /* Check that server dies */
5343
+ // Check that server dies
5375
5344
do {
5376
5345
if (!is_process_active (pid)) {
5377
5346
DBUG_PRINT (" info" , (" Process %d does not exist anymore" , pid));
@@ -5382,25 +5351,23 @@ static void do_shutdown_server(struct st_command *command) {
5382
5351
my_sleep (1000000L );
5383
5352
}
5384
5353
} while (timeout-- > 0 );
5354
+
5385
5355
error = 2 ;
5386
- /*
5387
- Abort to make it easier to find the hang/problem.
5388
- */
5356
+
5357
+ // Abort to make it easier to find the hang/problem.
5389
5358
abort_process (pid, ds_file_name.c_str ());
5390
- } else /* timeout == 0 */
5391
- {
5392
- /* Kill the server */
5359
+ } else {
5360
+ // timeout value is 0, kill the server
5393
5361
DBUG_PRINT (" info" , (" Killing server, pid: %d" , pid));
5394
- /*
5395
- kill_process can fail (bad privileges, non existing process on *nix etc),
5396
- so also check if the process is active before setting error.
5397
- */
5362
+
5363
+ // kill_process can fail (bad privileges, non existing process on
5364
+ // *nix etc), so also check if the process is active before setting
5365
+ // error.
5398
5366
if (!kill_process (pid) && is_process_active (pid)) error = 3 ;
5399
5367
}
5400
5368
5401
5369
end:
5402
5370
if (error) handle_command_error (command, error);
5403
- DBUG_VOID_RETURN;
5404
5371
}
5405
5372
5406
5373
// / Get the error code corresponding to an error string or to a
@@ -6951,6 +6918,9 @@ static struct my_option my_long_options[] = {
6951
6918
" Contains comma seperated list of to be excluded inc files." ,
6952
6919
&excluded_string, &excluded_string, 0 , GET_STR, REQUIRED_ARG, 0 , 0 , 0 , 0 ,
6953
6920
0 , 0 },
6921
+ {" offload-count-file" , OPT_OFFLOAD_COUNT_FILE, " Offload count report file" ,
6922
+ &opt_offload_count_file, &opt_offload_count_file, 0 , GET_STR, REQUIRED_ARG,
6923
+ 0 , 0 , 0 , 0 , 0 , 0 },
6954
6924
{" opt-trace-protocol" , OPT_TRACE_PROTOCOL,
6955
6925
" Trace DML statements with optimizer trace" , &opt_trace_protocol,
6956
6926
&opt_trace_protocol, 0 , GET_BOOL, NO_ARG, 0 , 0 , 0 , 0 , 0 , 0 },
@@ -6988,9 +6958,6 @@ static struct my_option my_long_options[] = {
6988
6958
&opt_safe_process_pid, &opt_safe_process_pid, 0 , GET_INT, REQUIRED_ARG, 0 ,
6989
6959
0 , 0 , 0 , 0 , 0 },
6990
6960
#endif
6991
- {" secondary-engine" , OPT_SECONDARY_ENGINE,
6992
- " Enable a secondary storage engine." , &opt_secondary_engine,
6993
- &opt_secondary_engine, 0 , GET_STR, REQUIRED_ARG, 0 , 0 , 0 , 0 , 0 , 0 },
6994
6961
{" shared-memory-base-name" , OPT_SHARED_MEMORY_BASE_NAME,
6995
6962
" Base name of shared memory." , &shared_memory_base_name,
6996
6963
&shared_memory_base_name, 0 , GET_STR, REQUIRED_ARG, 0 , 0 , 0 , 0 , 0 , 0 },
@@ -7659,7 +7626,7 @@ static void run_query_normal(struct st_connection *cn,
7659
7626
if (opt_change_propagation != -1 ) {
7660
7627
std::vector<unsigned int > ignore_errors = expected_errors->errors ();
7661
7628
// Run secondary engine unload statements.
7662
- if (run_secondary_engine_unload_statements (query, mysql, ignore_errors))
7629
+ if (secondary_engine. run_unload_statements (query, mysql, ignore_errors))
7663
7630
die (" Original query '%s'." , query);
7664
7631
}
7665
7632
@@ -7766,9 +7733,7 @@ static void run_query_normal(struct st_connection *cn,
7766
7733
if (opt_change_propagation != -1 ) {
7767
7734
std::vector<unsigned int > ignore_errors = expected_errors->errors ();
7768
7735
// Run secondary engine load statements.
7769
- if (run_secondary_engine_load_statements (opt_secondary_engine, query, mysql,
7770
- ignore_errors,
7771
- opt_change_propagation))
7736
+ if (secondary_engine.run_load_statements (query, mysql, ignore_errors))
7772
7737
die (" Original query '%s'." , query);
7773
7738
}
7774
7739
@@ -7804,7 +7769,7 @@ static void run_query_stmt(MYSQL *mysql, struct st_command *command,
7804
7769
if (opt_change_propagation != -1 ) {
7805
7770
std::vector<unsigned int > ignore_errors = expected_errors->errors ();
7806
7771
// Run secondary engine unload statements.
7807
- if (run_secondary_engine_unload_statements (query, mysql, ignore_errors))
7772
+ if (secondary_engine. run_unload_statements (query, mysql, ignore_errors))
7808
7773
die (" Original query '%s'." , query);
7809
7774
}
7810
7775
@@ -7996,9 +7961,7 @@ static void run_query_stmt(MYSQL *mysql, struct st_command *command,
7996
7961
if (opt_change_propagation != -1 ) {
7997
7962
std::vector<unsigned int > ignore_errors = expected_errors->errors ();
7998
7963
// Run secondary engine load statements.
7999
- if (run_secondary_engine_load_statements (opt_secondary_engine, query, mysql,
8000
- ignore_errors,
8001
- opt_change_propagation))
7964
+ if (secondary_engine.run_load_statements (query, mysql, ignore_errors))
8002
7965
die (" Original query '%s'." , query);
8003
7966
}
8004
7967
@@ -8921,6 +8884,15 @@ int main(int argc, char **argv) {
8921
8884
open_file (opt_include);
8922
8885
}
8923
8886
8887
+ if (opt_change_propagation != -1 )
8888
+ secondary_engine = Secondary_engine (opt_change_propagation);
8889
+
8890
+ if (opt_offload_count_file) {
8891
+ // Save the initial value of secondary engine execution status.
8892
+ if (secondary_engine.offload_count (&cur_con->mysql , " before" ))
8893
+ cleanup_and_exit (1 );
8894
+ }
8895
+
8924
8896
verbose_msg (" Start processing test commands from '%s' ..." ,
8925
8897
cur_file->file_name );
8926
8898
while (!read_command (&command) && !abort_flag) {
@@ -9287,6 +9259,12 @@ int main(int argc, char **argv) {
9287
9259
do_reset_connection ();
9288
9260
break ;
9289
9261
case Q_SEND_SHUTDOWN:
9262
+ if (opt_offload_count_file) {
9263
+ // Save the value of secondary engine execution status
9264
+ // before shutting down the server.
9265
+ if (secondary_engine.offload_count (&cur_con->mysql , " after" ))
9266
+ cleanup_and_exit (1 );
9267
+ }
9290
9268
handle_command_error (command,
9291
9269
mysql_query (&cur_con->mysql , " shutdown" ));
9292
9270
break ;
0 commit comments